iproduct list增加order to_order 字段
This commit is contained in:
parent
04b864e72f
commit
9eab3aa592
|
@ -3,7 +3,7 @@ from django_filters import rest_framework as filters
|
|||
from apps.mtm.models import Material
|
||||
from .models import IProduct, MaterialBatch
|
||||
from django.utils import timezone
|
||||
|
||||
from utils.mixins import DynamicFieldsFilterMixin
|
||||
|
||||
class MbFilterSet(filters.FilterSet):
|
||||
material = filters.ModelMultipleChoiceFilter(field_name="material", queryset=Material.objects.all())
|
||||
|
@ -20,7 +20,7 @@ class MbFilterSet(filters.FilterSet):
|
|||
return queryset
|
||||
|
||||
|
||||
class IProductFilterSet(filters.FilterSet):
|
||||
class IProductFilterSet(DynamicFieldsFilterMixin, filters.FilterSet):
|
||||
order = filters.NumberFilter(field_name="wproduct__subproduction_plan__production_plan__order")
|
||||
to_order = filters.NumberFilter(field_name="wproduct__to_order")
|
||||
update_time_start = filters.DateFilter(field_name="update_time", lookup_expr='gte')
|
||||
|
|
|
@ -3,11 +3,13 @@ from rest_framework import serializers
|
|||
|
||||
from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, MaterialBatch, WareHouse, Inventory
|
||||
from apps.qm.models import TestRecord, TestRecordItem
|
||||
from apps.sam.serializers import OrderSimpleSerializer
|
||||
|
||||
|
||||
from apps.system.serializers import FileSimpleSerializer, UserSimpleSerializer
|
||||
from apps.mtm.serializers import MaterialSimpleSerializer
|
||||
from django.db import transaction
|
||||
from utils.mixins import DynamicFieldsSerializerMixin
|
||||
|
||||
|
||||
|
||||
|
@ -49,12 +51,15 @@ class MaterialBatchSerializer(serializers.ModelSerializer):
|
|||
fields = '__all__'
|
||||
|
||||
|
||||
class IProductListSerializer(serializers.ModelSerializer):
|
||||
class IProductListSerializer(DynamicFieldsSerializerMixin, serializers.ModelSerializer):
|
||||
material_ = MaterialSimpleSerializer(source='material', read_only=True)
|
||||
warehouse_ = WareHouseSimpleSerializer(source='warehouse', read_only=True)
|
||||
need_to_order = serializers.BooleanField(source='wproduct.need_to_order', read_only=True)
|
||||
is_mtestok = serializers.BooleanField(source='wproduct.is_mtestok', read_only=True)
|
||||
remark_mtest = serializers.CharField(source='wproduct.remark_mtest', read_only=True)
|
||||
to_order_ = OrderSimpleSerializer(source='wproduct.to_order', read_only=True)
|
||||
order_ = OrderSimpleSerializer(
|
||||
source='wproduct.subproduction_plan.production_plan.order', read_only=True)
|
||||
class Meta:
|
||||
model = IProduct
|
||||
fields = '__all__'
|
||||
|
|
|
@ -187,7 +187,9 @@ class IProductViewSet(ListModelMixin, GenericViewSet):
|
|||
"""
|
||||
perms_map = {'*': '*'}
|
||||
queryset = IProduct.objects.select_related(
|
||||
'material', 'warehouse', 'wproduct__subproduction_plan__production_plan__order')
|
||||
'material', 'warehouse',
|
||||
'wproduct__subproduction_plan__production_plan__order',
|
||||
'wproduct__to_order')
|
||||
serializer_class = IProductListSerializer
|
||||
filterset_class = IProductFilterSet
|
||||
search_fields = []
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
from django.db import transaction
|
||||
from rest_framework import exceptions, serializers
|
||||
|
||||
from apps.inm.models import IProduct
|
||||
from apps.inm.serializers import IProductListSerializer
|
||||
from rest_framework import serializers
|
||||
|
||||
from .models import Contract, Customer, Order, Sale, SaleProduct
|
||||
from .models import Contract, Customer, Order
|
||||
|
||||
from apps.mtm.serializers import MaterialSimpleSerializer
|
||||
from utils.tools import ranstr
|
||||
|
@ -65,47 +62,3 @@ class OrderSimpleSerializer(serializers.ModelSerializer):
|
|||
model = Order
|
||||
fields = ['id', 'number', 'contract_', 'customer_', 'need_mtest', 'delivery_date']
|
||||
|
||||
class SaleCreateSerializer(serializers.ModelSerializer):
|
||||
iproducts = serializers.PrimaryKeyRelatedField(queryset=
|
||||
IProduct.objects.all(), many=True)
|
||||
class Meta:
|
||||
model = Sale
|
||||
fields = ['customer', 'order', 'product', 'iproducts']
|
||||
|
||||
def validate(self, attrs):
|
||||
order = attrs.get('order', None)
|
||||
if order:
|
||||
if order.customer:
|
||||
attrs['customer'] = order.customer
|
||||
attrs['product'] = order.product
|
||||
for i in attrs['iproducts']:
|
||||
if i.material != attrs['product']:
|
||||
raise exceptions.APIException('产品选取错误')
|
||||
return super().validate(attrs)
|
||||
|
||||
|
||||
class SaleListSerializer(serializers.ModelSerializer):
|
||||
customer_ = CustomerSimpleSerializer(source='customer', read_only=True)
|
||||
order_ = OrderSimpleSerializer(source='order', read_only=True)
|
||||
product_ = MaterialSimpleSerializer(source='product', read_only=True)
|
||||
class Meta:
|
||||
model = Sale
|
||||
fields = '__all__'
|
||||
|
||||
class SaleProductListSerializer(serializers.ModelSerializer):
|
||||
iproduct_ = IProductListSerializer(source='iproduct', read_only=True)
|
||||
class Meta:
|
||||
model = SaleProduct
|
||||
fields = '__all__'
|
||||
|
||||
class SaleProductCreateSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = SaleProduct
|
||||
fields = ['sale', 'iproduct']
|
||||
|
||||
def create(self, validated_data):
|
||||
validated_data['number'] = validated_data['iproduct'].number
|
||||
instance = SaleProduct.objects.create(**validated_data)
|
||||
instance.sale.count = SaleProduct.objects.filter(sale=instance.sale).count()
|
||||
instance.sale.save()
|
||||
return instance
|
|
@ -0,0 +1,51 @@
|
|||
from rest_framework import serializers
|
||||
from rest_framework import exceptions
|
||||
from apps.inm.models import IProduct
|
||||
from apps.inm.serializers import IProductListSerializer
|
||||
from apps.mtm.serializers import MaterialSimpleSerializer
|
||||
from apps.sam.models import Sale, SaleProduct
|
||||
from apps.sam.serializers import CustomerSimpleSerializer, OrderSimpleSerializer
|
||||
class SaleCreateSerializer(serializers.ModelSerializer):
|
||||
iproducts = serializers.PrimaryKeyRelatedField(queryset=
|
||||
IProduct.objects.all(), many=True)
|
||||
class Meta:
|
||||
model = Sale
|
||||
fields = ['customer', 'order', 'product', 'iproducts']
|
||||
|
||||
def validate(self, attrs):
|
||||
order = attrs.get('order', None)
|
||||
if order:
|
||||
if order.customer:
|
||||
attrs['customer'] = order.customer
|
||||
attrs['product'] = order.product
|
||||
for i in attrs['iproducts']:
|
||||
if i.material != attrs['product']:
|
||||
raise exceptions.APIException('产品选取错误')
|
||||
return super().validate(attrs)
|
||||
|
||||
|
||||
class SaleListSerializer(serializers.ModelSerializer):
|
||||
customer_ = CustomerSimpleSerializer(source='customer', read_only=True)
|
||||
order_ = OrderSimpleSerializer(source='order', read_only=True)
|
||||
product_ = MaterialSimpleSerializer(source='product', read_only=True)
|
||||
class Meta:
|
||||
model = Sale
|
||||
fields = '__all__'
|
||||
|
||||
class SaleProductListSerializer(serializers.ModelSerializer):
|
||||
iproduct_ = IProductListSerializer(source='iproduct', read_only=True)
|
||||
class Meta:
|
||||
model = SaleProduct
|
||||
fields = '__all__'
|
||||
|
||||
class SaleProductCreateSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = SaleProduct
|
||||
fields = ['sale', 'iproduct']
|
||||
|
||||
def create(self, validated_data):
|
||||
validated_data['number'] = validated_data['iproduct'].number
|
||||
instance = SaleProduct.objects.create(**validated_data)
|
||||
instance.sale.count = SaleProduct.objects.filter(sale=instance.sale).count()
|
||||
instance.sale.save()
|
||||
return instance
|
|
@ -1,9 +1,11 @@
|
|||
from django.db.models import base
|
||||
from rest_framework import urlpatterns
|
||||
from apps.sam.views import CustomerViewSet,ContractViewSet,OrderViewSet, SaleProductViewSet, SaleViewSet
|
||||
from apps.sam.views import CustomerViewSet,ContractViewSet, OrderViewSet
|
||||
from django.urls import path, include
|
||||
from rest_framework.routers import DefaultRouter
|
||||
|
||||
from apps.sam.views_sale import SaleProductViewSet, SaleViewSet
|
||||
|
||||
router = DefaultRouter()
|
||||
router.register('customer', CustomerViewSet, basename='customer')
|
||||
router.register('contract', ContractViewSet, basename='contract')
|
||||
|
|
|
@ -1,22 +1,12 @@
|
|||
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.sam.serializers import ContractCreateUpdateSerializer, ContractSerializer, \
|
||||
CustomerCreateUpdateSerializer, CustomerSerializer, OrderCreateUpdateSerializer, OrderSerializer
|
||||
from apps.sam.models import Contract, Customer, Order
|
||||
from rest_framework.viewsets import 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
|
||||
from rest_framework.decorators import action
|
||||
# Create your views here.
|
||||
class CustomerViewSet(CreateUpdateCustomMixin, ModelViewSet):
|
||||
"""
|
||||
|
@ -81,129 +71,6 @@ class OrderViewSet(CreateUpdateCustomMixin, ModelViewSet):
|
|||
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()
|
||||
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
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.mtm.models import Material
|
||||
from apps.sam.models import Sale, SaleProduct
|
||||
from apps.sam.serializers_sale import SaleCreateSerializer, SaleListSerializer, SaleProductCreateSerializer, SaleProductListSerializer
|
||||
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 apps.inm.signals import update_inm
|
||||
from rest_framework import serializers
|
||||
|
||||
class SaleViewSet(CreateUpdateModelAMixin, 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()
|
Loading…
Reference in New Issue