mirror of
https://github.com/himool/HimoolERP.git
synced 2024-09-20 14:56:00 +08:00
feat: 应收欠款, 应付欠款
This commit is contained in:
parent
8aa5363834
commit
a7944caa4b
|
@ -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]
|
||||||
|
|
||||||
|
|
|
@ -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']
|
||||||
|
|
|
@ -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',
|
||||||
]
|
]
|
||||||
|
|
|
@ -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',
|
||||||
]
|
]
|
||||||
|
|
|
@ -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')
|
||||||
|
|
|
@ -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',
|
||||||
]
|
]
|
||||||
|
|
|
@ -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',
|
||||||
]
|
]
|
||||||
|
|
|
@ -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',
|
||||||
]
|
]
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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',
|
||||||
]
|
]
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -3,5 +3,8 @@
|
||||||
|
|
||||||
## 功能
|
## 功能
|
||||||
|
|
||||||
|
- 查询应付欠款:
|
||||||
|
[/api/supplier_arrears/]{search, page, has_arrears: true}
|
||||||
|
|
||||||
|
|
||||||
## 其他接口
|
## 其他接口
|
||||||
|
|
|
@ -3,5 +3,8 @@
|
||||||
|
|
||||||
## 功能
|
## 功能
|
||||||
|
|
||||||
|
- 查询应收欠款:
|
||||||
|
[/api/client_arrears/]{search, page, has_arrears: true}
|
||||||
|
|
||||||
|
|
||||||
## 其他接口
|
## 其他接口
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -3,5 +3,8 @@
|
||||||
|
|
||||||
## 功能
|
## 功能
|
||||||
|
|
||||||
|
- 查询资金流水:
|
||||||
|
[/api/finance_flows/]
|
||||||
|
|
||||||
|
|
||||||
## 其他接口
|
## 其他接口
|
||||||
|
|
Loading…
Reference in a new issue