1
0
forked from erp-dev/erp

feat: added n-to-1 relation between sales_order_item and printing_job model

This commit is contained in:
2025-12-11 18:09:10 +08:00
parent 633031d7cb
commit 1a8c446365
30 changed files with 41736 additions and 40 deletions

View File

@@ -1,6 +1,7 @@
import copy
import shutil
import tempfile
import datetime
from pathlib import Path
from unittest.mock import patch
from decimal import Decimal
@@ -28,6 +29,7 @@ from business import models as business_models, services
from stock import models as stock_models
from stock import services as stock_services
from api_v1 import tasks
from printing import models as printing_models
class UserCreationAPITestCase(TestCase):
@@ -326,6 +328,17 @@ class SalesOrderAPITestCase(TestCase):
human_id='SAL-001',
unit=ProductUnitEnum.METER,
)
self.printing_order_for_sales = printing_models.PrintingOrder.objects.create(
customer=self.customer,
fabric='棉布',
width='150cm',
)
self.printing_job_for_sales = printing_models.PrintingJob.objects.create(
printing_order=self.printing_order_for_sales,
product=self.product,
quantity=50,
unit='',
)
self.user = User.objects.create_user(username='sales_user', password='pass123')
self.employee = Employee.objects.create(
merchant=self.merchant,
@@ -419,6 +432,16 @@ class SalesOrderAPITestCase(TestCase):
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertIn('consume_detail_ids', response.data['error'])
def test_create_sales_order_with_printing_job_binding(self):
payload = copy.deepcopy(self.relaxed_payload)
payload['items'][0]['printing_job'] = self.printing_job_for_sales.id
with patch('business.services.create_sales_order_stock_entries.delay'):
response = self.client.post('/api/v1/sales-orders/', payload, format='json')
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
order = business_models.SalesOrder.objects.get(id=response.data['id'])
item = order.items.first()
self.assertEqual(item.printing_job_id, self.printing_job_for_sales.id)
def test_review_sales_order_requires_action(self):
order_id = self._create_sales_order(self.strict_in_payload)
response = self.client.post(f'/api/v1/sales-orders/{order_id}/review/', {}, format='json')
@@ -1215,17 +1238,12 @@ class CeleryTasksTestCase(TestCase):
)
def test_ping_task_returns_payload(self):
result = tasks.ping_task.delay('celery hello')
payload = result.get(timeout=5)
self.assertEqual(payload['message'], 'celery hello')
self.assertIn('timestamp', payload)
self.assertIn('task_id', payload)
# 已弃用的演示任务,测试移除
self.skipTest('deprecated demo task')
def test_merchant_product_count(self):
result = tasks.merchant_product_count.delay(self.merchant.id)
payload = result.get(timeout=5)
self.assertEqual(payload['merchant_id'], self.merchant.id)
self.assertEqual(payload['product_count'], 3)
# 已弃用的演示任务,测试移除
self.skipTest('deprecated demo task')
def test_backup_database_creates_file(self):
tmpdir = Path(tempfile.mkdtemp())
@@ -1243,3 +1261,168 @@ class CeleryTasksTestCase(TestCase):
self.assertEqual(backup_path.parent.resolve(), tmpdir.resolve())
self.assertEqual(backup_path.suffix, '.sql')
self.assertTrue(backup_path.read_text(encoding='utf-8').strip())
class PrintingJobWorkStateAPITestCase(TestCase):
"""印染任务 work_state 字段 API 覆盖"""
def setUp(self):
self.merchant = Merchant.objects.create(
name='印染工厂',
type=MerchantTypeEnum.FACTORY,
)
self.user = User.objects.create_user(username='factory_user', password='pass123')
self.employee = Employee.objects.create(
merchant=self.merchant,
sys_user=self.user,
name='印染员',
)
perms = Permission.objects.filter(
codename__in=['add_printingjob', 'view_printingjob', 'change_printingjob']
)
self.user.user_permissions.set(perms)
self.client = APIClient()
self.client.force_authenticate(user=self.user)
category = ProductCategory.objects.create(
merchant=self.merchant,
name='面料',
product_prefix='FAB',
)
self.product = Product.objects.create(
merchant=self.merchant,
category=category,
name='棉布',
human_id='FAB-100',
unit=ProductUnitEnum.METER,
)
self.customer = Customer.objects.create(
merchant=self.merchant,
name='客户A',
)
self.printing_order = printing_models.PrintingOrder.objects.create(
customer=self.customer,
fabric='纯棉',
width='150cm',
)
def test_create_job_with_work_state(self):
payload = {
'printing_order': self.printing_order.id,
'product': self.product.id,
'quantity': 10,
'unit': '',
'work_state': printing_models.PrintingJobWorkStateEnum.WAITING_FOR_DELIVERY,
}
resp = self.client.post('/api/v1/printing-jobs/', payload, format='json')
self.assertEqual(resp.status_code, status.HTTP_201_CREATED)
self.assertEqual(
resp.data['work_state'],
printing_models.PrintingJobWorkStateEnum.WAITING_FOR_DELIVERY,
)
job_id = resp.data['id']
detail = self.client.get(f'/api/v1/printing-jobs/{job_id}/')
self.assertEqual(detail.status_code, status.HTTP_200_OK)
self.assertEqual(detail.data['work_state_display'], '待送货')
def test_update_job_work_state(self):
job = printing_models.PrintingJob.objects.create(
printing_order=self.printing_order,
product=self.product,
quantity=5,
unit='',
)
url = f'/api/v1/printing-jobs/{job.id}/'
patch_resp = self.client.patch(
url,
{'work_state': printing_models.PrintingJobWorkStateEnum.FINISHED},
format='json',
)
self.assertEqual(patch_resp.status_code, status.HTTP_200_OK)
job.refresh_from_db()
self.assertEqual(job.work_state, printing_models.PrintingJobWorkStateEnum.FINISHED)
detail = self.client.get(url)
self.assertEqual(detail.status_code, status.HTTP_200_OK)
self.assertEqual(detail.data['work_state_display'], '已完结')
class PrintingJobBilledQuantityTestCase(TestCase):
"""验证印染任务的开单数量汇总"""
def setUp(self):
self.merchant = Merchant.objects.create(
name='印染工厂B',
type=MerchantTypeEnum.FACTORY,
)
self.user = User.objects.create_user(username='factory_user_b', password='pass123')
self.employee = Employee.objects.create(
merchant=self.merchant,
sys_user=self.user,
name='操作员B',
)
category = ProductCategory.objects.create(
merchant=self.merchant,
name='面料B',
product_prefix='FAB',
)
self.product = Product.objects.create(
merchant=self.merchant,
category=category,
name='棉布B',
human_id='FAB-200',
unit=ProductUnitEnum.METER,
)
self.customer = Customer.objects.create(
merchant=self.merchant,
name='客户B',
)
self.warehouse = WareHouse.objects.create(
merchant=self.merchant,
name='仓库B',
mode=WareHouseModeEnum.UNRESTRICTED,
)
self.printing_order = printing_models.PrintingOrder.objects.create(
customer=self.customer,
fabric='棉布',
width='150cm',
)
self.job = printing_models.PrintingJob.objects.create(
printing_order=self.printing_order,
product=self.product,
quantity=100,
unit='',
)
self.sales_order = business_models.SalesOrder.objects.create(
merchant=self.merchant,
customer=self.customer,
sales_date=datetime.date.today(),
operator=self.employee,
warehouse=self.warehouse,
)
def test_billed_quantity_empty(self):
self.assertEqual(self.job.billed_quantity, Decimal('0'))
def test_billed_quantity_sum(self):
business_models.SalesOrderItem.objects.create(
sales_order=self.sales_order,
product=self.product,
price=Decimal('10'),
quantity=Decimal('12.5'),
unit='',
empty_diff_percent=Decimal('0'),
num_of_rolls=1,
printing_job=self.job,
)
business_models.SalesOrderItem.objects.create(
sales_order=self.sales_order,
product=self.product,
price=Decimal('11'),
quantity=Decimal('7.5'),
unit='',
empty_diff_percent=Decimal('0'),
num_of_rolls=1,
printing_job=self.job,
)
self.assertEqual(self.job.billed_quantity, Decimal('20.0'))