ข้ามไปที่เนื้อหา

Warranty & Claims — กระบวนการทำงาน (Process flows)

สถาปัตยกรรมและวงจรชีวิตถูกสร้างอัตโนมัติจากโค้ด (dispatch, สถานะ enum ใน CHECK, การเขียน SET status) ส่วน sequence และหมายเหตุเขียนขึ้นเอง

สถาปัตยกรรม

%%{init: {"theme":"base","themeVariables":{"darkMode":true,"background":"#1e1e1e","primaryColor":"#2d2d30","primaryBorderColor":"#569cd6","primaryTextColor":"#d4d4d4","lineColor":"#6796c6","secondaryColor":"#3a3d41","secondaryBorderColor":"#dcdcaa","tertiaryColor":"#252526","tertiaryBorderColor":"#569cd6","clusterBkg":"#252526","clusterBorder":"#569cd6","titleColor":"#569cd6","noteBkgColor":"#3a3d41","noteTextColor":"#dcdcaa"},"flowchart":{"useMaxWidth":false},"state":{"useMaxWidth":false}}}%%
flowchart LR
  C["Client"] --> A["Pages Fn claims<br/>bolt_session auth · company_id scope"]
  A --> D["dispatch<br/>register_warranty · transfer_warranty · warranty_transfer · claim_intake · rma_quarantine · restock_refurb · claim_disposition · rma_disposition …"]
  D --> K["Kernel<br/>erp_document + journal<br/>atomic GL / stock"]
  K --> DB[("D1 tables")]
  D --> DB
  D --> EV["events<br/>append audit trail"]
  EV --> DB
  DB -.-> T["claims_warranty_registration<br/>claims_warranty_transfer<br/>claims_warranty_case<br/>claims_warranty_claim_line<br/>claims_warranty_entitlement_check<br/>claims_warranty_rma_stock_movement<br/>claims_warranty_triage_decision<br/>claims_warranty_repair_order"]

วงจรชีวิต (Lifecycle)

วงจรชีวิตของเอกสาร Kernel (erp_document.docstatus)

เอกสารทุกฉบับในโมดูลนี้ที่ขยับเงินหรือสต็อกจะถูกโพสต์ผ่าน kernel ที่ใช้ร่วมกัน โดยเดินตาม docstatus ที่กำหนดไว้ตายตัว:

%%{init: {"theme":"base","themeVariables":{"darkMode":true,"background":"#1e1e1e","primaryColor":"#2d2d30","primaryBorderColor":"#569cd6","primaryTextColor":"#d4d4d4","lineColor":"#6796c6","secondaryColor":"#3a3d41","secondaryBorderColor":"#dcdcaa","tertiaryColor":"#252526","tertiaryBorderColor":"#569cd6","clusterBkg":"#252526","clusterBorder":"#569cd6","titleColor":"#569cd6","noteBkgColor":"#3a3d41","noteTextColor":"#dcdcaa"},"flowchart":{"useMaxWidth":false},"state":{"useMaxWidth":false}}}%%
stateDiagram-v2
  [*] --> Draft: createDocument (docstatus 0)
  Draft --> Submitted: submitDocument (docstatus 1, journal posted)
  Submitted --> Cancelled: cancelDocument (docstatus 2, reversed)
  Submitted --> [*]
  Cancelled --> [*]

claims_warranty_case.status

สถานะ: draft (เริ่มต้น) · accepted · rejected · triaged · in_repair · resolved · closed

สถานะ ตั้งค่าโดย (grep จาก SET status='…')
triaged triageClaim
in_repair startRepair, resolveClaim

claims_warranty_case.operational_status

สถานะ: draft (เริ่มต้น) · triaged · in_repair · resolved · closed · rejected

claims_warranty_claim_line.entitlement_status

สถานะ: in_warranty (เริ่มต้น) · out_of_warranty · unregistered · void · goodwill

claims_warranty_claim_line.line_status

สถานะ: accepted (เริ่มต้น) · rejected · goods_in · triaged · in_repair · in_replacement · in_refund · resolved · closed

สถานะ ตั้งค่าโดย (grep จาก SET line_status='…')
triaged triageClaim
in_repair startRepair

claims_warranty_registration.status

สถานะ: provisional (เริ่มต้น) · active · voided · superseded

Flow สำคัญ: การเปลี่ยนสินค้าตามการรับประกัน (resolve_claim, kind=replace)

เส้นทางที่แตะเงินมากที่สุด: รายการที่ยังอยู่ในประกัน (in-warranty) ถูกปิดด้วยการจ่ายสินค้าชิ้นใหม่ให้แทน เมื่อสินค้าคงคลังถูกตัดออกอย่างถาวร kernel จึงโพสต์ทั้งการตัดสต็อก (stock-out) และ รายการ GL ที่หักล้างกันแบบ atomic โดยมีคีย์กำกับเพื่อให้ replay ได้แบบ idempotent

