From 9461d57159e852054f10761d626cdaf9d581cd55 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Wed, 11 Oct 2023 15:16:58 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=87=BA=E5=85=A5=E5=BA=93=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E6=96=B0=E5=A2=9E=E5=88=86=E5=A4=9A=E4=B8=AA=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/inm/serializers.py | 116 +++++++++++++++++++++++++++++++--------- apps/inm/urls.py | 12 +++-- apps/inm/views.py | 103 +++++++++++++++++++++++++++-------- 3 files changed, 183 insertions(+), 48 deletions(-) diff --git a/apps/inm/serializers.py b/apps/inm/serializers.py index 8ef9eeb5..e28faa70 100644 --- a/apps/inm/serializers.py +++ b/apps/inm/serializers.py @@ -3,8 +3,9 @@ from rest_framework.exceptions import ValidationError from apps.mtm.serializers import MaterialSerializer from apps.pum.models import PuOrder +from apps.sam.models import Order from apps.system.models import Dept, User -from apps.utils.constants import EXCLUDE_FIELDS_BASE, EXCLUDE_FIELDS_DEPT +from apps.utils.constants import EXCLUDE_FIELDS_BASE, EXCLUDE_FIELDS_DEPT, EXCLUDE_FIELDS from apps.utils.serializers import CustomModelSerializer from .models import MIO, MaterialBatch, MIOItem, WareHouse @@ -29,35 +30,51 @@ class MaterialBatchSerializer(CustomModelSerializer): read_only_fields = EXCLUDE_FIELDS_BASE -class MIOSerializer(CustomModelSerializer): +class MIOListSerializer(CustomModelSerializer): create_by_name = serializers.CharField( source='create_by.name', read_only=True) + submit_user_name = serializers.CharField( + source='submit_user.name', read_only=True) + do_user_name = serializers.CharField( + source='do_user.name', read_only=True) + belong_dept_name = serializers.CharField( + source='belong_dept.name', read_only=True) + supllier_name = serializers.CharField( + source='supplier.name', read_only=True) + customer_name = serializers.CharField( + source='customer.name', read_only=True) + order_number = serializers.CharField(source='order.number', read_only=True) + pu_order_number = serializers.CharField( + source='pu_order.name', read_only=True) class Meta: model = MIO fields = '__all__' - read_only_fields = EXCLUDE_FIELDS_DEPT + ['state', 'submit_time'] + read_only_fields = EXCLUDE_FIELDS + \ + ['state', 'submit_time', 'submit_user'] - def validate(self, attrs): - if 'pu_order' in attrs and attrs['pu_order']: - attrs['supplier'] = attrs['pu_order'].supplier - elif 'order' in attrs and attrs['order']: - attrs['customer'] = attrs['order'].customer - return super().validate(attrs) + # def validate(self, attrs): + # if 'pu_order' in attrs and attrs['pu_order']: + # attrs['supplier'] = attrs['pu_order'].supplier + # if attrs['pu_order'].belong_dept: + # attrs['belong_dept'] = attrs['pu_order'].belong_dept + # elif 'order' in attrs and attrs['order']: + # attrs['customer'] = attrs['order'].customer + # return super().validate(attrs) - def create(self, validated_data): - type = validated_data['type'] - if type == MIO.MIO_TYPE_PUR_IN: - pu_order = validated_data.get('pu_order', None) - if pu_order and pu_order.state in [PuOrder.PUORDER_SUBMITED, PuOrder.PUORDER_SHIP]: - pass - else: - raise ValidationError('该采购订单不可选') - return super().create(validated_data) + # def create(self, validated_data): + # type = validated_data['type'] + # if type == MIO.MIO_TYPE_PUR_IN: + # pu_order = validated_data.get('pu_order', None) + # if pu_order and pu_order.state in [PuOrder.PUORDER_SUBMITED, PuOrder.PUORDER_SHIP]: + # pass + # else: + # raise ValidationError('该采购订单不可选') + # return super().create(validated_data) - def update(self, instance, validated_data): - validated_data.pop('type') - return super().update(instance, validated_data) + # def update(self, instance, validated_data): + # validated_data.pop('type') + # return super().update(instance, validated_data) class MIOItemSerializer(CustomModelSerializer): @@ -83,7 +100,8 @@ class MIODoSerializer(CustomModelSerializer): class Meta: model = MIO - fields = ['number', 'note', 'do_user', 'belong_dept', 'type'] + fields = ['id', 'number', 'note', 'do_user', + 'belong_dept', 'type', 'inout_date'] def create(self, validated_data): if validated_data['type'] not in [MIO.MIO_TYPE_DO_OUT, MIO.MIO_TYPE_DO_IN]: @@ -91,6 +109,56 @@ class MIODoSerializer(CustomModelSerializer): return super().create(validated_data) def update(self, instance, validated_data): - if instance.state != MIO.MIO_CREATE: - raise ValidationError('记录非创建中') + validated_data.pop('type') + return super().update(instance, validated_data) + + +class MIOSaleSerializer(CustomModelSerializer): + order = serializers.PrimaryKeyRelatedField( + label="订单", queryset=Order.objects.all(), required=True) + + class Meta: + model = MIO + fields = ['id', 'number', 'note', 'order', 'inout_date'] + + def create(self, validated_data): + validated_data['type'] = MIO.MIO_TYPE_SALE_OUT + order = validated_data['order'] + validated_data['customer'] = order.customer + if order.belong_dept: + validated_data['belong_dept'] = order.belong_dept + return super().create(validated_data) + + +class MIOPurSerializer(CustomModelSerializer): + pu_order = serializers.PrimaryKeyRelatedField( + label="采购订单", queryset=PuOrder.objects.all(), required=True) + + class Meta: + model = MIO + fields = ['id', 'number', 'note', 'pu_order', 'inout_date'] + + def create(self, validated_data): + validated_data['type'] = MIO.MIO_TYPE_PUR_IN + pu_order = validated_data['pu_order'] + validated_data['supplier'] = pu_order.supplier + if pu_order.belong_dept: + validated_data['belong_dept'] = pu_order.belong_dept + return super().create(validated_data) + + +class MIOOtherSerializer(CustomModelSerializer): + + class Meta: + model = MIO + fields = ['id', 'number', 'note', 'supplier', + 'customer', 'type', 'inout_date'] + + def create(self, validated_data): + if validated_data['type'] not in [MIO.MIO_TYPE_OTHER_OUT, MIO.MIO_TYPE_OTHER_IN]: + raise ValidationError('出入库类型错误') + return super().create(validated_data) + + def update(self, instance, validated_data): + validated_data.pop('type') return super().update(instance, validated_data) diff --git a/apps/inm/urls.py b/apps/inm/urls.py index b1317764..e4e0656a 100644 --- a/apps/inm/urls.py +++ b/apps/inm/urls.py @@ -1,15 +1,21 @@ from django.urls import path, include from rest_framework.routers import DefaultRouter -from apps.inm.views import (WarehouseVIewSet, MaterialBatchViewSet, MIOViewSet, MIOItemViewSet) +from apps.inm.views import ( + WarehouseVIewSet, MaterialBatchViewSet, MIOViewSet, MIOItemViewSet, MioDoViewSet, MioSaleViewSet, MioPurViewSet, MioOtherViewSet) API_BASE_URL = 'api/inm/' HTML_BASE_URL = 'inm/' router = DefaultRouter() router.register('warehouse', WarehouseVIewSet, basename='warehouse') -router.register('materialbatch', MaterialBatchViewSet, basename='materialbatch') +router.register('materialbatch', MaterialBatchViewSet, + basename='materialbatch') router.register('mio', MIOViewSet, basename='mio') +router.register('mio/do', MioDoViewSet) +router.register('mio/sale', MioSaleViewSet) +router.register('mio/pur', MioPurViewSet) +router.register('mio/other', MioOtherViewSet) 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 6fda8d58..0ae1b40d 100644 --- a/apps/inm/views.py +++ b/apps/inm/views.py @@ -9,10 +9,10 @@ from rest_framework.response import Response from apps.inm.models import WareHouse, MaterialBatch, MIO, MIOItem from apps.inm.serializers import ( - MaterialBatchSerializer, WareHourseSerializer, MIOSerializer, MIOItemSerializer, MIODoSerializer) + MaterialBatchSerializer, WareHourseSerializer, MIOListSerializer, MIOItemSerializer, MIODoSerializer, MIOSaleSerializer, MIOPurSerializer, MIOOtherSerializer) from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet from apps.inm.services import InmService -from apps.utils.mixins import BulkCreateModelMixin, BulkDestroyModelMixin +from apps.utils.mixins import BulkCreateModelMixin, BulkDestroyModelMixin, BulkUpdateModelMixin # Create your views here. @@ -46,35 +46,96 @@ class MaterialBatchViewSet(ListModelMixin, CustomGenericViewSet): filterset_fields = ['warehouse', 'material'] -class MIOViewSet(ListModelMixin, DestroyModelMixin, CustomGenericViewSet): +class MioDoViewSet(BulkCreateModelMixin, BulkUpdateModelMixin, CustomGenericViewSet): + perms_map = {'post': '*', 'put': 'mio.do'} + queryset = MIO.objects.filter( + type__in=[MIO.MIO_TYPE_DO_IN, MIO.MIO_TYPE_DO_OUT]) + serializer_class = MIODoSerializer + + def create(self, request, *args, **kwargs): + """ + 生产领料/入库 + + 生产领料/入库 + """ + return super().create(request, *args, **kwargs) + + +class MioSaleViewSet(BulkCreateModelMixin, BulkUpdateModelMixin, CustomGenericViewSet): + perms_map = {'post': '*', 'put': 'mio.sale'} + queryset = MIO.objects.filter( + type__in=[MIO.MIO_TYPE_DO_IN, MIO.MIO_TYPE_DO_OUT]) + serializer_class = MIOSaleSerializer + + def create(self, request, *args, **kwargs): + """ + 销售出库 + + 销售出库 + """ + return super().create(request, *args, **kwargs) + + +class MioPurViewSet(BulkCreateModelMixin, BulkUpdateModelMixin, CustomGenericViewSet): + perms_map = {'post': '*', 'put': 'mio.pur'} + queryset = MIO.objects.filter( + type__in=[MIO.MIO_TYPE_PUR_IN]) + serializer_class = MIOPurSerializer + + def create(self, request, *args, **kwargs): + """ + 采购入库 + + 采购入库 + """ + return super().create(request, *args, **kwargs) + + +class MioOtherViewSet(BulkCreateModelMixin, BulkUpdateModelMixin, CustomGenericViewSet): + perms_map = {'post': '*', 'put': 'mio.other'} + queryset = MIO.objects.filter( + type__in=[MIO.MIO_TYPE_OTHER_OUT, MIO.MIO_TYPE_OTHER_IN]) + serializer_class = MIOOtherSerializer + + def create(self, request, *args, **kwargs): + """ + 其他出入库 + + 其他出入库 + """ + return super().create(request, *args, **kwargs) + + +class MIOViewSet(ListModelMixin, BulkCreateModelMixin, BulkUpdateModelMixin, DestroyModelMixin, CustomGenericViewSet): """ list: 出入库记录 出入库记录 """ - perms_map = {'get': '*', 'delete': 'mio.delete'} queryset = MIO.objects.all() select_related_fields = ['create_by'] - serializer_class = MIOSerializer + serializer_class = MIOListSerializer + filterset_fields = ['state', 'type', 'pu_order', 'order'] + + def get_serializer(self, *args, **kwargs): + if self.action in ['create', 'update', 'partial_update']: + type = self.request.data.get('type') + if type in [MIO.MIO_TYPE_DO_IN, MIO.MIO_TYPE_DO_OUT]: + return MIODoSerializer(*args, **kwargs) + elif type in [MIO.MIO_TYPE_OTHER_IN, MIO.MIO_TYPE_OTHER_OUT]: + return MIOOtherSerializer(*args, **kwargs) + elif type == MIO.MIO_TYPE_SALE_OUT: + return MIOSaleSerializer(*args, **kwargs) + elif type == MIO.MIO_TYPE_PUR_IN: + return MIOPurSerializer(*args, **kwargs) + return super().get_serializer(*args, **kwargs) def perform_destroy(self, instance): if instance.state != MIO.MIO_CREATE: raise ParseError('非创建中不可删除') return super().perform_destroy(instance) - @action(methods=['post'], detail=False, perms_map={'post': 'mio.do'}, serializer_class=MIODoSerializer) - @transaction.atomic - def do(self, request, *args, **kwargs): - """创建生产领料/生产入库 - - 创建生产领料/生产入库 - """ - sr = MIODoSerializer(data=request.data) - sr.is_valid(raise_exception=True) - sr.save() - return Response() - - @action(methods=['post'], detail=True, perms_map={'post': 'mio.update'}, serializer_class=serializers.Serializer) + @action(methods=['post'], detail=True, perms_map={'post': 'mio.submit'}, serializer_class=serializers.Serializer) @transaction.atomic def submit(self, request, *args, **kwargs): """提交 @@ -82,9 +143,8 @@ class MIOViewSet(ListModelMixin, DestroyModelMixin, CustomGenericViewSet): 提交 """ ins = self.get_object() - user = request.user - if ins.state != MIO.MIO_TYPE_DO_OUT and ins.create_by != user: - raise PermissionDenied('非创建人不可提交') + if ins.inout_date is None: + raise ParseError('出入库日期未填写') if ins.state != MIO.MIO_CREATE: raise ParseError('记录状态异常') ins.submit_time = timezone.now() @@ -101,6 +161,7 @@ class MIOItemViewSet(ListModelMixin, BulkCreateModelMixin, BulkDestroyModelMixin 出入库明细 """ + perms_map = {'get': '*', 'post': '*', 'delete': '*'} queryset = MIOItem.objects.all() serializer_class = MIOItemSerializer select_related_fields = ['warehouse', 'mio', 'material']