from django.db import transaction from django.db.models.aggregates import Count from rest_framework import exceptions, serializers from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, ListModelMixin, RetrieveModelMixin from apps.mtm.models import Material from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, WareHouse from apps.inm.signals import update_inm from apps.sam.filters import ContractFilterSet, OrderFilterSet from apps.sam.serializers import ContractCreateUpdateSerializer, ContractSerializer, CustomerCreateUpdateSerializer, CustomerSerializer, OrderCreateUpdateSerializer, OrderSerializer, SaleCreateSerializer, SaleListSerializer, SaleProductCreateSerializer, SaleProductListSerializer from apps.sam.models import Contract, Customer, Order, Sale, SaleProduct from rest_framework.viewsets import GenericViewSet, ModelViewSet from apps.system.mixins import CreateUpdateCustomMixin from django.shortcuts import render from rest_framework.decorators import action from django.db.models import F from rest_framework.response import Response from django.utils import timezone from apps.wf.models import Workflow # Create your views here. class CustomerViewSet(CreateUpdateCustomMixin, ModelViewSet): """ 客户-增删改查 """ perms_map = {'*': '*'} queryset = Customer.objects.all() serializer_class = CustomerSerializer search_fields = ['name', 'contact'] filterset_fields = [] ordering_fields = ['create_time'] ordering = ['-create_time'] def get_serializer_class(self): if self.action in ['create', 'update']: return CustomerCreateUpdateSerializer return CustomerSerializer class ContractViewSet(CreateUpdateCustomMixin, ModelViewSet): """ 合同-增删改查 """ perms_map = {'*': '*'} queryset = Contract.objects.select_related('customer').all() serializer_class = ContractSerializer search_fields = ['name'] filterset_class = ContractFilterSet ordering_fields = ['create_time'] ordering = ['-create_time'] def get_serializer_class(self): if self.action in ['create', 'update']: return ContractCreateUpdateSerializer return ContractSerializer class OrderViewSet(CreateUpdateCustomMixin, ModelViewSet): """ 订单-增删改查 """ perms_map = {'*': '*'} queryset = Order.objects.select_related('contract', 'customer').all() serializer_class = OrderSerializer search_fields = ['number', 'product'] filterset_class = OrderFilterSet ordering_fields = ['create_time'] ordering = ['-create_time'] def get_serializer_class(self): if self.action in ['create', 'update']: return OrderCreateUpdateSerializer return super().get_serializer_class() @action(methods=['get'], detail=False, perms_map={'get':'*'}) def toplan(self, request, pk=None): queryset = Order.objects.filter(count__gt=F('planed_count')).order_by('-id') page = self.paginate_queryset(queryset) if page is not None: serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) serializer = self.get_serializer(queryset, many=True) return Response(serializer.data) class SaleViewSet(CreateUpdateCustomMixin, ListModelMixin, RetrieveModelMixin, CreateModelMixin, DestroyModelMixin, GenericViewSet): """ 销售记录 """ perms_map = {'*': '*'} queryset = Sale.objects.select_related('customer', 'order', 'product', 'order__contract').all() serializer_class = SaleListSerializer search_fields = ['customer__name', 'order__number'] filterset_fields = ['product', 'order', 'customer'] ordering_fields = ['create_time'] ordering = ['-create_time'] def get_serializer_class(self): if self.action == 'create': return SaleCreateSerializer elif self.action == 'retrieve': return SaleListSerializer return super().get_serializer_class() def create(self, request, *args, **kwargs): data = request.data serializer = SaleCreateSerializer(data=data) serializer.is_valid(raise_exception=True) vdata = serializer.validated_data with transaction.atomic(): iproducts = vdata.pop('iproducts') vdata['count'] = len(iproducts) sale = Sale.objects.create(**vdata) i_l = [] for i in iproducts: i_d ={} i_d['sale'] = sale i_d['number'] = i.number i_d['iproduct'] = i i_l.append(SaleProduct(**i_d)) SaleProduct.objects.bulk_create(i_l) return Response() @action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=serializers.Serializer) @transaction.atomic def audit(self, request, pk=None): """ 审核 """ obj = self.get_object() if obj.is_audited: raise exceptions.APIException('已审核通过') # 创建出库记录 fifo = FIFO() fifo.type = FIFO.FIFO_TYPE_SALE_OUT fifo.is_audited = True fifo.auditor = request.user fifo.inout_date = timezone.now() fifo.create_by = request.user fifo.save() # 创建出库条目 ips = IProduct.objects.filter(sale_iproduct__sale=obj) items = ips.values('warehouse', 'material', 'batch').annotate(total=Count('id')) for i in items: warehouse = WareHouse.objects.get(id=i['warehouse']) material = Material.objects.get(id=i['material']) fifoitem = FIFOItem() fifoitem.need_test = False fifoitem.warehouse = warehouse fifoitem.material = material fifoitem.count = i['total'] fifoitem.batch = i['batch'] fifoitem.fifo = fifo fifoitem.save() items_p = ips.filter(warehouse=warehouse, batch=i['batch']) ipxs = [] for i in items_p: # 创建出库明细半成品 ip = {} ip['fifoitem'] = fifoitem ip['number'] = i.number ip['material'] = i.material ip['iproduct'] = i ipxs.append(FIFOItemProduct(**ip)) FIFOItemProduct.objects.bulk_create(ipxs) # 更新成品库情况 ips.update(is_saled=True) # 更新动态产品表情况 from apps.wpm.models import WProduct WProduct.objects.filter(iproduct_wproduct__sale_iproduct__sale=obj).update( act_state=WProduct.WPR_ACT_STATE_SELLED) # 更新库存 update_inm(fifo) # 变更审核状态 obj.is_audited = True obj.save() # 变更订单状态 if obj.order: order = obj.order order.delivered_count = order.delivered_count + obj.count order.save() return Response() class SaleProductViewSet(ListModelMixin, DestroyModelMixin, CreateModelMixin, GenericViewSet): """ 销售记录关联产品 """ perms_map = {'*': '*'} queryset = SaleProduct.objects.select_related('iproduct', 'iproduct__material', 'iproduct__warehouse').all() serializer_class = SaleProductListSerializer search_fields = [] filterset_fields = ['sale', 'iproduct'] ordering_fields = ['create_time'] ordering = ['id'] def get_serializer_class(self): if self.action == 'create': return SaleProductCreateSerializer return super().get_serializer_class() def destroy(self, request, *args, **kwargs): obj = self.get_object() sale = obj.sale if sale.is_audited: raise exceptions.APIException('该销售记录已审核,不可删除产品') sale.count = SaleProduct.objects.filter(sale=obj.sale).count() sale.save() obj.delete() return Response()