Finance (Vendor)
Nội dung này hiện chưa có sẵn bằng ngôn ngữ của bạn.
Executive summary
Section titled “Executive summary”Finance covers transactions, expenses, refunds, invoices, receivables, and reports across multiple subroutes. Module finance applies; some screens are dense—use store context and API filters consistently.
Operational flows that combine POS, orders, and receivables are summarized in Sales, POS & receivables (procedures).
Goals and non-goals
Section titled “Goals and non-goals”| Goals | Non-goals |
|---|---|
| Operational money movement visibility | Replace certified accounting close |
| Link vendor UI routes to finance APIs | Document tax jurisdiction rules |
Current platform behavior
Section titled “Current platform behavior”- Hub at
/dashboard/finances; ledger and order-settlement variants per table below. - Detailed field semantics and filters: Swagger / API conventions.
- Vendor finance UI must not deep-link the Clover merchant dashboard (
https://www.clover.com). Order rows open/dashboard/orders/:id, tax settings open catalog taxes, billing statements open/dashboard/billing, and Clover CDN images/SVGs are served fromapps/vendor-web/public/images/finance/. Backend Clover API hosts (api.clover.com) are unchanged.
Sequence: happy path
Section titled “Sequence: happy path”- Open Finances hub → pick tab/filter.
- Drill to transaction detail or order settlement per investigation.
- Export or reconcile per ops process (if UI provides export).
Security and operations
Section titled “Security and operations”- Finance data is highly sensitive—role-gate, audit exports, no shared screenshots.
Test scenarios (UAT / QA)
Section titled “Test scenarios (UAT / QA)”| ID | Scenario | Expected |
|---|---|---|
| F1 | Employee with finance | Routes open |
| F2 | Employee without finance | Blocked |
| F3 | Transaction detail | Matches API source of truth |
Routes
Section titled “Routes”| Route | Purpose |
|---|---|
/dashboard/finances | Finances hub — account transaction list with tabs (e.g. All / cash-in / collected-by-admin) using transactions overview + list APIs |
/dashboard/finance/cash-book | Removed — SPA redirects to /dashboard/finance/transactions (bookmarks and old links) |
/dashboard/finance/transactions | Ledger transactions (includes manual create modal for account transactions) |
/dashboard/finance/transactions/:id | Account transaction detail (account_transactions row) |
/dashboard/finance/transactions/orders | Order-settlement style transaction list |
/dashboard/finance/transactions/orders/:id | Per-order settlement detail |
/dashboard/finance/expenses | Expense lines (P&L-style) — list supports multi-select batch status updates (approve / mark paid / cancel), mirroring receivables batch UX |
/dashboard/finance/expenses/:id | Expense detail + lifecycle updates + activity timeline |
/dashboard/finance/refunds | Refund requests / status |
/dashboard/finance/invoices | Invoice list with payment progress and overdue tracking |
/dashboard/finance/invoices/create | Create invoice (manual draft → API create) |
/dashboard/finance/invoices/:id | Invoice detail (summary, customer, issue/due timeline) |
/dashboard/finance/receivables | Customer debt / BNPL-style receivable lines (scoped via order → store) |
/dashboard/finance/sales-overview | Sales overview — period summary (gross/net sales, taxes, tips), tender types, cash deposits by device, revenue classes; default landing when opening Finance in the sidebar |
/dashboard/finance/report | Financial reports — pick the report type from the dropdown (full-width content); child paths like /dashboard/finance/report/by-time stay bookmarkable |
/dashboard/finance/report/taxes | Taxes — sales tax by rate (applicable sales, collected, refunded, net) for completed paid orders in the selected period |
Financial report — Excel export
Section titled “Financial report — Excel export”Export Excel builds an .xlsx with a short cover block (report title, reporting period, store scope, optional “prepared by”, generation timestamp, and a footer note about USD-style negatives and reconciling tax/tender against the POS register journal). Data sheets use typed columns (currency, integers, dates where applicable), frozen header row, AutoFilter, and light borders so the file reads like an ops workbook rather than a raw CSV paste.
The Point of Sale → Revenue by product report uses the same export helper and cover pattern for consistency with dashboard finance exports.
Low stock — “All stores” for vendor employees
Section titled “Low stock — “All stores” for vendor employees”When the store filter is All stores, the finance Low stock KPI strip and table call catalog overview / low-stock without a store_id so the backend can aggregate across every store the employee is authorized to access. (Other catalog screens still auto-scope to the employee’s current store.) Choosing a single store in the filter sends that store_id explicitly.
Retail / wholesale — charts
Section titled “Retail / wholesale — charts”Channel charts and the daily trend block are collapsed by default so the period summary, export, and daily breakdown table stay closer together; expand when you need the visuals.
Access (RBAC)
Section titled “Access (RBAC)”Paths under /dashboard/finance and /dashboard/finances map to module finance. See Vendor panel overview.
Data model (frontend comments)
Section titled “Data model (frontend comments)”The client vendor-finance.api.ts documents the split:
/vendor/finance/transactions—account_transactionsledger rows (balance-style fields such ascurrent_balance,transaction_type,method,ref)./vendor/finance/expenses— analytical expense lines for vendor-scoped P&L (not the same as customer invoice receivables)./vendor/finance/invoices— issued invoice rows (invoices) with status (unpaid,partially_paid,paid,overdue) and aggregate payment progress.- Invoice rows are now auto-synced from
orders: created on order creation and updated when order payment status changes. /vendor/finance/receivables— customer debt lines tied to orders (BNPL / installments-style); distinct from generic ledger expenses.
Backend modules and migrations define how these rows relate to AccountTransaction and customer invoices; treat the three surfaces above as different screens in the vendor app.
APIs (representative)
Section titled “APIs (representative)”All prefixed under /vendor/finance/ in apps/vendor-web/src/services/vendor-finance.api.ts:
| Surface | Endpoints |
|---|---|
| Transactions | .../transactions/overview, .../transactions, POST .../transactions (manual ledger record), .../transactions/:id |
| Order transactions | .../transactions/orders/overview, .../transactions/orders, .../transactions/orders/:id |
| Expenses | .../expenses/overview, .../expenses (list supports tab (all | pending | approved | paid | cancelled), status, expense_type, date/search/sort), .../expenses/:id (GET detail), PATCH .../expenses/:id (update expense_status / description; writes audit_logs), PATCH .../expenses/batch (batch: approve | mark_paid | cancel; skips ineligible rows; writes audit_logs per update) |
| Refunds | .../refunds/overview, .../refunds, .../refunds/:refundId (PATCH updates status) |
| Invoices | .../invoices/overview, .../invoices (list; query filters: store_id, status, tab (all | unpaid | partial | paid | overdue), date_from / date_to, user_id, amount_min / amount_max, search, sort), POST .../invoices (create invoice for existing order in authorized store), .../invoices/:id (GET detail) |
| Receivables | .../receivables/overview, .../receivables (list; query filters: store_id, status, tab (all | unpaid | partial | paid | overdue), date_from / date_to, user_id, amount_min / amount_max, search, sort), .../receivables/:id (GET detail with payments + activities), PATCH .../receivables/:id (edit due date / paid amount partial), PATCH .../receivables/batch (batch settle: mark_paid | cancel | waive; writes audit_logs with JWT actor per row) |
| Reports | .../report/summary, .../report/daily, .../report/staff (per linked vendor employee on orders) |
Report summary / daily: totals and each daily row include order_discount: coupon + store + line-item discounts on orders that count toward gross_sales / refunds in the same window (and the same optional sale_type filter: retail vs wholesale). The expenses field remains the sum of vendor expense ledger lines in range (not attributed by sale channel). Retail and wholesale finance report screens use order_discount for the “discount” column so it matches OrderSaleType–scoped orders instead of reusing expenses.
When sale_type is set (0 retail or 1 wholesale), net_revenue is (gross_sales − tax_total) − refunds − order_discount so channel revenue is not reduced by store-wide ledger expenses on days with no orders in that channel. Without sale_type, net_revenue is (gross_sales − tax_total) − expenses − refunds (P&L-style).
On the vendor retail / wholesale report charts, Revenue composition uses net_revenue, order_discount, and refunds only (not the expenses ledger), so the donut matches order-scoped statistics shared across channels.
Receivables / “thu nợ”: the vendor app lists receivable lines and KPIs via the endpoints above. Use quick tabs (all, unpaid, partial, paid, overdue) for fast filtering, then open detail (GET /vendor/finance/receivables/:id) to inspect payment/activity history. PATCH /vendor/finance/receivables/:id supports editing payment_deadline and absolute paid_amount (partial payment correction). PATCH /vendor/finance/receivables/batch settles selected rows at full balance with actions mark_paid (optional receivable_payments row when there was a remainder), cancel, or waive; each affected row appends audit_logs including the vendor JWT actor and optional note. Staff may still use order detail flows where applicable—see Sales, POS & receivables (procedures) §5 for how order payment_status relates to receivable rows.
Expenses: expense lines now support POS-vendor categories such as coupon, vendor_payout, delivery_payout, staff_salary, and pos_operational (plus legacy values). Lifecycle status is tracked via expense_status (pending, approved, paid, cancelled) with quick tabs in the list and editable status in detail (PATCH /vendor/finance/expenses/:id). PATCH /vendor/finance/expenses/batch applies approve (pending → approved), mark_paid (pending or approved → paid), or cancel (to cancelled when not already paid/cancelled); each updated row appends audit_logs with optional note and audit_context default finance_expenses.
- POS order flow now auto-creates
delivery_payoutexpense rows whendelivery.partner_delivery_chargeis provided. - Purchase lot flow now auto-creates
vendor_payoutexpense rows (pending) when a lot is created, so supplier payables are visible in Finance > Expenses.
Refund status changes: PATCH /vendor/finance/refunds/:refundId accepts action (approved | rejected | refunded) and optional admin_note. Optional audit_context (finance_refunds | order_detail) tags the audit row so Orders (Vendor) activity logs show whether the change was made from the refunds list or the order detail screen.
When an order is marked refunded, wallet refunds (method wallet) credit customer wallet balance and write a wallet ledger row. Refund amount is computed on the gross returned lines (line subtotal after item discount plus tax and add-ons). Loyalty is rolled back proportionally to the refunded amount ratio against order_amount, and coupon redemption analytics exclude orders whose payment_status is refunded.
List responses use shared meta pagination (page, limit, total_pages). GET /vendor/finance/transactions and GET /vendor/finance/expenses also include meta.amount_sum: the sum of amount over the rows matching the current filters (same scope as meta.total), as a number for UI totals.
Manual account transaction create (POST /vendor/finance/transactions): vendor users can record analytical ledger rows for authorized stores (e.g. manual cash-in or admin-collected adjustment) with payload keys store_id, transaction_type (CASH_IN | COLLECTED_BY_ADMIN), from_type (store | deliveryman), from_id, amount, plus optional current_balance, method, ref, note, created_at, updated_at (ISO datetime). created_at and updated_at are legacy timestamp overrides for migration/compatibility use-cases. This flow writes account_transactions + audit_logs and intentionally does not mutate wallet balances.
Related settings: templates and SMTP
Section titled “Related settings: templates and SMTP”Vendor users can now configure invoice/receipt rendering defaults and SMTP delivery from Settings:
/dashboard/settings/receipt-template— receipt template metadata, logo image, sample line items, and receipt options for suggested tips, signature line, and invoice barcode/dashboard/settings/invoice-template— invoice template metadata, logo image, and sample line items/dashboard/settings/smtp— SMTP host/port/auth/from identity + test email action
Back-end endpoints are under /vendor/settings/*:
GET|PATCH /vendor/settings/receipt-templateGET|PATCH /vendor/settings/invoice-templateGET|PATCH /vendor/settings/smtpPOST /vendor/settings/smtp/test
Related
Section titled “Related”- Sales, POS & receivables (procedures) — receivable lifecycle vs order payment flags.
- Orders (Vendor) — refunds and order-linked money movement.
- POS — payments that flow into finance reporting.