Files
PayrollManagementSystem/db/queries/业务数据.sql
T
liuwenxinandClaude Code 20fcf06f51 feat(business): 新增业务数据七表及 V5 迁移(业务/明细/状态留痕/发货/回款/评级配置)
- businesses 五项汇总冗余列服务层事务内维护;毛利润不落库(派生值,M3 台账固化)
- 行级 product_category 折算锚点(#14);回款 settlement_status 预置为 M3 防重锚点
- 评级等级种子四条(迁移+init-dev 双写);编号前缀常量 YW/SH/HK
- 双轨 SQL 同步(V4/V5 重导,schema_sync+test_models 164 例全绿)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-13 11:22:34 +08:00

116 lines
5.2 KiB
SQL

-- ============================================================================
-- 业务数据查询留档(M2 业务数据管理)
--
-- 设计要点:
-- - businesses 的 total_* 五列为服务层维护的汇总冗余,查询直接读冗余列
-- 而非实时 JOIN 聚合;本文件同时给出「对账用」的实时聚合口径
-- - 回款天数 = formula.payment_days(ship_date, receipt_date),即
-- DATEDIFF(receipt_date, ship_date) + 1(发货日首日计第 1 天,对照表 #1),
-- 应用层以纯函数为准,SQL 版仅供人工对账
-- - 毛利润率/折算毛利润额不落库:视图按行实时计算(阈值取 M1 参数快照)
-- ============================================================================
-- 1. 业务台账(列表页;冗余列直读)
SELECT b.id,
b.business_no,
c.company_name,
c.customer_type,
b.status,
b.business_date,
p.personnel_name AS owner_name,
pa.personnel_name AS assistant_name,
b.total_sale_amount,
b.total_cost_amount,
b.total_ship_amount,
b.total_received_amount,
b.total_freight_amount
FROM businesses b
JOIN customers c ON c.id = b.customer_id
LEFT JOIN personnel p ON p.id = b.owner_personnel_id
LEFT JOIN personnel pa ON pa.id = b.assistant_personnel_id
WHERE (:keyword IS NULL OR b.business_no LIKE CONCAT('%', :keyword, '%')
OR c.company_name LIKE CONCAT('%', :keyword, '%'))
AND (:status IS NULL OR b.status = :status)
AND (:customer_id IS NULL OR b.customer_id = :customer_id)
AND (:owner_personnel_id IS NULL OR b.owner_personnel_id = :owner_personnel_id)
ORDER BY b.id DESC
LIMIT :limit OFFSET :offset;
-- 2. 汇总冗余对账(五列与明细/发货/回款实时聚合的一致性校验,T11 集成用例同口径)
SELECT b.id,
b.total_sale_amount,
COALESCE((SELECT SUM(i.sale_amount) FROM business_items i WHERE i.business_id = b.id), 0) AS live_sale,
b.total_ship_amount,
COALESCE((SELECT SUM(si.amount) FROM shipments s JOIN shipment_items si ON si.shipment_id = s.id
WHERE s.business_id = b.id), 0) AS live_ship,
b.total_received_amount,
COALESCE((SELECT SUM(r.amount) FROM receipts r WHERE r.business_id = b.id), 0) AS live_received,
b.total_freight_amount,
COALESCE((SELECT SUM(s.freight_amount) FROM shipments s WHERE s.business_id = b.id), 0) AS live_freight
FROM businesses b
WHERE b.total_sale_amount <> COALESCE((SELECT SUM(i.sale_amount) FROM business_items i WHERE i.business_id = b.id), 0)
OR b.total_ship_amount <> COALESCE((SELECT SUM(si.amount) FROM shipments s JOIN shipment_items si ON si.shipment_id = s.id
WHERE s.business_id = b.id), 0)
OR b.total_received_amount <> COALESCE((SELECT SUM(r.amount) FROM receipts r WHERE r.business_id = b.id), 0)
OR b.total_freight_amount <> COALESCE((SELECT SUM(s.freight_amount) FROM shipments s WHERE s.business_id = b.id), 0);
-- 3. 未指定发货批次的回款(M3 核算前置校验名单;列表页筛选项)
SELECT r.id, r.receipt_batch_no, b.business_no, r.receipt_date, r.amount, r.is_barter
FROM receipts r
JOIN businesses b ON b.id = r.business_id
WHERE r.shipment_id IS NULL
AND r.settlement_status = 0
ORDER BY r.receipt_date;
-- 4. 回款天数对账视图(SQL 版仅供人工核对;应用层以 formula.payment_days 为准)
SELECT r.id,
r.receipt_batch_no,
b.business_no,
s.shipment_no,
s.ship_date,
r.receipt_date,
DATEDIFF(r.receipt_date, s.ship_date) + 1 AS payment_days
FROM receipts r
JOIN businesses b ON b.id = r.business_id
LEFT JOIN shipments s ON s.id = r.shipment_id
WHERE r.shipment_id IS NOT NULL
ORDER BY r.receipt_date DESC;
-- 5. 按产品类别的毛利润汇总(毛利润视图的类别汇总口径;阈值需按 M1 参数快照逐日匹配,
-- 此处仅聚合源数据,折算在应用层以 formula.converted_profit 计算)
SELECT i.product_category,
SUM(i.sale_amount) AS sale_total,
SUM(i.cost_amount) AS cost_total,
SUM(i.sale_amount - COALESCE(i.cost_amount, 0)) AS profit_total
FROM business_items i
WHERE i.business_id = :business_id
GROUP BY i.product_category;
-- 6. 业务状态流转时间线(详情页;创建首条 old=new=1)
SELECT l.old_status, l.new_status, l.change_reason, l.operator_name, l.create_time
FROM business_status_logs l
WHERE l.business_id = :business_id
ORDER BY l.create_time, l.id;
-- 7. 发货单与明细(列表 + 行展开)
SELECT s.id, s.shipment_no, b.business_no, s.ship_date, s.freight_amount, s.total_amount
FROM shipments s
JOIN businesses b ON b.id = s.business_id
WHERE (:business_id IS NULL OR s.business_id = :business_id)
AND (:ship_date_from IS NULL OR s.ship_date >= :ship_date_from)
AND (:ship_date_to IS NULL OR s.ship_date <= :ship_date_to)
ORDER BY s.id DESC
LIMIT :limit OFFSET :offset;
SELECT si.product_name, si.spec_model, si.unit, si.quantity, si.sale_price, si.amount
FROM shipment_items si
WHERE si.shipment_id = :shipment_id
ORDER BY si.id;
-- 8. 评级等级判定(前端按 sort_order 升序首个 min_score ≤ 总分取等级;SQL 版供后端复用)
SELECT grade_name, min_score, max_score
FROM customer_rating_grades
WHERE min_score <= :total_score
ORDER BY sort_order
LIMIT 1;