付款单的的审核完成,和销售模型类

master
laoxiao 2 years ago
parent b097ecffbe
commit 9b2fe5decf

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

@ -0,0 +1,6 @@
from django.apps import AppConfig
class FinancialInfoConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'financial_info'

@ -0,0 +1,79 @@
from django.db import models
from ERP_5.utils.base_model import BaseModel
# 货币种类
currency_choices = (
('CNY', '人民币'),
('USD', '美元'),
('EUR', '欧元'),
('JPY', '日元'),
('HKD', '港币')
)
# 付款类型
pay_choices = (
('1', '采购定金'),
('2', '采购货款'),
('3', '欠款还款'),
('4', '其他付款')
)
# 付款单的模型类
class PaymentModel(BaseModel):
pay_date = models.DateTimeField('付款日期')
number_code = models.CharField('单据编号,不让用户填写', max_length=28)
discount_money = models.DecimalField('优惠金额(付款优惠),最多精确到小数点后两位', max_digits=10, default=0, decimal_places=2,
blank=True, null=True)
pay_money = models.DecimalField('合计 付款金额最多精确到小数点后两位', max_digits=10, decimal_places=2, default=0)
this_money = models.DecimalField('实际 付款金额最多精确到小数点后两位', max_digits=10, decimal_places=2, default=0)
remark = models.CharField('备注', max_length=512, blank=True, null=True)
currency = models.CharField('货币种类', max_length=20, null=True, choices=currency_choices, default='CNY')
pay_category = models.CharField('付款类型', max_length=2, null=True, choices=pay_choices, default='1')
status = models.CharField('状态,0:未审核,1:已审核', max_length=1, default='0')
account = models.ForeignKey('basic_info.SettlementAccountModel', null=True, blank=True, on_delete=models.SET_NULL,
verbose_name='结算账户,审核之后不能改')
operator_user = models.ForeignKey('erp_system.UserModel', related_name='operator_pay_list', null=True,
blank=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='operator3_pay_list', null=True, blank=True, on_delete=models.SET_NULL,
verbose_name='审核人员,不能修改')
# 增加一个冗余字段
check_user_name = models.CharField('审核人员的真实姓名', max_length=20, null=True, blank=True)
supplier = models.ForeignKey('basic_info.SupplierModel', null=True, blank=True, on_delete=models.SET_NULL,
verbose_name='供应商,审核之后不能改')
# 增加一个冗余字段
supplier_name = models.CharField('供应商名称', max_length=30, null=True, blank=True)
purchase = models.ForeignKey('purchase_info.PurchaseModel', 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)
class Meta:
db_table = 't_payment'
verbose_name = '付款单表'
verbose_name_plural = verbose_name
ordering = ['id']
# 付款单中 付款项目的模型类
class PaymentItemModel(BaseModel):
# 冗余字段
storage_code = models.CharField('采购入库单编号,不让用户填写', max_length=28)
purchase_storage = models.ForeignKey('warehouse_info.PurchaseStorageModel', related_name='pay_item_list', null=True, blank=True,
on_delete=models.SET_NULL, verbose_name='采购入库单')
payment = models.ForeignKey('PaymentModel', null=True, blank=True, related_name='item_list', on_delete=models.SET_NULL,
verbose_name='付款单,不能改')
should_money = models.DecimalField('应该 付款金额(就是采购入库单中需要支付的金额),最多精确到小数点后两位', max_digits=10, decimal_places=2, default=0)
this_money = models.DecimalField('本次 付款金额,最多精确到小数点后两位', max_digits=10, decimal_places=2, default=0)
remark = models.CharField('备注', max_length=512, blank=True, null=True)
class Meta:
db_table = 't_payment_item'
verbose_name = '付款单中的 付款项目表'
verbose_name_plural = verbose_name
ordering = ['id']

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.

