feat: 应收欠款, 应付欠款

This commit is contained in:
Czw996 2021-12-24 23:35:24 +08:00
parent 8aa5363834
commit a7944caa4b
17 changed files with 200 additions and 6 deletions

View file

@ -107,7 +107,7 @@ class ClientSerializer(BaseSerializer):
class Meta: class Meta:
model = Client model = Client
read_only_fields = ['id', 'level_display', 'category_name', 'arrears_amount', 'has_arrears'] read_only_fields = ['id', 'level_display', 'category_name']
fields = ['number', 'name', 'level', 'category', 'contact', 'phone', 'email', 'address', fields = ['number', 'name', 'level', 'category', 'contact', 'phone', 'email', 'address',
'remark', 'order', 'is_active', 'initial_arrears_amount', *read_only_fields] 'remark', 'order', 'is_active', 'initial_arrears_amount', *read_only_fields]
@ -221,7 +221,7 @@ class SupplierSerializer(BaseSerializer):
class Meta: class Meta:
model = Supplier model = Supplier
read_only_fields = ['id', 'category_name', 'arrears_amount', 'has_arrears'] read_only_fields = ['id', 'category_name']
fields = ['number', 'name', 'category', 'contact', 'phone', 'email', 'address', 'bank_account', fields = ['number', 'name', 'category', 'contact', 'phone', 'email', 'address', 'bank_account',
'bank_name', 'remark', 'order', 'is_active', 'initial_arrears_amount', *read_only_fields] 'bank_name', 'remark', 'order', 'is_active', 'initial_arrears_amount', *read_only_fields]

View file

@ -161,7 +161,7 @@ class ClientViewSet(ModelViewSet, DataProtectMixin, ExportMixin, ImportMixin):
serializer_class = ClientSerializer serializer_class = ClientSerializer
permission_classes = [IsAuthenticated, ClientPermission] permission_classes = [IsAuthenticated, ClientPermission]
filterset_fields = ['level', 'category', 'has_arrears', 'is_active'] filterset_fields = ['level', 'category', 'is_active']
search_fields = ['number', 'name', 'contact', 'remark'] search_fields = ['number', 'name', 'contact', 'remark']
ordering_fields = ['id', 'number', 'name', 'order'] ordering_fields = ['id', 'number', 'name', 'order']
ordering = ['order', 'id'] ordering = ['order', 'id']
@ -274,7 +274,7 @@ class SupplierViewSet(ModelViewSet, DataProtectMixin, ExportMixin, ImportMixin):
serializer_class = SupplierSerializer serializer_class = SupplierSerializer
permission_classes = [IsAuthenticated, SupplierPermission] permission_classes = [IsAuthenticated, SupplierPermission]
filterset_fields = ['category', 'has_arrears', 'is_active'] filterset_fields = ['category', 'is_active']
search_fields = ['number', 'name', 'contact', 'remark'] search_fields = ['number', 'name', 'contact', 'remark']
ordering_fields = ['id', 'number', 'name', 'order'] ordering_fields = ['id', 'number', 'name', 'order']
ordering = ['order', 'id'] ordering = ['order', 'id']

View file

@ -1,6 +1,14 @@
from extensions.permissions import ModelPermission from extensions.permissions import ModelPermission
class ClientArrearsPermission(ModelPermission):
code = 'client_arrears'
class SupplierArrearsPermission(ModelPermission):
code = 'supplier_arrears'
class PaymentOrderPermission(ModelPermission): class PaymentOrderPermission(ModelPermission):
code = 'payment_order' code = 'payment_order'
@ -18,6 +26,7 @@ class AccountTransferRecordPermission(ModelPermission):
__all__ = [ __all__ = [
'ClientArrearsPermission', 'SupplierArrearsPermission',
'PaymentOrderPermission', 'CollectionOrderPermission', 'PaymentOrderPermission', 'CollectionOrderPermission',
'ChargeOrderPermission', 'AccountTransferRecordPermission', 'ChargeOrderPermission', 'AccountTransferRecordPermission',
] ]

View file

