1
0
forked from erp-dev/erp
This commit is contained in:
2025-11-03 17:55:30 +08:00
commit 9fde654e2f
77 changed files with 7831 additions and 0 deletions

0
basic_info/__init__.py Normal file
View File

82
basic_info/admin.py Normal file
View File

@@ -0,0 +1,82 @@
from django.contrib import admin
from . import models
@admin.register(models.Supplier)
class SupplierAdmin(admin.ModelAdmin):
list_display = ('name', 'area', 'email', 'mobile')
search_fields = ('name', 'area', 'email', 'mobile')
@admin.register(models.ProductCategory)
class ProductCategoryAdmin(admin.ModelAdmin):
list_display = ('name', 'product_prefix', 'description')
search_fields = ('name',)
@admin.register(models.Product)
class ProductAdmin(admin.ModelAdmin):
list_display = (
'name',
'category',
'human_id',
'color',
'width_size',
'transform_rate',
'single_price_in',
'single_price_out',
)
search_fields = ('name', 'human_id')
list_filter = ('category',)
@admin.register(models.BankAccount)
class BankAccountAdmin(admin.ModelAdmin):
list_display = ('name', 'auto_number')
search_fields = ('name', 'auto_number')
@admin.register(models.WareHouse)
class WareHouseAdmin(admin.ModelAdmin):
list_display = ('name', 'location', 'area', 'mobile')
search_fields = ('name', 'area')
@admin.register(models.Customer)
class CustomerAdmin(admin.ModelAdmin):
list_display = ('name', 'area', 'email', 'mobile', 'total_debt')
search_fields = ('name', 'area', 'email', 'mobile')
@admin.display(boolean=False, description='累欠金额')
def total_debt(self, obj):
return '0 (动态逻辑字段待实现)'
@admin.register(models.Employee)
class EmployeeAdmin(admin.ModelAdmin):
list_display = ('name', 'mobile', 'status', 'job_type', 'sys_user')
search_fields = ('name', 'mobile')
list_filter = (
'job_type',
'status',
)
@admin.register(models.DeviceInfo)
class DeviceInfoAdmin(admin.ModelAdmin):
list_display = ('name', 'type', 'is_occupied', 'status')
search_fields = ('name', 'start_working_at', 'stop_working_at')
list_filter = ('type', 'status')
@admin.register(models.VehicleType)
class VehicleTypeAdmin(admin.ModelAdmin):
list_display = ('name', 'description')
search_fields = ('name',)
@admin.register(models.VehicleTransportRecord)
class VehicleTransportRecordAdmin(admin.ModelAdmin):
list_display = ('driver_name', 'contact_number', 'delivery_date')
search_fields = ('driver_name', 'contact_number')
list_filter = ('vehicle_type',)

7
basic_info/apps.py Normal file
View File

@@ -0,0 +1,7 @@
from django.apps import AppConfig
class BasicInfoConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'basic_info'
verbose_name = '基础资料'

View File

