From de94a564163c3c1cec4d8152026f8bc7cf0ffba1 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Wed, 17 Nov 2021 15:45:24 +0800 Subject: [PATCH 01/39] =?UTF-8?q?=E5=88=9B=E5=BB=BA=E7=94=9F=E4=BA=A7?= =?UTF-8?q?=E8=AE=A1=E5=88=92=E6=97=A0=E9=9C=80=E5=A1=AB=E5=86=99=E7=BC=96?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/pm/serializers.py | 2 +- hb_server/apps/wpm/serializers.py | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/hb_server/apps/pm/serializers.py b/hb_server/apps/pm/serializers.py index 735b0cc..90ff400 100644 --- a/hb_server/apps/pm/serializers.py +++ b/hb_server/apps/pm/serializers.py @@ -8,7 +8,7 @@ from apps.system.serializers import OrganizationSimpleSerializer class ProductionPlanCreateFromOrderSerializer(serializers.ModelSerializer): class Meta: model = ProductionPlan - fields = ['order', 'number', 'count', 'start_date', 'end_date'] + fields = ['order', 'count', 'start_date', 'end_date'] class ProductionPlanSerializer(serializers.ModelSerializer): order_ = OrderSerializer(source='order', read_only=True) diff --git a/hb_server/apps/wpm/serializers.py b/hb_server/apps/wpm/serializers.py index c5bae06..80e8c8c 100644 --- a/hb_server/apps/wpm/serializers.py +++ b/hb_server/apps/wpm/serializers.py @@ -2,7 +2,7 @@ from rest_framework import serializers, exceptions from rest_framework.serializers import ModelSerializer from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, MaterialBatch, WareHouse from apps.inm.signals import update_inm -from apps.mtm.models import Material, RecordForm, Step +from apps.mtm.models import Material, RecordForm, Step, SubprodctionMaterial from apps.mtm.serializers import MaterialSimpleSerializer, StepSimpleSerializer from apps.pm.models import SubProductionPlan, SubProductionProgress @@ -32,10 +32,10 @@ class PickSerializer(serializers.Serializer): def create(self, validated_data): picks = validated_data.pop('picks') sp = validated_data.pop('subproduction_plan') - if sp.state not in [1,2]: + if sp.state not in [1, 2, 3]: raise exceptions.ValidationError('该子计划状态错误') - if sp.is_picked: - raise exceptions.ValidationError('该子计划已领料') + # if sp.is_picked: + # raise exceptions.ValidationError('该子计划已领料') # for i in picks: # try: # instance = MaterialBatch.objects.get(material=i['material'], batch=i['batch']) @@ -82,9 +82,11 @@ class PickSerializer(serializers.Serializer): wm.count = wm.count + i['count'] wm.save() # 更新子计划物料情况 - spp = SubProductionProgress.objects.get(material=i['material'], subproduction_plan=sp, type=1) + spp = SubProductionProgress.objects.get(material=i['material'], subproduction_plan=sp, type=SubprodctionMaterial.SUB_MA_TYPE_IN) spp.count_pick = spp.count_pick + i['count'] spp.save() + if spp.count_pick > spp.count: + raise exceptions.APIException('超过计划需求数') # 更新半成品表 wproducts = WProduct.objects.filter(pk__in=[x.wproduct for x in i['iproducts']]) first_step = Step.objects.get(pk=sp.steps[0].id) From 4e5eead1a8c062f6ab2307af92b61b5ab7bde337 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Wed, 17 Nov 2021 16:38:25 +0800 Subject: [PATCH 02/39] =?UTF-8?q?=E6=93=8D=E4=BD=9C=E6=97=B6=E6=8E=89?= =?UTF-8?q?=E5=87=BA=E5=B7=A5=E5=85=B7=E5=B7=A5=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mtm/migrations/0035_auto_20211117_1637.py | 34 +++++++++++++++++++ hb_server/apps/mtm/models.py | 7 ++-- hb_server/apps/mtm/serializers.py | 4 +-- hb_server/apps/mtm/views.py | 3 +- ...3_alter_subproductionplan_subproduction.py | 20 +++++++++++ hb_server/apps/pm/models.py | 2 +- hb_server/apps/pm/views.py | 4 ++- hb_server/apps/wpm/views.py | 13 +++++-- 8 files changed, 77 insertions(+), 10 deletions(-) create mode 100644 hb_server/apps/mtm/migrations/0035_auto_20211117_1637.py create mode 100644 hb_server/apps/pm/migrations/0013_alter_subproductionplan_subproduction.py diff --git a/hb_server/apps/mtm/migrations/0035_auto_20211117_1637.py b/hb_server/apps/mtm/migrations/0035_auto_20211117_1637.py new file mode 100644 index 0000000..4899c49 --- /dev/null +++ b/hb_server/apps/mtm/migrations/0035_auto_20211117_1637.py @@ -0,0 +1,34 @@ +# Generated by Django 3.2.6 on 2021-11-17 08:37 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('mtm', '0034_auto_20211116_1603'), + ] + + operations = [ + migrations.AddField( + model_name='techdoc', + name='enabled', + field=models.BooleanField(default=True, verbose_name='是否启用'), + ), + migrations.AlterField( + model_name='step', + name='type', + field=models.IntegerField(choices=[(1, '常规'), (2, '分割'), (3, '结合')], default=1, verbose_name='操作类型'), + ), + migrations.AlterField( + model_name='subprodctionmaterial', + name='subproduction', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='subm_subprod', to='mtm.subproduction', verbose_name='关联生产分解'), + ), + migrations.AlterField( + model_name='techdoc', + name='subproduction', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tech_subprod', to='mtm.subproduction', verbose_name='关联生产分解'), + ), + ] diff --git a/hb_server/apps/mtm/models.py b/hb_server/apps/mtm/models.py index 6a92190..46e82b4 100644 --- a/hb_server/apps/mtm/models.py +++ b/hb_server/apps/mtm/models.py @@ -72,7 +72,7 @@ class Step(CommonAModel): STEP_TYPE_DIV = 2 STEP_TYPE_COMB = 3 step_type_choices=( - (STEP_TYPE_NOM, '普通'), + (STEP_TYPE_NOM, '常规'), (STEP_TYPE_DIV, '分割'), (STEP_TYPE_COMB, '结合') ) @@ -199,7 +199,7 @@ class SubprodctionMaterial(CommonADModel): material = models.ForeignKey(Material, verbose_name='物料', on_delete=models.CASCADE, related_name='subplan_material') is_main = models.BooleanField('是否主产出', default=False) # 以该产品完成度计算进度 count = models.FloatField('消耗量/产出量', default=0) - subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE) + subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE, related_name='subm_subprod') type = models.IntegerField('物料应用类型', default=1) sort = models.IntegerField('排序号', default=1) @@ -223,8 +223,9 @@ class TechDoc(CommonADModel): """ name = models.CharField('名称', max_length=50) file = models.ForeignKey(File, verbose_name='技术文件', on_delete=models.CASCADE) - subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE) + subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE, related_name='tech_subprod') content = models.TextField('内容', null=True, blank=True) + enabled = models.BooleanField('是否启用', default=True) class Meta: verbose_name = '技术文件' diff --git a/hb_server/apps/mtm/serializers.py b/hb_server/apps/mtm/serializers.py index b07ccb7..3e7a46d 100644 --- a/hb_server/apps/mtm/serializers.py +++ b/hb_server/apps/mtm/serializers.py @@ -241,9 +241,9 @@ class TechDocListSerializer(serializers.ModelSerializer): class TechDocCreateSerializer(serializers.ModelSerializer): class Meta: model = TechDoc - fields = ['file', 'subproduction', 'name', 'content'] + fields = ['file', 'subproduction', 'name', 'content', 'enabled'] class TechDocUpdateSerializer(serializers.ModelSerializer): class Meta: model = TechDoc - fields = ['file', 'name', 'content'] + fields = ['file', 'name', 'content', 'enabled'] diff --git a/hb_server/apps/mtm/views.py b/hb_server/apps/mtm/views.py index 679f7d2..947ca5d 100644 --- a/hb_server/apps/mtm/views.py +++ b/hb_server/apps/mtm/views.py @@ -153,7 +153,8 @@ class RecordFormViewSet(OptimizationMixin, CreateUpdateModelAMixin, ModelViewSet queryset = RecordForm.objects.all() filterset_fields = ['step', 'type', 'material'] search_fields = ['name'] - ordering='id' + ordering='sort' + ordering_fields = ['sort', 'id'] def get_serializer_class(self): if self.action =='create': diff --git a/hb_server/apps/pm/migrations/0013_alter_subproductionplan_subproduction.py b/hb_server/apps/pm/migrations/0013_alter_subproductionplan_subproduction.py new file mode 100644 index 0000000..7896e13 --- /dev/null +++ b/hb_server/apps/pm/migrations/0013_alter_subproductionplan_subproduction.py @@ -0,0 +1,20 @@ +# Generated by Django 3.2.6 on 2021-11-17 08:37 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('mtm', '0035_auto_20211117_1637'), + ('pm', '0012_alter_subproductionprogress_type'), + ] + + operations = [ + migrations.AlterField( + model_name='subproductionplan', + name='subproduction', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='subplan_subprod', to='mtm.subproduction', verbose_name='关联生产分解'), + ), + ] diff --git a/hb_server/apps/pm/models.py b/hb_server/apps/pm/models.py index ddddd78..b63e1c1 100644 --- a/hb_server/apps/pm/models.py +++ b/hb_server/apps/pm/models.py @@ -40,7 +40,7 @@ class SubProductionPlan(CommonAModel): (4, '已完成') ) production_plan = models.ForeignKey(ProductionPlan, verbose_name='关联主生产计划', on_delete=models.CASCADE) - subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE) + subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE, related_name='subplan_subprod') start_date = models.DateField('计划开工日期') end_date = models.DateField('计划完工日期') diff --git a/hb_server/apps/pm/views.py b/hb_server/apps/pm/views.py index 2128aab..c1999ea 100644 --- a/hb_server/apps/pm/views.py +++ b/hb_server/apps/pm/views.py @@ -1,4 +1,5 @@ from datetime import timezone +from django.db import transaction from rest_framework import serializers from rest_framework.views import APIView from apps.em.models import Equipment @@ -49,7 +50,8 @@ class ProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, CreateModel elif self.action == 'list': return ProductionPlanSerializer return super().get_serializer_class() - + + @transaction.atomic() def create(self, request, *args, **kwargs): data = request.data serializer = self.get_serializer(data=data) diff --git a/hb_server/apps/wpm/views.py b/hb_server/apps/wpm/views.py index 7a5f9c3..a43f942 100644 --- a/hb_server/apps/wpm/views.py +++ b/hb_server/apps/wpm/views.py @@ -7,8 +7,8 @@ from rest_framework.views import APIView from rest_framework.viewsets import GenericViewSet, ModelViewSet from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, WareHouse from apps.inm.signals import update_inm -from apps.mtm.models import Material, RecordForm, Step, SubprodctionMaterial -from apps.mtm.serializers import RecordFormDetailSerializer +from apps.mtm.models import Material, RecordForm, Step, SubprodctionMaterial, TechDoc +from apps.mtm.serializers import RecordFormDetailSerializer, SubprodctionMaterialListSerializer, TechDocListSerializer from apps.pm.models import SubProductionPlan, SubProductionProgress from apps.pm.serializers import SubProductionPlanListSerializer, SubProductionPlanUpdateSerializer from apps.qm.models import TestRecordItem @@ -319,6 +319,15 @@ class DoFormInit(CreateAPIView, GenericAPIView): ret['forms'] = [] ret_0['id'] = 0 ret_0['name'] = '基本信息' + # 查询工具工装 + ret_0['tools'] = SubprodctionMaterialListSerializer(instance= + SubprodctionMaterial.objects.filter(type=SubprodctionMaterial.SUB_MA_TYPE_TOOL, + subproduction__subplan_subprod__in = splans), many=True).data + # 查询技术文档 + ret_0['techdocs'] = TechDocListSerializer(instance = + TechDoc.objects.filter(subproduction__subplan_subprod__in = splans, enabled=True)\ + .distinct(), many=True).data + ret['forms'].append(ret_0) forms = RecordForm.objects.filter(step=vdata['step'], type=RecordForm.RF_TYPE_DO) if forms.exists(): From b0e213aae9130229cec3f532396e411c095b74c8 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Wed, 17 Nov 2021 16:46:12 +0800 Subject: [PATCH 03/39] =?UTF-8?q?=E8=A1=A8=E6=A0=BC=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/mtm/views.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/hb_server/apps/mtm/views.py b/hb_server/apps/mtm/views.py index 947ca5d..847e1dc 100644 --- a/hb_server/apps/mtm/views.py +++ b/hb_server/apps/mtm/views.py @@ -153,8 +153,8 @@ class RecordFormViewSet(OptimizationMixin, CreateUpdateModelAMixin, ModelViewSet queryset = RecordForm.objects.all() filterset_fields = ['step', 'type', 'material'] search_fields = ['name'] - ordering='sort' - ordering_fields = ['sort', 'id'] + ordering='id' + def get_serializer_class(self): if self.action =='create': @@ -185,6 +185,8 @@ class RecordFormFieldViewSet(OptimizationMixin, CreateUpdateModelAMixin, ModelVi queryset = RecordFormField.objects.all() filterset_fields = ['field_type', 'form'] search_fields = ['field_name', 'field_key'] + ordering = 'id' + ordering_fields = ['sort', 'id'] def get_serializer_class(self): if self.action =='create': From 4d7584940556e637e7fa1d8a06d703cc429c4099 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Wed, 17 Nov 2021 17:04:08 +0800 Subject: [PATCH 04/39] =?UTF-8?q?=E5=8D=8A=E6=88=90=E5=93=81=E9=A2=86?= =?UTF-8?q?=E6=96=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/wpm/serializers.py | 1 + 1 file changed, 1 insertion(+) diff --git a/hb_server/apps/wpm/serializers.py b/hb_server/apps/wpm/serializers.py index 80e8c8c..726de39 100644 --- a/hb_server/apps/wpm/serializers.py +++ b/hb_server/apps/wpm/serializers.py @@ -55,6 +55,7 @@ class PickSerializer(serializers.Serializer): i['count'] = len(i['iproducts']) isLowLevel = True if i['count']>0: + i.pop('iproducts') i['fifo'] = fifo i['is_testok'] = True # 默认检测合格 i['subproduction_plan'] = sp From 3fbede05f7cbcb1f4879d6af6f23975212c0a0ff Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 18 Nov 2021 08:25:02 +0800 Subject: [PATCH 05/39] =?UTF-8?q?=E8=A1=A8=E5=AD=97=E6=AE=B5=E6=94=B9?= =?UTF-8?q?=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_client/.env.development | 4 +- hb_client/src/views/wpm/need.vue | 10 ++-- hb_client/src/views/wpm/worktask.vue | 8 +-- .../0018_alter_fifoitem_subproduction_plan.py | 20 +++++++ hb_server/apps/inm/models.py | 2 +- hb_server/apps/pm/signals.py | 2 +- ...0010_rename_m_state_testrecord_material.py | 18 +++++++ hb_server/apps/qm/models.py | 2 +- .../wpm/migrations/0014_auto_20211117_2254.py | 53 +++++++++++++++++++ .../wpm/migrations/0015_auto_20211117_2332.py | 38 +++++++++++++ hb_server/apps/wpm/models.py | 23 +++++--- hb_server/apps/wpm/serializers.py | 16 +++--- hb_server/apps/wpm/views.py | 52 +++++++++++------- 13 files changed, 200 insertions(+), 48 deletions(-) create mode 100644 hb_server/apps/inm/migrations/0018_alter_fifoitem_subproduction_plan.py create mode 100644 hb_server/apps/qm/migrations/0010_rename_m_state_testrecord_material.py create mode 100644 hb_server/apps/wpm/migrations/0014_auto_20211117_2254.py create mode 100644 hb_server/apps/wpm/migrations/0015_auto_20211117_2332.py diff --git a/hb_client/.env.development b/hb_client/.env.development index 003a43c..ef83e12 100644 --- a/hb_client/.env.development +++ b/hb_client/.env.development @@ -2,8 +2,8 @@ ENV = 'development' # base api -#VUE_APP_BASE_API = 'http://127.0.0.1:8000/api' -VUE_APP_BASE_API = 'http://47.95.0.242:2222/api' +VUE_APP_BASE_API = 'http://127.0.0.1:8000/api' +#VUE_APP_BASE_API = 'http://47.95.0.242:2222/api' # vue-cli uses the VUE_CLI_BABEL_TRANSPILE_MODULES environment variable, diff --git a/hb_client/src/views/wpm/need.vue b/hb_client/src/views/wpm/need.vue index d49842f..756ad66 100644 --- a/hb_client/src/views/wpm/need.vue +++ b/hb_client/src/views/wpm/need.vue @@ -14,7 +14,7 @@ > - + @@ -27,7 +27,7 @@ - + @@ -62,7 +62,7 @@ > - + @@ -75,7 +75,7 @@ - + @@ -389,7 +389,7 @@ export default { //调该物料对应的检查表 this.outerVisible = true; this.wproduct=scope.row.id;//半成品ID - this.listQueryrecordform.material = scope.row.m_state;// + this.listQueryrecordform.material = scope.row.material;// this.listQueryrecordform.type = 2; getrecordformList(this.listQueryrecordform).then((response) => { if (response.data) { diff --git a/hb_client/src/views/wpm/worktask.vue b/hb_client/src/views/wpm/worktask.vue index 5e6a15d..bacb304 100644 --- a/hb_client/src/views/wpm/worktask.vue +++ b/hb_client/src/views/wpm/worktask.vue @@ -132,13 +132,13 @@ @@ -719,7 +719,7 @@ export default { this.listLoading = false; }); //半成品 - getwproductList({page:0,p_state__process:this.process}).then((response) => { + getwproductList({page:0,step__process:this.process}).then((response) => { if (response.data) { this.wproductData = response.data; //console.log( this.wproductData) @@ -731,7 +731,7 @@ export default { //大工序下子工序产出的半成品 getwproductLists() { this.wproductdata.page = 0; - this.wproductdata.p_state__process = this.process; + this.wproductdata.step__process = this.process; if (this.subproduction_plan != "") { this.wproductdata.subproduction_plan = this.subproduction_plan; } diff --git a/hb_server/apps/inm/migrations/0018_alter_fifoitem_subproduction_plan.py b/hb_server/apps/inm/migrations/0018_alter_fifoitem_subproduction_plan.py new file mode 100644 index 0000000..c188322 --- /dev/null +++ b/hb_server/apps/inm/migrations/0018_alter_fifoitem_subproduction_plan.py @@ -0,0 +1,20 @@ +# Generated by Django 3.2.6 on 2021-11-17 15:06 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('pm', '0013_alter_subproductionplan_subproduction'), + ('inm', '0017_alter_iproduct_number'), + ] + + operations = [ + migrations.AlterField( + model_name='fifoitem', + name='subproduction_plan', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='pm.subproductionplan', verbose_name='关联子生产计划'), + ), + ] diff --git a/hb_server/apps/inm/models.py b/hb_server/apps/inm/models.py index 57e3e17..dbd87cf 100644 --- a/hb_server/apps/inm/models.py +++ b/hb_server/apps/inm/models.py @@ -82,7 +82,7 @@ class FIFOItem(BaseModel): count = models.IntegerField('数量', default=0, validators=[MinValueValidator(0)]) batch = models.CharField('批次号', max_length=100, default='') fifo = models.ForeignKey(FIFO, verbose_name='关联出入库', on_delete=models.CASCADE) - subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.DO_NOTHING, null=True, blank=True) + subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.CASCADE, null=True, blank=True) class FIFOItemProduct(BaseModel): """ diff --git a/hb_server/apps/pm/signals.py b/hb_server/apps/pm/signals.py index b07a67c..49874bd 100644 --- a/hb_server/apps/pm/signals.py +++ b/hb_server/apps/pm/signals.py @@ -13,7 +13,7 @@ def update_subplan_main(sender, instance, created, **kwargs): subplan.main_product = instance.material subplan.main_count = instance.count subplan.main_count_real = instance.count_real - if subplan.main_count >= instance.count_real: + if instance.count_real>= instance.count: subplan.state = 4 subplan.save() diff --git a/hb_server/apps/qm/migrations/0010_rename_m_state_testrecord_material.py b/hb_server/apps/qm/migrations/0010_rename_m_state_testrecord_material.py new file mode 100644 index 0000000..01705a4 --- /dev/null +++ b/hb_server/apps/qm/migrations/0010_rename_m_state_testrecord_material.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.6 on 2021-11-17 15:32 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('qm', '0009_alter_testrecorditem_is_testok'), + ] + + operations = [ + migrations.RenameField( + model_name='testrecord', + old_name='m_state', + new_name='material', + ), + ] diff --git a/hb_server/apps/qm/models.py b/hb_server/apps/qm/models.py index 0cc9d5d..fb61f53 100644 --- a/hb_server/apps/qm/models.py +++ b/hb_server/apps/qm/models.py @@ -50,7 +50,7 @@ class TestRecord(CommonAModel): form = models.ForeignKey('mtm.recordform', verbose_name='所用表格', on_delete=models.CASCADE) is_testok = models.BooleanField('是否合格', default=True) wproduct = models.ForeignKey('wpm.wproduct', verbose_name='关联的动态产品', on_delete=models.CASCADE, null=True, blank=True) - m_state = models.ForeignKey('mtm.material', verbose_name='关联的物料状态', on_delete=models.CASCADE, null=True, blank=True) + material = models.ForeignKey('mtm.material', verbose_name='关联的物料状态', on_delete=models.CASCADE, null=True, blank=True) fifo_item = models.ForeignKey('inm.fifoitem', verbose_name='关联的出入库批次', on_delete=models.CASCADE, null=True, blank=True) remark = models.TextField('备注', default='') diff --git a/hb_server/apps/wpm/migrations/0014_auto_20211117_2254.py b/hb_server/apps/wpm/migrations/0014_auto_20211117_2254.py new file mode 100644 index 0000000..93c87c1 --- /dev/null +++ b/hb_server/apps/wpm/migrations/0014_auto_20211117_2254.py @@ -0,0 +1,53 @@ +# Generated by Django 3.2.6 on 2021-11-17 14:54 + +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('mtm', '0035_auto_20211117_1637'), + ('pm', '0013_alter_subproductionplan_subproduction'), + ('wpm', '0013_auto_20211116_0841'), + ] + + operations = [ + migrations.RenameField( + model_name='operation', + old_name='p_state', + new_name='step', + ), + migrations.RemoveField( + model_name='operation', + name='m_state', + ), + migrations.RemoveField( + model_name='operation', + name='wproducts', + ), + migrations.CreateModel( + name='OperationWproduct', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')), + ('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')), + ('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')), + ('number', models.CharField(blank=True, max_length=50, null=True, verbose_name='物品编号')), + ('material', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='操作时的物料状态')), + ('operation', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='wpm.operation', verbose_name='关联操作')), + ('production_plan', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pm.productionplan', verbose_name='当前主生产计划')), + ('subproduction_plan', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pm.subproductionplan', verbose_name='当前子生产计划')), + ('wproduct', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='wpm.wproduct', verbose_name='关联半成品')), + ], + options={ + 'abstract': False, + }, + ), + migrations.AddField( + model_name='operation', + name='wproducts', + field=models.ManyToManyField(through='wpm.OperationWproduct', to='wpm.WProduct', verbose_name='关联半成品'), + ), + ] diff --git a/hb_server/apps/wpm/migrations/0015_auto_20211117_2332.py b/hb_server/apps/wpm/migrations/0015_auto_20211117_2332.py new file mode 100644 index 0000000..42c40a1 --- /dev/null +++ b/hb_server/apps/wpm/migrations/0015_auto_20211117_2332.py @@ -0,0 +1,38 @@ +# Generated by Django 3.2.6 on 2021-11-17 15:32 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('mtm', '0035_auto_20211117_1637'), + ('wpm', '0014_auto_20211117_2254'), + ] + + operations = [ + migrations.RenameField( + model_name='wproduct', + old_name='m_state', + new_name='material', + ), + migrations.RemoveField( + model_name='wproduct', + name='p_state', + ), + migrations.RemoveField( + model_name='wproduct', + name='pre_pstate', + ), + migrations.AddField( + model_name='wproduct', + name='pre_step', + field=models.ForeignKey(blank=True, help_text='已执行完的步骤', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='w_pre_step', to='mtm.step', verbose_name='已执行到'), + ), + migrations.AddField( + model_name='wproduct', + name='step', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='w_step', to='mtm.step', verbose_name='所在步骤'), + ), + ] diff --git a/hb_server/apps/wpm/models.py b/hb_server/apps/wpm/models.py index 7424783..8ec6790 100644 --- a/hb_server/apps/wpm/models.py +++ b/hb_server/apps/wpm/models.py @@ -33,9 +33,9 @@ class WProduct(CommonAModel): (WPR_ACT_STATE_INM, '库存中'), ) number = models.CharField('物品编号', unique=True, null=True, blank=True, max_length=50) - m_state = models.ForeignKey(Material, verbose_name='所属物料状态', on_delete=models.CASCADE) - pre_pstate = models.ForeignKey(Step, verbose_name='已执行到', help_text='已执行完的步骤', null=True, blank=True, on_delete=models.CASCADE, related_name='w_pre_pstate') - p_state = models.ForeignKey(Step, verbose_name='所在步骤', on_delete=models.CASCADE, null=True, blank=True, related_name='w_ptate') + material = models.ForeignKey(Material, verbose_name='所属物料状态', on_delete=models.CASCADE) + pre_step = models.ForeignKey(Step, verbose_name='已执行到', help_text='已执行完的步骤', null=True, blank=True, on_delete=models.CASCADE, related_name='w_pre_step') + step = models.ForeignKey(Step, verbose_name='所在步骤', on_delete=models.CASCADE, null=True, blank=True, related_name='w_step') act_state = models.IntegerField('进行状态', default=0, choices=act_state_choices) is_executed = models.BooleanField('子工序是否已执行', default=False) is_hidden = models.BooleanField('是否隐藏', default=False) @@ -49,12 +49,23 @@ class Operation(CommonAModel): """ 生产操作 """ - wproducts = models.JSONField('关联产品ID列表', default=list, blank=True) - m_state = models.ForeignKey(Material, verbose_name='操作时的物料状态', on_delete=models.CASCADE, null=True, blank=True) - p_state = models.ForeignKey(Step, verbose_name='操作步骤', on_delete=models.CASCADE, null=True, blank=True) + wproducts = models.ManyToManyField(WProduct, verbose_name='关联半成品', through='wpm.operationwproduct') + step = models.ForeignKey(Step, verbose_name='操作步骤', on_delete=models.CASCADE, null=True, blank=True) use_scrap = models.BooleanField('是否使用的边角料', default=False) remark = models.CharField('操作备注', max_length=200, null=True, blank=True) +class OperationWproduct(BaseModel): + """ + 生产操作半成品关联表 + """ + operation = models.ForeignKey(Operation, verbose_name='关联操作', on_delete=models.CASCADE) + wproduct = models.ForeignKey(WProduct, verbose_name='关联半成品', on_delete=models.CASCADE) + number = models.CharField('物品编号', null=True, blank=True, max_length=50) + material = models.ForeignKey(Material, verbose_name='操作时的物料状态', on_delete=models.CASCADE) + subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE) + production_plan = models.ForeignKey(ProductionPlan, verbose_name='当前主生产计划', on_delete=models.CASCADE) + + class OperationMaterial(BaseModel): """ 生产操作物料消耗产出表 diff --git a/hb_server/apps/wpm/serializers.py b/hb_server/apps/wpm/serializers.py index 726de39..31dbea7 100644 --- a/hb_server/apps/wpm/serializers.py +++ b/hb_server/apps/wpm/serializers.py @@ -91,7 +91,7 @@ class PickSerializer(serializers.Serializer): # 更新半成品表 wproducts = WProduct.objects.filter(pk__in=[x.wproduct for x in i['iproducts']]) first_step = Step.objects.get(pk=sp.steps[0].id) - wproducts.update(p_state=first_step, is_executed=False, + wproducts.update(step=first_step, is_executed=False, act_state=WProduct.WPR_ACT_STATE_DOING, is_hidden=False, warehouse=None, subproduction_plan=sp, production_plan=sp.production_plan) sp.is_picked=True @@ -117,8 +117,8 @@ class WProductListSerializer(serializers.ModelSerializer): """ 半成品列表 """ - m_state_ = MaterialSimpleSerializer(source='m_state', read_only=True) - p_state_ = StepSimpleSerializer(source='p_state', read_only=True) + material_ = MaterialSimpleSerializer(source='material', read_only=True) + step_ = StepSimpleSerializer(source='step', read_only=True) class Meta: model = WProduct fields = '__all__' @@ -126,8 +126,8 @@ class WProductListSerializer(serializers.ModelSerializer): class OperationDetailSerializer(serializers.ModelSerializer): wproducts_ = serializers.SerializerMethodField() create_by_ = UserSimpleSerializer(source='create_by', read_only=True) - m_state_ = MaterialSimpleSerializer(source='m_state', read_only=True) - p_state_ = StepSimpleSerializer(source='p_state', read_only=True) + material_ = MaterialSimpleSerializer(source='material', read_only=True) + step_ = StepSimpleSerializer(source='step', read_only=True) class Meta: model = Operation fields = '__all__' @@ -137,8 +137,8 @@ class OperationDetailSerializer(serializers.ModelSerializer): class OperationListSerializer(serializers.ModelSerializer): create_by_ = UserSimpleSerializer(source='create_by', read_only=True) - m_state_ = MaterialSimpleSerializer(source='m_state', read_only=True) - p_state_ = StepSimpleSerializer(source='p_state', read_only=True) + material_ = MaterialSimpleSerializer(source='material', read_only=True) + step_ = StepSimpleSerializer(source='step', read_only=True) class Meta: model = Operation fields = '__all__' @@ -166,7 +166,7 @@ class OperationInitSerializer(serializers.Serializer): raise exceptions.ValidationError('不可进行操作') # if i.subproduction_plan != subproduction_plan: # raise exceptions.ValidationError('半成品所属子计划不一致') - if i.p_state != step: + if i.step != step: raise exceptions.ValidationError('半成品所属子工序不一致') else: if step.type != Step.STEP_TYPE_DIV: diff --git a/hb_server/apps/wpm/views.py b/hb_server/apps/wpm/views.py index a43f942..1ff9c5d 100644 --- a/hb_server/apps/wpm/views.py +++ b/hb_server/apps/wpm/views.py @@ -15,7 +15,7 @@ from apps.qm.models import TestRecordItem from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin from rest_framework.decorators import action -from apps.wpm.models import WMaterial, WProduct, Operation, OperationMaterial, OperationRecord, OperationRecordItem +from apps.wpm.models import OperationWproduct, WMaterial, WProduct, Operation, OperationMaterial, OperationRecord, OperationRecordItem from apps.wpm.serializers import OperationDetailSerializer, OperationListSerializer, PickHalfSerializer, PickSerializer, OperationInitSerializer, OperationSubmitSerializer, WMaterialListSerializer, WProductListSerializer, WplanPutInSerializer, WpmTestRecordCreateSerializer, WproductPutInSerializer from rest_framework.response import Response @@ -51,7 +51,7 @@ class WPlanViewSet(ListModelMixin, GenericViewSet): """ mIds = SubProductionProgress.objects.filter(type=SubprodctionMaterial.SUB_MA_TYPE_IN, material__type=Material.MA_TYPE_HALFGOOD).values_list('material', flat=True) - queyset = WProduct.objects.filter(is_hidden=False, m_state__in=mIds, act_state=WProduct.WPR_ACT_STATE_OK) + queyset = WProduct.objects.filter(is_hidden=False, material__in=mIds, act_state=WProduct.WPR_ACT_STATE_OK) return Response(WProductListSerializer(instance=queyset, many=True).data) elif request.method=='POST': serializer= PickHalfSerializer(data=request.data) @@ -59,7 +59,7 @@ class WPlanViewSet(ListModelMixin, GenericViewSet): vdata = serializer.data wps = WProduct.objects.filter(pk__in=[x for x in vdata['wproducts']]) first_step = Step.objects.get(pk=sp.steps[0].id) - wps.update(p_state=first_step, is_executed=False, + wps.update(step=first_step, is_executed=False, act_state=WProduct.WPR_ACT_STATE_DOING, is_hidden=False, warehouse=None, subproduction_plan=sp, production_plan=sp.production_plan) return Response() @@ -79,7 +79,7 @@ class WPlanViewSet(ListModelMixin, GenericViewSet): batch = subplan.production_plan.number warehouse = WareHouse.objects.get(id=vdata['warehouse']) wproducts = WProduct.objects.filter(subproduction_plan=subplan, - act_state=WProduct.WPR_ACT_STATE_OK, m_state=material, is_deleted=False) + act_state=WProduct.WPR_ACT_STATE_OK, material=material, is_deleted=False) if wproducts.exists(): # 创建入库记录 remark = vdata.get('remark', '') @@ -150,9 +150,9 @@ class WProductViewSet(ListModelMixin, GenericViewSet): 半成品 """ perms_map={'*':'*'} - queryset = WProduct.objects.select_related('p_state', 'm_state').filter(is_hidden=False) + queryset = WProduct.objects.select_related('step', 'material').filter(is_hidden=False) serializer_class = WProductListSerializer - filterset_fields = ['p_state', 'subproduction_plan', 'm_state', 'production_plan', 'p_state__process', 'act_state'] + filterset_fields = ['step', 'subproduction_plan', 'material', 'production_plan', 'step__process', 'act_state'] search_fields = ['number'] ordering_fields = ['id'] ordering = ['id'] @@ -173,7 +173,7 @@ class WProductViewSet(ListModelMixin, GenericViewSet): if 'is_testok' not in vdata: raise exceptions.APIException('未填写检测结论') - obj = serializer.save(create_by = self.request.user, m_state=wproduct.m_state) + obj = serializer.save(create_by = self.request.user, material=wproduct.material) tris = [] for m in record_data: # 保存记录详情 form_field = m['form_field'] @@ -219,7 +219,7 @@ class WProductViewSet(ListModelMixin, GenericViewSet): warehouse = WareHouse.objects.get(id=vdata['warehouse']) if wproduct.act_state != WProduct.WPR_ACT_STATE_OK: raise exceptions.APIException('半成品不可入库') - material = wproduct.m_state + material = wproduct.material batch = wproduct.production_plan.number # 创建入库记录 remark = vdata.get('remark', '') @@ -258,9 +258,9 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet): 生产操作记录 """ perms_map={'*':'*'} - queryset = Operation.objects.select_related('p_state', 'm_state').all() + queryset = Operation.objects.select_related('step', 'material').all() serializer_class = OperationListSerializer - filterset_fields = ['p_state', 'm_state'] + filterset_fields = ['step', 'step__process'] ordering_fields = ['id'] ordering = ['-id'] @@ -351,14 +351,26 @@ class DoFormSubmit(CreateAPIView, GenericAPIView): # 创建一个生产操作记录 action_obj = Operation() - action_obj.p_state = vdata['step'] - if 'wproducts' in data and data['wproducts']: - action_obj.wproducts = data['wproducts'] - action_obj.m_state = vdata['wproducts'][0].m_state + action_obj.step = vdata['step'] action_obj.remark = vdata.get('remark', '') # 操作备注 action_obj.create_by = request.user action_obj.use_scrap = vdata.get('use_scrap', False) action_obj.save() + + # 保存关联半成品 + if 'wproducts' in data and data['wproducts']: + owps = [] + for i in data['wproducts']: + owp = {} + owp['operation'] = action_obj + wp = WProduct.objects.get(pk=i) + owp['wproduct'] = wp + owp['number'] = wp.number + owp['material'] = wp.material + owp['subproduction_plan'] = wp.subproduction_plan + owp['production_plan'] = wp.production_plan + owps.append(OperationWproduct(**owp)) + OperationWproduct.objects.bulk_create(owps) # 保存物料消耗 for i in vdata['input']: @@ -384,7 +396,7 @@ class DoFormSubmit(CreateAPIView, GenericAPIView): # 获取下一步子工序 if vdata['step'].type == Step.STEP_TYPE_DIV: newstep, _ = WpmServies.get_next_step(i['subproduction_plan'], vdata['step']) - wpr = dict(m_state=ma, p_state=newstep, + wpr = dict(material=ma, step=newstep, act_state=WProduct.WPR_ACT_STATE_DOING, is_executed=False, remark='', subproduction_plan=i['subproduction_plan'], production_plan=i['subproduction_plan'].production_plan) @@ -413,8 +425,8 @@ class DoFormSubmit(CreateAPIView, GenericAPIView): wproducts.update(is_hidden=True) # 隐藏 newstep, hasNext = WpmServies.get_next_step(i['subproduction_plan'], vdata['step']) wproduct = WProduct() - wproduct.m_state = vdata['subproduction_plan'].main_product - wproduct.p_state = newstep + wproduct.material = vdata['subproduction_plan'].main_product + wproduct.step = newstep wproduct.subproduction_plan=vdata['subproduction_plan'] wproduct.production_plan=vdata['subproduction_plan'].production_plan wproduct.parent = data['wproducts'] @@ -431,14 +443,14 @@ class DoFormSubmit(CreateAPIView, GenericAPIView): for wproduct in vdata['wproducts']: # 获取下一步子工序 newstep, hasNext = WpmServies.get_next_step(i['subproduction_plan'], vdata['step']) - wproduct.p_state = newstep - wproduct.pre_pstate=vdata['step'] + wproduct.step = newstep + wproduct.pre_step=vdata['step'] if hasNext: wproduct.is_executed= False else: wproduct.is_executed= True wproduct.act_state=WProduct.WPR_ACT_STATE_TOTEST - wproduct.m_state=wproduct.subproduction_plan.main_product + wproduct.material=wproduct.subproduction_plan.main_product wproduct.save() # 保存自定义表单结果 From fde8a6053954f82dc8c4420456dd885dce9a4ff3 Mon Sep 17 00:00:00 2001 From: shilixia <2309368887@qq.com> Date: Thu, 18 Nov 2021 08:27:33 +0800 Subject: [PATCH 06/39] xial --- hb_client/src/views/pm/plan.vue | 4 +-- hb_client/src/views/wpm/worktask.vue | 38 ++++++++++++++++++++-------- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/hb_client/src/views/pm/plan.vue b/hb_client/src/views/pm/plan.vue index 7fb0a6f..5aed59b 100644 --- a/hb_client/src/views/pm/plan.vue +++ b/hb_client/src/views/pm/plan.vue @@ -167,9 +167,7 @@ label-position="right" :rules="rule1" > - - - + diff --git a/hb_client/src/views/wpm/worktask.vue b/hb_client/src/views/wpm/worktask.vue index 5e6a15d..4b6c748 100644 --- a/hb_client/src/views/wpm/worktask.vue +++ b/hb_client/src/views/wpm/worktask.vue @@ -227,8 +227,8 @@ >