1
0
forked from erp-dev/erp

fix: docs

This commit is contained in:
2026-06-13 11:44:15 +08:00
parent 0bcaa2db44
commit 9a1c92febf
10 changed files with 195 additions and 57 deletions

View File

@@ -1437,6 +1437,20 @@ class BusinessRedFlushAPITestCase(TestCase):
order.refresh_from_db()
self.assertEqual(order.status, business_models.PurchaseOrderStatusEnum.APPROVED)
self.assertTrue(order.is_red_flushed)
self.assertEqual(
business_models.BalanceChangeRecord.objects.filter(
source_type=business_models.BalanceChangeSourceEnum.PURCHASE_ORDER,
source_id=order.id,
red_flush_id=order.red_flush_id,
).count(),
2,
)
self.assertTrue(
stock_models.StockChangeRecord.objects.filter(
source_type=stock_models.StockChangeSourceEnum.OFFSET,
red_flush_id=order.red_flush_id,
).exists()
)
def test_sales_order_red_flush_success(self):
order = self._create_approved_sales_order()
@@ -1495,6 +1509,54 @@ class BusinessRedFlushAPITestCase(TestCase):
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertTrue(response.data['is_red_flushed'])
def test_red_flush_requires_employee_permission(self):
order = self._create_approved_payment_order()
user_without_employee = User.objects.create_user(username='red_flush_no_employee', password='pass123')
self.client.force_authenticate(user=user_without_employee)
response = self.client.post(
f'/api/v1/payment-orders/{order.id}/red-flush/',
{'reason': '无员工身份红冲'},
format='json',
)
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
self.assertEqual(response.data['error'], '无权限访问')
order.refresh_from_db()
self.assertFalse(order.is_red_flushed)
def test_purchase_order_red_flush_stock_failure_returns_400_and_rolls_back(self):
order = services.create_purchase_order(
merchant=self.merchant,
supplier=self.supplier,
order_date=datetime.date(2025, 11, 26),
warehouse=self.warehouse,
operator=self.employee,
items=self._items(),
)
services.review_purchase_order(
purchase_order=order,
target_status=business_models.PurchaseOrderStatusEnum.APPROVED,
reviewed_by=self.user,
)
response = self.client.post(
f'/api/v1/purchase-orders/{order.id}/red-flush/',
{'reason': '缺库存记录红冲'},
format='json',
)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertIn('采购单缺少可红冲的库存记录', response.data['error'])
order.refresh_from_db()
self.assertFalse(order.is_red_flushed)
records = business_models.BalanceChangeRecord.objects.filter(
source_type=business_models.BalanceChangeSourceEnum.PURCHASE_ORDER,
source_id=order.id,
)
self.assertEqual(records.count(), 1)
self.assertFalse(records.first().cancelled)
def test_red_flush_rejects_external_payment_order(self):
order = self._create_approved_payment_order()
order.is_external_source = True

View File

@@ -167,7 +167,9 @@
- **响应**`{"customer": 12, "customer_name": "张三", "balance": "1234.50"}`
- `balance` 为字符串格式的十进制数,正数表示客户欠款,应收;负数表示已收超额。
如需对 `items` 结构、仓库模式审批流程做深入了解,请参阅:
如需对 `items` 结构、仓库模式审批流程或红冲 API 做深入了解,请参阅:
- `docs/2026-06-12_business_red_flush_api.md`
- `docs/2026-06-12_business_red_flush_design.md`
- `docs/purchase_order_approval_and_red_flush.md`
- `docs/sales_order_approval_and_red_flush.md`

View File

@@ -364,6 +364,7 @@ class PrintingJobListSerializer(serializers.ModelSerializer):
is_sales_order_bound = serializers.SerializerMethodField()
billed_quantity = serializers.DecimalField(max_digits=18, decimal_places=2, read_only=True)
merchant_id = serializers.IntegerField(source='merchant.id', read_only=True, allow_null=True)
fabric = serializers.SerializerMethodField()
class Meta:
model = models.PrintingJob
@@ -377,6 +378,7 @@ class PrintingJobListSerializer(serializers.ModelSerializer):
'is_sales_order_bound',
'batch_advance_records',
'saleitems',
'fabric',
'created_at', 'updated_at'
]
read_only_fields = [
@@ -449,6 +451,9 @@ class PrintingJobListSerializer(serializers.ModelSerializer):
def get_is_sales_order_bound(self, obj):
return _get_is_sales_order_bound(obj)
def get_fabric(self, obj):
return obj.printing_order.fabric
class PrintingJobDetailSerializer(serializers.ModelSerializer):
"""印染款式明细详情序列化器"""
@@ -470,6 +475,7 @@ class PrintingJobDetailSerializer(serializers.ModelSerializer):
is_sales_order_bound = serializers.SerializerMethodField()
billed_quantity = serializers.DecimalField(max_digits=18, decimal_places=2, read_only=True)
merchant_id = serializers.IntegerField(source='merchant.id', read_only=True, allow_null=True)
fabric = serializers.SerializerMethodField()
class Meta:
model = models.PrintingJob
@@ -483,6 +489,7 @@ class PrintingJobDetailSerializer(serializers.ModelSerializer):
'is_sales_order_bound',
'batch_advance_records',
'saleitems',
'fabric',
'created_at', 'updated_at'
]
read_only_fields = [
@@ -524,6 +531,9 @@ class PrintingJobDetailSerializer(serializers.ModelSerializer):
def get_is_sales_order_bound(self, obj):
return _get_is_sales_order_bound(obj)
def get_fabric(self, obj):
return obj.printing_order.fabric
class PrintingJobCreateUpdateSerializer(serializers.ModelSerializer):
"""印染款式明细创建/更新序列化器"""