%%{init: {"theme":"base","themeVariables":{"darkMode":true,"background":"#1e1e1e","primaryColor":"#2d2d30","primaryBorderColor":"#569cd6","primaryTextColor":"#d4d4d4","lineColor":"#6796c6","secondaryColor":"#3a3d41","secondaryBorderColor":"#dcdcaa","secondaryTextColor":"#d4d4d4","tertiaryColor":"#252526","tertiaryBorderColor":"#569cd6","noteBkgColor":"#3a3d41","noteTextColor":"#dcdcaa","clusterBkg":"#252526","clusterBorder":"#569cd6","titleColor":"#569cd6","actorBkg":"#2d2d30","actorBorder":"#569cd6","actorTextColor":"#d4d4d4","signalColor":"#9cdcfe","signalTextColor":"#d4d4d4","noteBkgColor":"#3a3d41","labelBoxBkgColor":"#3a3d41","labelBoxBorderColor":"#dcdcaa"},"flowchart":{"useMaxWidth":false},"sequence":{"useMaxWidth":false},"state":{"useMaxWidth":false},"er":{"useMaxWidth":false}}}%%
sequenceDiagram
  participant C as Client
  participant FN as claims Fn
  participant DB as D1 claims tables
  participant K as kernel
  participant L as stock ledger + GL

  C->>FN: POST action=resolve_claim, kind=replace
  FN->>FN: getIdentityAsync -> company + cap
  FN->>DB: SELECT claim_line + case
  FN->>DB: prior resolution (line, replace)?
  Note over FN,DB: exists -> return idempotent, no re-post
  FN->>L: currentAvgCost(variant, from_location)
  Note over FN: replaceValue = qty * avg cost
  FN->>K: createDocument(STOCK)<br/>stock -qty + Dr warranty_claim_expense / Cr inventory
  K->>L: post stock-out + GL (amount_from_stock)
  FN->>K: submitDocument(idempotency_key claims-resolve:line:replace)
  K-->>FN: document id
  FN->>DB: INSERT replacement_order (state closed, carryover)
  FN->>DB: UPDATE line + case -> closed
  FN->>DB: appendEvent claims.resolution.completed
  FN-->>C: { ok, resolution }

หมายเหตุ

  • จุดประสงค์: จัดการ warranty แบบผูก serial ตั้งแต่ลงทะเบียน (register_warranty) โอนสิทธิ์ (transfer_warranty) รับเคลม (claim_intake) กัก RMA (rma_quarantine) จนถึงปิดเคส (resolve_claim) และเคลมคืน supplier (supplier_claim_back) — ทั้งหมด company-scoped ผ่าน getIdentityAsync.
  • Entitlement เป็น gate จริง: claim_intake ตัดสินจากกฎ claim_date <= warranty_expiry เทียบ registration ล่าสุดของ serial; ผ่าน = case accepted, ไม่ผ่าน = case+line rejected แล้ว throw 422 พร้อม snapshot ลง erp_claims_warranty_entitlement_check. triage_claim บล็อกเคสไม่มีสิทธิ์เว้นแต่ decision = reject.
  • Money-safety (subledger == GL): ทุกการขยับ stock ที่มีมูลค่าไปผ่าน kernel createDocument/submitDocument เท่านั้น. rma_quarantine เป็น transfer value-neutral (in-cost = currentAvgCost ของ source, ไม่มี journal). restock_refurb clamp inbound cost ไม่ให้เกิน carrying (write down ได้อย่างเดียว) แล้วโพสต์ส่วนต่าง Dr warranty_claim_expense / Cr inventory. scrap และ replace relieve inventory จริงพร้อม writeoff/expense offset.
  • Idempotency: resolve_claim มี re-resolution guard ด้วย UNIQUE (claim_line, kind) (retry คืนของเดิม); replace/refund/credit ยังฝัง deterministic idempotency_key (claims-resolve:<line>:<kind>) ให้ kernel replay โพสต์เดิมแทน double-post; restock_refurb เช็ค operation_group ซ้ำก่อน move.
  • Location invariants: hold ต้องเป็น quality_hold/claim_cage; restock source = hold location ที่บันทึกตอน quarantine และปลายทางต้องเป็น sellable (site/warehouse/zone/bin); scrap ต้องเป็น location type scrap. กันของ strand หรือมูลค่าค้าง balance sheet.
  • Gotchas: ทุก action append เข้า erp_claims_warranty_event_log (append-only, มี customer_visible flag; มีแค่ intake accepted ที่ตั้ง 1). GET read surface จำกัด resource เป็น whitelist ของ 8 ตารางกัน SQL injection และต้อง cap manage/erp/finance/accounting. resolve_claim kind=replace ปิดเป็น closed, ส่วน repair/refund/credit/reject/return_as_is ปิดเป็น resolved.