@@ -0,0 +1,133 @@
# Generated by Django 5.2.7 on 2025-11-03 06:06
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='BankAccount',
fields=[
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('id', models.BigAutoField(primary_key=True, serialize=False)),
('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='备注描述')),
('attachment', models.FileField(blank=True, null=True, upload_to='bank_accounts/', verbose_name='附件')),
],
options={
'verbose_name': '银行账户',
'verbose_name_plural': '银行账户',
},
),
migrations.CreateModel(
name='ProductCategory',
fields=[
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('id', models.BigAutoField(primary_key=True, serialize=False)),
('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='产品编号前缀')),
],
options={
'verbose_name': '产品类别',
'verbose_name_plural': '产品类别',
},
),
migrations.CreateModel(
name='ProductUnit',
fields=[
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('id', models.BigAutoField(primary_key=True, serialize=False)),
('name', models.CharField(max_length=20, verbose_name='单位名称')),
('description', models.TextField(blank=True, null=True, verbose_name='备注描述')),
],
options={
'verbose_name': '产品单位',
'verbose_name_plural': '产品单位',
},
),
migrations.CreateModel(
name='Supplier',
fields=[
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('id', models.BigAutoField(primary_key=True, serialize=False)),
('name', models.CharField(max_length=100, verbose_name='供应商名称')),
('area', models.CharField(blank=True, max_length=100, null=True, verbose_name='地区')),
('email', models.EmailField(blank=True, max_length=254, null=True, verbose_name='电子邮箱')),
('mobile', models.CharField(blank=True, max_length=20, null=True, verbose_name='手机')),
('contact', models.TextField(blank=True, null=True, verbose_name='联系人')),
('description', models.TextField(blank=True, null=True, verbose_name='备注描述')),
],
options={
'verbose_name': '供应商',
'verbose_name_plural': '供应商',
},
),
migrations.CreateModel(
name='WareHouse',
fields=[
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('id', models.BigAutoField(primary_key=True, serialize=False)),
('name', models.CharField(max_length=100, verbose_name='仓库名称')),
('location', models.CharField(blank=True, max_length=200, null=True, verbose_name='仓库地址')),
('contact', models.CharField(blank=True, max_length=100, null=True, verbose_name='联系人')),
('mobile', models.CharField(blank=True, max_length=20, null=True, verbose_name='手机')),
('area', models.CharField(blank=True, max_length=100, null=True, verbose_name='地区')),
('description', models.TextField(blank=True, null=True, verbose_name='备注描述')),
],
options={
'verbose_name': '仓库资料',
'verbose_name_plural': '仓库资料',
},
),
migrations.CreateModel(
name='Product',
fields=[
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('id', models.BigAutoField(primary_key=True, serialize=False)),
('name', models.CharField(max_length=100, verbose_name='产品名')),
('human_id', models.CharField(blank=True, max_length=100, verbose_name='产品编号')),
('color', models.CharField(blank=True, max_length=50, null=True, verbose_name='颜色')),
('width_size', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='宽幅')),
('single_price', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='单价')),
('spec', models.CharField(blank=True, max_length=100, null=True, verbose_name='规格')),
('description', models.TextField(blank=True, null=True, verbose_name='备注描述')),
('category', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='products', to='basic_info.productcategory', verbose_name='产品类别')),
('unit', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='products', to='basic_info.productunit', verbose_name='单位')),
],
options={
'verbose_name': '产品资料',
'verbose_name_plural': '产品资料',
},
),
migrations.CreateModel(
name='PurchaseOrder',
fields=[
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('id', models.BigAutoField(primary_key=True, serialize=False)),
('order_date', models.DateField(verbose_name='订单日期')),
('total_amount', models.DecimalField(decimal_places=2, max_digits=15, verbose_name='总金额')),
('remarks', models.TextField(blank=True, null=True, verbose_name='备注')),
('supplier', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='purchase_orders', to='basic_info.supplier', verbose_name='供应商')),
],
options={
'verbose_name': '采购单',
'verbose_name_plural': '采购单',
},
),
]

View File

@@ -0,0 +1,16 @@
# Generated by Django 5.2.7 on 2025-11-03 06:11
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('basic_info', '0001_initial'),
]
operations = [
migrations.DeleteModel(
name='PurchaseOrder',
),
]

View File

