JetDiji
Şube Mobil API — Geliştirici Rehberi Şube (acente) mobil uygulaması · Bearer kimlik doğrulama

Şube Mobil API Rehberi

Şube (acente) mobil uygulamasını geliştirenler için. Uygulama, web şube panelindeki (B01–B17, kuryeler, bölgeler, depolar) ekranlarla aynı uçları kullanır. Alan ve şema ayrıntıları için API Referansı'na bakın (üstten "Şube Mobil API"yi seçin).

1. Hızlı başlangıç

Dört istekle ilk akışı preprod ortamında deneyin. Şifre yerine kendi test şifrenizi yazın.

  1. Giriş yapın, token alın. X-Client-Type: mobile başlığı şarttır; yoksa token yanıtta gelmez.
    curl -X POST "https://api-mobile.preprod.jetdiji.com/api/portal/v1/agency-auth/login" \
      -H "Content-Type: application/json" \
      -H "X-Client-Type: mobile" \
      -d '{"email":"sube.yetkili@example.com","password":"***"}'
    Yanıttaki data.accessToken değerini saklayın (8 saat geçerli). 409 AGENCY_SELECTION_REQUIRED gelirse error.agencies listesinden bir id seçip aynı isteğe "agencyId" ekleyin.
  2. Oturumu doğrulayın. Yetkiler (capabilities) buradan gelir.
    TOKEN="buraya-accessToken"
    curl "https://api-mobile.preprod.jetdiji.com/api/portal/v1/agency-auth/session" \
      -H "Authorization: Bearer $TOKEN"
  3. Bir ekran verisi okuyun (B11 Ana sayfa).
    curl "https://api-mobile.preprod.jetdiji.com/api/portal/v1/branch/dashboard" \
      -H "Authorization: Bearer $TOKEN"
  4. Bir yazma isteği gönderin (kurye ata). Gönderi ve kurye kimliklerini GET branch/preparation ve GET branch/dispatch/options?shipmentId=… yanıtlarından alın. Her yazma isteğinde yeni bir Idempotency-Key üretin.
    curl -X POST "https://api-mobile.preprod.jetdiji.com/api/portal/v1/branch/dispatch/handover" \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      -H "Idempotency-Key: 6f1d1c7e-2b7a-4e0c-9a51-3a9f8f2e7b10" \
      -d '{"courierId":"KURYE_ID","shipmentIds":["GONDERI_ID"]}'
    Aynı komutu aynı anahtarla tekrar çalıştırın: yanıt 200 ve data.replayed: true olur, ikinci bir zimmet açılmaz.

2. Ortamlar ve hesaplar

OrtamBase URLKullanım
Preprod (test)https://api-mobile.preprod.jetdiji.comGeliştirme ve test. Önce burada çalışın.
Canlıhttps://api-mobile.jetdiji.comMağaza sürümü.
  • Yollar iki ortamda aynıdır: /api/portal/v1/....
  • Hesaplar ve token'lar ortamlar arasında geçmez.
  • Swagger'daki / ("Aynı origin") sunucusu yalnız doküman panelin kendi alan adında açıldığında kullanılır. "Try it out" yalnız test ortamlarında çalışır.
  • Test hesabı: JetDiji ekibinden isteyin. Tüm düğmeleri deneyebilmek için AGENCY_ADMIN rolü isteyin; yalnız operasyon akışını görmek için AGENCY_OPERATOR yeterlidir (bkz. Roller).

3. Kimlik doğrulama

  1. POST agency-auth/login — gövde { email, password, agencyId? }, başlık X-Client-Type: mobile. Yanıt: data.accessToken, data.tokenType: "Bearer", data.expiresAt (ISO). Başlık yoksa token yalnız jetdiji_agency_session çerezine yazılır (web).
  2. Şube seçimi (409). Kullanıcının birden çok şube yetkisi varsa ya da kullanıcı SYSTEM_OWNER ise (tek şube olsa bile) yanıt 409 AGENCY_SELECTION_REQUIRED + error.agencies[] olur. Kullanıcıya listeyi gösterin, seçilen id'yi agencyId olarak ekleyip aynı isteği tekrarlayın. SYSTEM_OWNER tüm aktif şubeleri seçebilir; şube rolü olmadan da şube seçerek bağlanabilir.
  3. GET agency-auth/session — açılışta token'ı doğrulayın; rolleri (roles[].code), yetenekleri (capabilities: { operate, manage }) ve şube bilgisini alın.
  4. Sonraki tüm isteklerde Authorization: Bearer <accessToken>. Token, web çerezindekiyle aynı HS256 JWT'dir.
  5. POST agency-auth/logout — sunucu oturumu LOGGED_OUT yapar; token artık geçmez. Token geçersiz ya da eksik olsa da 200 döner. Ardından token'ı cihazdan silin.

Token süresi

  • Oturum 8 saat geçerlidir (JWT exp + sunucudaki portal_user_sessions.expiresAt).
  • Süre dolunca, oturum iptal edilince ya da şube / kullanıcı pasifleşince tüm uçlar 401 UNAUTHENTICATED döner → giriş ekranı.
  • Yenileme (refresh) ucu yoktur; süre dolunca yeniden giriş gerekir.

Giriş hataları

HTTPKodNe yapmalı
400INVALID_JSON, INVALID_EMAIL, PASSWORD_REQUIREDFormu düzeltin. Bozuk JSON artık 500 değil 400 döner.
401INVALID_CREDENTIALSYanlış şifrede error.remainingAttempts ve error.lockedUntil: null gelir; kalan hakkı gösterin. Kayıtsız e-postada ek alan yoktur.
423ACCOUNT_TEMPORARILY_LOCKED5 hatalı denemede hesap 15 dakika kilitlenir. error.lockedUntil'e kadar bekletin. Kilitlenme anında error.remainingAttempts: 0.
403ACCOUNT_NOT_ACTIVE, PASSWORD_NOT_SET, NO_ACTIVE_AGENCY_ACCESS, AGENCY_ACCESS_DENIEDKullanıcı pasif / davet tamamlanmamış / aktif şube yetkisi yok / seçilen şubeye yetki yok. Mesajı gösterin.
409AGENCY_SELECTION_REQUIREDŞube seçtirin, agencyId ile tekrarlayın.
500LOGIN_FAILEDBeklenmeyen hata; tekrar deneyin.

Hata ek alanları (remainingAttempts, lockedUntil, agencies) error içindedir. Üst seviye kopyaları ve 409'daki data.agencies yalnız eski web uyumluluğu içindir; mobil error.* okur.

Diğer notlar

  • E-posta küçük harfe çevrilir. Davetli (INVITED) kullanıcı ilk girişte ACTIVE olur.
  • Şifre değiştirme: şube API'sinde şifre değiştirme ucu yoktur. mustChangePassword: true gelirse bunu kullanıcıya bilgi olarak gösterin.
  • Token saklama: iOS Keychain / Android Keystore (EncryptedSharedPreferences). Düz dosyaya ya da AsyncStorage'a yazmayın; token'ı loglamayın.
  • Web çerezi (jetdiji_agency_session, httpOnly) de desteklenir ama mobilde kullanılmaz.
  • Yetki ve düğme gösterimi için Roller bölümüne bakın.

4. Hata yönetimi

Tüm uçlar (kimlik, acente, şube) aynı zarfı döner:

