feat: 出入库记录新增分多个接口

This commit is contained in:
caoqianming 2023-10-11 15:16:58 +08:00
parent aff046db88
commit 9461d57159
3 changed files with 183 additions and 48 deletions

View File

@ -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)

View File

@ -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)),
]
]

View File

@ -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']