先訂清楚要判斷甚麼,再準備資料
送貨及開單都可能分批,要各自沿訂單明細合計後才連接。一次接上兩邊明細會互相倍增。不能只看有沒有發票;即使已開過單,也可能只處理了部分數量。
以下全部是假設資料。請在新的 SQLite 測試資料庫建立各表,再執行唯讀查詢。數量以件計,金額以港元的分作整數儲存;顯示港元時除以 100。
| 編號 | 明細編號 | 數量 | 狀態代碼 |
|---|---|---|---|
| D1 | L1 | 2 | completed |
| D2 | L1 | 2 | completed |
| D3 | L2 | 3 | completed |
| D4 | L3 | 1 | pending |
| D5 | L4 | 1 | completed |
CREATE TABLE orders(id TEXT PRIMARY KEY, status TEXT);
CREATE TABLE order_lines(id TEXT PRIMARY KEY, order_id TEXT, sku TEXT, ordered_qty INTEGER, unit_cents INTEGER);
CREATE TABLE deliveries(id TEXT PRIMARY KEY, line_id TEXT, qty INTEGER, status TEXT);
CREATE TABLE billed_lines(id TEXT PRIMARY KEY, line_id TEXT, qty INTEGER, status TEXT);
INSERT INTO orders VALUES ('O1','confirmed'),('O2','confirmed'),('O3','cancelled');
INSERT INTO order_lines VALUES ('L1','O1','A',5,1000),('L2','O1','B',3,2000),('L3','O2','C',4,500),('L4','O3','A',1,1000);
INSERT INTO deliveries VALUES ('D1','L1',2,'completed'),('D2','L1',2,'completed'),('D3','L2',3,'completed'),('D4','L3',1,'pending'),('D5','L4',1,'completed');
INSERT INTO billed_lines VALUES ('BL1','L1',2,'issued'),('BL2','L2',3,'issued'),('BL3','L1',1,'void');執行查詢,核對實際結果
WITH shipped AS (
SELECT line_id,SUM(qty) AS qty FROM deliveries WHERE status='completed' GROUP BY line_id
), billed AS (
SELECT line_id,SUM(qty) AS qty FROM billed_lines WHERE status='issued' GROUP BY line_id
)
SELECT l.id,l.order_id,s.qty AS delivered_qty,COALESCE(b.qty,0) AS billed_qty,
(s.qty-COALESCE(b.qty,0))*l.unit_cents AS unbilled_cents
FROM order_lines l JOIN orders o ON o.id=l.order_id
JOIN shipped s ON s.line_id=l.id LEFT JOIN billed b ON b.line_id=l.id
WHERE o.status='confirmed' AND s.qty>COALESCE(b.qty,0) ORDER BY l.id;| 編號 | 訂單編號 | 已送數量 | 已開單數量 | 未開單(分) |
|---|---|---|---|---|
| L1 | O1 | 4 | 2 | 2000 |
L1 已送 4 件,只開單 2 件,每件 1000 分,尚有 HK$20.00 的數量未開單。L2 已全數開單;L3 尚未完成送貨,未計入。另開發票前須核實收貨確認及開單條件。
按資料範圍使用結果
金額採單一單價,未計折扣、退貨或稅。這只是要跟進的未開單金額,不能稱為已確認收入。取消訂單即使有送貨也被排除,該矛盾要另查。
本例的建表、資料及結果已在 SQLite 執行。套用時先在系統測試副本調整欄位及狀態規則,再與流程負責人核對預期結果。其他資料庫平台未經測試。