修改表名

This commit is contained in:
caoqianming 2021-11-09 00:14:30 +08:00
parent b083f1cd8d
commit 2b3f45eb7f
19 changed files with 354 additions and 98 deletions

View File

@ -66,7 +66,7 @@
</el-col> </el-col>
</el-row> </el-row>
<el-card style="margin-top: 6px"> <el-card style="margin-top: 2px">
<div slot="header" class="clearfix"> <div slot="header" class="clearfix">
<span>日志列表</span> <span>日志列表</span>
</div> </div>

View File

@ -53,11 +53,15 @@ class FIFO(CommonAModel):
""" """
出入库记录 出入库记录
""" """
FIFO_TYPE_DO_OUT = 1 # 生产领料
FIFO_TYPE_SALE_OUT = 2
FIFO_TYPE_PUR_IN = 3
FIFO_TYPE_DO_IN = 4
type_choices = ( type_choices = (
(1, '生产领料'), (FIFO_TYPE_DO_OUT, '生产领料'),
(2, '销售提货'), (FIFO_TYPE_SALE_OUT, '销售提货'),
(3, '采购入库'), (FIFO_TYPE_PUR_IN, '采购入库'),
(4, '生产入库') (FIFO_TYPE_DO_IN, '生产入库')
) )
type = models.IntegerField('出入库类型', default=1) type = models.IntegerField('出入库类型', default=1)
is_audited = models.BooleanField('是否审核', default=False) is_audited = models.BooleanField('是否审核', default=False)

View File

@ -91,7 +91,7 @@ class FIFOInPurSerializer(serializers.ModelSerializer):
pass pass
# 创建采购入库 # 创建采购入库
validated_data['type'] = 3 validated_data['type'] = FIFO.FIFO_TYPE_PUR_IN
obj = FIFO(**validated_data) obj = FIFO(**validated_data)
obj.save() obj.save()
for i in details: for i in details:

View File

@ -9,7 +9,7 @@ def update_inm(instance:FIFO, type:int=1):
更新库存(正反) 更新库存(正反)
""" """
warehouse = instance.warehouse warehouse = instance.warehouse
if instance.type in [3]: # 采购入库 if instance.type in [FIFO.FIFO_TYPE_PUR_IN]: # 采购入库
# 更新相关表 # 更新相关表
for i in FIFOItem.objects.filter(fifo=instance): for i in FIFOItem.objects.filter(fifo=instance):
material = i.material material = i.material
@ -23,7 +23,7 @@ def update_inm(instance:FIFO, type:int=1):
o2.save() o2.save()
material.count = material.count + i.count material.count = material.count + i.count
material.save() material.save()
elif instance.type in [1]: # 生产领料 elif instance.type in [FIFO.FIFO_TYPE_DO_OUT]: # 生产领料
# 更新相关表 # 更新相关表
for i in FIFOItem.objects.filter(fifo=instance): for i in FIFOItem.objects.filter(fifo=instance):
material = i.material material = i.material

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.6 on 2021-11-08 09:07
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('mtm', '0028_auto_20211102_1707'),
]
operations = [
migrations.AddField(
model_name='step',
name='type',
field=models.IntegerField(choices=[(1, '普通'), (2, '分割'), (3, '结合')], default=1, verbose_name='操作类型'),
),
]

View File

