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