"""合同班合单:可录判定、按供应商分组、草稿映射。""" from __future__ import annotations from collections import OrderedDict from datetime import date, datetime from decimal import Decimal, ROUND_HALF_UP from contract_draft import ContractDraft from contract_flow_steps import ContractGoodsLine from repo import PurchaseContractRow def is_claimable(row: PurchaseContractRow) -> bool: if int(row.process_status or 0) != 0: return False if row.contract_entry_status is not None and int(row.contract_entry_status) == 0: if (row.contract_no or "").strip(): return False return True def group_by_supplier(rows: list[PurchaseContractRow]) -> list[list[PurchaseContractRow]]: groups: OrderedDict[str, list[PurchaseContractRow]] = OrderedDict() for row in sorted(rows, key=lambda item: item.fid): groups.setdefault(row.supplier_id, []).append(row) return list(groups.values()) def missing_mdm_reason(rows: list[PurchaseContractRow]) -> str | None: if not rows: return "缺少供应商MDM码" if not (rows[0].supplier_mdm_code or "").strip(): return "缺少供应商MDM码" for row in rows: if not (row.goods_mdm_code or "").strip(): return "缺少货品MDM码" return None def money4(value) -> str: amount = Decimal(str(value)).quantize(Decimal("0.0001"), rounding=ROUND_HALF_UP) return f"{amount:.4f}" def iso_date(value) -> str: if value is None: return "" if isinstance(value, datetime): return value.date().isoformat() if isinstance(value, date): return value.isoformat() return str(value)[:10] def draft_from_group(rows: list[PurchaseContractRow]) -> ContractDraft: first = rows[0] sign = iso_date(first.contract_sign_date) total = sum( (Decimal(str(row.qty)) * Decimal(str(row.unit_price)) for row in rows), Decimal("0"), ) goods = [ ContractGoodsLine( operation_code=(row.goods_mdm_code or "").strip(), goods_code=(row.goods_mdm_code or "").strip(), goods_name=row.goods_name, approval_no=row.reg_no, spec=row.spec, unit=row.unit, quantity=float(row.qty), mdm_code=(row.goods_mdm_code or "").strip(), unit_price=money4(row.unit_price), ) for row in rows ] return ContractDraft( supplier_name=first.supplier_name, order_date=sign, source_type="", customer_code=(first.supplier_mdm_code or "").strip(), customer_name=first.supplier_name, contract_category="采购协议", amount=money4(total), contract_sign_date=sign, contract_start_date=iso_date(first.contract_start_date), contract_end_date=iso_date(first.contract_end_date), is_prepayment="否", belong_year=sign[:4], payment_method="账期支付", payment_days=str(first.payment_term), goods_lines=goods, )