From 8c356308406e4213c332a57d1edf965641c424dc Mon Sep 17 00:00:00 2001 From: caoqianming Date: Sat, 29 Jan 2022 15:25:17 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E5=B7=A5=E5=BA=8F=E4=B8=AD=E6=A3=80?= =?UTF-8?q?=E9=AA=8C=E5=9F=BA=E6=9C=AC=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/develop/views.py | 6 +- .../mtm/migrations/0045_usedstep_need_test.py | 18 ++ hb_server/apps/mtm/models.py | 1 + hb_server/apps/pm/filters.py | 6 +- hb_server/apps/pm/views.py | 3 +- .../qm/migrations/0023_auto_20220129_1512.py | 36 +++ ...e_is_midtesing_testrecord_is_midtesting.py | 18 ++ hb_server/apps/qm/models.py | 3 +- hb_server/apps/qm/serializers.py | 6 +- hb_server/apps/qm/views.py | 12 +- hb_server/apps/wpm/filters.py | 6 +- .../wpm/migrations/0053_auto_20220129_1512.py | 65 ++++ hb_server/apps/wpm/models.py | 24 +- hb_server/apps/wpm/services.py | 18 +- hb_server/apps/wpm/signals.py | 8 +- hb_server/apps/wpm/urls.py | 4 +- hb_server/apps/wpm/views.py | 298 ++++-------------- 17 files changed, 247 insertions(+), 285 deletions(-) create mode 100644 hb_server/apps/mtm/migrations/0045_usedstep_need_test.py create mode 100644 hb_server/apps/qm/migrations/0023_auto_20220129_1512.py create mode 100644 hb_server/apps/qm/migrations/0024_rename_is_midtesing_testrecord_is_midtesting.py create mode 100644 hb_server/apps/wpm/migrations/0053_auto_20220129_1512.py diff --git a/hb_server/apps/develop/views.py b/hb_server/apps/develop/views.py index 1e84384..2412742 100644 --- a/hb_server/apps/develop/views.py +++ b/hb_server/apps/develop/views.py @@ -10,7 +10,7 @@ from apps.pm.models import ProductionPlan, SubProductionPlan from apps.sam.models import Order from apps.wf.models import Ticket from apps.wpm.models import Operation, OperationMaterial, WProduct, WproductFlow -from apps.wpm.services import WpmServies +from apps.wpm.services import WpmService from apps.em.tasks import update_equip_state_by_next_check_date # Create your views here. @@ -46,7 +46,7 @@ class UpdateCuttingView(APIView): i.coperation = op i.save() WproductFlow.objects.filter(wproduct=i).update(coperation=op) - WpmServies.update_cutting_list_with_operation(op) + WpmService.update_cutting_list_with_operation(op) return Response() from apps.qm.models import TestRecord @@ -90,7 +90,7 @@ class UpdateSpg(APIView): 冷加工重新计算合格率 """ for i in SubProductionPlan.objects.filter(subproduction__process__id=1): - WpmServies.update_subproduction_progress_main(sp=i) + WpmService.update_subproduction_progress_main(sp=i) return Response() diff --git a/hb_server/apps/mtm/migrations/0045_usedstep_need_test.py b/hb_server/apps/mtm/migrations/0045_usedstep_need_test.py new file mode 100644 index 0000000..11b7fff --- /dev/null +++ b/hb_server/apps/mtm/migrations/0045_usedstep_need_test.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.9 on 2022-01-29 07:12 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('mtm', '0044_subproduction_need_combtest'), + ] + + operations = [ + migrations.AddField( + model_name='usedstep', + name='need_test', + field=models.BooleanField(default=False, verbose_name='工序内检验'), + ), + ] diff --git a/hb_server/apps/mtm/models.py b/hb_server/apps/mtm/models.py index 4afb8b5..f8ccc83 100644 --- a/hb_server/apps/mtm/models.py +++ b/hb_server/apps/mtm/models.py @@ -242,6 +242,7 @@ class UsedStep(CommonADModel): 涉及的生产子工序 """ step = models.ForeignKey(Step, verbose_name='子工序', on_delete=models.CASCADE, related_name='usedstep') + need_test = models.BooleanField('工序内检验', default=False) remark = models.TextField('生产备注', null=True, blank=True) subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE, related_name='usedstep_subproduction') diff --git a/hb_server/apps/pm/filters.py b/hb_server/apps/pm/filters.py index aa9c6da..a53c29d 100644 --- a/hb_server/apps/pm/filters.py +++ b/hb_server/apps/pm/filters.py @@ -3,7 +3,7 @@ from apps.mtm.models import Material, Step from apps.pm.models import ProductionPlan, SubProductionProgress from apps.wpm.models import Operation, WProduct from datetime import * -from apps.wpm.services import WpmServies +from apps.wpm.services import WpmService from django.db.models import F from utils.mixins import DynamicFieldsFilterMixin @@ -52,9 +52,9 @@ class SubproductionProgressFilterSet(filters.FilterSet): wproducts = WProduct.objects.filter(ow_wproduct__operation=value) step = operation.step if wproducts.exists(): - subplans = WpmServies.get_subplans_queryset_from_wproducts(wproducts) + subplans = WpmService.get_subplans_queryset_from_wproducts(wproducts) else: - subplans = WpmServies.get_subplans_queyset_from_step(step) + subplans = WpmService.get_subplans_queyset_from_step(step) queryset = queryset.filter(subproduction_plan__in=subplans) if step.type == Step.STEP_TYPE_NOM: queryset = queryset.exclude(material__type__in =[Material.MA_TYPE_HALFGOOD, Material.MA_TYPE_GOOD]) diff --git a/hb_server/apps/pm/views.py b/hb_server/apps/pm/views.py index 0fea0a7..449cb2d 100644 --- a/hb_server/apps/pm/views.py +++ b/hb_server/apps/pm/views.py @@ -89,7 +89,8 @@ class ProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, CreateModel subps = SubProduction.objects.filter(product=production_plan.product).order_by('process__number') for index, i in enumerate(subps): steps = Step.objects.filter(usedstep__subproduction=i, usedstep__subproduction__is_deleted=False, - usedstep__is_deleted=False, is_deleted=False).values('id', 'number', 'name', 'usedstep__remark') + usedstep__is_deleted=False, is_deleted=False + ).values('id', 'number', 'name', 'usedstep__remark', need_test=F('usedstep__need_test')) instance = SubProductionPlan.objects.create(production_plan=production_plan, subproduction=i, start_date=production_plan.start_date, end_date=production_plan.end_date, workshop=i.process.workshop, process=i.process, create_by=request.user, diff --git a/hb_server/apps/qm/migrations/0023_auto_20220129_1512.py b/hb_server/apps/qm/migrations/0023_auto_20220129_1512.py new file mode 100644 index 0000000..912b50e --- /dev/null +++ b/hb_server/apps/qm/migrations/0023_auto_20220129_1512.py @@ -0,0 +1,36 @@ +# Generated by Django 3.2.9 on 2022-01-29 07:12 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('qm', '0022_auto_20211216_1401'), + ] + + operations = [ + migrations.AddField( + model_name='testrecord', + name='is_midtesing', + field=models.BooleanField(default=False, verbose_name='是否子工序检验中'), + ), + migrations.AddField( + model_name='testrecorditem', + name='create_by', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='testrecorditem_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人'), + ), + migrations.AddField( + model_name='testrecorditem', + name='update_by', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='testrecorditem_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人'), + ), + migrations.AlterField( + model_name='testrecord', + name='type', + field=models.PositiveSmallIntegerField(choices=[(20, '工序检验'), (30, '工序复检'), (36, '夹层检验'), (40, '成品检验')], default=20), + ), + ] diff --git a/hb_server/apps/qm/migrations/0024_rename_is_midtesing_testrecord_is_midtesting.py b/hb_server/apps/qm/migrations/0024_rename_is_midtesing_testrecord_is_midtesting.py new file mode 100644 index 0000000..720045d --- /dev/null +++ b/hb_server/apps/qm/migrations/0024_rename_is_midtesing_testrecord_is_midtesting.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.9 on 2022-01-29 07:24 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('qm', '0023_auto_20220129_1512'), + ] + + operations = [ + migrations.RenameField( + model_name='testrecord', + old_name='is_midtesing', + new_name='is_midtesting', + ), + ] diff --git a/hb_server/apps/qm/models.py b/hb_server/apps/qm/models.py index c3db665..db776de 100644 --- a/hb_server/apps/qm/models.py +++ b/hb_server/apps/qm/models.py @@ -47,13 +47,11 @@ class TestRecord(CommonADModel): """ 检验记录 """ - TEST_STEP = 10 TEST_PROCESS = 20 TEST_PROCESS_RE = 30 TEST_COMB = 36 TEST_FINAL = 40 type_choice = ( - (TEST_STEP, '子工序检验'), (TEST_PROCESS, '工序检验'), (TEST_PROCESS_RE, '工序复检'), (TEST_COMB, '夹层检验'), @@ -70,6 +68,7 @@ class TestRecord(CommonADModel): fifo_item = models.ForeignKey('inm.fifoitem', verbose_name='关联的出入库批次', on_delete=models.CASCADE, null=True, blank=True) origin_test = models.ForeignKey('self', verbose_name='原检验记录', on_delete=models.CASCADE, null=True, blank=True) is_submited = models.BooleanField('是否提交', default=False) + is_midtesting = models.BooleanField('是否子工序检验中', default=False) remark = models.TextField('备注', default='') diff --git a/hb_server/apps/qm/serializers.py b/hb_server/apps/qm/serializers.py index ecfc2d3..fd64cd6 100644 --- a/hb_server/apps/qm/serializers.py +++ b/hb_server/apps/qm/serializers.py @@ -135,7 +135,7 @@ class TestRecordUpdateSerializer(serializers.ModelSerializer): if i['field_value'] != tri.field_value: tri.field_value = i['field_value'] tri.update_by = update_by - tri.is_testok = i['is_testok'] - tri.is_hidden = i['is_hidden'] - tri.save() + tri.is_testok = i['is_testok'] + tri.is_hidden = i['is_hidden'] + tri.save() return instance diff --git a/hb_server/apps/qm/views.py b/hb_server/apps/qm/views.py index 247e6d6..7cb1f40 100644 --- a/hb_server/apps/qm/views.py +++ b/hb_server/apps/qm/views.py @@ -12,7 +12,7 @@ from django.db import transaction from rest_framework.decorators import action from apps.wpm.models import WProduct -from apps.wpm.services import WpmServies +from apps.wpm.services import WpmService # Create your views here. class StandardViewSet(CreateUpdateModelAMixin, ModelViewSet): """ @@ -69,7 +69,7 @@ class TestRecordViewSet(ListModelMixin, UpdateModelMixin, RetrieveModelMixin, De def update(self, request, *args, **kwargs): obj = self.get_object() - if obj.is_submited: + if obj.is_submited and obj.is_midtesting is False: raise exceptions.APIException('该记录已提交不可编辑') return super().update(request, *args, **kwargs) @@ -77,20 +77,22 @@ class TestRecordViewSet(ListModelMixin, UpdateModelMixin, RetrieveModelMixin, De obj = self.get_object() if obj.is_submited: raise exceptions.APIException('该记录已提交不可删除') - WpmServies.add_wproduct_flow_log(obj.wproduct, 'test_delete') + WpmService.add_wproduct_flow_log(obj.wproduct, 'test_delete') return super().destroy(request, *args, **kwargs) @action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=TestRecordUpdateSerializer) def submit(self, request, pk=None): obj = self.get_object() + if obj.is_submited and obj.is_midtesting is False: + raise exceptions.APIException('该记录已提交') # 校验是否有未填项目 - if obj.type != TestRecord.TEST_PROCESS_RE: + if obj.type != TestRecord.TEST_PROCESS_RE and obj.is_midtesting is False: if TestRecordItem.objects.filter(field_value__isnull=True, is_hidden=False, test_record=obj).exists(): raise exceptions.APIException('存在未填写项目') with transaction.atomic(): obj.is_submited=True obj.save() - WpmServies.update_wproduct_by_test(obj, request.user) # 这里已经做了日志记录和进度计算 + WpmService.update_wproduct_by_test(obj, request.user) # 这里已经做了日志记录和进度计算 return Response() # def create(self, request, *args, **kwargs): diff --git a/hb_server/apps/wpm/filters.py b/hb_server/apps/wpm/filters.py index 5cfb6ea..2798e98 100644 --- a/hb_server/apps/wpm/filters.py +++ b/hb_server/apps/wpm/filters.py @@ -1,7 +1,7 @@ from django_filters import rest_framework as filters from apps.mtm.models import Material, Step -from apps.wpm.services import WpmServies +from apps.wpm.services import WpmService from utils.mixins import DynamicFieldsFilterMixin from .models import Operation, OperationMaterial, OperationRecord, WMaterial, WProduct @@ -20,10 +20,10 @@ class WMaterialFilterSet(filters.FilterSet): wproducts = WProduct.objects.filter(ow_wproduct__operation=value) step = operation.step if wproducts.exists(): - subplans = WpmServies.get_subplans_queryset_from_wproducts( + subplans = WpmService.get_subplans_queryset_from_wproducts( wproducts) else: - subplans = WpmServies.get_subplans_queyset_from_step(step) + subplans = WpmService.get_subplans_queyset_from_step(step) queryset = queryset.filter(subproduction_plan__in=subplans).exclude( material__type=Material.MA_TYPE_HALFGOOD) return queryset diff --git a/hb_server/apps/wpm/migrations/0053_auto_20220129_1512.py b/hb_server/apps/wpm/migrations/0053_auto_20220129_1512.py new file mode 100644 index 0000000..21d27fe --- /dev/null +++ b/hb_server/apps/wpm/migrations/0053_auto_20220129_1512.py @@ -0,0 +1,65 @@ +# Generated by Django 3.2.9 on 2022-01-29 07:12 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('mtm', '0045_usedstep_need_test'), + ('wpm', '0052_auto_20220125_1116'), + ] + + operations = [ + migrations.AddField( + model_name='wproduct', + name='material_check', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='wp_material_check', to='mtm.material', verbose_name='按物料状态检查'), + ), + migrations.AddField( + model_name='wproductflow', + name='material_check', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='wpf_material_check', to='mtm.material', verbose_name='按物料状态检查'), + ), + migrations.AlterField( + model_name='wproduct', + name='child', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='wp_child', to='wpm.wproduct'), + ), + migrations.AlterField( + model_name='wproduct', + name='material', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='wp_material', to='mtm.material', verbose_name='所属物料状态'), + ), + migrations.AlterField( + model_name='wproduct', + name='pre_step', + field=models.ForeignKey(blank=True, help_text='已执行完的步骤', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='wp_pre_step', to='mtm.step', verbose_name='已执行到'), + ), + migrations.AlterField( + model_name='wproduct', + name='step', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='wp_step', to='mtm.step', verbose_name='所在步骤'), + ), + migrations.AlterField( + model_name='wproductflow', + name='child', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='wpf_child', to='wpm.wproductflow'), + ), + migrations.AlterField( + model_name='wproductflow', + name='material', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='wpf_material', to='mtm.material', verbose_name='所属物料状态'), + ), + migrations.AlterField( + model_name='wproductflow', + name='pre_step', + field=models.ForeignKey(blank=True, help_text='已执行完的步骤', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='wpf_pre_step', to='mtm.step', verbose_name='已执行到'), + ), + migrations.AlterField( + model_name='wproductflow', + name='step', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='wpf_step', to='mtm.step', verbose_name='所在步骤'), + ), + ] diff --git a/hb_server/apps/wpm/models.py b/hb_server/apps/wpm/models.py index 571960e..997e65c 100644 --- a/hb_server/apps/wpm/models.py +++ b/hb_server/apps/wpm/models.py @@ -1,4 +1,5 @@ import re + from rest_framework import exceptions from django.db import models from django.db.models.base import Model @@ -88,16 +89,20 @@ class WProduct(CommonAModel): number = models.CharField( '物品编号', unique=True, null=True, blank=True, max_length=50) material = models.ForeignKey( - Material, verbose_name='所属物料状态', on_delete=models.CASCADE) + Material, verbose_name='所属物料状态', on_delete=models.CASCADE, + related_name='wp_material') + material_check = models.ForeignKey( + Material, verbose_name='按物料状态检查', on_delete=models.CASCADE, + null=True, blank=True, related_name='wp_material_check') pre_step = models.ForeignKey(Step, verbose_name='已执行到', help_text='已执行完的步骤', null=True, blank=True, - on_delete=models.CASCADE, related_name='w_pre_step') + on_delete=models.CASCADE, related_name='wp_pre_step') step = models.ForeignKey(Step, verbose_name='所在步骤', on_delete=models.CASCADE, null=True, blank=True, - related_name='w_step') + related_name='wp_step') act_state = models.IntegerField( '进行状态', default=0, choices=act_state_choices) is_hidden = models.BooleanField('是否隐藏', default=False) child = models.ForeignKey('self', blank=True, null=True, - on_delete=models.CASCADE, related_name='wproduct_child') + on_delete=models.CASCADE, related_name='wp_child') remark = models.CharField('备注', max_length=200, null=True, blank=True) subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE, related_name='wproduct_subplan') @@ -164,16 +169,19 @@ class WproductFlow(CommonAModel): WProduct, on_delete=models.CASCADE, verbose_name='关联产品', null=True, blank=True) number = models.CharField('物品编号', null=True, blank=True, max_length=50) material = models.ForeignKey( - Material, verbose_name='所属物料状态', on_delete=models.CASCADE) + Material, verbose_name='所属物料状态', on_delete=models.CASCADE, related_name='wpf_material') + material_check = models.ForeignKey( + Material, verbose_name='按物料状态检查', on_delete=models.CASCADE, + null=True, blank=True, related_name='wpf_material_check') pre_step = models.ForeignKey(Step, verbose_name='已执行到', help_text='已执行完的步骤', null=True, blank=True, - on_delete=models.CASCADE, related_name='wl_pre_step') + on_delete=models.CASCADE, related_name='wpf_pre_step') step = models.ForeignKey(Step, verbose_name='所在步骤', on_delete=models.CASCADE, null=True, blank=True, - related_name='wl_step') + related_name='wpf_step') act_state = models.IntegerField( '进行状态', default=0, choices=WProduct.act_state_choices) is_hidden = models.BooleanField('是否隐藏', default=False) child = models.ForeignKey('self', blank=True, null=True, - on_delete=models.CASCADE, related_name='wproduct_child') + on_delete=models.CASCADE, related_name='wpf_child') remark = models.CharField('备注', max_length=200, null=True, blank=True) subproduction_plan = models.ForeignKey( SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE) diff --git a/hb_server/apps/wpm/services.py b/hb_server/apps/wpm/services.py index d880f7f..c3ca066 100644 --- a/hb_server/apps/wpm/services.py +++ b/hb_server/apps/wpm/services.py @@ -9,19 +9,21 @@ from apps.system.models import User from apps.wf.models import State, TicketFlow, Transition from apps.wpm.models import Operation, OperationMaterial, WProduct, WproductFlow, WprouctTicket from utils.tools import ranstr -class WpmServies(object): +class WpmService(object): @classmethod def get_next_step(cls, subproduction_plan:SubProductionPlan, nowstep:Step): """ 获取下一步骤 """ - stepIds = [i['id'] for i in subproduction_plan.steps] + steps_list = subproduction_plan.steps + stepIds = [i['id'] for i in steps_list] pindex = stepIds.index(nowstep.id) + need_test = steps_list[pindex].get('need_test', False) if pindex + 1 < len(stepIds): - return Step.objects.get(pk=stepIds[pindex+1]), True + return Step.objects.get(pk=stepIds[pindex+1]), need_test else: - return nowstep, False + return nowstep, need_test @classmethod def get_subplans_queryset_from_wproducts(cls, wproducts:List): @@ -47,9 +49,15 @@ class WpmServies(object): """ is_testok = test.is_testok wproduct = test.wproduct + test_i = None if is_testok: if wproduct.act_state == WProduct.WPR_ACT_STATE_TORETEST: # 复检 wproduct.act_state = WProduct.WPR_ACT_STATE_DOWAIT + + elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOTEST and \ + test.is_midtesing is True: + wproduct.act_state = WProduct.WPR_ACT_STATE_DOWAIT + test_i = test elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOTEST and wproduct.material.type == Material.MA_TYPE_GOOD: # 成品检验 wproduct.act_state = WProduct.WPR_ACT_STATE_TOFINALTEST @@ -97,7 +105,7 @@ class WpmServies(object): wproduct.update_by = user wproduct.update_time = timezone.now() - wproduct.test = None + wproduct.test = test_i wproduct.last_test_result = is_testok wproduct.save() # 添加日志 diff --git a/hb_server/apps/wpm/signals.py b/hb_server/apps/wpm/signals.py index 9b37b54..04455d7 100644 --- a/hb_server/apps/wpm/signals.py +++ b/hb_server/apps/wpm/signals.py @@ -8,7 +8,7 @@ from django.dispatch import receiver from rest_framework import exceptions from apps.wpm.models import WProduct, WproductFlow, WprouctTicket from apps.wpm.models import OperationWproduct -from apps.wpm.services import WpmServies +from apps.wpm.services import WpmService @receiver(post_save, sender=Ticket) @@ -34,7 +34,7 @@ def handleTicket(sender, instance, created, **kwargs): # 工单绑定半成品 wproduct.ticket = instance wproduct.save() - WpmServies.add_wproduct_flow_log(wproduct, 'ticket_create') + WpmService.add_wproduct_flow_log(wproduct, 'ticket_create') elif instance.act_state == Ticket.TICKET_ACT_STATE_FINISH: @@ -77,7 +77,7 @@ def handleTicket(sender, instance, created, **kwargs): wp.save() # 添加日志 - WpmServies.add_wproduct_flow_log(wp, 'ticket_finish') + WpmService.add_wproduct_flow_log(wp, 'ticket_finish') # 更新子计划合格进度 - WpmServies.update_subproduction_progress_main(sp=wp.subproduction_plan) + WpmService.update_subproduction_progress_main(sp=wp.subproduction_plan) diff --git a/hb_server/apps/wpm/urls.py b/hb_server/apps/wpm/urls.py index b617c02..40614fd 100644 --- a/hb_server/apps/wpm/urls.py +++ b/hb_server/apps/wpm/urls.py @@ -3,7 +3,7 @@ from rest_framework import urlpatterns from django.urls import path, include from rest_framework.routers import DefaultRouter -from apps.wpm.views import CuttingListViewSet, DoFormInit, DoFormSubmit, OperationEquipViewSet, OperationMaterialInputViewSet, OperationMaterialOutputViewSet, OperationMaterialToolViewSet, OperationRecordViewSet, OperationViewSet, OperationWproductViewSet, WMaterialViewSet, WPlanViewSet, WProductViewSet, WproductTicketViewSet +from apps.wpm.views import CuttingListViewSet, OperationEquipViewSet, OperationMaterialInputViewSet, OperationMaterialOutputViewSet, OperationMaterialToolViewSet, OperationRecordViewSet, OperationViewSet, OperationWproductViewSet, WMaterialViewSet, WPlanViewSet, WProductViewSet, WproductTicketViewSet router = DefaultRouter() router.register('wmaterial', WMaterialViewSet, basename='wmaterial') @@ -19,8 +19,6 @@ router.register('operation_tool', OperationMaterialToolViewSet, basename='operat router.register('subplan', WPlanViewSet, basename='wplan') router.register('cutting_list', CuttingListViewSet, basename='cutting_list') urlpatterns = [ - path('do/init/', DoFormInit.as_view()), - path('do/submit/', DoFormSubmit.as_view()), path('', include(router.urls)), ] diff --git a/hb_server/apps/wpm/views.py b/hb_server/apps/wpm/views.py index 7696562..cf607ec 100644 --- a/hb_server/apps/wpm/views.py +++ b/hb_server/apps/wpm/views.py @@ -32,7 +32,7 @@ from apps.wpm.serializers import CuttingListSerializer, OperationEquipListSerial from rest_framework.response import Response from django.db import transaction from rest_framework import exceptions, serializers -from apps.wpm.services import WpmServies +from apps.wpm.services import WpmService from django.utils import timezone from rest_framework import status from django.db.models import Count @@ -105,7 +105,7 @@ class WPlanViewSet(ListModelMixin, GenericViewSet): m.update_by = request.user m.update_time = timezone.now() m.save() - WpmServies.add_wproduct_flow_log( + WpmService.add_wproduct_flow_log( instance=m, change_str='pick_half') pw = PickWproduct() pw.pick = pick @@ -151,7 +151,7 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet): perms_map = {'*': '*'} queryset = WProduct.objects.select_related('step', 'material', 'subproduction_plan', 'warehouse', 'subproduction_plan__production_plan__order', - 'to_order').prefetch_related('wproduct_child') + 'to_order').prefetch_related('wp_child') serializer_class = WProductListSerializer filterset_class = WProductFilterSet search_fields = ['number'] @@ -188,7 +188,6 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet): WProduct.WPR_ACT_STATE_TORETEST, WProduct.WPR_ACT_STATE_TOFINALTEST, WProduct.WPR_ACT_STATE_TOCOMBTEST]: raise exceptions.APIException('该产品当前状态不可检验') - savedict = dict( create_by=request.user, wproduct=wproduct, @@ -208,13 +207,16 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet): savedict['type'] = TestRecord.TEST_FINAL elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOCOMBTEST: savedict['type'] = TestRecord.TEST_COMB + elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOTEST and\ + wproduct.step != wproduct.pre_step: # 如果是工序内检验 + savedict['is_midtesting'] = True tr = TestRecord.objects.create(**savedict) # 更新wproduct wproduct.test = tr wproduct.update_by = request.user wproduct.update_time = timezone.now() wproduct.save() - WpmServies.add_wproduct_flow_log(wproduct, 'test_init') + WpmService.add_wproduct_flow_log(wproduct, 'test_init') # 创建检验条目 for i in RecordFormField.objects.filter(form=form, is_deleted=False): tri = TestRecordItem() @@ -224,6 +226,7 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet): tri.create_by = request.user tri.save() return Response(TestRecordDetailSerializer(instance=tr).data) + @action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=WproductPutInsSerializer) @transaction.atomic @@ -281,7 +284,7 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet): i.update_by = request.user i.update_time = timezone.now() i.save() - WpmServies.add_wproduct_flow_log(i, 'putins') + WpmService.add_wproduct_flow_log(i, 'putins') return Response() @action(methods=['post'], detail=True, perms_map={'post': '*'}, serializer_class=WproductPutInSerializer) @@ -328,7 +331,7 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet): wproduct.act_state = WProduct.WPR_ACT_STATE_INM wproduct.warehouse = warehouse wproduct.save() - WpmServies.add_wproduct_flow_log(wproduct, 'putin') + WpmService.add_wproduct_flow_log(wproduct, 'putin') return Response() @action(methods=['post'], detail=True, perms_map={'post': '*'}, serializer_class=ScrapSerializer) @@ -354,9 +357,9 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet): obj.update_by = request.user obj.update_time = timezone.now() obj.save() - WpmServies.add_wproduct_flow_log(obj, 'scrap') + WpmService.add_wproduct_flow_log(obj, 'scrap') if obj.step.process.id == 1: # 如果是冷加工 - WpmServies.update_cutting_list_with_operation(obj.coperation) + WpmService.update_cutting_list_with_operation(obj.coperation) return Response() # @action(methods=['get'], detail=False, perms_map={'get':'*'}) @@ -411,14 +414,14 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet): is_mtestok = request.data.get('is_mtestok') obj.is_mtestok = is_mtestok if is_mtestok: - WpmServies.update_plan_state_by_mtestok( + WpmService.update_plan_state_by_mtestok( obj.subproduction_plan.production_plan) obj.update_by = request.user obj.save() change_str = 'mtest_notok' if is_mtestok: change_str = 'mtest_ok' - WpmServies.add_wproduct_flow_log(instance=obj, change_str=change_str) + WpmService.add_wproduct_flow_log(instance=obj, change_str=change_str) return Response() @action(methods=['get'], detail=True, perms_map={'get': '*'}) @@ -461,7 +464,7 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet): i.need_to_order = True i.update_by = request.user i.save() - WpmServies.add_wproduct_flow_log(i, change_str='need_to_order') + WpmService.add_wproduct_flow_log(i, change_str='need_to_order') return Response() @action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=WproductToOrderSerializer) @@ -486,7 +489,7 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet): i.to_order = order i.update_by = request.user i.save() - WpmServies.add_wproduct_flow_log(i,change_str='to_order') + WpmService.add_wproduct_flow_log(i,change_str='to_order') return Response() class WproductTicketViewSet(ListModelMixin, GenericViewSet): @@ -544,7 +547,7 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd i.act_state = WProduct.WPR_ACT_STATE_DOWAIT i.update_by = request.user i.save() - WpmServies.add_wproduct_flow_log(i, 'operation_delete') + WpmService.add_wproduct_flow_log(i, 'operation_delete') self.perform_destroy(instance) return Response(status=status.HTTP_204_NO_CONTENT) @@ -565,14 +568,14 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd # 创建操作所用半成品关联记录 if 'wproducts' in vdata: owps = [] - splans = WpmServies.get_subplans_queryset_from_wproducts( + splans = WpmService.get_subplans_queryset_from_wproducts( vdata['wproducts']) for wpd in vdata['wproducts']: wpd.operation = op wpd.act_state = WProduct.WPR_ACT_STATE_DOING wpd.update_by = request.user wpd.save() - WpmServies.add_wproduct_flow_log(wpd, 'operation_create') + WpmService.add_wproduct_flow_log(wpd, 'operation_create') owp = {} owp['operation'] = op owp['wproduct'] = wpd @@ -583,7 +586,7 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd owps.append(OperationWproduct(**owp)) OperationWproduct.objects.bulk_create(owps) else: - splans = WpmServies.get_subplans_queryset_from_wproducts( + splans = WpmService.get_subplans_queryset_from_wproducts( vdata['wproducts']) # 查询需要填写的自定义表格 forms = RecordForm.objects.filter( @@ -677,22 +680,30 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd wsp = i.subproduction_plan # 获取下一步子工序 - newstep, hasNext = WpmServies.get_next_step(wsp, step) + newstep, needTest = WpmService.get_next_step(wsp, step) wp.step = newstep wp.pre_step = step - if hasNext: - wp.act_state = WProduct.WPR_ACT_STATE_DOWAIT - else: + + if step == newstep: wp.act_state = WProduct.WPR_ACT_STATE_TOTEST wp.material = wsp.product + if wp.test:# 如果有正在进行的工序中检验 + wp.test.is_midtesting = False + wp.test.save() + else: + wp.act_state = WProduct.WPR_ACT_STATE_DOWAIT + if needTest: + wp.act_state = WProduct.WPR_ACT_STATE_TOTEST + wp.material_check = wsp.product + wp.operation = None wp.update_by = request.user wp.save() - WpmServies.add_wproduct_flow_log(wp, 'operation_submit') + WpmService.add_wproduct_flow_log(wp, 'operation_submit') for i in ows.values('subproduction_plan').distinct(): # 更新进度 - WpmServies.update_subproduction_progress_main(sp=wsp) + WpmService.update_subproduction_progress_main(sp=wsp) elif step.type == Step.STEP_TYPE_DIV: # 更新物料产出情况 @@ -700,7 +711,7 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd raise exceptions.APIException('请选择物料产出') for i in omos: if i.subproduction_progress.is_main: - newstep, _ = WpmServies.get_next_step( + newstep, _ = WpmService.get_next_step( i.subproduction_plan, step) wpr = dict(material=i.material, step=newstep, act_state=WProduct.WPR_ACT_STATE_DOWAIT, remark='', @@ -709,33 +720,40 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd for x in range(i.count): ins = WProduct.objects.create(**wpr) # 添加日志 - WpmServies.add_wproduct_flow_log( + WpmService.add_wproduct_flow_log( ins, 'wproduct_create') # 更新进度 - WpmServies.update_subproduction_progress_main( + WpmService.update_subproduction_progress_main( sp=i.subproduction_plan) elif step.type == Step.STEP_TYPE_COMB: oms_w = omos.filter(subproduction_progress__is_main=True) if len(oms_w) == 1: oms_w = oms_w[0] # 校验单片数量是否正确, 暂时未写 - newstep, hasNext = WpmServies.get_next_step( + newstep, needTest = WpmService.get_next_step( oms_w.subproduction_plan, step) wproduct = WProduct() wproduct.material = oms_w.material wproduct.step = newstep wproduct.subproduction_plan = oms_w.subproduction_plan - if hasNext: - wproduct.act_state = WProduct.WPR_ACT_STATE_DOWAIT - else: + if step == newstep: wproduct.act_state = WProduct.WPR_ACT_STATE_TOTEST - # 更新子计划进度 - WpmServies.update_subproduction_progress_main( - sp=oms_w.subproduction_plan) + if wproduct.test:# 如果有正在进行的工序中检验 + wproduct.test.is_midtesting = False + wproduct.test.save() + else: + wproduct.act_state = WProduct.WPR_ACT_STATE_DOWAIT + if needTest: + wproduct.act_state = WProduct.WPR_ACT_STATE_TOTEST + wproduct.material_check = wproduct.product + + # 更新子计划进度 + WpmService.update_subproduction_progress_main( + sp=oms_w.subproduction_plan) wproduct.create_by = request.user wproduct.coperation = op wproduct.save() - WpmServies.add_wproduct_flow_log(wproduct, 'wproduct_create') + WpmService.add_wproduct_flow_log(wproduct, 'wproduct_create') # 隐藏原半成品 wps = WProduct.objects.filter(ow_wproduct__operation=op) wps.update(is_hidden=True, child=wproduct, @@ -747,7 +765,7 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd # 如果是冷加工 if step.process.id == 1: - WpmServies.update_cutting_list_with_operation(op=op) + WpmService.update_cutting_list_with_operation(op=op) return Response() @@ -971,213 +989,3 @@ class OperationMaterialToolViewSet(ListModelMixin, CreateModelMixin, DestroyMode return Response() -class DoFormInit(CreateAPIView, GenericAPIView): - perms_map = {'*': '*'} - serializer_class = OperationInitSerializer - - def post(self, request, format=None): - """ - 调用操作表单 - """ - data = request.data - serializer = OperationInitSerializer(data=data) - serializer.is_valid(raise_exception=True) - vdata = serializer.validated_data - ret = {} - ret_0 = {} - ret_0['step'] = data['step'] - splans = [] - ret_0['input'] = [] - # ret_0['subproduction_plan'] = data['subproduction_plan'] - if 'wproducts' in data and data['wproducts']: - ret_0['wproducts'] = data['wproducts'] - splans = WProduct.objects.filter(id__in=data['wproducts']).values_list( - 'subproduction_plan', flat=True) - # 调出所属子计划现有物料 - ret_0['input'] = WMaterialListSerializer(instance=WMaterial.objects.filter( - subproduction_plan__in=splans), many=True).data - else: - if 'subproduction_plan' in vdata: - splans = [vdata['subproduction_plan']] - else: - splans = SubProductionPlan.objects.filter(is_deleted=False, - subproduction__usedstep_subproduction__step=vdata[ - 'step'], - state=3) - ret_0['wproducts'] = [] - ret_0['input'] = WMaterialListSerializer(instance=WMaterial.objects.filter( - subproduction_plan__in=splans), many=True).data - - for i in ret_0['input']: - i['count_input'] = 0 - # 需要输出的物料 - if ret_0['wproducts']: - # 排除主要产物, 因为已经放到半成品里了, 由半成品进行处理, 夹层可能需要特殊处理 - o_objs = SubProductionProgress.objects.filter( - subproduction_plan__in=splans, type=SubprodctionMaterial.SUB_MA_TYPE_OUT).exclude(is_main=True) - - else: - # 此时显示所有子计划需要输出的物料 - o_objs = SubProductionProgress.objects.filter( - subproduction_plan__in=splans, type=SubprodctionMaterial.SUB_MA_TYPE_OUT) - ret_0['output'] = list(o_objs.values( - 'subproduction_plan', 'material', 'material__name', 'material__number')) - for i in ret_0['output']: - i['count_output'] = 0 - 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(): - ret['forms'].extend(RecordFormDetailSerializer( - instance=forms, many=True).data) - return Response(ret) - - -class DoFormSubmit(CreateAPIView, GenericAPIView): - perms_map = {'*': '*'} - serializer_class = OperationSubmitSerializer - - @transaction.atomic - def post(self, request, format=None): - """ - 提交操作表单 - """ - data = request.data - serializer = OperationSubmitSerializer( - data=data, context={'request': self.request}) - serializer.is_valid(raise_exception=True) - vdata = serializer.validated_data # 校验之后的数据 - - # 创建一个生产操作记录 - action_obj = Operation() - 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 - owps.append(OperationWproduct(**owp)) - OperationWproduct.objects.bulk_create(owps) - - # 保存物料消耗 - for i in vdata['input']: - if i['count_input']: # 如果有消耗 - i_wmat = i['id'] - OperationMaterial.objects.create(type=1, operation=action_obj, - wmaterial=i_wmat, count=i['count_input']) - # 更新车间物料 - i_wmat.count = i_wmat.count - i['count_input'] - i_wmat.save() - # 更新子计划物料消耗情况 - sp = SubProductionProgress.objects.get(subproduction_plan=i_wmat.subproduction_plan, - material=i_wmat.material) - sp.count_real = sp.count_real + i['count_input'] - sp.save() - - # 物料产出 - if 'output' in data and data['output']: - for i in vdata['output']: # 已经序列化好的数据 - ma = i['material'] - if i['subproduction_plan'].product == ma: # 如果是该计划主产物 - # 如果是切割 - # 获取下一步子工序 - if vdata['step'].type == Step.STEP_TYPE_DIV: - newstep, _ = WpmServies.get_next_step( - i['subproduction_plan'], vdata['step']) - wpr = dict(material=ma, step=newstep, - act_state=WProduct.WPR_ACT_STATE_DOWAIT, remark='', - subproduction_plan=i['subproduction_plan']) - for x in range(i['count_output']): - WProduct.objects.create(**wpr) - else: - # 更新操作产出物料表 - OperationMaterial.objects.create(type=2, operation=action_obj, - material=ma, count=i['count_output']) - # 更新车间物料表 - ins, _ = WMaterial.objects.get_or_create(subproduction_plan=i['subproduction_plan'], - material=ma) - ins.count = ins.count + i['count_output'] - ins.save() - # 更新子计划进度表 - sp = SubProductionProgress.objects.get(subproduction_plan=i['subproduction_plan'], - material=ma) - sp.count_real = sp.count_real + i['count_input'] - sp.save() - - # 更新动态产品表 - if 'wproducts' in vdata and vdata['wproducts']: - if vdata['step'].type == Step.STEP_TYPE_COMB: - wproducts = vdata['wproducts'] - if 'suproduction_plan' in vdata: - wproducts.update(is_hidden=True) # 隐藏 - newstep, hasNext = WpmServies.get_next_step( - i['subproduction_plan'], vdata['step']) - wproduct = WProduct() - wproduct.material = vdata['subproduction_plan'].product - wproduct.step = newstep - wproduct.subproduction_plan = vdata['subproduction_plan'] - wproduct.parent = data['wproducts'] - if hasNext: - wproduct.act_state = WProduct.WPR_ACT_STATE_DOWAIT - else: - wproduct.act_state = WProduct.WPR_ACT_STATE_TOTEST - wproduct.save() - else: - raise exceptions.APIException('请指定子计划') - else: - for wproduct in vdata['wproducts']: - # 获取下一步子工序 - newstep, hasNext = WpmServies.get_next_step( - wproduct.subproduction_plan, vdata['step']) - wproduct.step = newstep - wproduct.pre_step = vdata['step'] - if hasNext: - wproduct.act_state = WProduct.WPR_ACT_STATE_DOWAIT - else: - wproduct.act_state = WProduct.WPR_ACT_STATE_TOTEST - wproduct.material = wproduct.subproduction_plan.product - wproduct.save() - - # 保存自定义表单结果 - for i in vdata['forms']: - wr = OperationRecord() - wr.form = i['form'] - wr.create_by = request.user - wr.operation = action_obj - wr.save() - wrds = [] - for m in i['record_data']: # 保存记录详情 - form_field = m['form_field'] - m['field_name'] = form_field.field_name - m['field_key'] = form_field.field_key - m['field_type'] = form_field.field_type - m['field_value'] = m['field_value'] - m['sort'] = form_field.sort - m['operation_record'] = wr - wrds.append(OperationRecordItem(**m)) - OperationRecordItem.objects.bulk_create(wrds) - return Response() From fadd16eb1f7630ccffc1f378450af222131a122f Mon Sep 17 00:00:00 2001 From: caoqianming Date: Sat, 29 Jan 2022 15:53:24 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E5=B7=A5=E5=BA=8F=E4=B8=AD=E6=A3=80?= =?UTF-8?q?=E9=AA=8C=E6=9C=80=E5=90=8E=E4=B8=80=E6=AD=A5=E6=97=B6=E8=AE=BE?= =?UTF-8?q?=E4=B8=BA=E6=9C=AA=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/wpm/views.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hb_server/apps/wpm/views.py b/hb_server/apps/wpm/views.py index cf607ec..43d9cee 100644 --- a/hb_server/apps/wpm/views.py +++ b/hb_server/apps/wpm/views.py @@ -689,6 +689,7 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd wp.material = wsp.product if wp.test:# 如果有正在进行的工序中检验 wp.test.is_midtesting = False + wp.test.is_submited = False wp.test.save() else: wp.act_state = WProduct.WPR_ACT_STATE_DOWAIT @@ -740,6 +741,7 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd wproduct.act_state = WProduct.WPR_ACT_STATE_TOTEST if wproduct.test:# 如果有正在进行的工序中检验 wproduct.test.is_midtesting = False + wproduct.test.is_submited = False wproduct.test.save() else: wproduct.act_state = WProduct.WPR_ACT_STATE_DOWAIT From 6e90fad047338aad165ca404db18efc55f0717c9 Mon Sep 17 00:00:00 2001 From: shilixia <2309368887@qq.com> Date: Thu, 10 Feb 2022 09:00:54 +0800 Subject: [PATCH 3/5] caigoujilu --- hb_client/src/api/pum.js | 61 ++++ hb_client/src/router/index.js | 13 +- hb_client/src/views/procurement/puorder.vue | 292 ++++++++++++++++++ .../src/views/procurement/puorderitem.vue | 197 ++++++++++++ hb_client/src/views/procurement/vendor.vue | 3 +- 5 files changed, 562 insertions(+), 4 deletions(-) create mode 100644 hb_client/src/api/pum.js create mode 100644 hb_client/src/views/procurement/puorder.vue create mode 100644 hb_client/src/views/procurement/puorderitem.vue diff --git a/hb_client/src/api/pum.js b/hb_client/src/api/pum.js new file mode 100644 index 0000000..2a807b4 --- /dev/null +++ b/hb_client/src/api/pum.js @@ -0,0 +1,61 @@ +import request from '@/utils/request' + +export function getPuorderList(query) { + return request({ + url: '/pum/pu_order/', + method: 'get', + params: query + }) +} +export function createPuorder(data) { + return request({ + url: '/pum/pu_order/', + method: 'post', + data + }) +} +export function updatePuorder(id, data) { + return request({ + url: `/pum/pu_order/${id}/`, + method: 'put', + data + }) +} +export function deletePuorder(id, data) { + return request({ + url: `/pum/pu_order/${id}/`, + method: 'delete', + data + }) +} +//采购订单审核 +export function createPuorderAudit(id,data) { + return request({ + url: `/pum/pu_order/${id}/audit/`, + method: 'post', + data + }) +} +//采购订单条目 +export function getPuorderItemList(query) { + return request({ + url: '/pum/pu_order_item/', + method: 'get', + params: query + }) +} +export function createPuorderItem(data) { + return request({ + url: '/pum/pu_order_item/', + method: 'post', + data + }) +} +//采购订单条目删除 +export function deletePuorderItem(id, data) { + return request({ + url: `/pum/pu_order_item/${id}/`, + method: 'delete', + data + }) +} \ No newline at end of file diff --git a/hb_client/src/router/index.js b/hb_client/src/router/index.js index 980eabf..e793c8d 100644 --- a/hb_client/src/router/index.js +++ b/hb_client/src/router/index.js @@ -508,10 +508,17 @@ export const asyncRoutes = [ meta: { title: '供应商', icon: 'example', perms: ['vendor_manage'] } }, { - path: 'vendor', - name: 'vendor', - component: () => import('@/views/procurement/vendor'), + path: 'puorder', + name: 'puorder', + component: () => import('@/views/procurement/puorder'), meta: { title: '采购订单', icon: 'example', perms: ['vendor_manage'] } + }, + { + path: 'puorderitem/:id', + name: 'puorderitem', + component: () => import('@/views/procurement/puorderitem'), + meta: { title: '采购订单项', perms: ['vendor_manage'] }, + hidden: true } ] }, diff --git a/hb_client/src/views/procurement/puorder.vue b/hb_client/src/views/procurement/puorder.vue new file mode 100644 index 0000000..6a28a35 --- /dev/null +++ b/hb_client/src/views/procurement/puorder.vue @@ -0,0 +1,292 @@ + + diff --git a/hb_client/src/views/procurement/puorderitem.vue b/hb_client/src/views/procurement/puorderitem.vue new file mode 100644 index 0000000..3a8b9d3 --- /dev/null +++ b/hb_client/src/views/procurement/puorderitem.vue @@ -0,0 +1,197 @@ + + diff --git a/hb_client/src/views/procurement/vendor.vue b/hb_client/src/views/procurement/vendor.vue index bf1a781..fcfc435 100644 --- a/hb_client/src/views/procurement/vendor.vue +++ b/hb_client/src/views/procurement/vendor.vue @@ -8,7 +8,7 @@ 编辑 From 7528f4970984e4a790c87e52a58b72bb378c7c27 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 10 Feb 2022 09:16:09 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E9=87=87=E8=B4=AD=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=E5=85=A5=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/inm/serializers.py | 4 ++-- hb_server/apps/inm/views.py | 22 ++++++++++++---------- hb_server/apps/monitor/views.py | 4 ++-- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/hb_server/apps/inm/serializers.py b/hb_server/apps/inm/serializers.py index b1e842a..44aeb52 100644 --- a/hb_server/apps/inm/serializers.py +++ b/hb_server/apps/inm/serializers.py @@ -80,7 +80,7 @@ class FIFOItemCreateSerializer(serializers.ModelSerializer): class Meta: model = FIFOItem fields = ['warehouse', - 'material', 'batch', 'fifo', 'files', 'pu_order_item'] + 'material', 'batch', 'fifo', 'files', 'pu_order_item', 'count'] def create(self, validated_data): fifo = validated_data['fifo'] @@ -97,7 +97,7 @@ class FIFOItemCreateSerializer(serializers.ModelSerializer): class FIFOItemUpdateSerializer(serializers.ModelSerializer): class Meta: model = FIFOItem - fields = ['warehouse', 'batch', 'files'] + fields = ['warehouse', 'batch', 'files', 'count'] class FIFOItemSerializer(serializers.ModelSerializer): warehouse_ = WareHouseSimpleSerializer(source='warehouse', read_only=True) diff --git a/hb_server/apps/inm/views.py b/hb_server/apps/inm/views.py index 7a4e069..a7ba143 100644 --- a/hb_server/apps/inm/views.py +++ b/hb_server/apps/inm/views.py @@ -25,7 +25,8 @@ class WarehouseViewSet(CreateUpdateModelAMixin, ModelViewSet): """ 仓库-增删改查 """ - perms_map = {'*': '*'} + perms_map = {'get': '*', 'post':'warehouse_create', + 'put':'warehouse_update', 'delete':'warehouse_delete'} queryset = WareHouse.objects.select_related('create_by').all() serializer_class = WareHouseSerializer search_fields = ['name', 'number', 'place'] @@ -43,7 +44,7 @@ class InventoryViewSet(ListModelMixin, GenericViewSet): """ 仓库物料表 """ - perms_map = {'*': '*'} + perms_map = {'get': '*'} queryset = Inventory.objects.select_related( 'material', 'warehouse').filter(count__gt=0).all() serializer_class = InventorySerializer @@ -54,7 +55,7 @@ class InventoryViewSet(ListModelMixin, GenericViewSet): class MaterialBatchViewSet(ListModelMixin, GenericViewSet): - perms_map = {'*': '*'} + perms_map = {'get': '*'} queryset = MaterialBatch.objects.select_related( 'material', 'warehouse').filter(count__gt=0).all() serializer_class = MaterialBatchSerializer @@ -81,7 +82,8 @@ class FIFOItemViewSet(ListModelMixin, CreateModelMixin, DestroyModelMixin, Updat """ 出入库记录详情表 """ - perms_map = {'*': '*'} + perms_map = {'get': '*', 'post':'fifoitem_create', + 'put':'fifoitem_update', 'delete':'fifoitem_delete'} queryset = FIFOItem.objects.select_related('material', 'fifo').prefetch_related('files').all() serializer_class = FIFOItemSerializer filterset_fields = ['material', 'fifo', @@ -115,7 +117,7 @@ class FIFOItemViewSet(ListModelMixin, CreateModelMixin, DestroyModelMixin, Updat raise ValidationError('该出入库记录已审核') return super().destroy(request, *args, **kwargs) - @action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=InmTestRecordCreateSerializer) + @action(methods=['post'], detail=False, perms_map={'post': 'fifoitem_test'}, serializer_class=InmTestRecordCreateSerializer) def test(self, request, pk=None): """ 检验 @@ -147,7 +149,7 @@ class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet): """ 出入库记录 """ - perms_map = {'*': '*'} + perms_map = {'get': '*', 'delete':'fifo_delete'} queryset = FIFO.objects.select_related('auditor', 'create_by') serializer_class = FIFOListSerializer filterset_fields = '__all__' @@ -166,7 +168,7 @@ class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet): raise exceptions.APIException('该记录已审核,不可删除') return super().destroy(request, *args, **kwargs) - @action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=FIFOInPurSerializer) + @action(methods=['post'], detail=False, perms_map={'post': 'fifo_in_pur'}, serializer_class=FIFOInPurSerializer) def in_pur(self, request, pk=None): """ 采购入库 @@ -176,7 +178,7 @@ class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet): serializer.save(create_by=request.user) return Response() - @action(methods=['post'], detail=False, perms_map={'post': '*'}, + @action(methods=['post'], detail=False, perms_map={'post': 'fifo_in_other'}, serializer_class=FIFOInOtherSerializer) def in_other(self, request, pk=None): """ @@ -187,7 +189,7 @@ class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet): serializer.save(create_by=request.user) return Response() - @action(methods=['post'], detail=True, perms_map={'post': '*'}, serializer_class=serializers.Serializer) + @action(methods=['post'], detail=True, perms_map={'post': 'fifo_audit'}, serializer_class=serializers.Serializer) def audit(self, request, pk=None): """ 审核通过 @@ -213,7 +215,7 @@ class IProductViewSet(ListModelMixin, GenericViewSet): """ 半成品库存表 """ - perms_map = {'*': '*'} + perms_map = {'get': '*'} queryset = IProduct.objects.select_related( 'material', 'warehouse', 'wproduct__subproduction_plan__production_plan__order', diff --git a/hb_server/apps/monitor/views.py b/hb_server/apps/monitor/views.py index ffd85fe..b383f4d 100644 --- a/hb_server/apps/monitor/views.py +++ b/hb_server/apps/monitor/views.py @@ -45,7 +45,7 @@ def get_file_list(file_path): return dir_list class LogView(APIView): - + permission_classes = [IsAuthenticated] @swagger_auto_schema(manual_parameters=[ openapi.Parameter('name', openapi.IN_QUERY, description='日志文件名', type=openapi.TYPE_STRING) ]) @@ -82,7 +82,7 @@ class LogView(APIView): class LogDetailView(APIView): - + permission_classes = [IsAuthenticated] def get(self, request, name): """ 查看日志详情 From e086bcda58140716b6e99121b3f0c216dfb72fd5 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 10 Feb 2022 09:18:25 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E5=87=BA=E5=85=A5=E5=BA=93=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E8=A1=A8=E5=A2=9E=E5=8A=A0=E5=85=B6=E4=BB=96=E5=85=A5?= =?UTF-8?q?=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/inm/models.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hb_server/apps/inm/models.py b/hb_server/apps/inm/models.py index 90d80c7..64b4108 100644 --- a/hb_server/apps/inm/models.py +++ b/hb_server/apps/inm/models.py @@ -67,11 +67,13 @@ class FIFO(CommonADModel): FIFO_TYPE_SALE_OUT = 2 FIFO_TYPE_PUR_IN = 3 FIFO_TYPE_DO_IN = 4 + FIFO_TYPE_OTHER_IN = 5 type_choices = ( (FIFO_TYPE_DO_OUT, '生产领料'), (FIFO_TYPE_SALE_OUT, '销售提货'), (FIFO_TYPE_PUR_IN, '采购入库'), - (FIFO_TYPE_DO_IN, '生产入库') + (FIFO_TYPE_DO_IN, '生产入库'), + (FIFO_TYPE_OTHER_IN, '其他入库') ) number = models.CharField('记录编号', max_length=100) type = models.IntegerField('出入库类型', default=1)