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.mtm.serializers import MaterialSerializer
from apps.pum.models import PuOrder from apps.pum.models import PuOrder
from apps.sam.models import Order
from apps.system.models import Dept, User 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 apps.utils.serializers import CustomModelSerializer
from .models import MIO, MaterialBatch, MIOItem, WareHouse from .models import MIO, MaterialBatch, MIOItem, WareHouse
@ -29,35 +30,51 @@ class MaterialBatchSerializer(CustomModelSerializer):
read_only_fields = EXCLUDE_FIELDS_BASE read_only_fields = EXCLUDE_FIELDS_BASE
class MIOSerializer(CustomModelSerializer): class MIOListSerializer(CustomModelSerializer):
create_by_name = serializers.CharField( create_by_name = serializers.CharField(
source='create_by.name', read_only=True) 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: class Meta:
model = MIO model = MIO
fields = '__all__' 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): # def validate(self, attrs):
if 'pu_order' in attrs and attrs['pu_order']: # if 'pu_order' in attrs and attrs['pu_order']:
attrs['supplier'] = attrs['pu_order'].supplier # attrs['supplier'] = attrs['pu_order'].supplier
elif 'order' in attrs and attrs['order']: # if attrs['pu_order'].belong_dept:
attrs['customer'] = attrs['order'].customer # attrs['belong_dept'] = attrs['pu_order'].belong_dept
return super().validate(attrs) # elif 'order' in attrs and attrs['order']:
# attrs['customer'] = attrs['order'].customer
# return super().validate(attrs)
def create(self, validated_data): # def create(self, validated_data):
type = validated_data['type'] # type = validated_data['type']
if type == MIO.MIO_TYPE_PUR_IN: # if type == MIO.MIO_TYPE_PUR_IN:
pu_order = validated_data.get('pu_order', None) # pu_order = validated_data.get('pu_order', None)
if pu_order and pu_order.state in [PuOrder.PUORDER_SUBMITED, PuOrder.PUORDER_SHIP]: # if pu_order and pu_order.state in [PuOrder.PUORDER_SUBMITED, PuOrder.PUORDER_SHIP]:
pass # pass
else: # else:
raise ValidationError('该采购订单不可选') # raise ValidationError('该采购订单不可选')
return super().create(validated_data) # return super().create(validated_data)
def update(self, instance, validated_data): # def update(self, instance, validated_data):
validated_data.pop('type') # validated_data.pop('type')
return super().update(instance, validated_data) # return super().update(instance, validated_data)
class MIOItemSerializer(CustomModelSerializer): class MIOItemSerializer(CustomModelSerializer):
@ -83,7 +100,8 @@ class MIODoSerializer(CustomModelSerializer):
class Meta: class Meta:
model = MIO 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): def create(self, validated_data):
if validated_data['type'] not in [MIO.MIO_TYPE_DO_OUT, MIO.MIO_TYPE_DO_IN]: 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) return super().create(validated_data)
def update(self, instance, validated_data): def update(self, instance, validated_data):
if instance.state != MIO.MIO_CREATE: validated_data.pop('type')
raise ValidationError('记录非创建中') 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) return super().update(instance, validated_data)

View File

@ -1,14 +1,20 @@
from django.urls import path, include from django.urls import path, include
from rest_framework.routers import DefaultRouter 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/' API_BASE_URL = 'api/inm/'
HTML_BASE_URL = 'inm/' HTML_BASE_URL = 'inm/'
router = DefaultRouter() router = DefaultRouter()
router.register('warehouse', WarehouseVIewSet, basename='warehouse') 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', 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') router.register('mioitem', MIOItemViewSet, basename='mioitem')
urlpatterns = [ urlpatterns = [
path(API_BASE_URL, include(router.urls)), 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.models import WareHouse, MaterialBatch, MIO, MIOItem
from apps.inm.serializers import ( 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.utils.viewsets import CustomGenericViewSet, CustomModelViewSet
from apps.inm.services import InmService 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. # Create your views here.
@ -46,35 +46,96 @@ class MaterialBatchViewSet(ListModelMixin, CustomGenericViewSet):
filterset_fields = ['warehouse', 'material'] 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: 出入库记录 list: 出入库记录
出入库记录 出入库记录
""" """
perms_map = {'get': '*', 'delete': 'mio.delete'}
queryset = MIO.objects.all() queryset = MIO.objects.all()
select_related_fields = ['create_by'] 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): def perform_destroy(self, instance):
if instance.state != MIO.MIO_CREATE: if instance.state != MIO.MIO_CREATE:
raise ParseError('非创建中不可删除') raise ParseError('非创建中不可删除')
return super().perform_destroy(instance) return super().perform_destroy(instance)
@action(methods=['post'], detail=False, perms_map={'post': 'mio.do'}, serializer_class=MIODoSerializer) @action(methods=['post'], detail=True, perms_map={'post': 'mio.submit'}, serializer_class=serializers.Serializer)
@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)
@transaction.atomic @transaction.atomic
def submit(self, request, *args, **kwargs): def submit(self, request, *args, **kwargs):
"""提交 """提交
@ -82,9 +143,8 @@ class MIOViewSet(ListModelMixin, DestroyModelMixin, CustomGenericViewSet):
提交 提交
""" """
ins = self.get_object() ins = self.get_object()
user = request.user if ins.inout_date is None:
if ins.state != MIO.MIO_TYPE_DO_OUT and ins.create_by != user: raise ParseError('出入库日期未填写')
raise PermissionDenied('非创建人不可提交')
if ins.state != MIO.MIO_CREATE: if ins.state != MIO.MIO_CREATE:
raise ParseError('记录状态异常') raise ParseError('记录状态异常')
ins.submit_time = timezone.now() ins.submit_time = timezone.now()
@ -101,6 +161,7 @@ class MIOItemViewSet(ListModelMixin, BulkCreateModelMixin, BulkDestroyModelMixin
出入库明细 出入库明细
""" """
perms_map = {'get': '*', 'post': '*', 'delete': '*'}
queryset = MIOItem.objects.all() queryset = MIOItem.objects.all()
serializer_class = MIOItemSerializer serializer_class = MIOItemSerializer
select_related_fields = ['warehouse', 'mio', 'material'] select_related_fields = ['warehouse', 'mio', 'material']