付款单的的接口完成部分并测试成功,还有付款单的审核

master
laoxiao 1 year ago
parent 0695e4757d
commit b097ecffbe

@ -0,0 +1,74 @@
from django.db import transaction
from django.db.models import Sum
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from financial_info.models import PaymentItemModel, PaymentModel
class PaymentItemSerializer(serializers.ModelSerializer):
"""
付款单中 付款项目 的序列化器
"""
# 查询当前采购入库单中已经支付金额
already_payment = serializers.SerializerMethodField(read_only=True, help_text='已经付款的金额')
class Meta:
model = PaymentItemModel
fields = '__all__'
def get_already_payment(self, obj):
"""
查询当前采购入库单中已经支付金额
:param obj: PaymentItemModel
:return: 0获取其他的数值
"""
if obj.purchase_storage:
pay_dict = PaymentItemModel.objects.filter(purchase_storage_id=obj.purchase_storage.id)\
.exclude(payment__status='0')\
.aggregate(sum=Sum('this_money'))
if pay_dict:
return pay_dict['sum'] if pay_dict['sum'] else 0
return 0
return 0
class PaymentSerializer(serializers.ModelSerializer):
"""
付款单序列化器
"""
item_list = PaymentItemSerializer(many=True, required=False)
class Meta:
model = PaymentModel
fields = '__all__'
def create(self, validated_data):
if 'item_list' not in validated_data:
return super(PaymentSerializer, self).create(validated_data)
item_list = validated_data.pop('item_list')
with transaction.atomic():
payment = PaymentModel.objects.create(**validated_data)
for item in item_list:
# 插入付款项目
PaymentItemModel.objects.create(payment=payment, **item)
return payment
# 必须重写update
def update(self, instance, validated_data):
if instance.status != '0':
raise ValidationError("付款单已经生效,不能修改!")
with transaction.atomic():
if 'item_list' in validated_data:
item_list = validated_data.pop('item_list')
old_list = instance.item_list.all()
if old_list.exists():
# 然后把旧数据删除因为在validated_data拿不到货品库存数据的ID
instance.item_list.all().delete()
for item in item_list: # 重新插入采购项 数据
PaymentItemModel.objects.create(payment=instance, **item)
result = super(PaymentSerializer, 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 payment_views
from rest_framework_jwt.views import obtain_jwt_token
urlpatterns = [
# path('admin/', admin.site.urls),
]
router = DefaultRouter()
router.register('payment', payment_views.PaymentViewSet)
urlpatterns += router.urls

@ -0,0 +1,135 @@
from django.db import transaction
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 erp_system.models import UserModel
from financial_info.models import PaymentModel
from financial_info.serializer.payment_serializer import PaymentSerializer
class PaymentViewSet(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: 修改后的付款单信息
list:
付款单--该接口可以弃用
付款单列表信息, status: 200(成功), return: 付款单信息列表
retrieve:
查询某一个付款单
查询指定ID的付款单, status: 200(成功), return: 用户付款单
"""
queryset = PaymentModel.objects.all()
serializer_class = PaymentSerializer
pagination_class = GlobalPagination
def get_queryset(self):
if self.action == 'find': # 过滤查询
# 获取请求参数(在json中)
number_code = self.request.data.get('number_code', None)
check_user = self.request.data.get('check_user', 0)
start_date = self.request.data.get('start_date', None)
end_date = self.request.data.get('start_date', None)
supplier = self.request.data.get('supplier', 0)
operator_user = self.request.data.get('operator_user', 0)
status = self.request.data.get('status', None)
account = self.request.data.get('account', 0)
purchase_number_code = self.request.data.get('purchase_number_code', None)
query = Q()
if check_user:
query.add(Q(check_user__id=check_user), 'AND')
if account:
query.add(Q(account__id=account), 'AND')
if purchase_number_code:
query.add(Q(purchase__number_code__contains=purchase_number_code), 'AND')
if start_date:
query.add(Q(pay_date__gt=start_date), 'AND')
if end_date:
query.add(Q(pay_date__lt=end_date), 'AND')
if supplier:
query.add(Q(supplier__id=supplier), '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 PaymentModel.objects.filter(query).distinct().all()
else:
return PaymentModel.objects.all()
params = openapi.Schema(type=openapi.TYPE_OBJECT, properties={
'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"),
'supplier': openapi.Schema(type=openapi.TYPE_INTEGER, description="供应商的ID"),
'operator_user': openapi.Schema(type=openapi.TYPE_INTEGER, description="财务人员的ID"),
'check_user': openapi.Schema(type=openapi.TYPE_INTEGER, description="审核人员的ID"),
'account': openapi.Schema(type=openapi.TYPE_INTEGER, description="结算账户的ID"),
'purchase_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(PaymentViewSet, 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 item in queryset:
pass

@ -22,7 +22,7 @@ class PurchaseModel(BaseModel):
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,
check_user = models.ForeignKey('erp_system.UserModel', related_name='checker2_purchase_list', null=True, blank=True, on_delete=models.SET_NULL,
verbose_name='审核人员,不能修改')
# 增加一个冗余字段
check_user_name = models.CharField('操作人员的真实姓名', max_length=20, null=True, blank=True)

@ -35,7 +35,7 @@ class PurchaseItemsSerializer(serializers.ModelSerializer):
goods_id=obj.goods.id).exclude(purchase_storage__status='0')\
.aggregate(sum=Sum('purchase_count'))
if in_count:
return in_count['sum']
return in_count['sum'] if in_count['sum'] else 0
return 0
class PurchaseSerializer(serializers.ModelSerializer):

@ -25,12 +25,12 @@ class PurchaseStorageModel(BaseModel):
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='operator_in_list', null=True,
operator_user = models.ForeignKey('erp_system.UserModel', related_name='operator4_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', null=True, blank=True, on_delete=models.SET_NULL,
check_user = models.ForeignKey('erp_system.UserModel', related_name='checker3_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)

@ -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 in_storage_views
from rest_framework_jwt.views import obtain_jwt_token
urlpatterns = [
# path('admin/', admin.site.urls),
]
router = DefaultRouter()
router.register('storage', in_storage_views.InStorageViewSet)
urlpatterns += router.urls

@ -160,7 +160,7 @@ class InStorageViewSet(viewsets.ModelViewSet, MultipleDestroyMixin, MultipleAudi
.aggregate(my_sum=Sum('number_count'))
in_count = 0
if in_count_dict:
in_count = in_count_dict['my_sum']
in_count = in_count_dict['my_sum'] if in_count_dict['my_sum'] else 0
# 第一种情况: 已经入库数量 + 当前正在入库的数量 == 采购总数量。
if (in_count + item.number_count) == item.purchase.number_count:
item.purchase.status = '3' # 全部入库

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

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

Loading…
Cancel
Save