forked from erp-dev/erp
feat: mission category
This commit is contained in:
@@ -194,3 +194,33 @@ class VehicleTransportRecordAdmin(AdminBase):
|
||||
list_display = ('driver_name', 'contact_number', 'delivery_date')
|
||||
search_fields = ('driver_name', 'contact_number')
|
||||
list_filter = ('vehicle_type',)
|
||||
|
||||
|
||||
class TransportVehicleMaterialCapacityInline(admin.TabularInline):
|
||||
model = models.TransportVehicleMaterialCapacity
|
||||
extra = 0
|
||||
fields = ('material_name', 'capacity')
|
||||
|
||||
|
||||
@admin.register(models.TransportVehicle)
|
||||
class TransportVehicleAdmin(AdminBase):
|
||||
inlines = [TransportVehicleMaterialCapacityInline]
|
||||
list_display = ('name', 'license_plate')
|
||||
search_fields = ('name', 'license_plate')
|
||||
|
||||
def save_formset(self, request, form, formset, change):
|
||||
instances = formset.save(commit=False)
|
||||
for obj in formset.deleted_objects:
|
||||
obj.delete()
|
||||
for instance in instances:
|
||||
if isinstance(instance, models.TransportVehicleMaterialCapacity):
|
||||
instance.merchant = form.instance.merchant
|
||||
instance.save()
|
||||
formset.save_m2m()
|
||||
|
||||
|
||||
@admin.register(models.TransportVehicleMaterialCapacity)
|
||||
class TransportVehicleMaterialCapacityAdmin(AdminBase):
|
||||
list_display = ('transport_vehicle', 'material_name', 'capacity')
|
||||
search_fields = ('transport_vehicle__name', 'transport_vehicle__license_plate', 'material_name')
|
||||
list_filter = ('transport_vehicle',)
|
||||
|
||||
45
basic_info/migrations/0026_transportvehicle_and_capacity.py
Normal file
45
basic_info/migrations/0026_transportvehicle_and_capacity.py
Normal file
@@ -0,0 +1,45 @@
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('basic_info', '0025_customer_uniq_customer_merchant_name'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='TransportVehicle',
|
||||
fields=[
|
||||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
|
||||
('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
|
||||
('id', models.BigAutoField(primary_key=True, serialize=False)),
|
||||
('name', models.CharField(max_length=100, verbose_name='车辆名称')),
|
||||
('license_plate', models.CharField(max_length=20, verbose_name='车牌号码')),
|
||||
('merchant', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='transport_vehicles', to='basic_info.merchant', verbose_name='所属商户')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '运输车辆',
|
||||
'verbose_name_plural': '运输车辆',
|
||||
'unique_together': {('merchant', 'license_plate')},
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='TransportVehicleMaterialCapacity',
|
||||
fields=[
|
||||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
|
||||
('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
|
||||
('id', models.BigAutoField(primary_key=True, serialize=False)),
|
||||
('material_name', models.CharField(max_length=100, verbose_name='物料名')),
|
||||
('capacity', models.PositiveIntegerField(verbose_name='容量(条)')),
|
||||
('merchant', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='transport_vehicle_material_capacities', to='basic_info.merchant', verbose_name='所属商户')),
|
||||
('transport_vehicle', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='material_capacities', to='basic_info.transportvehicle', verbose_name='运输车辆')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '运输车辆物料容量',
|
||||
'verbose_name_plural': '运输车辆物料容量',
|
||||
'unique_together': {('transport_vehicle', 'material_name')},
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -574,6 +574,42 @@ class VehicleTransportRecord(ModelBase):
|
||||
verbose_name_plural = '司机车次'
|
||||
|
||||
|
||||
class TransportVehicle(ModelBase):
|
||||
id = models.BigAutoField(primary_key=True)
|
||||
merchant = models.ForeignKey('Merchant', on_delete=models.PROTECT, related_name='transport_vehicles', verbose_name='所属商户')
|
||||
name = models.CharField(max_length=100, verbose_name='车辆名称')
|
||||
license_plate = models.CharField(max_length=20, verbose_name='车牌号码')
|
||||
|
||||
def __str__(self):
|
||||
return f'{self.name} ({self.license_plate})'
|
||||
|
||||
class Meta:
|
||||
verbose_name = '运输车辆'
|
||||
verbose_name_plural = '运输车辆'
|
||||
unique_together = ('merchant', 'license_plate')
|
||||
|
||||
|
||||
class TransportVehicleMaterialCapacity(ModelBase):
|
||||
id = models.BigAutoField(primary_key=True)
|
||||
merchant = models.ForeignKey('Merchant', on_delete=models.PROTECT, related_name='transport_vehicle_material_capacities', verbose_name='所属商户')
|
||||
transport_vehicle = models.ForeignKey(
|
||||
TransportVehicle,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='material_capacities',
|
||||
verbose_name='运输车辆',
|
||||
)
|
||||
material_name = models.CharField(max_length=100, verbose_name='物料名')
|
||||
capacity = models.PositiveIntegerField(verbose_name='容量(条)')
|
||||
|
||||
def __str__(self):
|
||||
return f'{self.transport_vehicle.name}-{self.material_name}:{self.capacity}'
|
||||
|
||||
class Meta:
|
||||
verbose_name = '运输车辆物料容量'
|
||||
verbose_name_plural = '运输车辆物料容量'
|
||||
unique_together = ('transport_vehicle', 'material_name')
|
||||
|
||||
|
||||
class MerchantSettingTypeEnum(models.TextChoices):
|
||||
"""商户设置类型枚举"""
|
||||
STR = 'str', '字符串'
|
||||
|
||||
@@ -7,7 +7,7 @@ from django.core.exceptions import ValidationError
|
||||
from .models import (
|
||||
Merchant, MerchantTypeEnum, WareHouse, WarehouseTypeEnum,
|
||||
WareHouseModeEnum, EmployeeType, Employee, EmployeeStatusEnum,
|
||||
FrontendPage, FrontendPageTypeEnum
|
||||
FrontendPage, FrontendPageTypeEnum, TransportVehicle, TransportVehicleMaterialCapacity
|
||||
)
|
||||
|
||||
|
||||
@@ -171,6 +171,45 @@ class EmployeeTypeTestCase(TestCase):
|
||||
self.assertEqual(emp_type.employees.count(), 2)
|
||||
|
||||
|
||||
class TransportVehicleTestCase(TestCase):
|
||||
def setUp(self):
|
||||
self.merchant = Merchant.objects.create(
|
||||
name='运输商户',
|
||||
type=MerchantTypeEnum.STORE
|
||||
)
|
||||
|
||||
def test_create_transport_vehicle_with_material_capacity(self):
|
||||
vehicle = TransportVehicle.objects.create(
|
||||
merchant=self.merchant,
|
||||
name='9.6米厢车',
|
||||
license_plate='浙A12345'
|
||||
)
|
||||
capacity = TransportVehicleMaterialCapacity.objects.create(
|
||||
merchant=self.merchant,
|
||||
transport_vehicle=vehicle,
|
||||
material_name='棉布',
|
||||
capacity=120
|
||||
)
|
||||
|
||||
self.assertEqual(vehicle.license_plate, '浙A12345')
|
||||
self.assertEqual(str(vehicle), '9.6米厢车 (浙A12345)')
|
||||
self.assertEqual(capacity.capacity, 120)
|
||||
self.assertEqual(vehicle.material_capacities.count(), 1)
|
||||
|
||||
def test_transport_vehicle_license_plate_unique_per_merchant(self):
|
||||
TransportVehicle.objects.create(
|
||||
merchant=self.merchant,
|
||||
name='一号车',
|
||||
license_plate='浙A99999'
|
||||
)
|
||||
with self.assertRaises(Exception):
|
||||
TransportVehicle.objects.create(
|
||||
merchant=self.merchant,
|
||||
name='二号车',
|
||||
license_plate='浙A99999'
|
||||
)
|
||||
|
||||
|
||||
class FrontendPageTestCase(TestCase):
|
||||
"""测试前端页面模型"""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user