forked from erp-dev/erp
feat: added pre sales order and pre purchase order models and crud
This commit is contained in:
@@ -101,6 +101,15 @@ def _normalize_pre_sales_items(
|
||||
return normalized
|
||||
|
||||
|
||||
def _normalize_pre_purchase_items(
|
||||
*,
|
||||
merchant: basic_info_models.Merchant,
|
||||
items: List[Dict[str, Any]],
|
||||
) -> List[Dict[str, Any]]:
|
||||
# 与预销售单明细字段保持一致的弱关联产品输入结构
|
||||
return _normalize_pre_sales_items(merchant=merchant, items=items)
|
||||
|
||||
|
||||
def list_pre_sales_orders(*, merchant: basic_info_models.Merchant):
|
||||
return models.PreSalesOrder.objects.filter(merchant=merchant).select_related(
|
||||
'merchant', 'customer', 'warehouse', 'created_by'
|
||||
@@ -121,7 +130,8 @@ def create_pre_sales_order(
|
||||
merchant: basic_info_models.Merchant,
|
||||
customer_id: int | str | None,
|
||||
warehouse_id: int | str | None,
|
||||
created_by: basic_info_models.Employee,
|
||||
operator: basic_info_models.Employee,
|
||||
created_by=None,
|
||||
kind: int | str | None = None,
|
||||
items: List[Dict[str, Any]],
|
||||
remarks: str | None = '',
|
||||
@@ -160,8 +170,8 @@ def create_pre_sales_order(
|
||||
except basic_info_models.WareHouse.DoesNotExist as exc:
|
||||
raise ValueError(f'仓库 {warehouse_id_int} 不存在') from exc
|
||||
|
||||
if created_by.merchant_id != merchant.id:
|
||||
raise ValueError('创建者所属商户与预销售单所属商户不一致')
|
||||
if operator.merchant_id != merchant.id:
|
||||
raise ValueError('经办人所属商户与预销售单所属商户不一致')
|
||||
|
||||
normalized_items = _normalize_pre_sales_items(merchant=merchant, items=items)
|
||||
|
||||
@@ -171,6 +181,7 @@ def create_pre_sales_order(
|
||||
customer=customer,
|
||||
warehouse=warehouse,
|
||||
created_by=created_by,
|
||||
operator=operator,
|
||||
kind=kind_int or models.SalesOrderKindEnum.WHOLESALE,
|
||||
remarks=remarks,
|
||||
)
|
||||
@@ -295,3 +306,200 @@ def update_pre_sales_order(
|
||||
def delete_pre_sales_order(*, pre_sales_order: models.PreSalesOrder) -> None:
|
||||
with transaction.atomic():
|
||||
pre_sales_order.delete()
|
||||
|
||||
|
||||
def list_pre_purchase_orders(*, merchant: basic_info_models.Merchant):
|
||||
return models.PrePurchaseOrder.objects.filter(merchant=merchant).select_related(
|
||||
'merchant', 'supplier', 'warehouse', 'created_by'
|
||||
).prefetch_related('items')
|
||||
|
||||
|
||||
def get_pre_purchase_order(*, merchant: basic_info_models.Merchant, pre_purchase_order_id: int) -> models.PrePurchaseOrder:
|
||||
try:
|
||||
return models.PrePurchaseOrder.objects.select_related(
|
||||
'merchant', 'supplier', 'warehouse', 'created_by'
|
||||
).prefetch_related('items').get(id=pre_purchase_order_id, merchant=merchant)
|
||||
except models.PrePurchaseOrder.DoesNotExist as exc:
|
||||
raise ValueError('预采购单不存在') from exc
|
||||
|
||||
|
||||
def create_pre_purchase_order(
|
||||
*,
|
||||
merchant: basic_info_models.Merchant,
|
||||
supplier_id: int | str | None,
|
||||
warehouse_id: int | str | None,
|
||||
operator: basic_info_models.Employee,
|
||||
created_by=None,
|
||||
kind: int | str | None = None,
|
||||
items: List[Dict[str, Any]],
|
||||
remarks: str | None = '',
|
||||
) -> models.PrePurchaseOrder:
|
||||
if not supplier_id:
|
||||
raise ValueError('缺少供应商 ID')
|
||||
if not warehouse_id:
|
||||
raise ValueError('缺少仓库 ID')
|
||||
|
||||
try:
|
||||
supplier_id_int = int(supplier_id)
|
||||
except (TypeError, ValueError) as exc:
|
||||
raise ValueError('supplier 必须为整数') from exc
|
||||
|
||||
try:
|
||||
warehouse_id_int = int(warehouse_id)
|
||||
except (TypeError, ValueError) as exc:
|
||||
raise ValueError('warehouse 必须为整数') from exc
|
||||
|
||||
kind_int: int | None
|
||||
if kind is None or kind == '':
|
||||
kind_int = None
|
||||
else:
|
||||
try:
|
||||
kind_int = int(kind)
|
||||
except (TypeError, ValueError) as exc:
|
||||
raise ValueError('kind 必须为整数') from exc
|
||||
|
||||
try:
|
||||
supplier = basic_info_models.Supplier.objects.get(id=supplier_id_int, merchant=merchant)
|
||||
except basic_info_models.Supplier.DoesNotExist as exc:
|
||||
raise ValueError(f'供应商 {supplier_id_int} 不存在') from exc
|
||||
|
||||
try:
|
||||
warehouse = basic_info_models.WareHouse.objects.get(id=warehouse_id_int, merchant=merchant)
|
||||
except basic_info_models.WareHouse.DoesNotExist as exc:
|
||||
raise ValueError(f'仓库 {warehouse_id_int} 不存在') from exc
|
||||
|
||||
if operator.merchant_id != merchant.id:
|
||||
raise ValueError('经办人所属商户与预采购单所属商户不一致')
|
||||
|
||||
normalized_items = _normalize_pre_purchase_items(merchant=merchant, items=items)
|
||||
|
||||
with transaction.atomic():
|
||||
pre_purchase_order = models.PrePurchaseOrder.objects.create(
|
||||
merchant=merchant,
|
||||
supplier=supplier,
|
||||
warehouse=warehouse,
|
||||
created_by=created_by,
|
||||
operator=operator,
|
||||
kind=kind_int or models.PurchaseOrderKindEnum.WHOLESALE,
|
||||
remarks=remarks,
|
||||
)
|
||||
|
||||
try:
|
||||
pre_purchase_order.full_clean()
|
||||
except ValidationError as exc:
|
||||
raise ValueError(str(exc)) from exc
|
||||
|
||||
models.PrePurchaseOrderItem.objects.bulk_create(
|
||||
[
|
||||
models.PrePurchaseOrderItem(
|
||||
pre_purchase_order=pre_purchase_order,
|
||||
product_id=item['product_id'],
|
||||
product_name=item.get('product_name') or '',
|
||||
color=item.get('color'),
|
||||
quantity=item.get('quantity'),
|
||||
unit=item.get('unit') or '',
|
||||
spec=item.get('spec'),
|
||||
quantity_of_rolls=item.get('quantity_of_rolls'),
|
||||
num_of_rolls=item.get('num_of_rolls') or 1,
|
||||
order_quantity=item.get('order_quantity'),
|
||||
remarks=item.get('remarks'),
|
||||
)
|
||||
for item in normalized_items
|
||||
]
|
||||
)
|
||||
|
||||
pre_purchase_order.refresh_from_db()
|
||||
return pre_purchase_order
|
||||
|
||||
|
||||
def update_pre_purchase_order(
|
||||
*,
|
||||
pre_purchase_order: models.PrePurchaseOrder,
|
||||
supplier_id: int | str | None = None,
|
||||
warehouse_id: int | str | None = None,
|
||||
kind: int | str | None = None,
|
||||
items: List[Dict[str, Any]] | None = None,
|
||||
remarks: str | None = None,
|
||||
) -> models.PrePurchaseOrder:
|
||||
merchant = pre_purchase_order.merchant
|
||||
|
||||
new_supplier = pre_purchase_order.supplier
|
||||
if supplier_id is not None:
|
||||
if supplier_id == '':
|
||||
raise ValueError('supplier 必须为整数')
|
||||
try:
|
||||
supplier_id_int = int(supplier_id)
|
||||
except (TypeError, ValueError) as exc:
|
||||
raise ValueError('supplier 必须为整数') from exc
|
||||
try:
|
||||
new_supplier = basic_info_models.Supplier.objects.get(id=supplier_id_int, merchant=merchant)
|
||||
except basic_info_models.Supplier.DoesNotExist as exc:
|
||||
raise ValueError(f'供应商 {supplier_id_int} 不存在') from exc
|
||||
|
||||
new_warehouse = pre_purchase_order.warehouse
|
||||
if warehouse_id is not None:
|
||||
if warehouse_id == '':
|
||||
raise ValueError('warehouse 必须为整数')
|
||||
try:
|
||||
warehouse_id_int = int(warehouse_id)
|
||||
except (TypeError, ValueError) as exc:
|
||||
raise ValueError('warehouse 必须为整数') from exc
|
||||
try:
|
||||
new_warehouse = basic_info_models.WareHouse.objects.get(id=warehouse_id_int, merchant=merchant)
|
||||
except basic_info_models.WareHouse.DoesNotExist as exc:
|
||||
raise ValueError(f'仓库 {warehouse_id_int} 不存在') from exc
|
||||
|
||||
if kind is None or kind == '':
|
||||
new_kind = pre_purchase_order.kind
|
||||
else:
|
||||
try:
|
||||
new_kind = int(kind)
|
||||
except (TypeError, ValueError) as exc:
|
||||
raise ValueError('kind 必须为整数') from exc
|
||||
|
||||
new_remarks = remarks if remarks is not None else pre_purchase_order.remarks
|
||||
|
||||
if items is None:
|
||||
raise ValueError('items 需要为非空数组')
|
||||
normalized_items = _normalize_pre_purchase_items(merchant=merchant, items=items)
|
||||
|
||||
with transaction.atomic():
|
||||
pre_purchase_order.supplier = new_supplier
|
||||
pre_purchase_order.warehouse = new_warehouse
|
||||
pre_purchase_order.kind = new_kind
|
||||
pre_purchase_order.remarks = new_remarks
|
||||
|
||||
try:
|
||||
pre_purchase_order.full_clean()
|
||||
except ValidationError as exc:
|
||||
raise ValueError(str(exc)) from exc
|
||||
|
||||
pre_purchase_order.save(update_fields=['supplier', 'warehouse', 'kind', 'remarks', 'updated_at'])
|
||||
|
||||
pre_purchase_order.items.all().delete()
|
||||
models.PrePurchaseOrderItem.objects.bulk_create(
|
||||
[
|
||||
models.PrePurchaseOrderItem(
|
||||
pre_purchase_order=pre_purchase_order,
|
||||
product_id=item['product_id'],
|
||||
product_name=item.get('product_name') or '',
|
||||
color=item.get('color'),
|
||||
quantity=item.get('quantity'),
|
||||
unit=item.get('unit') or '',
|
||||
spec=item.get('spec'),
|
||||
quantity_of_rolls=item.get('quantity_of_rolls'),
|
||||
num_of_rolls=item.get('num_of_rolls') or 1,
|
||||
order_quantity=item.get('order_quantity'),
|
||||
remarks=item.get('remarks'),
|
||||
)
|
||||
for item in normalized_items
|
||||
]
|
||||
)
|
||||
|
||||
pre_purchase_order.refresh_from_db()
|
||||
return pre_purchase_order
|
||||
|
||||
|
||||
def delete_pre_purchase_order(*, pre_purchase_order: models.PrePurchaseOrder) -> None:
|
||||
with transaction.atomic():
|
||||
pre_purchase_order.delete()
|
||||
|
||||
Reference in New Issue
Block a user