{
  "success": false,
  "error": {
    "code": "DISPATCH_NOT_READY",
    "message": "Gönderi artık dağıtıma hazırlık adımında değil. Ekranı yenileyin.",
    "shipmentNumber": "JD2026100300123"
  },
  "code": "DISPATCH_NOT_READY",
  "message": "Gönderi artık dağıtıma hazırlık adımında değil. Ekranı yenileyin."
}
  • Yalnız error.code'a bakın. error.message varsa kullanıcıya doğrudan gösterilebilir; yoksa kod için kendi çevirinizi kullanın. Üst seviye code / message eski web uyumluluğu içindir.
  • Uca özgü ek alanlar error içindedir (eski error.details kaldırıldı): shipmentNumber, transferId, transferNumber, max, variables, allowed, reason, issues, minLength / maxLength; login'de remainingAttempts, lockedUntil, agencies.
  • Bozuk JSON: JSON gövde okuyan tüm uçlarda bozuk / boş / nesne olmayan gövde → 400 INVALID_JSON (eski INVALID_BODY kaldırıldı). İstisna: transfers/incoming/{id}/confirm boş gövdeyi {} sayar.
  • Şema hatası (geçerli JSON, yanlış alan): zod kullanan uçlarda (transfer, etiket, sayım) 422 VALIDATION_FAILED + error.issues: [{ path, code, message }]; diğer uçlarda uca özgü 400 kodları (ör. DISPATCH_INVALID_INPUT, CARD_OWNER_TYPE_INVALID).
  • Başarı: { "success": true, "data": ... }. Yazma uçlarında ayrıca üst seviye replayed / idempotent gelir (eski web uyumluluğu; mobil data.replayed okur).

İstemci ne yapmalı

HTTPAnlamİstemci davranışı
401Oturum yok / süresi dolduToken'ı silin, giriş ekranına dönün.
403Yetki yok (FORBIDDEN)error.message ile yetki mesajı gösterin; düğmeyi pasif tutun. Kuyruktan çıkarın, tekrar denemeyin.
404Kayıt bu şubede yokMesajı gösterin, listeyi yenileyin.
409Durum değişti / çakışmaerror.message'ı gösterin ve ekranı yenileyin. Tekrar denemeyin.
422Alan doğrulama hatasıerror.issues[].path ile ilgili alanın altında hata gösterin.
423Hesap kilitli (yalnız login)error.lockedUntil'e kadar girişi kapatın.
429Çok fazla istekŞube uçları bugün 429 dönmez. Gelirse bir süre bekleyip aynı anahtarla tekrar deneyin.
5xx / ağ hatasıSunucu ya da bağlantı sorunuAynı Idempotency-Key ile tekrar deneyin (bkz. Yazma istekleri).

400 hataları (eksik anahtar, bozuk JSON, geçersiz alan) istemci hatasıdır: düzeltmeden tekrar göndermeyin.

Tüm hata kodları sözlüğü

Ortak

KodHTTPAnlam
UNAUTHENTICATED401Token yok / geçersiz / süresi dolmuş / oturum kapalı
INVALID_JSON400Gövde geçerli bir JSON nesnesi değil (bozuk / boş / dizi)
VALIDATION_FAILED422Gövde / path parametresi doğrulaması (zod) başarısız (error.issues)
FORBIDDEN403Yetenek yok; ayrıntı error.reason (BRANCH_OPERATE_REQUIRED, BRANCH_MANAGE_REQUIRED)
IDEMPOTENCY_KEY_REQUIRED400Idempotency-Key başlığı zorunlu
IDEMPOTENCY_KEY_INVALID400Anahtar 8–160 boşluksuz görünür ASCII değil (error.minLength, error.maxLength)
INTERNAL_ERROR500Beklenmeyen hata (transfer / etiket / sayım / SMS / fatura / sözleşme / performans)

Giriş ve şube

KodHTTPAnlam
INVALID_EMAIL400E-posta biçimi geçersiz
PASSWORD_REQUIRED400Şifre boş
INVALID_CREDENTIALS401E-posta veya şifre hatalı (error.remainingAttempts, error.lockedUntil)
ACCOUNT_TEMPORARILY_LOCKED4235 hatalı deneme → 15 dk kilit (error.lockedUntil)
ACCOUNT_NOT_ACTIVE403Kullanıcı pasif / askıda / kilitli
PASSWORD_NOT_SET403Şifre belirlenmemiş (davet tamamlanmamış)
NO_ACTIVE_AGENCY_ACCESS403Aktif şube yetkisi yok
AGENCY_ACCESS_DENIED403İstenen agencyId için yetki yok
AGENCY_SELECTION_REQUIRED409Şube seçilmeli (error.agencies)
LOGIN_FAILED500Beklenmeyen giriş hatası
AGENCY_NOT_FOUND404Oturumdaki şube bulunamadı
BRANCH_NOT_FOUND404Şube kaydı yok

Ekran verisi yükleme (500)

KodHTTPAnlam
AGENCY_COURIERS_LOAD_FAILED / AGENCY_REGIONS_LOAD_FAILED / AGENCY_WAREHOUSES_LOAD_FAILED500Liste yüklenemedi
BRANCH_DASHBOARD_FAILED / BRANCH_COURIER_MAP_FAILED / BRANCH_PENDING_FAILED500Ekran verisi yüklenemedi
BRANCH_PREPARATION_GET_FAILED / BRANCH_DISPATCH_GET_FAILED / BRANCH_COURIER_JOBS_GET_FAILED / BRANCH_DISPATCH_OPTIONS_FAILED / BRANCH_PRINT_ROWS_FAILED500Dağıtım verisi yüklenemedi
COURIER_HANDOVER_FAILED / COURIER_HANDOVER_CHANGE_FAILED / COURIER_HANDOVER_CANCEL_FAILED / COURIER_REASSIGN_FAILED / BRANCH_RETURN_SCAN_FAILED500Dağıtım işleminde beklenmeyen hata

Dağıtım ve zimmet

KodHTTPAnlam
DISPATCH_INVALID_INPUT400Gönderi / kurye kimliği geçersiz, liste boş veya >200: "Şube ve kurye seçimini kontrol edin."
BRANCH_SHIPMENT_NOT_FOUND404Gönderi bu birimde değil
BRANCH_COURIER_NOT_FOUND404Kurye bu birime aktif bağlı / çalışır durumda değil
SHIPMENT_NOT_FOUND404"Gönderi bulunamadı."
DISPATCH_NOT_READY409"Gönderi artık dağıtıma hazırlık adımında değil. Ekranı yenileyin."
DISPATCH_SELECTION_STALE409"Gönderi bilgileri değişti. Seçimi yenileyip tekrar onaylayın."
DISPATCH_COURIER_UNAVAILABLE409"Seçilen kurye artık uygun değil. Kurye listesini yenileyin."
DISPATCH_TRANSITION_FAILED409"Dağıtım başlatılamadı. Atama kaydedilmedi."
MAX_REDELIVERY_COUNT_REACHED409"Gönderinin dağıtıma çıkış hakkı doldu."
REASSIGN_NOT_IN_DISTRIBUTION409"Kurye yalnız dağıtımdaki gönderide değiştirilebilir."
REASSIGN_SAME_COURIER409"Gönderi zaten bu kuryede."
HANDOVER_EMPTY409"Zimmetlenecek gönderi seçin."
HANDOVER_ALREADY_PENDING409"Gönderi zaten bir kuryenin kabulünü bekliyor." (CUSTODY_TRANSFER_SUBJECT_LOCKED buna çevrilir)
HANDOVER_SHIPMENT_WITH_COURIER409"Gönderi hâlâ bir kuryenin zimmetinde. Önce gün sonu iadesi alınmalı."
HANDOVER_SOURCE_NOT_AT_COURIER409"Gönderi şu anki kuryenin zimmetinde görünmüyor."
HANDOVER_SOURCE_NOT_AT_UNIT409"Gönderi bu teslimat biriminin zimmetinde değil."
HANDOVER_NOT_PENDING409"Kabul bekleyen zimmet bulunamadı. Ekranı yenileyin."
CANCEL_REASON_REQUIRED / CANCEL_REASON_INVALID400İptal nedeni eksik / katalogda yok
CUSTODY_* (ör. CUSTODY_ACCEPTANCE_ITEM_ALREADY_PROCESSED)servisZimmet servisinden gelen kodlar (servisin HTTP durumuyla)

Kurye dönüşü

KodHTTPAnlam
RETURN_SCAN_REQUIRED400"Gönderi barkodunu okutun."
RETURN_SCAN_NOT_FOUND404"Bu barkodla gönderi bulunamadı."
RETURN_NOT_WITH_COURIER409"Gönderi bir kuryenin zimmetinde görünmüyor."
RETURN_RESULT_REQUIRED409"Gönderi hâlâ dağıtımda. Kurye önce teslim sonucunu girmeli."
RETURN_UNIT_REQUIRED409"Gönderinin teslimat birimi bulunamadı."