@ -6,6 +6,31 @@ from apps.data.models import *
from apps.system.models import * from apps.system.models import *
class ClientArrearsSerializer(BaseSerializer):
"""应收欠款"""
level_display = CharField(source='get_level_display', read_only=True, label='等级')
category_name = CharField(source='category.name', read_only=True, label='分类名称')
class Meta:
model = Client
fields = ['id', 'number', 'name', 'level', 'level_display', 'category', 'category_name',
'contact', 'phone', 'email', 'address', 'remark', 'order', 'is_active',
'initial_arrears_amount', 'arrears_amount', 'has_arrears']
class SupplierArrearsSerializer(BaseSerializer):
"""应付欠款"""
category_name = CharField(source='category.name', read_only=True, label='分类名称')
class Meta:
model = Supplier
fields = ['id', 'number', 'name', 'category', 'category_name', 'contact', 'phone', 'email',
'address', 'bank_account', 'bank_name', 'remark', 'order', 'is_active',
'initial_arrears_amount', 'arrears_amount', 'has_arrears']
class PaymentOrderSerializer(BaseSerializer): class PaymentOrderSerializer(BaseSerializer):
"""付款单据""" """付款单据"""
@ -226,10 +251,10 @@ class ChargeOrderSerializer(BaseSerializer):
client = attrs.get('client') client = attrs.get('client')
if (supplier and client) or not (supplier or client): if (supplier and client) or not (supplier or client):
raise ValidationError('供应商或客户选择重复') raise ValidationError('供应商或客户选择重复')
if attrs['type'] != attrs['charge_item'].type: if attrs['type'] != attrs['charge_item'].type:
raise ValidationError('收支类型与收支项目不匹配') raise ValidationError('收支类型与收支项目不匹配')
if attrs['charge_amount'] > attrs['total_amount']: if attrs['charge_amount'] > attrs['total_amount']:
raise ValidationError('实收/付金额大于应收/付金额') raise ValidationError('实收/付金额大于应收/付金额')
return super().validate(attrs) return super().validate(attrs)
@ -292,6 +317,7 @@ class AccountTransferRecordSerializer(BaseSerializer):
__all__ = [ __all__ = [
'ClientArrearsSerializer', 'SupplierArrearsSerializer',
'PaymentOrderSerializer', 'CollectionOrderSerializer', 'PaymentOrderSerializer', 'CollectionOrderSerializer',
'ChargeOrderSerializer', 'AccountTransferRecordSerializer', 'ChargeOrderSerializer', 'AccountTransferRecordSerializer',
] ]

View file

@ -3,6 +3,8 @@ from apps.finance.views import *
router = BaseRouter() router = BaseRouter()
router.register('client_arrears', ClientArrearsViewSet, 'client_arrears')
router.register('supplier_arrears', SupplierArrearsViewSet, 'supplier_arrears')
router.register('payment_orders', PaymentOrderViewSet, 'payment_order') router.register('payment_orders', PaymentOrderViewSet, 'payment_order')
router.register('collection_orders', CollectionOrderViewSet, 'collection_order') router.register('collection_orders', CollectionOrderViewSet, 'collection_order')
router.register('charge_orders', ChargeOrderViewSet, 'charge_order') router.register('charge_orders', ChargeOrderViewSet, 'charge_order')

View file