@ -12,13 +12,19 @@ class Material(CommonAModel):
""" """
物料 物料
""" """
MA_TYPE_GOOD = 1
MA_TYPE_HALFGOOD = 2
MA_TYPE_MAINSO = 3
MA_TYPE_HELPSO = 4
MA_TYPE_TOOL = 5
MA_TYPE_HELPTOOL = 6
type_choices=( type_choices=(
(1, '成品'), (MA_TYPE_GOOD, '成品'),
(2, '半成品'), (MA_TYPE_HALFGOOD, '半成品'),
(3, '主要原料'), (MA_TYPE_MAINSO, '主要原料'),
(4, '辅助材料') , (MA_TYPE_HELPSO, '辅助材料') ,
(5, '加工工具'), (MA_TYPE_TOOL, '加工工具'),
(6, '辅助工装') (MA_TYPE_HELPTOOL, '辅助工装')
) )
unit_choices =( unit_choices =(
('', ''), ('', ''),
@ -62,6 +68,15 @@ class Step(CommonAModel):
""" """
工序步骤 工序步骤
""" """
STEP_TYPE_NOM = 1
STEP_TYPE_DIV = 2
STEP_TYPE_COMB = 3
step_type_choices=(
(STEP_TYPE_NOM, '普通'),
(STEP_TYPE_DIV, '分割'),
(STEP_TYPE_COMB, '结合')
)
type = models.IntegerField('操作类型', choices=step_type_choices, default=1)
process = models.ForeignKey(Process, on_delete=models.CASCADE, verbose_name='所属工序', related_name='step_process') process = models.ForeignKey(Process, on_delete=models.CASCADE, verbose_name='所属工序', related_name='step_process')
name = models.CharField('工序步骤名称', max_length=100) name = models.CharField('工序步骤名称', max_length=100)
number = models.CharField('步骤编号', max_length=100, null=True, blank=True) number = models.CharField('步骤编号', max_length=100, null=True, blank=True)
@ -80,9 +95,11 @@ class RecordForm(CommonAModel):
""" """
记录表格 记录表格
""" """
RF_TYPE_DO = 1
RF_TYPE_TEST = 2
type_choices=( type_choices=(
(1, '生产记录'), (RF_TYPE_DO, '生产记录'),
(2, '检验记录') (RF_TYPE_TEST, '检验记录')
) )
name = models.CharField('表格名称', max_length=100, unique=True) name = models.CharField('表格名称', max_length=100, unique=True)
type = models.IntegerField('表格类型', choices=type_choices, default=1) type = models.IntegerField('表格类型', choices=type_choices, default=1)
@ -164,10 +181,13 @@ class SubprodctionMaterial(CommonAModel):
""" """
输入/输出物料/工具工装 输入/输出物料/工具工装
""" """
SUB_MA_TYPE_IN = 1
SUB_MA_TYPE_OUT = 2
SUB_MA_TYPE_TOOL = 3
type_choices=( type_choices=(
(1, '输入物料'), (SUB_MA_TYPE_IN, '输入物料'),
(2, '输出物料'), (SUB_MA_TYPE_OUT, '输出物料'),
(3, '工具工装') (SUB_MA_TYPE_TOOL, '工具工装')
) )
material = models.ForeignKey(Material, verbose_name='物料', on_delete=models.CASCADE, related_name='subplan_material') material = models.ForeignKey(Material, verbose_name='物料', on_delete=models.CASCADE, related_name='subplan_material')
is_main = models.BooleanField('是否主产出', default=False) # 以该产品完成度计算进度 is_main = models.BooleanField('是否主产出', default=False) # 以该产品完成度计算进度

View File

@ -95,9 +95,9 @@ class InputMaterialSerializer(serializers.ModelSerializer):
fields = ['count', 'sort', 'material', 'subproduction'] fields = ['count', 'sort', 'material', 'subproduction']
def create(self, validated_data): def create(self, validated_data):
if SubprodctionMaterial.objects.filter(material=validated_data['material'], subproduction=validated_data['subproduction'], is_deleted=False, type=1).exists(): if SubprodctionMaterial.objects.filter(material=validated_data['material'], subproduction=validated_data['subproduction'], is_deleted=False, type=SubprodctionMaterial.SUB_MA_TYPE_IN).exists():
raise ValidationError('该物料已存在') raise ValidationError('该物料已存在')
validated_data['type']=1 validated_data['type']=SubprodctionMaterial.SUB_MA_TYPE_IN
return super().create(validated_data) return super().create(validated_data)
class InputMaterialUpdateSerializer(serializers.ModelSerializer): class InputMaterialUpdateSerializer(serializers.ModelSerializer):
@ -111,11 +111,11 @@ class OutputMaterialSerializer(serializers.ModelSerializer):
fields = ['count', 'sort', 'material', 'subproduction', 'is_main'] fields = ['count', 'sort', 'material', 'subproduction', 'is_main']
def create(self, validated_data): def create(self, validated_data):
if SubprodctionMaterial.objects.filter(subproduction=validated_data['subproduction'], is_deleted=False, is_main=True, type=2).exists(): if SubprodctionMaterial.objects.filter(subproduction=validated_data['subproduction'], is_deleted=False, is_main=True, type=SubprodctionMaterial.SUB_MA_TYPE_OUT).exists():
raise ValidationError('主产出只能有1个') raise ValidationError('主产出只能有1个')
if SubprodctionMaterial.objects.filter(material=validated_data['material'], subproduction=validated_data['subproduction'], is_deleted=False, type=2).exists(): if SubprodctionMaterial.objects.filter(material=validated_data['material'], subproduction=validated_data['subproduction'], is_deleted=False, type=SubprodctionMaterial.SUB_MA_TYPE_OUT).exists():
raise ValidationError('该物料已存在') raise ValidationError('该物料已存在')
validated_data['type']=2 validated_data['type']=SubprodctionMaterial.SUB_MA_TYPE_OUT
return super().create(validated_data) return super().create(validated_data)
class OutputMaterialUpdateSerializer(serializers.ModelSerializer): class OutputMaterialUpdateSerializer(serializers.ModelSerializer):

View File

@ -85,7 +85,7 @@ class InputMaterialViewSet(CreateUpdateModelAMixin, ModelViewSet):
输入物料-增删改查 输入物料-增删改查
""" """
perms_map = {'*':'*'} perms_map = {'*':'*'}
queryset = SubprodctionMaterial.objects.select_related('material').filter(type=1) queryset = SubprodctionMaterial.objects.select_related('material').filter(type=SubprodctionMaterial.SUB_MA_TYPE_IN)
serializer_class = InputMaterialSerializer serializer_class = InputMaterialSerializer
filterset_fields = ['subproduction'] filterset_fields = ['subproduction']
ordering = ['sort', '-create_time'] ordering = ['sort', '-create_time']
@ -102,7 +102,7 @@ class OutputMaterialViewSet(CreateUpdateModelAMixin, ModelViewSet):
输出物料-增删改查 输出物料-增删改查
""" """
perms_map = {'*':'*'} perms_map = {'*':'*'}
queryset = SubprodctionMaterial.objects.select_related('material').filter(type=2) queryset = SubprodctionMaterial.objects.select_related('material').filter(type=SubprodctionMaterial.SUB_MA_TYPE_OUT)
serializer_class = OutputMaterialSerializer serializer_class = OutputMaterialSerializer
filterset_fields = ['subproduction'] filterset_fields = ['subproduction']
ordering = ['sort', '-create_time'] ordering = ['sort', '-create_time']
@ -119,7 +119,7 @@ class OtherMaterialViewSet(CreateUpdateModelAMixin, ListModelMixin, DestroyModel
其他物料-增删改查 其他物料-增删改查
""" """
perms_map = {'*':'*'} perms_map = {'*':'*'}
queryset = SubprodctionMaterial.objects.select_related('material').filter(type=3) queryset = SubprodctionMaterial.objects.select_related('material').filter(type=SubprodctionMaterial.SUB_MA_TYPE_TOOL)
serializer_class = OutputMaterialSerializer serializer_class = OutputMaterialSerializer
filterset_fields = ['subproduction'] filterset_fields = ['subproduction']
ordering = ['sort', '-create_time'] ordering = ['sort', '-create_time']

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.6 on 2021-11-08 09:07
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('pm', '0011_auto_20211104_1006'),
]
operations = [
migrations.AlterField(
model_name='subproductionprogress',
name='type',
field=models.IntegerField(default=((1, '输入物料'), (2, '输出物料'), (3, '工具工装')), verbose_name='物料应用类型'),
),
]

View File

@ -7,7 +7,7 @@ import django.utils.timezone as timezone
from django.db.models.query import QuerySet from django.db.models.query import QuerySet
from utils.model import SoftModel, BaseModel from utils.model import SoftModel, BaseModel
from apps.mtm.models import Material, Process, SubProduction from apps.mtm.models import Material, Process, SubProduction, SubprodctionMaterial
from apps.sam.models import Order from apps.sam.models import Order
class ProductionPlan(CommonAModel): class ProductionPlan(CommonAModel):
@ -65,15 +65,10 @@ class SubProductionProgress(BaseModel):
""" """
子计划生产进度统计表/物料消耗 子计划生产进度统计表/物料消耗
""" """
type_choices=(
(1, '输入物料'),
(2, '输出物料'),
(3, '工具工装')
)
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.CASCADE, related_name='progress_subplan') subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.CASCADE, related_name='progress_subplan')
material = models.ForeignKey(Material, verbose_name='关联物料', on_delete=models.CASCADE) material = models.ForeignKey(Material, verbose_name='关联物料', on_delete=models.CASCADE)
is_main = models.BooleanField('是否主产出', default=False) is_main = models.BooleanField('是否主产出', default=False)
type = models.IntegerField('物料应用类型', default=1) type = models.IntegerField('物料应用类型', default=SubprodctionMaterial.type_choices)
count = models.IntegerField('应出入数') count = models.IntegerField('应出入数')
count_pick = models.IntegerField('实际领用数', default=0) count_pick = models.IntegerField('实际领用数', default=0)
count_real = models.IntegerField('实际消耗/产出数', default=0) count_real = models.IntegerField('实际消耗/产出数', default=0)

