193 lines
7.5 KiB
Python
193 lines
7.5 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, SaleUpShipPicSerializer
|
|
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()
|
|
|
|
@transaction.atomic
|
|
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(state=IProduct.SALE_OK)
|
|
return Response()
|
|
|
|
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.create_by = request.user
|
|
fifo.number = 'CK' + ranstr(7)
|
|
fifo.save()
|
|
|
|
obj.is_audited = True
|
|
obj.save()
|
|
|
|
return Response()
|
|
|
|
@action(methods=['post'], detail=True, perms_map={'post':'sale_up_ship'}, serializer_class=SaleUpShipPicSerializer)
|
|
@transaction.atomic
|
|
def up_ship(self, request, pk=None):
|
|
"""
|
|
上传物流信息
|
|
"""
|
|
serializer = SaleUpShipPicSerializer(data=request.data)
|
|
serializer.is_valid(raise_exception=True)
|
|
vdata = serializer.validated_data
|
|
obj = self.get_object()
|
|
obj.ship_pic = vdata['path']
|
|
obj.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':
|
|
if not obj.sale.is_audited:
|
|
raise exceptions.APIException('该销售记录未审核,不可装箱')
|
|
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()
|
|
if obj.sale.is_audited:
|
|
raise exceptions.APIException('该销售记录已审核,不可填写备注')
|
|
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() |