1
0
forked from erp-dev/erp

feat: pick up logic of api - stock_record_change.post to stock - services module

This commit is contained in:
2025-11-24 10:34:54 +08:00
parent 40ca4fc1c3
commit d1f83c7df1
3 changed files with 172 additions and 64 deletions

View File

@@ -1,13 +1,101 @@
from . import models
from django.db import transaction
from django.db.models import Sum
from django.utils import timezone
from sse.services import push_simple_message_with_object_id
from basic_info import models as basic_models
import logging
from typing import List, Dict, Any, Tuple
logger = logging.getLogger(__name__)
def create_stock_change_record_with_details(
*,
merchant: basic_models.Merchant,
created_by,
type: int,
warehouse_id: int,
source_type: int,
source_id: int | None = None,
products: List[Dict[str, Any]] | None = None,
) -> Tuple[models.StockChangeRecord, List[models.StockChangeDetail], int]:
"""
创建库存变动记录及其明细
参数:
merchant: 当前商户
created_by: 操作人(可为空)
type: 出入库类型
warehouse_id: 仓库ID
source_type: 来源类型
source_id: 来源单据ID可选
products: 产品及数量列表
"""
if not merchant:
raise ValueError('必须提供商户信息')
if not warehouse_id:
raise ValueError('必须提供仓库ID')
if not products:
raise ValueError('产品列表不能为空')
try:
warehouse = basic_models.WareHouse.objects.get(id=warehouse_id)
except basic_models.WareHouse.DoesNotExist:
raise ValueError(f'仓库ID {warehouse_id} 不存在')
if warehouse.merchant_id != merchant.id:
raise ValueError('仓库不属于当前商户')
created_details: List[models.StockChangeDetail] = []
created_count = 0
with transaction.atomic():
stock_change_record = models.StockChangeRecord.objects.create(
type=type,
warehouse=warehouse,
source_type=source_type,
source_id=source_id,
merchant=merchant,
created_by=created_by,
)
logger.info('创建新库存变动记录 ID: %s', stock_change_record.id)
for product_data in products:
product_id = product_data.get('product')
quantities = product_data.get('quantity', [])
if not product_id or not quantities:
raise ValueError('产品数据不完整,缺少 product 或 quantity')
try:
product = basic_models.Product.objects.get(id=product_id)
except basic_models.Product.DoesNotExist:
raise ValueError(f'产品ID {product_id} 不存在')
if product.merchant_id != merchant.id:
raise ValueError(f'产品ID {product_id} 不属于当前商户')
for quantity in quantities:
detail = models.StockChangeDetail.objects.create(
stock_change_record=stock_change_record,
product=product,
quantity=quantity,
merchant=merchant,
unit=product.unit,
)
created_details.append(detail)
created_count += 1
if warehouse.merchant.auto_complete_stock_change:
make_stock_change_completed(stock_change_record)
logger.info('自动确认库存变动记录 ID: %s', stock_change_record.id)
return stock_change_record, created_details, created_count
def find_inventory(product_id: int, warehouse_id: int) -> models.Inventory | None:
"""根据产品ID和仓库ID查找库存记录"""