1
0
forked from erp-dev/erp

feat: BalanceChangeRecord

This commit is contained in:
2025-12-01 15:22:59 +08:00
parent 9acc4e14fc
commit a3b4af2602
8 changed files with 359 additions and 14 deletions

View File

@@ -179,6 +179,15 @@ class PurchaseOrderServiceTestCase(TestCase):
supplier=self.supplier,
)
self.assertEqual(balance.balance, purchase_order.get_total_amount())
record = business_models.BalanceChangeRecord.objects.get(
merchant=self.merchant,
source_type=business_models.BalanceChangeSourceEnum.PURCHASE_ORDER,
source_id=purchase_order.id,
)
self.assertEqual(record.target_type, business_models.BalanceChangeTargetEnum.SUPPLIER)
self.assertEqual(record.delta, purchase_order.get_total_amount())
self.assertEqual(record.balance_after, balance.balance)
self.assertEqual(record.direction, business_models.BalanceChangeDirectionEnum.INCREASE)
def test_create_purchase_order_without_items_raises(self):
with self.assertRaises(ValueError):
@@ -209,6 +218,13 @@ class PurchaseOrderServiceTestCase(TestCase):
reviewed_by=self.user,
)
self.assertEqual(cancelled.status, business_models.PurchaseOrderStatusEnum.CANCELLED)
self.assertFalse(
business_models.BalanceChangeRecord.objects.filter(
merchant=self.merchant,
source_type=business_models.BalanceChangeSourceEnum.PURCHASE_ORDER,
source_id=purchase_order.id,
).exists()
)
def test_review_purchase_order_cancel_blocked_after_stock_created(self):
purchase_order = services.create_purchase_order(
@@ -337,6 +353,15 @@ class SalesOrderServiceTestCase(TestCase):
customer=self.customer,
)
self.assertEqual(balance.balance, sales_order.get_total_amount())
record = business_models.BalanceChangeRecord.objects.get(
merchant=self.merchant,
source_type=business_models.BalanceChangeSourceEnum.SALES_ORDER,
source_id=sales_order.id,
)
self.assertEqual(record.target_type, business_models.BalanceChangeTargetEnum.CUSTOMER)
self.assertEqual(record.delta, sales_order.get_total_amount())
self.assertEqual(record.balance_after, balance.balance)
self.assertEqual(record.direction, business_models.BalanceChangeDirectionEnum.INCREASE)
def test_sales_order_cancel_blocked_after_stock_created(self):
sales_order = services.create_sales_order(
@@ -361,6 +386,13 @@ class SalesOrderServiceTestCase(TestCase):
target_status=business_models.SalesOrderStatusEnum.CANCELLED,
reviewed_by=self.user,
)
self.assertFalse(
business_models.BalanceChangeRecord.objects.filter(
merchant=self.merchant,
source_type=business_models.BalanceChangeSourceEnum.SALES_ORDER,
source_id=sales_order.id,
).exists()
)
def test_sales_order_requires_consume_ids_for_strict_out(self):
with self.assertRaises(ValueError):
@@ -443,6 +475,14 @@ class PaymentReceiptServiceTestCase(TestCase):
supplier=self.supplier,
)
self.assertEqual(balance.balance, Decimal('-120.50'))
record = business_models.BalanceChangeRecord.objects.get(
merchant=self.merchant,
source_type=business_models.BalanceChangeSourceEnum.PAYMENT_ORDER,
source_id=order.id,
)
self.assertEqual(record.direction, business_models.BalanceChangeDirectionEnum.DECREASE)
self.assertEqual(record.delta, Decimal('-120.50'))
self.assertEqual(record.balance_after, balance.balance)
with self.assertRaises(ValueError):
services.review_payment_order(
payment_order=order,
@@ -465,6 +505,13 @@ class PaymentReceiptServiceTestCase(TestCase):
reviewed_by=self.operator,
)
self.assertEqual(cancelled.status, business_models.ReceiptOrderStatusEnum.CANCELLED)
self.assertFalse(
business_models.BalanceChangeRecord.objects.filter(
merchant=self.merchant,
source_type=business_models.BalanceChangeSourceEnum.RECEIPT_ORDER,
source_id=order.id,
).exists()
)
def test_payment_amount_must_be_positive(self):
with self.assertRaises(ValueError):
@@ -500,6 +547,44 @@ class PaymentReceiptServiceTestCase(TestCase):
customer=self.customer,
)
self.assertEqual(balance.balance, Decimal('-10'))
records = business_models.BalanceChangeRecord.objects.filter(
merchant=self.merchant,
source_type=business_models.BalanceChangeSourceEnum.RECEIPT_ORDER,
source_id=order.id,
)
self.assertEqual(records.count(), 1)
self.assertEqual(records.first().balance_after, balance.balance)
def test_payment_approval_is_idempotent(self):
order = services.create_payment_order(
merchant=self.merchant,
supplier=self.supplier,
payment_date=timezone.now().date(),
amount='75.00',
operator=self.operator,
)
services.review_payment_order(
payment_order=order,
target_status=business_models.PaymentOrderStatusEnum.APPROVED,
reviewed_by=self.operator,
)
services.review_payment_order(
payment_order=order,
target_status=business_models.PaymentOrderStatusEnum.APPROVED,
reviewed_by=self.operator,
)
balance = business_models.SupplierBalance.objects.get(
merchant=self.merchant,
supplier=self.supplier,
)
self.assertEqual(balance.balance, Decimal('-75.00'))
records = business_models.BalanceChangeRecord.objects.filter(
merchant=self.merchant,
source_type=business_models.BalanceChangeSourceEnum.PAYMENT_ORDER,
source_id=order.id,
)
self.assertEqual(records.count(), 1)
self.assertEqual(records.first().balance_after, balance.balance)
class PurchaseOrderStockServiceTestCase(TestCase):
@@ -668,6 +753,13 @@ class SalesOrderConcurrencyTestCase(TransactionTestCase):
customer=self.customer,
)
self.assertEqual(balance.balance, self.sales_order.get_total_amount())
records = business_models.BalanceChangeRecord.objects.filter(
merchant=self.merchant,
source_type=business_models.BalanceChangeSourceEnum.SALES_ORDER,
source_id=self.sales_order.id,
)
self.assertEqual(records.count(), 1)
self.assertEqual(records.first().balance_after, balance.balance)
def tearDown(self):
connections.close_all()