@@ -0,0 +1,31 @@
# Generated by Django 5.2.7 on 2025-11-03 06:14
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('basic_info', '0002_delete_purchaseorder'),
]
operations = [
migrations.CreateModel(
name='Customer',
fields=[
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('id', models.BigAutoField(primary_key=True, serialize=False)),
('name', models.CharField(max_length=100, verbose_name='客户名称')),
('area', models.CharField(blank=True, max_length=100, null=True, verbose_name='地区')),
('email', models.EmailField(blank=True, max_length=254, null=True, verbose_name='电子邮箱')),
('mobile', models.CharField(blank=True, max_length=20, null=True, verbose_name='手机')),
('contact', models.TextField(blank=True, null=True, verbose_name='联系人')),
('description', models.TextField(blank=True, null=True, verbose_name='备注描述')),
],
options={
'verbose_name': '客户资料',
'verbose_name_plural': '客户资料',
},
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 5.2.7 on 2025-11-03 06:15
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('basic_info', '0003_customer'),
]
operations = [
migrations.AlterField(
model_name='customer',
name='contact',
field=models.CharField(blank=True, null=True, verbose_name='联系人'),
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 5.2.7 on 2025-11-03 06:16
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('basic_info', '0004_alter_customer_contact'),
]
operations = [
migrations.AlterField(
model_name='customer',
name='mobile',
field=models.CharField(max_length=20, verbose_name='手机'),
),
]

View File

@@ -0,0 +1,33 @@
# Generated by Django 5.2.7 on 2025-11-03 06:24
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('basic_info', '0005_alter_customer_mobile'),
]
operations = [
migrations.CreateModel(
name='Employee',
fields=[
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('id', models.BigAutoField(primary_key=True, serialize=False)),
('name', models.CharField(max_length=100, verbose_name='员工姓名')),
('job_type', models.CharField(choices=[('打纸', '打纸'), ('滚筒', '滚筒'), ('仓库', '仓库'), ('送货', '送货')], default='打纸', max_length=20, verbose_name='职位')),
('mobile', models.CharField(blank=True, max_length=20, null=True, verbose_name='手机')),
('area', models.CharField(blank=True, max_length=100, null=True, verbose_name='地区')),
('email', models.EmailField(blank=True, max_length=254, null=True, verbose_name='电子邮箱')),
('contact', models.CharField(blank=True, null=True, verbose_name='联系人')),
('description', models.TextField(blank=True, null=True, verbose_name='备注描述')),
('status', models.CharField(choices=[('在职', '在职'), ('离职', '离职')], default='在职', max_length=20, verbose_name='员工状态')),
],
options={
'verbose_name': '员工资料',
'verbose_name_plural': '员工资料',
},
),
]

View File

@@ -0,0 +1,17 @@
# Generated by Django 5.2.7 on 2025-11-03 06:27
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('basic_info', '0006_employee'),
]
operations = [
migrations.RemoveField(
model_name='employee',
name='contact',
),
]

View File

@@ -0,0 +1,17 @@
# Generated by Django 5.2.7 on 2025-11-03 06:29
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('basic_info', '0007_remove_employee_contact'),
]
operations = [
migrations.RemoveField(
model_name='employee',
name='email',
),
]

View File

@@ -0,0 +1,21 @@
# Generated by Django 5.2.7 on 2025-11-03 07:05
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('basic_info', '0008_remove_employee_email'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.AddField(
model_name='employee',
name='sys_user',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='employee', to=settings.AUTH_USER_MODEL, verbose_name='系统用户'),
),
]

View File

@@ -0,0 +1,32 @@
# Generated by Django 5.2.7 on 2025-11-03 07:14
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('basic_info', '0009_employee_sys_user'),
]
operations = [
migrations.CreateModel(
name='DeviceInfo',
fields=[
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('id', models.BigAutoField(primary_key=True, serialize=False)),
('name', models.CharField(max_length=100, verbose_name='设备名称')),
('type', models.CharField(choices=[('滚筒', '滚筒'), ('打印', '打印')], default='滚筒', max_length=20, verbose_name='设备类型')),
('status', models.CharField(choices=[('使用中', '使用中'), ('停用', '停用'), ('维修中', '维修中')], default='使用中', max_length=20, verbose_name='设备状态')),
('start_working_at', models.DateField(blank=True, null=True, verbose_name='开始服役日期')),
('stop_working_at', models.DateField(blank=True, null=True, verbose_name='停止服役日期')),
('is_occupied', models.BooleanField(default=False, verbose_name='是否被占用')),
('description', models.TextField(blank=True, null=True, verbose_name='备注描述')),
],
options={
'verbose_name': '设备信息',
'verbose_name_plural': '设备信息',
},
),
]

