|
|
@@ -1003,11 +1003,17 @@ def _validate_contract_type_and_products(data: dict) -> None:
|
|
|
|
|
|
|
|
|
def _normalize_framework_contract_data(data: dict) -> None:
|
|
|
+ """框架合同:按需/随行就市行清零;有小计则累加写入合同金额(不再强制头金额为 0)。"""
|
|
|
if not is_framework_contract_type(_get_field(data, "contract_type", "contractType")):
|
|
|
return
|
|
|
- data["amount"] = 0
|
|
|
- data["amountWithTax"] = 0
|
|
|
- products = _get_field(data, "products", "productList") or []
|
|
|
+ products = _get_field(data, "products", "productList")
|
|
|
+ if products is None:
|
|
|
+ # 未带产品明细时不改写金额(避免更新接口误清空)
|
|
|
+ return
|
|
|
+ if not isinstance(products, list):
|
|
|
+ products = []
|
|
|
+
|
|
|
+ total = Decimal("0")
|
|
|
for product in products:
|
|
|
if not isinstance(product, dict):
|
|
|
continue
|
|
|
@@ -1022,6 +1028,20 @@ def _normalize_framework_contract_data(data: dict) -> None:
|
|
|
product["subtotal"] = 0
|
|
|
product["taxAmount"] = 0
|
|
|
|
|
|
+ subtotal_raw = _get_field(product, "subtotal")
|
|
|
+ if subtotal_raw is not None and str(subtotal_raw).strip() != "":
|
|
|
+ line = _decimal_value(subtotal_raw)
|
|
|
+ else:
|
|
|
+ qty = _decimal_value(_get_field(product, "quantity"))
|
|
|
+ price = _decimal_value(_get_field(product, "price"))
|
|
|
+ discount = _decimal_value(_get_field(product, "discount"))
|
|
|
+ line = qty * price * (Decimal("1") - discount / Decimal("100"))
|
|
|
+ total += line
|
|
|
+
|
|
|
+ tax_rate = _decimal_value(_get_field(data, "tax_rate", "taxRate"), Decimal("0"))
|
|
|
+ data["amount"] = float(total)
|
|
|
+ data["amountWithTax"] = float(_calc_amount_with_tax(total, tax_rate))
|
|
|
+
|
|
|
|
|
|
def _validate_product_prices_by_contract_type(data: dict) -> None:
|
|
|
contract_type = (_get_field(data, "contract_type", "contractType") or "").strip()
|
|
|
@@ -1400,6 +1420,13 @@ def update_contract(
|
|
|
contract_type = (_get_field(data, "contract_type", "contractType") or old.contract_type or "sale").strip()
|
|
|
old.contract_type = contract_type
|
|
|
|
|
|
+ # 框架合同金额在 work_data 上汇总后,需写回 data,供下方 apply 落库
|
|
|
+ if is_framework_contract_type(contract_type) and product_rows is not None:
|
|
|
+ if "amount" in work_data:
|
|
|
+ data["amount"] = work_data["amount"]
|
|
|
+ if "amountWithTax" in work_data:
|
|
|
+ data["amountWithTax"] = work_data["amountWithTax"]
|
|
|
+
|
|
|
# 再编辑回草稿:作废全部历史审批(含已通过/已拒绝),避免再提审后 canApprove 命中旧记录
|
|
|
invalidate_all_approvals(db, contract_id)
|
|
|
|