diff --git a/hb_server/apps/pm/migrations/0019_alter_productionplan_process_json.py b/hb_server/apps/pm/migrations/0019_alter_productionplan_process_json.py new file mode 100644 index 0000000..4bc670e --- /dev/null +++ b/hb_server/apps/pm/migrations/0019_alter_productionplan_process_json.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.9 on 2021-12-28 06:17 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('pm', '0018_productionplan_process_json'), + ] + + operations = [ + migrations.AlterField( + model_name='productionplan', + name='process_json', + field=models.JSONField(blank=True, default=dict, null=True, verbose_name='按工序的统计数'), + ), + ] diff --git a/hb_server/apps/wpm/filters.py b/hb_server/apps/wpm/filters.py index 231a858..bf3783e 100644 --- a/hb_server/apps/wpm/filters.py +++ b/hb_server/apps/wpm/filters.py @@ -25,6 +25,7 @@ class WMaterialFilterSet(filters.FilterSet): class WProductFilterSet(filters.FilterSet): tag = filters.CharFilter(method='filter_tag') + production_plan = filters.NumberFilter(field_name='subproduction_plan__production_plan') class Meta: model = WProduct fields = ['step', 'subproduction_plan', 'material', 'step__process', 'act_state', 'material__type'] diff --git a/hb_server/apps/wpm/migrations/0039_auto_20211228_1417.py b/hb_server/apps/wpm/migrations/0039_auto_20211228_1417.py new file mode 100644 index 0000000..4d4be43 --- /dev/null +++ b/hb_server/apps/wpm/migrations/0039_auto_20211228_1417.py @@ -0,0 +1,58 @@ +# Generated by Django 3.2.9 on 2021-12-28 06:17 + +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 = [ + ('inm', '0024_auto_20211227_0948'), + ('qm', '0022_auto_20211216_1401'), + ('mtm', '0042_alter_recordformfield_field_type'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('pm', '0019_alter_productionplan_process_json'), + ('wf', '0023_auto_20211227_1318'), + ('wpm', '0038_auto_20211227_0948'), + ] + + operations = [ + migrations.AlterField( + model_name='wprouctticket', + name='step', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.step', verbose_name='所在步骤/发现步骤'), + ), + migrations.CreateModel( + name='WproductFlow', + 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(blank=True, max_length=50, null=True, unique=True, verbose_name='物品编号')), + ('act_state', models.IntegerField(choices=[(6, '待复检'), (8, '操作准备中'), (10, '操作进行中'), (20, '待检验'), (26, '待夹层检验'), (30, '已合格'), (40, '已入库'), (50, '不合格'), (60, '待成品检验'), (70, '已报废'), (80, '已售出')], default=0, verbose_name='进行状态')), + ('is_hidden', models.BooleanField(default=False, verbose_name='是否隐藏')), + ('remark', models.CharField(blank=True, max_length=200, null=True, verbose_name='备注')), + ('scrap_reason', models.IntegerField(blank=True, choices=[(10, '气泡'), (20, '破点'), (30, '划伤'), (40, '其他')], null=True, verbose_name='报废原因')), + ('ng_sign', models.PositiveSmallIntegerField(blank=True, choices=[(10, '返工'), (20, '返修'), (30, '报废'), (40, '让步接收'), (50, '偏离许可'), (60, '降级使用'), (70, '退回供方'), (80, '召回')], null=True, verbose_name='不合格标记')), + ('is_lastlog', models.BooleanField(default=True, verbose_name='是否该子计划下的最后一条日志')), + ('child', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='wpm.wproductflow')), + ('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='wproductflow_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')), + ('material', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='所属物料状态')), + ('operation', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='wpm.operation', verbose_name='当前操作')), + ('pre_step', models.ForeignKey(blank=True, help_text='已执行完的步骤', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='wl_pre_step', to='mtm.step', verbose_name='已执行到')), + ('step', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='wl_step', to='mtm.step', verbose_name='所在步骤')), + ('subproduction_plan', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pm.subproductionplan', verbose_name='当前子生产计划')), + ('test', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='qm.testrecord', verbose_name='当前检验')), + ('ticket', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='wf.ticket', verbose_name='当前工单')), + ('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='wproductflow_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')), + ('warehouse', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='inm.warehouse', verbose_name='所在仓库')), + ('wproduct', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='wpm.wproduct', verbose_name='关联产品')), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/hb_server/apps/wpm/models.py b/hb_server/apps/wpm/models.py index 52f6f32..69a1f3b 100644 --- a/hb_server/apps/wpm/models.py +++ b/hb_server/apps/wpm/models.py @@ -124,6 +124,34 @@ class WprouctTicket(CommonAModel): ticket = models.ForeignKey('wf.ticket', verbose_name='关联工单', on_delete=models.CASCADE, related_name='wt_ticket') decision = models.PositiveSmallIntegerField('最终决定', choices=WProduct.ng_choices, null=True, blank=True) +class WproductFlow(CommonAModel): + """ + 动态产品表日志 + """ + wproduct = models.ForeignKey(WProduct, on_delete=models.CASCADE, verbose_name='关联产品', null=True, blank=True) + number = models.CharField('物品编号', unique=True, null=True, blank=True, max_length=50) + material = models.ForeignKey(Material, verbose_name='所属物料状态', on_delete=models.CASCADE) + pre_step = models.ForeignKey(Step, verbose_name='已执行到', help_text='已执行完的步骤', null=True, blank=True, on_delete=models.CASCADE, related_name='wl_pre_step') + step = models.ForeignKey(Step, verbose_name='所在步骤', on_delete=models.CASCADE, null=True, blank=True, related_name='wl_step') + act_state = models.IntegerField('进行状态', default=0, choices=WProduct.act_state_choices) + is_hidden = models.BooleanField('是否隐藏', default=False) + child = models.ForeignKey('self', blank=True, null=True, on_delete=models.CASCADE) + remark = models.CharField('备注', max_length=200, null=True, blank=True) + subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE) + + scrap_reason = models.IntegerField('报废原因', choices= WProduct.scrap_reason_choices, null=True, blank=True) + ng_sign = models.PositiveSmallIntegerField('不合格标记', choices= WProduct.ng_choices, null=True, blank=True) + + warehouse = models.ForeignKey(WareHouse, verbose_name='所在仓库', on_delete=models.SET_NULL, null=True, blank=True) + operation = models.ForeignKey('wpm.operation', verbose_name='当前操作', + on_delete=models.SET_NULL, null=True, blank=True) + test = models.ForeignKey('qm.testrecord', verbose_name='当前检验', + on_delete=models.SET_NULL, null=True, blank=True) + ticket = models.ForeignKey('wf.ticket', verbose_name='当前工单', + on_delete=models.SET_NULL, null=True, blank=True) + is_lastlog = models.BooleanField('是否该子计划下的最后一条日志', default=True) + + class Pick(CommonADModel): """ 领料记录 diff --git a/hb_server/apps/wpm/signals.py b/hb_server/apps/wpm/signals.py index 14c8a20..48b7b3c 100644 --- a/hb_server/apps/wpm/signals.py +++ b/hb_server/apps/wpm/signals.py @@ -6,7 +6,7 @@ from apps.qm.models import TestRecord from apps.wf.models import Ticket from django.dispatch import receiver from rest_framework import exceptions -from apps.wpm.models import WProduct, WprouctTicket +from apps.wpm.models import WProduct, WproductFlow, WprouctTicket from apps.wpm.models import OperationWproduct @@ -85,5 +85,16 @@ def handleTicket(sender, instance, created, **kwargs): wp.ticket = None # 解除当前工单 wp.save() - - \ No newline at end of file + +@receiver(post_save, sender=WProduct) +def update_wproduct_log(sender, instance, created, **kwargs): + """ + 更新产品变动日志 + """ + WproductFlow.objects.filter(wproduct=instance, subproduction_plan=instance.subproduction_plan).update(is_lastlog=False) + ins = WproductFlow() + ins.wproduct = instance + for f in WproductFlow._meta.fields: + if f.name not in ['id', 'create_time', 'update_time', 'wproduct', 'is_lastlog']: + setattr(ins, f.name, getattr(instance, f.name, None)) + ins.save() \ No newline at end of file