View File

@@ -0,0 +1,49 @@
# Generated by Django 5.2.7 on 2025-11-03 07:26
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('basic_info', '0010_deviceinfo'),
]
operations = [
migrations.CreateModel(
name='VehicleType',
fields=[
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('id', models.BigAutoField(primary_key=True, serialize=False)),
('name', models.CharField(max_length=50, verbose_name='车辆类型名称')),
('description', models.TextField(blank=True, null=True, verbose_name='备注描述')),
],
options={
'verbose_name': '车辆类型',
'verbose_name_plural': '车辆类型',
},
),
migrations.AlterModelOptions(
name='deviceinfo',
options={'verbose_name': '设备资料', 'verbose_name_plural': '设备资料'},
),
migrations.CreateModel(
name='VehicleTransportRecord',
fields=[
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('id', models.BigAutoField(primary_key=True, serialize=False)),
('driver_name', models.CharField(max_length=100, verbose_name='司机姓名')),
('contact_number', models.CharField(blank=True, max_length=20, null=True, verbose_name='联系电话')),
('license_plate', models.CharField(blank=True, max_length=20, null=True, verbose_name='车牌号码')),
('delivery_date', models.DateField(verbose_name='送货日期')),
('vehicle_type', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='vehicles', to='basic_info.vehicletype', verbose_name='车次')),
],
options={
'verbose_name': '司机车次',
'verbose_name_plural': '司机车次',
},
),
]

View File

@@ -0,0 +1,19 @@
# Generated by Django 5.2.7 on 2025-11-03 08:58
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('basic_info', '0011_vehicletype_alter_deviceinfo_options_and_more'),
]
operations = [
migrations.AlterField(
model_name='product',
name='unit',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='products', to='basic_info.productunit', verbose_name='主单位'),
),
]

View File

@@ -0,0 +1,36 @@
# Generated by Django 5.2.7 on 2025-11-03 09:10
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('basic_info', '0012_alter_product_unit'),
('stock', '0018_remove_inventory_unit'),
]
operations = [
migrations.RemoveField(
model_name='product',
name='unit',
),
migrations.AddField(
model_name='product',
name='main_unit',
field=models.IntegerField(choices=[(1, ''), (2, ''), (3, '公斤')], default=1, verbose_name='主单位'),
),
migrations.AddField(
model_name='product',
name='sub_unit',
field=models.IntegerField(blank=True, choices=[(1, ''), (2, ''), (3, '公斤')], null=True, verbose_name='辅单位'),
),
migrations.AddField(
model_name='product',
name='transform_rate',
field=models.DecimalField(blank=True, decimal_places=4, max_digits=10, null=True, verbose_name='转换率(主单位->辅单位)'),
),
migrations.DeleteModel(
name='ProductUnit',
),
]

View File

@@ -0,0 +1,31 @@
# Generated by Django 5.2.7 on 2025-11-03 09:30
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('basic_info', '0013_remove_product_unit_product_main_unit_and_more'),
]
operations = [
migrations.RemoveField(
model_name='product',
name='main_unit',
),
migrations.RemoveField(
model_name='product',
name='sub_unit',
),
migrations.AlterField(
model_name='product',
name='single_price',
field=models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='单价(米)'),
),
migrations.AlterField(
model_name='product',
name='transform_rate',
field=models.DecimalField(blank=True, decimal_places=4, max_digits=10, null=True, verbose_name='公斤转换率'),
),
]

View File

@@ -0,0 +1,27 @@
# Generated by Django 5.2.7 on 2025-11-03 09:47
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('basic_info', '0014_remove_product_main_unit_remove_product_sub_unit_and_more'),
]
operations = [
migrations.RemoveField(
model_name='product',
name='single_price',
),
migrations.AddField(
model_name='product',
name='single_price_in',
field=models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='参考进价'),
),
migrations.AddField(
model_name='product',
name='single_price_out',
field=models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='参考售价'),
),
]