View File

@ -155,7 +155,7 @@ class SubProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, UpdateMo
领料需求清单 领料需求清单
""" """
obj = self.get_object() obj = self.get_object()
instance = SubProductionProgress.objects.filter(subproduction_plan=obj, type=1) instance = SubProductionProgress.objects.filter(subproduction_plan=obj, type=SubprodctionMaterial.SUB_MA_TYPE_IN)
serializer = SubProductionProgressSerializer(instance=instance, many=True) serializer = SubProductionProgressSerializer(instance=instance, many=True)
return Response(serializer.data) return Response(serializer.data)
@ -165,7 +165,7 @@ class SubProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, UpdateMo
领料需求清单/库存数 领料需求清单/库存数
""" """
obj = self.get_object() obj = self.get_object()
instance = SubProductionProgress.objects.filter(subproduction_plan=obj, type=1) instance = SubProductionProgress.objects.filter(subproduction_plan=obj, type=SubprodctionMaterial.SUB_MA_TYPE_IN)
serializer = SubProductionProgressSerializer(instance=instance, many=True) serializer = SubProductionProgressSerializer(instance=instance, many=True)
need = serializer.data need = serializer.data
materials = [] materials = []

View File

@ -30,7 +30,6 @@ class Migration(migrations.Migration):
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='wproduct_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')), ('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='wproduct_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
('m_state', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='所属物料状态')), ('m_state', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='所属物料状态')),
('p_state', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='mtm.step', verbose_name='所在步骤')), ('p_state', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='mtm.step', verbose_name='所在步骤')),
('parent', models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.CASCADE, to='wpm.wproduct', verbose_name='上一级')),
('subproduction_plan', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pm.subproductionplan', verbose_name='关联子生产计划')), ('subproduction_plan', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pm.subproductionplan', verbose_name='关联子生产计划')),
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='wproduct_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')), ('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='wproduct_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
], ],

View File

