forked from erp-dev/erp
feat: BalanceChangeRecord
This commit is contained in:
@@ -462,3 +462,89 @@ class CustomerBalance(ModelBase):
|
||||
verbose_name = '客户余额'
|
||||
verbose_name_plural = '客户余额'
|
||||
unique_together = ('merchant', 'customer')
|
||||
|
||||
|
||||
class BalanceChangeTargetEnum(models.IntegerChoices):
|
||||
SUPPLIER = 1, '供应商'
|
||||
CUSTOMER = 2, '客户'
|
||||
|
||||
|
||||
class BalanceChangeSourceEnum(models.IntegerChoices):
|
||||
PURCHASE_ORDER = 1, '采购单'
|
||||
SALES_ORDER = 2, '销售单'
|
||||
PAYMENT_ORDER = 3, '付款单'
|
||||
RECEIPT_ORDER = 4, '收款单'
|
||||
|
||||
|
||||
class BalanceChangeDirectionEnum(models.IntegerChoices):
|
||||
INCREASE = 1, '增加'
|
||||
DECREASE = 2, '减少'
|
||||
|
||||
|
||||
class BalanceChangeRecord(ModelBase):
|
||||
merchant = models.ForeignKey(
|
||||
basic_info_models.Merchant,
|
||||
on_delete=models.PROTECT,
|
||||
related_name='balance_change_records',
|
||||
verbose_name='所属商户',
|
||||
)
|
||||
supplier = models.ForeignKey(
|
||||
basic_info_models.Supplier,
|
||||
on_delete=models.PROTECT,
|
||||
related_name='balance_change_records',
|
||||
verbose_name='供应商',
|
||||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
customer = models.ForeignKey(
|
||||
basic_info_models.Customer,
|
||||
on_delete=models.PROTECT,
|
||||
related_name='balance_change_records',
|
||||
verbose_name='客户',
|
||||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
target_type = models.IntegerField(
|
||||
choices=BalanceChangeTargetEnum.choices,
|
||||
verbose_name='业务主体类型',
|
||||
)
|
||||
source_type = models.IntegerField(
|
||||
choices=BalanceChangeSourceEnum.choices,
|
||||
verbose_name='来源业务类型',
|
||||
)
|
||||
source_id = models.BigIntegerField(verbose_name='来源业务ID')
|
||||
delta = models.DecimalField(max_digits=15, decimal_places=2, verbose_name='变动金额')
|
||||
direction = models.IntegerField(
|
||||
choices=BalanceChangeDirectionEnum.choices,
|
||||
verbose_name='方向',
|
||||
)
|
||||
balance_before = models.DecimalField(max_digits=15, decimal_places=2, verbose_name='变动前余额')
|
||||
balance_after = models.DecimalField(max_digits=15, decimal_places=2, verbose_name='变动后余额')
|
||||
request_id = models.CharField(max_length=64, null=True, blank=True, verbose_name='幂等请求ID')
|
||||
remarks = models.TextField(blank=True, null=True, verbose_name='备注')
|
||||
extra_meta = models.JSONField(default=dict, blank=True, verbose_name='扩展信息')
|
||||
offset_to = models.BigIntegerField(null=True, blank=True, verbose_name='冲抵目标ID')
|
||||
offset_at = models.DateTimeField(null=True, blank=True, verbose_name='冲抵时间')
|
||||
offset_id = models.BigIntegerField(null=True, blank=True, verbose_name='冲抵来源ID')
|
||||
cancelled = models.BooleanField(default=False, verbose_name='已被冲抵')
|
||||
cancelled_at = models.DateTimeField(null=True, blank=True, verbose_name='被冲抵时间')
|
||||
|
||||
class Meta:
|
||||
verbose_name = '余额变动记录'
|
||||
verbose_name_plural = '余额变动记录'
|
||||
indexes = [
|
||||
models.Index(fields=['merchant', 'source_type', 'source_id'], name='balance_change_source_idx'),
|
||||
]
|
||||
constraints = [
|
||||
models.CheckConstraint(
|
||||
check=(
|
||||
(models.Q(supplier__isnull=False, customer__isnull=True))
|
||||
| (models.Q(supplier__isnull=True, customer__isnull=False))
|
||||
),
|
||||
name='balance_change_single_counterparty',
|
||||
),
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
counterparty = self.supplier or self.customer
|
||||
return f'余额变动 {self.id} - {counterparty}'
|
||||
|
||||
Reference in New Issue
Block a user