@ -1,15 +1,18 @@
from django.db import transaction from django.db import transaction
from django.db.models import Q from django.db.models import Q, F, Sum
from drf_yasg import openapi from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema from drf_yasg.utils import swagger_auto_schema
from rest_framework import viewsets from rest_framework import viewsets, status
from rest_framework.decorators import action 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.base_views import MultipleDestroyMixin, MultipleAuditMixin
from ERP_5.utils.paginations import GlobalPagination from ERP_5.utils.paginations import GlobalPagination
from basic_info.models import SupplierModel, SettlementAccountModel
from erp_system.models import UserModel from erp_system.models import UserModel
from financial_info.models import PaymentModel from financial_info.models import PaymentModel, PaymentItemModel
from financial_info.serializer.payment_serializer import PaymentSerializer from financial_info.serializer.payment_serializer import PaymentSerializer
from warehouse_info.models import PurchaseStorageModel
class PaymentViewSet(viewsets.ModelViewSet, MultipleDestroyMixin, MultipleAuditMixin): class PaymentViewSet(viewsets.ModelViewSet, MultipleDestroyMixin, MultipleAuditMixin):
@ -118,7 +121,6 @@ class PaymentViewSet(viewsets.ModelViewSet, MultipleDestroyMixin, MultipleAuditM
'ids': openapi.Schema(type=openapi.TYPE_ARRAY, items=openapi.Schema(type=openapi.TYPE_INTEGER), 'ids': openapi.Schema(type=openapi.TYPE_ARRAY, items=openapi.Schema(type=openapi.TYPE_INTEGER),
description="选择哪些需要批量的ID主键列表"), description="选择哪些需要批量的ID主键列表"),
'user_id': 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="批量审核") @swagger_auto_schema(method='put', request_body=body_param, operation_description="批量审核")
@ -131,5 +133,64 @@ class PaymentViewSet(viewsets.ModelViewSet, MultipleDestroyMixin, MultipleAuditM
# 为了减少代码量,参数的验证就不写了 # 为了减少代码量,参数的验证就不写了
queryset = self.get_queryset().filter(id__in=audit_ids).all() queryset = self.get_queryset().filter(id__in=audit_ids).all()
check_user = UserModel.objects.get(id=int(user_id)) check_user = UserModel.objects.get(id=int(user_id))
for item in queryset: for pm in queryset: # 期中pm是付款单
pass # 判断1关联的采购单状态是否为“未审核”
if pm.purchase and pm.purchase.status == '0':
return Response(data={'detail': '采购订单未审核,不能付款'}, status=status.HTTP_400_BAD_REQUEST)
# 判断2 付款单的状态是否为:“已审核”
if pm.status == '1':
return Response(data={'detail': '付款单已经审核,不需要再次审核'}, status=status.HTTP_400_BAD_REQUEST)
# 判断3 结算账户的余额是否够用
if pm.this_money > pm.account.balance:
return Response(data={'detail': '选择的结算账户中的余额不够,不能付款'}, status=status.HTTP_400_BAD_REQUEST)
# 处理关联业务逻辑
# 业务一: 采购定金付款
if pm.pay_category == '1' and pm.purchase:
pm.purchase.status = '5' # 已付定金
pm.purchase.save()
# 业务二: 供应商欠款 支付
if pm.pay_category == '3':
SupplierModel.objects.filter(id=pm.supplier.id).update(current_pay=F('current_pay') - pm.pay_money)
# 业务三: 入库货款 支付
if pm.pay_category == '2' and pm.purchase:
if pm.item_list.exists(): # 这种判断不回从数据库中返回数据
for item in pm.item_list.all(): # 期中item是付款项目
# 判断4 入库单必须是已经审核状态
if item.purchase_storage and item.purchase_storage.status != '1':
return Response(data={'detail': '入库单未审核或者已经付款,不能付款'}, status=status.HTTP_400_BAD_REQUEST)
# 业务三——第1种情况 对应的入库单,是否应该:付款完成 ,首先需要查询该入库单的已经付款金额之和
sum_dict = PaymentItemModel.objects\
.filter(purchase_storage_id=item.purchase_storage.id, payment__status='1')\
.aggregate(sum=Sum('this_money'))
pay_sum = sum_dict['sum'] if sum_dict['sum'] else 0
if item.should_money == (pay_sum + item.this_money):
item.purchase_storage.status = '2' # 把入库单的状态修改为:付款完成
item.purchase_storage.save()
# 业务三——第2种情况 对应的采购单状态是否要改为:采购完成
# 采购完成的条件: 1、该采购单必须是全部入库状态2、该采购单中 所有的入库单状态也都必须是:付款完成
purchase = item.payment.purchase
if purchase.status == '3':
# 查询 该采购单中 所有入库单状态不是:'付款完成' 的有多少个?
number = PurchaseStorageModel.objects\
.filter(purchase_id=purchase.id)\
.exclude(status='2').count()
if number == 0: # 则 所有的入库单状态都为:付款完成
purchase.status = '4' # 修改采购单状态为: 采购完成
purchase.save()
else:
return Response(data={'detail': '没有选择付款项目,支付货款的时候必须选择'}, status=status.HTTP_400_BAD_REQUEST)
# 至此: 三种业务都完成
# 业务四: 修改 结算账户的余额
SettlementAccountModel.objects.filter(id=pm.account.id)\
.update(balance=F('balance') - pm.this_money)
# 至此: 四种业务都完成,开始修改付款单的状态以及审核信息
# 审核
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)

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