@ -95,11 +95,6 @@ class Migration(migrations.Migration):
name='act_state', name='act_state',
field=models.IntegerField(choices=[(1, '生产中'), (2, '待检测'), (3, '已合格')], default=0, verbose_name='进行状态'), field=models.IntegerField(choices=[(1, '生产中'), (2, '待检测'), (3, '已合格')], default=0, verbose_name='进行状态'),
), ),
migrations.AlterField(
model_name='wproduct',
name='parent',
field=models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.CASCADE, to='wpm.wproduct', verbose_name='上一级'),
),
migrations.AddField( migrations.AddField(
model_name='wproductrecorddetail', model_name='wproductrecorddetail',
name='wproduct_record', name='wproduct_record',

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.6 on 2021-11-08 09:07
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('wpm', '0007_alter_wproductrecorditem_field_type'),
]
operations = [
migrations.AddField(
model_name='wproduct',
name='is_hidden',
field=models.BooleanField(default=False, verbose_name='是否隐藏'),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.6 on 2021-11-08 15:07
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('wpm', '0008_wproduct_is_hidden'),
]
operations = [
migrations.AddField(
model_name='wproduct',
name='parent',
field=models.JSONField(blank=True, default=list, verbose_name=''),
),
]

View File

@ -0,0 +1,136 @@
# Generated by Django 3.2.6 on 2021-11-08 15:35
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('mtm', '0029_step_type'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('wpm', '0009_wproduct_parent'),
]
operations = [
migrations.CreateModel(
name='Operation',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
('wproducts', models.JSONField(blank=True, default=list, verbose_name='关联产品ID列表')),
('remark', models.CharField(blank=True, max_length=200, null=True, verbose_name='操作备注')),
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='operation_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
('m_state', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='操作时的物料状态')),
('p_state', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='mtm.step', verbose_name='操作步骤')),
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='operation_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='OperationMaterial',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
('type', models.IntegerField(choices=[(1, '消耗'), (2, '产出')], default=0, verbose_name='类型')),
('count', models.IntegerField(verbose_name='消耗或产出数量')),
('material', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='可能产出的副产品')),
('operation', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='wpm.operation', verbose_name='关联的生产操作')),
('wmaterial', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='wpm.wmaterial', verbose_name='关联的车间物料')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='OperationRecord',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='operationrecord_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
('form', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.recordform', verbose_name='所用的生产记录表格')),
('operation', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='wpm.operation', verbose_name='关联的生产操作')),
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='operationrecord_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='OperationRecordItem',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
('field_name', models.CharField(max_length=50, verbose_name='字段名')),
('field_key', models.CharField(max_length=50, verbose_name='字段标识')),
('field_type', models.CharField(choices=[(1, '生产记录'), (2, '检验记录')], max_length=50, verbose_name='字段类型')),
('field_value', models.JSONField(blank=True, default=dict, verbose_name='录入值')),
('sort', models.IntegerField(default=1, verbose_name='排序号')),
('form_field', models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.CASCADE, to='mtm.recordformfield', verbose_name='关联字段')),
('operation_record', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='wpm.operation', verbose_name='关联的生产记录')),
],
options={
'abstract': False,
},
),
migrations.RemoveField(
model_name='wproductmaterial',
name='material',
),
migrations.RemoveField(
model_name='wproductmaterial',
name='wmaterial',
),
migrations.RemoveField(
model_name='wproductmaterial',
name='wproduct_action',
),
migrations.RemoveField(
model_name='wproductrecord',
name='create_by',
),
migrations.RemoveField(
model_name='wproductrecord',
name='form',
),
migrations.RemoveField(
model_name='wproductrecord',
name='update_by',
),
migrations.RemoveField(
model_name='wproductrecord',
name='wproduct_action',
),
migrations.RemoveField(
model_name='wproductrecorditem',
name='form_field',
),
migrations.RemoveField(
model_name='wproductrecorditem',
name='wproduct_record',
),
migrations.DeleteModel(
name='WProductAction',
),
migrations.DeleteModel(
name='WProductMaterial',
),
migrations.DeleteModel(
name='WProductRecord',
),
migrations.DeleteModel(
name='WProductRecordItem',
),
]

View File

