from __future__ import annotations from typing import Any, Dict, List from django.db import transaction from datetime import date, datetime from decimal import Decimal from typing import Any, Dict, List from django.db import transaction from basic_info import models as basic_info_models from . import models from .tasks import create_purchase_order_stock_entries def _normalize_order_date(value) -> date: if isinstance(value, date): return value if isinstance(value, datetime): return value.date() if isinstance(value, str): try: return date.fromisoformat(value) except ValueError as exc: raise ValueError('order_date 格式不正确,应为 YYYY-MM-DD') from exc raise ValueError('order_date 格式不正确') def create_purchase_order( *, merchant: basic_info_models.Merchant, supplier: basic_info_models.Supplier, order_date, total_amount, warehouse_id: int, items: List[Dict[str, Any]], remarks: str | None = '', created_by=None, ) -> models.PurchaseOrder: """ 创建采购订单并触发异步创建入库单任务。 Args: merchant: 采购单所属商户 supplier: 供应商 order_date: 订单日期 (date) total_amount: 总金额 warehouse_id: 入库仓库ID items: 产品明细,格式示例: [ {'product_id': 1, 'quantities': ['10.00', '5.00']}, {'product_id': 2, 'quantities': ['3.50']}, ] 该结构会被传递给 StockFlowService,需满足其模式要求。 remarks: 备注 created_by: 创建者用户(可选,用于 stock 记录中的 created_by) """ if not items: raise ValueError('items 不能为空') if not warehouse_id: raise ValueError('warehouse_id 不能为空') normalized_date = _normalize_order_date(order_date) total_amount = Decimal(str(total_amount)) with transaction.atomic(): purchase_order = models.PurchaseOrder.objects.create( merchant=merchant, supplier=supplier, order_date=normalized_date, total_amount=total_amount, remarks=remarks, ) created_by_id = getattr(created_by, 'id', None) create_purchase_order_stock_entries.delay( purchase_order_id=purchase_order.id, warehouse_id=warehouse_id, items=items, created_by_id=created_by_id, ) return purchase_order