修改表名
This commit is contained in:
parent
b083f1cd8d
commit
2b3f45eb7f
|
@ -66,7 +66,7 @@
|
|||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-card style="margin-top: 6px">
|
||||
<el-card style="margin-top: 2px">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>日志列表</span>
|
||||
</div>
|
||||
|
|
|
@ -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 = (
|
||||
(1, '生产领料'),
|
||||
(2, '销售提货'),
|
||||
(3, '采购入库'),
|
||||
(4, '生产入库')
|
||||
(FIFO_TYPE_DO_OUT, '生产领料'),
|
||||
(FIFO_TYPE_SALE_OUT, '销售提货'),
|
||||
(FIFO_TYPE_PUR_IN, '采购入库'),
|
||||
(FIFO_TYPE_DO_IN, '生产入库')
|
||||
)
|
||||
type = models.IntegerField('出入库类型', default=1)
|
||||
is_audited = models.BooleanField('是否审核', default=False)
|
||||
|
|
|
@ -91,7 +91,7 @@ class FIFOInPurSerializer(serializers.ModelSerializer):
|
|||
pass
|
||||
|
||||
# 创建采购入库
|
||||
validated_data['type'] = 3
|
||||
validated_data['type'] = FIFO.FIFO_TYPE_PUR_IN
|
||||
obj = FIFO(**validated_data)
|
||||
obj.save()
|
||||
for i in details:
|
||||
|
|
|
@ -9,7 +9,7 @@ def update_inm(instance:FIFO, type:int=1):
|
|||
更新库存(正反)
|
||||
"""
|
||||
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):
|
||||
material = i.material
|
||||
|
@ -23,7 +23,7 @@ def update_inm(instance:FIFO, type:int=1):
|
|||
o2.save()
|
||||
material.count = material.count + i.count
|
||||
material.save()
|
||||
elif instance.type in [1]: # 生产领料
|
||||
elif instance.type in [FIFO.FIFO_TYPE_DO_OUT]: # 生产领料
|
||||
# 更新相关表
|
||||
for i in FIFOItem.objects.filter(fifo=instance):
|
||||
material = i.material
|
||||
|
|
|
@ -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='操作类型'),
|
||||
),
|
||||
]
|
|
@ -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=(
|
||||
(1, '成品'),
|
||||
(2, '半成品'),
|
||||
(3, '主要原料'),
|
||||
(4, '辅助材料') ,
|
||||
(5, '加工工具'),
|
||||
(6, '辅助工装')
|
||||
(MA_TYPE_GOOD, '成品'),
|
||||
(MA_TYPE_HALFGOOD, '半成品'),
|
||||
(MA_TYPE_MAINSO, '主要原料'),
|
||||
(MA_TYPE_HELPSO, '辅助材料') ,
|
||||
(MA_TYPE_TOOL, '加工工具'),
|
||||
(MA_TYPE_HELPTOOL, '辅助工装')
|
||||
)
|
||||
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')
|
||||
name = models.CharField('工序步骤名称', max_length=100)
|
||||
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=(
|
||||
(1, '生产记录'),
|
||||
(2, '检验记录')
|
||||
(RF_TYPE_DO, '生产记录'),
|
||||
(RF_TYPE_TEST, '检验记录')
|
||||
)
|
||||
name = models.CharField('表格名称', max_length=100, unique=True)
|
||||
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=(
|
||||
(1, '输入物料'),
|
||||
(2, '输出物料'),
|
||||
(3, '工具工装')
|
||||
(SUB_MA_TYPE_IN, '输入物料'),
|
||||
(SUB_MA_TYPE_OUT, '输出物料'),
|
||||
(SUB_MA_TYPE_TOOL, '工具工装')
|
||||
)
|
||||
material = models.ForeignKey(Material, verbose_name='物料', on_delete=models.CASCADE, related_name='subplan_material')
|
||||
is_main = models.BooleanField('是否主产出', default=False) # 以该产品完成度计算进度
|
||||
|
|
|
@ -95,9 +95,9 @@ class InputMaterialSerializer(serializers.ModelSerializer):
|
|||
fields = ['count', 'sort', 'material', 'subproduction']
|
||||
|
||||
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('该物料已存在')
|
||||
validated_data['type']=1
|
||||
validated_data['type']=SubprodctionMaterial.SUB_MA_TYPE_IN
|
||||
return super().create(validated_data)
|
||||
|
||||
class InputMaterialUpdateSerializer(serializers.ModelSerializer):
|
||||
|
@ -111,11 +111,11 @@ class OutputMaterialSerializer(serializers.ModelSerializer):
|
|||
fields = ['count', 'sort', 'material', 'subproduction', 'is_main']
|
||||
|
||||
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个')
|
||||
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('该物料已存在')
|
||||
validated_data['type']=2
|
||||
validated_data['type']=SubprodctionMaterial.SUB_MA_TYPE_OUT
|
||||
return super().create(validated_data)
|
||||
|
||||
class OutputMaterialUpdateSerializer(serializers.ModelSerializer):
|
||||
|
|
|
@ -85,7 +85,7 @@ class InputMaterialViewSet(CreateUpdateModelAMixin, ModelViewSet):
|
|||
输入物料-增删改查
|
||||
"""
|
||||
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
|
||||
filterset_fields = ['subproduction']
|
||||
ordering = ['sort', '-create_time']
|
||||
|
@ -102,7 +102,7 @@ class OutputMaterialViewSet(CreateUpdateModelAMixin, ModelViewSet):
|
|||
输出物料-增删改查
|
||||
"""
|
||||
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
|
||||
filterset_fields = ['subproduction']
|
||||
ordering = ['sort', '-create_time']
|
||||
|
@ -119,7 +119,7 @@ class OtherMaterialViewSet(CreateUpdateModelAMixin, ListModelMixin, DestroyModel
|
|||
其他物料-增删改查
|
||||
"""
|
||||
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
|
||||
filterset_fields = ['subproduction']
|
||||
ordering = ['sort', '-create_time']
|
||||
|
|
|
@ -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='物料应用类型'),
|
||||
),
|
||||
]
|
|
@ -7,7 +7,7 @@ import django.utils.timezone as timezone
|
|||
from django.db.models.query import QuerySet
|
||||
|
||||
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
|
||||
|
||||
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')
|
||||
material = models.ForeignKey(Material, verbose_name='关联物料', on_delete=models.CASCADE)
|
||||
is_main = models.BooleanField('是否主产出', default=False)
|
||||
type = models.IntegerField('物料应用类型', default=1)
|
||||
type = models.IntegerField('物料应用类型', default=SubprodctionMaterial.type_choices)
|
||||
count = models.IntegerField('应出入数')
|
||||
count_pick = models.IntegerField('实际领用数', default=0)
|
||||
count_real = models.IntegerField('实际消耗/产出数', default=0)
|
||||
|
|
|
@ -155,7 +155,7 @@ class SubProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, UpdateMo
|
|||
领料需求清单
|
||||
"""
|
||||
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)
|
||||
return Response(serializer.data)
|
||||
|
||||
|
@ -165,7 +165,7 @@ class SubProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, UpdateMo
|
|||
领料需求清单/库存数
|
||||
"""
|
||||
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)
|
||||
need = serializer.data
|
||||
materials = []
|
||||
|
|
|
@ -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='创建人')),
|
||||
('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='所在步骤')),
|
||||
('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='关联子生产计划')),
|
||||
('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='最后编辑人')),
|
||||
],
|
||||
|
|
|
@ -95,11 +95,6 @@ class Migration(migrations.Migration):
|
|||
name='act_state',
|
||||
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(
|
||||
model_name='wproductrecorddetail',
|
||||
name='wproduct_record',
|
||||
|
|
|
@ -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='是否隐藏'),
|
||||
),
|
||||
]
|
|
@ -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='父'),
|
||||
),
|
||||
]
|
|
@ -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',
|
||||
),
|
||||
]
|
|
@ -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)
|
||||
material = models.ForeignKey(Material, verbose_name='关联物料', on_delete=models.CASCADE)
|
||||
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)
|
||||
act_state = models.IntegerField('进行状态', default=0, choices=act_state_choices)
|
||||
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)
|
||||
subproduction_plan = models.ForeignKey(SubProductionPlan, 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)
|
||||
remark = models.CharField('操作备注', max_length=200, null=True, blank=True)
|
||||
|
||||
class WProductMaterial(BaseModel):
|
||||
class OperationMaterial(BaseModel):
|
||||
"""
|
||||
车间生产物料消耗产出表
|
||||
"""
|
||||
|
@ -60,20 +59,20 @@ class WProductMaterial(BaseModel):
|
|||
(2, '产出')
|
||||
)
|
||||
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)
|
||||
material = models.ForeignKey(Material, verbose_name='可能产出的副产品', on_delete=models.CASCADE, null=True, blank=True)
|
||||
count = models.IntegerField('消耗或产出数量')
|
||||
|
||||
class WProductRecord(CommonAModel):
|
||||
class OperationRecord(CommonAModel):
|
||||
"""
|
||||
记录表格
|
||||
"""
|
||||
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_value = models.JSONField('录入值', default=dict, blank=True)
|
||||
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)
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ from apps.mtm.serializers import MaterialSimpleSerializer
|
|||
|
||||
from apps.pm.models import SubProductionPlan, SubProductionProgress
|
||||
from django.utils import timezone
|
||||
|
||||
from apps.wpm.models import WMaterial, WProduct, WProductRecord, WProductRecordItem
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from apps.wpm.models import WMaterial, WProduct, OperationRecord, OperationRecordItem
|
||||
|
||||
class PickDetailSerializer(serializers.Serializer):
|
||||
material = serializers.PrimaryKeyRelatedField(queryset=Material.objects.all(), label="物料ID")
|
||||
|
@ -38,7 +38,7 @@ class PickSerializer(serializers.Serializer):
|
|||
operator = self.context['request'].user
|
||||
validated_data['create_by'] = operator
|
||||
validated_data['operator'] = operator
|
||||
validated_data['type'] = 1
|
||||
validated_data['type'] = FIFO.FIFO_TYPE_DO_OUT
|
||||
validated_data['inout_date'] = timezone.now()
|
||||
fifo = FIFO.objects.create(**validated_data)
|
||||
for i in picks:
|
||||
|
@ -81,7 +81,7 @@ class WMaterialListSerializer(serializers.ModelSerializer):
|
|||
fields = '__all__'
|
||||
|
||||
|
||||
class WActionInitSerializer(serializers.Serializer):
|
||||
class OperationInitSerializer(serializers.Serializer):
|
||||
step = serializers.PrimaryKeyRelatedField(queryset=Step.objects.all(), label="子工序ID")
|
||||
subproduction_plan = serializers.PrimaryKeyRelatedField(queryset=SubProductionPlan.objects.all(), label="子计划ID")
|
||||
wproducts = serializers.ListField(child=
|
||||
|
@ -94,17 +94,16 @@ class WActionInitSerializer(serializers.Serializer):
|
|||
stepIds=[i['id'] for i in subproduction_plan.steps]
|
||||
if step.id not in stepIds:
|
||||
raise serializers.ValidationError('请选择正确的子工序操作')
|
||||
|
||||
if 'wproducts' in data:
|
||||
|
||||
if 'wproducts' in data and data['wproducts']:
|
||||
for i in data['wproducts']:
|
||||
if i.subproduction_plan != subproduction_plan:
|
||||
raise serializers.ValidationError('半成品所属子计划不一致')
|
||||
if i.step != step:
|
||||
raise serializers.ValidationError('半成品所属子工序不一致')
|
||||
else:
|
||||
if WProduct.objects.filter(subproduction_plan__production_plan=subproduction_plan.production_plan,
|
||||
is_deleted=False).exists(): # 存在动态半成品 # 这里后续需要更改比如报废状态
|
||||
raise serializers.ValidationError('请选择半成品进行操作')
|
||||
if step.type != Step.STEP_TYPE_DIV:
|
||||
raise serializers.ValidationError(_('请选择半成品进行操作'))
|
||||
return data
|
||||
|
||||
|
||||
|
@ -116,27 +115,27 @@ class DoOutputSerializer(serializers.Serializer):
|
|||
material = serializers.PrimaryKeyRelatedField(queryset=Material.objects.all(), label='物料ID')
|
||||
count_output = serializers.IntegerField(min_value=0, label='产出数量')
|
||||
|
||||
class WProductRecordItemSerializer(serializers.ModelSerializer):
|
||||
class OperationRecordItemSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = WProductRecordItem
|
||||
model = OperationRecordItem
|
||||
fields = ['form_field', 'field_value']
|
||||
|
||||
class WProductRecordSerializer(serializers.ModelSerializer):
|
||||
record_data = WProductRecordItemSerializer(many=True)
|
||||
class OperationRecordSerializer(serializers.ModelSerializer):
|
||||
record_data = OperationRecordItemSerializer(many=True)
|
||||
class Meta:
|
||||
model = WProductRecord
|
||||
model = OperationRecord
|
||||
fields = ['form', 'record_data']
|
||||
|
||||
|
||||
|
||||
class WActionSubmitSerializer(serializers.Serializer):
|
||||
class OperationSubmitSerializer(serializers.Serializer):
|
||||
step = serializers.PrimaryKeyRelatedField(queryset=Step.objects.all(), label="子工序ID")
|
||||
subproduction_plan = serializers.PrimaryKeyRelatedField(queryset=SubProductionPlan.objects.all(), label="子计划ID")
|
||||
wproducts = serializers.ListField(child=
|
||||
serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all()), label="半成品ID列表", required=False)
|
||||
input = DoInputSerializer(many=True, required=False)
|
||||
output = DoOutputSerializer(many=True, required=False)
|
||||
forms = WProductRecordSerializer(many=True, required=False)
|
||||
forms = OperationRecordSerializer(many=True, required=False)
|
||||
|
||||
|
||||
|
|
@ -5,16 +5,16 @@ from rest_framework.utils import serializer_helpers
|
|||
from rest_framework.utils.field_mapping import get_relation_kwargs
|
||||
from rest_framework.views import APIView
|
||||
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.pm.models import SubProductionPlan, SubProductionProgress
|
||||
from apps.pm.serializers import SubProductionPlanListSerializer, SubProductionPlanUpdateSerializer
|
||||
|
||||
from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
|
||||
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
|
||||
# Create your views here.
|
||||
class WPlanViewSet(ListModelMixin, GenericViewSet):
|
||||
|
@ -52,13 +52,13 @@ class WMaterialViewSet(CreateUpdateModelAMixin, ListModelMixin, GenericViewSet):
|
|||
|
||||
class DoFormInit(CreateAPIView, GenericAPIView):
|
||||
perms_map={'*':'*'}
|
||||
serializer_class=WActionInitSerializer
|
||||
serializer_class=OperationInitSerializer
|
||||
def post(self, request, format=None):
|
||||
"""
|
||||
调用操作表单
|
||||
"""
|
||||
data = request.data
|
||||
serializer = WActionInitSerializer(data=data)
|
||||
serializer = OperationInitSerializer(data=data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
vdata = serializer.validated_data
|
||||
ret = {}
|
||||
|
@ -75,15 +75,14 @@ class DoFormInit(CreateAPIView, GenericAPIView):
|
|||
for i in ret_0['input']:
|
||||
i['count_input'] = 0
|
||||
# 需要输出的物料
|
||||
# 如果传入半成品列表就不需要
|
||||
if ret_0['wproducts']:
|
||||
# 排除wproduct列表
|
||||
# mids = WProduct.objects.filter(pk__in=data['wproducts']).values_list('m_state', flat=True)
|
||||
# 排除主要产物, 因为已经放到半成品里了, 由半成品进行处理, 夹层可能需要特殊处理
|
||||
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:
|
||||
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'))
|
||||
for i in ret_0['output']:
|
||||
i['count_output']=0
|
||||
|
@ -91,7 +90,7 @@ class DoFormInit(CreateAPIView, GenericAPIView):
|
|||
ret_0['id'] = 0
|
||||
ret_0['name'] = '基本信息'
|
||||
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():
|
||||
ret['forms'].extend(RecordFormDetailSerializer(instance=forms, many=True).data)
|
||||
return Response(ret)
|
||||
|
@ -99,17 +98,18 @@ class DoFormInit(CreateAPIView, GenericAPIView):
|
|||
|
||||
class DoFormSubmit(CreateAPIView, GenericAPIView):
|
||||
perms_map={'*':'*'}
|
||||
serializer_class = WActionSubmitSerializer
|
||||
serializer_class = OperationSubmitSerializer
|
||||
def post(self, request, format=None):
|
||||
"""
|
||||
提交操作表单
|
||||
"""
|
||||
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)
|
||||
vdata = serializer.validated_data #校验之后的数据
|
||||
|
||||
# 创建一个生产操作记录
|
||||
action_obj = WProductAction()
|
||||
action_obj = Operation()
|
||||
action_obj.p_state = vdata['step']
|
||||
if 'wproducts' in data and data['wproducts']:
|
||||
action_obj.wproducts = data['wproducts']
|
||||
|
@ -122,7 +122,7 @@ class DoFormSubmit(CreateAPIView, GenericAPIView):
|
|||
for i in vdata['input']:
|
||||
if i['count_input']: #如果有消耗
|
||||
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'])
|
||||
# 更新车间物料
|
||||
i_wmat.count = i_wmat.count- i['count_input']
|
||||
|
@ -139,15 +139,20 @@ class DoFormSubmit(CreateAPIView, GenericAPIView):
|
|||
ma = i['material']
|
||||
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'],
|
||||
production_plan=vdata['subproduction_plan'].production_plan)
|
||||
for x in range(i['count_output']):
|
||||
WProduct.objects.create(**wpr)
|
||||
# 如果是切割
|
||||
# 获取下一步子工序
|
||||
if vdata['step'].type == Step.STEP_TYPE_DIV:
|
||||
stepIds = [i['id'] for i in vdata['subproduction_plan'].steps]
|
||||
pindex = stepIds.index(vdata['step'].id)
|
||||
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:
|
||||
# 更新操作消耗物料表
|
||||
WProductMaterial.objects.create(type=2, wproduct_action=action_obj,
|
||||
# 更新操作产出物料表
|
||||
OperationMaterial.objects.create(type=2, operation=action_obj,
|
||||
material= ma, count=i['count_output'])
|
||||
# 更新车间物料表
|
||||
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.save()
|
||||
|
||||
# 更新主产出
|
||||
# 更新动态产品表
|
||||
if 'wproducts' in data and 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']:
|
||||
wr = WProductRecord()
|
||||
wr = OperationRecord()
|
||||
wr.form = i['form']
|
||||
wr.create_by = request.user
|
||||
wr.wproduct_action = action_obj
|
||||
wr.operation = action_obj
|
||||
wr.save()
|
||||
wrds = []
|
||||
for m in i['record_data']: # 保存记录详情
|
||||
|
@ -180,9 +217,9 @@ class DoFormSubmit(CreateAPIView, GenericAPIView):
|
|||
m['field_type'] = form_field.field_type
|
||||
m['field_value'] = m['field_value']
|
||||
m['sort'] = form_field.sort
|
||||
m['wproduct_record'] = wr
|
||||
wrds.append(WProductRecordItem(**m))
|
||||
WProductRecordItem.objects.bulk_create(wrds)
|
||||
m['operation_record'] = wr
|
||||
wrds.append(OperationRecordItem(**m))
|
||||
Operation.objects.bulk_create(wrds)
|
||||
return Response()
|
||||
|
||||
|
Loading…
Reference in New Issue