236 lines
9.0 KiB
Python
236 lines
9.0 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)
|
|
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)
|
|
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)
|
|
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']
|