forked from erp-dev/erp
feat: mes module
This commit is contained in:
220
api_v2/tests.py
220
api_v2/tests.py
@@ -15,6 +15,7 @@ from api_v2.views.printing import PrintingJobByCustomerView
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from stateflow import models as stateflow_models
|
||||
from django.test.utils import override_settings
|
||||
from mes import models as mes_models
|
||||
|
||||
|
||||
class QuickCreateEmployeeUserAPITest(TestCase):
|
||||
@@ -2292,3 +2293,222 @@ class AgentTransportVehicleAPITest(TestCase):
|
||||
url = f'/api/v2/ai/transport-vehicles/{self.vehicle_a.license_plate}/'
|
||||
response = self.client.get(url, {'merchant_id': self.merchant.id})
|
||||
self.assertEqual(response.status_code, 401)
|
||||
|
||||
|
||||
@override_settings(AGENT_ACCESS_KEY='agent-test-key')
|
||||
class AgentMesAPITest(TestCase):
|
||||
def setUp(self):
|
||||
self.client = APIClient()
|
||||
self.device_list_url = '/api/v2/ai/mes/devices/'
|
||||
self.assignment_list_url = '/api/v2/ai/mes/production-assignments/'
|
||||
|
||||
self.merchant = basic_models.Merchant.objects.create(
|
||||
name='MES Agent 商户',
|
||||
type=basic_models.MerchantTypeEnum.FACTORY,
|
||||
)
|
||||
self.other_merchant = basic_models.Merchant.objects.create(
|
||||
name='其他 MES 商户',
|
||||
type=basic_models.MerchantTypeEnum.FACTORY,
|
||||
)
|
||||
self.user = get_user_model().objects.create_user(username='agent-mes-user', password='pass12345')
|
||||
self.other_user = get_user_model().objects.create_user(username='agent-mes-other-user', password='pass12345')
|
||||
self.employee = basic_models.Employee.objects.create(merchant=self.merchant, sys_user=self.user, name='MES员工')
|
||||
self.other_employee = basic_models.Employee.objects.create(merchant=self.other_merchant, sys_user=self.other_user, name='其他MES员工')
|
||||
|
||||
self.category = mes_models.DeviceCategory.objects.create(
|
||||
merchant=self.merchant,
|
||||
name='打印机',
|
||||
created_by=self.user,
|
||||
operator=self.employee,
|
||||
)
|
||||
self.device_a = mes_models.Device.objects.create(
|
||||
merchant=self.merchant,
|
||||
category=self.category,
|
||||
name='设备A',
|
||||
peak_capacity=120,
|
||||
capacity_unit=mes_models.CapacityUnitEnum.METER,
|
||||
extra={'capacity': {'per_hour': 120}},
|
||||
created_by=self.user,
|
||||
operator=self.employee,
|
||||
)
|
||||
self.device_b = mes_models.Device.objects.create(
|
||||
merchant=self.merchant,
|
||||
category=self.category,
|
||||
name='设备B',
|
||||
peak_capacity=90,
|
||||
capacity_unit=mes_models.CapacityUnitEnum.YARD,
|
||||
created_by=self.user,
|
||||
operator=self.employee,
|
||||
)
|
||||
self.other_category = mes_models.DeviceCategory.objects.create(
|
||||
merchant=self.other_merchant,
|
||||
name='他商户分类',
|
||||
created_by=self.other_user,
|
||||
operator=self.other_employee,
|
||||
)
|
||||
self.other_device = mes_models.Device.objects.create(
|
||||
merchant=self.other_merchant,
|
||||
category=self.other_category,
|
||||
name='他商户设备',
|
||||
peak_capacity=60,
|
||||
created_by=self.other_user,
|
||||
operator=self.other_employee,
|
||||
)
|
||||
|
||||
self.customer = basic_models.Customer.objects.create(
|
||||
merchant=self.merchant,
|
||||
name='测试客户',
|
||||
mobile='13800138011',
|
||||
)
|
||||
self.other_customer = basic_models.Customer.objects.create(
|
||||
merchant=self.other_merchant,
|
||||
name='他商户客户',
|
||||
mobile='13800138012',
|
||||
)
|
||||
self.printing_order = printing_models.PrintingOrder.objects.create(
|
||||
merchant=self.merchant,
|
||||
customer=self.customer,
|
||||
fabric='测试面料',
|
||||
width='150cm',
|
||||
created_by=self.user,
|
||||
)
|
||||
self.other_printing_order = printing_models.PrintingOrder.objects.create(
|
||||
merchant=self.other_merchant,
|
||||
customer=self.other_customer,
|
||||
fabric='其他面料',
|
||||
width='160cm',
|
||||
created_by=self.other_user,
|
||||
)
|
||||
self.content_type = ContentType.objects.get_for_model(printing_models.PrintingOrder)
|
||||
|
||||
self.assignment_published = mes_models.ProductionAssignment.objects.create(
|
||||
merchant=self.merchant,
|
||||
device=self.device_a,
|
||||
content_type=self.content_type,
|
||||
object_id=self.printing_order.id,
|
||||
assigner=self.employee,
|
||||
assignee=self.employee,
|
||||
production_quantity=300,
|
||||
status=mes_models.ProductionAssignmentStatusEnum.PUBLISHED,
|
||||
created_by=self.user,
|
||||
operator=self.employee,
|
||||
)
|
||||
self.assignment_draft = mes_models.ProductionAssignment.objects.create(
|
||||
merchant=self.merchant,
|
||||
device=self.device_b,
|
||||
content_type=self.content_type,
|
||||
object_id=self.printing_order.id,
|
||||
assigner=self.employee,
|
||||
production_quantity=100,
|
||||
status=mes_models.ProductionAssignmentStatusEnum.DRAFT,
|
||||
created_by=self.user,
|
||||
operator=self.employee,
|
||||
)
|
||||
self.other_assignment = mes_models.ProductionAssignment.objects.create(
|
||||
merchant=self.other_merchant,
|
||||
device=self.other_device,
|
||||
content_type=self.content_type,
|
||||
object_id=self.other_printing_order.id,
|
||||
assigner=self.other_employee,
|
||||
production_quantity=50,
|
||||
status=mes_models.ProductionAssignmentStatusEnum.PUBLISHED,
|
||||
created_by=self.other_user,
|
||||
operator=self.other_employee,
|
||||
)
|
||||
|
||||
mes_models.ProductionAssignment.objects.filter(id=self.assignment_published.id).update(
|
||||
created_at=timezone.make_aware(datetime.datetime(2026, 5, 1, 10, 0, 0))
|
||||
)
|
||||
mes_models.ProductionAssignment.objects.filter(id=self.assignment_draft.id).update(
|
||||
created_at=timezone.make_aware(datetime.datetime(2026, 5, 3, 12, 0, 0))
|
||||
)
|
||||
mes_models.ProductionAssignment.objects.filter(id=self.other_assignment.id).update(
|
||||
created_at=timezone.make_aware(datetime.datetime(2026, 5, 2, 9, 0, 0))
|
||||
)
|
||||
|
||||
def _headers(self, key='agent-test-key'):
|
||||
return {'HTTP_AUTHORIZATION': key}
|
||||
|
||||
def test_list_mes_devices_success(self):
|
||||
response = self.client.get(
|
||||
self.device_list_url,
|
||||
{'merchant_id': self.merchant.id},
|
||||
**self._headers(),
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.data['count'], 2)
|
||||
self.assertEqual(response.data['results'][0]['category']['name'], '打印机')
|
||||
|
||||
def test_list_mes_devices_isolates_by_merchant(self):
|
||||
response = self.client.get(
|
||||
self.device_list_url,
|
||||
{'merchant_id': self.other_merchant.id},
|
||||
**self._headers(),
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.data['count'], 1)
|
||||
self.assertEqual(response.data['results'][0]['id'], self.other_device.id)
|
||||
|
||||
def test_list_mes_devices_requires_access_key(self):
|
||||
response = self.client.get(self.device_list_url, {'merchant_id': self.merchant.id})
|
||||
self.assertEqual(response.status_code, 401)
|
||||
|
||||
def test_list_mes_production_assignments_filters_by_date_range(self):
|
||||
response = self.client.get(
|
||||
self.assignment_list_url,
|
||||
{
|
||||
'merchant_id': self.merchant.id,
|
||||
'start_date': '2026-05-01',
|
||||
'end_date': '2026-05-02',
|
||||
},
|
||||
**self._headers(),
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.data['count'], 1)
|
||||
self.assertEqual(response.data['results'][0]['id'], self.assignment_published.id)
|
||||
self.assertEqual(response.data['results'][0]['device']['id'], self.device_a.id)
|
||||
|
||||
def test_list_mes_production_assignments_supports_status_and_device_filter(self):
|
||||
response = self.client.get(
|
||||
self.assignment_list_url,
|
||||
{
|
||||
'merchant_id': self.merchant.id,
|
||||
'start_date': '2026-05-01',
|
||||
'end_date': '2026-05-31',
|
||||
'device_id': self.device_b.id,
|
||||
'status': mes_models.ProductionAssignmentStatusEnum.DRAFT,
|
||||
},
|
||||
**self._headers(),
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.data['count'], 1)
|
||||
self.assertEqual(response.data['results'][0]['id'], self.assignment_draft.id)
|
||||
|
||||
def test_list_mes_production_assignments_rejects_invalid_date_range(self):
|
||||
response = self.client.get(
|
||||
self.assignment_list_url,
|
||||
{
|
||||
'merchant_id': self.merchant.id,
|
||||
'start_date': '2026-05-31',
|
||||
'end_date': '2026-05-01',
|
||||
},
|
||||
**self._headers(),
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 400)
|
||||
self.assertIn('end_date', response.data)
|
||||
|
||||
def test_list_mes_production_assignments_requires_access_key(self):
|
||||
response = self.client.get(
|
||||
self.assignment_list_url,
|
||||
{
|
||||
'merchant_id': self.merchant.id,
|
||||
'start_date': '2026-05-01',
|
||||
'end_date': '2026-05-31',
|
||||
},
|
||||
)
|
||||
self.assertEqual(response.status_code, 401)
|
||||
|
||||
Reference in New Issue
Block a user