diff --git a/hb_server/apps/wpm/migrations/0027_pick_pickwproduct.py b/hb_server/apps/wpm/migrations/0027_pick_pickwproduct.py new file mode 100644 index 0000000..b9b4f4e --- /dev/null +++ b/hb_server/apps/wpm/migrations/0027_pick_pickwproduct.py @@ -0,0 +1,54 @@ +# Generated by Django 3.2.9 on 2021-12-02 01:54 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('inm', '0019_auto_20211201_1011'), + ('pm', '0015_auto_20211122_1556'), + ('mtm', '0040_material_piece_count'), + ('wpm', '0026_auto_20211201_1608'), + ] + + operations = [ + migrations.CreateModel( + name='Pick', + 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='删除标记')), + ('type', models.PositiveSmallIntegerField(choices=[(10, '仓库领取'), (20, '半成品领取')], default=10)), + ('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='pick_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')), + ('fifo', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='inm.fifo', verbose_name='关联的出入库记录')), + ('subproduction_plan', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pm.subproductionplan', verbose_name='关联子生产计划')), + ('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='pick_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='PickWproduct', + 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='领取时的物料状态')), + ('pick', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='wpm.pick', 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, related_name='pw_wproduct', to='wpm.wproduct', verbose_name='关联半成品')), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/hb_server/apps/wpm/models.py b/hb_server/apps/wpm/models.py index 9bd50d2..b1af088 100644 --- a/hb_server/apps/wpm/models.py +++ b/hb_server/apps/wpm/models.py @@ -3,7 +3,7 @@ from django.db import models from django.db.models.base import Model import django.utils.timezone as timezone from django.db.models.query import QuerySet -from apps.inm.models import WareHouse +from apps.inm.models import FIFO, WareHouse from apps.pm.models import ProductionPlan, SubProductionPlan, SubProductionProgress from apps.system.models import CommonADModel, CommonAModel, CommonBModel, Organization, User, Dict, File from utils.model import SoftModel, BaseModel @@ -20,7 +20,6 @@ class WMaterial(BaseModel): batch = models.CharField('批次号', max_length=100, null=True, blank=True) count = models.PositiveIntegerField('当前数量', default=0) - class WProduct(CommonAModel): """ 动态半成品/成品表 @@ -55,6 +54,31 @@ class WProduct(CommonAModel): operation = models.ForeignKey('wpm.operation', verbose_name='关联操作', on_delete=models.SET_NULL, null=True, blank=True, related_name='current_operation') + +class Pick(CommonADModel): + """ + 领料记录 + """ + PICK_FROM_WAREHOUSE = 10 + PICK_FROM_WPRODUCT = 20 + type_choice = ( + (PICK_FROM_WAREHOUSE, '仓库领取'), + (PICK_FROM_WPRODUCT, '半成品领取'), + ) + subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.CASCADE) + type = models.PositiveSmallIntegerField(choices=type_choice, default=PICK_FROM_WAREHOUSE) + fifo = models.ForeignKey(FIFO, verbose_name='关联的出入库记录', on_delete=models.CASCADE, null=True, blank=True) + +class PickWproduct(BaseModel): + """ + 领取半成品时详情 + """ + pick = models.ForeignKey(Pick, verbose_name='关联领料', on_delete=models.CASCADE) + wproduct = models.ForeignKey(WProduct, verbose_name='关联半成品', on_delete=models.CASCADE, related_name='pw_wproduct') + 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) + class Operation(CommonADModel): """ 生产操作 diff --git a/hb_server/apps/wpm/serializers.py b/hb_server/apps/wpm/serializers.py index ec95ed0..7bca29e 100644 --- a/hb_server/apps/wpm/serializers.py +++ b/hb_server/apps/wpm/serializers.py @@ -13,7 +13,7 @@ from django.utils.translation import gettext_lazy as _ from apps.pm.serializers import SubproductionPlanSimpleSerializer from apps.qm.models import TestRecord, TestRecordItem from apps.system.serializers import UserSimpleSerializer -from apps.wpm.models import Operation, OperationEquip, OperationMaterial, OperationWproduct, WMaterial, WProduct, OperationRecord, OperationRecordItem +from apps.wpm.models import Operation, OperationEquip, OperationMaterial, OperationWproduct, Pick, WMaterial, WProduct, OperationRecord, OperationRecordItem from django.db import transaction class PickHalfSerializer(serializers.Serializer): @@ -32,7 +32,6 @@ class PickDetailSerializer(serializers.Serializer): class PickSerializer(serializers.Serializer): subproduction_plan=serializers.PrimaryKeyRelatedField(queryset=SubProductionPlan.objects.all(), label="子计划ID") picks = PickDetailSerializer(many=True) # 从库存里拿 - def create(self, validated_data): picks = validated_data.pop('picks') @@ -108,6 +107,13 @@ class PickSerializer(serializers.Serializer): sp.state = SubProductionPlan.SUBPLAN_STATE_WORKING #生产中 sp.state_date_real = timezone.now() #实际开工日期 sp.save() + # 创建领料记录 + pick = Pick() + pick.subproduction_plan = sp + pick.type = Pick.PICK_FROM_WAREHOUSE + pick.fifo = fifo + pick.create_by = self.context['request'].user + pick.save() # 更新库存 fifo.is_audited = True fifo.save() diff --git a/hb_server/apps/wpm/views.py b/hb_server/apps/wpm/views.py index 86712f3..5fc6d27 100644 --- a/hb_server/apps/wpm/views.py +++ b/hb_server/apps/wpm/views.py @@ -16,7 +16,7 @@ from apps.qm.models import TestRecordItem from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin from rest_framework.decorators import action from apps.wpm.filters import WMaterialFilterSet -from apps.wpm.models import OperationEquip, OperationWproduct, WMaterial, WProduct, Operation, OperationMaterial, OperationRecord, OperationRecordItem +from apps.wpm.models import OperationEquip, OperationWproduct, Pick, PickWproduct, WMaterial, WProduct, Operation, OperationMaterial, OperationRecord, OperationRecordItem from apps.wpm.serializers import OperationEquipListSerializer, OperationEquipUpdateSerializer, OperationMaterialCreate1Serailizer, OperationMaterialCreate2Serailizer, OperationMaterialCreate3Serializer, OperationMaterialListSerializer, OperationRecordListSerializer, OperationRecordSubmitSerializer, OperationUpdateSerializer, OperationWproductListSerializer, OperationCreateSerializer, OperationDetailSerializer, OperationListSerializer, PickHalfSerializer, PickSerializer, OperationInitSerializer, OperationSubmitSerializer, WMaterialListSerializer, WProductListSerializer, WplanPutInSerializer, WpmTestRecordCreateSerializer, WproductPutInSerializer from rest_framework.response import Response @@ -59,6 +59,12 @@ class WPlanViewSet(ListModelMixin, GenericViewSet): serializer.is_valid(raise_exception=True) vdata = serializer.data first_step = Step.objects.get(pk=sp.steps[0]['id']) + # 创建领料记录 + pick = Pick() + pick.subproduction_plan = sp + pick.type = Pick.PICK_FROM_WPRODUCT + pick.create_by = request.user + pick.save() for i in vdata: if 'wproducts' in i and len(i['wproducts'])>0: spp = SubProductionProgress.objects.get(pk=i['id']) @@ -66,12 +72,23 @@ class WPlanViewSet(ListModelMixin, GenericViewSet): # if spp.count_pick > spp.count: # raise exceptions.APIException('超过计划数') spp.save() - wps = WProduct.objects.filter(pk__in=[x for x in i['wproducts']]) + wps = WProduct.objects.filter(pk__in=[x for x in i['wproducts']], act_state=WProduct.WPR_ACT_STATE_OK) wps.update(step=first_step, is_executed=False, act_state=WProduct.WPR_ACT_STATE_TORETEST, is_hidden=False, warehouse=None, subproduction_plan=sp, update_by=request.user, update_time=timezone.now()) + for i in wps: + pw = PickWproduct() + pw.pick =pick + pw.wproduct = i + pw.number = i.number + pw.material = i.material + pw.subproduction_plan = i.suproduction_plan + pw.save() + else: + raise exceptions.APIException('未选择任何玻璃') sp.is_picked = True sp.save() + return Response()