hberp/hb_server/apps/sam/views.py

207 lines
7.8 KiB
Python

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.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct
from apps.inm.signals import update_inm
from apps.sam.serializers import ContractCreateUpdateSerializer, ContractSerializer, CustomerCreateUpdateSerializer, CustomerSerializer, OrderCreateUpdateSerializer, OrderSerializer, SaleCreateSerializer, SaleListSerializer, SaleProductCreateSerializer, SaleProductListSerializer, SaleProductMtestSerializer
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
# 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_fields = []
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_fields = ['product', 'contract', 'customer']
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.save()
# 出库条目
spds = SaleProduct.objects.filter(sale=obj)
for i in spds:
if i.is_mtested and i.is_mtestok:
pass
else:
raise exceptions.APIException('存在未军检产品')
# 创建出库条目
ips = IProduct.objects.filter(sale_iproduct__sale=obj)
items = ips.values('warehouse', 'material', 'batch').annotate(total=Count('id'))
for i in items:
fifoitem = FIFOItem()
fifoitem.is_tested = True
fifoitem.is_testok = True
fifoitem.warehouse = i['warehouse']
fifoitem.material = i['material']
fifoitem.count = i['total']
fifoitem.batch = i['batch']
fifoitem.fifo = fifo
fifoitem.save()
items_p = ips.filter(warehouse=i['warehouse'], batch=i['batch'])
ips = []
for i in items_p:
# 创建入库明细半成品
ip = {}
ip['fifoitem'] = fifoitem
ip['number'] = i.number
ip['material'] = i.material
ip['iproduct'] = i
ips.append(FIFOItemProduct(**ip))
FIFOItemProduct.objects.bulk_create(ips)
# 更新库存
update_inm(fifo)
# 更新成品库情况
ips.update(is_saled=True)
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()
obj.sale.count = SaleProduct.objects.filter(sale=obj.sale).count()
obj.sale.save()
obj.delete()
return Response()
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=SaleProductMtestSerializer)
def mtest(self, request, pk=None):
"""
军检
"""
obj = self.get_object()
if obj.is_mtested:
raise exceptions.APIException('已进行军检')
obj.remark = request.data.get('remark', None)
obj.is_mtested = True
obj.is_mtestok = request.data.get('is_mtestok')
obj.save()
return Response()