销售出库全部写完

master
laoxiao 1 year ago
parent 9b2fe5decf
commit eb7daca9aa

@ -146,11 +146,11 @@ class PaymentViewSet(viewsets.ModelViewSet, MultipleDestroyMixin, MultipleAuditM
# 处理关联业务逻辑
# 业务一: 采购定金付款
if pm.pay_category == '1' and pm.purchase:
pm.purchase.status = '5' # 已付定金
if pm.pay_category == '1' and pm.purchase and not pm.item_list.exists():
pm.purchase.status = '5' # 已付定金
pm.purchase.save()
# 业务二: 供应商欠款 支付
if pm.pay_category == '3':
if pm.pay_category == '3' and not pm.item_list.exists():
SupplierModel.objects.filter(id=pm.supplier.id).update(current_pay=F('current_pay') - pm.pay_money)
# 业务三: 入库货款 支付
if pm.pay_category == '2' and pm.purchase:

@ -0,0 +1,107 @@
from django.db import transaction
from django.db.models import Sum
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from ERP_5.utils.get_inventory import get_inventory_by_goods
from sale_info.models import SaleModel, SaleItemModel
from warehouse_info.models import SaleDeliverItemModel
class SalesItemSerializer(serializers.ModelSerializer):
"""
销售单的 项目序列化
"""
# 注意:既然只有 库存数据没有,那么可以增加一个属性
cur_inventory = serializers.SerializerMethodField(read_only=True, label='当前仓库中库存')
# 额外增加的属性为了后面的订单出库单。already_out_number已经出库数量
already_out_number = serializers.SerializerMethodField(read_only=True, label='当前的销售订单中,已经出库的数量')
class Meta:
model = SaleItemModel
fields = '__all__'
def get_cur_inventory(self, obj): # 当前的obj为SaleItemModel对象
result = get_inventory_by_goods(obj.goods.id)
return result if result else 0
def get_already_out_number(self, obj): # 当前的obj为SaleItemModel对象
if obj.sale.status == '0' or obj.sale.status == '1':
# 如果销售订单都没有出库则不用查了直接返回0
return 0
else:
# 先根据销售单的ID作为一个过滤条件, 基于当前货品ID作为第二个过滤条件 而且出库单的状态是已经审核
out_count = SaleDeliverItemModel.objects.filter(
sale_deliver__sale__id=obj.sale.id,
goods_id=obj.goods.id).exclude(sale_deliver__status='0') \
.aggregate(sum=Sum('sale_count'))
if out_count:
return out_count['sum'] if out_count['sum'] else 0
return 0
class SaleSerializer(serializers.ModelSerializer):
"""
销售单反序列化器用于新增和修改 查询列表的序列化器用于入库单列表
"""
item_list = SalesItemSerializer(many=True)
# 销售订单列表中需要展示:商品信息。
goods_info = serializers.SerializerMethodField(read_only=True, label='列表中展示的商品信息')
class Meta:
model = SaleModel
fields = '__all__'
def get_goods_info(self, obj):
"""
商品信息是由 商品1名称 商品1规格 , 商品2名称 商品2规格 ....
"""
if obj.item_list.all():
result = []
for item in obj.item_list.all():
result.append(item.name + (item.specification if item.specification else ''))
return ', '.join(result)
return ""
# 同时插入销售单和销售单中货品项。必须重写create
def create(self, validated_data):
item_list = validated_data.pop('item_list')
with transaction.atomic():
sale = SaleModel.objects.create(**validated_data)
for item in item_list:
sale_item = SaleItemModel.objects.create(sale=sale, **item)
# 把一些冗余属性也加进去
goods = item.get('goods')
sale_item.specification = goods.specification
sale_item.model_number = goods.model_number
sale_item.number_code = goods.number_code
sale_item.color = goods.color
sale_item.units = goods.units
sale_item.units_name = goods.units.basic_name
sale_item.save()
return sale
# 同时插入销售单和销售单中货品项。必须重写update
def update(self, instance, validated_data):
if instance.status == '1':
raise ValidationError("销售单已经生效,不能修改")
item_list = validated_data.pop('item_list')
old_list = instance.item_list.all()
with transaction.atomic():
if old_list.exists():
# 然后把旧数据删除因为在validated_data拿不到货品库存数据的ID
instance.item_list.all().delete()
for item in item_list: # 重新插入销售项 数据
sale_item = SaleItemModel.objects.create(sale=instance, **item)
# 把一些冗余属性也加进去
goods = item.get('goods')
sale_item.specification = goods.specification
sale_item.model_number = goods.model_number
sale_item.number_code = goods.number_code
sale_item.color = goods.color
sale_item.units = goods.units
sale_item.units_name = goods.units.basic_name
sale_item.save()
result = super(SaleSerializer, self).update(instance=instance, validated_data=validated_data)
return result

@ -0,0 +1,32 @@
"""ERP_5 URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/3.2/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, re_path
from rest_framework.routers import DefaultRouter
from .views import sale_views
from rest_framework_jwt.views import obtain_jwt_token
urlpatterns = [
# path('admin/', admin.site.urls),
]
router = DefaultRouter()
router.register('sales', sale_views.SalesView)
urlpatterns += router.urls

@ -0,0 +1,108 @@
from django.db.models import Q
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
from rest_framework import viewsets
from rest_framework.decorators import action
from ERP_5.utils.base_views import MultipleDestroyMixin, MultipleAuditMixin
from ERP_5.utils.paginations import GlobalPagination
from sale_info.models import SaleModel
from sale_info.serializer.sale_serializer import SaleSerializer
class SalesView(viewsets.ModelViewSet, MultipleDestroyMixin, MultipleAuditMixin):
"""
create:
销售单--新增,注意其中images_list="1,2,3,4";里面是附件的ID
销售单新增, status: 201(成功), return: 新增销售单信息
destroy:
销售单--删除
销售单删除, status: 204(成功), return: None
multiple_delete:
销售单--批量删除,必传参数ids=[1,2,3,4...]
销售单批量删除, status: 204(成功), return: None
update:
销售单--修改,注意其中images_list="1,2,3,4";里面是附件的ID
销售单修改, status: 200(成功), return: 修改后的销售单信息
partial_update:
销售单--局部修改,可以传参任意属性的值服务器会修改指定的属性值
销售单局部修改, status: 200(成功), return: 修改后的销售单信息
list:
销售单--该接口可以弃用
销售单列表信息, status: 200(成功), return: 销售单信息列表
retrieve:
查询某一个销售单
查询指定ID的销售单, status: 200(成功), return: 用户销售单
"""
queryset = SaleModel.objects.all()
serializer_class = SaleSerializer
pagination_class = GlobalPagination
def get_queryset(self):
if self.action == 'find': # 过滤查询
# 获取请求参数(在json中)
number_code = self.request.data.get('number_code', None)
keyword = self.request.data.get('keyword', None)
start_date = self.request.data.get('start_date', None)
end_date = self.request.data.get('end_date', None)
customer = self.request.data.get('customer', 0)
operator_user = self.request.data.get('operator_user', 0)
status = self.request.data.get('status', None)
query = Q()
if keyword:
child_query = Q()
child_query.add(Q(item_list__name__contains=keyword), 'OR')
child_query.add(Q(item_list__specification=keyword), 'OR')
query.add(child_query, 'AND')
if start_date:
query.add(Q(invoices_date__gt=start_date), 'AND')
if end_date:
query.add(Q(invoices_date__lt=end_date), 'AND')
if customer:
query.add(Q(customer__id=customer), 'AND')
if number_code:
query.add(Q(number_code__contains=number_code), 'AND')
if operator_user:
query.add(Q(operator_user__id=operator_user), 'AND')
if status:
query.add(Q(status=status), 'AND')
return SaleModel.objects.filter(query).distinct().all()
else:
return SaleModel.objects.all()
params = openapi.Schema(type=openapi.TYPE_OBJECT, properties={
'keyword': openapi.Schema(type=openapi.TYPE_STRING, description="名称的关键字或者型号"),
'start_date': openapi.Schema(type=openapi.TYPE_STRING, description="起始日期2020-10-01"),
'number_code': openapi.Schema(type=openapi.TYPE_STRING, description="编号(序列号)"),
'end_date': openapi.Schema(type=openapi.TYPE_STRING, description="结束日期2020-10-01"),
'status': openapi.Schema(type=openapi.TYPE_STRING, description="状态0或者1,2,3.."),
'customer': openapi.Schema(type=openapi.TYPE_INTEGER, description="客户商的ID"),
'operator_user': openapi.Schema(type=openapi.TYPE_INTEGER, description="操作用户的ID"),
})
# 分页参数必须是query_param(看源码)
page_param = openapi.Parameter(name='page', in_=openapi.IN_QUERY, description="页号", type=openapi.TYPE_INTEGER)
size_param = openapi.Parameter(name='size', in_=openapi.IN_QUERY, description="每页显示数量", type=openapi.TYPE_INTEGER)
@swagger_auto_schema(method='POST', request_body=params, manual_parameters=[page_param, size_param],
operation_description="销售订单的搜索过滤")
@action(methods=['POST'], detail=False)
def find(self, request, *args, **kwargs):
return super(SalesView, self).list(request=request, *args, **kwargs)

@ -93,3 +93,97 @@ class PurchaseStorageItemModel(BaseModel):
def __str__(self):
return self.name + ' ' + self.specification
# 销售出库单 模型类
class SaleDeliverModel(BaseModel):
invoices_date = models.DateTimeField('单据日期')
number_code = models.CharField('单据编号,不让用户填写', max_length=28)
remark = models.CharField('备注', max_length=512, blank=True, null=True)
discount = models.DecimalField('优惠率,最多精确到小数点后两位', max_digits=5, default=0, decimal_places=2, blank=True, null=True)
discount_money = models.DecimalField('优惠金额(付款优惠),最多精确到小数点后两位', max_digits=10, default=0, decimal_places=2,
blank=True,
null=True)
last_amount = models.DecimalField('优惠后总金额,最多精确到小数点后两位', max_digits=13, decimal_places=2, default=0, blank=True,
null=True)
other_money = models.DecimalField('其他费用,最多精确到小数点后两位', max_digits=10, decimal_places=2, default=0, blank=True,
null=True)
deduction_deposit = models.DecimalField('订金抵扣,最多精确到小数点后两位', max_digits=10, decimal_places=2, default=0, blank=True,
null=True)
this_proceeds = models.DecimalField('本次收款,最多精确到小数点后两位', max_digits=10, decimal_places=2, default=0, blank=True,
null=True)
this_debt = models.DecimalField('本次欠款,最多精确到小数点后两位', max_digits=10, decimal_places=2, default=0, blank=True,
null=True)
number_count = models.DecimalField('出库总数量,最多精确到小数点后两位', max_digits=10, decimal_places=2, blank=True, default=0)
status = models.CharField('状态,0:未审核,1:已审核,2:已收款完成', max_length=1, default='0')
operator_user = models.ForeignKey('erp_system.UserModel', related_name='operator6_in_list', null=True,
on_delete=models.SET_NULL,
verbose_name='入库操作人员,不能修改')
# 增加一个冗余字段
operator_user_name = models.CharField('操作人员的真实姓名', max_length=20, null=True, blank=True)
check_user = models.ForeignKey('erp_system.UserModel', related_name='check7_in_list', null=True, blank=True, on_delete=models.SET_NULL,
verbose_name='审核人员,不能修改')
# 增加一个冗余字段
check_user_name = models.CharField('操作人员的真实姓名', max_length=20, null=True, blank=True)
account = models.ForeignKey('basic_info.SettlementAccountModel', null=True, on_delete=models.SET_NULL,
verbose_name='结算账户,审核之后不能改')
customer = models.ForeignKey('basic_info.CustomerModel', null=True, blank=True, on_delete=models.SET_NULL,
verbose_name='客户,审核之后不能改')
# 增加一个冗余字段
customer_name = models.CharField('客户商的名称', max_length=30, null=True, blank=True)
sale = models.ForeignKey('sale_info.SaleModel', null=True, blank=True, on_delete=models.SET_NULL,
verbose_name='销售订单,审核之后不能改')
attachment_list = models.CharField('附件的id列表字段的值为: 1,2,3,4', max_length=20, null=True, blank=True)
is_other = models.CharField('是否是其他出库,0:销售出库,1:其他出库', max_length=1, default='0')
class Meta:
db_table = 't_sale_deliver'
verbose_name = '出库单表'
verbose_name_plural = verbose_name
ordering = ['id']
# 出库单中的货品(货品项目) 模型类
class SaleDeliverItemModel(BaseModel):
# 这些个也都是冗余字段, 减少查询的时候,表连接查询的次数
name = models.CharField(max_length=20, verbose_name='货品名称')
number_code = models.CharField('货品的编号或者批号', max_length=28, null=True, blank=True)
specification = models.CharField('货品规格', max_length=50, null=True, blank=True)
model_number = models.CharField('型号', max_length=50, null=True, blank=True)
color = models.CharField('颜色', max_length=50, null=True, blank=True)
units_name = models.CharField('单位名字', max_length=50, null=True, blank=True)
units = models.ForeignKey('goods_info.UnitsModel', on_delete=models.SET_NULL, null=True, blank=True)
category = models.ForeignKey('goods_info.GoodsCategoryModel', on_delete=models.SET_NULL, null=True, blank=True)
category_name = models.CharField('货品类别名称', max_length=50, null=True, blank=True)
remark = models.CharField('备注', max_length=512, blank=True, null=True)
sale_count = models.DecimalField('出库数量,最多精确到小数点后两位', max_digits=10, decimal_places=2, default=0)
sale_price = models.DecimalField('单价,最多精确到小数点后两位', max_digits=10, decimal_places=2, default=0)
sale_money = models.DecimalField('金额,最多精确到小数点后两位', max_digits=10, decimal_places=2, default=0)
sale_deliver = models.ForeignKey('SaleDeliverModel', related_name='item_list', null=True, blank=True,
on_delete=models.CASCADE,
verbose_name='销售出库单')
goods = models.ForeignKey('goods_info.GoodsModel', null=True, on_delete=models.SET_NULL,
verbose_name='货品')
warehouse = models.ForeignKey('basic_info.WarehouseModel', null=True, on_delete=models.SET_NULL,
verbose_name='出库的仓库')
warehouse_name = models.CharField('仓库名字', max_length=50, null=True)
class Meta:
db_table = 't_sale_deliver_items'
verbose_name = '出库单的项目表'
verbose_name_plural = verbose_name
ordering = ['id']
def __str__(self):
return self.name + ' ' + self.specification

@ -0,0 +1,93 @@
from django.db import transaction
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from ERP_5.utils.get_inventory import get_inventory_by_goods
from warehouse_info.models import SaleDeliverItemModel, SaleDeliverModel
class DeliveryItemSerializer(serializers.ModelSerializer):
"""
出库单的 项目序列化
"""
# 注意:既然只有 库存数据没有,那么可以增加一个属性
cur_inventory = serializers.SerializerMethodField(read_only=True, label='在当前仓库中库存')
class Meta:
model = SaleDeliverItemModel
fields = '__all__'
def get_cur_inventory(self, obj): # 当前的obj为SaleDeliverItemModel
result = get_inventory_by_goods(obj.goods.id, obj.warehouse.id)
return result if result else 0
class DeliverySerializer(serializers.ModelSerializer):
"""
出库单反序列化器用于新增和修改 查询列表的序列化器用于出库单列表
"""
item_list = DeliveryItemSerializer(many=True)
# 出库单列表中需要展示:商品信息。
goods_info = serializers.SerializerMethodField(read_only=True, label='列表中展示的商品信息')
class Meta:
model = SaleDeliverModel
fields = '__all__'
def get_goods_info(self, obj):
"""
商品信息是由 商品1名称 商品1规格 , 商品2名称 商品2规格 ....
"""
if obj.item_list.all():
result = []
for item in obj.item_list.all():
result.append(item.name + (item.specification if item.specification else ''))
return ', '.join(result)
return ""
# 同时插出出库单和 出库单中货品项。必须重写create
def create(self, validated_data):
item_list = validated_data.pop('item_list')
with transaction.atomic():
sd = SaleDeliverModel.objects.create(**validated_data)
for item in item_list:
psi = SaleDeliverItemModel.objects.create(sale_deliver=sd, **item)
# 把一些冗余属性也加进去
goods = item.get('goods')
psi.specification = goods.specification
psi.model_number = goods.model_number
psi.number_code = goods.number_code
psi.color = goods.color
psi.category = goods.category
psi.category_name = goods.category.name
psi.units = goods.units
psi.units_name = goods.units.basic_name
psi.save()
return sd
# 同时插出出库单和出库单中货品项。必须重写update
def update(self, instance, validated_data):
if instance.status == '1':
raise ValidationError("出库单已经生效,不能修改")
item_list = validated_data.pop('item_list')
old_list = instance.item_list.all()
with transaction.atomic():
if old_list.exists():
# 然后把旧数据删除因为在validated_data拿不到货品库存数据的ID
instance.item_list.all().delete()
for item in item_list: # 重新插出出库项 数据
psi = SaleDeliverItemModel.objects.create(sale_deliver=instance, **item)
# 把一些冗余属性也加进去
goods = item.get('goods')
psi.specification = goods.specification
psi.model_number = goods.model_number
psi.number_code = goods.number_code
psi.color = goods.color
psi.category = goods.category
psi.category_name = goods.category.name
psi.units = goods.units
psi.units_name = goods.units.basic_name
psi.save()
result = super(DeliverySerializer, self).update(instance=instance, validated_data=validated_data)
return result

@ -16,7 +16,7 @@ Including another URLconf
from django.contrib import admin
from django.urls import path, re_path
from rest_framework.routers import DefaultRouter
from .views import in_storage_views
from .views import in_storage_views, out_storage_views
from rest_framework_jwt.views import obtain_jwt_token
@ -28,5 +28,6 @@ urlpatterns = [
router = DefaultRouter()
router.register('storage', in_storage_views.InStorageViewSet)
router.register('deliver', out_storage_views.OutStorageView)
urlpatterns += router.urls

@ -0,0 +1,186 @@
from django.db import transaction
from django.db.models import Q, F, Sum
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.response import Response
from ERP_5.utils.base_views import MultipleDestroyMixin, MultipleAuditMixin
from ERP_5.utils.paginations import GlobalPagination
from basic_info.models import CustomerModel
from erp_system.models import UserModel
from goods_info.models import GoodsInventoryModel
from warehouse_info.models import SaleDeliverModel
from warehouse_info.serializer.out_storage_serializer import DeliverySerializer
class OutStorageView(viewsets.ModelViewSet, MultipleDestroyMixin, MultipleAuditMixin):
"""
create:
仓库(销售)出库单--新增,注意其中images_list="1,2,3,4";里面是附件的ID
仓库(销售)出库单新增, status: 201(成功), return: 新增仓库(销售)出库单信息
destroy:
仓库(销售)出库单--删除
仓库(销售)出库单删除, status: 204(成功), return: None
multiple_delete:
仓库(销售)出库单--批量删除,必传参数ids=[1,2,3,4...]
仓库(销售)出库单批量删除, status: 204(成功), return: None
update:
仓库(销售)出库单--修改,注意其中images_list="1,2,3,4";里面是附件的ID
仓库(销售)出库单修改, status: 200(成功), return: 修改后的仓库(销售)出库单信息
partial_update:
仓库(销售)出库单--局部修改,可以传参任意属性的值服务器会修改指定的属性值
仓库(销售)出库单局部修改, status: 200(成功), return: 修改后的仓库(销售)出库单信息
list:
仓库(销售)出库单--该接口可以弃用
仓库(销售)出库单列表信息, status: 200(成功), return: 仓库(销售)出库单信息列表
retrieve:
查询某一个仓库(销售)出库单
查询指定ID的仓库(销售)出库单, status: 200(成功), return: 用户仓库(销售)出库单
"""
queryset = SaleDeliverModel.objects.all()
serializer_class = DeliverySerializer
pagination_class = GlobalPagination
def get_queryset(self):
if self.action == 'find': # 过滤查询
# 获取请求参数(在json中)
number_code = self.request.data.get('number_code', None)
keyword = self.request.data.get('keyword', None)
start_date = self.request.data.get('start_date', None)
end_date = self.request.data.get('start_date', None)
customer = self.request.data.get('customer', 0)
operator_user = self.request.data.get('operator_user', 0)
status = self.request.data.get('status', None)
warehouse = self.request.data.get('warehouse', 0)
account = self.request.data.get('account', 0)
sale_number_code = self.request.data.get('sale_number_code', None)
query = Q()
if keyword:
child_query = Q()
child_query.add(Q(item_list__name__contains=keyword), 'OR')
child_query.add(Q(item_list__specification=keyword), 'OR')
query.add(child_query, 'AND')
if warehouse:
query.add(Q(item_list__warehouse_id=warehouse), 'AND')
if account:
query.add(Q(account__id=account), 'AND')
if sale_number_code:
query.add(Q(sale__number_code__contains=sale_number_code), 'AND')
if start_date:
query.add(Q(invoices_date__gt=start_date), 'AND')
if end_date:
query.add(Q(invoices_date__lt=end_date), 'AND')
if customer:
query.add(Q(customer__id=customer), 'AND')
if number_code:
query.add(Q(number_code__contains=number_code), 'AND')
if operator_user:
query.add(Q(operator_user__id=operator_user), 'AND')
if status:
query.add(Q(status=status), 'AND')
return SaleDeliverModel.objects.filter(query).distinct().all()
else:
return SaleDeliverModel.objects.all()
params = openapi.Schema(type=openapi.TYPE_OBJECT, properties={
'keyword': openapi.Schema(type=openapi.TYPE_STRING, description="名称的关键字或者型号"),
'start_date': openapi.Schema(type=openapi.TYPE_STRING, description="起始日期2020-10-01"),
'number_code': openapi.Schema(type=openapi.TYPE_STRING, description="编号(序列号)"),
'end_date': openapi.Schema(type=openapi.TYPE_STRING, description="结束日期2020-10-01"),
'status': openapi.Schema(type=openapi.TYPE_STRING, description="状态0或者1,2,3.."),
'customer': openapi.Schema(type=openapi.TYPE_INTEGER, description="客户的ID"),
'operator_user': openapi.Schema(type=openapi.TYPE_INTEGER, description="操作用户的ID"),
'warehouse': openapi.Schema(type=openapi.TYPE_INTEGER, description="仓库的ID"),
'account': openapi.Schema(type=openapi.TYPE_INTEGER, description="结算账户的ID"),
'sale_number_code': openapi.Schema(type=openapi.TYPE_STRING, description="销售订单编号关键字"),
})
# 分页参数必须是query_param(看源码)
page_param = openapi.Parameter(name='page', in_=openapi.IN_QUERY, description="页号", type=openapi.TYPE_INTEGER)
size_param = openapi.Parameter(name='size', in_=openapi.IN_QUERY, description="每页显示数量", type=openapi.TYPE_INTEGER)
@swagger_auto_schema(method='POST', request_body=params, manual_parameters=[page_param, size_param],
operation_description="出库单的搜索过滤")
@action(methods=['POST'], detail=False)
def find(self, request, *args, **kwargs):
return super(OutStorageView, self).list(request=request, *args, **kwargs)
"""
自定义的 批量审核的 视图函数
"""
body_param = openapi.Schema(type=openapi.TYPE_OBJECT, required=['ids', 'user_id'], properties={
'ids': openapi.Schema(type=openapi.TYPE_ARRAY, items=openapi.Schema(type=openapi.TYPE_INTEGER),
description="选择哪些需要批量的ID主键列表"),
'user_id': openapi.Schema(type=openapi.TYPE_INTEGER, description="审核人的用户ID"),
# 'is_audit': openapi.Schema(type=openapi.TYPE_STRING, description="是否审核审核1")
})
@swagger_auto_schema(method='put', request_body=body_param, operation_description="批量审核")
@action(methods=['put'], detail=False)
@transaction.atomic # 自动 数据库事务
def multiple_audit(self, request, *args, **kwargs):
audit_ids = request.data.get('ids')
user_id = request.data.get('user_id') # 用户ID
# is_audit = request.data.get('is_audit', '1') # 是否审核审核1
# 为了减少代码量,参数的验证就不写了
queryset = self.get_queryset().filter(id__in=audit_ids).all()
check_user = UserModel.objects.get(id=int(user_id))
for deliver in queryset: # 出库单
# 条件是否成立
if deliver.status != '0': # 0以后的状态是不能审核的
return Response(data={'detail': '不能审核,因为订单已生效'}, status=status.HTTP_400_BAD_REQUEST)
if deliver.status == '0' and deliver.sale:
if deliver.sale.status != '1' and deliver.sale.status != '2' and deliver.sale.status != '5':
return Response(data={'detail': '不能审核,因为关联的销售订单未生效或者已经出库完成'}, status=status.HTTP_400_BAD_REQUEST)
# 处理审核的业务
# 业务一: 如果有欠款,需要修改客户的末期应收
if deliver.this_debt:
CustomerModel.objects.filter(id=deliver.customer_id).update(
current_receivable=F('current_receivable') + deliver.this_debt)
# 业务二: 修改关联的销售单, 状态: 部分出库或者全部出库
if deliver.sale:
# 已经出库的数量
out_count_dict = SaleDeliverModel.objects \
.filter(sale_id=deliver.sale_id) \
.exclude(status='0').aggregate(sum=Sum('number_count'))
out_count = out_count_dict['sum'] if out_count_dict['sum'] else 0
if (out_count + deliver.number_count) == deliver.sale.number_count:
# 全部出库
deliver.sale.status = '3'
else:
deliver.sale.status = '2'
deliver.sale.save()
# 业务三: 原来的库存 -= 当前出库数量
if deliver.item_list.exists():
for item in deliver.item_list.all():
GoodsInventoryModel.objects \
.filter(goods_id=item.goods_id, warehouse_id=item.warehouse_id) \
.update(cur_inventory=F('cur_inventory') - item.sale_count)
# 审核
self.get_queryset().filter(id__in=audit_ids).update(status='1', check_user_name=check_user.real_name,
check_user_id=check_user.id)
return Response(status=status.HTTP_200_OK)

@ -47,6 +47,7 @@ INSTALLED_APPS = [
'purchase_info',
'warehouse_info',
'financial_info',
'sale_info',
# 'django.contrib.staticfiles', # required for serving swagger ui's css/js files
'drf_yasg',

@ -41,6 +41,7 @@ urlpatterns = [
path('api/', include('purchase_info.urls')),
path('api/', include('warehouse_info.urls')),
path('api/', include('financial_info.urls')),
path('api/', include('sale_info.urls')),
re_path(r'^api/generate_code/$', GenerateCode.as_view()),
# 媒体资源文件的访问路由

Loading…
Cancel
Save