@ -12,8 +12,6 @@ class WMaterial(BaseModel):
""" """
车间生产物料 车间生产物料
""" """
# workshop = models.ForeignKey(Organization, verbose_name='生产车间', on_delete=models.CASCADE)
# process = models.ForeignKey(Process, verbose_name='关联大工序', on_delete=models.CASCADE)
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子计划', on_delete=models.CASCADE) subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子计划', on_delete=models.CASCADE)
material = models.ForeignKey(Material, verbose_name='关联物料', on_delete=models.CASCADE) material = models.ForeignKey(Material, verbose_name='关联物料', on_delete=models.CASCADE)
batch = models.CharField('批次号', max_length=100, null=True, blank=True) batch = models.CharField('批次号', max_length=100, null=True, blank=True)
@ -36,13 +34,14 @@ class WProduct(CommonAModel):
p_state = models.ForeignKey(Step, verbose_name='所在步骤', on_delete=models.CASCADE, null=True, blank=True) p_state = models.ForeignKey(Step, verbose_name='所在步骤', on_delete=models.CASCADE, null=True, blank=True)
act_state = models.IntegerField('进行状态', default=0, choices=act_state_choices) act_state = models.IntegerField('进行状态', default=0, choices=act_state_choices)
is_executed = models.BooleanField('子工序是否已执行', default=False) is_executed = models.BooleanField('子工序是否已执行', default=False)
parent = models.ForeignKey('self', verbose_name='上一级', on_delete=models.CASCADE, db_constraint=False, null=True, blank=True) is_hidden = models.BooleanField('是否隐藏', default=False)
parent = models.JSONField('', default=list, blank=True)
remark = models.CharField('备注', max_length=200, null=True, blank=True) remark = models.CharField('备注', max_length=200, null=True, blank=True)
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE) subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE)
production_plan = models.ForeignKey(ProductionPlan, verbose_name='关联主生产计划', on_delete=models.CASCADE) production_plan = models.ForeignKey(ProductionPlan, verbose_name='关联主生产计划', on_delete=models.CASCADE)
class WProductAction(CommonAModel): class Operation(CommonAModel):
""" """
生产操作 生产操作
""" """
@ -51,7 +50,7 @@ class WProductAction(CommonAModel):
p_state = models.ForeignKey(Step, verbose_name='操作步骤', on_delete=models.CASCADE, null=True, blank=True) p_state = models.ForeignKey(Step, verbose_name='操作步骤', on_delete=models.CASCADE, null=True, blank=True)
remark = models.CharField('操作备注', max_length=200, null=True, blank=True) remark = models.CharField('操作备注', max_length=200, null=True, blank=True)
class WProductMaterial(BaseModel): class OperationMaterial(BaseModel):
""" """
车间生产物料消耗产出表 车间生产物料消耗产出表
""" """
@ -60,20 +59,20 @@ class WProductMaterial(BaseModel):
(2, '产出') (2, '产出')
) )
type = models.IntegerField('类型', default=0, choices=type_choices) type = models.IntegerField('类型', default=0, choices=type_choices)
wproduct_action = models.ForeignKey(WProductAction, verbose_name='关联的生产操作', on_delete=models.CASCADE) operation = models.ForeignKey(Operation, verbose_name='关联的生产操作', on_delete=models.CASCADE)
wmaterial = models.ForeignKey(WMaterial, verbose_name='关联的车间物料', on_delete=models.CASCADE, null=True, blank=True) wmaterial = models.ForeignKey(WMaterial, verbose_name='关联的车间物料', on_delete=models.CASCADE, null=True, blank=True)
material = models.ForeignKey(Material, verbose_name='可能产出的副产品', on_delete=models.CASCADE, null=True, blank=True) material = models.ForeignKey(Material, verbose_name='可能产出的副产品', on_delete=models.CASCADE, null=True, blank=True)
count = models.IntegerField('消耗或产出数量') count = models.IntegerField('消耗或产出数量')
class WProductRecord(CommonAModel): class OperationRecord(CommonAModel):
""" """
记录表格 记录表格
""" """
form = models.ForeignKey(RecordForm, verbose_name='所用的生产记录表格', on_delete=models.CASCADE) form = models.ForeignKey(RecordForm, verbose_name='所用的生产记录表格', on_delete=models.CASCADE)
wproduct_action = models.ForeignKey(WProductAction, verbose_name='关联的生产操作', on_delete=models.CASCADE) operation = models.ForeignKey(Operation, verbose_name='关联的生产操作', on_delete=models.CASCADE)
class WProductRecordItem(BaseModel): class OperationRecordItem(BaseModel):
""" """
记录表格字段值 记录表格字段值
""" """
@ -83,5 +82,5 @@ class WProductRecordItem(BaseModel):
field_type = models.CharField('字段类型', choices=RecordForm.type_choices, max_length=50) field_type = models.CharField('字段类型', choices=RecordForm.type_choices, max_length=50)
field_value = models.JSONField('录入值', default=dict, blank=True) field_value = models.JSONField('录入值', default=dict, blank=True)
sort = models.IntegerField('排序号', default=1) sort = models.IntegerField('排序号', default=1)
wproduct_record = models.ForeignKey(WProductRecord, verbose_name='关联的生产记录', on_delete=models.CASCADE) operation_record = models.ForeignKey(Operation, verbose_name='关联的生产记录', on_delete=models.CASCADE)

View File

