iproduct list增加order to_order 字段

This commit is contained in:
caoqianming 2022-01-26 09:21:23 +08:00
parent 04b864e72f
commit 9eab3aa592
8 changed files with 214 additions and 192 deletions

View File

@ -3,7 +3,7 @@ from django_filters import rest_framework as filters
from apps.mtm.models import Material from apps.mtm.models import Material
from .models import IProduct, MaterialBatch from .models import IProduct, MaterialBatch
from django.utils import timezone from django.utils import timezone
from utils.mixins import DynamicFieldsFilterMixin
class MbFilterSet(filters.FilterSet): class MbFilterSet(filters.FilterSet):
material = filters.ModelMultipleChoiceFilter(field_name="material", queryset=Material.objects.all()) material = filters.ModelMultipleChoiceFilter(field_name="material", queryset=Material.objects.all())
@ -20,7 +20,7 @@ class MbFilterSet(filters.FilterSet):
return queryset return queryset
class IProductFilterSet(filters.FilterSet): class IProductFilterSet(DynamicFieldsFilterMixin, filters.FilterSet):
order = filters.NumberFilter(field_name="wproduct__subproduction_plan__production_plan__order") order = filters.NumberFilter(field_name="wproduct__subproduction_plan__production_plan__order")
to_order = filters.NumberFilter(field_name="wproduct__to_order") to_order = filters.NumberFilter(field_name="wproduct__to_order")
update_time_start = filters.DateFilter(field_name="update_time", lookup_expr='gte') update_time_start = filters.DateFilter(field_name="update_time", lookup_expr='gte')

View File

@ -3,11 +3,13 @@ from rest_framework import serializers
from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, MaterialBatch, WareHouse, Inventory from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, MaterialBatch, WareHouse, Inventory
from apps.qm.models import TestRecord, TestRecordItem from apps.qm.models import TestRecord, TestRecordItem
from apps.sam.serializers import OrderSimpleSerializer
from apps.system.serializers import FileSimpleSerializer, UserSimpleSerializer from apps.system.serializers import FileSimpleSerializer, UserSimpleSerializer
from apps.mtm.serializers import MaterialSimpleSerializer from apps.mtm.serializers import MaterialSimpleSerializer
from django.db import transaction from django.db import transaction
from utils.mixins import DynamicFieldsSerializerMixin
@ -49,12 +51,15 @@ class MaterialBatchSerializer(serializers.ModelSerializer):
fields = '__all__' fields = '__all__'
class IProductListSerializer(serializers.ModelSerializer): class IProductListSerializer(DynamicFieldsSerializerMixin, serializers.ModelSerializer):
material_ = MaterialSimpleSerializer(source='material', read_only=True) material_ = MaterialSimpleSerializer(source='material', read_only=True)
warehouse_ = WareHouseSimpleSerializer(source='warehouse', read_only=True) warehouse_ = WareHouseSimpleSerializer(source='warehouse', read_only=True)
need_to_order = serializers.BooleanField(source='wproduct.need_to_order', 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) is_mtestok = serializers.BooleanField(source='wproduct.is_mtestok', read_only=True)
remark_mtest = serializers.CharField(source='wproduct.remark_mtest', 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: class Meta:
model = IProduct model = IProduct
fields = '__all__' fields = '__all__'

View File

@ -187,7 +187,9 @@ class IProductViewSet(ListModelMixin, GenericViewSet):
""" """
perms_map = {'*': '*'} perms_map = {'*': '*'}
queryset = IProduct.objects.select_related( 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 serializer_class = IProductListSerializer
filterset_class = IProductFilterSet filterset_class = IProductFilterSet
search_fields = [] search_fields = []

View File

@ -1,10 +1,7 @@
from django.db import transaction
from rest_framework import exceptions, serializers
from apps.inm.models import IProduct from rest_framework import serializers
from apps.inm.serializers import IProductListSerializer
from .models import Contract, Customer, Order, Sale, SaleProduct from .models import Contract, Customer, Order
from apps.mtm.serializers import MaterialSimpleSerializer from apps.mtm.serializers import MaterialSimpleSerializer
from utils.tools import ranstr from utils.tools import ranstr
@ -65,47 +62,3 @@ class OrderSimpleSerializer(serializers.ModelSerializer):
model = Order model = Order
fields = ['id', 'number', 'contract_', 'customer_', 'need_mtest', 'delivery_date'] 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

View File

@ -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

View File

@ -1,9 +1,11 @@
from django.db.models import base from django.db.models import base
from rest_framework import urlpatterns 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 django.urls import path, include
from rest_framework.routers import DefaultRouter from rest_framework.routers import DefaultRouter
from apps.sam.views_sale import SaleProductViewSet, SaleViewSet
router = DefaultRouter() router = DefaultRouter()
router.register('customer', CustomerViewSet, basename='customer') router.register('customer', CustomerViewSet, basename='customer')
router.register('contract', ContractViewSet, basename='contract') router.register('contract', ContractViewSet, basename='contract')

View File

@ -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.filters import ContractFilterSet, OrderFilterSet
from apps.sam.serializers import ContractCreateUpdateSerializer, ContractSerializer, CustomerCreateUpdateSerializer, CustomerSerializer, OrderCreateUpdateSerializer, OrderSerializer, SaleCreateSerializer, SaleListSerializer, SaleProductCreateSerializer, SaleProductListSerializer from apps.sam.serializers import ContractCreateUpdateSerializer, ContractSerializer, \
from apps.sam.models import Contract, Customer, Order, Sale, SaleProduct CustomerCreateUpdateSerializer, CustomerSerializer, OrderCreateUpdateSerializer, OrderSerializer
from rest_framework.viewsets import GenericViewSet, ModelViewSet from apps.sam.models import Contract, Customer, Order
from rest_framework.viewsets import ModelViewSet
from apps.system.mixins import CreateUpdateCustomMixin from apps.system.mixins import CreateUpdateCustomMixin
from django.shortcuts import render
from rest_framework.decorators import action
from django.db.models import F from django.db.models import F
from rest_framework.response import Response from rest_framework.response import Response
from django.utils import timezone from rest_framework.decorators import action
from apps.wf.models import Workflow
# Create your views here. # Create your views here.
class CustomerViewSet(CreateUpdateCustomMixin, ModelViewSet): class CustomerViewSet(CreateUpdateCustomMixin, ModelViewSet):
""" """
@ -81,129 +71,6 @@ class OrderViewSet(CreateUpdateCustomMixin, ModelViewSet):
return Response(serializer.data) 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()

View File

@ -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()