Skip to content

ADR-0005. Lưu snapshot giá (v1 + v2) khi thanh toán vào item của đơn

TrườngGiá trị
Trạng tháiAccepted
Ngày2026-03-20
Người quyết địnhPhat Nguyen
Thay thế cho-

Bối cảnh

  • Quy tắc định giá trong @nx/pricing thay đổi thường xuyên - khuyến mãi, hiệu chỉnh giá, ghi đè fare.
  • Hoá đơn POS phát hành phải phản ánh đúng giá tại thời điểm thanh toán - chứ không phải giá hiện hành 3 tuần sau khi kế toán đối chiếu.
  • Định giá v1 trả về các điểm giá đơn giản. v2 trả về một object snapshot giàu thông tin, kèm vết áp dụng quy tắc, các mức giảm giá đã áp dụng, và chi tiết quy đổi tiền tệ.

Quyết định

Tại bước thanh toán (CheckoutService.checkout), sale gọi PricingNetworkService.calculate() (v1) VÀ calculateV2() (v2) cho các item của đơn. Cả hai kết quả được lưu trên mỗi SaleOrderItem:

  • unitPrice ← kết quả v1 (giá bán hiển thị)
  • priceMetadata (jsonb) ← snapshot v2 kèm vết định giá đầy đủ
  • fareId, fareProvider ← tham chiếu tới quy tắc đã định giá cho dòng đó

Snapshot v2 là nguồn sự thật cho hoàn tiền, audit và khai thuế. v1 là cái khách nhìn thấy.

Hệ quả

ƯuNhược
Hoá đơn bất biến sau khi thanh toánĐộ trễ gọi định giá tăng gấp đôi
Vết audit đầy đủ cho từng dòngpriceMetadata jsonb phình to
Thay đổi quy tắc không bao giờ ảnh hưởng tới đơn cũService định giá phải truy cập được lúc thanh toán
Hoàn tiền biết chính xác mức giảm giá nào đã áp dụngLogic hoàn tiền phải đọc snapshot v2, không gọi lại định giá

Các phương án đã cân nhắc

Phương ánƯuNhượcLý do từ chối
Chỉ lưu unitPrice (không snapshot)Tốn ít dung lượng hơnKhông audit được quy tắc nào đã áp dụngKhông đủ cho hoàn tiền và thuế
Gọi lại định giá mỗi lần đọcLuôn "mới nhất"Hoàn tiền phản ánh giá hiện tại, không phải giá đã trảSai về bản chất thiết kế
Chỉ lưu snapshot khi đơn hoàn tấtTốn ít dung lượng trước khi trả tiềnMất dữ liệu định giá nếu đơn bị huỷ trước khi hoàn tấtThiếu sót cho audit

Tham chiếu

  • sale/src/services/checkout.service.ts
  • sale/src/services/pricing-network.service.ts
  • core/src/models/schemas/sale/sale-item/schema.ts (priceMetadata, fareId, fareProvider)

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.