1
0
forked from erp-dev/erp
Files
erpnew/business/tests/test_balance_before_snapshot.py
2026-06-22 22:27:28 +08:00

226 lines
8.7 KiB
Python

from decimal import Decimal
from django.test import TestCase
from django.utils import timezone
from basic_info import models as basic_models
from business import models as business_models, services
from .fixtures import create_basic_fixtures, create_sales_fixtures
class OrderBalanceBeforeSnapshotTestCase(TestCase):
def setUp(self):
(
self.supplier_merchant,
self.supplier,
_supplier_strict_warehouse,
self.supplier_warehouse,
self.supplier_product,
self.supplier_operator,
) = create_basic_fixtures()
(
self.customer_merchant,
self.customer,
_customer_strict_warehouse,
self.customer_warehouse,
_customer_strict_out_warehouse,
self.customer_product,
self.customer_operator,
) = create_sales_fixtures()
def _supplier_items(self):
return [
{
'product_id': self.supplier_product.id,
'quantity': '3',
'num_of_rolls': 1,
'price': '12.50',
}
]
def _customer_items(self):
return [
{
'product_id': self.customer_product.id,
'quantity': '4',
'num_of_rolls': 1,
'price': '8.25',
}
]
def _create_supplier_orders(self):
purchase_order = services.create_purchase_order(
merchant=self.supplier_merchant,
supplier=self.supplier,
order_date=timezone.now().date(),
warehouse=self.supplier_warehouse,
operator=self.supplier_operator,
items=self._supplier_items(),
)
purchase_return_order = services.create_purchase_return_order(
merchant=self.supplier_merchant,
supplier=self.supplier,
return_date=timezone.now().date(),
warehouse=self.supplier_warehouse,
operator=self.supplier_operator,
items=self._supplier_items(),
purchase_order=purchase_order,
)
return purchase_order, purchase_return_order
def _create_customer_orders(self):
sales_order = services.create_sales_order(
merchant=self.customer_merchant,
customer=self.customer,
order_date=timezone.now().date(),
warehouse=self.customer_warehouse,
operator=self.customer_operator,
items=self._customer_items(),
)
sales_return_order = services.create_sales_return_order(
merchant=self.customer_merchant,
customer=self.customer,
return_date=timezone.now().date(),
warehouse=self.customer_warehouse,
operator=self.customer_operator,
items=self._customer_items(),
sales_order=sales_order,
)
return sales_order, sales_return_order
def test_all_four_creation_services_capture_current_balance(self):
business_models.SupplierBalance.objects.create(
merchant=self.supplier_merchant,
supplier=self.supplier,
balance=Decimal('123.45'),
)
business_models.CustomerBalance.objects.create(
merchant=self.customer_merchant,
customer=self.customer,
balance=Decimal('-67.89'),
)
purchase_order, purchase_return_order = self._create_supplier_orders()
sales_order, sales_return_order = self._create_customer_orders()
self.assertEqual(purchase_order.balance_before_snapshot, Decimal('123.45'))
self.assertEqual(purchase_return_order.balance_before_snapshot, Decimal('123.45'))
self.assertEqual(sales_order.balance_before_snapshot, Decimal('-67.89'))
self.assertEqual(sales_return_order.balance_before_snapshot, Decimal('-67.89'))
def test_missing_balance_rows_snapshot_zero_instead_of_null(self):
purchase_order, purchase_return_order = self._create_supplier_orders()
sales_order, sales_return_order = self._create_customer_orders()
for order in (
purchase_order,
purchase_return_order,
sales_order,
sales_return_order,
):
self.assertEqual(order.balance_before_snapshot, Decimal('0'))
self.assertIsNotNone(order.balance_before_snapshot)
def test_updates_and_later_balance_changes_do_not_recalculate_snapshot(self):
supplier_balance = business_models.SupplierBalance.objects.create(
merchant=self.supplier_merchant,
supplier=self.supplier,
balance=Decimal('100.00'),
)
customer_balance = business_models.CustomerBalance.objects.create(
merchant=self.customer_merchant,
customer=self.customer,
balance=Decimal('200.00'),
)
purchase_order, purchase_return_order = self._create_supplier_orders()
sales_order, sales_return_order = self._create_customer_orders()
other_supplier = basic_models.Supplier.objects.create(
merchant=self.supplier_merchant,
name='快照测试供应商B',
)
other_customer = basic_models.Customer.objects.create(
merchant=self.customer_merchant,
name='快照测试客户B',
)
business_models.SupplierBalance.objects.create(
merchant=self.supplier_merchant,
supplier=other_supplier,
balance=Decimal('999.00'),
)
business_models.CustomerBalance.objects.create(
merchant=self.customer_merchant,
customer=other_customer,
balance=Decimal('888.00'),
)
supplier_balance.balance = Decimal('300.00')
supplier_balance.save(update_fields=['balance', 'updated_at'])
customer_balance.balance = Decimal('400.00')
customer_balance.save(update_fields=['balance', 'updated_at'])
services.update_purchase_order(
purchase_order=purchase_order,
supplier=other_supplier,
items=self._supplier_items(),
)
services.update_purchase_return_order(
purchase_return_order=purchase_return_order,
supplier=other_supplier,
items=self._supplier_items(),
)
services.update_sales_order(
sales_order=sales_order,
customer=other_customer,
items=self._customer_items(),
)
services.update_sales_return_order(
sales_return_order=sales_return_order,
customer=other_customer,
items=self._customer_items(),
)
for order in (purchase_order, purchase_return_order):
order.refresh_from_db()
self.assertEqual(order.balance_before_snapshot, Decimal('100.00'))
for order in (sales_order, sales_return_order):
order.refresh_from_db()
self.assertEqual(order.balance_before_snapshot, Decimal('200.00'))
def test_api_serializers_expose_snapshot_as_read_only(self):
business_models.SupplierBalance.objects.create(
merchant=self.supplier_merchant,
supplier=self.supplier,
balance=Decimal('123.45'),
)
business_models.CustomerBalance.objects.create(
merchant=self.customer_merchant,
customer=self.customer,
balance=Decimal('67.89'),
)
purchase_order, purchase_return_order = self._create_supplier_orders()
sales_order, sales_return_order = self._create_customer_orders()
from api_v1.views.business.purchase.views import PurchaseOrderSerializer
from api_v1.views.business.purchase_return.views import PurchaseReturnOrderSerializer
from api_v1.views.business.sales.views import SalesOrderSerializer
from api_v1.views.business.sales_return.views import SalesReturnOrderSerializer
cases = (
(PurchaseOrderSerializer, purchase_order, '123.45'),
(PurchaseReturnOrderSerializer, purchase_return_order, '123.45'),
(SalesOrderSerializer, sales_order, '67.89'),
(SalesReturnOrderSerializer, sales_return_order, '67.89'),
)
for serializer_class, order, expected in cases:
with self.subTest(serializer=serializer_class.__name__):
self.assertEqual(serializer_class(order).data['balance_before_snapshot'], expected)
serializer = serializer_class(
order,
data={'balance_before_snapshot': '9999.99'},
partial=True,
)
self.assertTrue(serializer.is_valid(), serializer.errors)
self.assertNotIn('balance_before_snapshot', serializer.validated_data)