@ -7,8 +7,8 @@ from apps.mtm.serializers import MaterialSimpleSerializer
from apps.pm.models import SubProductionPlan, SubProductionProgress from apps.pm.models import SubProductionPlan, SubProductionProgress
from django.utils import timezone from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from apps.wpm.models import WMaterial, WProduct, WProductRecord, WProductRecordItem from apps.wpm.models import WMaterial, WProduct, OperationRecord, OperationRecordItem
class PickDetailSerializer(serializers.Serializer): class PickDetailSerializer(serializers.Serializer):
material = serializers.PrimaryKeyRelatedField(queryset=Material.objects.all(), label="物料ID") material = serializers.PrimaryKeyRelatedField(queryset=Material.objects.all(), label="物料ID")
@ -38,7 +38,7 @@ class PickSerializer(serializers.Serializer):
operator = self.context['request'].user operator = self.context['request'].user
validated_data['create_by'] = operator validated_data['create_by'] = operator
validated_data['operator'] = operator validated_data['operator'] = operator
validated_data['type'] = 1 validated_data['type'] = FIFO.FIFO_TYPE_DO_OUT
validated_data['inout_date'] = timezone.now() validated_data['inout_date'] = timezone.now()
fifo = FIFO.objects.create(**validated_data) fifo = FIFO.objects.create(**validated_data)
for i in picks: for i in picks:
@ -81,7 +81,7 @@ class WMaterialListSerializer(serializers.ModelSerializer):
fields = '__all__' fields = '__all__'
class WActionInitSerializer(serializers.Serializer): class OperationInitSerializer(serializers.Serializer):
step = serializers.PrimaryKeyRelatedField(queryset=Step.objects.all(), label="子工序ID") step = serializers.PrimaryKeyRelatedField(queryset=Step.objects.all(), label="子工序ID")
subproduction_plan = serializers.PrimaryKeyRelatedField(queryset=SubProductionPlan.objects.all(), label="子计划ID") subproduction_plan = serializers.PrimaryKeyRelatedField(queryset=SubProductionPlan.objects.all(), label="子计划ID")
wproducts = serializers.ListField(child= wproducts = serializers.ListField(child=
@ -94,17 +94,16 @@ class WActionInitSerializer(serializers.Serializer):
stepIds=[i['id'] for i in subproduction_plan.steps] stepIds=[i['id'] for i in subproduction_plan.steps]
if step.id not in stepIds: if step.id not in stepIds:
raise serializers.ValidationError('请选择正确的子工序操作') raise serializers.ValidationError('请选择正确的子工序操作')
if 'wproducts' in data: if 'wproducts' in data and data['wproducts']:
for i in data['wproducts']: for i in data['wproducts']:
if i.subproduction_plan != subproduction_plan: if i.subproduction_plan != subproduction_plan:
raise serializers.ValidationError('半成品所属子计划不一致') raise serializers.ValidationError('半成品所属子计划不一致')
if i.step != step: if i.step != step:
raise serializers.ValidationError('半成品所属子工序不一致') raise serializers.ValidationError('半成品所属子工序不一致')
else: else:
if WProduct.objects.filter(subproduction_plan__production_plan=subproduction_plan.production_plan, if step.type != Step.STEP_TYPE_DIV:
is_deleted=False).exists(): # 存在动态半成品 # 这里后续需要更改比如报废状态 raise serializers.ValidationError(_('请选择半成品进行操作'))
raise serializers.ValidationError('请选择半成品进行操作')
return data return data
@ -116,27 +115,27 @@ class DoOutputSerializer(serializers.Serializer):
material = serializers.PrimaryKeyRelatedField(queryset=Material.objects.all(), label='物料ID') material = serializers.PrimaryKeyRelatedField(queryset=Material.objects.all(), label='物料ID')
count_output = serializers.IntegerField(min_value=0, label='产出数量') count_output = serializers.IntegerField(min_value=0, label='产出数量')
class WProductRecordItemSerializer(serializers.ModelSerializer): class OperationRecordItemSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = WProductRecordItem model = OperationRecordItem
fields = ['form_field', 'field_value'] fields = ['form_field', 'field_value']
class WProductRecordSerializer(serializers.ModelSerializer): class OperationRecordSerializer(serializers.ModelSerializer):
record_data = WProductRecordItemSerializer(many=True) record_data = OperationRecordItemSerializer(many=True)
class Meta: class Meta:
model = WProductRecord model = OperationRecord
fields = ['form', 'record_data'] fields = ['form', 'record_data']
class WActionSubmitSerializer(serializers.Serializer): class OperationSubmitSerializer(serializers.Serializer):
step = serializers.PrimaryKeyRelatedField(queryset=Step.objects.all(), label="子工序ID") step = serializers.PrimaryKeyRelatedField(queryset=Step.objects.all(), label="子工序ID")
subproduction_plan = serializers.PrimaryKeyRelatedField(queryset=SubProductionPlan.objects.all(), label="子计划ID") subproduction_plan = serializers.PrimaryKeyRelatedField(queryset=SubProductionPlan.objects.all(), label="子计划ID")
wproducts = serializers.ListField(child= wproducts = serializers.ListField(child=
serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all()), label="半成品ID列表", required=False) serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all()), label="半成品ID列表", required=False)
input = DoInputSerializer(many=True, required=False) input = DoInputSerializer(many=True, required=False)
output = DoOutputSerializer(many=True, required=False) output = DoOutputSerializer(many=True, required=False)
forms = WProductRecordSerializer(many=True, required=False) forms = OperationRecordSerializer(many=True, required=False)

View File

