feat: WMaterialViewSet 添加手动来料创建和删除接口

- 新增 WMaterialCreateSerializer,validate 中自动推导 belong_dept
- ViewSet 使用 create_serializer_class,perform_create 设置 is_manual=True
- 删除校验逻辑移至模型 delete 方法,校验 is_manual 及关联记录(mlogb/handoverb/ftestwork/mioitem)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
caoqianming 2026-03-27 10:08:42 +08:00
parent 61f70d4907
commit 320822019a
3 changed files with 27 additions and 3 deletions

View File

@ -128,6 +128,20 @@ class WMaterial(CommonBDModel):
number_from = models.TextField("来源于个号", null=True, blank=True)
is_manual = models.BooleanField('手动创建', default=False)
def delete(self, *args, **kwargs):
if not self.is_manual:
raise ParseError('只能删除手动创建的车间库存')
checks = [
(self.mlogb_set.exists, '存在关联的生产明细'),
(self.handoverb_wm.exists, '存在关联的交接明细'),
(self.ftestwork_set.exists, '存在关联的检验记录'),
(self.wm_mioitem.exists, '存在关联的出入库明细'),
]
for check, msg in checks:
if check():
raise ParseError(msg)
super().delete(*args, **kwargs)
@property
def belong_dept_or_mgroup_id(self):
return self.mgroup.id if self.mgroup else self.belong_dept.id

View File

@ -207,6 +207,16 @@ class WMaterialSerializer(CustomModelSerializer):
ret['count_canhandover'] = str(Decimal(ret['count']) - Decimal(ret['count_handovering']))
return ret
class WMaterialCreateSerializer(CustomModelSerializer):
class Meta:
model = WMaterial
fields = ['material', 'count', 'batch', 'mgroup']
def validate(self, attrs):
attrs['belong_dept'] = attrs['mgroup'].belong_dept
return attrs
class MlogbDefectSerializer(CustomModelSerializer):
defect_name = serializers.CharField(source="defect.name", read_only=True)
defect_okcate = serializers.CharField(source="defect.okcate", read_only=True)

View File

@ -21,6 +21,7 @@ from .serializers import (
SfLogSerializer,
StLogSerializer,
WMaterialSerializer,
WMaterialCreateSerializer,
MlogRevertSerializer,
MlogSerializer,
MlogRelatedSerializer,
@ -173,6 +174,7 @@ class WMaterialViewSet(CustomCreateModelMixin, DestroyModelMixin, CustomListMode
perms_map = {"get": "*", "post": "wmaterial.create", "delete": "wmaterial.delete"}
queryset = WMaterial.objects.filter(count__gt=0)
serializer_class = WMaterialSerializer
create_serializer_class = WMaterialCreateSerializer
select_related_fields = ["material", "belong_dept", "material__process", "supplier"]
search_fields = ["material__name", "material__specification", "batch", "material__model", "defect__name", "notok_sign"]
filterset_class = WMaterialFilter
@ -190,11 +192,9 @@ class WMaterialViewSet(CustomCreateModelMixin, DestroyModelMixin, CustomListMode
return queryset.exclude(state=WMaterial.WM_SCRAP)
def perform_create(self, serializer):
serializer.save(create_by=self.request.user, belong_dept=self.request.user.dept, is_manual=True)
serializer.save(create_by=self.request.user, is_manual=True)
def perform_destroy(self, instance):
if not instance.is_manual:
raise ParseError('只能删除手动创建的车间库存')
instance.delete()
@action(methods=["post"], detail=False, perms_map={"post": "*"}, serializer_class=DeptBatchSerializer)