90 lines
2.8 KiB
Python
90 lines
2.8 KiB
Python
"""合同班合单:可录判定、按供应商分组、草稿映射。"""
|
|
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码"
|
|
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_id,
|
|
goods_code=row.goods_id,
|
|
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 "",
|
|
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,
|
|
)
|