@ -0,0 +1,6 @@
from django.apps import AppConfig
class SaleInfoConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'sale_info'

@ -0,0 +1,71 @@
from django.db import models
from ERP_5.utils.base_model import BaseModel
# 销售订单 模型类
class SaleModel(BaseModel):
invoices_date = models.DateTimeField('单据日期')
number_code = models.CharField('单据编号,不让用户填写', max_length=28)
discount = models.DecimalField('优惠率,最多精确到小数点后两位', max_digits=5, decimal_places=2, blank=True, default=0)
discount_money = models.DecimalField('优惠金额(付款优惠),最多精确到小数点后两位', max_digits=10, decimal_places=2, blank=True,
default=0)
remark = models.CharField('备注', max_length=512, blank=True, null=True)
last_amount = models.DecimalField('优惠后总金额,最多精确到小数点后两位', max_digits=13, decimal_places=2, blank=True, default=0)
deposit = models.DecimalField('收取定金,最多精确到小数点后两位', max_digits=10, decimal_places=2, blank=True, default=0)
number_count = models.DecimalField('销售数量,最多精确到小数点后两位', max_digits=10, decimal_places=2, blank=True, default=0)
status = models.CharField('状态,0:未审核,1:已审核,2:部分发货,3:全部发货,4:完成销售,5:已收定金', max_length=1, default='0')
operator_user = models.ForeignKey('erp_system.UserModel', related_name='operator_sale_list', null=True,
blank=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', 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, blank=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)
attachment_list = models.CharField('附件的id列表字段的值为: 1,2,3,4', max_length=20, null=True, blank=True)
class Meta:
db_table = 't_sales'
verbose_name = '销售表'
verbose_name_plural = verbose_name
ordering = ['id']
# 销售订单(货品项目) 模型类
class SaleItemModel(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)
remark = models.CharField('备注', max_length=512, blank=True, null=True)
sales_count = models.DecimalField('销售数量,最多精确到小数点后两位', max_digits=10, decimal_places=2, default=0)
sales_price = models.DecimalField('销售单价,最多精确到小数点后两位', max_digits=10, decimal_places=2, default=0)
sales_money = models.DecimalField('销售金额,最多精确到小数点后两位', max_digits=10, decimal_places=2, default=0)
sale = models.ForeignKey('SaleModel', 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='货品,必须要传')
class Meta:
db_table = 't_sales_items'
verbose_name = '销售订单的项目表'
verbose_name_plural = verbose_name
ordering = ['id']

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.
Loading…
Cancel
Save