PayrollManagementSystem/scripts/tplus/profile_source.py

49 lines
3.3 KiB
Python
Raw Normal View History

"""只读统计主从关系、状态和负数行,不输出业务明细。"""
import argparse
import json
from pathlib import Path
import pyodbc
QUERIES = {
"personnel_dates": "SELECT COUNT_BIG(*) AS total, SUM(CASE WHEN updated IS NULL THEN 1 ELSE 0 END) AS null_updated FROM AA_Person",
"product_dates": "SELECT COUNT_BIG(*) AS total, SUM(CASE WHEN updated IS NULL THEN 1 ELSE 0 END) AS null_updated FROM AA_Inventory",
"order_detail_parent": "SELECT COUNT_BIG(*) AS total, SUM(CASE WHEN h.ID IS NULL THEN 1 ELSE 0 END) AS orphan_rows FROM SA_SaleOrder_b b LEFT JOIN SA_SaleOrder h ON h.ID=b.idSaleOrderDTO",
"delivery_detail_parent": "SELECT COUNT_BIG(*) AS total, SUM(CASE WHEN h.ID IS NULL THEN 1 ELSE 0 END) AS orphan_rows FROM SA_SaleDelivery_b b LEFT JOIN SA_SaleDelivery h ON h.ID=b.idSaleDeliveryDTO",
"receipt_detail_parent": "SELECT COUNT_BIG(*) AS total, SUM(CASE WHEN h.ID IS NULL THEN 1 ELSE 0 END) AS orphan_rows FROM ARAP_ReceivePayment_b b LEFT JOIN ARAP_ReceivePayment h ON h.ID=b.idArapReceivePaymentDTO",
"delivery_order_link": "SELECT COUNT_BIG(*) AS total, SUM(CASE WHEN b.saleOrderId IS NULL OR b.saleOrderId=0 THEN 1 ELSE 0 END) AS missing_order_id, SUM(CASE WHEN b.saleOrderId>0 AND h.ID IS NULL THEN 1 ELSE 0 END) AS invalid_order_id FROM SA_SaleDelivery_b b LEFT JOIN SA_SaleOrder h ON h.ID=b.saleOrderId",
"receipt_order_link": "SELECT COUNT_BIG(*) AS total, SUM(CASE WHEN p.SaleOrderID IS NULL OR p.SaleOrderID=0 THEN 1 ELSE 0 END) AS missing_order_id, SUM(CASE WHEN p.SaleOrderID>0 AND h.ID IS NULL THEN 1 ELSE 0 END) AS invalid_order_id FROM ARAP_ReceivePayment p LEFT JOIN SA_SaleOrder h ON h.ID=p.SaleOrderID",
"receipt_direction": "SELECT isReceiveFlag, COUNT_BIG(*) AS total FROM ARAP_ReceivePayment GROUP BY isReceiveFlag",
"receipt_status": "SELECT voucherstate, cancelState, COUNT_BIG(*) AS total FROM ARAP_ReceivePayment GROUP BY voucherstate,cancelState",
"negative_deliveries": "SELECT SUM(CASE WHEN quantity<0 THEN 1 ELSE 0 END) AS negative_quantity, SUM(CASE WHEN costAmount<0 THEN 1 ELSE 0 END) AS negative_cost FROM SA_SaleDelivery_b",
}
def main() -> int:
"""执行固定白名单统计,并保存无凭据、无明细的 JSON。"""
parser = argparse.ArgumentParser(description="T+ 只读数据质量统计")
parser.add_argument("--connection-file", required=True, type=Path)
parser.add_argument("--report", required=True, type=Path)
args = parser.parse_args()
c = json.loads(args.connection_file.read_text(encoding="utf-8-sig"))
cs = ("DRIVER={" + c["driver"] + "};SERVER=" + c["host"] + "," + str(c["port"])
+ ";DATABASE=" + c["database"] + ";UID=" + c["user"]
+ ";PWD={" + c["password"].replace("}", "}}") + "};")
result = {}
with pyodbc.connect(cs, timeout=10) as connection:
connection.timeout = 120
cursor = connection.cursor()
for name, sql in QUERIES.items():
cursor.execute(sql)
names = [column[0] for column in cursor.description]
result[name] = [dict(zip(names, row, strict=True)) for row in cursor.fetchall()]
print(name, json.dumps(result[name]), flush=True)
args.report.parent.mkdir(parents=True, exist_ok=True)
args.report.write_text(json.dumps(result, indent=2), encoding="utf-8")
return 0
if __name__ == "__main__":
raise SystemExit(main())