From 515d0b5c17c4002b24d7ec81722108978d264897 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Tue, 26 Sep 2023 11:24:52 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=87=BA=E5=85=A5=E5=BA=93=E6=98=8E?= =?UTF-8?q?=E7=BB=86=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/inm/migrations/0002_mio_mioitem.py | 64 +++++++++++++++++++++++++ apps/inm/serializers.py | 17 ++++++- apps/inm/urls.py | 3 +- apps/inm/views.py | 23 +++++++-- apps/pm/views.py | 2 +- 5 files changed, 102 insertions(+), 7 deletions(-) create mode 100644 apps/inm/migrations/0002_mio_mioitem.py diff --git a/apps/inm/migrations/0002_mio_mioitem.py b/apps/inm/migrations/0002_mio_mioitem.py new file mode 100644 index 00000000..9ccd7c98 --- /dev/null +++ b/apps/inm/migrations/0002_mio_mioitem.py @@ -0,0 +1,64 @@ +# Generated by Django 3.2.12 on 2023-09-26 02: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 = [ + ('system', '0002_myschedule'), + ('pum', '0001_initial'), + ('mtm', '0012_auto_20230926_1054'), + ('sam', '0003_orderitem_mtask'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('inm', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='MIO', + fields=[ + ('id', models.CharField(editable=False, help_text='主键ID', max_length=20, 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(max_length=20, verbose_name='编号')), + ('state', models.PositiveSmallIntegerField(choices=[(10, '创建中'), (20, '已提交')], default=10, help_text='10', verbose_name='状态')), + ('type', models.CharField(choices=[('do_out', '生产领料'), ('sale_out', '销售发货'), ('pur_in', '采购入库'), ('do_in', '生产入库'), ('other_in', '其他入库'), ('other_out', '其他出库')], default='do_out', help_text="(('do_out', '生产领料'), ('sale_out', '销售发货'), ('pur_in', '采购入库'), ('do_in', '生产入库'), ('other_in', '其他入库'), ('other_out', '其他出库'))", max_length=10, verbose_name='出入库类型')), + ('inout_date', models.DateField(blank=True, null=True, verbose_name='出入库日期')), + ('note', models.CharField(default='', max_length=1000, verbose_name='备注')), + ('expiration_date', models.DateField(blank=True, null=True, verbose_name='有效期')), + ('submit_time', models.DateTimeField(blank=True, null=True, verbose_name='提交时间')), + ('belong_dept', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='mio_belong_dept', to='system.dept', verbose_name='所属部门')), + ('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='mio_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')), + ('customer', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='sam.customer', verbose_name='客户')), + ('order', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='sam.order', verbose_name='关联订单')), + ('pu_order', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='pum.puorder', verbose_name='关联采购订单')), + ('supplier', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='pum.supplier', verbose_name='供应商')), + ('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='mio_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='MIOItem', + fields=[ + ('id', models.CharField(editable=False, help_text='主键ID', max_length=20, 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='删除标记')), + ('batch', models.CharField(max_length=20, verbose_name='批次号')), + ('count', models.PositiveIntegerField(default=0, verbose_name='数量')), + ('material', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='物料')), + ('mio', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='inm.mio', verbose_name='关联出入库')), + ('warehouse', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='inm.warehouse', verbose_name='仓库')), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/apps/inm/serializers.py b/apps/inm/serializers.py index 0f1d34d5..6f3c3e22 100644 --- a/apps/inm/serializers.py +++ b/apps/inm/serializers.py @@ -4,6 +4,7 @@ from apps.inm.models import WareHouse, MaterialBatch, MIO, MIOItem from apps.utils.constants import EXCLUDE_FIELDS_DEPT, EXCLUDE_FIELDS_BASE from apps.pum.models import PuOrder from rest_framework.exceptions import ValidationError +from apps.mtm.serializers import MaterialSerializer class WareHourseSerializer(CustomModelSerializer): @@ -48,4 +49,18 @@ class MIOSerializer(CustomModelSerializer): def update(self, instance, validated_data): validated_data.pop('type') - return super().update(instance, validated_data) \ No newline at end of file + return super().update(instance, validated_data) + + +class MIOItemSerializer(CustomModelSerializer): + warehouse_name = serializers.CharField(source='warehouse', read_only=True) + material_ = MaterialSerializer(source='material', read_only=True) + class Meta: + model = MIOItem + fields = '__all__' + + def create(self, validated_data): + mio = validated_data['mio'] + if mio.state != MIO.MIO_CREATE: + raise ValidationError('出入库记录非创建中不可新增') + return super().create(validated_data) diff --git a/apps/inm/urls.py b/apps/inm/urls.py index 31f4d54b..b1317764 100644 --- a/apps/inm/urls.py +++ b/apps/inm/urls.py @@ -1,6 +1,6 @@ from django.urls import path, include from rest_framework.routers import DefaultRouter -from apps.inm.views import (WarehouseVIewSet, MaterialBatchViewSet, MIOViewSet) +from apps.inm.views import (WarehouseVIewSet, MaterialBatchViewSet, MIOViewSet, MIOItemViewSet) API_BASE_URL = 'api/inm/' HTML_BASE_URL = 'inm/' @@ -9,6 +9,7 @@ router = DefaultRouter() router.register('warehouse', WarehouseVIewSet, basename='warehouse') router.register('materialbatch', MaterialBatchViewSet, basename='materialbatch') router.register('mio', MIOViewSet, basename='mio') +router.register('mioitem', MIOItemViewSet, basename='mioitem') urlpatterns = [ path(API_BASE_URL, include(router.urls)), ] \ No newline at end of file diff --git a/apps/inm/views.py b/apps/inm/views.py index 7ad3507b..66475ac0 100644 --- a/apps/inm/views.py +++ b/apps/inm/views.py @@ -7,10 +7,11 @@ from rest_framework import serializers from django.utils import timezone from rest_framework.response import Response -from apps.inm.models import WareHouse, MaterialBatch, MIO -from apps.inm.serializers import (MaterialBatchSerializer, WareHourseSerializer, MIOSerializer) +from apps.inm.models import WareHouse, MaterialBatch, MIO, MIOItem +from apps.inm.serializers import (MaterialBatchSerializer, WareHourseSerializer, MIOSerializer, MIOItemSerializer) from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet from apps.inm.services import InmService +from apps.utils.mixins import BulkCreateModelMixin, BulkDestroyModelMixin # Create your views here. @@ -79,5 +80,19 @@ class MIOViewSet(ListModelMixin, DestroyModelMixin, CustomGenericViewSet): InmService.update_inm(ins) return Response() -class MIOItemViewSet(CustomModelViewSet): - pass \ No newline at end of file +class MIOItemViewSet(ListModelMixin, BulkCreateModelMixin, BulkDestroyModelMixin, CustomGenericViewSet): + """ + list: 出入库明细 + + 出入库明细 + """ + queryset = MIOItem.objects.all() + serializer_class = MIOItemSerializer + select_related_fields = ['warehouse', 'mio', 'material'] + filterset_fields = ['warehouse', 'mio', 'material'] + ordering = ['create_time'] + + def perform_destroy(self, instance): + if instance.state != MIO.MIO_CREATE: + raise ParseError('出入库记录非创建中不可删除') + return super().perform_destroy(instance) \ No newline at end of file diff --git a/apps/pm/views.py b/apps/pm/views.py index a2e4a334..ddafc997 100644 --- a/apps/pm/views.py +++ b/apps/pm/views.py @@ -23,7 +23,7 @@ class MtaskViewSet(CustomModelViewSet): ordering_fields = ['start_date', 'process__sort'] ordering = ['process__sort', '-start_date', '-create_time'] - @action(methods=['post'], detail=True, perms_map={'post': 'mtasks.schedue'}, serializer_class=SchedueSerializer) + @action(methods=['post'], detail=False, perms_map={'post': 'mtasks.schedue'}, serializer_class=SchedueSerializer) @transaction.atomic def schedue_from_orderitems(self, request, *args, **kwargs): """从多个订单明细自动排产