hberp/hb_server/apps/sam/views_sale.py

211 lines
8.4 KiB
Python

from rest_framework.mixins import ListModelMixin, DestroyModelMixin, CreateModelMixin, RetrieveModelMixin
from rest_framework.viewsets import GenericViewSet
from rest_framework.response import Response
from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, WareHouse
from apps.inm.services import InmService
from apps.mtm.models import Material, PackItem
from apps.sam.models import Sale, SalePack, SaleProduct
from apps.sam.serializers_sale import SRemarkItemCreateSerializer, SaleCreateSerializer, SaleListSerializer, SaleProductCreateSerializer, SaleProductListSerializer, SaleProductPackDetailSerializer, SaleProductPackSerializer
from rest_framework import exceptions
from django.db import transaction
from rest_framework.decorators import action
from django.utils import timezone
from apps.system.mixins import CreateUpdateModelAMixin
from rest_framework import serializers
from django.db.models import Count
from utils.tools import ranstr
class SaleViewSet(CreateUpdateModelAMixin, ListModelMixin, RetrieveModelMixin, CreateModelMixin, DestroyModelMixin, GenericViewSet):
"""
销售记录
"""
perms_map = {'get': '*', 'post':'sale_create', 'delete':'sale_delete'}
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 destroy(self, request, *args, **kwargs):
obj = self.get_object()
if obj.is_audited:
raise exceptions.APIException('该销售记录已审核,不可删除')
obj.delete()
IProduct.objects.filter(sale_iproduct__sale=obj).update()
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)
if vdata['count'] + vdata['order'].delivered_count > vdata['order'].count:
raise exceptions.APIException('超过订单所需数量')
sale = Sale.objects.create(**vdata)
i_l = []
for i in iproducts:
i.state = IProduct.SALE_LOCK
i.save()
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':'sale_audit'}, serializer_class=serializers.Serializer)
@transaction.atomic
def audit(self, request, pk=None):
"""
审核
"""
obj = self.get_object()
if obj.is_audited:
raise exceptions.APIException('已审核通过')
if obj.order:
if obj.count + obj.order.delivered_count > obj.order.count:
raise exceptions.APIException('超过订单所需数量')
# 创建出库记录
fifo = FIFO()
fifo.sale = obj
fifo.type = FIFO.FIFO_TYPE_SALE_OUT
fifo.is_audited = False
fifo.auditor = request.user
fifo.inout_date = timezone.now()
fifo.create_by = request.user
fifo.number = 'CK' + ranstr(7)
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)
# 更新动态产品表情况
# from apps.wpm.models import WProduct
# WProduct.objects.filter(iproduct_wproduct__sale_iproduct__sale=obj).update(
# act_state=WProduct.WPR_ACT_STATE_SELLED)
# 更新库存
# InmService.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 = {'get': '*', 'post':'sale_update', 'delete':'sale_delete'}
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('该销售记录已审核,不可删除产品')
obj.delete()
sale.count = SaleProduct.objects.filter(sale=obj.sale).count()
sale.save()
return Response()
def create(self, request, *args, **kwargs):
obj = self.get_object()
sale = obj.sale
if sale.is_audited:
raise exceptions.APIException('该销售记录已审核,不可添加产品')
return super().create(request, *args, **kwargs)
@action(methods=['get', 'post'], detail=True, perms_map={'post':'sale_pack', 'get':'*'}, serializer_class=SaleProductPackSerializer)
@transaction.atomic
def pack(self, request, pk=None):
"""
打包装箱
"""
obj = self.get_object()
if request.method == 'GET':
for i in PackItem.objects.filter(product=obj.iproduct.material, is_deleted=False):
SalePack.objects.get_or_create(sale_product=obj, packitem=i,
defaults={
"sale_product":obj,
"packitem":i,
"count":i.count
})
return Response(SaleProductPackDetailSerializer(instance=obj).data)
elif request.method == 'POST':
serializer = SaleProductPackSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
vdata = serializer.validated_data
obj.packnum = vdata['packnum']
obj.remark = vdata.get('remark', '')
for i in vdata['detail']:
pi = i['id']
pi.count = i['count']
pi.save()
obj.save()
return Response()
@action(methods=['post'], detail=True, perms_map={'post':'sale_pack'}, serializer_class=SRemarkItemCreateSerializer)
@transaction.atomic
def remark(self, request, pk=None):
"""
不装箱备注
"""
obj = self.get_object()
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
vdata = serializer.validated_data
obj.remark = vdata['remark']
obj.save()
return Response()