跳至內容
Astera Technology

發票接上付款紀錄後,總額為甚麼變大了?

先把同一張發票的付款合計成一筆,再計發票及收款總額,避免一張發票計兩次。

先訂清楚要判斷甚麼,再準備資料

I1 有兩筆已收款,直接連接便會把整張發票金額重複兩次。使用不重複金額的合計也不可靠,因為不同發票可能剛好同額。先按發票合計付款,確保每張發票只接上一筆付款總數。

以下全部是假設資料。請在新的 SQLite 測試資料庫建立各表,再執行唯讀查詢。數量以件計,金額以港元的分作整數儲存;顯示港元時除以 100。

假設輸入節錄;完整相關資料見下方 SQL
編號發票編號金額(分)狀態代碼
P1I140000settled
P2I120000settled
P3I250000settled
P4I320000failed
下載可編輯 CSV ↓
可直接執行的完整假設資料(SQLite)
CREATE TABLE customers(id TEXT PRIMARY KEY, name TEXT);
CREATE TABLE invoices(id TEXT PRIMARY KEY, customer_id TEXT, amount_cents INTEGER, due_on TEXT, status TEXT);
CREATE TABLE payments(id TEXT PRIMARY KEY, invoice_id TEXT, amount_cents INTEGER, status TEXT);
CREATE TABLE refunds(id TEXT PRIMARY KEY, payment_id TEXT, amount_cents INTEGER, status TEXT);
INSERT INTO customers VALUES ('C1','Acorn'),('C2','Birch');
INSERT INTO invoices VALUES ('I1','C1',100000,'2026-10-01','issued'),('I2','C2',50000,'2026-10-20','issued'),('I3','C9',20000,'2026-10-02','issued'),('I4','C1',30000,'2026-09-01','void');
INSERT INTO payments VALUES ('P1','I1',40000,'settled'),('P2','I1',20000,'settled'),('P3','I2',50000,'settled'),('P4','I3',20000,'failed');
INSERT INTO refunds VALUES ('R1','P1',10000,'completed'),('R2','P1',5000,'pending'),('R3','P3',50000,'completed');

執行查詢,核對實際結果

SQLite 唯讀查詢
WITH paid AS (
 SELECT invoice_id,SUM(amount_cents) AS paid_cents FROM payments
 WHERE status='settled' GROUP BY invoice_id
)
SELECT SUM(i.amount_cents) AS invoice_cents,
       SUM(COALESCE(p.paid_cents,0)) AS gross_paid_cents
FROM invoices i LEFT JOIN paid p ON p.invoice_id=i.id
WHERE i.status='issued';
以上 SQLite 假設資料的查詢結果
發票總額(分)原始收款(分)
170000110000
下載可編輯 CSV ↓

已發出發票共 170000 分,即 HK$1,700.00;已完成收款共 HK$1,100.00。直接連接會把發票總額錯算成 270000 分。發票金額和收款是兩個指標,都不能直接稱為已確認收入。

按資料範圍使用結果

此表看原始收款,未扣退款。假設每筆付款只屬於一張發票;跨發票付款須有分配表。作廢發票及失敗付款已明確排除。

本例的建表、資料及結果已在 SQLite 執行。套用時先在系統測試副本調整欄位及狀態規則,再與流程負責人核對預期結果。其他資料庫平台未經測試。

相關資源