from django.shortcuts import render from rest_framework import serializers from rest_framework import exceptions from rest_framework.exceptions import APIException from rest_framework.mixins import DestroyModelMixin, ListModelMixin, RetrieveModelMixin 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 FIFOItemSerializer, FIFOInPurSerializer, FIFOListSerializer, IProductListSerializer, InmTestRecordCreateSerializer, MaterialBatchQuerySerializer, MaterialBatchSerializer, WareHouseSerializer, WareHouseCreateUpdateSerializer, InventorySerializer from apps.inm.signals import update_inm from apps.mtm.models import Material from apps.pm.services import PmService from apps.qm.models import TestRecordItem from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin from rest_framework.decorators import action from rest_framework.response import Response from django.db import transaction from django.utils import timezone from apps.wpm.services import WpmServies # Create your views here. class WarehouseViewSet(CreateUpdateModelAMixin, ModelViewSet): """ 仓库-增删改查 """ perms_map = {'*': '*'} 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 = {'*': '*'} 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 = {'*': '*'} 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, DestroyModelMixin, GenericViewSet): """ 出入库记录详情表 """ perms_map = {'*': '*'} queryset = FIFOItem.objects.select_related('material', 'fifo').all() serializer_class = FIFOItemSerializer filterset_fields = ['material', 'fifo', 'fifo__type', 'is_tested', 'is_testok'] search_fields = [] ordering_fields = ['create_time'] ordering = ['-create_time'] def perform_destroy(self, instance): if instance.fifo.is_audited: raise APIException('该出入库记录已通过审核, 无法删除') return super().perform_destroy(instance) @action(methods=['post'], detail=False, perms_map={'post': '*'}, 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.is_tested = True obj.fifo_item.save() return Response() class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet): """ 出入库记录 """ perms_map = {'*': '*'} 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_submited: raise exceptions.APIException('该记录已审核,不可删除') return super().destroy(request, *args, **kwargs) @action(methods=['post'], detail=False, perms_map={'post': '*'}, 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=True, perms_map={'post': '*'}, serializer_class=serializers.Serializer) def audit(self, request, pk=None): """ 审核通过 """ obj = self.get_object() for i in FIFOItem.objects.filter(fifo=obj): if not i.is_testok: raise APIException('未检验通过, 不可审核') if obj.is_audited: raise APIException('该入库记录已审核通过') with transaction.atomic(): obj.is_audited = True obj.auditor = request.user obj.inout_date = timezone.now() # 也是审核日期 obj.save() update_inm(obj) # 更新库存 return Response() class IProductViewSet(ListModelMixin, GenericViewSet): """ 半成品库存表 """ perms_map = {'*': '*'} queryset = IProduct.objects.select_related( 'material', 'warehouse', 'wproduct__subproduction_plan__production_plan__order') serializer_class = IProductListSerializer filterset_class = IProductFilterSet search_fields = [] ordering_fields = ['create_time'] ordering = ['-create_time']