222 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			222 lines
		
	
	
		
			8.4 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, 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=True, perms_map={'post': 'fifo_audit'}, serializer_class=serializers.Serializer)
 | 
						|
    def audit(self, request, pk=None):
 | 
						|
        """
 | 
						|
        审核通过
 | 
						|
        """
 | 
						|
        obj = self.get_object()
 | 
						|
        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('未检验通过, 不可审核')
 | 
						|
        if obj.is_audited:
 | 
						|
            raise APIException('该入库记录已审核通过')
 | 
						|
        with transaction.atomic():
 | 
						|
            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']
 |