"""采购模型:PurchaseOrder(订单)+ PurchaseBill(进货单/收货入库单)。""" from decimal import Decimal from django.db import models from apps.core.base_models import TenantScopedModel class PurchaseOrder(TenantScopedModel): """采购订单(可选,预先订货流程)。""" STATE_CHOICES = [ ("draft", "草稿"), ("confirmed", "已确认"), ("received", "已收货"), ("cancelled", "已取消"), ] bill_no = models.CharField(max_length=64) supplier = models.ForeignKey( "partner.Supplier", on_delete=models.PROTECT, related_name="purchase_orders", ) warehouse = models.ForeignKey( "inventory.Warehouse", on_delete=models.PROTECT, related_name="purchase_orders", ) bill_date = models.DateField() expected_date = models.DateField(null=True, blank=True) total_amount = models.DecimalField(max_digits=18, decimal_places=4, default=0) state = models.CharField(max_length=16, choices=STATE_CHOICES, default="draft") remark = models.TextField(blank=True, default="") class Meta: db_table = "purchase_order" unique_together = [("tenant", "bill_no")] ordering = ["-bill_date", "-id"] verbose_name_plural = "采购订单" class PurchaseOrderLine(TenantScopedModel): order = models.ForeignKey( PurchaseOrder, on_delete=models.CASCADE, related_name="lines" ) product = models.ForeignKey( "catalog.Product", on_delete=models.PROTECT, related_name="po_lines" ) source_unit = models.ForeignKey( "catalog.Unit", null=True, blank=True, on_delete=models.SET_NULL, related_name="%(class)s_lines", help_text="录入单位(空=按基本单位)", ) source_quantity = models.DecimalField( max_digits=18, decimal_places=4, null=True, blank=True, help_text="录入数量(按录入单位;quantity 恒为基本单位数量)", ) quantity = models.DecimalField(max_digits=18, decimal_places=4) unit_price = models.DecimalField(max_digits=18, decimal_places=4) amount = models.DecimalField(max_digits=18, decimal_places=4, default=0) received_qty = models.DecimalField(max_digits=18, decimal_places=4, default=0) class Meta: db_table = "purchase_order_line" ordering = ["id"] class PurchaseBill(TenantScopedModel): """进货单(实际收货入库时生成)。""" STATE_CHOICES = [ ("draft", "草稿"), ("confirmed", "已过账"), ("cancelled", "已取消"), ] bill_no = models.CharField(max_length=64) supplier = models.ForeignKey( "partner.Supplier", on_delete=models.PROTECT, related_name="purchase_bills", ) warehouse = models.ForeignKey( "inventory.Warehouse", on_delete=models.PROTECT, related_name="purchase_bills", ) order = models.ForeignKey( PurchaseOrder, null=True, blank=True, on_delete=models.SET_NULL, related_name="bills", ) bill_date = models.DateField() total_amount = models.DecimalField(max_digits=18, decimal_places=4, default=0) state = models.CharField(max_length=16, choices=STATE_CHOICES, default="draft") remark = models.TextField(blank=True, default="") class Meta: db_table = "purchase_bill" unique_together = [("tenant", "bill_no")] ordering = ["-bill_date", "-id"] verbose_name_plural = "进货单" class PurchaseBillLine(TenantScopedModel): bill = models.ForeignKey( PurchaseBill, on_delete=models.CASCADE, related_name="lines" ) product = models.ForeignKey( "catalog.Product", on_delete=models.PROTECT, related_name="bill_lines" ) batch_no = models.CharField( max_length=64, blank=True, default="", help_text="批次号(批次管理商品必填)" ) production_date = models.DateField(null=True, blank=True) expiry_date = models.DateField(null=True, blank=True) source_unit = models.ForeignKey( "catalog.Unit", null=True, blank=True, on_delete=models.SET_NULL, related_name="%(class)s_lines", help_text="录入单位(空=按基本单位)", ) source_quantity = models.DecimalField( max_digits=18, decimal_places=4, null=True, blank=True, help_text="录入数量(按录入单位;quantity 恒为基本单位数量)", ) quantity = models.DecimalField(max_digits=18, decimal_places=4) unit_price = models.DecimalField(max_digits=18, decimal_places=4) amount = models.DecimalField(max_digits=18, decimal_places=4, default=0) tax_rate = models.DecimalField( max_digits=6, decimal_places=4, default=0, help_text="行税率(0.13 = 13%);价内口径:amount 为含税额", ) tax_amount = models.DecimalField( max_digits=18, decimal_places=4, default=0, help_text="行税额(从含税额中拆出)", ) class Meta: db_table = "purchase_bill_line" ordering = ["id"]