Skip to content

ADR-0001. Model phiếu ghi sổ kép + ledger

FieldValue
StatusAccepted
Date2026-04-22
Decidersfinance-team
Supersedes

Bối cảnh

  • Model trước ghi nhận biến động tiền dưới dạng các dòng FinanceTransaction phẳng với type INCOME/EXPENSE/TRANSFER và một tài khoản duy nhất — không có nhóm chứng từ, không có counter-leg, và không có phiếu sẵn-sàng-audit.
  • Ghi sổ kế toán POS Việt Nam kỳ vọng các chứng từ nhận diện được: Phiếu thu (receipt), Phiếu chi (payment), Phiếu chuyển khoản (transfer), Phiếu kế toán (adjustment), mỗi loại có số chạy theo từng merchant.
  • Biến động COGS và tài sản tồn kho cần một counter-leg cân bằng (DEBIT một tài khoản, CREDIT tài khoản khác) — không thể với giao dịch một-phía.
  • Số dư tài khoản phải tái dựng được và chống giả mạo.

Quyết định

Chúng tôi sẽ model finance theo ghi sổ kép: một header FinanceVoucher (type RECEIPT / PAYMENT / TRANSFER / ADJUSTMENT) sở hữu N dòng FinanceTransaction, mỗi dòng là DEBIT (100_DEBIT, balance lên) hoặc CREDIT (200_CREDIT, balance xuống) trên một FinanceAccount.

Hướng dòng được suy ra cho RECEIPT (toàn DEBIT) và PAYMENT (toàn CREDIT), và explicit + cân bằng cho TRANSFER (Σdebit == Σcredit) và ADJUSTMENT. Số được tạo theo (merchantId, type, yearMonth) qua FinanceVoucherSequence với tiền tố PT/PC/PCK/PKT. Mỗi dòng đã post snapshot balanceBefore/balanceAfter và một postingSequence đơn điệu; dòng tài khoản được khóa FOR UPDATE cho toàn bộ quá trình post.

Hệ quả

ƯuNhược
Chứng từ sẵn-sàng-audit với số ổn định theo từng merchantNhiều bảng hơn + một động cơ hạch toán phải duy trì
Counter-leg cân bằng cho phép kế toán COGS / tài sản tồn khoCaller của TRANSFER/ADJUSTMENT phải cung cấp dòng cân bằng
Snapshot balance theo từng dòng + posting sequence làm ledger chống giả mạoPost phiếu là một transaction nhiều dòng (tranh chấp lock dưới tải)
Void trở thành bút toán đảo cân bằng, không bao giờ chỉnh sửa phá hủyMột tiền tệ thực thi theo từng phiếu (đa tiền tệ hoãn lại)

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

Phương ánƯuNhượcLý do loại bỏ
Giao dịch một-phía phẳng (model trước)Đơn giản nhấtKhông chứng từ, không counter-leg, không hỗ trợ COGSKhông thể biểu diễn hạch toán cân bằng
Sổ cái tổng đầy đủ với chart-of-accountsHoàn chỉnh về kế toánQuá mức cho POS SMB; UX vận hành dốcQuá nặng cho phạm vi hiện tại
Ledger event-sourced (append event, project balance)Audit mạnhHạ tầng mới; độ trễ project balancepostingSequence + snapshot đã cho audit mà không tốn chi phí rebuild

Tham chiếu

  • packages/core/src/services/finance/finance-voucher.service.ts (_performIssue, postLines, resolveLineDirection, computeHeaderAmount)
  • packages/core/src/models/schemas/finance/finance-voucher/, finance-transaction/, finance-voucher-sequence/
  • Domain Model

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