@ -9,6 +9,33 @@ from apps.finance.filters import *
from apps.finance.schemas import * from apps.finance.schemas import *
from apps.finance.models import * from apps.finance.models import *
from apps.flow.models import * from apps.flow.models import *
from apps.data.models import *
class ClientArrearsViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin):
"""应收欠款"""
serializer_class = ClientArrearsSerializer
permission_classes = [IsAuthenticated, ClientArrearsPermission]
filterset_fields = ['category', 'level', 'is_active', 'has_arrears']
search_fields = ['number', 'name', 'contact', 'remark']
ordering_fields = ['id', 'number', 'name', 'order', 'initial_arrears_amount', 'arrears_amount']
ordering = ['order', 'id']
select_related_fields = ['category']
queryset = Client.objects.all()
class SupplierArrearsViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin):
"""应付欠款"""
serializer_class = SupplierArrearsSerializer
permission_classes = [IsAuthenticated, SupplierArrearsPermission]
filterset_fields = ['category', 'is_active', 'has_arrears']
search_fields = ['number', 'name', 'contact', 'remark']
ordering_fields = ['id', 'number', 'name', 'order', 'initial_arrears_amount', 'arrears_amount']
ordering = ['order', 'id']
select_related_fields = ['category']
queryset = Supplier.objects.all()
class PaymentOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, CreateModelMixin): class PaymentOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, CreateModelMixin):
@ -416,6 +443,7 @@ class AccountTransferRecordViewSet(BaseViewSet, ListModelMixin, RetrieveModelMix
__all__ = [ __all__ = [
'ClientArrearsViewSet', 'SupplierArrearsViewSet',
'PaymentOrderViewSet', 'CollectionOrderViewSet', 'PaymentOrderViewSet', 'CollectionOrderViewSet',
'ChargeOrderViewSet', 'AccountTransferRecordViewSet', 'ChargeOrderViewSet', 'AccountTransferRecordViewSet',
] ]

View file

@ -30,6 +30,10 @@ PurchaseOrderOptionPermission = BasePermission
# Sales # Sales
SalesOrderOptionPermission = BasePermission SalesOrderOptionPermission = BasePermission
# Finance
ClientArrearsOptionPermission = BasePermission
SupplierArrearsOptionPermission = BasePermission
__all__ = [ __all__ = [
'RoleOptionPermission', 'UserOptionPermission', 'RoleOptionPermission', 'UserOptionPermission',
@ -39,4 +43,5 @@ __all__ = [
'BatchOptionPermission', 'InventoryOptionPermission', 'BatchOptionPermission', 'InventoryOptionPermission',
'PurchaseOrderOptionPermission', 'PurchaseOrderOptionPermission',
'SalesOrderOptionPermission', 'SalesOrderOptionPermission',
'ClientArrearsOptionPermission', 'SupplierArrearsOptionPermission',
] ]

View file

@ -202,6 +202,26 @@ class SalesOrderOptionSerializer(ModelSerializer):
'creator_name', 'create_time', 'sales_goods_items', 'sales_account_items'] 'creator_name', 'create_time', 'sales_goods_items', 'sales_account_items']
# Finance
class ClientArrearsOptionSerializer(BaseSerializer):
category_name = CharField(source='category.name', read_only=True, label='分类名称')
class Meta:
model = Client
fields = ['id', 'number', 'name', 'category', 'category_name', 'contact', 'phone', 'email',
'address', 'remark', 'is_active', 'arrears_amount', 'has_arrears']
class SupplierArrearsOptionSerializer(BaseSerializer):
category_name = CharField(source='category.name', read_only=True, label='分类名称')
class Meta:
model = Supplier
fields = ['id', 'number', 'name', 'category', 'category_name', 'contact', 'phone', 'email',
'address', 'remark', 'is_active', 'arrears_amount', 'has_arrears']
__all__ = [ __all__ = [
'RoleOptionSerializer', 'UserOptionSerializer', 'RoleOptionSerializer', 'UserOptionSerializer',
'WarehouseOptionSerializer', 'WarehouseOptionSerializer',
@ -212,4 +232,5 @@ __all__ = [
'BatchOptionSerializer', 'InventoryOptionSerializer', 'BatchOptionSerializer', 'InventoryOptionSerializer',
'PurchaseOrderOptionSerializer', 'PurchaseOrderOptionSerializer',
'SalesOrderOptionSerializer', 'SalesOrderOptionSerializer',
'ClientArrearsOptionSerializer', 'SupplierArrearsOptionSerializer',
] ]

View file

@ -31,4 +31,8 @@ router.register('purchase_orders/options', PurchaseOrderOptionViewSet, 'purchase
# Sales # Sales
router.register('sales_orders/options', SalesOrderOptionViewSet, 'sales_order_option') router.register('sales_orders/options', SalesOrderOptionViewSet, 'sales_order_option')
# Finance
router.register('client_arrears/options', ClientArrearsOptionViewSet, 'client_arrear_option')
router.register('supplier_arrears/options', SupplierArrearsOptionViewSet, 'supplier_arrear_option')
urlpatterns = router.urls urlpatterns = router.urls

View file

@ -165,6 +165,29 @@ class SalesOrderOptionViewSet(LimitedOptionViewSet):
queryset = SalesOrder.objects.all() queryset = SalesOrder.objects.all()
# Finance
class ClientArrearsOptionViewSet(InfiniteOptionViewSet):
serializer_class = ClientArrearsOptionSerializer
permission_classes = [IsAuthenticated, ClientArrearsOptionPermission]
filterset_fields = ['category', 'level', 'is_active', 'has_arrears']
search_fields = ['number', 'name', 'contact', 'remark']
ordering_fields = ['id', 'number', 'name', 'order', 'arrears_amount']
ordering = ['order', 'id']
select_related_fields = ['category']
queryset = Client.objects.all()
class SupplierArrearsOptionViewSet(InfiniteOptionViewSet):
serializer_class = SupplierArrearsOptionSerializer
permission_classes = [IsAuthenticated, SupplierArrearsOptionPermission]
filterset_fields = ['category', 'is_active', 'has_arrears']
search_fields = ['number', 'name', 'contact', 'remark']
ordering_fields = ['id', 'number', 'name', 'order', 'arrears_amount']
ordering = ['order', 'id']
select_related_fields = ['category']
queryset = Supplier.objects.all()
__all__ = [ __all__ = [
'RoleOptionViewSet', 'UserOptionViewSet', 'RoleOptionViewSet', 'UserOptionViewSet',
'WarehouseOptionViewSet', 'WarehouseOptionViewSet',
@ -175,4 +198,5 @@ __all__ = [
'BatchOptionViewSet', 'InventoryOptionViewSet', 'BatchOptionViewSet', 'InventoryOptionViewSet',
'PurchaseOrderOptionViewSet', 'PurchaseOrderOptionViewSet',
'SalesOrderOptionViewSet', 'SalesOrderOptionViewSet',
'ClientArrearsOptionViewSet', 'SupplierArrearsOptionViewSet',
] ]

View file

@ -3,5 +3,20 @@
## 功能 ## 功能
- 查询/创建付款单:
[/api/payment_orders/]
- 获取付款单号:
[/api/payment_orders/number/]
- 作废付款单:
[/api/payment_orders/{id}/void/]
## 其他接口 ## 其他接口
- 供应商选项:
[/api/supplier_arrears/options/]{is_active: true, has_arrears: true}
- 经手人选项:
[/api/users/options/]{is_active: true}

View file

@ -3,5 +3,8 @@
## 功能 ## 功能
- 查询应付欠款:
[/api/supplier_arrears/]{search, page, has_arrears: true}
## 其他接口 ## 其他接口

View file

@ -3,5 +3,8 @@
## 功能 ## 功能
- 查询应收欠款:
[/api/client_arrears/]{search, page, has_arrears: true}
## 其他接口 ## 其他接口

View file

@ -3,5 +3,20 @@
## 功能 ## 功能
- 查询/创建收款单:
[/api/collection_orders/]
- 获取收款单号:
[/api/collection_orders/number/]
- 作废收款单:
[/api/collection_orders/{id}/void/]
## 其他接口 ## 其他接口
- 客户选项:
[/api/client_arrears/options/]{is_active: true, has_arrears: true}
- 经手人选项:
[/api/users/options/]{is_active: true}

View file

@ -3,5 +3,29 @@
## 功能 ## 功能
- 查询/创建收支单:
[/api/charge_orders/]
- 获取收支单号:
[/api/charge_orders/number/]
- 作废收支单:
[/api/charge_orders/{id}/void/]
## 其他接口 ## 其他接口
- 客户选项:
[/api/clients/options/]{is_active: true}
- 供应商选项:
[/api/suppliers/options/]{is_active: true}
- 收支项目选项:
[/api/charge_items/options/]
- 经手人选项:
[/api/users/options/]{is_active: true}
- 结算账户选项:
[/api/accounts/options/]{is_active: true}

View file

@ -3,5 +3,17 @@
## 功能 ## 功能
- 查询/创建账户转账:
[/api/account_transfer_records/]
- 作废账户转账:
[/api/account_transfer_records/{id}/void/]
## 其他接口 ## 其他接口
- 结算账户选项:
[/api/accounts/options/]{is_active: true}
- 经手人选项:
[/api/users/options/]{is_active: true}

View file

@ -3,5 +3,8 @@
## 功能 ## 功能
- 查询资金流水:
[/api/finance_flows/]
## 其他接口 ## 其他接口