1
0
forked from erp-dev/erp

fear: stock reverse placeholder

This commit is contained in:
2025-11-30 13:40:47 +08:00
parent 4b3cd8eb75
commit f6f0ec2ae9
8 changed files with 554 additions and 31 deletions

View File

@@ -381,6 +381,30 @@ class StockFlowService:
products=products,
)
def offset_stock_change(
self,
*,
source_record_id: int,
reason: str,
items: List[Dict[str, Any]] | None = None,
request_id: str | None = None,
extra_meta: Dict[str, Any] | None = None,
) -> Tuple[models.StockChangeRecord, List[models.StockChangeDetail], int]:
"""
创建针对既有库存变动记录的红冲(对冲)占位接口。
Args:
source_record_id: 需要被红冲的库存变动记录 ID。
reason: 红冲原因,必须明确记录以便审计。
items: 可选的部分红冲明细(支持宽进/严进等结构);为空时表示全量对冲。
request_id: 幂等键;同一 request_id 的请求应视为一次操作。
extra_meta: 额外的上下文信息(触发来源、操作者备注等)。
Returns:
新生成的反向 `StockChangeRecord`、其明细列表以及明细数量。
"""
raise NotImplementedError('库存红冲功能尚未实现')
def _get_and_validate_warehouse(self, warehouse_id: int) -> basic_models.WareHouse:
if not warehouse_id:
raise ValueError('必须提供仓库ID')

View File

@@ -1,12 +1,10 @@
from django.core.exceptions import ValidationError
from django.test import TestCase
from django.utils import timezone
from decimal import Decimal
from unittest.mock import patch, MagicMock
import logging
from basic_info.models import Product, WareHouse, Supplier, ProductUnitEnum, ProductCategory, Merchant, MerchantTypeEnum, WareHouseModeEnum
from business.models import PurchaseOrder
from basic_info.models import Product, WareHouse, ProductUnitEnum, ProductCategory, Merchant, MerchantTypeEnum, WareHouseModeEnum
from . import models, services
@@ -49,14 +47,6 @@ class StockServicesTestCase(TestCase):
location="备用仓库地址"
)
# 创建供应商
cls.supplier = Supplier.objects.create(
merchant=cls.merchant,
name="测试供应商",
contact="张三",
mobile="13800138000"
)
# 创建产品
cls.product_fabric_a = Product.objects.create(
merchant=cls.merchant,
@@ -83,21 +73,14 @@ class StockServicesTestCase(TestCase):
def setUp(self):
"""每个测试方法执行前的设置"""
# 创建采购单
self.purchase_order = PurchaseOrder.objects.create(
merchant=self.merchant,
supplier=self.supplier,
order_date=timezone.now().date(),
total_amount=Decimal('1000.00'),
remarks="测试采购单"
)
self.purchase_source_id = 1001
# 创建库存变动记录(入库)
self.stock_change_in = models.StockChangeRecord.objects.create(
merchant=self.merchant,
type=models.StockChangeTypeEnum.ADD,
source_type=models.StockChangeSourceEnum.PURCHASE,
source_id=self.purchase_order.id,
source_id=self.purchase_source_id,
warehouse=self.warehouse_main,
is_finished=False
)
@@ -392,7 +375,7 @@ class CreateStockChangeRecordWithDetailsTestCase(StockServicesTestCase):
type=models.StockChangeTypeEnum.ADD,
warehouse_id=self.warehouse_main.id,
source_type=models.StockChangeSourceEnum.PURCHASE,
source_id=self.purchase_order.id,
source_id=self.purchase_source_id,
products=self.products_payload,
)
@@ -418,7 +401,7 @@ class CreateStockChangeRecordWithDetailsTestCase(StockServicesTestCase):
type=models.StockChangeTypeEnum.ADD,
warehouse_id=self.warehouse_main.id,
source_type=models.StockChangeSourceEnum.PURCHASE,
source_id=self.purchase_order.id,
source_id=self.purchase_source_id,
products=self.products_payload,
)
@@ -435,7 +418,7 @@ class CreateStockChangeRecordWithDetailsTestCase(StockServicesTestCase):
type=models.StockChangeTypeEnum.ADD,
warehouse_id=self.warehouse_main.id,
source_type=models.StockChangeSourceEnum.PURCHASE,
source_id=self.purchase_order.id,
source_id=self.purchase_source_id,
products=products,
)
@@ -451,7 +434,7 @@ class CreateStockChangeRecordWithDetailsTestCase(StockServicesTestCase):
type=models.StockChangeTypeEnum.ADD,
warehouse_id=self.warehouse_main.id,
source_type=models.StockChangeSourceEnum.PURCHASE,
source_id=self.purchase_order.id,
source_id=self.purchase_source_id,
products=[{'product': self.product_fabric_a.id, 'quantity': [Decimal('10.00')]}],
)
@@ -468,7 +451,7 @@ class CreateStockChangeRecordWithDetailsTestCase(StockServicesTestCase):
type=models.StockChangeTypeEnum.ADD,
warehouse_id=self.warehouse_main.id,
source_type=models.StockChangeSourceEnum.PURCHASE,
source_id=self.purchase_order.id,
source_id=self.purchase_source_id,
products=[{'product': self.product_fabric_a.id, 'quantity': [Decimal('5.00'), Decimal('6.00')]}],
)
@@ -604,7 +587,7 @@ class CreateStockChangeRecordRelaxedTestCase(StockServicesTestCase):
type=models.StockChangeTypeEnum.ADD,
warehouse_id=self.warehouse_main.id,
source_type=models.StockChangeSourceEnum.PURCHASE,
source_id=self.purchase_order.id,
source_id=self.purchase_source_id,
products=products,
)
@@ -629,7 +612,7 @@ class CreateStockChangeRecordRelaxedTestCase(StockServicesTestCase):
type=models.StockChangeTypeEnum.ADD,
warehouse_id=self.warehouse_main.id,
source_type=models.StockChangeSourceEnum.PURCHASE,
source_id=self.purchase_order.id,
source_id=self.purchase_source_id,
products=products,
)
@@ -654,7 +637,7 @@ class CreateStockChangeRecordRelaxedTestCase(StockServicesTestCase):
type=models.StockChangeTypeEnum.ADD,
warehouse_id=self.warehouse_main.id,
source_type=models.StockChangeSourceEnum.PURCHASE,
source_id=self.purchase_order.id,
source_id=self.purchase_source_id,
products=products,
)
@@ -676,7 +659,7 @@ class CreateStockChangeRecordRelaxedTestCase(StockServicesTestCase):
type=models.StockChangeTypeEnum.ADD,
warehouse_id=self.warehouse_main.id,
source_type=models.StockChangeSourceEnum.PURCHASE,
source_id=self.purchase_order.id,
source_id=self.purchase_source_id,
products=products,
)
@@ -700,7 +683,7 @@ class CreateStockChangeRecordRelaxedTestCase(StockServicesTestCase):
type=models.StockChangeTypeEnum.ADD,
warehouse_id=self.warehouse_main.id,
source_type=models.StockChangeSourceEnum.PURCHASE,
source_id=self.purchase_order.id,
source_id=self.purchase_source_id,
products=products,
)
@@ -724,7 +707,7 @@ class CreateStockChangeRecordRelaxedTestCase(StockServicesTestCase):
type=models.StockChangeTypeEnum.ADD,
warehouse_id=self.warehouse_main.id,
source_type=models.StockChangeSourceEnum.PURCHASE,
source_id=self.purchase_order.id,
source_id=self.purchase_source_id,
products=products,
)