Transfer ve etiket

KodHTTPAnlam
TRANSFER_NOT_FOUND404Transfer bu birime ait değil
TRANSFER_NOT_OPEN409Transfer kabul bekleyen durumda değil
SCAN_VALUE_REQUIRED422Okutma değeri boş
SCAN_NOT_IN_INCOMING_TRANSFER404Okutulan kod gelen transferlerde yok
LABEL_VOID409Etiket iptal edilmiş
LABEL_NOT_IN_BRANCH404Etiket bu şubenin deposunda değil
SHIPMENT_NOT_IN_BRANCH404Gönderi bu birimin zimmetinde / atamasında değil
SHIPMENT_TERMINAL409Gönderi kapanmış (terminal durum)
SHIPMENT_IN_TRANSIT409Gönderi açık bir zimmet devrinde (kilitli)
TRANSFER_EMPTY422Satır yok
DESTINATION_NOT_CENTER422Hedef merkez depo değil
TRANSFER_MIXED_SOURCE409Satırlar farklı zimmet kaynaklarında
TRANSFER_ENDPOINT_SAME422Kaynak ve hedef aynı
TRANSFER_ITEM_DUPLICATE409Aynı gönderi iki kez
TRANSFER_DISPATCH_FAILED409Sevk başarısız; taslak kalır (error.transferId, error.transferNumber)
WAREHOUSE_NOT_IN_BRANCH404Depo bu şubenin aktif deposu değil (sayımda: stok yönetimli olmalı)
LABEL_OPERATION_REJECTED4xxEtiket servisi reddetti; error.message Türkçe

Sayım

KodHTTPAnlam
COUNT_NOT_FOUND404Sayım bu şubenin deposunda değil
COUNT_OPERATION_REJECTED4xxSayım servisi reddetti (ör. açık sayım, sayılmamış ürün); error.message Türkçe

SMS

KodHTTPAnlam
TARGET_TYPE_INVALID400Hedef türü geçersiz (eğitimde de kullanılır, bkz. aşağı)
CHANNEL_INVALID / TEMPLATE_REQUIRED / TARGETS_REQUIRED / PHONE_INVALID400SMS isteği geçersiz
TOO_MANY_TARGETS400Alıcı üst sınırı aşıldı (error.max = 500)
TARGET_TYPE_NOT_SUPPORTED / CHANNEL_NOT_AVAILABLE422Hedef / kanal desteklenmiyor
TEMPLATE_VARIABLES_REQUIRED422Eksik / desteklenmeyen şablon değişkeni (error.variables)
TEMPLATE_NOT_FOUND / TARGET_NOT_FOUND404Şablon / alıcı bulunamadı

Eğitim, performans, fatura, kart

KodHTTPAnlam
TARGET_TYPE_INVALID400Eğitim targetType BRANCH / COURIER / CUSTOMER_PROCESS değil (error.allowed)
RANGE_INVALID400range today / 7d / 30d değil
PERIOD_INVALID400period YYYY-MM değil
SUPPORT_CATEGORY_INVALID / DISPUTE_REASON_REQUIRED / NOTE_REQUIRED400Fatura destek isteği geçersiz
CARD_OWNER_TYPE_INVALID / CARD_TOKEN_REQUIRED400Kart isteği geçersiz
CARD_OWNER_NOT_FOUND / CARD_NOT_FOUND404Kart sahibi / kart bu şubeye ait değil
CARD_OWNER_INACTIVE409Kart sahibi aktif değil
CARD_SIGNING_NOT_CONFIGURED503Sunucuda kart imza anahtarı yok

5. Yazma istekleri ve çevrimdışı

Idempotency-Key kuralı

  • Tüm şube yazma uçlarında başlık Idempotency-Key zorunludur: 8–160 karakter, boşluksuz görünür ASCII (0x21–0x7E). Önerilen: UUID v4.
  • Her kullanıcı eylemi için bir kez üretin; yeniden denemede aynı anahtarı gönderin.
  • Başlık yok → 400 IDEMPOTENCY_KEY_REQUIRED. Uzunluk / karakter dışı → 400 IDEMPOTENCY_KEY_INVALID (error.minLength, error.maxLength). Sunucu anahtarı kırpmaz, yok saymaz.
  • X-Client-Event-Id başlığı ve gövdedeki clientEventId anahtar yerine geçmez. Sunucu başlığı okumaz; gövde alanı varsa yalnız audit kaydına yazılır.

Tekrar davranışı

  • Aynı anahtar + aynı uç tekrar gelirse ilk başarılı sonuç döner: HTTP 200 (ilk istek 201/202 olsa bile) ve data.replayed: true (ilk istekte false). Üst seviye replayed ve idempotent aynı değerin eski web kopyasıdır.
  • Anahtar kapsamı: dağıtım, etiket, sayım ve kart uçlarında aynı kullanıcı; transfer, kurye dönüşü, SMS ve fatura uçlarında aynı şube.
  • Hatalı ilk istek saklanmaz; aynı anahtarla yeniden denenebilir. Aynı anahtar farklı gövdeyle gelirse ilk sonuç döner (gövde karşılaştırılmaz).
  • Sonucu nesne olmayan işlemlerde (counts/{id} void-scan, line-reason, close, cancel) yanıt data: { result: null, replayed } olur.
  • Kontrol sırası: oturum (401) → yetenek (403) → anahtar (400) → gövde (400/422). İstisnalar: compliance/cards yeteneği gövdedeki ownerType'a göre seçtiği için anahtar → gövde → yetenek; counts/{id} yetenek kontrolü (action'a göre) gövde doğrulandıktan ve sayım bulunduktan sonra yapılır.
