1
0
forked from erp-dev/erp

feat: retry haobuye sync order

This commit is contained in:
2026-04-07 16:56:46 +08:00
parent ebd687ccdd
commit 76ea445880
15 changed files with 1098 additions and 118 deletions

View File

@@ -745,6 +745,18 @@ class SalesItemDetailAPITestCase(APITestCase):
mobile="13800138032",
status=basic_models.EmployeeStatusEnum.ACTIVE,
)
self.same_merchant_other_user = User.objects.create_user(
username="sales_item_detail_same_merchant_user",
password="testpass123",
email="sales_item_detail_same_merchant@example.com",
)
self.same_merchant_other_employee = basic_models.Employee.objects.create(
sys_user=self.same_merchant_other_user,
merchant=self.merchant,
name="同商户其它员工",
mobile="13800138033",
status=basic_models.EmployeeStatusEnum.ACTIVE,
)
self.customer = basic_models.Customer.objects.create(
merchant=self.merchant,
@@ -783,6 +795,47 @@ class SalesItemDetailAPITestCase(APITestCase):
unit="",
created_by=self.user,
)
self.new_printing_job = printing_models.PrintingJob.objects.create(
merchant=self.merchant,
printing_order=self.printing_order,
product=self.product,
quantity=30,
unit="",
created_by=self.user,
)
self.other_customer = basic_models.Customer.objects.create(
merchant=self.other_merchant,
name="其它详情测试客户",
mobile="13900139034",
area="苏州",
)
self.other_category = basic_models.ProductCategory.objects.create(
merchant=self.other_merchant,
name="其它详情分类",
)
self.other_product = basic_models.Product.objects.create(
merchant=self.other_merchant,
category=self.other_category,
name="其它详情产品",
human_id="DETAIL002",
)
self.other_printing_order = printing_models.PrintingOrder.objects.create(
merchant=self.other_merchant,
customer=self.other_customer,
fabric="其它详情面料",
width="160cm",
process=self.process,
created_by=self.other_user,
external_order_id="EXT-DETAIL-002",
)
self.foreign_printing_job = printing_models.PrintingJob.objects.create(
merchant=self.other_merchant,
printing_order=self.other_printing_order,
product=self.other_product,
quantity=40,
unit="",
created_by=self.other_user,
)
self.sales_item = shipment_models.SalesItem.objects.create(
merchant=self.merchant,
name="详情销售品",
@@ -943,6 +996,118 @@ class SalesItemDetailAPITestCase(APITestCase):
self.sales_item.refresh_from_db()
self.assertIsNone(self.sales_item.delete_at)
def test_rebuild_sales_item_success_with_original_quantity(self):
resp = self.client.post(
f"/api/v1/shipment/sales-items/{self.sales_item.id}/rebuild/",
{
"new_printing_job_id": self.new_printing_job.id,
},
format="json",
)
self.assertEqual(resp.status_code, status.HTTP_201_CREATED)
data = resp.json()
self.assertEqual(data["detail"], "销售品已重建")
self.assertEqual(data["old_sales_item_id"], self.sales_item.id)
self.assertNotEqual(data["new_sales_item_id"], self.sales_item.id)
self.sales_item.refresh_from_db()
self.assertIsNotNone(self.sales_item.delete_at)
self.assertEqual(self.sales_item.delete_by, self.user)
new_sales_item = shipment_models.SalesItem.objects.get(id=data["new_sales_item_id"])
self.assertEqual(new_sales_item.created_by, self.user)
self.assertEqual(new_sales_item.printing_job_id, self.new_printing_job.id)
self.assertEqual(new_sales_item.quantity, Decimal("88.00"))
self.assertEqual(new_sales_item.name, self.sales_item.name)
self.assertEqual(new_sales_item.unit, self.sales_item.unit)
self.assertEqual(new_sales_item.customer_id, self.sales_item.customer_id)
rebuild_record = shipment_models.SalesItemRebuildRecord.objects.get(
id=data["rebuild_record_id"]
)
self.assertEqual(rebuild_record.old_sales_item_id, self.sales_item.id)
self.assertEqual(rebuild_record.new_sales_item_id, new_sales_item.id)
self.assertEqual(rebuild_record.operator_id, self.user.id)
self.assertEqual(rebuild_record.old_printing_job_id, self.printing_job.id)
self.assertEqual(rebuild_record.new_printing_job_id, self.new_printing_job.id)
self.assertEqual(rebuild_record.old_quantity, Decimal("88.00"))
self.assertEqual(rebuild_record.new_quantity, Decimal("88.00"))
def test_rebuild_sales_item_success_with_override_quantity(self):
resp = self.client.post(
f"/api/v1/shipment/sales-items/{self.sales_item.id}/rebuild/",
{
"new_printing_job_id": self.new_printing_job.id,
"quantity": "66.50",
},
format="json",
)
self.assertEqual(resp.status_code, status.HTTP_201_CREATED)
new_sales_item = shipment_models.SalesItem.objects.get(
id=resp.json()["new_sales_item_id"]
)
self.assertEqual(new_sales_item.quantity, Decimal("66.50"))
def test_rebuild_sales_item_not_found(self):
resp = self.client.post(
"/api/v1/shipment/sales-items/999999/rebuild/",
{
"new_printing_job_id": self.new_printing_job.id,
},
format="json",
)
self.assertEqual(resp.status_code, status.HTTP_404_NOT_FOUND)
def test_rebuild_sales_item_creator_mismatch_returns_403(self):
self.client.force_authenticate(user=self.same_merchant_other_user)
resp = self.client.post(
f"/api/v1/shipment/sales-items/{self.sales_item.id}/rebuild/",
{
"new_printing_job_id": self.new_printing_job.id,
},
format="json",
)
self.assertEqual(resp.status_code, status.HTTP_403_FORBIDDEN)
self.assertEqual(resp.json()["detail"], "只有销售品创建者才能执行重建")
def test_rebuild_sales_item_rejects_invalid_new_printing_job(self):
resp = self.client.post(
f"/api/v1/shipment/sales-items/{self.sales_item.id}/rebuild/",
{
"new_printing_job_id": self.foreign_printing_job.id,
},
format="json",
)
self.assertEqual(resp.status_code, status.HTTP_400_BAD_REQUEST)
self.assertIn("不存在或不属于当前商户", resp.json()["detail"])
def test_rebuild_sales_item_rejects_when_already_bound_to_shipment(self):
shipment = shipment_models.Shipment.objects.create(
merchant=self.merchant,
customer=self.customer,
shipment_date="2026-04-03",
created_by=self.user,
)
self.sales_item.shipment = shipment
self.sales_item.save(update_fields=["shipment", "updated_at"])
resp = self.client.post(
f"/api/v1/shipment/sales-items/{self.sales_item.id}/rebuild/",
{
"new_printing_job_id": self.new_printing_job.id,
},
format="json",
)
self.assertEqual(resp.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(resp.json()["detail"], "已关联出货单的销售品不允许删除")
class ShipmentCreateAPITestCase(TestCase):
"""测试创建出货单 API"""