1
0
forked from erp-dev/erp

feat: agent api complete

This commit is contained in:
2026-04-15 00:20:13 +08:00
parent 714d6287fe
commit 4f3109546d
9 changed files with 553 additions and 6 deletions

View File

@@ -352,9 +352,81 @@ class AgentUnshippedShipmentListAPITest(TestCase):
)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data['count'], 1)
self.assertEqual(response.data['results'][0]['id'], self.unshipped_target.id)
self.assertEqual(response.data['results'][0]['customer_name'], '客户A')
self.assertIsNone(response.data['results'][0]['delivery'])
result = response.data['results'][0]
self.assertEqual(result['id'], self.unshipped_target.id)
self.assertEqual(result['customer_name'], '客户A')
self.assertIsNone(result['delivery'])
self.assertIn('sales_items', result)
def test_list_unshipped_shipments_includes_sales_items_with_printing_job_width(self):
category = basic_models.ProductCategory.objects.create(
merchant=self.merchant, name='品类', product_prefix='T',
)
product = basic_models.Product.objects.create(
merchant=self.merchant, category=category, name='产品甲',
)
printing_order = printing_models.PrintingOrder.objects.create(
customer=self.customer,
fabric='',
width='150cm',
)
printing_job = printing_models.PrintingJob.objects.create(
printing_order=printing_order,
product=product,
quantity=100,
unit='',
)
item_with_job = shipment_models.SalesItem.objects.create(
merchant=self.merchant,
shipment=self.unshipped_target,
name='销售品甲',
quantity=50,
unit=shipment_models.UnitChoices.PIECE,
printing_job_id=printing_job.id,
)
item_no_job = shipment_models.SalesItem.objects.create(
merchant=self.merchant,
shipment=self.unshipped_target,
name='销售品乙',
quantity=10,
unit=shipment_models.UnitChoices.PIECE,
)
response = self.client.get(
self.url,
{'merchant_id': self.merchant.id, 'area': '华东'},
**self._headers(),
)
self.assertEqual(response.status_code, 200)
result = response.data['results'][0]
items_by_id = {i['id']: i for i in result['sales_items']}
self.assertIn(item_with_job.id, items_by_id)
self.assertEqual(items_by_id[item_with_job.id]['printing_job_width'], '150cm')
self.assertEqual(items_by_id[item_with_job.id]['printing_job_id'], printing_job.id)
self.assertIn(item_no_job.id, items_by_id)
self.assertIsNone(items_by_id[item_no_job.id]['printing_job_width'])
def test_list_unshipped_shipments_excludes_soft_deleted_sales_items(self):
item = shipment_models.SalesItem.objects.create(
merchant=self.merchant,
shipment=self.unshipped_target,
name='待删除品',
quantity=5,
unit=shipment_models.UnitChoices.PIECE,
delete_at=datetime.datetime(2026, 4, 14, 0, 0, tzinfo=datetime.timezone.utc),
)
response = self.client.get(
self.url,
{'merchant_id': self.merchant.id, 'area': '华东'},
**self._headers(),
)
self.assertEqual(response.status_code, 200)
result = response.data['results'][0]
item_ids = [i['id'] for i in result['sales_items']]
self.assertNotIn(item.id, item_ids)
def test_list_unshipped_shipments_requires_access_key(self):
response = self.client.get(
@@ -2093,3 +2165,130 @@ class PrintingJobBatchAddParametersAPITest(TestCase):
format='json'
)
self.assertEqual(response.status_code, 401)
@override_settings(AGENT_ACCESS_KEY='agent-test-key')
class AgentTransportVehicleAPITest(TestCase):
def setUp(self):
self.client = APIClient()
self.list_url = '/api/v2/ai/transport-vehicles/'
self.merchant = basic_models.Merchant.objects.create(
name='车辆商户',
type=basic_models.MerchantTypeEnum.FACTORY,
)
self.other_merchant = basic_models.Merchant.objects.create(
name='其他商户',
type=basic_models.MerchantTypeEnum.FACTORY,
)
self.vehicle_a = basic_models.TransportVehicle.objects.create(
merchant=self.merchant,
name='大卡车',
license_plate='粤A12345',
)
self.cap_a1 = basic_models.TransportVehicleMaterialCapacity.objects.create(
merchant=self.merchant,
transport_vehicle=self.vehicle_a,
material_name='坯布',
capacity=500,
)
self.cap_a2 = basic_models.TransportVehicleMaterialCapacity.objects.create(
merchant=self.merchant,
transport_vehicle=self.vehicle_a,
material_name='成品',
capacity=300,
)
self.vehicle_b = basic_models.TransportVehicle.objects.create(
merchant=self.merchant,
name='小货车',
license_plate='粤B67890',
)
self.other_vehicle = basic_models.TransportVehicle.objects.create(
merchant=self.other_merchant,
name='他商户车',
license_plate='粤A12345', # same plate, different merchant
)
def _headers(self, key='agent-test-key'):
return {'HTTP_AUTHORIZATION': key}
# --- list ---
def test_list_vehicles_success(self):
response = self.client.get(
self.list_url,
{'merchant_id': self.merchant.id},
**self._headers(),
)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data['count'], 2)
ids = [r['id'] for r in response.data['results']]
self.assertIn(self.vehicle_a.id, ids)
self.assertIn(self.vehicle_b.id, ids)
def test_list_vehicles_includes_material_capacities(self):
response = self.client.get(
self.list_url,
{'merchant_id': self.merchant.id},
**self._headers(),
)
self.assertEqual(response.status_code, 200)
vehicle_a_data = next(r for r in response.data['results'] if r['id'] == self.vehicle_a.id)
material_names = {c['material_name'] for c in vehicle_a_data['material_capacities']}
self.assertEqual(material_names, {'坯布', '成品'})
def test_list_vehicles_isolates_by_merchant(self):
response = self.client.get(
self.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_vehicle.id)
def test_list_vehicles_requires_merchant_id(self):
response = self.client.get(self.list_url, **self._headers())
self.assertEqual(response.status_code, 400)
self.assertIn('merchant_id', response.data)
def test_list_vehicles_rejects_nonexistent_merchant(self):
response = self.client.get(
self.list_url,
{'merchant_id': 999999},
**self._headers(),
)
self.assertEqual(response.status_code, 400)
def test_list_vehicles_requires_access_key(self):
response = self.client.get(self.list_url, {'merchant_id': self.merchant.id})
self.assertEqual(response.status_code, 401)
# --- detail ---
def test_detail_vehicle_success(self):
url = f'/api/v2/ai/transport-vehicles/{self.vehicle_a.license_plate}/'
response = self.client.get(url, {'merchant_id': self.merchant.id}, **self._headers())
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data['id'], self.vehicle_a.id)
self.assertEqual(response.data['license_plate'], '粤A12345')
capacities = {c['material_name']: c['capacity'] for c in response.data['material_capacities']}
self.assertEqual(capacities, {'坯布': 500, '成品': 300})
def test_detail_vehicle_same_plate_different_merchant_returns_404(self):
# other_merchant also has '粤A12345', but querying with self.merchant should return vehicle_a
url = f'/api/v2/ai/transport-vehicles/{self.vehicle_a.license_plate}/'
response = self.client.get(url, {'merchant_id': self.other_merchant.id}, **self._headers())
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data['id'], self.other_vehicle.id)
def test_detail_vehicle_not_found_returns_404(self):
url = '/api/v2/ai/transport-vehicles/粤Z99999/'
response = self.client.get(url, {'merchant_id': self.merchant.id}, **self._headers())
self.assertEqual(response.status_code, 404)
def test_detail_vehicle_requires_access_key(self):
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)