Hướng dẫn/GBS Flow & Definitions

GBS Sales Order & Purchase Order — Flow & Definitions

Hệ thống đồng bộ tài liệu giữa eCentric Workspace (team.ecentric.vn) ↔ GBS (team.boxme.asia). Cập nhật: 2026-06-01 · Sync version: v13

1. Tổng quan luồng làm việc

GBS SO/PO là hệ thống yêu cầu đơn hàng nội bộ. Form được tạo trên eCentric, qua duyệt Finance, sau đó tự động đồng bộ sang GBS (ERPNext bên Boxme) để xử lý kế toán/xuất hóa đơn.

Các bên tham gia

  • User — người tạo SO/PO (Submitter)
  • Finance — duyệt L1 trên eCentric (vai trò: Finance Approver)
  • System — sync engine tự động giữa 2 nền tảng
  • GBS Team — Revenue Verifier + Revenue Manager bên Boxme

Sơ đồ tổng thể

flowchart LR
    Start([Bắt đầu]):::startNode --> Create[User tạo SO/PO trên form]
    Create --> FinReview{Finance review}
    FinReview -->|Phê duyệt| Sync[Sync sang GBS]
    FinReview -->|Send back| CanSua[Trạng thái Cần sửa]
    CanSua --> EditForm[User chỉnh sửa form]
    EditForm --> Resubmit[Submit lại]
    Resubmit --> FinReview
    Sync --> GBSReview[GBS Verifier/Manager review]
    GBSReview -->|Approve| Done([Approved - To Bill]):::endNode
    GBSReview -->|Reject| GBSReject[GBS Rejected]
    GBSReject --> Resubmit
    classDef startNode fill:#d1fae5,stroke:#10b981
    classDef endNode fill:#fce7f3,stroke:#ec4899
      
Lưu ý: Toàn bộ flow là 2 chiều — sau khi GBS quyết định, eCentric tự đồng bộ trạng thái về qua scheduled poll (15 phút) hoặc click "Check Status" thủ công trên detail page.

Sự khác biệt giữa SO và PO

Khía cạnhSales Order (SO)Purchase Order (PO)
Mục đíchĐơn hàng bán (revenue)Đơn hàng mua (cost)
Boxme workflowGBS Services Sales Order Approval (chain Verifier → Manager)PO Approval Workflow (1 step Submit → Pending Verifier)
Có Parent SO?KhôngCó thể (PO tạo từ SO sẽ link)
Auto-advance sau syncCó (v12) — Services tự lên Pending Revenue ManagerChưa có (cần click Submit on GBS thủ công)

2. Happy path — flow chi tiết từng bước

Bước 1: User tạo form

Vào menu SO Request hoặc PO Request (sidebar). Điền form gồm các trường bắt buộc: title, customer/supplier, brand, project, dates, items (item_code, qty, rate), taxes template, store, attachments.

  • Trạng thái local: Pending
  • Submitter tự động lấy từ session email (frappe.session.user) — kể cả nếu form gửi rỗng (defensive fallback v7).
  • Attachments upload trực tiếp lên SharePoint qua Upload Session, không qua server proxy.

Bước 2: Finance duyệt

Finance vào All Tickets → tab GBS SO/PO → mở doc → click Approve (hoặc Send back/Reject).

  • Approve → status local = Approved → triggers sync hook (After Save).
  • Send back → status = Cần sửa → user thấy banner đỏ + button "Sửa & Submit lại".
  • Reject → status = Rejected → kết thúc, không tiếp tục.

Bước 3: Sync sang GBS (tự động)

Sync code sync_gbs_so_outgoing (v13) hoặc sync_gbs_po_outgoing chạy ngay sau Save khi status = Approved.

  • POST mới: gửi toàn bộ payload (title, customer, items, taxes, project, custom_store, etc.) lên boxme. Tạo doc với workflow_state = Draft.
  • Sau POST thành công cho Services SO: auto fire apply_workflow "Submit for Approval" → boxme đi Pending Revenue Manager. (v12)
  • Attachments: tách rời upload SharePoint anonymous link + POST File record sang boxme.

Bước 4: GBS Team review

Verifier (trucdt@boxme.asia...) review → Manager (thuynt2@boxme.asia...) approve.

  • Boxme state chuyển: Pending Revenue Verifier → Pending Revenue Manager → Approved.
  • Sau Approved: docstatus = 1, status = "To Bill", invoice-ready.

Bước 5: Polling đồng bộ trạng thái về

poll_gbs_status chạy mỗi 15 phút (cron) cập nhật gbs_status trên local. User cũng có thể click "Check Status" button thủ công.

Hoàn tất: Local doc gbs_status = Approved + boxme docstatus = 1 → flow xong, doc sẵn sàng xuất hóa đơn.

State diagram chi tiết

