forked from erp-dev/erp
feat: BalanceChangeRecord
This commit is contained in:
@@ -25,15 +25,25 @@ class BalanceService:
|
||||
merchant: basic_info_models.Merchant,
|
||||
supplier: basic_info_models.Supplier,
|
||||
delta: Decimal,
|
||||
source_type: models.BalanceChangeSourceEnum,
|
||||
source_id: int,
|
||||
request_id: str | None = None,
|
||||
remarks: str | None = '',
|
||||
extra_meta: Dict[str, Any] | None = None,
|
||||
):
|
||||
with transaction.atomic():
|
||||
balance, _ = models.SupplierBalance.objects.select_for_update().get_or_create(
|
||||
merchant=merchant,
|
||||
supplier=supplier,
|
||||
defaults={'balance': Decimal('0')},
|
||||
)
|
||||
balance.balance += delta
|
||||
balance.save(update_fields=['balance', 'updated_at'])
|
||||
BalanceService._adjust_balance(
|
||||
merchant=merchant,
|
||||
counterparty=supplier,
|
||||
balance_model=models.SupplierBalance,
|
||||
balance_field='supplier',
|
||||
delta=delta,
|
||||
target_type=models.BalanceChangeTargetEnum.SUPPLIER,
|
||||
source_type=source_type,
|
||||
source_id=source_id,
|
||||
request_id=request_id,
|
||||
remarks=remarks,
|
||||
extra_meta=extra_meta,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def adjust_customer_balance(
|
||||
@@ -41,16 +51,77 @@ class BalanceService:
|
||||
merchant: basic_info_models.Merchant,
|
||||
customer: basic_info_models.Customer,
|
||||
delta: Decimal,
|
||||
source_type: models.BalanceChangeSourceEnum,
|
||||
source_id: int,
|
||||
request_id: str | None = None,
|
||||
remarks: str | None = '',
|
||||
extra_meta: Dict[str, Any] | None = None,
|
||||
):
|
||||
BalanceService._adjust_balance(
|
||||
merchant=merchant,
|
||||
counterparty=customer,
|
||||
balance_model=models.CustomerBalance,
|
||||
balance_field='customer',
|
||||
delta=delta,
|
||||
target_type=models.BalanceChangeTargetEnum.CUSTOMER,
|
||||
source_type=source_type,
|
||||
source_id=source_id,
|
||||
request_id=request_id,
|
||||
remarks=remarks,
|
||||
extra_meta=extra_meta,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _adjust_balance(
|
||||
*,
|
||||
merchant: basic_info_models.Merchant,
|
||||
counterparty,
|
||||
balance_model,
|
||||
balance_field: str,
|
||||
delta: Decimal,
|
||||
target_type: models.BalanceChangeTargetEnum,
|
||||
source_type: models.BalanceChangeSourceEnum,
|
||||
source_id: int,
|
||||
request_id: str | None,
|
||||
remarks: str | None,
|
||||
extra_meta: Dict[str, Any] | None,
|
||||
):
|
||||
meta_payload = extra_meta or {}
|
||||
remarks_value = remarks or ''
|
||||
with transaction.atomic():
|
||||
balance, _ = models.CustomerBalance.objects.select_for_update().get_or_create(
|
||||
balance, _ = balance_model.objects.select_for_update().get_or_create(
|
||||
merchant=merchant,
|
||||
customer=customer,
|
||||
defaults={'balance': Decimal('0')},
|
||||
**{balance_field: counterparty},
|
||||
)
|
||||
before = balance.balance
|
||||
balance.balance += delta
|
||||
balance.save(update_fields=['balance', 'updated_at'])
|
||||
|
||||
record_kwargs = {
|
||||
'merchant': merchant,
|
||||
'target_type': target_type,
|
||||
'source_type': source_type,
|
||||
'source_id': source_id,
|
||||
'delta': delta,
|
||||
'direction': (
|
||||
models.BalanceChangeDirectionEnum.INCREASE
|
||||
if delta >= 0
|
||||
else models.BalanceChangeDirectionEnum.DECREASE
|
||||
),
|
||||
'balance_before': before,
|
||||
'balance_after': balance.balance,
|
||||
'request_id': request_id,
|
||||
'remarks': remarks_value,
|
||||
'extra_meta': meta_payload,
|
||||
}
|
||||
if target_type == models.BalanceChangeTargetEnum.SUPPLIER:
|
||||
record_kwargs['supplier'] = counterparty
|
||||
else:
|
||||
record_kwargs['customer'] = counterparty
|
||||
|
||||
models.BalanceChangeRecord.objects.create(**record_kwargs)
|
||||
|
||||
@staticmethod
|
||||
def get_customer_balance(
|
||||
*,
|
||||
@@ -373,6 +444,8 @@ def review_payment_order(
|
||||
merchant=locked.merchant,
|
||||
supplier=locked.supplier,
|
||||
delta=-locked.amount,
|
||||
source_type=models.BalanceChangeSourceEnum.PAYMENT_ORDER,
|
||||
source_id=locked.id,
|
||||
)
|
||||
locked.refresh_from_db(fields=['status', 'updated_at'])
|
||||
return locked
|
||||
@@ -424,6 +497,8 @@ def review_receipt_order(
|
||||
merchant=locked.merchant,
|
||||
customer=locked.customer,
|
||||
delta=-locked.amount,
|
||||
source_type=models.BalanceChangeSourceEnum.RECEIPT_ORDER,
|
||||
source_id=locked.id,
|
||||
)
|
||||
locked.refresh_from_db(fields=['status', 'updated_at'])
|
||||
return locked
|
||||
@@ -577,6 +652,8 @@ def _approve_purchase_order(
|
||||
merchant=locked_order.merchant,
|
||||
supplier=locked_order.supplier,
|
||||
delta=locked_order.get_total_amount(),
|
||||
source_type=models.BalanceChangeSourceEnum.PURCHASE_ORDER,
|
||||
source_id=locked_order.id,
|
||||
)
|
||||
|
||||
created_by_id = getattr(reviewed_by, 'id', None)
|
||||
@@ -632,6 +709,8 @@ def _approve_sales_order(
|
||||
merchant=locked_order.merchant,
|
||||
customer=locked_order.customer,
|
||||
delta=locked_order.get_total_amount(),
|
||||
source_type=models.BalanceChangeSourceEnum.SALES_ORDER,
|
||||
source_id=locked_order.id,
|
||||
)
|
||||
|
||||
created_by_id = getattr(reviewed_by, 'id', None)
|
||||
|
||||
Reference in New Issue
Block a user