Uç (POST)İlk yanıtTekrar
branch/dispatch/handover, handover/change, handover/cancel, dispatch/reassign200200
branch/pending/courier-return-scan200200
branch/transfers/incoming/scan200200
branch/transfers/incoming/{id}/accept, .../{id}/confirm200200
branch/transfers/outgoing201200
branch/counts201200
branch/counts/{countId} (tüm action'lar)200200
branch/labels201 (generate) / 200 (reprint, printed)200
branch/compliance/cards201200
branch/invoices/support201200 (data.idempotent de korunur, eski alan)
branch/sms/send202200 (data.idempotent de korunur; yanıt partinin güncel özetidir)

Anahtar gerekmeyen POST'lar (yan etkisiz; başlık gönderilirse yok sayılır): transfers/outgoing/resolve, preparation/print-rows, sms/preview, compliance/cards/verify (audit yazar ama durum değiştirmez). agency-auth/login ve logout da anahtar istemez.

Çevrimdışı kuyruk

Web'deki offline-queue.ts ile aynı sözleşme:

  1. Kullanıcı eylemi geldiğinde anahtarı üretin ve isteği anahtarıyla birlikte cihazda saklayın.
  2. İsteği gönderin. Ağ hatası ya da 5xx gelirse kuyrukta tutun ve aynı Idempotency-Key ile yeniden deneyin.
  3. Sunucu teyidi (success: true) gelmeden "tamamlandı / içeri alındı" göstermeyin; o ana kadar "kuyrukta" gösterin.
  4. 4xx yanıt kalıcı hatadır: kaydı kuyruktan çıkarın ve kullanıcıya gösterin.

6. Ekran ekran akışlar

Her kart aynı sırayı izler: amaç, çağrı sırası, iş kuralları, hata durumunda ne yapılmalı. Yollar /api/portal/v1/ önekiyle başlar. Tüm yazma çağrıları Idempotency-Key ister (bkz. 5. bölüm); yetki için Roller bölümüne bakın.

GirişGiriş ve kabuk

Amaç

Kullanıcıyı içeri almak, şubeyi seçtirmek ve her ekranda kullanıcı / şube adını ve yetkileri göstermek.

Çağrı sırası

  1. POST agency-auth/login (X-Client-Type: mobile)
  2. 409 ise şube seçtirin → POST agency-auth/login (agencyId ile)
  3. GET agency-auth/session — rol, şube adı, capabilities
  4. Çıkış: POST agency-auth/logout

İş kuralları

  • Oturum 8 saat; yenileme ucu yok. Ayrıntılar 3. bölümde.

Hata durumunda

B11Ana sayfa

Amaç

Şubenin gün özetini göstermek: KPI'lar, kurye canlı durumu, zimmet onay sayıları.

Çağrı sırası

  1. GET branch/dashboard — açılışta ve yenilemede

İş kuralları

  • Bugün dağıtılacak = 4010 + 4020; bugün teslim = 5010 / 5020; bugün iptal = 8010 / 8030.
  • Bekleyen işlem = B13 kuyruklarının toplamı. Merkeze iade = 7010 / 7030 veya alt 3022 (returnToCenter).
  • Acil = 9116 (Devir), SLA ihlali ya da 24 saat içinde dolacak SLA.
  • Kurye canlı durumu son konum yaşından türetilir (bkz. konum).

Hata durumunda

  • 404 AGENCY_NOT_FOUND: oturumdaki şube yok → çıkış yaptırıp yeniden girişe yönlendirin.
  • 500 BRANCH_DASHBOARD_FAILED: "yüklenemedi" gösterin, yenile düğmesi sunun.
B01Hazırlık / kurye ataması

Amaç

Birimde kurye bekleyen ve şubeye gelecek gönderileri listelemek; seçilenleri kuryeye atamak, atamayı değiştirmek ve etiket yazdırmak.

Çağrı sırası

  1. GET branch/preparation
  2. "Kurye ata": GET branch/dispatch/options?shipmentId=<ilk seçili> → POST branch/dispatch/handover
  3. "Değiştir" (IN_QUEUE): aynı options → POST branch/dispatch/handover/change
  4. Dağıtımdaki (4020) satırda "Kurye değiştir": GET branch/dispatch/reassign?shipmentId= → POST branch/dispatch/reassign
  5. "Etiket yazdır": POST branch/preparation/print-rows → etiketi cihazda çizin
  6. Her yazma işleminden sonra GET branch/preparation

İş kuralları

  • rows: birimdeki 4010 gönderiler (AWAITING_COURIER, IN_QUEUE) + INCOMING (merkezde hazırlanan, yalnız KUVEYT_HGS ürünü, 2010 / 2011, en fazla 300 aday).
  • Atama gönderiyi 4010'da bırakır (IN_QUEUE); zimmet ve 4020'ye geçiş kurye okutarak kabul edince olur (bkz. zimmet kuralları).
  • options: bu birime aktif bağlı, çalışır durumdaki (AVAILABLE / ASSIGNED / WORKING) kuryeler. eligible: kurye bölgesi gönderinin ilçesine uyuyor. ready: false ise atama DISPATCH_NOT_READY ile reddedilir; "Değiştir" modunda web ready'yi yok sayar. Çoklu seçimde ilk gönderinin seçenekleri kullanılır.
  • handover: 1–200 gönderi, tek COURIER_HANDOVER devri; geçersiz UUID'ler elenir, tekrarlar tekilleştirilir.
  • handover/change iki ayrı adımdır (geri al + yeniden zimmetle); ikinci adım başarısız olursa gönderi birimin zimmetinde kalır — yeniden atayın.
  • reassign: REASSIGN devri açar; mevcut kurye listede yoktur; zimmet ve görev yeni kurye okutana kadar eski kuryededir. note 500 karakterde kesilir.
  • print-rows: 1–200 gönderi, hepsi bu birimde olmalı; geçersiz UUID'ler sessizce elenir. ZPL dönmez, alıcı telefonu yoktur. Veri değiştirmez, anahtar istemez.
  • kpis.efficiency = bugün çıkan / (bugün çıkan + birimde bekleyen) yüzdesi; payda 0 ise null.
  • Düğmeler capabilities.operate ile açılır (canManage eski alan, aynı değer).

Hata durumunda

  • 409 (DISPATCH_NOT_READY, HANDOVER_ALREADY_PENDING, HANDOVER_SHIPMENT_WITH_COURIER, MAX_REDELIVERY_COUNT_REACHED, DISPATCH_COURIER_UNAVAILABLE…): error.message'ı ve error.shipmentNumber'ı gösterin, listeyi ve kurye seçeneklerini yenileyin.
  • 404 BRANCH_SHIPMENT_NOT_FOUND / BRANCH_COURIER_NOT_FOUND: gönderi ya da kurye artık bu birimde değil → listeyi yenileyin.
  • 400 DISPATCH_INVALID_INPUT: seçim boş ya da 200'den fazla → seçimi düzeltin.
  • 403: kullanıcının operate yetkisi yok → düğmeyi pasif gösterin.
B12Bugün dağıtılacaklar

Amaç

Birimde bugün dağıtılacak (4010) ve dağıtımdaki (4020) gönderileri öncelikle göstermek; kurye atamak ya da değiştirmek.

Çağrı sırası

  1. GET branch/dispatch
  2. Kurye ata / değiştir diyaloğu B01 ile aynı: dispatch/options → dispatch/handover ya da handover/change; 4020 için dispatch/reassign (GET → POST)
  3. İşlemden sonra GET branch/dispatch

İş kuralları

  • En fazla 500 satır.
  • Öncelik HIGH: Devir (9116 / tekrar çıkış), SLA ihlali ya da 24 saat içinde dolacak SLA. late: SLA ihlali.
  • kpis.overdueHoldings: kuryede alarm eşiğini aşan gönderi sayısı.
  • Düğmeler capabilities.operate ile açılır.

Hata durumunda

  • Atama hataları B01 ile aynıdır. 500 BRANCH_DISPATCH_GET_FAILED: yenile düğmesi sunun.
B14Kurye işleri

Amaç

Tek bir gönderiye odaklanıp uygun kuryeyi seçmek: öneriler, ata, değiştir, iptal ve gönderinin son olayları.

Çağrı sırası

  1. GET branch/courier-jobs?shipmentId=&locale=
  2. detail.actions neyi açıyorsa: ata → POST dispatch/handover (tek gönderi); değiştir → POST dispatch/handover/change (IN_QUEUE) ya da POST dispatch/reassign (IN_DISTRIBUTION); iptal → POST dispatch/handover/cancel (cancelReasons'dan neden seçilir)
  3. GET branch/courier-jobs ile yenileyin

İş kuralları

  • shipments: dağıtım panosu satırları (4010 / 4020). shipmentId yoksa ilk satır seçilir; verilirse bu birimde olmalı.
  • detail.actions: assign (AWAITING_COURIER ve hazır), change (IN_QUEUE → handover/change, IN_DISTRIBUTION → reassign), cancel (IN_QUEUE).
  • suggestions sırası: bölge uyumu (MATCH > PARTIAL > NONE), aktif iş, ETA, ad. activeJobs = 4020 + kabul bekleyen zimmet; ETA hesabı konum bölümünde.
  • cancelReasons: 5110 (teslim edilemedi) neden kataloğu; ad locale'e göre gelir, "DLF-xx - " öneki atılır. Teslim edilemedi nedenleri için ayrı bir uç yoktur.
  • İptal yalnız kabul bekleyen zimmette yapılır; gönderi birimde ve 4010'da kalır, neden audit'e yazılır.
  • recent: gönderi olayları + şube paneli audit kayıtları (en fazla 12).

Hata durumunda

  • 409 HANDOVER_NOT_PENDING (iptal / değiştir): gönderi artık kabul beklemiyor (ör. kurye okuttu, 4020) → yenileyin.
  • 400 CANCEL_REASON_REQUIRED / CANCEL_REASON_INVALID: katalogdan neden seçtirin.
  • 400 DISPATCH_INVALID_INPUT: shipmentId UUID değil. 404 BRANCH_SHIPMENT_NOT_FOUND: gönderi bu birimde değil.
B10Kurye haritası

Amaç

Şube kuryelerini haritada göstermek: son konum, canlı durum ve elindeki gönderiler.

Çağrı sırası

  1. GET branch/courier-map — ekran açıkken periyodik yenileyin

İş kuralları

  • Son 24 saatteki son konum. Durum: ACTIVE ≤10 dk, BREAK 10–60 dk, OFFLINE >60 dk ya da konum yok (eşikler thresholds).
  • Sıralama: canlı durum, elindeki gönderi sayısı (azalan), ad.
  • Gönderide resultMissing: kurye teslim sonucunu girmedi; overdue: alarm eşiği aşıldı.
  • Harita çizimi, kümeleme ve mesafe istemcide yapılır.

Hata durumunda

  • 500 BRANCH_COURIER_MAP_FAILED: son başarılı veriyi göstermeye devam edin, sonraki periyotta tekrar deneyin.
B13Bekleyen işlemler

Amaç

Şubede aksiyon bekleyen işleri listelemek ve kuryeden dönen gönderiyi okutarak teslim almak.

Çağrı sırası

  1. GET branch/pending
  2. Kurye dönüşü okut: POST branch/pending/courier-return-scan (her okutma)
  3. GET branch/pending ile yenileyin

İş kuralları

  • Kuyruklar (her biri en fazla 500): handovers (kuryeye zimmet, kurye okutmadı), returns (kurye iade başlattı, şube okutmadı), endOfDay (sonuç girilmiş, iade başlatılmamış), overdue (alarm eşiğini aşan), approvals (2040 / 2041-2042), matching (2030). approvals / matching öğelerinde courier ve transferNumber null'dır.
  • Okutma: zimmet birime geçer, otomatik yeniden dağıtım denenir (data.redelivery: applied; olmadıysa reason = NOT_WAITING / MANUAL_DECISION_REQUIRED).
  • Gönderi bu birime açık bir kurye iadesinde (COURIER_RETURN) ya da bu birimin kuryesinin zimmetinde olmalı.
  • scanType: AUTO (varsayılan; tanınmayan değer de AUTO) | CARGO_CODE | PARCEL_BARCODE | ITEM_BARCODE (son ikisi aynı barkod çözümleyicisi). scanCode 191, clientEventId 100 karakterde kesilir; clientEventId yalnız audit içindir.

Hata durumunda

  • 400 RETURN_SCAN_REQUIRED: okutma boş → tekrar okutun.
  • 404 RETURN_SCAN_NOT_FOUND / SHIPMENT_NOT_FOUND: barkod tanınmadı ya da gönderi bu birimin kuryesinde değil.
  • 409 RETURN_RESULT_REQUIRED: kurye önce teslim sonucunu girmeli. RETURN_NOT_WITH_COURIER, RETURN_UNIT_REQUIRED, CUSTODY_*: error.message'ı gösterin ("<gönderiNo>: <metin>" biçiminde olabilir; gönderi no ayrıca error.shipmentNumber).
B02/B17Transfer kabul

Amaç

Şubeye gelen transferleri okutup içeri almak ve transferi onaylayarak kapatmak.

Çağrı sırası

  1. GET branch/transfers/incoming
  2. Seç: GET branch/transfers/incoming/{transferId}
  3. Okut: POST branch/transfers/incoming/scan (her okutma)
  4. "İçeri Al": POST branch/transfers/incoming/{transferId}/accept
  5. "Transfer Onayla": POST branch/transfers/incoming/{transferId}/confirm

İş kuralları

  • Liste: depo → birim ve birim → birim transferleri; açık (DISPATCHED, ACCEPTANCE_PENDING) + son 7 günde kapanan (ACCEPTED, PARTIALLY_ACCEPTED, REJECTED); en fazla 100. Kurye devir / dönüşleri burada yoktur; summary yalnız açıkları sayar.
  • Detay satır state: IN, SCANNED, PENDING, MISSING, EXCEPTION.
  • Okutma zorunludur; okutulmayan kalem içeri alınmaz. Okutma sonuçları ve merkez kaynaklı otomatik kabul Transfer okutma bölümünde.
  • Onay, okutulanları içeri alır ve kalanları MISSING (NOT_SCANNED_AT_BRANCH) kapatır.

Hata durumunda

  • 404 SCAN_NOT_IN_INCOMING_TRANSFER: kod gelen transferlerde yok → uyarı gösterin, okutmaya devam edin.
  • 422 SCAN_VALUE_REQUIRED / VALIDATION_FAILED: okutma boş ya da alan hatalı.
  • 409 TRANSFER_NOT_OPEN: transfer kapanmış → listeyi yenileyin. 409 CUSTODY_*: mesajı gösterin.
  • accept yanıtındaki failed[] kalemlerini (200 içinde) kullanıcıya listeleyin.
B03Merkeze transfer

Amaç

Şubedeki gönderileri okutarak merkez depoya transfer oluşturmak ve sevk etmek.

Çağrı sırası

  1. GET branch/transfers/outgoing
  2. Okut: POST branch/transfers/outgoing/resolve (her kod)
  3. Koli etiketi gerekiyorsa: POST branch/labels action=generate → yazdır → action=printed
  4. Gönder: POST branch/transfers/outgoing
  5. GET branch/transfers/outgoing ile yenileyin

İş kuralları

  • Seçenekler: merkez depolar (işleticisi olmayan aktif depolar), transfer türleri, şube depoları, son 20 merkeze transfer.
  • resolve yan etkisizdir; kurallar Transfer okutma bölümünde.
  • Gönderimde gönderi başına bir satır; expectedQuantity = barkod sayısı (en az 1). Tüm satırlar bu birimin zimmetinde (kuryede değil) ve aynı zimmet kaynağında olmalı.
  • Taslağı ve anahtarı cihazda saklayın; ağ kesintisinde aynı anahtarla tekrar gönderin.

Hata durumunda

  • 409 TRANSFER_DISPATCH_FAILED: taslak oluştu ama sevk edilemedi → error.transferNumber'ı gösterin.
  • 409 TRANSFER_MIXED_SOURCE / TRANSFER_ITEM_DUPLICATE: satırları düzeltin.
  • 422 TRANSFER_EMPTY / DESTINATION_NOT_CENTER / TRANSFER_ENDPOINT_SAME: formu düzeltin.
  • Okutmada 404 LABEL_NOT_IN_BRANCH / SHIPMENT_NOT_IN_BRANCH, 409 LABEL_VOID / SHIPMENT_TERMINAL / SHIPMENT_IN_TRANSIT: kodu listeye eklemeyin, nedenini gösterin.
B04Etiket

Amaç

Şube deposu için koli / paket / ürün etiketi üretmek ve Zebra yazıcıdan basmak.

Çağrı sırası

  1. GET branch/labels
  2. POST branch/labels action=generate
  3. ZPL'i yazıcıya gönderin
  4. Baskı başarılıysa POST branch/labels action=printed
  5. Yeniden basım: listedeki ZPL ya da action=reprint

İş kuralları

  • Çalışma alanı: aktif depolar, etiket türleri (CASE, PACKAGE, ITEM), son 30 aktif etiket (ZPL dahil).
  • generate: 1–200 adet; shipmentReference verilirse gönderi bu birimin atamasında ya da zimmetinde olmalı. Tekrarında yeni etiket üretilmez.
  • reprint yan etkisiz; printed basım sayacını artırır ve audit yazar.
  • Yazdırma ayrıntıları Etiket yazdırma (ZPL) bölümünde.

Hata durumunda

  • 404 WAREHOUSE_NOT_IN_BRANCH / SHIPMENT_NOT_IN_BRANCH / LABEL_NOT_IN_BRANCH: seçimi yenileyin.
  • 409 LABEL_OPERATION_REJECTED: error.message (Türkçe) gösterin.
  • Yazıcı hatasında printed çağırmayın; kullanıcı yeniden bassın.
B05Sayım

Amaç

Şube deposunda stok sayımı yapmak: başlat, okut, tamamla, onayla.

Çağrı sırası

  1. GET branch/counts
  2. Başlat: POST branch/counts
  3. GET branch/counts/{countId}
  4. Okut: POST branch/counts/{countId} action=scan (her okutma) / manual / line-reason / void-scan
  5. Tamamla: action=close
  6. Onay: action=post (ya da cancel)

İş kuralları

  • Liste: aktif, stok yönetimli depolar ve son 50 sayım; openCount = DRAFT / IN_PROGRESS / REVIEW durumundaki ilk sayım.
  • Sayım kör değildir: sistem stoğu ile sayılan yan yana görünür.
  • scan, line-reason, close → operate; manual, void-scan, post, cancel → manage. Yönetici düğmeleri capabilities.manage ile açılır.
  • Action ayrıntıları ve clientScanId kuralı Sayım bölümünde.

Hata durumunda

  • 409 / 422 COUNT_OPERATION_REJECTED: durum uygun değil, depoda açık sayım, sayılmamış ürün vb. → error.message.
  • 404 COUNT_NOT_FOUND / WAREHOUSE_NOT_IN_BRANCH: listeyi yenileyin.
  • 403 BRANCH_MANAGE_REQUIRED: işlem yönetici ister.
B15SMS

Amaç

Gönderi alıcılarına ya da kuryelere şablonlu SMS göndermek ve gönderim geçmişini izlemek.

Çağrı sırası

  1. GET branch/sms/templates + GET branch/sms/history
  2. Alıcı: GET branch/sms/targets?type=SHIPMENTS&q= ya da type=COURIERS
  3. POST branch/sms/preview
  4. POST branch/sms/send (aynı gövde)
  5. GET branch/sms/history

İş kuralları

  • Şablonlar: aktif, müşteri / ürün kapsamsız NOTIFICATION / SHIPMENT_WORKFLOW; kod başına kullanıcı diline en uygun ve en yüksek sürüm.
  • Kanal yalnız SMS. Hedef türleri: SHIPMENTS (gönderi id), COURIERS (kurye id), MANUAL (05XXXXXXXXX / +905XXXXXXXXX). En fazla 500 alıcı.
  • SHIPMENTS araması: bu birimin teslim edilmemiş gönderileri, en fazla 100; q gönderi no / takip no / alıcı adında (80 karakter). Telefonlar maskeli (+90 5** *** 12 34).
  • variables: en fazla 20 anahtar (^[A-Za-z_][A-Za-z0-9_]{0,59}$), değer metin / sayı (300 karakterde kesilir); branchName ve recipientName otomatik dolar.
  • Önizleme ilk ulaşılabilir alıcı için metni ve segment sayısını döner; eksik değişkenler missingVariables içinde (rendered: null).
  • Gönderim kuyruğa alınır (202); sağlayıcıya doğrudan istek atılmaz. Ağ geçidi yoksa kayıtlar SKIPPED (SMS_GATEWAY_NOT_CONFIGURED); telefonu olmayan alıcı SKIPPED (RECIPIENT_PHONE_MISSING).
  • Parti kimliği BRANCH_MSG:<providerId>:<anahtar>; tekrar istekte partinin güncel özeti döner (gatewayConfigured: null).
  • Geçmiş: son 400 kayıt; en fazla 30 parti, parti başına 50 alıcı; telefonlar maskeli.

Hata durumunda

  • 422 TEMPLATE_VARIABLES_REQUIRED: error.variables alanlarını kullanıcıdan isteyin.
  • 400 TOO_MANY_TARGETS: error.max (500) sınırını gösterin. 400 PHONE_INVALID: numarayı düzeltin.
  • 422 CHANNEL_NOT_AVAILABLE / TARGET_TYPE_NOT_SUPPORTED: PUSH, BOTH ve CUSTOMER_GROUP desteklenmez.
  • 404 TEMPLATE_NOT_FOUND / TARGET_NOT_FOUND: şablon ya da alıcı listesini yenileyin.
B09Duyurular

Amaç

Şubeye duyuruları ve operasyon uyarılarını göstermek.

Çağrı sırası

  1. GET branch/announcements

İş kuralları

  • schemaReady: false: announcements her zaman boş. Boş durum ekranı gösterin.
  • Gerçek veri operationalAlerts: son 30 günde bu birimin gönderileri için açılan INTERNAL bildirimler (en fazla 50; SLA motoru → category: SLA).
  • Okundu / onay ucu yoktur.

Hata durumunda

  • Yalnız 401 beklenir; genel kurala göre giriş ekranına dönün.
B08Eğitim

Amaç

Şube, kurye ve müşteri süreci eğitimlerini listelemek (model henüz yok).

Çağrı sırası

  1. GET branch/training?targetType= (BRANCH, COURIER, CUSTOMER_PROCESS; boş = tümü)

İş kuralları

  • schemaReady: false; trainings her zaman boş. İlerleme ucu yoktur.
  • targetType büyük / küçük harf duyarsız; yanıtta büyük harfe çevrilmiş değer ya da null.

Hata durumunda

  • 400 TARGET_TYPE_INVALID: error.allowed listesinden seçtirin.
B16Performans

Amaç

Şube ve kurye teslim performansını seçilen aralıkta göstermek.

Çağrı sırası

  1. GET branch/performance?range= (today, 7d, 30d; varsayılan 7d)

İş kuralları

  • Yalnız bu birimin tamamlanmış teslim denemeleri (en fazla 20.000); Türkiye günü (UTC+3). truncated: true ise limit aşıldı.
  • Teslim oranı = denenen tekil gönderilerden teslim edilenler; ilk denemede teslim; ortalama süre startedAt → attemptedAt (>24 saat hariç); SLA = planlı teslimi olanlarda deliveredAt ≤ plannedDeliveryAt.
  • Yüzdeler 1 ondalık, payda 0 ise null (grafikte "—" gösterin). daily en az 7 gün.

Hata durumunda

  • 400 RANGE_INVALID: geçerli aralığa dönün. 500 INTERNAL_ERROR: yenile düğmesi sunun.
B06Fatura mutabakatı

Amaç

Dönem faturalarını göstermek ve fatura için itiraz / talep / geri arama / canlı destek kaydı açmak.

Çağrı sırası

  1. GET branch/invoices?period=YYYY-MM
  2. POST branch/invoices/support
  3. GET branch/invoices ile yenileyin

İş kuralları

  • schemaReady: false: invoices her zaman boş. Gerçek veri supportCases (son 30; period filtresi uygulanmaz). period boşsa içinde bulunulan ay (UTC+3).
  • Talep manage yetkisi ister; INTERNAL destek kaydı açar (SupportTicket, requesterTypeCode=AGENCY).
  • category: DISPUTE, REQUEST, CALL_REQUEST, LIVE_CHAT. DISPUTE için reasonKey zorunlu (büyük harfe çevrilir); DISPUTE ve REQUEST için note en az 5 karakter (en fazla 1000). invoiceId serbest referanstır (100 karakterde kesilir).
  • Fatura onay (approve) ucu yoktur.

Hata durumunda

  • 400 DISPUTE_REASON_REQUIRED / NOTE_REQUIRED / SUPPORT_CATEGORY_INVALID / PERIOD_INVALID: formu düzeltin.
  • 403 BRANCH_MANAGE_REQUIRED: talep düğmesini operatöre pasif gösterin.
B07Sözleşme / evrak / kart

Amaç

Şube sözleşme ve evrak durumunu, kuryelerin belge özetini göstermek; şube / kurye kartı (QR) üretmek ve doğrulamak.

Çağrı sırası

  1. GET branch/compliance
  2. Kart: POST branch/compliance/cards
  3. QR doğrula: POST branch/compliance/cards/verify

İş kuralları

  • schemaReady: false: contracts[] (PARTNERSHIP, KVKK, SLA) ve documents[] (IDENTITY, TAX_PLATE, AUTHORIZATION, SIGNATURE_CIRCULAR, BRANCH_PHOTO) her kalemde NOT_AVAILABLE. Gerçek veri: şubeye aktif bağlı kuryelerin belge ve onay özeti (operationReady).
  • Kart: HMAC imzalı belirteç JDC1.<payload>.<imza> + QR (card.qrSvg, satır içi SVG); 365 gün geçerli; aynı gün aynı sahip için aynı belirteç. Kalıcı kart / iptal / yenileme kaydı yoktur.
  • Yetki: ownerType=COURIER → operate, ownerType=BRANCH → manage. BRANCH için ownerId oturumdaki şube id'si olmalı.
  • Doğrulama: imza, süre ve sahibin canlı durumu (şube ACTIVE; kurye şubeye aktif bağlı ve uygun durumda). Yalnız kendi şubesinin kartı. token 2000 karakterde kesilir. Audit yazar, durum değiştirmez; anahtar istemez.

Hata durumunda

  • Doğrulamada imza geçersizse hata değil: 200 + valid: false, reason: SIGNATURE_INVALID → "geçersiz kart" gösterin.
  • 404 CARD_NOT_FOUND: başka şube / tenant kartı. 404 CARD_OWNER_NOT_FOUND, 409 CARD_OWNER_INACTIVE: sahibi kontrol edin.
  • 503 CARD_SIGNING_NOT_CONFIGURED: sunucuda imza anahtarı yok → JetDiji ekibine bildirin.
KuryelerŞube kuryeleri

Amaç

Şubeye bağlı kuryeleri listelemek.

Çağrı sırası

  1. GET agency/couriers

İş kuralları

  • Şubeye ACTIVE ve geçerlilik aralığında bağlı kurye atamaları; birincil önce, sonra ada göre.
  • shipmentCount: kuryedeki 40xx durumlu gönderi sayısı. Telefonlar maskesiz döner (kurye telefonu).
  • İsteğe bağlı özet kartı için GET agency/overview kullanılabilir; web şube paneli bunu kullanmıyor (eski acente portalı kullanıyor).

Hata durumunda

  • 500 AGENCY_COURIERS_LOAD_FAILED: yenile düğmesi sunun.
BölgelerHizmet bölgeleri

Amaç

Şubenin hizmet verdiği il / ilçe / mahalleleri göstermek.

Çağrı sırası

  1. GET agency/regions

İş kuralları

  • ACTIVE ve geçerli bölge kapsamaları; il / ilçe / mahalle adları tekilleştirilmiş özet.

Hata durumunda

  • 500 AGENCY_REGIONS_LOAD_FAILED: yenile düğmesi sunun.
DepolarŞube depoları

Amaç

Şubenin depolarını listelemek.

Çağrı sırası

  1. GET agency/warehouses

İş kuralları

  • Şubenin işleticisi ya da sahibi olduğu, arşivlenmemiş depolar.

Hata durumunda

  • 404 AGENCY_NOT_FOUND: yeniden giriş. 500 AGENCY_WAREHOUSES_LOAD_FAILED: yenile düğmesi sunun.

7. Kavramlar

Gönderi durum kodları

currentStatusCode sayısal metindir. Şube uçlarında kullanılanlar:

KodAnlamŞubede nerede
2010 / 2011Hazırlıkta / Gönderi hazırlanıyorB01 "şubeye gelecek" (stage=INCOMING, yalnız KUVEYT_HGS ürünü)
2030Hazırlıkta / Eşleme bekliyorB13 matching
2040 (alt 2041 / 2042)Onay kuyruğuB13 approvals
3020 / alt 3022Transferde / Merkeze transferdeB11 returnToCenter
4010Teslimat şubesinde / planlıB01, B12, B14 (AWAITING_COURIER, IN_QUEUE)
4020 (alt 4021 dağıtıma çıktı, 4022 teslimat işleminde)DağıtımdaB12, B14 (IN_DISTRIBUTION)
5010 / 5020Teslim edildi / Teslim edildi (evrak)B11 deliveredToday
5110Teslim edilemediİptal nedeni kataloğu (courier-jobs.cancelReasons) bu durumun nedenleridir
7010 / 7030İade bekliyor / İade edilecekB11 returnToCenter
8010 / 8030İptal / Operasyon kaynaklı iptalB11 cancelledToday

Aşama (stage)

  • INCOMING: merkezde hazırlanıyor, bu şubeye gelecek.
  • AWAITING_COURIER: 4010, kurye yok.
  • IN_QUEUE: 4010, kuryeye zimmetlendi, kurye henüz okutmadı.
  • IN_DISTRIBUTION: 4020, dağıtımda.

Neden kodları

  • 9117 Normal ilk çıkış.
  • 9116 Devir: alıcıya ulaşılamayınca tekrar çıkış. Öncelik HIGH.
  • Teslim edilemedi (5110) nedenleri ayrı bir uçta değil, GET branch/courier-jobs yanıtındaki cancelReasons[] içinde gelir.

Zimmet kuralları

  • Okutarak kabul: kurye ataması (dispatch/handover) gönderiyi 4010'da bırakır (stage=IN_QUEUE). Zimmet ve 4020'ye geçiş yalnız kurye kendi uygulamasında okutarak kabul ettiğinde olur.
  • Kurye değişimi: dağıtımdaki gönderide reassign REASSIGN devri açar; yeni kurye okutana kadar zimmet eski kuryededir.
  • Gün sonu: kurye gönderiyi elinde tutabilir; gün sonu iadesi şubede okutularak alınır (pending/courier-return-scan). Kabulde otomatik yeniden dağıtım denenir (redelivery).
  • Kuryede bekleme alarmı: varsayılan 24 saat; şube bazında 1–336 saat arası ayarlanabilir (Provider.configuration.courierHoldingAlertHours). Yanıtlarda alertHours / holdingAlertHours olarak gelir; overdue bayrakları bu eşiğe göredir.

8. Roller (operate / manage)

Şube tek bir yetki modeli kullanır (src/modules/agency-portal/branch-permissions.ts). Roller iki yeteneğe çevrilir:

YetenekAnlamıSahip olanlar
operateGünlük operasyon: dağıtım, devir, transfer kabul, etiket, sayım okutma, SMS gönderimi…AGENCY_ADMIN, AGENCY_OPERATOR ve sistem sahibi
manageYönetim / onay / mali: sayım manuel giriş, okutma iptali, onay, iptal; fatura destek; şube kartıAGENCY_ADMIN ve sistem sahibi
okumaGET'ler ve yan etkisiz POST'larOturumlu her şube kullanıcısı (diğer roller yalnız okur)
  • Sistem sahibi = oturumda isSystemOwner: true ya da rol kodu SYSTEM_OWNER. Şube rolü olmadan girişte şube seçerek bağlanabilir.
  • Düğmeler: GET agency-auth/session → user.capabilities: { operate, manage }. Aynı nesne preparation, dispatch, courier-jobs, counts, counts/{id} yanıtlarında capabilities olarak da gelir.
  • Eski canManage alanı korunur: preparation / dispatch / courier-jobs → capabilities.operate; counts / counts/{id} → capabilities.manage. Mobilde capabilities kullanın.
  • Yetkisiz kullanıcıya yazma düğmelerini pasif ve ipuçlu gösterin; yine de her yazma ucunda 403'ü ele alın.
  • Yetki hatası her uçta tektir: 403 FORBIDDEN, error.reason = BRANCH_OPERATE_REQUIRED ("Bu işlem şube operasyon yetkisi gerektirir.") ya da BRANCH_MANAGE_REQUIRED ("Bu işlem şube yöneticisi yetkisi gerektirir."). Eski BRANCH_FORBIDDEN kodu ve eski reason değerleri (BRANCH_DISPATCH_ROLE_REQUIRED, COUNT_PERMISSION_REQUIRED) artık dönmez.

Uç → yetki tablosu

UçGereken yetenek
dispatch/handover, handover/change, handover/cancel, dispatch/reassign (POST)operate
pending/courier-return-scanoperate
transfers/incoming/scan, transfers/incoming/{id}/accept, transfers/incoming/{id}/confirmoperate
transfers/outgoing (POST)operate
labels (POST: generate, reprint, printed)operate
counts (POST, sayım başlat)operate
counts/{id} (POST) action = scan, line-reason, closeoperate
counts/{id} (POST) action = manual, void-scan, post, cancelmanage
sms/sendoperate
preparation/print-rowsoperate
compliance/cards ownerType=COURIERoperate
compliance/cards ownerType=BRANCHmanage
invoices/supportmanage
Yan etkisiz POST'lar (transfers/outgoing/resolve, sms/preview, compliance/cards/verify) ve tüm GET'leroturum yeterli

9. Etiket yazdırma (ZPL)

  • branch/labels uçları her etikette hazır ZPL (zpl) döner: 100×100 mm, 203 dpi (^PW800 ^LL800), ^CI28 (UTF-8). QR yazıcıda üretilir (^BQ).
  • Alıcı adı ve telefonu etikete asla basılmaz; yanıtta da yer almaz.
  1. POST branch/labels { action: "generate", labelTypeCode, quantity, warehouseId, shipmentReference? }
  2. ZPL'i Zebra yazıcıya gönderin: Bluetooth (Zebra Link-OS SDK / BLE SPP) ya da ağ üzerinden TCP 9100 portuna ham ZPL. Birden çok etiketi \n ile birleştirip tek seferde yollayabilirsiniz (web de böyle yapar).
  3. Baskı başarılı olunca POST branch/labels { action: "printed", labelIds, printer: "<cihaz adı>" } (sayaç + audit). Web, Zebra yoksa printer: "BROWSER" gönderir.
  • Zebra yoksa web etiketi istemcide HTML olarak çizip tarayıcıdan yazdırır (label-html); HTML üreten bir API ucu yoktur. Mobilde ZPL kullanamıyorsanız aynı alanlardan (barkod, tür, paket i/n, gönderi no, depo, tarih) yerel bir PDF / görsel üretin.
  • B01 "Etiket yazdır" (preparation/print-rows) ZPL döndürmez; gönderi satırı verir, etiket istemcide çizilir (alıcı telefonu bu sorguda da yoktur).

10. Sayım

Tüm işlemler POST branch/counts/{countId} üzerinden, gövdedeki action ile yapılır.

actionYetkiNe yaparYanıt data
scanoperateBarkod okut (ana yöntem, adet 1). Alanlar: clientScanId, barcode, isteğe bağlı deviceTypeCode, isDamaged, containerId, sealIntact.ScanResult
manualmanageManuel adet; quantity + reasonNote (3–500) zorunlu; aynı işlemde audit yazılır.ScanResult
void-scanmanageOkutmayı iptal (scanId, reason).{ result: null, replayed }
line-reasonoperateFark nedeni (yalnız kapatılmış satır): MISCOUNT, DAMAGE, LOSS, RECORD_ERROR, FOUND, RETURN_PENDING, OTHER.{ result: null, replayed }
closeoperate"Sayımı Tamamla" (REVIEW). uncountedAsZero: false iken sayılmamış ürün varsa 409.{ result: null, replayed }
postmanageOnay: POSTED, stok hareketleri oluşur.{ movementCount, replayed }
cancelmanageSayımı iptal (reason zorunlu).{ result: null, replayed }
  • clientScanId (1–60, [A-Za-z0-9_-]) sayım servisinde ayrı bir tekrar korumasıdır: aynı id adedi ikinci kez eklemez. Web bunu çevrimdışı kuyrukla, Idempotency-Key = clientScanId olacak şekilde gönderir; UUID her iki kurala da uyar.
  • data.replayed yalnız Idempotency-Key tekrarını gösterir. clientScanId tekrarında (yeni anahtarla) adet eklenmez ama data.replayed: false döner.
  • Yetki kontrolü gövde doğrulandıktan ve sayım bulunduktan sonra yapılır.
  • Başlatma (POST branch/counts): warehouseId, countTypeCode (FULL, CYCLE, SPOT; varsayılan FULL), note. Sayım kör değildir (blind: false, detayda expectedHidden: false); audit inventory.count.started.
  • Detay (GET branch/counts/{countId}): başlık, özet, satırlar (sistem stoğu / sayılan / fark), koli durumları, seri farkları, son okutmalar, kullanıcı adları. Alt nesneler admin sayım modülüyle aynı çıktıdır (getStockCountDetail).

11. Transfer okutma

Gelen transfer (B02/B17)

DurumactioneventCodeSonraki adım
Merkez kaynaklı transfer (centerSource: true: tenant zimmeti ya da işleticisi olmayan depo)AUTO_INTAKEintake.autoKalem doğrudan kabul edildi.
Diğer kaynaklarSCANNEDtransfer.scan.accepted"İçeri Al" (accept) gerekir.
Kalem zaten içeri alınmışALREADY_INTAKENtransfer.scan.duplicateYok (200 döner).
  • scanType (CARGO_CODE | PARCEL_BARCODE | ITEM_BARCODE) yalnız önceliktir: önce kalemin okutma kodu (ITEM_BARCODE'da seri no da) aranır, sonra gönderi no / takip no / etiket / koli barkodu tüm yollarla çözülür.
  • transferId verilirse arama o transferle sınırlanır. clientEventId (1–80) zorunlu alandır ama yalnız audit içindir; deviceId isteğe bağlıdır.
  • accept (eventCode: "transfer.accept"): okutulmuş ve bekleyen kalemleri kabul eder; kalem hataları failed[] içinde (200). Yeni anahtarla tekrar çağrı kabul edilmiş kalemleri atlar (accepted: 0).
  • confirm (eventCode: "transfer.accepted"): okutulanları içeri alır, kalanları MISSING (NOT_SCANNED_AT_BRANCH) kapatır; transfer ACCEPTED / PARTIALLY_ACCEPTED olur. İsteğe bağlı note (500).

Merkeze transfer (B03)

  • resolve: gönderiye bağlı olmayan, şube deposundaki koli / paket etiketi → kind: PACKAGE (transferin ambalaj barkodu, gövdede packageBarcodes). Aksi halde gönderi çözümlenir → kind: SHIPMENT (bu birimin zimmetinde, terminal değil, açık devirde değil).
  • scanType=CARGO_CODE kargo koduyla, diğerleri AUTO çözümleyiciyle aranır.
  • Gönderim: transferType (RETURN, EQUIPMENT, PHYSICAL_DOCUMENT, CARD_RETURN, BRANCH_TRANSFER, OTHER), destinationWarehouseId (centers[].id), lines (1–500; her satır shipmentId + en fazla 200 barcodes), packageBarcodes (en fazla 200), note (300).
  • Taslak + satırlar + sevk tek istekte yapılır; sevk başarısızsa taslak kalır (409 TRANSFER_DISPATCH_FAILED). Başarıda eventCode: "transfer.dispatched".
  • Gönderiye bağlı olmayan ekipman / evrak satırı eklenemez (her satır bir shipmentId ister).

12. Dosya, konum ve harita

Dosya

Şube uçlarında multipart yükleme ve dosya indirme ucu yoktur. Kart QR'ı yanıtta satır içi SVG (card.qrSvg), etiketler ZPL metni olarak gelir.

Konum ve harita

  • Şube uygulaması konum göndermez. Kurye konumu kurye uygulamasının görev konum ucundan gelir.
  • courier-map / dashboard son 24 saatteki son konumu döner. Canlı durum son konum yaşından türetilir: ACTIVE ≤10 dk, BREAK 10–60 dk, OFFLINE >60 dk ya da konum yok (eşikler thresholds).
  • Harita çizimi, kümeleme ve mesafe gösterimi istemcide yapılır.
  • Kurye önerilerindeki etaMinutes sunucuda kuş uçuşu mesafe / 20 km/sa + 5 dk ile hesaplanır; konum 180 dakikadan eskiyse null.

13. Boş dönen modüller

Bu modüllerin şeması henüz yok. Uçlar schemaReady: false döner ve sahte veri üretmez; uygulamada boş durum ekranı gösterin.

EkranBoş alanGerçek veri
B09 DuyurularannouncementsoperationalAlerts
B08 Eğitimtrainings—
B06 FaturainvoicessupportCases
B07 Sözleşme / evrakcontracts[], documents[] (her kalem NOT_AVAILABLE)Kurye belge / onay özeti

Olmayan işlemler

  • SMS: kanal yalnız SMS (PUSH, BOTH → 422 CHANNEL_NOT_AVAILABLE); hedef CUSTOMER_GROUP → 422 TARGET_TYPE_NOT_SUPPORTED. Ağ geçidi yoksa kayıtlar SKIPPED (SMS_GATEWAY_NOT_CONFIGURED).
  • Fatura onayı (approve) yok.
  • Şube kartı iptal / yenileme kaydı yok (kart imzalı belirteçtir, 365 gün geçerli).
  • Merkeze transferde gönderiye bağlı olmayan ekipman / evrak satırı eklenemez.
  • Duyuru okundu / onay ve eğitim ilerleme uçları yok.
  • Şifre değiştirme ve token yenileme uçları yok.