hberp/hb_server/apps/inm/views.py

239 lines
9.1 KiB
Python

from rest_framework import serializers
from rest_framework import exceptions
from rest_framework.exceptions import APIException, ValidationError
from rest_framework.mixins import DestroyModelMixin, ListModelMixin, UpdateModelMixin, CreateModelMixin
from rest_framework.viewsets import GenericViewSet, ModelViewSet
from apps.inm.filters import IProductFilterSet, MbFilterSet
from apps.inm.models import FIFO, FIFOItem, IProduct, MaterialBatch, WareHouse, Inventory
from apps.inm.serializers import FIFOInOtherSerializer, FIFOItemCreateSerializer, FIFOItemSerializer, FIFOInPurSerializer, FIFOItemUpdateSerializer, FIFOListSerializer, FIFOOutOtherSerializer, IProductListSerializer, \
InmTestRecordCreateSerializer, MaterialBatchQuerySerializer, MaterialBatchSerializer, WareHouseSerializer, \
WareHouseCreateUpdateSerializer, InventorySerializer
from apps.inm.services import InmService
from apps.qm.models import TestRecordItem
from apps.system.mixins import CreateUpdateModelAMixin
from rest_framework.decorators import action
from rest_framework.response import Response
from django.db import transaction
from django.utils import timezone
# Create your views here.
class WarehouseViewSet(CreateUpdateModelAMixin, ModelViewSet):
"""
仓库-增删改查
"""
perms_map = {'get': '*', 'post':'warehouse_create',
'put':'warehouse_update', 'delete':'warehouse_delete'}
queryset = WareHouse.objects.select_related('create_by').all()
serializer_class = WareHouseSerializer
search_fields = ['name', 'number', 'place']
filterset_fields = []
ordering_fields = ['create_time']
ordering = ['-create_time']
def get_serializer_class(self):
if self.action in ['create', 'update']:
return WareHouseCreateUpdateSerializer
return WareHouseSerializer
class InventoryViewSet(ListModelMixin, GenericViewSet):
"""
仓库物料表
"""
perms_map = {'get': '*'}
queryset = Inventory.objects.select_related(
'material', 'warehouse').filter(count__gt=0).all()
serializer_class = InventorySerializer
filterset_fields = ['material', 'warehouse']
search_fields = []
ordering_fields = ['create_time']
ordering = ['-create_time']
class MaterialBatchViewSet(ListModelMixin, GenericViewSet):
perms_map = {'get': '*'}
queryset = MaterialBatch.objects.select_related(
'material', 'warehouse').filter(count__gt=0).all()
serializer_class = MaterialBatchSerializer
# filterset_fields = ['material', 'warehouse']
filterset_class = MbFilterSet
search_fields = []
ordering_fields = ['create_time']
ordering = ['-create_time']
@action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=MaterialBatchQuerySerializer)
def query(self, request, pk=None):
"""
复杂查询
"""
data = request.data
serializer = MaterialBatchQuerySerializer(data=data)
serializer.is_valid(raise_exception=True)
queryset = self.queryset.filter(
warehouse__id=data['warehouse'], material__id__in=data['materials'])
return Response(MaterialBatchSerializer(instance=queryset, many=True).data)
class FIFOItemViewSet(ListModelMixin, CreateModelMixin, DestroyModelMixin, UpdateModelMixin, GenericViewSet):
"""
出入库记录详情表
"""
perms_map = {'get': '*', 'post':'fifoitem_create',
'put':'fifoitem_update', 'delete':'fifoitem_delete'}
queryset = FIFOItem.objects.select_related('material', 'fifo').prefetch_related('files').all()
serializer_class = FIFOItemSerializer
filterset_fields = ['material', 'fifo',
'fifo__type', 'need_test', 'is_testok']
search_fields = []
ordering_fields = ['create_time']
ordering = ['-create_time']
def get_serializer_class(self):
if self.action == 'update':
return FIFOItemUpdateSerializer
elif self.action == 'create':
return FIFOItemCreateSerializer
return super().get_serializer_class()
def update(self, request, *args, **kwargs):
obj = self.get_object()
if obj.fifo.is_audited:
raise ValidationError('该出入库记录已审核')
return super().update(request, *args, **kwargs)
def destroy(self, request, *args, **kwargs):
obj = self.get_object()
if obj.fifo.is_audited:
raise ValidationError('该出入库记录已审核')
return super().destroy(request, *args, **kwargs)
@action(methods=['post'], detail=False, perms_map={'post': 'fifoitem_test'}, serializer_class=InmTestRecordCreateSerializer)
def test(self, request, pk=None):
"""
检验
"""
serializer = InmTestRecordCreateSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
vdata = serializer.validated_data
record_data = vdata.pop('record_data')
if 'is_testok' not in vdata:
raise APIException('未填写检验结论')
with transaction.atomic():
obj = serializer.save(create_by=self.request.user)
tris = []
for m in record_data: # 保存记录详情
m['field_value'] = m['field_value']
m['is_testok'] = m['is_testok'] if 'is_testok' in m else True
m['test_record'] = obj
tris.append(TestRecordItem(**m))
TestRecordItem.objects.bulk_create(tris)
# 如果检验合格
if obj.fifo_item:
obj.fifo_item.is_testok = True if obj.is_testok else False
obj.fifo_item.save()
return Response()
class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
"""
出入库记录
"""
perms_map = {'get': '*', 'delete':'fifo_delete'}
queryset = FIFO.objects.select_related('auditor', 'create_by')
serializer_class = FIFOListSerializer
filterset_fields = '__all__'
ordering_fields = '__all__'
search_fields = []
ordering = ['-pk']
def get_serializer_class(self):
if self.action == 'list':
return FIFOListSerializer
return super().get_serializer_class()
def destroy(self, request, *args, **kwargs):
obj = self.get_object()
if obj.is_audited:
raise exceptions.APIException('该记录已审核,不可删除')
return super().destroy(request, *args, **kwargs)
@action(methods=['post'], detail=False, perms_map={'post': 'fifo_in_pur'}, serializer_class=FIFOInPurSerializer)
@transaction.atomic()
def in_pur(self, request, pk=None):
"""
采购入库
"""
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save(create_by=request.user)
return Response()
@action(methods=['post'], detail=False, perms_map={'post': 'fifo_in_other'},
serializer_class=FIFOInOtherSerializer)
@transaction.atomic()
def in_other(self, request, pk=None):
"""
其他入库
"""
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save(create_by=request.user)
return Response()
@action(methods=['post'], detail=False, perms_map={'post': 'fifo_out_other'},
serializer_class=FIFOOutOtherSerializer)
@transaction.atomic()
def out_other(self, request, pk=None):
"""
其他出库
"""
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save(create_by=request.user)
return Response()
@action(methods=['post'], detail=True, perms_map={'post': 'fifo_audit'}, serializer_class=serializers.Serializer)
@transaction.atomic
def audit(self, request, pk=None):
"""
审核通过
"""
obj = self.get_object()
if obj.is_audited:
raise APIException('该入库记录已审核通过')
if obj.type == FIFO.FIFO_TYPE_SALE_OUT: # 如果是销售提货,需额外处理
InmService.sale_out_audit(obj)
else:
if not FIFOItem.objects.filter(fifo=obj).exists():
raise ValidationError('出入库条目为空')
for i in FIFOItem.objects.filter(fifo=obj, need_test=True):
if not i.is_testok:
raise APIException('未检验通过, 不可审核')
obj.is_audited = True
obj.auditor = request.user
obj.inout_date = timezone.now() # 也是审核日期
obj.save()
InmService.update_inm(obj) # 更新库存
return Response()
class IProductViewSet(ListModelMixin, GenericViewSet):
"""
半成品库存表
"""
perms_map = {'get': '*'}
queryset = IProduct.objects.select_related(
'material', 'warehouse',
'wproduct__subproduction_plan__production_plan__order',
'wproduct__to_order')
serializer_class = IProductListSerializer
filterset_class = IProductFilterSet
search_fields = []
ordering_fields = ['create_time']
ordering = ['-create_time']