View File

285
basic_info/models.py Normal file
View File

@@ -0,0 +1,285 @@
from decimal import Decimal
from django.db import models
from flower.common import ModelBase
from django.contrib.auth.models import User
METER_TO_YARD_RATE = 0.9144
YARD_TO_METER_RATE = 1.09361
class VehicleType(ModelBase):
id = models.BigAutoField(primary_key=True)
name = models.CharField(max_length=50, verbose_name='车辆类型名称')
description = models.TextField(blank=True, null=True, verbose_name='备注描述')
def __str__(self):
return self.name
class Meta:
verbose_name = '车辆类型'
verbose_name_plural = '车辆类型'
class WareHouse(ModelBase):
id = models.BigAutoField(primary_key=True)
name = models.CharField(max_length=100, verbose_name='仓库名称')
location = models.CharField(max_length=200, blank=True, null=True, 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='地区')
description = models.TextField(blank=True, null=True, verbose_name='备注描述')
def __str__(self):
return self.name
class Meta:
verbose_name = '仓库资料'
verbose_name_plural = '仓库资料'
class ProductUnitEnum(models.IntegerChoices):
METER = 1, ''
YARD = 2, ''
KG = 3, '公斤'
class Supplier(ModelBase):
id = models.BigAutoField(primary_key=True)
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='电子邮箱')
mobile = models.CharField(max_length=20, blank=True, null=True, verbose_name='手机')
contact = models.TextField(blank=True, null=True, verbose_name='联系人')
description = models.TextField(blank=True, null=True, verbose_name='备注描述')
def __str__(self):
return self.name
class Meta:
verbose_name = '供应商'
verbose_name_plural = '供应商'
class BankAccount(ModelBase):
id = models.BigAutoField(primary_key=True)
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='备注描述')
attachment = models.FileField(upload_to='bank_accounts/', blank=True, null=True, verbose_name='附件')
def __str__(self):
return f'{self.name} - {self.auto_number}'
class Meta:
verbose_name = '银行账户'
verbose_name_plural = '银行账户'
class ProductCategory(ModelBase):
id = models.BigAutoField(primary_key=True)
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='产品编号前缀')
def __str__(self):
return self.name
class Meta:
verbose_name = '产品类别'
verbose_name_plural = '产品类别'
class Product(ModelBase):
id = models.BigAutoField(primary_key=True)
category = models.ForeignKey(
ProductCategory,
on_delete=models.PROTECT,
related_name='products',
verbose_name='产品类别',
)
name = models.CharField(max_length=100, verbose_name='产品名')
human_id = models.CharField(max_length=100, verbose_name='产品编号', blank=True)
color = models.CharField(max_length=50, blank=True, null=True, verbose_name='颜色')
width_size = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True, verbose_name='宽幅')
single_price_in = models.DecimalField(
max_digits=10,
decimal_places=2,
verbose_name='参考进价',
blank=True,
null=True,
)
single_price_out = models.DecimalField(
max_digits=10,
decimal_places=2,
verbose_name='参考售价',
blank=True,
null=True,
)
spec = models.CharField(max_length=100, blank=True, null=True, verbose_name='规格')
description = models.TextField(blank=True, null=True, verbose_name='备注描述')
transform_rate = models.DecimalField(
max_digits=10,
decimal_places=4,
blank=True,
null=True,
verbose_name='公斤转换率',
)
def __str__(self):
return self.name
def save(
self,
*args,
force_insert=False,
force_update=False,
using=None,
update_fields=None,
):
super().save(
*args,
force_insert=force_insert,
force_update=force_update,
using=using,
update_fields=update_fields,
)
# Generate human_id if not set after saving to get the ID
if not self.human_id and self.category:
self.human_id = f'{self.category.product_prefix}{self.id:05d}'
super().save(
*args,
force_insert=False,
force_update=False,
using=using,
update_fields=['human_id'],
)
class Meta:
verbose_name = '产品资料'
verbose_name_plural = '产品资料'
class Customer(ModelBase):
id = models.BigAutoField(primary_key=True)
name = models.CharField(max_length=100, 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='电子邮箱')
contact = models.CharField(blank=True, null=True, verbose_name='联系人')
description = models.TextField(blank=True, null=True, verbose_name='备注描述')
def __str__(self):
return self.name
class Meta:
verbose_name = '客户资料'
verbose_name_plural = '客户资料'
class EmployeeTypeEnum(models.TextChoices):
PRINTER = '打纸', '打纸'
ROLLING = '滚筒', '滚筒'
WARE = '仓库', '仓库'
DELIVERY = '送货', '送货'
class EmployeeStatusEnum(models.TextChoices):
ACTIVE = '在职', '在职'
INACTIVE = '离职', '离职'
class Employee(ModelBase):
id = models.BigAutoField(primary_key=True)
sys_user = models.OneToOneField(
User,
on_delete=models.PROTECT,
related_name='employee',
null=True,
blank=True,
verbose_name='系统用户',
)
name = models.CharField(max_length=100, verbose_name='员工姓名')
job_type = models.CharField(
max_length=20,
choices=EmployeeTypeEnum.choices,
default=EmployeeTypeEnum.PRINTER,
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='地区')
description = models.TextField(blank=True, null=True, verbose_name='备注描述')
status = models.CharField(
max_length=20,
choices=EmployeeStatusEnum.choices,
default=EmployeeStatusEnum.ACTIVE,
verbose_name='员工状态',
)
def __str__(self):
return self.name
class Meta:
verbose_name = '员工资料'
verbose_name_plural = '员工资料'
class DeviceStatusEnum(models.TextChoices):
ACTIVE = '使用中', '使用中'
INACTIVE = '停用', '停用'
MAINTENANCE = '维修中', '维修中'
class DeviceTypeEnum(models.TextChoices):
ROLLING = '滚筒', '滚筒'
PRINTER = '打印', '打印'
class DeviceInfo(ModelBase):
id = models.BigAutoField(primary_key=True)
name = models.CharField(max_length=100, verbose_name='设备名称')
type = models.CharField(
max_length=20,
choices=DeviceTypeEnum.choices,
default=DeviceTypeEnum.ROLLING,
verbose_name='设备类型',
)
status = models.CharField(
max_length=20,
choices=DeviceStatusEnum.choices,
default=DeviceStatusEnum.ACTIVE,
verbose_name='设备状态',
)
start_working_at = models.DateField(blank=True, null=True, verbose_name='开始服役日期')
stop_working_at = models.DateField(blank=True, null=True, verbose_name='停止服役日期')
is_occupied = models.BooleanField(default=False, verbose_name='是否被占用')
description = models.TextField(blank=True, null=True, verbose_name='备注描述')
def __str__(self):
return self.name
class Meta:
verbose_name = '设备资料'
verbose_name_plural = '设备资料'
class VehicleTransportRecord(ModelBase):
id = models.BigAutoField(primary_key=True)
vehicle_type = models.ForeignKey(
VehicleType,
on_delete=models.PROTECT,
related_name='vehicles',
verbose_name='车次',
)
driver_name = models.CharField(max_length=100, verbose_name='司机姓名')
contact_number = models.CharField(max_length=20, blank=True, null=True, verbose_name='联系电话')
license_plate = models.CharField(max_length=20, verbose_name='车牌号码', null=True, blank=True)
delivery_date = models.DateField(verbose_name='送货日期')
def __str__(self):
return f'{self.vehicle_type}-{self.driver_name}-{self.delivery_date}'
class Meta:
verbose_name = '司机车次'
verbose_name_plural = '司机车次'

3
basic_info/tests.py Normal file
View File

@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

3
basic_info/views.py Normal file
View File

@@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.