From 3bd4cb014e67cb17f79be0078a06539c61ea3ada Mon Sep 17 00:00:00 2001 From: caoqianming Date: Wed, 27 Oct 2021 13:17:01 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=87=87=E8=B4=AD=E5=85=A5?= =?UTF-8?q?=E5=BA=93=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../inm/migrations/0005_auto_20211025_1533.py | 86 +++++++++++++++++++ .../inm/migrations/0006_auto_20211027_0941.py | 26 ++++++ hb_server/apps/inm/models.py | 29 +++++-- hb_server/apps/inm/serializers.py | 52 ++++++++++- hb_server/apps/inm/urls.py | 3 +- hb_server/apps/inm/views.py | 23 ++++- .../pm/migrations/0007_auto_20211025_1533.py | 23 +++++ hb_server/server/settings.py | 2 +- 8 files changed, 231 insertions(+), 13 deletions(-) create mode 100644 hb_server/apps/inm/migrations/0005_auto_20211025_1533.py create mode 100644 hb_server/apps/inm/migrations/0006_auto_20211027_0941.py create mode 100644 hb_server/apps/pm/migrations/0007_auto_20211025_1533.py diff --git a/hb_server/apps/inm/migrations/0005_auto_20211025_1533.py b/hb_server/apps/inm/migrations/0005_auto_20211025_1533.py new file mode 100644 index 0000000..be966a8 --- /dev/null +++ b/hb_server/apps/inm/migrations/0005_auto_20211025_1533.py @@ -0,0 +1,86 @@ +# Generated by Django 3.2.6 on 2021-10-25 07:33 + +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), + ('wpm', '__first__'), + ('mtm', '0025_outputmaterial_is_main'), + ('pm', '0007_auto_20211025_1533'), + ('inm', '0004_auto_20210929_0842'), + ] + + operations = [ + migrations.AddField( + model_name='fifo', + name='inout_date', + field=models.DateField(default=django.utils.timezone.now, verbose_name='出入库日期'), + preserve_default=False, + ), + migrations.AddField( + model_name='fifo', + name='operator', + field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='system.user', verbose_name='操作人'), + preserve_default=False, + ), + migrations.AddField( + model_name='fifo', + name='subproduction_plan', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='pm.subproductionplan', verbose_name='关联子生产计划'), + ), + migrations.AddField( + model_name='fifo', + name='warehouse', + field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='inm.warehouse', verbose_name='仓库'), + preserve_default=False, + ), + migrations.AlterField( + model_name='materialbatch', + name='batch', + field=models.CharField(blank=True, max_length=100, null=True, unique=True, verbose_name='批次号'), + ), + migrations.CreateModel( + name='IProduct', + 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='删除标记')), + ('state', models.IntegerField(default=1, verbose_name='物品状态')), + ('number', models.CharField(blank=True, max_length=50, null=True, unique=True, verbose_name='物品编号')), + ('batch', models.CharField(blank=True, max_length=100, null=True, verbose_name='所属批次号')), + ('fifos', models.JSONField(blank=True, default=list, verbose_name='关联出入库记录')), + ('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='iproduct_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')), + ('d_product', models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.CASCADE, to='wpm.product', verbose_name='关联的动态产品')), + ('material', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='物料类型')), + ('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='iproduct_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')), + ('warehouse', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='inm.warehouse', verbose_name='所在仓库')), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='FIFODetail', + 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='删除标记')), + ('count', models.IntegerField(default=0, verbose_name='数量')), + ('batch', models.CharField(blank=True, max_length=100, null=True, verbose_name='批次号')), + ('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='fifodetail_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')), + ('material', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='物料类型')), + ('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='fifodetail_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/hb_server/apps/inm/migrations/0006_auto_20211027_0941.py b/hb_server/apps/inm/migrations/0006_auto_20211027_0941.py new file mode 100644 index 0000000..d637e16 --- /dev/null +++ b/hb_server/apps/inm/migrations/0006_auto_20211027_0941.py @@ -0,0 +1,26 @@ +# Generated by Django 3.2.6 on 2021-10-27 01:41 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('wpm', '__first__'), + ('inm', '0005_auto_20211025_1533'), + ] + + operations = [ + migrations.AddField( + model_name='fifodetail', + name='fifo', + field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='inm.fifo', verbose_name='关联出入库'), + preserve_default=False, + ), + migrations.AlterField( + model_name='iproduct', + name='d_product', + field=models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.CASCADE, to='wpm.product', verbose_name='关联的动态产品'), + ), + ] diff --git a/hb_server/apps/inm/models.py b/hb_server/apps/inm/models.py index 767745b..d2c6472 100644 --- a/hb_server/apps/inm/models.py +++ b/hb_server/apps/inm/models.py @@ -41,7 +41,7 @@ class MaterialBatch(BaseModel): material = models.ForeignKey(Material, on_delete=models.CASCADE, verbose_name='物料信息') warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库') count = models.IntegerField('存量', default=0) - batch = models.CharField('批次号', max_length=100, null=True, blank=True) + batch = models.CharField('批次号', max_length=100, null=True, blank=True, unique=True) expiration_date = models.DateField('有效期', null=True, blank=True) class Meta: verbose_name = '库存表' @@ -60,22 +60,37 @@ class FIFO(CommonAModel): (4, '生产入库') ) type = models.IntegerField('出入库类型', default=1) + warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='仓库') operator = models.ForeignKey(User, verbose_name='操作人', on_delete=models.CASCADE) subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.DO_NOTHING, null=True, blank=True) + inout_date = models.DateField('出入库日期') -# class FIFODetail(CommonAModel): -# """ -# 领料详细记录 -# """ -class Product(CommonAModel): +class FIFODetail(BaseModel): """ - 具体产品 + 出入库详细记录 """ + material = models.ForeignKey(Material, verbose_name='物料类型', on_delete=models.CASCADE) + count = models.IntegerField('数量', default=0) + batch = models.CharField('批次号', max_length=100, null=True, blank=True) + fifo = models.ForeignKey(FIFO, verbose_name='关联出入库', on_delete=models.CASCADE) + + +class IProduct(BaseModel): + """ + 具体产品条目 + """ + inm_product_state_choices = ( + (1, '可用'), + (2, '锁定'), + (3, '已消耗') + ) + state = models.IntegerField('物品状态', default=1) number = models.CharField('物品编号', unique=True, null=True, blank=True, max_length=50) material = models.ForeignKey(Material, verbose_name='物料类型', on_delete=models.CASCADE) warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库') batch = models.CharField('所属批次号', max_length=100, null=True, blank=True) + d_product = models.ForeignKey('wpm.product', on_delete=models.CASCADE, verbose_name='关联的动态产品', db_constraint=False, null=True, blank=True) fifos = models.JSONField('关联出入库记录', default=list, blank=True) diff --git a/hb_server/apps/inm/serializers.py b/hb_server/apps/inm/serializers.py index 808f470..926d19c 100644 --- a/hb_server/apps/inm/serializers.py +++ b/hb_server/apps/inm/serializers.py @@ -1,6 +1,6 @@ from rest_framework import serializers -from apps.inm.models import WareHouse,Inventory +from apps.inm.models import FIFO, FIFODetail, IProduct, WareHouse,Inventory from apps.system.serializers import UserSimpleSerializer from apps.mtm.serializers import MaterialSimpleSerializer @@ -32,3 +32,53 @@ class InventoryCreateUpdateSerializer(serializers.ModelSerializer): class Meta: model = Inventory fields = ['material', 'count', 'warehouse'] + +class IProductInPurSerializer(serializers.ModelSerializer): + class Meta: + model = IProduct + fields = ['number'] + +class FIFODetailInPurSerializer(serializers.ModelSerializer): + details = IProductInPurSerializer(many=True, required=False) + class Meta: + model = FIFODetail + fields = ['material', 'count', 'batch', 'details'] + +class FIFOInPurSerializer(serializers.ModelSerializer): + """ + 采购入库序列化 + """ + details = FIFODetailInPurSerializer(many=True) + class Meta: + model = FIFO + fields = ['warehouse', 'operator', 'details', 'inout_date'] + + def create(self, validated_data): + details = validated_data.pop('details') + if len(details)>0: + pass + else: + raise serializers.ValidationError('没有入库内容') + validated_data['type'] = 3 + obj = FIFO(**validated_data) + obj.save() + for i in details: + if 'details' in i: + p_details = i.pop('details') + if len(p_details) != i['count']: + raise serializers.ValidationError('数目对不上') + else: + serialier = FIFODetailInPurSerializer(data=i) + fifod = serialier.save(fifo=obj) + p_list = [] + for x in p_details: + x['state'] = 1 + x['material'] = i['material'] + x['warehouse'] = validated_data['warehouse'] + x['batch'] = i['batch'] + x['fifos'] = [fifod.id] + p_list.append(IProduct(**x)) + IProduct.objects.bulk_create(p_list) + else: + serialier = FIFODetailInPurSerializer(data=i) + serialier.save(fifo=obj) \ No newline at end of file diff --git a/hb_server/apps/inm/urls.py b/hb_server/apps/inm/urls.py index d680958..851ccc8 100644 --- a/hb_server/apps/inm/urls.py +++ b/hb_server/apps/inm/urls.py @@ -1,12 +1,13 @@ from django.db.models import base from rest_framework import urlpatterns -from apps.inm.views import WarehouseViewSet,InventoryViewSet +from apps.inm.views import FIFOViewSet, WarehouseViewSet,InventoryViewSet from django.urls import path, include from rest_framework.routers import DefaultRouter router = DefaultRouter() router.register('warehouse', WarehouseViewSet, basename='warehouse') router.register('inventory', InventoryViewSet, basename='inventory') +router.register('fifo', FIFOViewSet, basename='fifo') urlpatterns = [ path('', include(router.urls)), ] diff --git a/hb_server/apps/inm/views.py b/hb_server/apps/inm/views.py index e8e8754..3e292b1 100644 --- a/hb_server/apps/inm/views.py +++ b/hb_server/apps/inm/views.py @@ -1,11 +1,12 @@ from django.shortcuts import render +from rest_framework import serializers from rest_framework.mixins import ListModelMixin from rest_framework.viewsets import GenericViewSet, ModelViewSet from apps.inm.models import WareHouse,Inventory -from apps.inm.serializers import WareHouseSerializer, WareHouseCreateUpdateSerializer,InventorySerializer,InventoryCreateUpdateSerializer +from apps.inm.serializers import FIFOInPurSerializer, WareHouseSerializer, WareHouseCreateUpdateSerializer,InventorySerializer,InventoryCreateUpdateSerializer from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin - +from rest_framework.decorators import action # Create your views here. class WarehouseViewSet(CreateUpdateModelAMixin, ModelViewSet): @@ -27,11 +28,27 @@ class WarehouseViewSet(CreateUpdateModelAMixin, ModelViewSet): class InventoryViewSet(ListModelMixin, GenericViewSet): """ - 物料基本信息-增删改查 + 仓库物料表 """ perms_map = {'*': '*'} queryset = Inventory.objects.select_related('create_by').all() serializer_class = InventorySerializer filterset_fields = [] + search_fields = ['material', 'warehouse'] ordering_fields = ['create_time'] ordering = ['-create_time'] + +class FIFOViewSet(GenericViewSet): + """ + 出入库记录 + """ + perms_map = {'*': '*'} + @action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=FIFOInPurSerializer) + def in_pur(self, request, pk=None): + """ + 采购入库 + """ + serializer = self.get_serializer(data=request.data) + serializer.is_valid(raise_exception=True) + serializer.save() + \ No newline at end of file diff --git a/hb_server/apps/pm/migrations/0007_auto_20211025_1533.py b/hb_server/apps/pm/migrations/0007_auto_20211025_1533.py new file mode 100644 index 0000000..8676cdb --- /dev/null +++ b/hb_server/apps/pm/migrations/0007_auto_20211025_1533.py @@ -0,0 +1,23 @@ +# Generated by Django 3.2.6 on 2021-10-25 07:33 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('pm', '0006_alter_subproductionprogress_count_real'), + ] + + operations = [ + migrations.AddField( + model_name='subproductionplan', + name='end_date_real', + field=models.DateField(blank=True, null=True, verbose_name='实际完工日期'), + ), + migrations.AddField( + model_name='subproductionplan', + name='start_date_real', + field=models.DateField(blank=True, null=True, verbose_name='实际开工日期'), + ), + ] diff --git a/hb_server/server/settings.py b/hb_server/server/settings.py index 7d1174e..f2e54e5 100644 --- a/hb_server/server/settings.py +++ b/hb_server/server/settings.py @@ -57,7 +57,7 @@ INSTALLED_APPS = [ 'apps.sam', 'apps.qm', 'apps.pm', - # 'apps.wpm' + 'apps.wpm' ] MIDDLEWARE = [