Masa Kalemleri — POST /plugin-api/tables/update-orders ✓ Canlı

Dine-in masanın TÜM kalemlerini değiştirir — FULL REPLACE (packets/update-orders'ın masa karşılığı). total kuver dahil yeniden hesaplanır; fiyatlar Restomenum ürün kaydından (normal satış fiyatı). Hiçbir uç masayı KAPATMAZ.

← API Uçları · Masa açmak: tables/create · Masa ödemeleri: tables/update-payments · Paket karşılığı: packets/update-orders.

İstek

POST {RESTOMENUM_BASE}/plugin-api/tables/update-orders
Authorization: Bearer <apiKey>

{
  "tableId": "tbl-7a3f...",                       // ZORUNLU — açık masanın doc id'si
  "cart": [                                        // ZORUNLU — masanın YENİ kalem listesi (FULL REPLACE)
    { "product": "<productId>", "quantity": 2, "options": [{ "id": "1693060234600" }], "discount": 0, "note": "",
      "taxRate": 7,                                // ops (0..100) — satırın KDV oranı; ürünün oranını EZER
      "lineId": "qr-9f2c",                         // ops — kimlik; HER istekte yeniden beyan et (yoksa satır+metadata düşer)
      "metadata": [ { "key": "seat", "value": "2" } ] }   // ops — DİZİ (map değil)
  ]
}
  • Scope: orders:write · write rate-limit.
  • cart masanın tüm kalemlerini değiştirir (merge değil). Kalem: { product(id ≤128), quantity(0.001..9999), options?(≤50 beyan: { id } | { title } | düz string; fiyat beyan edilemez), discount?(≥0), note?(≤500), taxRate?(0..100), lineId?, metadata? }.
  • lineId (ops.): full-replace'te satır kimliğini korumanın tek yolu. Kurallar + metadata: Satır kimliği & metadata.
  • taxRate (ops., 0–100): satırın KDV oranı — verilirse ürünün oranını ezer ve satırda dondurulur, verilmezse ürünün oranı kullanılır. Geçersiz değer → 400 (Invalid taxRate (0-100 expected): <id>), sessizce ürüne düşmez. Beyanı yapan eklenti satırda taxRateBy ile kaydedilir — bu iç denetim izidir, hiçbir okuma yanıtında dönmez (teyitli). Kaynak: mali fişleme (fiscal.de).
  • Kuver masa ayarından yeniden uygulanır; total sunucuda hesaplanır.
  • tableId: açık masanın doc id'si — tables/open veya tables/get?id='ten al; table.close gate'inde gelen target.id de budur.

Yanıt

{ "success": true, "data": { "tableId": "tbl-7a3f...", "total": 268 } }   // total kuver DAHİL

Masa-özgü davranışlar (ZORUNLU bilgi)

  • Fiyat otoritesi: kalem fiyatları Restomenum ürün kaydından; gönderilen fiyat yok sayılır. Dine-in'de normal satış fiyatı kullanılır (web/delivery fiyatı DEĞİL).
  • Kuver: masanın kuver oranı + kişi sayısına göre kuver satırı otomatik eklenir; total bunu içerir. Plugin kuver göndermez/hesaplamaz.
  • Timer (süre-bazlı) ürünler desteklenmez: açık-büfe/saat-bazlı ürünü olan masada kalem değişimi reddedilir (full-replace süre sayacını sıfırlardı).
⏳ Sepette olmayan satır artık İZ BIRAKIYOR. Bu uç tam değiştirme (PUT) yapar; eskiden gönderilmeyen satır orders[]'dan sessizce düşer ve cancels[]'a hiçbir kayıt yazılmazdı — kayda girmiş bir pozisyonun izsiz kaybolması mali değişmezlik (Unveränderbarkeit) ile bağdaşmıyordu. Artık düşen satır için void kaydı yazılır: cancels[]'a girer, lineChanges'te cancelled olarak gelir ve plugin:<pluginId> aktör damgası taşır. Kuver satırı türev olduğu için dışlanır. İstek reddedilmez (meşru satır silme de bu yola düşer) — davranışın kendisi değişmedi, artık izlenebilir.

Kurallar & hatalar

Durummessage
cart'ta var olmayan ürünProduct not found: <id,...> (400)
Satırın taxRate'i 0–100 dışında/geçersizInvalid taxRate (0-100 expected): <id> (400)
lineId biçim ihlali / rezerve / istekte tekrarInvalid lineId: <id> · Duplicate lineId: <id> (400)
İptal edilmiş (void) satırın kimliği yeniden beyan edildilineId belongs to a cancelled line (409)
metadata düz map gönderildi (dizi bekleniyor)metadata must be an array of {key, value} (400)
Geçersiz key/değer, aynı yazarın tekrar eden anahtarı ya da yazar bütçesi (10 öğe / 256 karakter) aşımıInvalid metadata: <ürün>: <sebep> (400)
İstek başına 20 KB ya da belge geneli 100 KB bütçe aşımıTotal metadata size after merge … (yours: X, other plugins: Y) (400)
Gelen cart timer ürünü içeriyorTimer-priced products are not supported via plugin (time-dependent total) (400)
Mevcut masada timer ürünü varTable has timer-priced items; plugin order edit not allowed (400)
Yeni total mevcut ödemenin altındaPaid (X) exceeds new total (Y). Update payments first. (400)
Hesaplanan total negatifComputed total is negative — check discounts (400)
Masa yok / kapanmışTable not found (404)
Hata sırası: ürün bulunamadıysa oran kontrolüne bakılmaz (Product not found: …); aynı istekte birden çok satırın oranı geçersizse hepsi tek mesajda listelenir.
tables koleksiyonu yalnız açık masaları tutar — kapanan masa silinir,tables/update-* 404 döner. Ödemeleri önce düşürmek için tables/update-payments. Masa kapalıysa önce tables/create ile açın (bu uç masa açmaz).

cart[] — satır kimliği (lineId) & metadata

İki alan da opsiyoneldir; hiçbiri gönderilmezse davranış bugünküyle aynıdır (mevcut eklentiler etkilenmez). Tam kurallar: Satır Kimliği & metadata.

AlanTipZorunluAçıklama
cart[].lineIdstring–Kararlı satır kimliği — çağıran taşır, platform korur. 8–64 karakter (⏳ alt sınır 1 → 8'e çıktı), alfanümerik başlar, A-Z a-z 0-9 . _ : - içerir — ⚠️ noktalama yalnız İÇERİDE (pay_01H9ABCD geçer; _pay01H9ABCD ve -pay01H9ABCD 400); saf rakamdan oluşan kimlik reddedilir ("1", "42" → 400). kuver ve new rezervedir (büyük/küçük harf farketmez) → 400 Invalid lineId: kuver. Aynı istekteki liste içinde tekrar edemez → 400 Duplicate lineId: <id>; iptal edilmiş (void) bir satırın kimliğini yeniden beyan etmek → 409 lineId belongs to a cancelled line. Gönderilmeyen satıra platform üretir ve üretilen kimlikler beyan edilenlerle çakışmaz. ⚠️ Kimlik korunması koşulludur: her istekte yeniden beyan edilmelidir (aşağı bkz.).
cart[].metadataarray–Opak korelasyon alanı — { key, value } dizisi (düz map değil; map gönderen istek 400 metadata must be an array of {key, value} alır). Platform yorumlamaz: saklar ve okuma yanıtında yazar damgasıyla (by) döner. key alfanümerik başlar, A-Za-z0-9_-, ≤64; value string | number | boolean (iç içe obje / dizi / null → 400). Bütçeler: yazar başına ≤10 öğe / satır ve value ≤256 karakter, istek başına ≤20 KB (sepet ve ödeme ayrı), belge geneli birleşme sonrası ≤100 KB.
⏳ Grandfather — PLANLANAN davranış, bugün ETKİN DEĞİL. Af mantığı platformda yazılı ama şema katmanı isteği daha transaction'a girmeden reddettiği için ona ulaşılmıyor — dört yazma ucunun hepsinde ölçüldü. Bugün dokümanda zaten var olan zayıf bir kimlik de 400 alır. Ayrıntı: Satır kimliği → Grandfather. Aşağıdaki akış tasarlanan davranıştır:

Tam-sepet değiştirmede önceki yanıtta aldığın kimlikleri geri gönderirsin; kural konmadan önce yazılmış zayıf bir kimlik dokümanda duruyorsa onu reddetmek ilgisiz satırlar dahil tüm isteğini düşürür ve dokümanı kalıcı kilitlerdi. Bu yüzden:
1️⃣ Biçim geçersizse her zaman 400 — asla affedilmez.
2️⃣ Biçim geçerli ama zayıfsa (<8 karakter ya da saf rakam): kimlik dokümanda zaten varsa kabul edilir (grandfather), yoksa 400 (yeni zayıf beyan).
Kontrol transaction içinde, doküman zaten okunurken yapılır — ek okuma maliyeti yok.
⚠️ packets/create ve tables/create uçlarında grandfather YOKTUR: yeni satış açarlar, karşılaştırılacak mevcut doküman yoktur → her zayıf kimlik yeni beyandır ve 400 alır.
Öneri: anahtarını çifte çevir. Kural bir kalkan; yapısal çözüm (uuid, lineId) çiftini anahtar yapmaktır. uuid (kalıcı satış kimliği) artık her olayda geliyor ve satış bazında kesin ayrık — çift, bu hata sınıfını kuralın da ötesinde kapatır.
Altın kural: kimliği HER istekte yeniden beyan et. Bu uç tam değiştirme yapar — platform yalnız gelen listedeki kimlikleri dokümandakilerle eşler. Beyan edilmeyen satır "silinmiş" sayılır ve üzerindeki tüm metadata (başka eklentilerin yazdıkları dahil) onunla birlikte gider. İstek reddedilmez (meşru satır silme de bu yola düşer) ama platform kaybı loglar. Kimliği kendi kaydından türet ve kendi tarafında sakla — doğru/yanlış örneği.
metadata'ya PII yazmayın (ad, telefon, e-posta, adres, kart): sözleşme gereği yasaktır. Platform bu alanda desen taraması yapmaz — yanlış pozitif meşru bir mali kaydı reddedip satışı durdururdu; kural sözleşme düzeyindedir, ihlal eklentinin sorumluluğundadır. Müşteri verisi customers:read + rıza üzerinden alınır.
Görünürlük: alan tenant içi korelasyon verisidir (kiosk yazar, fiskal sağlayıcı okur) → her kanalda orders:read yeterlidir, müşteri-PII rızası gerekmez ve alan push gövdelerinden silinmez. note, paymentNote ve iptal reason bu kapsamda değildir — onlar gerçek kullanıcı girdisi taşır ve rıza kapısına tabi olmaya devam eder.