forked from erp-dev/erp
feat: new module: 'shipment', new signal when process was finished
This commit is contained in:
154
shipment/models.py
Normal file
154
shipment/models.py
Normal file
@@ -0,0 +1,154 @@
|
||||
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(可空)'
|
||||
)
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user