From c05432ce5688f4e2a43f6bd69ab635d83ba34a3a Mon Sep 17 00:00:00 2001 From: caoqianming Date: Tue, 6 May 2025 10:32:50 +0800 Subject: [PATCH 01/20] =?UTF-8?q?feat:=20=E6=A0=87=E7=AD=BE=E7=89=A9?= =?UTF-8?q?=E6=96=99=E6=A0=B9=E6=8D=AE=E6=A8=A1=E6=9D=BF=E6=89=93=E5=8D=B0?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/cm/filters.py | 10 ++++++ .../0005_labeltemplate_process_json.py | 18 ++++++++++ apps/cm/models.py | 4 ++- apps/cm/serializers.py | 2 ++ apps/cm/views.py | 36 ++++++++++++++++++- 5 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 apps/cm/filters.py create mode 100644 apps/cm/migrations/0005_labeltemplate_process_json.py diff --git a/apps/cm/filters.py b/apps/cm/filters.py new file mode 100644 index 00000000..48c7a300 --- /dev/null +++ b/apps/cm/filters.py @@ -0,0 +1,10 @@ +from django_filters import rest_framework as filters +from django.utils import timezone +from .models import LabelTemplate +from apps.utils.filters import MyJsonListFilter + +class LabelTemplateFilter(filters.FilterSet): + process_json__contains = MyJsonListFilter(field_name='按工序查询') + + class Meta: + model = LabelTemplate \ No newline at end of file diff --git a/apps/cm/migrations/0005_labeltemplate_process_json.py b/apps/cm/migrations/0005_labeltemplate_process_json.py new file mode 100644 index 00000000..e296d3ec --- /dev/null +++ b/apps/cm/migrations/0005_labeltemplate_process_json.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.12 on 2025-05-06 02:25 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('cm', '0004_labeltemplate'), + ] + + operations = [ + migrations.AddField( + model_name='labeltemplate', + name='process_json', + field=models.JSONField(blank=True, default=list, verbose_name='工序'), + ), + ] diff --git a/apps/cm/models.py b/apps/cm/models.py index 3329dcfe..64fa5af0 100644 --- a/apps/cm/models.py +++ b/apps/cm/models.py @@ -17,5 +17,7 @@ class LableMat(BaseModel): class LabelTemplate(BaseModel): + """TN: 标签模板""" name = models.TextField("名称") - commands = models.JSONField("指令模板", default=list, blank=True) \ No newline at end of file + commands = models.JSONField("指令模板", default=list, blank=True) + process_json = models.JSONField("工序", default=list, blank=True) \ No newline at end of file diff --git a/apps/cm/serializers.py b/apps/cm/serializers.py index 075c7f0f..32aae18e 100644 --- a/apps/cm/serializers.py +++ b/apps/cm/serializers.py @@ -7,6 +7,8 @@ from apps.utils.serializers import CustomModelSerializer class TidSerializer(serializers.Serializer): tid = serializers.CharField(label='表ID') + label_template = serializers.CharField(label='标签模板ID(可传default)', allow_null=True, required=False) + extra_data = serializers.JSONField(label='额外数据', allow_null=True, required=False) class LabelMatSerializer(serializers.ModelSerializer): diff --git a/apps/cm/views.py b/apps/cm/views.py index 2ab8c35d..001fc0a4 100644 --- a/apps/cm/views.py +++ b/apps/cm/views.py @@ -6,6 +6,7 @@ from apps.wpm.models import WMaterial from rest_framework.exceptions import ParseError, NotFound from rest_framework.response import Response from apps.utils.viewsets import CustomGenericViewSet, RetrieveModelMixin, CustomListModelMixin, CustomModelViewSet +from apps.cm.filters import LabelTemplateFilter # Create your views here. SPLIT_FIELD = "#" @@ -16,6 +17,20 @@ class LableMatViewSet(CustomListModelMixin, RetrieveModelMixin, CustomGenericVie queryset = LableMat.objects.all() select_related_fields = ["material", "material_origin", "supplier"] + def gen_commands(self, label_template, tdata): + if label_template == "default": + lt = LabelTemplate.objects.get(name="默认标签模板") + else: + lt = LabelTemplate.objects.get(id=label_template) + commands:list = lt.commands + try: + for item in commands: + item = item.format(**tdata) + except Exception as e: + raise ParseError(f"标签解析错误-{str(e)}") + return commands + + @action(methods=["post"], detail=False, serializer_class=TidSerializer) def get_from_mb(self, request, pk=None): """ @@ -24,6 +39,8 @@ class LableMatViewSet(CustomListModelMixin, RetrieveModelMixin, CustomGenericVie 从仓库明细获取物料标签 """ tid = request.data.get("tid") + label_template = request.data.get("label_template", None) + extra_data = request.data.get("extra_data", {}) try: mb = MaterialBatch.objects.get(id=tid) except MaterialBatch.DoesNotExist: @@ -31,6 +48,10 @@ class LableMatViewSet(CustomListModelMixin, RetrieveModelMixin, CustomGenericVie obj, _ = LableMat.objects.get_or_create(state=mb.state, material=mb.material, batch=mb.batch, defect=mb.defect, defaults={"supplier": mb.supplier}) rdata = LabelMatSerializer(obj).data rdata["code_label"] = f"mat{SPLIT_FIELD}{obj.id}" + if label_template: + tdata = {**rdata, **extra_data} + commands = self.gen_commands(label_template, tdata) + rdata["commands"] = commands return Response(rdata) @action(methods=["post"], detail=False, serializer_class=TidSerializer) @@ -41,6 +62,8 @@ class LableMatViewSet(CustomListModelMixin, RetrieveModelMixin, CustomGenericVie 从车间库存明细获取物料标签 """ tid = request.data.get("tid") + label_template = request.data.get("label_template", None) + extra_data = request.data.get("extra_data", {}) try: wm = WMaterial.objects.get(id=tid) except WMaterial.DoesNotExist: @@ -50,6 +73,10 @@ class LableMatViewSet(CustomListModelMixin, RetrieveModelMixin, CustomGenericVie material_origin=wm.material_origin) rdata = LabelMatSerializer(obj).data rdata["code_label"] = f"mat{SPLIT_FIELD}{obj.id}" + if label_template: + tdata = {**rdata, **extra_data} + commands = self.gen_commands(label_template, tdata) + rdata["commands"] = commands return Response(rdata) @action(methods=["post"], detail=False, serializer_class=TidSerializer) @@ -60,6 +87,8 @@ class LableMatViewSet(CustomListModelMixin, RetrieveModelMixin, CustomGenericVie 从出入库明细获取物料标签 """ tid = request.data.get("tid") + label_template = request.data.get("label_template", None) + extra_data = request.data.get("extra_data", {}) try: mioitem: MIOItem = MIOItem.objects.get(id=tid) except MIOItem.DoesNotExist: @@ -67,6 +96,10 @@ class LableMatViewSet(CustomListModelMixin, RetrieveModelMixin, CustomGenericVie obj, _ = LableMat.objects.get_or_create(state=10, material=mioitem.material, batch=mioitem.batch, defaults={"supplier": mioitem.mio.supplier}) rdata = LabelMatSerializer(obj).data rdata["code_label"] = f"mat{SPLIT_FIELD}{obj.id}" + if label_template: + tdata = {**rdata, **extra_data} + commands = self.gen_commands(label_template, tdata) + rdata["commands"] = commands return Response(rdata) @@ -77,4 +110,5 @@ class LabelTemplateViewSet(CustomModelViewSet): 标签模板 """ queryset = LabelTemplate.objects.all() - serializer_class = LabelTemplateSerializer \ No newline at end of file + serializer_class = LabelTemplateSerializer + filterset_class = LabelTemplateFilter \ No newline at end of file From adf21e716d69cf3a9c22b0692790d9f656bd3eb8 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Tue, 6 May 2025 10:35:08 +0800 Subject: [PATCH 02/20] =?UTF-8?q?fix:=20=E6=A0=87=E7=AD=BE=E6=A8=A1?= =?UTF-8?q?=E6=9D=BF=E7=AD=9B=E9=80=89bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/cm/filters.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/cm/filters.py b/apps/cm/filters.py index 48c7a300..34fc6fca 100644 --- a/apps/cm/filters.py +++ b/apps/cm/filters.py @@ -4,7 +4,8 @@ from .models import LabelTemplate from apps.utils.filters import MyJsonListFilter class LabelTemplateFilter(filters.FilterSet): - process_json__contains = MyJsonListFilter(field_name='按工序查询') + process = MyJsonListFilter(field_name='按工序查询') class Meta: - model = LabelTemplate \ No newline at end of file + model = LabelTemplate + fields = ['process'] \ No newline at end of file From 2128b4e84739f7cffaa93080051ac7e26a1b967e Mon Sep 17 00:00:00 2001 From: caoqianming Date: Tue, 6 May 2025 10:54:09 +0800 Subject: [PATCH 03/20] =?UTF-8?q?feat:=20mioitem=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=8E=92=E5=BA=8F=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/inm/views.py | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/inm/views.py b/apps/inm/views.py index 51fe7854..f9d1c1a9 100644 --- a/apps/inm/views.py +++ b/apps/inm/views.py @@ -254,6 +254,7 @@ class MIOItemViewSet(CustomListModelMixin, BulkCreateModelMixin, BulkDestroyMode "test_date": ["isnull", "exact"] } ordering = ['create_time'] + ordering_fields = ['create_time', 'test_date'] def add_info_for_list(self, data): From cc12d80c920ce0d1f4747b0200fb7f18565a1836 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Wed, 7 May 2025 10:25:07 +0800 Subject: [PATCH 04/20] =?UTF-8?q?feat:=20myjsonfield=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/utils/filters.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/utils/filters.py b/apps/utils/filters.py index 0e950877..18baa0ef 100755 --- a/apps/utils/filters.py +++ b/apps/utils/filters.py @@ -3,13 +3,16 @@ from django_filters import rest_framework as filters class MyJsonListFilter(filters.CharFilter): def filter(self, qs, value): + if value in ['all', '']: return qs elif ',' in value: value_l = value.split(',') qsx = qs.none() for i in value_l: - qsx = qsx | qs.filter(tags__contains=i) + kv = {f"{self.field_name}__contains": i} + qsx = qsx | qs.filter(**kv) return qsx else: - return qs.filter(tags__contains=value) + kv = {f"{self.field_name}__contains": value} + return qs.filter(**kv) From 7aafa5d9f7624f7f320c4d1afb27b9b1e9f6b132 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Wed, 7 May 2025 10:25:40 +0800 Subject: [PATCH 05/20] fix: labeltemplate filter bug --- apps/cm/filters.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/cm/filters.py b/apps/cm/filters.py index 34fc6fca..a067efce 100644 --- a/apps/cm/filters.py +++ b/apps/cm/filters.py @@ -4,7 +4,7 @@ from .models import LabelTemplate from apps.utils.filters import MyJsonListFilter class LabelTemplateFilter(filters.FilterSet): - process = MyJsonListFilter(field_name='按工序查询') + process = MyJsonListFilter(label='按工序查询', field_name="process_json") class Meta: model = LabelTemplate From a9f55eb61cd934486fea44dcabe8f2b2acfb41d8 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 8 May 2025 10:37:58 +0800 Subject: [PATCH 06/20] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E4=BC=A0?= =?UTF-8?q?=E5=85=A5label=5Ftemplate=5Fname?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/cm/serializers.py | 1 + apps/cm/views.py | 25 +++++++++++++++---------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/apps/cm/serializers.py b/apps/cm/serializers.py index 32aae18e..42f3fc30 100644 --- a/apps/cm/serializers.py +++ b/apps/cm/serializers.py @@ -8,6 +8,7 @@ from apps.utils.serializers import CustomModelSerializer class TidSerializer(serializers.Serializer): tid = serializers.CharField(label='表ID') label_template = serializers.CharField(label='标签模板ID(可传default)', allow_null=True, required=False) + label_template_name = serializers.CharField(label='标签模板名称', allow_null=True, required=False) extra_data = serializers.JSONField(label='额外数据', allow_null=True, required=False) diff --git a/apps/cm/views.py b/apps/cm/views.py index 001fc0a4..e7a929de 100644 --- a/apps/cm/views.py +++ b/apps/cm/views.py @@ -17,11 +17,13 @@ class LableMatViewSet(CustomListModelMixin, RetrieveModelMixin, CustomGenericVie queryset = LableMat.objects.all() select_related_fields = ["material", "material_origin", "supplier"] - def gen_commands(self, label_template, tdata): - if label_template == "default": - lt = LabelTemplate.objects.get(name="默认标签模板") - else: + def gen_commands(self, label_template, label_template_name, tdata): + if label_template: lt = LabelTemplate.objects.get(id=label_template) + else: + lt = LabelTemplate.objects.filter(name=label_template_name).first() + if not lt: + raise NotFound("标签模板不存在") commands:list = lt.commands try: for item in commands: @@ -40,6 +42,7 @@ class LableMatViewSet(CustomListModelMixin, RetrieveModelMixin, CustomGenericVie """ tid = request.data.get("tid") label_template = request.data.get("label_template", None) + label_template_name = request.data.get("label_template_name", None) extra_data = request.data.get("extra_data", {}) try: mb = MaterialBatch.objects.get(id=tid) @@ -48,9 +51,9 @@ class LableMatViewSet(CustomListModelMixin, RetrieveModelMixin, CustomGenericVie obj, _ = LableMat.objects.get_or_create(state=mb.state, material=mb.material, batch=mb.batch, defect=mb.defect, defaults={"supplier": mb.supplier}) rdata = LabelMatSerializer(obj).data rdata["code_label"] = f"mat{SPLIT_FIELD}{obj.id}" - if label_template: + if label_template or label_template_name: tdata = {**rdata, **extra_data} - commands = self.gen_commands(label_template, tdata) + commands = self.gen_commands(label_template, label_template_name, tdata) rdata["commands"] = commands return Response(rdata) @@ -63,6 +66,7 @@ class LableMatViewSet(CustomListModelMixin, RetrieveModelMixin, CustomGenericVie """ tid = request.data.get("tid") label_template = request.data.get("label_template", None) + label_template_name = request.data.get("label_template_name", None) extra_data = request.data.get("extra_data", {}) try: wm = WMaterial.objects.get(id=tid) @@ -73,9 +77,9 @@ class LableMatViewSet(CustomListModelMixin, RetrieveModelMixin, CustomGenericVie material_origin=wm.material_origin) rdata = LabelMatSerializer(obj).data rdata["code_label"] = f"mat{SPLIT_FIELD}{obj.id}" - if label_template: + if label_template or label_template_name: tdata = {**rdata, **extra_data} - commands = self.gen_commands(label_template, tdata) + commands = self.gen_commands(label_template, label_template_name, tdata) rdata["commands"] = commands return Response(rdata) @@ -88,6 +92,7 @@ class LableMatViewSet(CustomListModelMixin, RetrieveModelMixin, CustomGenericVie """ tid = request.data.get("tid") label_template = request.data.get("label_template", None) + label_template_name = request.data.get("label_template_name", None) extra_data = request.data.get("extra_data", {}) try: mioitem: MIOItem = MIOItem.objects.get(id=tid) @@ -96,9 +101,9 @@ class LableMatViewSet(CustomListModelMixin, RetrieveModelMixin, CustomGenericVie obj, _ = LableMat.objects.get_or_create(state=10, material=mioitem.material, batch=mioitem.batch, defaults={"supplier": mioitem.mio.supplier}) rdata = LabelMatSerializer(obj).data rdata["code_label"] = f"mat{SPLIT_FIELD}{obj.id}" - if label_template: + if label_template or label_template_name: tdata = {**rdata, **extra_data} - commands = self.gen_commands(label_template, tdata) + commands = self.gen_commands(label_template, label_template_name, tdata) rdata["commands"] = commands return Response(rdata) From dae8d50d2c45e7be846ce89bbf2cb8c6b6d3ee75 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 8 May 2025 10:45:25 +0800 Subject: [PATCH 07/20] fix: gen_commands bug --- apps/cm/views.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/cm/views.py b/apps/cm/views.py index e7a929de..214bbc26 100644 --- a/apps/cm/views.py +++ b/apps/cm/views.py @@ -26,11 +26,13 @@ class LableMatViewSet(CustomListModelMixin, RetrieveModelMixin, CustomGenericVie raise NotFound("标签模板不存在") commands:list = lt.commands try: + n_commands = [] for item in commands: item = item.format(**tdata) + n_commands.append(item) except Exception as e: raise ParseError(f"标签解析错误-{str(e)}") - return commands + return n_commands @action(methods=["post"], detail=False, serializer_class=TidSerializer) From cdb4e65159af6a2027a6540ec99e48da24c3e694 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 8 May 2025 13:12:07 +0800 Subject: [PATCH 08/20] =?UTF-8?q?feat:=20=E5=88=9D=E6=AD=A5=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=85=89=E8=8A=AF=E7=9A=84=E6=89=B9=E6=AC=A1=E5=88=86?= =?UTF-8?q?=E6=9E=90=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wpm/scripts/batch_gxerp.py | 7 +++++++ apps/wpm/services_2.py | 10 +++------- 2 files changed, 10 insertions(+), 7 deletions(-) create mode 100644 apps/wpm/scripts/batch_gxerp.py diff --git a/apps/wpm/scripts/batch_gxerp.py b/apps/wpm/scripts/batch_gxerp.py new file mode 100644 index 00000000..7b45e599 --- /dev/null +++ b/apps/wpm/scripts/batch_gxerp.py @@ -0,0 +1,7 @@ +def main(batch: str): + return None, None + + + +if __name__ == '__main__': + pass \ No newline at end of file diff --git a/apps/wpm/services_2.py b/apps/wpm/services_2.py index 1f0787ff..a1319b77 100644 --- a/apps/wpm/services_2.py +++ b/apps/wpm/services_2.py @@ -23,8 +23,9 @@ def get_alldata_with_batch_and_store(batch: str, need_update_time=True): last_time, data = get_alldata_with_batch(batch) elif BASE_PROJECT_CODE == "gxerp": need_update = True - last_time, data = get_alldata_with_batch_gx(batch) - + from apps.wpm.scripts.batch_gxerp import main + last_time, data = main(batch) + if need_update and last_time and data: bobj, _ = BatchSt.objects.get_or_create(batch=batch, defaults={ "last_time": last_time @@ -34,11 +35,6 @@ def get_alldata_with_batch_and_store(batch: str, need_update_time=True): bobj.data = json.loads(json.dumps(data, cls=MyJSONEncoder)) bobj.save() -def get_alldata_with_batch_gx(batch: str): - """ - 光芯获取batch的统计数据 - """ - return None, None def get_alldata_with_batch(batch: str): """ From 8a75fcbc4211330f5da6a8e9457f12e67590312e Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 8 May 2025 13:12:32 +0800 Subject: [PATCH 09/20] =?UTF-8?q?feat:=20labeltemplate=E6=B7=BB=E5=8A=A0na?= =?UTF-8?q?me=E6=9F=A5=E8=AF=A2=E6=9D=A1=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/cm/filters.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/cm/filters.py b/apps/cm/filters.py index a067efce..4cdbe3d5 100644 --- a/apps/cm/filters.py +++ b/apps/cm/filters.py @@ -8,4 +8,4 @@ class LabelTemplateFilter(filters.FilterSet): class Meta: model = LabelTemplate - fields = ['process'] \ No newline at end of file + fields = ['process', "name"] \ No newline at end of file From 5e2fd57b89389369b670245af1b47bcd0db9c81e Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 8 May 2025 13:22:02 +0800 Subject: [PATCH 10/20] =?UTF-8?q?feat:=20labeltemplate=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E6=A0=87=E7=AD=BE=E6=8C=87=E4=BB=A4=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/cm/models.py | 21 ++++++++++++++++++++- apps/cm/serializers.py | 7 ++++++- apps/cm/views.py | 41 ++++++++++++++++++----------------------- 3 files changed, 44 insertions(+), 25 deletions(-) diff --git a/apps/cm/models.py b/apps/cm/models.py index 64fa5af0..f2e22728 100644 --- a/apps/cm/models.py +++ b/apps/cm/models.py @@ -3,6 +3,7 @@ from apps.utils.models import BaseModel from apps.mtm.models import Material from apps.pum.models import Supplier from apps.wpm.models import WmStateOption +from rest_framework.exceptions import NotFound, ParseError # Create your models here. class LableMat(BaseModel): @@ -20,4 +21,22 @@ class LabelTemplate(BaseModel): """TN: 标签模板""" name = models.TextField("名称") commands = models.JSONField("指令模板", default=list, blank=True) - process_json = models.JSONField("工序", default=list, blank=True) \ No newline at end of file + process_json = models.JSONField("工序", default=list, blank=True) + + @classmethod + def gen_commands(cls, label_template, label_template_name, tdata): + if label_template: + lt = LabelTemplate.objects.get(id=label_template) + else: + lt = LabelTemplate.objects.filter(name=label_template_name).first() + if not lt: + raise NotFound("标签模板不存在") + commands:list = lt.commands + try: + n_commands = [] + for item in commands: + item = item.format(**tdata) + n_commands.append(item) + except Exception as e: + raise ParseError(f"标签解析错误-{str(e)}") + return n_commands \ No newline at end of file diff --git a/apps/cm/serializers.py b/apps/cm/serializers.py index 42f3fc30..5ccbfc51 100644 --- a/apps/cm/serializers.py +++ b/apps/cm/serializers.py @@ -7,10 +7,15 @@ from apps.utils.serializers import CustomModelSerializer class TidSerializer(serializers.Serializer): tid = serializers.CharField(label='表ID') - label_template = serializers.CharField(label='标签模板ID(可传default)', allow_null=True, required=False) + label_template = serializers.CharField(label='标签模板ID', allow_null=True, required=False) label_template_name = serializers.CharField(label='标签模板名称', allow_null=True, required=False) extra_data = serializers.JSONField(label='额外数据', allow_null=True, required=False) +class Tid2Serializer(serializers.Serializer): + label_template = serializers.CharField(label='标签模板ID', allow_null=True, required=False) + label_template_name = serializers.CharField(label='标签模板名称', allow_null=True, required=False) + data = serializers.JSONField(label='数据', allow_null=True, required=False) + class LabelMatSerializer(serializers.ModelSerializer): material_name = serializers.StringRelatedField(source='material', read_only=True) diff --git a/apps/cm/views.py b/apps/cm/views.py index 214bbc26..92c30a6a 100644 --- a/apps/cm/views.py +++ b/apps/cm/views.py @@ -1,6 +1,6 @@ from apps.cm.models import LableMat, LabelTemplate from rest_framework.decorators import action -from apps.cm.serializers import TidSerializer, LabelMatSerializer, LabelTemplateSerializer +from apps.cm.serializers import TidSerializer, LabelMatSerializer, LabelTemplateSerializer, Tid2Serializer from apps.inm.models import MaterialBatch, MIOItem from apps.wpm.models import WMaterial from rest_framework.exceptions import ParseError, NotFound @@ -17,24 +17,6 @@ class LableMatViewSet(CustomListModelMixin, RetrieveModelMixin, CustomGenericVie queryset = LableMat.objects.all() select_related_fields = ["material", "material_origin", "supplier"] - def gen_commands(self, label_template, label_template_name, tdata): - if label_template: - lt = LabelTemplate.objects.get(id=label_template) - else: - lt = LabelTemplate.objects.filter(name=label_template_name).first() - if not lt: - raise NotFound("标签模板不存在") - commands:list = lt.commands - try: - n_commands = [] - for item in commands: - item = item.format(**tdata) - n_commands.append(item) - except Exception as e: - raise ParseError(f"标签解析错误-{str(e)}") - return n_commands - - @action(methods=["post"], detail=False, serializer_class=TidSerializer) def get_from_mb(self, request, pk=None): """ @@ -55,7 +37,7 @@ class LableMatViewSet(CustomListModelMixin, RetrieveModelMixin, CustomGenericVie rdata["code_label"] = f"mat{SPLIT_FIELD}{obj.id}" if label_template or label_template_name: tdata = {**rdata, **extra_data} - commands = self.gen_commands(label_template, label_template_name, tdata) + commands = LabelTemplate.gen_commands(label_template, label_template_name, tdata) rdata["commands"] = commands return Response(rdata) @@ -81,7 +63,7 @@ class LableMatViewSet(CustomListModelMixin, RetrieveModelMixin, CustomGenericVie rdata["code_label"] = f"mat{SPLIT_FIELD}{obj.id}" if label_template or label_template_name: tdata = {**rdata, **extra_data} - commands = self.gen_commands(label_template, label_template_name, tdata) + commands = LabelTemplate.gen_commands(label_template, label_template_name, tdata) rdata["commands"] = commands return Response(rdata) @@ -105,7 +87,7 @@ class LableMatViewSet(CustomListModelMixin, RetrieveModelMixin, CustomGenericVie rdata["code_label"] = f"mat{SPLIT_FIELD}{obj.id}" if label_template or label_template_name: tdata = {**rdata, **extra_data} - commands = self.gen_commands(label_template, label_template_name, tdata) + commands = LabelTemplate.gen_commands(label_template, label_template_name, tdata) rdata["commands"] = commands return Response(rdata) @@ -118,4 +100,17 @@ class LabelTemplateViewSet(CustomModelViewSet): """ queryset = LabelTemplate.objects.all() serializer_class = LabelTemplateSerializer - filterset_class = LabelTemplateFilter \ No newline at end of file + filterset_class = LabelTemplateFilter + + @action(methods=["post"], detail=False, serializer_class=Tid2Serializer) + def commands(self, request, *args, **kwargs): + """ + 获取标签指令 + + 获取标签指令 + """ + label_template = request.data.get("label_template", None) + label_template_name = request.data.get("label_template_name", None) + data = request.data.get("data", {}) + return Response({"commands": LabelTemplate.gen_commands(label_template, label_template_name, data)}) + \ No newline at end of file From 20384ca33c9d9500cad1c500df977b6046e11a79 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 8 May 2025 13:53:59 +0800 Subject: [PATCH 11/20] =?UTF-8?q?feat:=20=E7=94=B1=E8=BE=93=E5=85=A5?= =?UTF-8?q?=E8=BD=AC=E8=BE=93=E5=87=BA=E9=9C=80=E8=80=83=E8=99=91=E5=88=B0?= =?UTF-8?q?=E5=8A=A0=E5=B7=A5=E5=89=8D=E4=B8=8D=E8=89=AF=E7=9A=84=E5=BD=B1?= =?UTF-8?q?=E5=93=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wpm/views.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/wpm/views.py b/apps/wpm/views.py index 67c49ed1..56db113b 100644 --- a/apps/wpm/views.py +++ b/apps/wpm/views.py @@ -602,8 +602,8 @@ class MlogbInViewSet(CreateModelMixin, UpdateModelMixin, DestroyModelMixin, Cust m_dict['batch'] = generate_new_batch(mlogbin.batch, mlog) if mtype == Process.PRO_NORMAL: # 正常 支持批到批, 个到个 - d_count_real = mlogbin.count_use - d_count_ok = mlogbin.count_use + d_count_real = mlogbin.count_use - mlogbin.count_pn_jgqbl + d_count_ok = d_count_real mlogbout, _ = Mlogb.objects.get_or_create(mlogb_from=mlogbin, defaults= update_dict(m_dict, {"count_real": d_count_real, "count_ok": d_count_ok})) mlogbout.count_json_from = mlogbin.count_json_from @@ -627,7 +627,7 @@ class MlogbInViewSet(CreateModelMixin, UpdateModelMixin, DestroyModelMixin, Cust mlogbout.number_from = mlogbwin.number mlogbout.save() elif material_in.tracking == Material.MA_TRACKING_SINGLE and material_out.tracking == Material.MA_TRACKING_SINGLE: - d_count_real = mlogbin.count_use * div_number + d_count_real = (mlogbin.count_use-mlogbin.count_pn_jgqbl) * div_number d_count_ok = d_count_real mlogbout, _ = Mlogb.objects.get_or_create(mlogb_from=mlogbin, defaults=update_dict(m_dict, {"count_real": d_count_real, "count_ok": d_count_ok})) @@ -639,13 +639,13 @@ class MlogbInViewSet(CreateModelMixin, UpdateModelMixin, DestroyModelMixin, Cust for i in range(div_number): Mlogbw.objects.get_or_create(mlogb=mlogbout, number=f'{wpr_.number}-{i+1}', defaults={"mlogbw_from": mlogbwin}) elif material_in.tracking == Material.MA_TRACKING_BATCH and material_out.tracking == Material.MA_TRACKING_BATCH: - d_count_real = mlogbin.count_use * div_number + d_count_real = (mlogbin.count_use-mlogbin.count_pn_jgqbl) * div_number d_count_ok = d_count_real mlogbout, _ = Mlogb.objects.get_or_create(mlogb_from=mlogbin, defaults=update_dict(m_dict,{"count_real": d_count_real, "count_ok": d_count_ok})) mlogbout.count_json_from = mlogbin.count_json_from mlogbout.save(update_fields=["count_json_from"]) elif mtype == Process.PRO_MERGE: # 支持批到批,批到个 - xcount = math.floor( mlogbin.count_use / route.div_number) + xcount = math.floor( (mlogbin.count_use-mlogbin.count_pn_jgqbl) / route.div_number) d_count_real = xcount d_count_ok = xcount mlogbout, _ = Mlogb.objects.get_or_create(mlogb_from=mlogbin, defaults=update_dict(m_dict, {"count_real": d_count_real, "count_ok": d_count_ok})) @@ -661,8 +661,8 @@ class MlogbInViewSet(CreateModelMixin, UpdateModelMixin, DestroyModelMixin, Cust for i in range(d_count_real): Mlogbw.objects.get_or_create(number=f'{number}-{i+1}', mlogb=mlogbout) elif is_fix:# 支持批到批,个到个 - d_count_real = mlogbin.count_use - d_count_ok = mlogbin.count_use + d_count_real = mlogbin.count_use-mlogbin.count_pn_jgqbl + d_count_ok = d_count_real Mlogb.objects.get_or_create(mlogb_from=mlogbin, defaults=update_dict(m_dict,{"count_real": d_count_real, "count_ok": d_count_ok})) if material_in.tracking == Material.MA_TRACKING_SINGLE and material_out.tracking == Material.MA_TRACKING_SINGLE: for mlogbwin in Mlogbw.objects.filter(mlogb=mlogbin).order_by("number"): From c29d1e99d8219d49c9385f5325624273064396a2 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 8 May 2025 14:56:40 +0800 Subject: [PATCH 12/20] =?UTF-8?q?feat:=20batchst=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E5=B9=B6=E6=9B=B4=E6=96=B0=E5=85=89=E5=AD=90?= =?UTF-8?q?=E7=9A=84=E7=BB=9F=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wpm/filters.py | 2 + apps/wpm/models.py | 1 + apps/wpm/services_2.py | 105 +++++++++++++++++++++++++++++++---------- 3 files changed, 82 insertions(+), 26 deletions(-) diff --git a/apps/wpm/filters.py b/apps/wpm/filters.py index a4a17fc4..c698d8e4 100644 --- a/apps/wpm/filters.py +++ b/apps/wpm/filters.py @@ -178,9 +178,11 @@ class BatchStFilter(filters.FilterSet): model = BatchSt fields = { "batch": ["exact", "contains", "startswith"], + "first_time": ["exact", "gte", "lte"], "last_time": ["exact", "gte", "lte"], "update_time": ["exact", "gte", "lte"], "material_start": ["exact"], + "material_start__cate": ["exact"], "material_start__type": ["exact"], "material_start__process": ["exact"] } diff --git a/apps/wpm/models.py b/apps/wpm/models.py index f6e306dd..cc344e1a 100644 --- a/apps/wpm/models.py +++ b/apps/wpm/models.py @@ -609,6 +609,7 @@ class BatchSt(BaseModel): """ batch = models.TextField("批次号", db_index=True) version = models.IntegerField("版本号", default=1, db_index=True) + first_time = models.DateTimeField("首次操作时间", null=True, blank=True) last_time = models.DateTimeField("最后操作时间", null=True, blank=True) data = models.JSONField("数据", default=list, blank=True) material_start = models.ForeignKey(Material, verbose_name="起始物料", on_delete=models.SET_NULL, null=True, blank=True) diff --git a/apps/wpm/services_2.py b/apps/wpm/services_2.py index a1319b77..f965c7c5 100644 --- a/apps/wpm/services_2.py +++ b/apps/wpm/services_2.py @@ -12,27 +12,29 @@ import decimal import logging myLogger = logging.getLogger('log') -def get_alldata_with_batch_and_store(batch: str, need_update_time=True): +def get_alldata_with_batch_and_store(batch: str): """ 获取某个批次的整体生产数据并保存 """ - need_update = False + data = None + action = "get" BASE_PROJECT_CODE = getattr(settings, "BASE_PROJECT_CODE", None) if BASE_PROJECT_CODE == "gzerp": - need_update = True - last_time, data = get_alldata_with_batch(batch) + action = "get_or_create" + data, extra = get_alldata_with_batch(batch) elif BASE_PROJECT_CODE == "gxerp": - need_update = True from apps.wpm.scripts.batch_gxerp import main - last_time, data = main(batch) + data, extra = main(batch) - if need_update and last_time and data: - bobj, _ = BatchSt.objects.get_or_create(batch=batch, defaults={ - "last_time": last_time - }) - if need_update_time: - bobj.last_time = last_time + if data: + if action == "get_or_create": + bobj, _ = BatchSt.objects.get_or_create(batch=batch) + elif action == "get": + bobj = BatchSt.objects.get(batch=batch, version=1) bobj.data = json.loads(json.dumps(data, cls=MyJSONEncoder)) + for k, v in extra.items(): + if hasattr(bobj, k): + setattr(bobj, k, v) bobj.save() @@ -50,13 +52,19 @@ def get_alldata_with_batch(batch: str): mlog_count_fields = Mlog.count_fields() + first_time = None + material_start = None if mlogs_blcx_qs.exists(): data["产品规格"] = [] data["棒料成型_出料人"] = [] data["棒料成型_切料人"] = [] data["棒料成型_备注"] = "" for item in mlogs_blcx_qs: - last_time = item.update_time if item.update_time > last_time else last_time + utime = item.submit_time + last_time = utime if utime > last_time else last_time + first_time = utime if first_time is None else (utime if utime < first_time else first_time) + if material_start is None: + material_start = item.material_out data["产品规格"].append(item.material_out) # 对象 if item.handle_user: data["棒料成型_出料人"].append(item.handle_user) # 对象 @@ -82,7 +90,7 @@ def get_alldata_with_batch(batch: str): except ZeroDivisionError: data["棒料成型_合格率"] = 0 except decimal.InvalidOperation: - myLogger.error(f"棒料成型_合格率计算错误decimal.InvalidOperation-{data}") + # myLogger.error(f"棒料成型_合格率计算错误decimal.InvalidOperation-{data}") data["棒料成型_合格率"] = 0 # 管料成型数据 @@ -92,7 +100,11 @@ def get_alldata_with_batch(batch: str): data["产品规格"] = [] data["管料成型_备注"] = "" for item in mlogs_glcx_qs: - last_time = item.update_time if item.update_time > last_time else last_time + utime = item.submit_time + last_time = utime if utime > last_time else last_time + first_time = utime if first_time is None else (utime if utime < first_time else first_time) + if material_start is None: + material_start = item.material_out data["产品规格"].append(item.material_out) # 对象 if item.note: data["管料成型_备注"] = ";".join([data["管料成型_备注"], item.note]) @@ -115,7 +127,11 @@ def get_alldata_with_batch(batch: str): data["七车间入库_仓库执行人"] = [] data["七车间入库_检验备注"] = "" for item in mioitem_qs: - last_time = item.update_time if item.update_time > last_time else last_time + utime = item.mio.submit_time + last_time = utime if utime > last_time else last_time + first_time = utime if first_time is None else (utime if utime < first_time else first_time) + if material_start is None: + material_start = item.material data["七车间入库_日期"].append(item.mio.inout_date) if item.test_note: data["七车间入库_检验备注"] = ";".join([data["七车间入库_检验备注"], item.test_note]) @@ -149,7 +165,11 @@ def get_alldata_with_batch(batch: str): data["十车间入库_日期"] = [] data["十车间入库_检验备注"] = "" for item in mioitem10_qs: - last_time = item.update_time if item.update_time > last_time else last_time + utime = item.mio.submit_time + last_time = utime if utime > last_time else last_time + first_time = utime if first_time is None else (utime if utime < first_time else first_time) + if material_start is None: + material_start = item.material if item.test_note: data["十车间入库_检验备注"] = ";".join([data["十车间入库_检验备注"], item.test_note]) if item.mio.do_user: @@ -184,7 +204,15 @@ def get_alldata_with_batch(batch: str): data["产品规格"] = [] for item in mlogs_glth_qs: data["产品规格"].append(item.material_out) - last_time = item.update_time if item.update_time > last_time else last_time + utime = item.submit_time + last_time = utime if utime > last_time else last_time + first_time = utime if first_time is None else (utime if utime < first_time else first_time) + if first_time is None: + first_time = item.update_time + else: + first_time = item.update_time if item.update_time < first_time else first_time + if material_start is None: + material_start = item.material_out if item.note: data["管料退火_备注"] = ";".join([data["管料退火_备注"], item.note]) if item.handle_date: @@ -216,7 +244,11 @@ def get_alldata_with_batch(batch: str): data["产品规格"] = [] for item in mioitem6_qs: data["产品规格"].append(item.material) - last_time = item.update_time if item.update_time > last_time else last_time + utime = item.mio.submit_time + last_time = utime if utime > last_time else last_time + first_time = utime if first_time is None else (utime if utime < first_time else first_time) + if material_start is None: + material_start = item.material data["六车间领料_日期"].append(item.mio.inout_date) if item.mio.do_user: data["六车间领料_仓库执行人"].append(item.mio.do_user) @@ -248,11 +280,15 @@ def get_alldata_with_batch(batch: str): mgroups = Mgroup.objects.filter(name=mgroup_name) mlogs_qs = Mlog.objects.filter(submit_time__isnull=False, mgroup__in=mgroups, batch=batch) if mlogs_qs.exists(): - last_time = item.update_time if item.update_time > last_time else last_time data[f'六车间_{mgroup_name}_日期'] = [] data[f'六车间_{mgroup_name}_操作人'] = [] data[f'六车间_{mgroup_name}_备注'] = "" for item in mlogs_qs: + utime = item.submit_time + last_time = utime if utime > last_time else last_time + first_time = utime if first_time is None else (utime if utime < first_time else first_time) + if material_start is None: + material_start = item.material_out if item.note: data[f'六车间_{mgroup_name}_备注'] = ";".join([data[f'六车间_{mgroup_name}_备注'], item.note]) if item.handle_date: @@ -272,7 +308,7 @@ def get_alldata_with_batch(batch: str): try: data[f'六车间_{mgroup_name}_合格率'] = round(data[f'六车间_{mgroup_name}_count_ok'] * 100/ data[f'六车间_{mgroup_name}_count_real'], 1) except decimal.InvalidOperation: - myLogger.error(f"六车间_{mgroup_name}_合格率decimal.InvalidOperation-{data}") + # myLogger.error(f"六车间_{mgroup_name}_合格率decimal.InvalidOperation-{data}") data[f'六车间_{mgroup_name}_合格率'] = 0 ftestwork_count_fields = FtestWork.count_fields() @@ -282,7 +318,11 @@ def get_alldata_with_batch(batch: str): data["六车间中检_日期"] = [] data['六车间中检_检验人'] = [] for item in ftestwork_qs: - last_time = item.update_time if item.update_time > last_time else last_time + utime = item.update_time + last_time = utime if utime > last_time else last_time + first_time = utime if first_time is None else (utime if utime < first_time else first_time) + if material_start is None: + material_start = item.material if item.test_date: data["六车间中检_日期"].append(item.test_date) if item.test_user: @@ -314,6 +354,11 @@ def get_alldata_with_batch(batch: str): data["六车间生产入库_检验日期"] = [] data["六车间生产入库_检验人"] = [] for item in mioitem6_qs2: + utime = item.mio.submit_time + last_time = utime if utime > last_time else last_time + first_time = utime if first_time is None else (utime if utime < first_time else first_time) + if material_start is None: + material_start = item.material data["六车间生产入库_日期"].append(item.mio.inout_date) if item.test_date: data["六车间生产入库_检验日期"].append(item.test_date) @@ -330,7 +375,7 @@ def get_alldata_with_batch(batch: str): try: data['六车间生产入库_合格率'] = round((data['六车间生产入库_count'] - data['六车间生产入库_count_notok']) * 100/ data['六车间生产入库_count'], 1) except decimal.InvalidOperation: - myLogger.error("六车间生产入库_合格率decimal.InvalidOperation-{data}") + # myLogger.error("六车间生产入库_合格率decimal.InvalidOperation-{data}") data['六车间生产入库_合格率'] = 0 # 成品检验数据 @@ -339,7 +384,11 @@ def get_alldata_with_batch(batch: str): data["成品检验_日期"] = [] data['成品检验_检验人'] = [] for item in ftestwork_qs: - last_time = item.update_time if item.update_time > last_time else last_time + utime = item.update_time + last_time = utime if utime > last_time else last_time + first_time = utime if first_time is None else (utime if utime < first_time else first_time) + if material_start is None: + material_start = item.material if item.test_date: data["成品检验_日期"].append(item.test_date) if item.test_user: @@ -374,7 +423,11 @@ def get_alldata_with_batch(batch: str): data['销售发货_仓库执行人'] = [] data['销售发货_count'] = 0 for item in mioitem_qs: - last_time = item.mio.update_time if item.mio.update_time > last_time else last_time + utime = item.mio.submit_time + last_time = utime if utime > last_time else last_time + first_time = utime if first_time is None else (utime if utime < first_time else first_time) + if material_start is None: + material_start = item.material if item.mio.inout_date: data["销售发货_日期"].append(item.mio.inout_date) if item.mio.do_user: @@ -386,5 +439,5 @@ def get_alldata_with_batch(batch: str): data["六车间_批次发货合格率"] = round(data["销售发货_count"] * 100/ data["六车间领料_count"], 1) data['销售发货_仓库执行人'] = ";".join([item.name for item in data['销售发货_仓库执行人']]) - return last_time, data + return data, {"material_start": material_start, "last_time": last_time, "first_time": first_time} \ No newline at end of file From 8a501c268162db26fd9bc0567d095eb9bb573264 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 8 May 2025 15:13:04 +0800 Subject: [PATCH 13/20] =?UTF-8?q?feat:=20batchst=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E5=B9=B6=E6=9B=B4=E6=96=B0=E5=85=89=E5=AD=90?= =?UTF-8?q?=E7=9A=84=E7=BB=9F=E8=AE=A12?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wpm/services_2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/wpm/services_2.py b/apps/wpm/services_2.py index f965c7c5..6e7fedf9 100644 --- a/apps/wpm/services_2.py +++ b/apps/wpm/services_2.py @@ -28,7 +28,7 @@ def get_alldata_with_batch_and_store(batch: str): if data: if action == "get_or_create": - bobj, _ = BatchSt.objects.get_or_create(batch=batch) + bobj, _ = BatchSt.objects.get_or_create(batch=batch, version=1) elif action == "get": bobj = BatchSt.objects.get(batch=batch, version=1) bobj.data = json.loads(json.dumps(data, cls=MyJSONEncoder)) From 954f5d262f57066539d7c6b61a47e13699d78b60 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 8 May 2025 16:13:50 +0800 Subject: [PATCH 14/20] =?UTF-8?q?feat:=20=E5=AE=8C=E5=96=84=E6=B8=85?= =?UTF-8?q?=E7=A9=BA=E6=95=B0=E6=8D=AE=E7=9A=84=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/develop/views.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/apps/develop/views.py b/apps/develop/views.py index 893b9cda..3dd2d692 100755 --- a/apps/develop/views.py +++ b/apps/develop/views.py @@ -616,14 +616,14 @@ class TestViewSet(CustomGenericViewSet): 'apps.rpm.tasks.close_rpj_by_leave_time']).delete() if 'mes' in datas: from apps.inm.models import MaterialBatch, MIO - from apps.mtm.models import Material + from apps.mtm.models import Material, RoutePack from apps.wpmw.models import Wpr - from apps.wpm.models import WMaterial, Mlog + from apps.wpm.models import WMaterial, Mlog, Handover, BatchSt from apps.pum.models import PuOrder from apps.sam.models import Order from apps.pm.models import Utask, Mtask - from apps.wpm.models import Handover from apps.qm.models import Ftest, FtestWork + from apps.wf.models import Ticket MaterialBatch.objects.all().delete() MIO.objects.all().delete() Wpr.objects.all().delete() @@ -636,7 +636,9 @@ class TestViewSet(CustomGenericViewSet): Handover.objects.all().delete() Ftest.objects.all().delete() FtestWork.objects.all().delete() - Material.objects.all().update(count=0, count_mb=0, count_wm=0) + Material.objects.get_queryset(all=True).update(count=0, count_mb=0, count_wm=0) + BatchSt.objects.all().delete() + Ticket.objects.get_queryset(all=True).delete() return Response() @action(methods=['post'], detail=False, serializer_class=Serializer, permission_classes=[]) From 0d3d4160ef1cde9e5e1436c0f60bf8f430abeec5 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 8 May 2025 16:18:19 +0800 Subject: [PATCH 15/20] release: 2.6.2025050816 --- changelog.md | 13 +++++++++++++ server/settings.py | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index 0daaedaf..b175d2cf 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,16 @@ +## 2.6.2025050816 +- feat: 新增功能 + - batchst添加字段并更新光子的统计 [caoqianming] + - 由输入转输出需考虑到加工前不良的影响 [caoqianming] + - 初步添加光芯的批次分析函数 [caoqianming] + - myjsonfield优化 [caoqianming] + - mioitem添加排序字段 [caoqianming] + - 标签物料根据模板打印功能 [caoqianming] + - ichat 修改接口去掉langchain [zty] +- fix: 问题修复 + - gen_commands bug [caoqianming] + - labeltemplate filter bug [caoqianming] + - 标签模板筛选bug [caoqianming] ## 2.6.2025043014 - feat: 新增功能 - 生产入库和领料支持b类合格品 [caoqianming] diff --git a/server/settings.py b/server/settings.py index dceec682..f234f979 100755 --- a/server/settings.py +++ b/server/settings.py @@ -35,7 +35,7 @@ sys.path.insert(0, os.path.join(BASE_DIR, 'apps')) ALLOWED_HOSTS = ['*'] SYS_NAME = '星途工厂综合管理系统' -SYS_VERSION = '2.6.2025043014' +SYS_VERSION = '2.6.2025050816' X_FRAME_OPTIONS = 'SAMEORIGIN' # Application definition From 06e04858df3a608b3a424787b06e5df4d82c45ec Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 8 May 2025 16:24:06 +0800 Subject: [PATCH 16/20] =?UTF-8?q?feat:=20batchst=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E6=95=B0=E6=8D=AE=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wpm/migrations/0115_batchst_first_time.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 apps/wpm/migrations/0115_batchst_first_time.py diff --git a/apps/wpm/migrations/0115_batchst_first_time.py b/apps/wpm/migrations/0115_batchst_first_time.py new file mode 100644 index 00000000..aef50426 --- /dev/null +++ b/apps/wpm/migrations/0115_batchst_first_time.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.12 on 2025-05-08 08:23 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('wpm', '0114_auto_20250428_1350'), + ] + + operations = [ + migrations.AddField( + model_name='batchst', + name='first_time', + field=models.DateTimeField(blank=True, null=True, verbose_name='首次操作时间'), + ), + ] From 1c8489a0b4620c333448b8b501568e458d42528b Mon Sep 17 00:00:00 2001 From: caoqianming Date: Fri, 9 May 2025 09:10:39 +0800 Subject: [PATCH 17/20] =?UTF-8?q?feat:=20base=20=E7=9F=AD=E4=BF=A1?= =?UTF-8?q?=E5=8F=91=E9=80=81=E5=8A=9F=E8=83=BD=E5=90=AF=E5=8A=A8=E6=8A=9B?= =?UTF-8?q?=E5=87=BA=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/utils/sms.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/utils/sms.py b/apps/utils/sms.py index 19616381..0bfc6dad 100644 --- a/apps/utils/sms.py +++ b/apps/utils/sms.py @@ -12,8 +12,8 @@ myLogger = logging.getLogger('log') @auto_log(name='阿里云短信', raise_exception=True, send_mail=True) def send_sms(phone: str, template_code: int, template_param: dict): config = get_sysconfig() - if config.get("sms", {}).get('enabled', True) is False: - return + if config.get("sms", {}).get('enabled', False) is False: + raise Exception("短信发送功能未启用") try: client = AcsClient(config['sms']['xn_key'], config['sms']['xn_secret'], 'default') From ad1bbaa32eed2d626415d9be8c0cd7787c7389e8 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Fri, 9 May 2025 09:13:35 +0800 Subject: [PATCH 18/20] =?UTF-8?q?feat:=20base=20=E7=9F=AD=E4=BF=A1?= =?UTF-8?q?=E5=8F=91=E9=80=81=E5=8A=9F=E8=83=BD=E5=90=AF=E5=8A=A8=E6=8A=9B?= =?UTF-8?q?=E5=87=BA=E5=BC=82=E5=B8=B82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/utils/sms.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/utils/sms.py b/apps/utils/sms.py index 0bfc6dad..7e3d85bb 100644 --- a/apps/utils/sms.py +++ b/apps/utils/sms.py @@ -4,6 +4,7 @@ import json import logging from server.settings import get_sysconfig from apps.utils.decorators import auto_log +from rest_framework.exceptions import ParseError # 实例化myLogger myLogger = logging.getLogger('log') @@ -13,7 +14,7 @@ myLogger = logging.getLogger('log') def send_sms(phone: str, template_code: int, template_param: dict): config = get_sysconfig() if config.get("sms", {}).get('enabled', False) is False: - raise Exception("短信发送功能未启用") + raise ParseError("短信发送功能未启用") try: client = AcsClient(config['sms']['xn_key'], config['sms']['xn_secret'], 'default') From 09072f79986f14bcec95e9fb0c7822113ce431bb Mon Sep 17 00:00:00 2001 From: caoqianming Date: Fri, 9 May 2025 16:51:55 +0800 Subject: [PATCH 19/20] =?UTF-8?q?feat:=20=E5=85=89=E8=8A=AF=E8=B4=A8?= =?UTF-8?q?=E6=A3=80=E8=A1=A8=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wpm/scripts/batch_gxerp.py | 90 ++++++++++++++++++++++++++++++++- 1 file changed, 89 insertions(+), 1 deletion(-) diff --git a/apps/wpm/scripts/batch_gxerp.py b/apps/wpm/scripts/batch_gxerp.py index 7b45e599..eb3116f1 100644 --- a/apps/wpm/scripts/batch_gxerp.py +++ b/apps/wpm/scripts/batch_gxerp.py @@ -1,7 +1,95 @@ +from apps.wpm.models import BatchSt +import logging +from apps.qm.models import Defect +from apps.wpm.models import Mlogb, MlogbDefect +import decimal +from django.db.models import Sum + +myLogger = logging.getLogger("log") + def main(batch: str): - return None, None + try: + batchst = BatchSt.objects.get(batch=batch, version=1) + except BatchSt.DoesNotExist: + myLogger.error(f"Batch {batch} does not exist") + return None, None + + data = {"批次号": batch} + mgroup_names = ["尺寸检验", "外观检验"] + for mgroup_name in mgroup_names: + mlogb1_qs = Mlogb.objects.filter(mlog__submit_time__isnull=False, material_out__isnull=False, mlog__mgroup__name=mgroup_name, batch=batch) + if mlogb1_qs.exists(): + data[f"{mgroup_name}_日期"] = [] + data[f"{mgroup_name}_操作人"] = [] + data[f"{mgroup_name}_count_real"] = 0 + data[f"{mgroup_name}_count_ok"] = 0 + data[f"{mgroup_name}_count_ok_full"] = 0 + for item in mlogb1_qs: + if item.mlog.handle_user: + data[f"{mgroup_name}_操作人"].append(item.mlog.handle_user) + if item.mlog.handle_date: + data[f"{mgroup_name}_日期"].append(item.mlog.handle_date) + data[f"{mgroup_name}_count_real"] += item.count_real + data[f"{mgroup_name}_count_ok"] += item.count_ok + data[f"{mgroup_name}_count_ok_full"] += item.count_ok_full + + try: + data[f"{mgroup_name}_合格率"] = round((data[f"{mgroup_name}-count_ok"] / data[f"{mgroup_name}-count_real"])*100, 2) + except decimal.InvalidOperation: + data[f"{mgroup_name}_合格率"] = 0 + + mlogbd1_qs = MlogbDefect.objects.filter(mlogb__in=mlogb1_qs, count__gt=0).values("defect__name").annotate(total=Sum("count")) + for item in mlogbd1_qs: + data[f"{mgroup_name}_缺陷_{item['defect__name']}"] = item["total"] + data[f"{mgroup_name}_缺陷_{item['defect__name']}-比例"] = round((item["total"] / data[f"{mgroup_name}-count_real"])*100, 2) + + data[f"{mgroup_name}_日期"] = list(set(data[f"{mgroup_name}_日期"])) + data[f"{mgroup_name}_日期"] = ";".join([item.strftime("%Y-%m-%d") for item in data[f"{mgroup_name}_日期"]]) + data[f"{mgroup_name}_操作人"] = list(set(data[f"{mgroup_name}_操作人"])) + data[f"{mgroup_name}_操作人"] = ";".join([item.name for item in data[f"{mgroup_name}_操作人"]]) + + mlogb2_qs = Mlogb.objects.filter(mlog__submit_time__isnull=False, material_out__isnull=False, mlog__mgroup__name="外观检验", mlog__is_fix=True, batch=batch) + if mlogb2_qs.exists(): + data["外观检验_返修_日期"] = [] + data["外观检验_返修_操作人"] = [] + data["外观检验_返修_count_real"] = 0 + data["外观检验_返修_count_ok"] = 0 + data["外观检验_返修_count_ok_full"] = 0 + for item in mlogb2_qs: + if item.mlog.handle_user: + data["外观检验_返修_操作人"].append(item.mlog.handle_user) + if item.mlog.handle_date: + data["外观检验_返修_日期"].append(item.mlog.handle_date) + data["外观检验_返修_count_real"] += item.count_real + data["外观检验_返修_count_ok"] += item.count_ok + data["外观检验_返修_count_ok_full"] += item.count_ok_full + + data["外观检验_返修_日期"] = list(set(data["外观检验_返修_日期"])) + data["外观检验_返修_日期"] = ";".join([item.strftime("%Y-%m-%d") for item in data["外观检验_返修_日期"]]) + data["外观检验_返修_操作人"] = list(set(data["外观检验_返修_操作人"])) + data["外观检验_返修_操作人"] = ";".join([item.name for item in data["外观检验_返修_操作人"]]) + + mlogbd2_qs = MlogbDefect.objects.filter(mlogb__in=mlogb2_qs, count__gt=0).values("defect__name").annotate(total=Sum("count")) + + for item in mlogbd2_qs: + data[f"外观检验_返修_缺陷_{item['defect__name']}"] = item["total"] + data[f"外观检验_返修_缺陷_{item['defect__name']}-比例"] = round((item["total"] / data["外观检验_返修-count_real"])*100, 2) + + if "外观检验_count_ok" in data: + data["外观检验_总合格数"] = data["外观检验_count_ok"] + data["外观检验_返修_count_ok"] if "外观检验_返修_count_ok" in data else 0 + try: + data["外观检验_总合格率"] = round((data["外观检验_总合格数"] / data["外观检验_count_real"])*100, 2) + except decimal.InvalidOperation: + data["外观检验_总合格率"] = 0 + + try: + data["外观检验_直通合格率"] = round((data["外观检验_总合格率"]* data["尺寸检验_合格率"])/100, 2) + except decimal.InvalidOperation: + data["外观检验_直通合格率"] = 0 + + return data, {} if __name__ == '__main__': pass \ No newline at end of file From c744c07326b338c8d2674e49fd60aecf5f23c14e Mon Sep 17 00:00:00 2001 From: caoqianming Date: Mon, 12 May 2025 08:25:23 +0800 Subject: [PATCH 20/20] release: 2.6.2025051208 --- changelog.md | 5 +++++ server/settings.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index b175d2cf..185badce 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,8 @@ +## 2.6.2025051208 +- feat: 新增功能 + - 光芯质检表格 [caoqianming] + - base 短信发送功能启动抛出异常 [caoqianming] + - batchst字段同步数据库 [caoqianming] ## 2.6.2025050816 - feat: 新增功能 - batchst添加字段并更新光子的统计 [caoqianming] diff --git a/server/settings.py b/server/settings.py index f234f979..119c1962 100755 --- a/server/settings.py +++ b/server/settings.py @@ -35,7 +35,7 @@ sys.path.insert(0, os.path.join(BASE_DIR, 'apps')) ALLOWED_HOSTS = ['*'] SYS_NAME = '星途工厂综合管理系统' -SYS_VERSION = '2.6.2025050816' +SYS_VERSION = '2.6.2025051208' X_FRAME_OPTIONS = 'SAMEORIGIN' # Application definition