领料入库item关联子计划
This commit is contained in:
parent
9236200cf3
commit
a1ecad9ffe
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
|
@ -67,7 +67,6 @@ class FIFO(CommonAModel):
|
||||||
type = models.IntegerField('出入库类型', default=1)
|
type = models.IntegerField('出入库类型', default=1)
|
||||||
is_audited = models.BooleanField('是否审核', default=False)
|
is_audited = models.BooleanField('是否审核', default=False)
|
||||||
auditor = models.ForeignKey(User, verbose_name='审核人', on_delete=models.CASCADE, null=True, blank=True)
|
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('出入库日期')
|
inout_date = models.DateField('出入库日期')
|
||||||
remark = models.CharField('备注', max_length=1000, default='')
|
remark = models.CharField('备注', max_length=1000, default='')
|
||||||
|
|
||||||
|
@ -83,23 +82,25 @@ class FIFOItem(BaseModel):
|
||||||
count = models.IntegerField('数量', default=0, validators=[MinValueValidator(0)])
|
count = models.IntegerField('数量', default=0, validators=[MinValueValidator(0)])
|
||||||
batch = models.CharField('批次号', max_length=100, default='')
|
batch = models.CharField('批次号', max_length=100, default='')
|
||||||
fifo = models.ForeignKey(FIFO, verbose_name='关联出入库', on_delete=models.CASCADE)
|
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):
|
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)
|
number = models.CharField('物品编号', unique=True, null=True, blank=True, max_length=50)
|
||||||
material = models.ForeignKey(Material, verbose_name='物料类型', on_delete=models.CASCADE)
|
material = models.ForeignKey(Material, verbose_name='物料类型', on_delete=models.CASCADE)
|
||||||
warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库')
|
warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库')
|
||||||
batch = models.CharField('所属批次号', max_length=100, default='')
|
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)
|
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)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -130,6 +130,7 @@ class InmTestRecordItemCreateSerializer(serializers.ModelSerializer):
|
||||||
class InmTestRecordCreateSerializer(serializers.ModelSerializer):
|
class InmTestRecordCreateSerializer(serializers.ModelSerializer):
|
||||||
record_data = InmTestRecordItemCreateSerializer(many=True)
|
record_data = InmTestRecordItemCreateSerializer(many=True)
|
||||||
fifo_item = serializers.PrimaryKeyRelatedField(queryset=FIFOItem.objects.all(), required=True)
|
fifo_item = serializers.PrimaryKeyRelatedField(queryset=FIFOItem.objects.all(), required=True)
|
||||||
|
is_testok = serializers.BooleanField()
|
||||||
class Meta:
|
class Meta:
|
||||||
model = TestRecord
|
model = TestRecord
|
||||||
fields = ['form', 'record_data', 'is_testok', 'fifo_item']
|
fields = ['form', 'record_data', 'is_testok', 'fifo_item']
|
|
@ -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='是否需要过程检验'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -81,6 +81,7 @@ class Step(CommonAModel):
|
||||||
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)
|
||||||
instruction_content = models.TextField('相应操作指导', null=True, blank=True)
|
instruction_content = models.TextField('相应操作指导', null=True, blank=True)
|
||||||
|
need_test = models.BooleanField('是否需要过程检验', default=False)
|
||||||
sort = models.IntegerField('排序号', default=1)
|
sort = models.IntegerField('排序号', default=1)
|
||||||
equipments = models.ManyToManyField(Equipment, verbose_name='使用设备', related_name='step_equips')
|
equipments = models.ManyToManyField(Equipment, verbose_name='使用设备', related_name='step_equips')
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,8 @@ def update_subplan_main(sender, instance, created, **kwargs):
|
||||||
subplan.main_product = instance.material
|
subplan.main_product = instance.material
|
||||||
subplan.main_count = instance.count
|
subplan.main_count = instance.count
|
||||||
subplan.main_count_real = instance.count_real
|
subplan.main_count_real = instance.count_real
|
||||||
|
if subplan.main_count == instance.count_real:
|
||||||
|
subplan.state = 4
|
||||||
subplan.save()
|
subplan.save()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ class PickSerializer(serializers.Serializer):
|
||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
picks = validated_data.pop('picks')
|
picks = validated_data.pop('picks')
|
||||||
sp = validated_data['subproduction_plan']
|
sp = validated_data.pop('subproduction_plan')
|
||||||
if sp.state not in [1,2]:
|
if sp.state not in [1,2]:
|
||||||
raise exceptions.ValidationError('该子计划状态错误')
|
raise exceptions.ValidationError('该子计划状态错误')
|
||||||
if sp.is_picked:
|
if sp.is_picked:
|
||||||
|
@ -48,6 +48,7 @@ class PickSerializer(serializers.Serializer):
|
||||||
i['fifo'] = fifo
|
i['fifo'] = fifo
|
||||||
i['count'] = i.pop('pick_count')
|
i['count'] = i.pop('pick_count')
|
||||||
i['is_testok'] = True # 默认检测合格
|
i['is_testok'] = True # 默认检测合格
|
||||||
|
i['subproduction_plan'] = sp
|
||||||
FIFOItem.objects.create(**i)
|
FIFOItem.objects.create(**i)
|
||||||
# 更新车间物料
|
# 更新车间物料
|
||||||
wm, _ = WMaterial.objects.get_or_create(material=i['material'], batch=i['batch'], \
|
wm, _ = WMaterial.objects.get_or_create(material=i['material'], batch=i['batch'], \
|
||||||
|
@ -183,6 +184,7 @@ class WpmTestRecordItemCreateSerializer(serializers.ModelSerializer):
|
||||||
class WpmTestRecordCreateSerializer(serializers.ModelSerializer):
|
class WpmTestRecordCreateSerializer(serializers.ModelSerializer):
|
||||||
record_data = WpmTestRecordItemCreateSerializer(many=True)
|
record_data = WpmTestRecordItemCreateSerializer(many=True)
|
||||||
wproduct = serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all(), required=True)
|
wproduct = serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all(), required=True)
|
||||||
|
is_testok = serializers.BooleanField()
|
||||||
class Meta:
|
class Meta:
|
||||||
model = TestRecord
|
model = TestRecord
|
||||||
fields = ['form', 'record_data', 'is_testok', 'wproduct']
|
fields = ['form', 'record_data', 'is_testok', 'wproduct']
|
||||||
|
|
|
@ -53,6 +53,7 @@ class WMaterialViewSet(CreateUpdateModelAMixin, ListModelMixin, GenericViewSet):
|
||||||
serializer.save()
|
serializer.save()
|
||||||
return Response()
|
return Response()
|
||||||
|
|
||||||
|
|
||||||
class WProductViewSet(ListModelMixin, GenericViewSet):
|
class WProductViewSet(ListModelMixin, GenericViewSet):
|
||||||
"""
|
"""
|
||||||
半成品
|
半成品
|
||||||
|
@ -65,6 +66,13 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
|
||||||
ordering_fields = ['id']
|
ordering_fields = ['id']
|
||||||
ordering = ['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)
|
@action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=WpmTestRecordCreateSerializer)
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
def test(self, request, pk=None):
|
def test(self, request, pk=None):
|
||||||
|
@ -77,7 +85,7 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
|
||||||
record_data = vdata.pop('record_data')
|
record_data = vdata.pop('record_data')
|
||||||
wproduct = vdata['wproduct']
|
wproduct = vdata['wproduct']
|
||||||
if wproduct.act_state != WProduct.WPR_ACT_STATE_TOTEST:
|
if wproduct.act_state != WProduct.WPR_ACT_STATE_TOTEST:
|
||||||
raise exceptions.APIException('该半成品无需检测')
|
raise exceptions.APIException('该半成品不可检测')
|
||||||
if 'is_testok' not in vdata:
|
if 'is_testok' not in vdata:
|
||||||
raise exceptions.APIException('未填写检测结论')
|
raise exceptions.APIException('未填写检测结论')
|
||||||
|
|
||||||
|
@ -96,8 +104,21 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
|
||||||
tris.append(TestRecordItem(**m))
|
tris.append(TestRecordItem(**m))
|
||||||
TestRecordItem.objects.bulk_create(tris)
|
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()
|
return Response()
|
||||||
|
|
||||||
class OperationViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
|
class OperationViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
|
||||||
|
|
Loading…
Reference in New Issue