From 1cb64b26afdede80cd673767cab790c8fb8f9e0b Mon Sep 17 00:00:00 2001 From: caoqianming Date: Tue, 19 Nov 2024 09:25:36 +0800 Subject: [PATCH 01/28] =?UTF-8?q?feat:=20mlog=20list=20=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E4=B8=80=E7=82=B9=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wpm/serializers.py | 19 ++++--------------- apps/wpm/views.py | 6 +++--- 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/apps/wpm/serializers.py b/apps/wpm/serializers.py index befa0ef1..8c276403 100644 --- a/apps/wpm/serializers.py +++ b/apps/wpm/serializers.py @@ -236,8 +236,6 @@ class MlogSerializer(CustomModelSerializer): source='create_by.name', read_only=True) update_by_name = serializers.CharField( source='update_by.name', read_only=True) - handovers = serializers.PrimaryKeyRelatedField( - source='handover_mlog', read_only=True, many=True) material_out_ = MaterialSimpleSerializer( source='material_out', read_only=True) material_out_name = serializers.StringRelatedField( @@ -254,24 +252,13 @@ class MlogSerializer(CustomModelSerializer): source='equipment', read_only=True) equipment_2_name = serializers.StringRelatedField( source='equipment_2', read_only=True) - shift = serializers.PrimaryKeyRelatedField( - label='班次ID', queryset=Shift.objects.all(), required=True) - mgroup = serializers.PrimaryKeyRelatedField( - label='工段ID', queryset=Mgroup.objects.all(), required=True - ) - material_out = serializers.PrimaryKeyRelatedField( - label='产物ID', queryset=Material.objects.all(), required=True - ) shift_name = serializers.CharField(source='shift.name', read_only=True) mlogb = MlogbSerializer( label='多产出件信息', many=True, required=False) mlogb_full = MlogbDetailSerializer( - label='物料信息', many=True, read_only=True - ) + label='物料信息', many=True, read_only=True) handle_users_ = UserSimpleSerializer( source='handle_users', many=True, read_only=True) - equipments_name = serializers.StringRelatedField( - source='equipments', read_only=True, many=True) ticket_ = TicketSimpleSerializer(source='ticket', read_only=True) test_user_name = serializers.CharField(source='test_user.name', read_only=True) @@ -281,7 +268,9 @@ class MlogSerializer(CustomModelSerializer): read_only_fields = EXCLUDE_FIELDS + \ ['submit_time', 'submit_user', 'material_outs'] extra_kwargs = { - "batch": {"required": True} + "batch": {"required": True}, + "shift": {"required": True}, + "material_out": {"required": True} } def create(self, validated_data): diff --git a/apps/wpm/views.py b/apps/wpm/views.py index 5c1456e8..a8a009da 100644 --- a/apps/wpm/views.py +++ b/apps/wpm/views.py @@ -149,10 +149,10 @@ class MlogViewSet(CustomModelViewSet): """ queryset = Mlog.objects.all() serializer_class = MlogSerializer - select_related_fields = ['create_by', 'update_by', 'mtask', - 'handle_user', 'handle_user_2', 'equipment', + select_related_fields = ['create_by', 'update_by', 'mtask', 'mtaskb', + 'handle_user', 'handle_user_2', 'equipment', 'mgroup__belong_dept', 'equipment_2', 'material_in', 'material_out', 'route__routepack', - 'supplier', 'ticket', 'mgroup__process', 'test_user'] + 'supplier', 'ticket', 'mgroup__process', 'test_user', 'handle_leader', 'test_user'] prefetch_related_fields = ['handle_users', 'material_outs', 'b_mlog', 'equipments'] filterset_class = MlogFilter From 5730a007420bbccc51136367dd4fc0da9152474d Mon Sep 17 00:00:00 2001 From: caoqianming Date: Tue, 19 Nov 2024 17:52:57 +0800 Subject: [PATCH 02/28] =?UTF-8?q?feat:=20ftest=E6=9B=B4=E6=96=B0ftestwork?= =?UTF-8?q?=E7=9A=84count=5Fsampling=E7=AD=89=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/qm/models.py | 4 +++- apps/qm/serializers.py | 5 +++++ apps/qm/views.py | 28 ++++++++++++++++++++-------- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/apps/qm/models.py b/apps/qm/models.py index 16baabac..d308d2d6 100644 --- a/apps/qm/models.py +++ b/apps/qm/models.py @@ -109,8 +109,10 @@ class FtestWork(CommonBDModel): """ 检验工作 """ + TYPE2_SOME = 10 + TYPE2_ALL = 20 type = models.CharField('检验类型', max_length=20, choices=FTEST_TYPE_CHOICES, default='prod') - type2 = models.PositiveSmallIntegerField('检验类型2', choices=((10, '抽检'), (20, '全检')), default=10) + type2 = models.PositiveSmallIntegerField('检验类型2', choices=((TYPE2_SOME, '抽检'), (TYPE2_ALL, '全检')), default=10) shift = models.ForeignKey(Shift, verbose_name='班次', on_delete=models.SET_NULL, null=True, blank=True) wm = models.ForeignKey(WMaterial, verbose_name='关联车间库存', on_delete=models.SET_NULL, null=True, blank=True) mb = models.ForeignKey('inm.materialbatch', verbose_name='关联仓库', on_delete=models.SET_NULL, null=True, blank=True) diff --git a/apps/qm/serializers.py b/apps/qm/serializers.py index 060acccc..dbff430a 100644 --- a/apps/qm/serializers.py +++ b/apps/qm/serializers.py @@ -182,3 +182,8 @@ class PtestSerializer(CustomModelSerializer): class Meta: model = Ptest fields = '__all__' + + def create(self, validated_data): + if Ptest.objects.filter(sample_number=validated_data['sample_number']).exists(): + raise serializers.ValidationError('该样品编号已存在') + return super().create(validated_data) diff --git a/apps/qm/views.py b/apps/qm/views.py index f03aa727..0941a5a6 100644 --- a/apps/qm/views.py +++ b/apps/qm/views.py @@ -83,23 +83,35 @@ class FtestViewSet(CustomModelViewSet): select_related_fields = ['test_user', 'check_user', 'ftest_work'] filterset_fields = ['type', 'ftest_work'] + def count_sampling(self, ftest_work:FtestWork): + qs = Ftest.objects.filter(ftest_work=ftest_work) + all_count = qs.count() + ok_count = qs.filter(is_ok=True).count() + ftest_work.count_sampling = all_count + ftest_work.count_sampling_ok = ok_count + if ftest_work.type2 == FtestWork.TYPE2_ALL: # 如果是全检 + ftest_work.count_ok = ok_count + ftest_work.count_notok = all_count - ok_count + ftest_work.save() + @transaction.atomic def perform_create(self, serializer): - ins = serializer.save() + ins: Ftest = serializer.save() if ins.ftest_work: - ins.ftest_work.count_sampling = Ftest.objects.filter( - ftest_work=ins.ftest_work).count() - ins.ftest_work.save() - return ins + self.count_sampling(ins.ftest_work) + + @transaction.atomic + def perform_update(self, serializer): + ins: Ftest = serializer.save() + if ins.ftest_work: + self.count_sampling(ins.ftest_work) @transaction.atomic def perform_destroy(self, instance): ftest_work = instance.ftest_work instance.delete() if ftest_work: - instance.ftest_work.count_sampling = Ftest.objects.filter( - ftest_work=instance.ftest_work).count() - instance.ftest_work.save() + self.count_sampling(ftest_work) class PtestViewSet(CustomModelViewSet): From a11ce128be6c050c68a0f1d8fa78367be25000a8 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Wed, 20 Nov 2024 09:45:53 +0800 Subject: [PATCH 03/28] =?UTF-8?q?feat:=20=E5=96=87=E5=8F=AD=E6=92=AD?= =?UTF-8?q?=E6=94=BE=E7=9A=84=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/ecm/service.py | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/ecm/service.py b/apps/ecm/service.py index 679401ec..3ff2507d 100644 --- a/apps/ecm/service.py +++ b/apps/ecm/service.py @@ -177,6 +177,7 @@ def save_voice_and_speak(event: Event): sps.append(i) # myLogger.info('获取到喇叭:' + str(sps)) if sps: + myLogger.info(f'喇叭播放:{event.voice_msg}, {sps}, {v_num}') spClient.speak(event.voice_msg, sps, v_num, v_p=v_p) except Exception: myLogger.error('喇叭播放失败', exc_info=True) From 598cadc4bb35b81f190997015b555c5a712aa7a4 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Wed, 20 Nov 2024 09:49:42 +0800 Subject: [PATCH 04/28] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=E5=96=87=E5=8F=AD=E6=92=AD=E6=94=BE=E6=B5=8B=E8=AF=95?= =?UTF-8?q?api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/develop/views.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/apps/develop/views.py b/apps/develop/views.py index 881b881f..1411fce7 100755 --- a/apps/develop/views.py +++ b/apps/develop/views.py @@ -469,6 +469,13 @@ class TestViewSet(CustomGenericViewSet): v_num=2) return Response() + @action(methods=['post'], detail=False, serializer_class=Serializer) + def test_event_speak(self, request, pk=None): + from apps.ecm.models import Event + from apps.ecm.service import save_voice_and_speak + save_voice_and_speak(Event.objects.get(id=request.data['event'])) + return Response() + @action(methods=['post'], detail=False, serializer_class=Serializer) def test_not_in_place(self, request, pk=None): opl = request.data.get('opl') From 16272cd15f06e3691a8f8d12f6aac4b394c0350d Mon Sep 17 00:00:00 2001 From: caoqianming Date: Wed, 20 Nov 2024 09:56:00 +0800 Subject: [PATCH 05/28] =?UTF-8?q?feat:=20save=5Fvoice=5Fand=5Fspeak=20?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/ecm/service.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/ecm/service.py b/apps/ecm/service.py index 3ff2507d..e9fed734 100644 --- a/apps/ecm/service.py +++ b/apps/ecm/service.py @@ -161,7 +161,7 @@ def save_voice_and_speak(event: Event): # else: # _, event.voice, _ = generate_voice(event.voice_msg, v_p) # event.save() - if main_cate.speaker_on and event.voice: + if main_cate.speaker_on and event.voice_msg: sps = [] if event.area: # 如果事件存在发生区域 sps = list(TDevice.objects.filter(area=event.area, @@ -175,7 +175,6 @@ def save_voice_and_speak(event: Event): for i in sps2: if i not in sps: sps.append(i) - # myLogger.info('获取到喇叭:' + str(sps)) if sps: myLogger.info(f'喇叭播放:{event.voice_msg}, {sps}, {v_num}') spClient.speak(event.voice_msg, sps, v_num, v_p=v_p) From 866726704632917cb6c224009d15e401c62dee9d Mon Sep 17 00:00:00 2001 From: caoqianming Date: Wed, 20 Nov 2024 13:18:42 +0800 Subject: [PATCH 06/28] =?UTF-8?q?feat:=20equipment=20=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E6=94=AF=E6=8C=81is=5Fdeleted=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/em/models.py | 3 +-- apps/em/views.py | 10 +++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/apps/em/models.py b/apps/em/models.py index 62f451db..85a2a69d 100644 --- a/apps/em/models.py +++ b/apps/em/models.py @@ -1,7 +1,6 @@ from django.db import models from apps.utils.models import CommonBModel, CommonADModel -from apps.system.models import User, Dictionary -from enum import Enum +from apps.system.models import User # Create your models here. diff --git a/apps/em/views.py b/apps/em/views.py index 2f4f98e2..439cf345 100644 --- a/apps/em/views.py +++ b/apps/em/views.py @@ -41,16 +41,16 @@ class EquipmentViewSet(CustomModelViewSet): 设备列表 """ - queryset = Equipment.objects.all() + queryset = Equipment.objects.get_queryset(all=True) serializer_class = EquipmentSerializer select_related_fields = ["create_by", "belong_dept", "keeper", "mgroup"] search_fields = ["number", "name"] filterset_class = EquipFilterSet - # def filter_queryset(self, queryset): - # if not self.detail and not self.request.query_params.get('type', None): - # raise ParseError('请指定设备类型') - # return super().filter_queryset(queryset) + def get_queryset(self): + if self.request.method == 'GET' and (not self.request.query_params.get('is_deleted', None)): + self.queryset = Equipment.objects.all() + return super().get_queryset() @action(methods=["post"], detail=False, perms_map={"post": "equipment.create"}, serializer_class=Serializer) @transaction.atomic From ae15f1a33c01f9183e0e786ae7d82e9e3926a665 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Wed, 20 Nov 2024 16:24:04 +0800 Subject: [PATCH 07/28] =?UTF-8?q?feat:=20speaker=20=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E5=BF=BD=E7=95=A5=E9=87=87=E9=9B=86=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/em/filters.py | 3 ++- apps/third/views_d.py | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/em/filters.py b/apps/em/filters.py index 57920f30..5241ea18 100644 --- a/apps/em/filters.py +++ b/apps/em/filters.py @@ -23,7 +23,8 @@ class EquipFilterSet(filters.FilterSet): "cate__code": ['exact', 'in', 'contains'], "cate__is_for_safe": ['exact'], "cate__is_for_enp": ['exact'], - "cate__is_car": ['exact'] + "cate__is_car": ['exact'], + "is_deleted": ['exact'] } def filter_tag(self, queryset, name, value): diff --git a/apps/third/views_d.py b/apps/third/views_d.py index c740efc4..8f881807 100644 --- a/apps/third/views_d.py +++ b/apps/third/views_d.py @@ -252,6 +252,8 @@ class TDeviceViewSet(ListModelMixin, UpdateModelMixin, DestroyModelMixin, Custom rows = res['rows'] t_l = [] for i in rows: + if i['name'] == '采集器': + continue t_l.append(i['sn']) td = TDevice.objects.filter(code=i['sn']).first() if td: @@ -425,6 +427,8 @@ class TDeviceViewSet(ListModelMixin, UpdateModelMixin, DestroyModelMixin, Custom _, res = spClient.request(**spapis['device_list'], params=request.data) codes = [] for i in res['rows']: + if i['name'] == '采集器': + continue codes.append(i['sn']) tds_info = TDeviceSerializer( instance=TDevice.objects.filter(code__in=codes), many=True).data From 72604f9992c02c337f96307fcf409fc75d3fda1a Mon Sep 17 00:00:00 2001 From: caoqianming Date: Wed, 20 Nov 2024 16:28:11 +0800 Subject: [PATCH 08/28] =?UTF-8?q?feat:=20speaker=20=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E5=BF=BD=E7=95=A5=E9=87=87=E9=9B=86=E5=99=A82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/third/views_d.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/third/views_d.py b/apps/third/views_d.py index 8f881807..ba2911e5 100644 --- a/apps/third/views_d.py +++ b/apps/third/views_d.py @@ -249,10 +249,11 @@ class TDeviceViewSet(ListModelMixin, UpdateModelMixin, DestroyModelMixin, Custom "pageSize": 1000 } _, res = spClient.request(**spapis['device_list'], params=params) - rows = res['rows'] + rows = res.get('rows', []) t_l = [] for i in rows: if i['name'] == '采集器': + rows.remove(i) continue t_l.append(i['sn']) td = TDevice.objects.filter(code=i['sn']).first() @@ -426,8 +427,10 @@ class TDeviceViewSet(ListModelMixin, UpdateModelMixin, DestroyModelMixin, Custom # print(request.data) _, res = spClient.request(**spapis['device_list'], params=request.data) codes = [] - for i in res['rows']: + rows = res.get('rows', []) + for i in rows: if i['name'] == '采集器': + rows.remove(i) continue codes.append(i['sn']) tds_info = TDeviceSerializer( @@ -435,7 +438,7 @@ class TDeviceViewSet(ListModelMixin, UpdateModelMixin, DestroyModelMixin, Custom tds_dict = {} for i in tds_info: tds_dict[i['code']] = i - for i in res['rows']: + for i in rows: i['my_info'] = {} if i['sn'] in tds_dict: i['my_info'] = tds_dict[i['sn']] From 5c2aac22e18fd8c9b4d13b9a05f4a466992b69d0 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Wed, 20 Nov 2024 16:38:14 +0800 Subject: [PATCH 09/28] =?UTF-8?q?feat:=20speaker=20=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E5=BF=BD=E7=95=A5=E9=87=87=E9=9B=86=E5=99=A83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/third/views_d.py | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/apps/third/views_d.py b/apps/third/views_d.py index ba2911e5..54f3b0d5 100644 --- a/apps/third/views_d.py +++ b/apps/third/views_d.py @@ -251,10 +251,8 @@ class TDeviceViewSet(ListModelMixin, UpdateModelMixin, DestroyModelMixin, Custom _, res = spClient.request(**spapis['device_list'], params=params) rows = res.get('rows', []) t_l = [] - for i in rows: - if i['name'] == '采集器': - rows.remove(i) - continue + filtered_rows = [i for i in rows if i['name'] != '采集器'] + for i in filtered_rows: t_l.append(i['sn']) td = TDevice.objects.filter(code=i['sn']).first() if td: @@ -427,18 +425,15 @@ class TDeviceViewSet(ListModelMixin, UpdateModelMixin, DestroyModelMixin, Custom # print(request.data) _, res = spClient.request(**spapis['device_list'], params=request.data) codes = [] - rows = res.get('rows', []) - for i in rows: - if i['name'] == '采集器': - rows.remove(i) - continue + filtered_rows = [i for i in res.get('rows', []) if i['name'] != '采集器'] + for i in filtered_rows: codes.append(i['sn']) tds_info = TDeviceSerializer( instance=TDevice.objects.filter(code__in=codes), many=True).data tds_dict = {} for i in tds_info: tds_dict[i['code']] = i - for i in rows: + for i in filtered_rows: i['my_info'] = {} if i['sn'] in tds_dict: i['my_info'] = tds_dict[i['sn']] From 258d4975f8229e4ab967dd464d70e238211fec94 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Wed, 20 Nov 2024 16:38:44 +0800 Subject: [PATCH 10/28] =?UTF-8?q?feat:=20speaker=20=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E5=BF=BD=E7=95=A5=E9=87=87=E9=9B=86=E5=99=A84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/third/views_d.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/third/views_d.py b/apps/third/views_d.py index 54f3b0d5..576bcd24 100644 --- a/apps/third/views_d.py +++ b/apps/third/views_d.py @@ -437,7 +437,7 @@ class TDeviceViewSet(ListModelMixin, UpdateModelMixin, DestroyModelMixin, Custom i['my_info'] = {} if i['sn'] in tds_dict: i['my_info'] = tds_dict[i['sn']] - return Response(res) + return Response(filtered_rows) @action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=Serializer, logging_methods=[]) From 3dfcbd8a8b9a248a28fbd961484c3346da308c10 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Wed, 20 Nov 2024 16:42:19 +0800 Subject: [PATCH 11/28] =?UTF-8?q?feat:=20speaker=20=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E5=BF=BD=E7=95=A5=E9=87=87=E9=9B=86=E5=99=A85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/third/views_d.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/third/views_d.py b/apps/third/views_d.py index 576bcd24..7472eb1f 100644 --- a/apps/third/views_d.py +++ b/apps/third/views_d.py @@ -437,7 +437,8 @@ class TDeviceViewSet(ListModelMixin, UpdateModelMixin, DestroyModelMixin, Custom i['my_info'] = {} if i['sn'] in tds_dict: i['my_info'] = tds_dict[i['sn']] - return Response(filtered_rows) + res['rows'] = filtered_rows + return Response(res) @action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=Serializer, logging_methods=[]) From 9014a7c8699ef22b4634d98652443a8427db827e Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 21 Nov 2024 10:45:31 +0800 Subject: [PATCH 12/28] =?UTF-8?q?feat:=20ftestwork=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E8=AE=BE=E5=A4=87=E5=92=8C=E5=A4=87=E6=B3=A8=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/qm/migrations/0026_auto_20241121_1044.py | 25 +++++++++++++++++++ apps/qm/models.py | 3 +++ apps/qm/serializers.py | 6 ++++- 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 apps/qm/migrations/0026_auto_20241121_1044.py diff --git a/apps/qm/migrations/0026_auto_20241121_1044.py b/apps/qm/migrations/0026_auto_20241121_1044.py new file mode 100644 index 00000000..0f27f003 --- /dev/null +++ b/apps/qm/migrations/0026_auto_20241121_1044.py @@ -0,0 +1,25 @@ +# Generated by Django 3.2.12 on 2024-11-21 02:44 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('em', '0018_alter_equipment_mgroup'), + ('qm', '0025_auto_20240920_0914'), + ] + + operations = [ + migrations.AddField( + model_name='ftestwork', + name='equipment', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='em.equipment', verbose_name='所属检验设备'), + ), + migrations.AddField( + model_name='ftestwork', + name='note', + field=models.TextField(blank=True, null=True, verbose_name='备注'), + ), + ] diff --git a/apps/qm/models.py b/apps/qm/models.py index d308d2d6..b38183be 100644 --- a/apps/qm/models.py +++ b/apps/qm/models.py @@ -2,6 +2,7 @@ from django.db import models from apps.system.models import CommonAModel, CommonADModel, User from apps.utils.models import CommonBDModel, BaseModel from apps.mtm.models import Material, Mgroup, Team, Shift +from apps.em.models import Equipment from apps.wpm.models import SfLog, WMaterial from django.utils.translation import gettext_lazy as _ @@ -131,6 +132,8 @@ class FtestWork(CommonBDModel): User, verbose_name='操作人', on_delete=models.CASCADE, related_name='ftestwork_test_user', null=True, blank=True) submit_time = models.DateTimeField('提交时间', null=True, blank=True) submit_user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='提交人', null=True, blank=True) + note = models.TextField('备注', null=True, blank=True) + equipment = models.ForeignKey(Equipment, verbose_name='所属检验设备', on_delete=models.SET_NULL, null=True, blank=True) class Ftest(CommonBDModel): diff --git a/apps/qm/serializers.py b/apps/qm/serializers.py index dbff430a..877ea786 100644 --- a/apps/qm/serializers.py +++ b/apps/qm/serializers.py @@ -66,7 +66,11 @@ class QuaStatUpdateSerializer(CustomModelSerializer): class FtestWorkCreateUpdateSerializer(CustomModelSerializer): class Meta: model = FtestWork - fields = ['id', 'shift', 'wm', 'mb', 'type', 'type2', 'test_date', 'count', 'count_sampling', 'count_sampling_ok', 'count_ok', 'count_notok', 'count_notok_json', 'test_user', 'need_update_wm'] + fields = ['id', 'shift', 'wm', 'mb', + 'type', 'type2', 'test_date', 'count', 'count_sampling', + 'count_sampling_ok', 'count_ok', 'count_notok', + 'count_notok_json', 'test_user', 'need_update_wm', + 'equipment', 'note'] extra_kwargs = {'test_user': {'required': True}, 'type': {'required': True}} def validate(self, attrs): From 93cabf0ebcbf3218d4d84fd35c1c321de4e00921 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 21 Nov 2024 11:25:31 +0800 Subject: [PATCH 13/28] =?UTF-8?q?feat:=20mlogb=E5=A2=9E=E5=8A=A0=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E6=9D=A1=E4=BB=B6=E4=BB=A5=E6=94=AF=E6=8C=81=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E8=BF=94=E5=B7=A5=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wpm/filters.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/wpm/filters.py b/apps/wpm/filters.py index 59d70620..30b484dd 100644 --- a/apps/wpm/filters.py +++ b/apps/wpm/filters.py @@ -117,6 +117,9 @@ class MlogbFilter(filters.FilterSet): fields = { "mlog": ["exact"], "mtask": ["exact"], + "wm_in": ["exact"], + "mlog__submit_time": ["isnull"], + "wm_in__state": ["exact"], "material_in": ["exact", "isnull"], "material_out": ["exact", "isnull"], } From 1bfafdb0e497b2d61a7ecb1975b9d55bbe6d1fdc Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 21 Nov 2024 13:21:53 +0800 Subject: [PATCH 14/28] =?UTF-8?q?feat:=20handover=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=A4=87=E6=B3=A8=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wpm/migrations/0072_handover_note.py | 18 ++++++++++++++++++ apps/wpm/models.py | 1 + apps/wpm/serializers.py | 2 +- 3 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 apps/wpm/migrations/0072_handover_note.py diff --git a/apps/wpm/migrations/0072_handover_note.py b/apps/wpm/migrations/0072_handover_note.py new file mode 100644 index 00000000..5f0acd07 --- /dev/null +++ b/apps/wpm/migrations/0072_handover_note.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.12 on 2024-11-21 05:21 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('wpm', '0071_auto_20241113_1555'), + ] + + operations = [ + migrations.AddField( + model_name='handover', + name='note', + field=models.TextField(blank=True, null=True, verbose_name='备注'), + ), + ] diff --git a/apps/wpm/models.py b/apps/wpm/models.py index 33718c65..68c6e292 100644 --- a/apps/wpm/models.py +++ b/apps/wpm/models.py @@ -356,6 +356,7 @@ class Handover(CommonADModel): submit_time = models.DateTimeField('提交时间', null=True, blank=True) submit_user = models.ForeignKey( User, verbose_name='提交人', on_delete=models.CASCADE, null=True, blank=True, related_name='handover_submit_user') + note = models.TextField('备注', null=True, blank=True) @property def handoverb(self): diff --git a/apps/wpm/serializers.py b/apps/wpm/serializers.py index 8c276403..f63cdb43 100644 --- a/apps/wpm/serializers.py +++ b/apps/wpm/serializers.py @@ -723,7 +723,7 @@ class HandoverSerializer(CustomModelSerializer): class HandoverUpdateSerializer(CustomModelSerializer): class Meta: model = Handover - fields = ['id', 'send_date', 'send_user', 'count', 'count_eweight', 'recive_user'] + fields = ['id', 'send_date', 'send_user', 'count', 'count_eweight', 'recive_user', 'note'] From 32158dfa776c4605f10910063ce40f568974ebd0 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 21 Nov 2024 13:34:15 +0800 Subject: [PATCH 15/28] =?UTF-8?q?feat:=20WMaterialFilter=20mtaskx=E6=A0=B9?= =?UTF-8?q?=E6=8D=AEbatch=5Fbind=E8=BF=9B=E8=A1=8C=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wpm/filters.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/wpm/filters.py b/apps/wpm/filters.py index 30b484dd..fb4d629b 100644 --- a/apps/wpm/filters.py +++ b/apps/wpm/filters.py @@ -37,7 +37,11 @@ class WMaterialFilter(filters.FilterSet): return queryset.filter(mgroup__id=value)|queryset.filter(belong_dept=Mgroup.objects.get(id=value).belong_dept, mgroup=None) def filter_mtaskx(self, queryset, name, value): - return WMaterial.mat_in_qs(mtask=Mtask.objects.get(id=value), qs=queryset) + mtask = Mtask.objects.get(id=value) + if mtask.route and mtask.route.batch_bind: + return WMaterial.mat_in_qs(mtask=Mtask.objects.get(id=value), qs=queryset) + return queryset + class Meta: model = WMaterial fields = { From 72b04ddc7af846b8d124ee94eee1246e396d4570 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 21 Nov 2024 15:20:27 +0800 Subject: [PATCH 16/28] =?UTF-8?q?feat:=20=E5=8D=95=E5=B7=A5=E5=BA=8F?= =?UTF-8?q?=E5=A4=9A=E5=B7=A5=E6=AE=B5=E6=83=85=E5=86=B5=E4=B8=8B=E5=B9=B3?= =?UTF-8?q?=E5=9D=87=E5=88=86=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/pm/services.py | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/apps/pm/services.py b/apps/pm/services.py index 124c7763..fd02d644 100644 --- a/apps/pm/services.py +++ b/apps/pm/services.py @@ -147,12 +147,15 @@ class PmService: mgroups = Mgroup.objects.filter(process=val.process) mgroups_count = mgroups.count() if mgroups_count == 1: - mgroup = mgroups.first() + pass elif mgroups_count == 0: raise ParseError(f'第{ind+1}步-工段不存在!') - else: # 后面可能会指定车间 - raise ParseError(f'第{ind+1}步-工段存在多个!') + else: # 存在同一工序的多个工段,先平均分配 + pass if schedule_type == 'to_day': + if mgroups_count > 1: + raise ParseError(f'第{ind+1}步-工段存在多个!') + mgroup = mgroups.first() task_count_day = math.ceil(count_task_list[ind]/rela_days) if rela_days >= 1: for i in range(rela_days): @@ -173,22 +176,23 @@ class PmService: 'is_count_utask': val.is_count_utask }) elif schedule_type == 'to_mgroup': - Mtask.objects.create(**{ - 'route': val, - 'number': f'{number}_r{ind+1}', - 'type': utask.type, - 'material_out': halfgood, - 'material_in': material_in, - 'mgroup': mgroup, - 'count': count_task_list[ind], - 'start_date': start_date, - 'end_date': end_date, - 'utask': utask, - 'create_by': user, - 'update_by': user, - 'hour_work': val.hour_work, - 'is_count_utask': val.is_count_utask - }) + for indx, mgroup in enumerate(mgroups): + Mtask.objects.create(**{ + 'route': val, + 'number': f'{number}_r{ind+1}_m{indx+1}', + 'type': utask.type, + 'material_out': halfgood, + 'material_in': material_in, + 'mgroup': mgroup, + 'count': math.ceil(count_task_list[ind]/mgroups_count), + 'start_date': start_date, + 'end_date': end_date, + 'utask': utask, + 'create_by': user, + 'update_by': user, + 'hour_work': val.hour_work, + 'is_count_utask': val.is_count_utask + }) else: raise ParseError('不支持的排产类型') @classmethod From 05af3361805f40e62c7be447fed5787820722b4e Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 21 Nov 2024 17:03:34 +0800 Subject: [PATCH 17/28] =?UTF-8?q?fix:=20mlog=20create=20=E6=97=B6=E7=9A=84?= =?UTF-8?q?bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wpm/serializers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/wpm/serializers.py b/apps/wpm/serializers.py index f63cdb43..34a0bbe1 100644 --- a/apps/wpm/serializers.py +++ b/apps/wpm/serializers.py @@ -336,7 +336,7 @@ class MlogSerializer(CustomModelSerializer): if wm_in: wm_in = instance.wm_in ddict = {"batch_ofrom": wm_in.batch_ofrom, "material_ofrom": wm_in.material_ofrom} - Mlogb.objects.create(**add_dict_2, defaults=ddict) + Mlogb.objects.get_or_create(**add_dict_2, defaults=ddict) return instance def update(self, instance, validated_data): From 8c63aea87787c62f7a552f23ee0cbef6acaba1a3 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 21 Nov 2024 17:04:36 +0800 Subject: [PATCH 18/28] fix: validate data pop None --- apps/inm/serializers.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/inm/serializers.py b/apps/inm/serializers.py index b4d6f957..318152b9 100644 --- a/apps/inm/serializers.py +++ b/apps/inm/serializers.py @@ -185,7 +185,7 @@ class MIODoSerializer(CustomModelSerializer): return super().create(validated_data) def update(self, instance, validated_data): - validated_data.pop('type') + validated_data.pop('type', None) return super().update(instance, validated_data) @@ -212,7 +212,7 @@ class MIOSaleSerializer(CustomModelSerializer): return super().create(validated_data) def update(self, instance, validated_data): - validated_data.pop('type') + validated_data.pop('type', None) return super().update(instance, validated_data) @@ -239,7 +239,7 @@ class MIOPurSerializer(CustomModelSerializer): return super().create(validated_data) def update(self, instance, validated_data): - validated_data.pop('type') + validated_data.pop('type', None) return super().update(instance, validated_data) @@ -259,7 +259,7 @@ class MIOOtherSerializer(CustomModelSerializer): return super().create(validated_data) def update(self, instance, validated_data): - validated_data.pop('type') + validated_data.pop('type', None) return super().update(instance, validated_data) From 2c569db0d80238152481c477cbb75ef780f2e599 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 21 Nov 2024 17:23:35 +0800 Subject: [PATCH 19/28] fix: do_in wm_production_dept --- apps/inm/services.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/inm/services.py b/apps/inm/services.py index 49f6f965..b22d3577 100644 --- a/apps/inm/services.py +++ b/apps/inm/services.py @@ -132,9 +132,10 @@ def do_in(item: MIOItem): else: raise ParseError(f'{str(xmaterial)}-{xbatch}车间物料不足') + wm_production_dept = wm.mgroup.belong_dept if wm.mgroup else None if production_dept is None: - production_dept = wm.mgroup.belong_dept - elif production_dept != wm.mgroup.belong_dept: + production_dept = wm_production_dept + elif wm_production_dept and production_dept != wm_production_dept: raise ParseError(f'{str(xmaterial)}-{xbatch}车间物料不属于同一车间') # 增加mb if not is_zhj: From 5d6ce9f6c0e794f5d144602358c6a30e8b206b5f Mon Sep 17 00:00:00 2001 From: caoqianming Date: Fri, 22 Nov 2024 09:07:03 +0800 Subject: [PATCH 20/28] feat: mlog_submit mlog_revert bug --- apps/wpm/services.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/wpm/services.py b/apps/wpm/services.py index d24fde94..ae7cff33 100644 --- a/apps/wpm/services.py +++ b/apps/wpm/services.py @@ -130,10 +130,10 @@ def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]): supplier = mlog.supplier # 外协 m_ins_list = [] if material_in: # 需要进行车间库存管理 + m_ins_list = [] + m_ins_bl_list = [] m_ins = Mlogb.objects.filter(mlog=mlog, material_in__isnull=False) if m_ins.exists(): - m_ins_list = [] - m_ins_bl_list = [] for mi in m_ins.all(): m_ins_list.append((mi.material_in, mi.batch, mi.count_use, mi.wm_in)) if mi.count_pn_jgqbl > 0: @@ -251,11 +251,11 @@ def mlog_revert(mlog: Mlog, user: User, now: Union[datetime.datetime, None]): stored_mgroup = mlog.stored_mgroup if material_in: # 领用数退回 + m_ins_list = [] + m_ins_bl_list = [] into_wm_mgroup = material_in.process.into_wm_mgroup if material_in.process else False m_ins = Mlogb.objects.filter(mlog=mlog, material_in__isnull=False) if m_ins.exists(): - m_ins_list = [] - m_ins_bl_list = [] for mi in m_ins.all(): m_ins_list.append((mi.material_in, mi.batch, mi.count_use, mi.wm_in)) if mi.count_pn_jgqbl > 0: From 580109aa9f446d1ad6aa054fdb8b1434ba34b3a7 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Fri, 22 Nov 2024 18:35:12 +0800 Subject: [PATCH 21/28] =?UTF-8?q?fix:=20mlog=20=E5=A1=AB=E5=86=99=E6=96=B9?= =?UTF-8?q?=E5=BC=8F=E5=8F=8Ahandoverb=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wpm/serializers.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/apps/wpm/serializers.py b/apps/wpm/serializers.py index 34a0bbe1..0b9bbb28 100644 --- a/apps/wpm/serializers.py +++ b/apps/wpm/serializers.py @@ -351,7 +351,8 @@ class MlogSerializer(CustomModelSerializer): mlogb = validated_data.pop('mlogb', []) instance: Mlog = super().update(instance, validated_data) wm_in = instance.wm_in - if instance.fill_way == Mlog.MLOG_12: + # 修改消耗 + if instance.fill_way in [Mlog.MLOG_12, Mlog.MLOG_2]: # 自动生成mlogb batch_in = instance.batch if wm_in: @@ -370,20 +371,23 @@ class MlogSerializer(CustomModelSerializer): minx.count_break = instance.count_break minx.count_pn_jgqbl = instance.count_pn_jgqbl minx.save() - - if mlogb and instance.fill_way == Mlog.MLOG_2: + Mlogb.objects.filter(mlog=instance, material_in__isnull=False).exclude(id=minx.id).delete() + + # 修改产出 + if instance.fill_way == Mlog.MLOG_2 and instance.material_out.brothers: + # 针对兄弟件的情况 Mlogb.objects.filter(mlog=instance, material_out__isnull=False).update(count_ok=0) for item in mlogb: Mlogb.objects.filter(mlog=instance, material_out=item['material_out']).update( count_ok=item['count_ok']) - elif instance.fill_way == Mlog.MLOG_12: + + elif instance.fill_way in [Mlog.MLOG_12, Mlog.MLOG_2]: # 生成产出物 batch_out = instance.batch if batch_out: pass else: batch_out = generate_new_batch(batch_in, instance) - mox, _ = Mlogb.objects.get_or_create(mlog=instance, batch=batch_out, mtask=instance.mtask, material_out=instance.material_out) mox.count_ok = instance.count_ok @@ -400,7 +404,7 @@ class MlogSerializer(CustomModelSerializer): return instance def validate(self, attrs): - attrs['fill_way'] = Mlog.MLOG_2 + attrs['fill_way'] = Mlog.MLOG_2 # 只填第二级 attrs['mtype'] = Mlog.MTYPE_SELF # 默认为自生产 fmlog = attrs.get('fmlog', None) mtaskb = attrs.get('mtaskb', None) @@ -634,7 +638,7 @@ class HandoverSerializer(CustomModelSerializer): material_name = serializers.StringRelatedField( source='material', read_only=True) wm_notok_sign = serializers.CharField(source='wm.notok_sign', read_only=True) - handoverb = HandoverbSerializer(many=True) + handoverb = HandoverbSerializer(many=True, required=False) def validate(self, attrs): if 'type' not in attrs: From 89d9a987f4b4b2210345ed1e396b894bfece025e Mon Sep 17 00:00:00 2001 From: caoqianming Date: Sat, 23 Nov 2024 22:24:38 +0800 Subject: [PATCH 22/28] =?UTF-8?q?fix:=20mtask=5Fsubmit=20=E4=B8=8D?= =?UTF-8?q?=E4=BC=9A=E8=A7=A6=E5=8F=91utask=5Fsubmit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/pm/services.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/pm/services.py b/apps/pm/services.py index fd02d644..d54315a6 100644 --- a/apps/pm/services.py +++ b/apps/pm/services.py @@ -323,8 +323,6 @@ class PmService: mtask.submit_time = now mtask.submit_user = user mtask.save() - utask = mtask.utask - PmService.utask_submit(utask) else: raise ParseError('该任务状态不可提交') @@ -337,4 +335,4 @@ class PmService: utask.state = Utask.UTASK_SUBMIT utask.save() else: - raise ParseError('该任务状态不可提交') \ No newline at end of file + raise ParseError('存在子任务未提交') \ No newline at end of file From cb36aac9ca820db58d6d8a5371a63a711bcbf1de Mon Sep 17 00:00:00 2001 From: caoqianming Date: Sat, 23 Nov 2024 22:32:55 +0800 Subject: [PATCH 23/28] =?UTF-8?q?feat:=20=E5=8E=BB=E9=99=A4handover=20send?= =?UTF-8?q?=E5=BC=BA=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wpm/serializers.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/wpm/serializers.py b/apps/wpm/serializers.py index 0b9bbb28..94751bfe 100644 --- a/apps/wpm/serializers.py +++ b/apps/wpm/serializers.py @@ -671,8 +671,10 @@ class HandoverSerializer(CustomModelSerializer): for ind, item in enumerate(attrs['handoverb']): wm = item["wm"] t_count += item["count"] - if wm.mgroup != attrs['send_mgroup']: - raise ParseError(f'第{ind+1}物料与交接工段不一致') + # if wm.mgroup and wm.mgroup != attrs['send_mgroup']: + # raise ParseError(f'第{ind+1}物料与交接工段不一致') + # if wm.belong_dept and wm.belong_dept != attrs['send_dept']: + # raise ParseError(f'第{ind+1}物料与交接部门不一致') if attrs["material"] != wm.material: raise ParseError(f'第{ind+1}物料与交接物料不一致') if wm.notok_sign is not None and attrs['type'] in [Handover.H_NORMAL, Handover.H_TEST]: From 84f7de61bc5bcd31d3b15821ba0802e23b6a17b5 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Sat, 23 Nov 2024 23:06:01 +0800 Subject: [PATCH 24/28] =?UTF-8?q?fix:=20mlog=20update=20=E6=B2=A1=E6=9C=89?= =?UTF-8?q?=E6=B6=88=E8=80=97=E6=97=B6=E7=9A=84=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wpm/serializers.py | 69 ++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 32 deletions(-) diff --git a/apps/wpm/serializers.py b/apps/wpm/serializers.py index 94751bfe..13330767 100644 --- a/apps/wpm/serializers.py +++ b/apps/wpm/serializers.py @@ -283,19 +283,20 @@ class MlogSerializer(CustomModelSerializer): instance: Mlog = super().create(validated_data) # 自动生成mlogb batch_in = instance.batch - wm_in = instance.wm_in - if wm_in: - batch_in = wm_in.batch - add_dict = { - 'mlog': instance, 'batch': batch_in, 'wm_in': wm_in, - 'mtask': instance.mtask, 'material_in': instance.material_in, - 'count_use': instance.count_use, 'count_break': instance.count_break, - 'count_pn_jgqbl': instance.count_pn_jgqbl - } - if wm_in: - add_dict['batch_ofrom'] = wm_in.batch_ofrom - add_dict['material_ofrom'] = wm_in.material_ofrom - Mlogb.objects.create(**add_dict) + if instance.material_in: # 如果有消耗 + wm_in = instance.wm_in + if wm_in: + batch_in = wm_in.batch + add_dict = { + 'mlog': instance, 'batch': batch_in, 'wm_in': wm_in, + 'mtask': instance.mtask, 'material_in': instance.material_in, + 'count_use': instance.count_use, 'count_break': instance.count_break, + 'count_pn_jgqbl': instance.count_pn_jgqbl + } + if wm_in: + add_dict['batch_ofrom'] = wm_in.batch_ofrom + add_dict['material_ofrom'] = wm_in.material_ofrom + Mlogb.objects.create(**add_dict) # mlogb只用于组合件输出物填写 brotherId_should_list = material_out.brothers @@ -308,6 +309,7 @@ class MlogSerializer(CustomModelSerializer): batch=instance.batch, mtask=instance.mtask, material_out=item['material_out'], + count_real=item['count_ok'], count_ok=item['count_ok']) if wm_in: mlogbx.batch_ofrom = wm_in.batch_ofrom @@ -326,6 +328,7 @@ class MlogSerializer(CustomModelSerializer): add_dict_2 = { 'mlog': instance, 'batch': batch_out, 'mtask': instance.mtask, 'material_out': instance.material_out, + 'count_real': instance.count_real, 'count_ok': instance.count_ok, 'count_notok': instance.count_notok, 'count_break_t': instance.count_break_t } @@ -354,31 +357,33 @@ class MlogSerializer(CustomModelSerializer): # 修改消耗 if instance.fill_way in [Mlog.MLOG_12, Mlog.MLOG_2]: # 自动生成mlogb - batch_in = instance.batch - if wm_in: - batch_in = wm_in.batch - minx, _ = Mlogb.objects.get_or_create( - mlog=instance, - batch=batch_in, - wm_in=instance.wm_in, - mtask=instance.mtask, - material_in=instance.material_in - ) - if wm_in: - minx.batch_ofrom = wm_in.batch_ofrom - minx.material_ofrom = wm_in.material_ofrom - minx.count_use = instance.count_use - minx.count_break = instance.count_break - minx.count_pn_jgqbl = instance.count_pn_jgqbl - minx.save() - Mlogb.objects.filter(mlog=instance, material_in__isnull=False).exclude(id=minx.id).delete() + if instance.material_in: # 有消耗的情况 + batch_in = instance.batch + if wm_in: + batch_in = wm_in.batch + minx, _ = Mlogb.objects.get_or_create( + mlog=instance, + batch=batch_in, + wm_in=instance.wm_in, + mtask=instance.mtask, + material_in=instance.material_in + ) + if wm_in: + minx.batch_ofrom = wm_in.batch_ofrom + minx.material_ofrom = wm_in.material_ofrom + minx.count_use = instance.count_use + minx.count_break = instance.count_break + minx.count_pn_jgqbl = instance.count_pn_jgqbl + minx.save() + Mlogb.objects.filter(mlog=instance, material_in__isnull=False).exclude(id=minx.id).delete() # 修改产出 if instance.fill_way == Mlog.MLOG_2 and instance.material_out.brothers: # 针对兄弟件的情况 - Mlogb.objects.filter(mlog=instance, material_out__isnull=False).update(count_ok=0) + Mlogb.objects.filter(mlog=instance, material_out__isnull=False).update(count_real=0, count_ok=0) for item in mlogb: Mlogb.objects.filter(mlog=instance, material_out=item['material_out']).update( + count_real=item['count_ok'], count_ok=item['count_ok']) elif instance.fill_way in [Mlog.MLOG_12, Mlog.MLOG_2]: From d52bd4e0643df7987817fc05b47eb0e18727d352 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Sat, 23 Nov 2024 23:12:45 +0800 Subject: [PATCH 25/28] =?UTF-8?q?feat:=20mlog=20=E5=8F=98=E5=8C=96?= =?UTF-8?q?=E4=B8=8D=E5=86=8D=E5=88=9B=E5=BB=BA=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wpm/views.py | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/apps/wpm/views.py b/apps/wpm/views.py index a8a009da..7952ebd7 100644 --- a/apps/wpm/views.py +++ b/apps/wpm/views.py @@ -160,17 +160,17 @@ class MlogViewSet(CustomModelViewSet): 'material_in__number', 'material_in__specification', 'batch', 'material_in__model', 'material_out__name', 'material_out__number', 'material_out__specification', 'material_out__model',] - @transaction.atomic - def perform_create(self, serializer): - ins = serializer.save() - data = MlogSerializer(ins).data - create_auditlog('create', ins, data) + # @transaction.atomic + # def perform_create(self, serializer): + # ins = serializer.save() + # data = MlogSerializer(ins).data + # create_auditlog('create', ins, data) @transaction.atomic def perform_destroy(self, instance): if instance.submit_time is not None: raise ParseError('日志已提交不可变动') - delete_auditlog(instance, instance.id) + # delete_auditlog(instance, instance.id) instance.delete() @transaction.atomic @@ -178,10 +178,10 @@ class MlogViewSet(CustomModelViewSet): ins = serializer.instance if ins.submit_time is not None: raise ParseError('该日志已提交!') - val_old = MlogSerializer(instance=ins).data + # val_old = MlogSerializer(instance=ins).data serializer.save() - val_new = MlogSerializer(instance=ins).data - create_auditlog('update', ins, val_new, val_old) + # val_new = MlogSerializer(instance=ins).data + # create_auditlog('update', ins, val_new, val_old) @action(methods=['post'], detail=False, perms_map={'post': 'mlog.init'}, serializer_class=MlogInitSerializer) def init(self, request, *args, **kwargs): @@ -213,7 +213,6 @@ class MlogViewSet(CustomModelViewSet): 日志提交 """ ins: Mlog = self.get_object() - vdata_old = MlogSerializer(ins).data now = timezone.now() if ins.ticket: raise ParseError('该日志存在审批!') @@ -225,8 +224,8 @@ class MlogViewSet(CustomModelViewSet): with transaction.atomic(): mlog_submit(ins, self.request.user, now) vdata_new = MlogSerializer(ins).data - create_auditlog('submit', ins, vdata_new, - vdata_old, now, self.request.user) + # create_auditlog('submit', ins, vdata_new, + # vdata_old, now, self.request.user) MyThread(target=cal_mtask_progress_from_mlog,args=(ins,)).start() MyThread(target=cal_material_count_from_mlog,args=(ins,)).start() return Response(vdata_new) @@ -246,8 +245,8 @@ class MlogViewSet(CustomModelViewSet): now = timezone.now() with transaction.atomic(): mlog_revert(ins, user, now) - create_auditlog('revert', ins, {}, {}, now, user, - request.data.get('change_reason', '')) + # create_auditlog('revert', ins, {}, {}, now, user, + # request.data.get('change_reason', '')) MyThread(target=cal_mtask_progress_from_mlog,args=(ins,)).start() MyThread(target=cal_material_count_from_mlog,args=(ins,)).start() return Response(MlogSerializer(instance=ins).data) From a484c0021de2d12a1404a4986f91b380dcf8c9df Mon Sep 17 00:00:00 2001 From: caoqianming Date: Sun, 24 Nov 2024 16:07:11 +0800 Subject: [PATCH 26/28] =?UTF-8?q?fix:=20wm=5Fin=20=E6=89=BE=E4=B8=8D?= =?UTF-8?q?=E5=88=B0=E7=9A=84=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wpm/serializers.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/apps/wpm/serializers.py b/apps/wpm/serializers.py index 13330767..b595790b 100644 --- a/apps/wpm/serializers.py +++ b/apps/wpm/serializers.py @@ -283,10 +283,10 @@ class MlogSerializer(CustomModelSerializer): instance: Mlog = super().create(validated_data) # 自动生成mlogb batch_in = instance.batch + wm_in = instance.wm_in + if wm_in: + batch_in = wm_in.batch if instance.material_in: # 如果有消耗 - wm_in = instance.wm_in - if wm_in: - batch_in = wm_in.batch add_dict = { 'mlog': instance, 'batch': batch_in, 'wm_in': wm_in, 'mtask': instance.mtask, 'material_in': instance.material_in, @@ -337,7 +337,6 @@ class MlogSerializer(CustomModelSerializer): add_dict_2[f.name] = getattr(instance, f.name) ddict = {} if wm_in: - wm_in = instance.wm_in ddict = {"batch_ofrom": wm_in.batch_ofrom, "material_ofrom": wm_in.material_ofrom} Mlogb.objects.get_or_create(**add_dict_2, defaults=ddict) return instance @@ -354,13 +353,13 @@ class MlogSerializer(CustomModelSerializer): mlogb = validated_data.pop('mlogb', []) instance: Mlog = super().update(instance, validated_data) wm_in = instance.wm_in + batch_in = instance.batch + if wm_in: + batch_in = wm_in.batch # 修改消耗 if instance.fill_way in [Mlog.MLOG_12, Mlog.MLOG_2]: # 自动生成mlogb if instance.material_in: # 有消耗的情况 - batch_in = instance.batch - if wm_in: - batch_in = wm_in.batch minx, _ = Mlogb.objects.get_or_create( mlog=instance, batch=batch_in, From 12d77e53b604e946fbbc46a433bf494d2e9b4a11 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Sun, 24 Nov 2024 17:03:39 +0800 Subject: [PATCH 27/28] =?UTF-8?q?feat:=20mlog=20submit=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E4=B8=80=E4=B8=AA=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wpm/services.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/wpm/services.py b/apps/wpm/services.py index ae7cff33..5fc58bef 100644 --- a/apps/wpm/services.py +++ b/apps/wpm/services.py @@ -198,6 +198,8 @@ def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]): notok_sign = f.name.replace('count_n_', '') m_outs_list.append( (item.material_out, item.batch if item.batch else mlog.batch, getattr(item, f.name), mlog.count_real_eweight, notok_sign, item)) stored_notok = True + # 这里有一个漏洞,在产出物为兄弟件的情况下,不合格品的数量是记录在mlog上的, + # 而不是mlogb上,以上的额外处理就没有效果了, 不过光子不记录不合格品 else: m_outs_list = [(material_out, mlog.batch, mlog.count_ok, mlog.count_real_eweight, None, mlog)] # 一次填写的暂时不处理不合格品 From 53322ed9ada71bb73a06689719178f83dc496b2b Mon Sep 17 00:00:00 2001 From: caoqianming Date: Sun, 24 Nov 2024 17:22:03 +0800 Subject: [PATCH 28/28] =?UTF-8?q?feat:=20=E5=85=84=E5=BC=9F=E4=BB=B6?= =?UTF-8?q?=E4=BA=A7=E5=87=BA=E9=9C=80=E8=A6=81=E6=B3=A8=E6=84=8Fbatch?= =?UTF-8?q?=E7=9A=84=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wpm/serializers.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/wpm/serializers.py b/apps/wpm/serializers.py index b595790b..61df3cff 100644 --- a/apps/wpm/serializers.py +++ b/apps/wpm/serializers.py @@ -309,7 +309,6 @@ class MlogSerializer(CustomModelSerializer): batch=instance.batch, mtask=instance.mtask, material_out=item['material_out'], - count_real=item['count_ok'], count_ok=item['count_ok']) if wm_in: mlogbx.batch_ofrom = wm_in.batch_ofrom @@ -379,10 +378,12 @@ class MlogSerializer(CustomModelSerializer): # 修改产出 if instance.fill_way == Mlog.MLOG_2 and instance.material_out.brothers: # 针对兄弟件的情况 - Mlogb.objects.filter(mlog=instance, material_out__isnull=False).update(count_real=0, count_ok=0) + Mlogb.objects.filter(mlog=instance, material_out__isnull=False).update( + batch=instance.batch, # 注意mlog的batch有可能会进行修改 + count_ok=0) for item in mlogb: Mlogb.objects.filter(mlog=instance, material_out=item['material_out']).update( - count_real=item['count_ok'], + batch=instance.batch, count_ok=item['count_ok']) elif instance.fill_way in [Mlog.MLOG_12, Mlog.MLOG_2]: