领料入库item关联子计划

This commit is contained in:
caoqianming 2021-11-12 13:16:29 +08:00
parent 9236200cf3
commit a1ecad9ffe
8 changed files with 109 additions and 12 deletions

View File

@ -0,0 +1,51 @@
# Generated by Django 3.2.6 on 2021-11-12 03:24
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('wpm', '0012_auto_20211111_1056'),
('mtm', '0030_step_need_test'),
('pm', '0012_alter_subproductionprogress_type'),
('inm', '0015_auto_20211111_0940'),
]
operations = [
migrations.RemoveField(
model_name='fifo',
name='subproduction_plan',
),
migrations.RemoveField(
model_name='iproduct',
name='fifos',
),
migrations.RemoveField(
model_name='iproduct',
name='state',
),
migrations.AddField(
model_name='fifoitem',
name='subproduction_plan',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='pm.subproductionplan', verbose_name='关联子生产计划'),
),
migrations.CreateModel(
name='FIFOItemProduct',
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='删除标记')),
('number', models.CharField(max_length=50, verbose_name='物品编号')),
('fifoitem', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='inm.fifoitem', verbose_name='关联出入库具体产品')),
('material', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='物料类型')),
('wproduct', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.CASCADE, to='wpm.wproduct', verbose_name='关联的动态产品')),
],
options={
'abstract': False,
},
),
]

View File

@ -67,7 +67,6 @@ class FIFO(CommonAModel):
type = models.IntegerField('出入库类型', default=1)
is_audited = models.BooleanField('是否审核', default=False)
auditor = models.ForeignKey(User, verbose_name='审核人', on_delete=models.CASCADE, null=True, blank=True)
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.DO_NOTHING, null=True, blank=True)
inout_date = models.DateField('出入库日期')
remark = models.CharField('备注', max_length=1000, default='')
@ -83,23 +82,25 @@ class FIFOItem(BaseModel):
count = models.IntegerField('数量', default=0, validators=[MinValueValidator(0)])
batch = models.CharField('批次号', max_length=100, default='')
fifo = models.ForeignKey(FIFO, verbose_name='关联出入库', on_delete=models.CASCADE)
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.DO_NOTHING, null=True, blank=True)
class FIFOItemProduct(BaseModel):
"""
出入库产品
"""
fifoitem = models.ForeignKey(FIFOItem, verbose_name='关联出入库具体产品', on_delete=models.CASCADE)
wproduct = models.ForeignKey('wpm.wproduct', on_delete=models.CASCADE, verbose_name='关联的动态产品', db_constraint=False, null=True, blank=True)
number = models.CharField('物品编号', max_length=50)
material = models.ForeignKey(Material, verbose_name='物料类型', on_delete=models.CASCADE)
class IProduct(BaseModel):
"""
具体产品条目
"""
inm_product_state_choices = (
(1, '可用'),
(2, '锁定'),
(3, '已消耗')
)
state = models.IntegerField('物品状态', default=1)
number = models.CharField('物品编号', unique=True, null=True, blank=True, max_length=50)
material = models.ForeignKey(Material, verbose_name='物料类型', on_delete=models.CASCADE)
warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库')
batch = models.CharField('所属批次号', max_length=100, default='')
wproduct = models.ForeignKey('wpm.wproduct', on_delete=models.CASCADE, verbose_name='关联的动态产品', db_constraint=False, null=True, blank=True)
fifos = models.JSONField('关联出入库记录', default=list, blank=True)

View File

@ -130,6 +130,7 @@ class InmTestRecordItemCreateSerializer(serializers.ModelSerializer):
class InmTestRecordCreateSerializer(serializers.ModelSerializer):
record_data = InmTestRecordItemCreateSerializer(many=True)
fifo_item = serializers.PrimaryKeyRelatedField(queryset=FIFOItem.objects.all(), required=True)
is_testok = serializers.BooleanField()
class Meta:
model = TestRecord
fields = ['form', 'record_data', 'is_testok', 'fifo_item']

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.6 on 2021-11-12 03:24
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('mtm', '0029_step_type'),
]
operations = [
migrations.AddField(
model_name='step',
name='need_test',
field=models.BooleanField(default=False, verbose_name='是否需要过程检验'),
),
]

View File

@ -81,6 +81,7 @@ class Step(CommonAModel):
name = models.CharField('工序步骤名称', max_length=100)
number = models.CharField('步骤编号', max_length=100, null=True, blank=True)
instruction_content = models.TextField('相应操作指导', null=True, blank=True)
need_test = models.BooleanField('是否需要过程检验', default=False)
sort = models.IntegerField('排序号', default=1)
equipments = models.ManyToManyField(Equipment, verbose_name='使用设备', related_name='step_equips')

View File

@ -13,6 +13,8 @@ def update_subplan_main(sender, instance, created, **kwargs):
subplan.main_product = instance.material
subplan.main_count = instance.count
subplan.main_count_real = instance.count_real
if subplan.main_count == instance.count_real:
subplan.state = 4
subplan.save()

View File

@ -25,7 +25,7 @@ class PickSerializer(serializers.Serializer):
def create(self, validated_data):
picks = validated_data.pop('picks')
sp = validated_data['subproduction_plan']
sp = validated_data.pop('subproduction_plan')
if sp.state not in [1,2]:
raise exceptions.ValidationError('该子计划状态错误')
if sp.is_picked:
@ -48,6 +48,7 @@ class PickSerializer(serializers.Serializer):
i['fifo'] = fifo
i['count'] = i.pop('pick_count')
i['is_testok'] = True # 默认检测合格
i['subproduction_plan'] = sp
FIFOItem.objects.create(**i)
# 更新车间物料
wm, _ = WMaterial.objects.get_or_create(material=i['material'], batch=i['batch'], \
@ -183,6 +184,7 @@ class WpmTestRecordItemCreateSerializer(serializers.ModelSerializer):
class WpmTestRecordCreateSerializer(serializers.ModelSerializer):
record_data = WpmTestRecordItemCreateSerializer(many=True)
wproduct = serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all(), required=True)
is_testok = serializers.BooleanField()
class Meta:
model = TestRecord
fields = ['form', 'record_data', 'is_testok', 'wproduct']

View File

@ -53,6 +53,7 @@ class WMaterialViewSet(CreateUpdateModelAMixin, ListModelMixin, GenericViewSet):
serializer.save()
return Response()
class WProductViewSet(ListModelMixin, GenericViewSet):
"""
半成品
@ -65,6 +66,13 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
ordering_fields = ['id']
ordering = ['id']
@action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=WpmTestRecordCreateSerializer)
@transaction.atomic
def putin():
"""
半成品入库
"""
@action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=WpmTestRecordCreateSerializer)
@transaction.atomic
def test(self, request, pk=None):
@ -77,7 +85,7 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
record_data = vdata.pop('record_data')
wproduct = vdata['wproduct']
if wproduct.act_state != WProduct.WPR_ACT_STATE_TOTEST:
raise exceptions.APIException('该半成品无需检测')
raise exceptions.APIException('该半成品不可检测')
if 'is_testok' not in vdata:
raise exceptions.APIException('未填写检测结论')
@ -96,8 +104,21 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
tris.append(TestRecordItem(**m))
TestRecordItem.objects.bulk_create(tris)
# 如果检测合格
# 如果检测合格, 变更动态产品进行状态
if obj.is_testok:
vdata['wproduct'].act_state = WProduct.WPR_ACT_STATE_OK
vdata['wproduct'].save()
# 更新子计划状态
# 获取该子计划主产品数, 更新进度
main_count = WProduct.objects.filter(subproduction_plan=wproduct.subproduction_plan, act_stae=WProduct.WPR_ACT_STATE_OK).count()
instance = SubProductionProgress.objects.get(subproduction_plan=wproduct.subproduction_plan,
is_main=True, type=SubprodctionMaterial.SUB_MA_TYPE_OUT)
instance.count_real = main_count
instance.save()
else:# 如果不合格
pass
return Response()
class OperationViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):