forked from erp-dev/erp
169 lines
4.1 KiB
Python
169 lines
4.1 KiB
Python
from django.db import models
|
||
from django.contrib.auth import get_user_model
|
||
from flower.common import ModelBase
|
||
from basic_info import models as basic_models
|
||
|
||
User = get_user_model()
|
||
|
||
|
||
class UnitChoices(models.IntegerChoices):
|
||
"""销售品单位"""
|
||
METER = 1, '米'
|
||
PIECE = 2, '件'
|
||
YARD = 3, '码'
|
||
UNIT = 4, '个'
|
||
|
||
|
||
class Shipment(ModelBase):
|
||
"""
|
||
出货单
|
||
|
||
记录一次出货操作,包含多个销售品。
|
||
"""
|
||
customer = models.ForeignKey(
|
||
basic_models.Customer,
|
||
on_delete=models.PROTECT,
|
||
related_name='shipments',
|
||
verbose_name='客户'
|
||
)
|
||
|
||
shipment_date = models.DateField(
|
||
verbose_name='出货日期',
|
||
help_text='实际出货日期'
|
||
)
|
||
|
||
remark = models.TextField(
|
||
blank=True,
|
||
default='',
|
||
verbose_name='备注'
|
||
)
|
||
|
||
created_by = models.ForeignKey(
|
||
User,
|
||
on_delete=models.SET_NULL,
|
||
null=True,
|
||
related_name='created_shipments',
|
||
verbose_name='创建人'
|
||
)
|
||
|
||
class Meta:
|
||
db_table = 'shipment'
|
||
verbose_name = '出货单'
|
||
verbose_name_plural = '出货单'
|
||
ordering = ['-created_at']
|
||
|
||
def __str__(self):
|
||
return f'出货单 #{self.id} - {self.customer.name}'
|
||
|
||
|
||
class SalesItem(ModelBase):
|
||
"""
|
||
销售品
|
||
|
||
出货单中的具体商品明细。
|
||
销售品可以先创建(待分配状态),后续再关联到出货单。
|
||
"""
|
||
shipment = models.ForeignKey(
|
||
Shipment,
|
||
on_delete=models.CASCADE,
|
||
null=True,
|
||
blank=True,
|
||
related_name='items',
|
||
verbose_name='出货单',
|
||
help_text='为空表示待分配'
|
||
)
|
||
|
||
name = models.CharField(
|
||
max_length=200,
|
||
verbose_name='名称'
|
||
)
|
||
|
||
quantity = models.DecimalField(
|
||
max_digits=12,
|
||
decimal_places=2,
|
||
verbose_name='数量'
|
||
)
|
||
|
||
unit = models.IntegerField(
|
||
choices=UnitChoices.choices,
|
||
default=UnitChoices.PIECE,
|
||
verbose_name='单位'
|
||
)
|
||
|
||
created_by = models.ForeignKey(
|
||
User,
|
||
on_delete=models.SET_NULL,
|
||
null=True,
|
||
related_name='created_sales_items',
|
||
verbose_name='创建人'
|
||
)
|
||
|
||
# 关联的生产明细订单(可空)
|
||
# 使用 PositiveIntegerField 而非 ForeignKey,避免模块间强依赖
|
||
printing_job_id = models.PositiveIntegerField(
|
||
null=True,
|
||
blank=True,
|
||
verbose_name='关联生产任务ID',
|
||
help_text='关联的 PrintingJob ID(可空)'
|
||
)
|
||
|
||
# 客户ID(可空,用于销售品级别的客户关联)
|
||
customer_id = models.PositiveIntegerField(
|
||
null=True,
|
||
blank=True,
|
||
verbose_name='客户ID',
|
||
help_text='销售品级别的客户ID(可空)'
|
||
)
|
||
|
||
position = models.CharField(
|
||
max_length=200,
|
||
blank=True,
|
||
default='',
|
||
verbose_name='货位'
|
||
)
|
||
|
||
remark = models.CharField(
|
||
max_length=200,
|
||
blank=True,
|
||
default='',
|
||
verbose_name='备注'
|
||
)
|
||
|
||
class Meta:
|
||
db_table = 'sales_item'
|
||
verbose_name = '销售品'
|
||
verbose_name_plural = '销售品'
|
||
ordering = ['id']
|
||
|
||
def __str__(self):
|
||
return f'{self.name} x {self.quantity} {self.get_unit_display()}'
|
||
|
||
def get_printing_job(self):
|
||
"""
|
||
获取关联的 PrintingJob 实例
|
||
|
||
Returns:
|
||
PrintingJob 实例,如果不存在则返回 None
|
||
"""
|
||
if not self.printing_job_id:
|
||
return None
|
||
try:
|
||
from printing.models import PrintingJob
|
||
return PrintingJob.objects.get(id=self.printing_job_id)
|
||
except Exception:
|
||
return None
|
||
|
||
def get_customer(self):
|
||
"""
|
||
获取关联的 Customer 实例
|
||
|
||
Returns:
|
||
Customer 实例,如果不存在则返回 None
|
||
"""
|
||
if not self.customer_id:
|
||
return None
|
||
try:
|
||
return basic_models.Customer.objects.get(id=self.customer_id)
|
||
except basic_models.Customer.DoesNotExist:
|
||
return None
|