stateDiagram-v2
    [*] --> Pending : User submit form
    Pending --> Approved : Finance approve
    Pending --> CanSua : Finance send back
    CanSua --> Pending : User edit + resubmit
    Approved --> GBSDraft : Sync POST
    GBSDraft --> GBSPendingManager : Auto Submit for Approval (Services)
    GBSPendingManager --> GBSApproved : Manager approve
    GBSPendingManager --> GBSRejected : Manager reject
    GBSRejected --> Approved : User resubmit cycle
    GBSApproved --> [*] : Invoice ready

    state CanSua {
      [*] --> ClickResubmit
      ClickResubmit --> FormEdit
      FormEdit --> SubmitAgain
      SubmitAgain --> [*]
    }
      

3. Error paths & Edge cases

3.1. GBS reject — Resubmit cycle

Khi GBS Verifier/Manager reject, boxme state = Rejected, poll cập nhật local gbs_status = "Rejected".

  • Detail page hiện banner đỏ + button Resubmit (chỉ submitter mới thấy).
  • Click Resubmit → resubmit_gbs_doc set status = "Cần sửa" + redirect đến form edit mode.
  • User chỉnh sửa fields/items/attachments → submit lại → resubmit_gbs_so/po save toàn bộ field thay đổi + reset status = Pending.
  • Finance approve lại → sync v13 detect resubmit_count > pushed_count → apply Resubmit transition trên boxme (Rejected → Draft) → settle loop ~1s (defends race condition) → PUT updated fields → auto Submit for Approval lại (Services).
sequenceDiagram
    autonumber
    actor User
    actor Finance
    participant eCentric
    participant Sync as Sync v13
    participant Boxme

    Boxme->>eCentric: Rejected (qua poll)
    User->>eCentric: Click Resubmit
    eCentric->>User: Redirect form edit
    User->>eCentric: Edit + Submit lại
    eCentric->>Finance: Status Pending
    Finance->>eCentric: Approve
    eCentric->>Sync: Trigger
    Sync->>Boxme: apply_workflow Resubmit
    Boxme-->>Sync: Rejected → Draft
    Note over Sync: Settle loop 1s (race defense)
    Sync->>Boxme: PUT updated fields
    Boxme-->>Sync: 200 OK
    Sync->>Boxme: apply Submit for Approval
    Boxme-->>Sync: Draft → Pending Manager
      

3.2. Race condition giữa apply_workflow và PUT (v13 fix)

Boxme có cache lag giữa workflow commit và state validate. Khi sync apply Resubmit (Rejected → Draft) thành công rồi PUT ngay → có thể 417 vì state cache chưa refresh.

Fix v13: Sau apply Resubmit, sync chạy 1 vòng GET state loop (max 5 lần) — mỗi GET là natural delay ~100-300ms. Đợi đến khi state thực sự = Draft mới PUT. Nếu không settle được, vẫn PUT (best effort).

3.3. Doc đã finalized — không PUT nữa (v13 fix)

Sau khi boxme team Approve (docstatus = 1, state = Approved/Cancelled), doc bị locked không sửa được. Nếu local resubmit_count > pushed_count mismatch nào đó còn sót → sync sẽ retry PUT → 417 vô tận.

Fix v13: Trước khi PUT, sync check boxme.docstatus. Nếu = 1 → skip PUT + bump tracker + clear sync_error → no more retry loop.

3.4. Consumer Goods skip-chain prevention (v4/v5 guard)

Boxme workflow design: chỉ "Submit for Approval" transitions yêu cầu order_type.endswith('Services'). Với Consumer Goods orders, workflow chỉ có "Submit" → Approved (skip-chain).

Sự cố trước đó: v4 guard chỉ block Consumer Goods, không cover trường hợp Services SO khi boxme đã past Draft state. Click "Submit on GBS" sai timing → fallback fire Approve skip-chain. v5 fix: Sales Order doctype NEVER fallback. Chỉ apply_workflow. PO không thay đổi (PO workflow không có skip-chain).

3.5. Rate input parseFloat vi-VN (form fix v2)

Khi user nhập rate dạng 12.962.962,962 (vi-VN với dấu phẩy thập phân), native form handler strip cả dấu phẩy trước khi parseFloat → biến 12,96 triệu thành 12 tỷ.

Fix: ec-gbs-rate-input-fix v2 với smart detection: phát hiện dấu phẩy (decimal vi-VN), preserve precision. Override native focusin/focusout handlers via capture phase + stopImmediatePropagation.

3.6. Submitter empty fallback (v7)

Nếu form quên gửi submittedBy field (auto-fill JS lỗi), submit endpoint dùng frappe.session.user fallback. Đảm bảo submitter luôn có giá trị → Resubmit button hiển thị đúng cho người tạo doc.

3.7. PUT lên Pending Verifier/Manager state (chưa fix)

Trường hợp: doc đã Pending Verifier/Manager trên boxme, user resubmit local → sync cố PUT update fields → 417 vì allow_edit perm chỉ cho Verifier/Manager. Sales User (commercial@ecentric.vn) không edit được.

Tạm thời: sync sẽ log sync_error và skip. User cần coordinate với boxme team (rút lại review hoặc reject để rồi resubmit). Backlog: notify boxme via comment + design decision.

4. Định nghĩa từng trường

Định nghĩa tự động tải từ DocType EC Field Description (single source of truth). Khi anh cập nhật từ điển, trang này tự load lại.

Đang tải định nghĩa...