1
0
forked from erp-dev/erp

feat: auto complete stock change

This commit is contained in:
2025-11-10 09:01:25 +08:00
parent 37c2e7d723
commit b2078dfa46
82 changed files with 1071 additions and 1336 deletions

View File

@@ -12,11 +12,19 @@ YARD_TO_METER_RATE = 1.09361
# ==================== 枚举类定义 ====================
class WareHouseModeEnum(models.IntegerChoices):
"""仓库出入库模式枚举"""
RESTRICT_IN = 1, '严进宽出'
RESTRICT_IN_OUT = 2, '严进严出'
UNRESTRICTED = 3, '宽进宽出'
class MerchantTypeEnum(models.IntegerChoices):
"""商户类型枚举"""
STORE = 1, '布行'
FACTORY = 2, '印花厂'
class ProductUnitEnum(models.IntegerChoices):
"""产品单位枚举"""
METER = 1, ''
@@ -54,6 +62,21 @@ class DeviceTypeEnum(models.TextChoices):
# ==================== 模型定义 ====================
class QuickInput(ModelBase):
id = models.BigAutoField(primary_key=True)
name = models.CharField(max_length=100, verbose_name='')
value = models.CharField(max_length=200, verbose_name='')
group = models.CharField(verbose_name='')
def __str__(self):
return f'{self.group}-{self.name}'
class Meta:
verbose_name = '快捷输入'
verbose_name_plural = '快捷输入'
unique_together = ('name', 'group')
class Merchant(ModelBase):
id = models.BigAutoField(primary_key=True)
name = models.CharField(max_length=100, verbose_name='商户名称')
@@ -62,6 +85,10 @@ class Merchant(ModelBase):
email = models.EmailField(blank=True, null=True, verbose_name='电子邮箱')
mobile = models.CharField(max_length=20, blank=True, null=True, verbose_name='手机')
contact = models.TextField(blank=True, null=True, verbose_name='联系人')
auto_complete_stock_change = models.BooleanField(
default=False,
verbose_name='自动确认库存变动',
)
description = models.TextField(blank=True, null=True, verbose_name='备注描述')
def __str__(self):
@@ -74,6 +101,7 @@ class Merchant(ModelBase):
class VehicleType(ModelBase):
id = models.BigAutoField(primary_key=True)
merchant = models.ForeignKey('Merchant', on_delete=models.PROTECT, related_name='vehicle_types', verbose_name='所属商户')
name = models.CharField(max_length=50, verbose_name='车辆类型名称')
description = models.TextField(blank=True, null=True, verbose_name='备注描述')
@@ -87,8 +115,14 @@ class VehicleType(ModelBase):
class WareHouse(ModelBase):
id = models.BigAutoField(primary_key=True)
merchant = models.ForeignKey('Merchant', on_delete=models.PROTECT, related_name='warehouses', verbose_name='所属商户')
name = models.CharField(max_length=100, verbose_name='仓库名称')
location = models.CharField(max_length=200, blank=True, null=True, verbose_name='仓库地址')
mode = models.IntegerField(
choices=WareHouseModeEnum.choices,
default=WareHouseModeEnum.RESTRICT_IN,
verbose_name='出入库模式',
)
contact = models.CharField(max_length=100, blank=True, null=True, verbose_name='联系人')
mobile = models.CharField(max_length=20, blank=True, null=True, verbose_name='手机')
area = models.CharField(max_length=100, blank=True, null=True, verbose_name='地区')
@@ -104,6 +138,7 @@ class WareHouse(ModelBase):
class Supplier(ModelBase):
id = models.BigAutoField(primary_key=True)
merchant = models.ForeignKey('Merchant', on_delete=models.PROTECT, related_name='suppliers', verbose_name='所属商户')
name = models.CharField(max_length=100, verbose_name='供应商名称')
area = models.CharField(max_length=100, blank=True, null=True, verbose_name='地区')
email = models.EmailField(blank=True, null=True, verbose_name='电子邮箱')
@@ -121,6 +156,7 @@ class Supplier(ModelBase):
class BankAccount(ModelBase):
id = models.BigAutoField(primary_key=True)
merchant = models.ForeignKey('Merchant', on_delete=models.PROTECT, related_name='bank_accounts', verbose_name='所属商户')
name = models.CharField(max_length=100, verbose_name='名称')
auto_number = models.CharField(max_length=50, verbose_name='自动编号')
description = models.TextField(blank=True, null=True, verbose_name='备注描述')
@@ -136,6 +172,7 @@ class BankAccount(ModelBase):
class ProductCategory(ModelBase):
id = models.BigAutoField(primary_key=True)
merchant = models.ForeignKey('Merchant', on_delete=models.PROTECT, related_name='product_categories', verbose_name='所属商户')
name = models.CharField(max_length=100, verbose_name='类别名称')
description = models.TextField(blank=True, null=True, verbose_name='类别描述')
product_prefix = models.CharField(max_length=5, verbose_name='产品编号前缀')
@@ -150,6 +187,7 @@ class ProductCategory(ModelBase):
class Product(ModelBase):
id = models.BigAutoField(primary_key=True)
merchant = models.ForeignKey('Merchant', on_delete=models.PROTECT, verbose_name='所属商户')
category = models.ForeignKey(
ProductCategory,
on_delete=models.PROTECT,
@@ -231,7 +269,21 @@ class Product(ModelBase):
class Customer(ModelBase):
id = models.BigAutoField(primary_key=True)
merchant = models.ForeignKey('Merchant', on_delete=models.PROTECT, related_name='customers', verbose_name='所属商户')
name = models.CharField(max_length=100, verbose_name='客户名称')
visible_employees = models.ManyToManyField(
'Employee',
blank=True,
related_name='visible_customers',
verbose_name='可见该客户的员工',
)
created_by = models.ForeignKey(
'Employee',
on_delete=models.PROTECT,
related_name='created_customers',
null=True,
verbose_name='创建者',
)
mobile = models.CharField(max_length=20, verbose_name='手机')
area = models.CharField(max_length=100, blank=True, null=True, verbose_name='地区')
email = models.EmailField(blank=True, null=True, verbose_name='电子邮箱')
@@ -248,6 +300,7 @@ class Customer(ModelBase):
class Employee(ModelBase):
id = models.BigAutoField(primary_key=True)
merchant = models.ForeignKey('Merchant', on_delete=models.PROTECT, related_name='employees', verbose_name='所属商户')
sys_user = models.OneToOneField(
User,
on_delete=models.PROTECT,
@@ -283,6 +336,7 @@ class Employee(ModelBase):
class DeviceInfo(ModelBase):
id = models.BigAutoField(primary_key=True)
merchant = models.ForeignKey('Merchant', on_delete=models.PROTECT, related_name='devices', verbose_name='所属商户')
name = models.CharField(max_length=100, verbose_name='设备名称')
type = models.CharField(
max_length=20,
@@ -311,6 +365,7 @@ class DeviceInfo(ModelBase):
class VehicleTransportRecord(ModelBase):
id = models.BigAutoField(primary_key=True)
merchant = models.ForeignKey('Merchant', on_delete=models.PROTECT, related_name='vehicle_transport_records', verbose_name='所属商户')
vehicle_type = models.ForeignKey(
VehicleType,
on_delete=models.PROTECT,