@ -5,16 +5,16 @@ from rest_framework.utils import serializer_helpers
from rest_framework.utils.field_mapping import get_relation_kwargs from rest_framework.utils.field_mapping import get_relation_kwargs
from rest_framework.views import APIView from rest_framework.views import APIView
from rest_framework.viewsets import GenericViewSet, ModelViewSet from rest_framework.viewsets import GenericViewSet, ModelViewSet
from apps.mtm.models import Material, RecordForm, Step from apps.mtm.models import Material, RecordForm, Step, SubprodctionMaterial
from apps.mtm.serializers import RecordFormDetailSerializer from apps.mtm.serializers import RecordFormDetailSerializer
from apps.pm.models import SubProductionPlan, SubProductionProgress from apps.pm.models import SubProductionPlan, SubProductionProgress
from apps.pm.serializers import SubProductionPlanListSerializer, SubProductionPlanUpdateSerializer from apps.pm.serializers import SubProductionPlanListSerializer, SubProductionPlanUpdateSerializer
from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
from rest_framework.decorators import action from rest_framework.decorators import action
from apps.wpm.models import WMaterial, WProduct, WProductAction, WProductMaterial, WProductRecord, WProductRecordItem from apps.wpm.models import WMaterial, WProduct, Operation, OperationMaterial, OperationRecord, OperationRecordItem
from apps.wpm.serializers import PickSerializer, WActionInitSerializer, WActionSubmitSerializer, WMaterialListSerializer from apps.wpm.serializers import PickSerializer, OperationInitSerializer, OperationSubmitSerializer, WMaterialListSerializer
from rest_framework.response import Response from rest_framework.response import Response
# Create your views here. # Create your views here.
class WPlanViewSet(ListModelMixin, GenericViewSet): class WPlanViewSet(ListModelMixin, GenericViewSet):
@ -52,13 +52,13 @@ class WMaterialViewSet(CreateUpdateModelAMixin, ListModelMixin, GenericViewSet):
class DoFormInit(CreateAPIView, GenericAPIView): class DoFormInit(CreateAPIView, GenericAPIView):
perms_map={'*':'*'} perms_map={'*':'*'}
serializer_class=WActionInitSerializer serializer_class=OperationInitSerializer
def post(self, request, format=None): def post(self, request, format=None):
""" """
调用操作表单 调用操作表单
""" """
data = request.data data = request.data
serializer = WActionInitSerializer(data=data) serializer = OperationInitSerializer(data=data)
serializer.is_valid(raise_exception=True) serializer.is_valid(raise_exception=True)
vdata = serializer.validated_data vdata = serializer.validated_data
ret = {} ret = {}
@ -75,15 +75,14 @@ class DoFormInit(CreateAPIView, GenericAPIView):
for i in ret_0['input']: for i in ret_0['input']:
i['count_input'] = 0 i['count_input'] = 0
# 需要输出的物料 # 需要输出的物料
# 如果传入半成品列表就不需要
if ret_0['wproducts']: if ret_0['wproducts']:
# 排除wproduct列表 # 排除主要产物, 因为已经放到半成品里了, 由半成品进行处理, 夹层可能需要特殊处理
# mids = WProduct.objects.filter(pk__in=data['wproducts']).values_list('m_state', flat=True)
o_objs = SubProductionProgress.objects.filter( o_objs = SubProductionProgress.objects.filter(
subproduction_plan=vdata['subproduction_plan'], type=2).exclude(is_main=True) subproduction_plan=vdata['subproduction_plan'], type=SubprodctionMaterial.SUB_MA_TYPE_OUT).exclude(is_main=True)
else: else:
o_objs = SubProductionProgress.objects.filter( o_objs = SubProductionProgress.objects.filter(
subproduction_plan=vdata['subproduction_plan'], type=2) subproduction_plan=vdata['subproduction_plan'], type=SubprodctionMaterial.SUB_MA_TYPE_OUT)
ret_0['output'] = list(o_objs.values('material', 'material__name', 'material__number')) ret_0['output'] = list(o_objs.values('material', 'material__name', 'material__number'))
for i in ret_0['output']: for i in ret_0['output']:
i['count_output']=0 i['count_output']=0
@ -91,7 +90,7 @@ class DoFormInit(CreateAPIView, GenericAPIView):
ret_0['id'] = 0 ret_0['id'] = 0
ret_0['name'] = '基本信息' ret_0['name'] = '基本信息'
ret['forms'].append(ret_0) ret['forms'].append(ret_0)
forms = RecordForm.objects.filter(step=vdata['step'], type=1) forms = RecordForm.objects.filter(step=vdata['step'], type=RecordForm.RF_TYPE_DO)
if forms.exists(): if forms.exists():
ret['forms'].extend(RecordFormDetailSerializer(instance=forms, many=True).data) ret['forms'].extend(RecordFormDetailSerializer(instance=forms, many=True).data)
return Response(ret) return Response(ret)
@ -99,17 +98,18 @@ class DoFormInit(CreateAPIView, GenericAPIView):
class DoFormSubmit(CreateAPIView, GenericAPIView): class DoFormSubmit(CreateAPIView, GenericAPIView):
perms_map={'*':'*'} perms_map={'*':'*'}
serializer_class = WActionSubmitSerializer serializer_class = OperationSubmitSerializer
def post(self, request, format=None): def post(self, request, format=None):
""" """
提交操作表单 提交操作表单
""" """
data = request.data data = request.data
serializer = WActionSubmitSerializer(data=data, context={'request':self.request}) serializer = OperationSubmitSerializer(data=data, context={'request':self.request})
serializer.is_valid(raise_exception=True) serializer.is_valid(raise_exception=True)
vdata = serializer.validated_data #校验之后的数据 vdata = serializer.validated_data #校验之后的数据
# 创建一个生产操作记录 # 创建一个生产操作记录
action_obj = WProductAction() action_obj = Operation()
action_obj.p_state = vdata['step'] action_obj.p_state = vdata['step']
if 'wproducts' in data and data['wproducts']: if 'wproducts' in data and data['wproducts']:
action_obj.wproducts = data['wproducts'] action_obj.wproducts = data['wproducts']
@ -122,7 +122,7 @@ class DoFormSubmit(CreateAPIView, GenericAPIView):
for i in vdata['input']: for i in vdata['input']:
if i['count_input']: #如果有消耗 if i['count_input']: #如果有消耗
i_wmat = i['id'] i_wmat = i['id']
WProductMaterial.objects.create(type=1, wproduct_action=action_obj, OperationMaterial.objects.create(type=1, operation=action_obj,
wmaterial= i_wmat, count=i['count_input']) wmaterial= i_wmat, count=i['count_input'])
# 更新车间物料 # 更新车间物料
i_wmat.count = i_wmat.count- i['count_input'] i_wmat.count = i_wmat.count- i['count_input']
@ -139,15 +139,20 @@ class DoFormSubmit(CreateAPIView, GenericAPIView):
ma = i['material'] ma = i['material']
if ma.is_main: if ma.is_main:
# 计划开始, 第一步切割创建动态产品 # 计划开始, 第一步切割创建动态产品
wpr = dict(m_state=ma, p_state=vdata['step'], # 如果是切割
act_state=WProduct.WPR_ACT_STATE_DOING, is_executed=True, remark='', # 获取下一步子工序
subproduction_plan=vdata['subproduction_plan'], if vdata['step'].type == Step.STEP_TYPE_DIV:
production_plan=vdata['subproduction_plan'].production_plan) stepIds = [i['id'] for i in vdata['subproduction_plan'].steps]
for x in range(i['count_output']): pindex = stepIds.index(vdata['step'].id)
WProduct.objects.create(**wpr) wpr = dict(m_state=ma, p_state=Step.objects.get(pk=stepIds[pindex+1]),
act_state=WProduct.WPR_ACT_STATE_DOING, is_executed=False, remark='',
subproduction_plan=vdata['subproduction_plan'],
production_plan=vdata['subproduction_plan'].production_plan)
for x in range(i['count_output']):
WProduct.objects.create(**wpr)
else: else:
# 更新操作消耗物料表 # 更新操作产出物料表
WProductMaterial.objects.create(type=2, wproduct_action=action_obj, OperationMaterial.objects.create(type=2, operation=action_obj,
material= ma, count=i['count_output']) material= ma, count=i['count_output'])
# 更新车间物料表 # 更新车间物料表
ins, _ = WMaterial.objects.get_or_create(subproduction_plan=vdata['subproduction_plan'], ins, _ = WMaterial.objects.get_or_create(subproduction_plan=vdata['subproduction_plan'],
@ -160,17 +165,49 @@ class DoFormSubmit(CreateAPIView, GenericAPIView):
sp.count_real = sp.count_real + i['count_input'] sp.count_real = sp.count_real + i['count_input']
sp.save() sp.save()
# 更新主产出 # 更新动态产品表
if 'wproducts' in data and data['wproducts']: if 'wproducts' in data and data['wproducts']:
wproducts = WProduct.objects.filter(pk__in=data['wproducts']) wproducts = WProduct.objects.filter(pk__in=data['wproducts'])
wproducts.update(p_state=vdata['step'], is_executed=True) # 获取下一步子工序
stepIds = [i['id'] for i in vdata['subproduction_plan'].steps]
pindex = stepIds.index(vdata['step'].id)
if pindex + 1 < len(stepIds): # 如果不是最后一步
newstep = Step.objects.get(pk=stepIds[pindex+1])
wproducts.update(p_state=newstep, is_executed=False)
# 特殊情况如果是夹层结合
if vdata['step'].type == Step.STEP_TYPE_COMB:
wproducts.update(is_hidden=True) # 隐藏
WProduct.objects.create(
m_state=vdata['subproduction_plan'].main_product, p_state = newstep,
act_state=WProduct.WPR_ACT_STATE_DOING, is_executed=False, remark='',
subproduction_plan=vdata['subproduction_plan'],
production_plan=vdata['subproduction_plan'].production_plan,
parent = data['wproducts']
)
else: # 如果是最后一步, 此时需要转序并更新状态为待检测
newstep = vdata['step']
wproducts.update(p_state=newstep, is_executed=True, act_state=WProduct.WPR_ACT_STATE_TOTEST)
# 特殊情况如果是夹层结合
if vdata['step'].type == Step.STEP_TYPE_COMB:
wproducts.update(is_hidden=True) # 隐藏
WProduct.objects.create(
m_state=vdata['subproduction_plan'].main_product, p_state = newstep,
act_state=WProduct.WPR_ACT_STATE_TOTEST, is_executed=True, remark='',
subproduction_plan=vdata['subproduction_plan'],
production_plan=vdata['subproduction_plan'].production_plan
)
# 保存自定义表单结果 # 保存自定义表单结果
for i in vdata['forms']: for i in vdata['forms']:
wr = WProductRecord() wr = OperationRecord()
wr.form = i['form'] wr.form = i['form']
wr.create_by = request.user wr.create_by = request.user
wr.wproduct_action = action_obj wr.operation = action_obj
wr.save() wr.save()
wrds = [] wrds = []
for m in i['record_data']: # 保存记录详情 for m in i['record_data']: # 保存记录详情
@ -180,9 +217,9 @@ class DoFormSubmit(CreateAPIView, GenericAPIView):
m['field_type'] = form_field.field_type m['field_type'] = form_field.field_type
m['field_value'] = m['field_value'] m['field_value'] = m['field_value']
m['sort'] = form_field.sort m['sort'] = form_field.sort
m['wproduct_record'] = wr m['operation_record'] = wr
wrds.append(WProductRecordItem(**m)) wrds.append(OperationRecordItem(**m))
WProductRecordItem.objects.bulk_create(wrds) Operation.objects.bulk_create(wrds)
return Response() return Response()