feat(wpm): add files to individual outputs
This commit is contained in:
parent
e23db9dc6c
commit
d86d70641d
|
|
@ -0,0 +1,24 @@
|
|||
# Generated by Django 4.2.27 on 2026-08-03
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("system", "0007_alter_dept_create_by_alter_dept_third_info_and_more"),
|
||||
("wpm", "0137_mlog_wpr_defect_snapshot"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="mlogbw",
|
||||
name="files",
|
||||
field=models.ManyToManyField(
|
||||
blank=True,
|
||||
related_name="mlogbw_outputs",
|
||||
to="system.file",
|
||||
verbose_name="产出附件",
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
@ -740,6 +740,12 @@ class Mlogbw(BaseModel):
|
|||
"""TN: 单个产品生产/检验日志
|
||||
"""
|
||||
number = models.TextField('单个编号', db_index=True)
|
||||
files = models.ManyToManyField(
|
||||
"system.File",
|
||||
verbose_name="产出附件",
|
||||
blank=True,
|
||||
related_name="mlogbw_outputs",
|
||||
)
|
||||
mlogb = models.ForeignKey(Mlogb, verbose_name='生产记录', on_delete=models.CASCADE, related_name="w_mlogb")
|
||||
mlogbw_from = models.ForeignKey("self", verbose_name='来源个', on_delete=models.CASCADE, null=True, blank=True, related_name="w_mlogbw_from")
|
||||
wpr = models.ForeignKey("wpmw.wpr", verbose_name='关联产品', on_delete=models.SET_NULL
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ from .models import (SfLog, StLog, SfLogExp, WMaterial, Mlog,
|
|||
Handover, Handoverb, Mlogb, AttLog,
|
||||
OtherLog, Fmlog, BatchSt, Mlogbw, Handoverbw, MlogbDefect, MlogUser, BatchLog)
|
||||
from apps.system.models import Dept, User
|
||||
from apps.system.serializers import UserSimpleSerializer
|
||||
from apps.system.serializers import FileSerializer, UserSimpleSerializer
|
||||
from apps.pm.models import Mtask, Mtaskb
|
||||
from apps.wpm.tasks import cal_enstat_when_pcoal_heat_change, cal_enstat_when_team_change, cal_exp_duration_sec
|
||||
from apps.wpm.services import get_sflog, find_material_can_change, generate_new_batch
|
||||
|
|
@ -923,6 +923,8 @@ class MlogbInUpdateSerializer(CustomModelSerializer):
|
|||
return ins
|
||||
|
||||
class MlogbwCreateUpdateSerializer(CustomModelSerializer):
|
||||
files = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
|
||||
files_ = FileSerializer(source="files", many=True, read_only=True)
|
||||
ftest = FtestProcessSerializer(required=False, allow_null=True)
|
||||
equip_name = serializers.CharField(source='equip.name', read_only=True)
|
||||
equip_number = serializers.CharField(source='equip.number', read_only=True)
|
||||
|
|
@ -936,7 +938,8 @@ class MlogbwCreateUpdateSerializer(CustomModelSerializer):
|
|||
fields = ["id", "number", "wpr", "note",
|
||||
"mlogb", "ftest", "equip", "tooling", "work_start_time",
|
||||
"work_end_time", "mlogbw_from", "equip_name", "equip_number",
|
||||
"tooling_name", "tooling_number", "wpr_number_out", "wpr_pre_info", "mlogb__batch"]
|
||||
"tooling_name", "tooling_number", "wpr_number_out", "wpr_pre_info", "mlogb__batch",
|
||||
"files", "files_"]
|
||||
read_only_fields = ["mlogbw_from"]
|
||||
|
||||
def validate(self, attrs):
|
||||
|
|
@ -998,6 +1001,15 @@ class MlogbwCreateUpdateSerializer(CustomModelSerializer):
|
|||
class MlogbwListSerializer(MlogbwCreateUpdateSerializer):
|
||||
ftest = FtestProcessListSerializer(read_only=True)
|
||||
|
||||
|
||||
class MlogbwFilesSerializer(CustomModelSerializer):
|
||||
files_ = FileSerializer(source="files", many=True, read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = Mlogbw
|
||||
fields = ["id", "files", "files_"]
|
||||
read_only_fields = ["id", "files_"]
|
||||
|
||||
class MlogbwStartTestSerializer(serializers.Serializer):
|
||||
mlogbw_ids = serializers.ListField(child=serializers.CharField(), label="mlogbwId列表")
|
||||
test_equip = serializers.CharField(label="测试设备", allow_null=True, required=False, allow_blank=True)
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
from django.test import SimpleTestCase
|
||||
from django.urls import reverse
|
||||
|
||||
from apps.system.models import File
|
||||
from apps.wpm.models import Mlogbw
|
||||
from apps.wpm.serializers import MlogbwFilesSerializer, MlogbwListSerializer
|
||||
from apps.wpm.views import MlogbwViewSet
|
||||
|
||||
|
||||
class MlogbwFilesDefinitionTests(SimpleTestCase):
|
||||
def test_files_field_links_system_file(self):
|
||||
field = Mlogbw._meta.get_field("files")
|
||||
|
||||
self.assertTrue(field.blank)
|
||||
self.assertIs(field.remote_field.model, File)
|
||||
self.assertEqual(field.remote_field.related_name, "mlogbw_outputs")
|
||||
|
||||
def test_list_serializer_exposes_file_ids_and_details(self):
|
||||
fields = MlogbwListSerializer().fields
|
||||
|
||||
self.assertTrue(fields["files"].read_only)
|
||||
self.assertTrue(fields["files_"].read_only)
|
||||
|
||||
def test_files_serializer_only_writes_file_relations(self):
|
||||
fields = MlogbwFilesSerializer().fields
|
||||
|
||||
self.assertEqual(set(fields), {"id", "files", "files_"})
|
||||
self.assertFalse(fields["files"].read_only)
|
||||
|
||||
def test_files_action_supports_read_and_update(self):
|
||||
self.assertEqual(MlogbwViewSet.files.mapping["get"], "files")
|
||||
self.assertEqual(MlogbwViewSet.files.mapping["put"], "files")
|
||||
self.assertEqual(
|
||||
reverse("mlogbw-files", kwargs={"pk": "single-id"}),
|
||||
"/api/wpm/mlogbw/single-id/files/",
|
||||
)
|
||||
|
|
@ -46,6 +46,7 @@ from .serializers import (
|
|||
BatchStSerializer,
|
||||
MlogbwCreateUpdateSerializer,
|
||||
MlogbwListSerializer,
|
||||
MlogbwFilesSerializer,
|
||||
HandoverMgroupSerializer,
|
||||
MlogListSerializer,
|
||||
MlogbSerializer,
|
||||
|
|
@ -1147,6 +1148,7 @@ class MlogbwViewSet(CustomModelViewSet):
|
|||
filterset_class = MlogbwFilter
|
||||
select_related_fields = ["ftest", "equip", "tooling", "wpr", "mlogb"]
|
||||
prefetch_related_fields = [
|
||||
"files",
|
||||
Prefetch(
|
||||
"ftest__items_ftest",
|
||||
queryset=FtestItem.objects.select_related(
|
||||
|
|
@ -1166,6 +1168,21 @@ class MlogbwViewSet(CustomModelViewSet):
|
|||
ordering = ["mlogb", "number", "create_time"]
|
||||
ordering_fields = ["number", "create_time", "mlogb"]
|
||||
|
||||
@action(detail=True, methods=["get", "put"], url_path="files")
|
||||
@transaction.atomic
|
||||
def files(self, request, *args, **kwargs):
|
||||
instance = self.get_object()
|
||||
if instance.mlogb.material_out_id is None:
|
||||
raise ParseError("只能给输出单件上传附件")
|
||||
if request.method == "PUT":
|
||||
MlogViewSet.lock_and_check_can_update(instance.mlogb.mlog)
|
||||
serializer = MlogbwFilesSerializer(instance, data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
serializer.save()
|
||||
else:
|
||||
serializer = MlogbwFilesSerializer(instance)
|
||||
return Response(serializer.data)
|
||||
|
||||
def perform_create(self, serializer):
|
||||
ins: Mlogbw = serializer.save()
|
||||
mlog: Mlog = None
|
||||
|
|
|
|||
Loading…
Reference in New Issue