From 2f5edc041cef43ecea35c24402a531b862ce6c39 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Wed, 10 Jul 2024 15:32:33 +0800 Subject: [PATCH] feat: mlog init --- apps/mtm/services.py | 6 +-- .../wpm/migrations/0051_auto_20240710_1508.py | 25 +++++++++ apps/wpm/models.py | 5 +- apps/wpm/serializers.py | 21 +++++++- apps/wpm/services.py | 29 ++++++++++- apps/wpm/views.py | 52 ++++++++++++------- 6 files changed, 110 insertions(+), 28 deletions(-) create mode 100644 apps/wpm/migrations/0051_auto_20240710_1508.py diff --git a/apps/mtm/services.py b/apps/mtm/services.py index 1e8876d4..c1a80c88 100644 --- a/apps/mtm/services.py +++ b/apps/mtm/services.py @@ -5,9 +5,6 @@ from apps.mtm.models import Material, Process from rest_framework.exceptions import ParseError from apps.utils.tools import ranstr from datetime import datetime -from apps.wpm.models import StLog -from apps.wpm.services import get_sflog -from apps.wpm.tasks import cal_exp_duration_sec from apps.wf.models import Ticket from django.db.models import Sum from typing import List @@ -109,6 +106,9 @@ def mgroup_run_change(mgroup: Mgroup, new_run: bool, last_timex: datetime): """ 调用工段运行变动 """ + from apps.wpm.services import get_sflog + from apps.wpm.tasks import cal_exp_duration_sec + from apps.wpm.models import StLog mgroup.is_running = new_run mgroup.save(update_fields=["is_running"]) diff --git a/apps/wpm/migrations/0051_auto_20240710_1508.py b/apps/wpm/migrations/0051_auto_20240710_1508.py new file mode 100644 index 00000000..56e04afd --- /dev/null +++ b/apps/wpm/migrations/0051_auto_20240710_1508.py @@ -0,0 +1,25 @@ +# Generated by Django 3.2.12 on 2024-07-10 07:08 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('mtm', '0033_auto_20240704_1003'), + ('wpm', '0050_auto_20240701_0936'), + ] + + operations = [ + migrations.AddField( + model_name='mlog', + name='reminder_interval_list', + field=models.JSONField(blank=True, default=list, verbose_name='提醒间隔'), + ), + migrations.AddField( + model_name='mlog', + name='route', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='mtm.route', verbose_name='生产路线'), + ), + ] diff --git a/apps/wpm/models.py b/apps/wpm/models.py index d6ddb5a5..b7e3ff1d 100644 --- a/apps/wpm/models.py +++ b/apps/wpm/models.py @@ -1,6 +1,6 @@ from django.db import models from apps.utils.models import CommonADModel, CommonBDModel, BaseModel -from apps.mtm.models import Mgroup, Team, Shift, Material +from apps.mtm.models import Mgroup, Team, Shift, Material, Route from apps.pm.models import Mtask from apps.system.models import User from django.utils.timezone import localtime @@ -106,7 +106,8 @@ class Mlog(CommonADModel): work_start_time = models.DateTimeField('生产开始时间', null=True, blank=True) work_end_time = models.DateTimeField('生产结束时间', null=True, blank=True) hour_work = models.FloatField('预计工时', null=True, blank=True) - + reminder_interval_list = models.JSONField('提醒间隔', default=list, blank=True) + route = models.ForeignKey(Route, verbose_name='生产路线', on_delete=models.SET_NULL, null=True, blank=True) mtask = models.ForeignKey( Mtask, verbose_name='关联任务', on_delete=models.CASCADE, null=True, blank=True, related_name='mlog_mtask') mgroup = models.ForeignKey( diff --git a/apps/wpm/serializers.py b/apps/wpm/serializers.py index 49314cd0..7779c3ca 100644 --- a/apps/wpm/serializers.py +++ b/apps/wpm/serializers.py @@ -10,7 +10,7 @@ from apps.system.serializers import UserSimpleSerializer from apps.pm.models import Mtask from apps.wpm.tasks import cal_enstat_when_pcoal_heat_change, cal_enstat_when_team_change, cal_exp_duration_sec from apps.wpm.services import get_sflog -from apps.mtm.models import Mgroup, TeamMember, Shift, Material +from apps.mtm.models import Mgroup, TeamMember, Shift, Material, Route from apps.mtm.serializers import MaterialSimpleSerializer from django.db import transaction from django.utils import timezone @@ -310,7 +310,24 @@ class MlogSerializer(CustomModelSerializer): class MlogInitSerializer(CustomModelSerializer): - pass + class Meta: + model = Mlog + fields = ['id', 'work_start_time', 'reminder_interval_list', 'route', 'equipment', 'handle_user', 'note'] + extra_kwargs = { + 'work_start_time': {'required': True}, + 'route':{'required': True}, + 'mgroup': {'required': True} + } + + def validate(self, attrs): + route: Route = attrs['route'] + mgroup: Mgroup = attrs['mgroup'] + if route.process != mgroup.process: + raise ValidationError('工序不匹配') + attrs['hour_work'] = route.hour_work + attrs['material_in'] = route.material_in + attrs['material_out'] = route.material_out + return attrs class MlogRevertSerializer(serializers.Serializer): change_reason = serializers.CharField(label='撤回原因') diff --git a/apps/wpm/services.py b/apps/wpm/services.py index f1d552e5..97046d6d 100644 --- a/apps/wpm/services.py +++ b/apps/wpm/services.py @@ -15,6 +15,7 @@ from apps.mtm.models import Mgroup, Shift, Material, Route from .models import SfLog, SfLogExp, WMaterial, Mlog, Mlogb, Handover from apps.mtm.models import Process +from apps.mtm.services import cal_material_count def get_sflog(mgroup: Mgroup, happen_time: datetime): @@ -317,11 +318,35 @@ def mlog_revert(mlog: Mlog, user: User, now: Union[datetime.datetime, None]): mlog.save() -def cal_mtask_progress(mtaskId_list = []): +def cal_mtask_progress(mtask: Mtask): """ 计算任务进度 """ - pass + + + +def cal_mtask_progress_from_mlog(mlog: Mlog): + """ + 更新mlog关联的任务进度(可线程中执行) + """ + +def cal_material_count_from_mlog(mlog: Mlog): + """ + 更新mlog关联的物料数量(可单独执行) + """ + matid_list = [] + if mlog.material_in: + matid_list.append(mlog.material_in.id) + if mlog.material_out: + matid_list.append(mlog.material_out.id) + matid_list2 = Mlogb.objects.filter(mlog=mlog).values_list('material_in__id', 'material_out__id').distinct() + for matid in matid_list2: + if matid[0]: + matid_list.append(matid[0]) + if matid[1]: + matid_list.append(matid[1]) + cal_material_count(matid_list) + def update_mtask(mtask: Mtask): from apps.pm.models import Utask diff --git a/apps/wpm/views.py b/apps/wpm/views.py index 8ff42142..bf1236b7 100644 --- a/apps/wpm/views.py +++ b/apps/wpm/views.py @@ -19,8 +19,10 @@ from .filters import StLogFilter, SfLogFilter, WMaterialFilter, MlogFilter, Hand from .models import SfLog, SfLogExp, StLog, WMaterial, Mlog, Handover, Mlogb, AttLog, OtherLog from .serializers import (SflogExpSerializer, SfLogSerializer, StLogSerializer, WMaterialSerializer, MlogRevertSerializer, MlogSerializer, MlogRelatedSerializer, DeptBatchSerializer, HandoverSerializer, - GenHandoverSerializer, GenHandoverWmSerializer, MlogAnaSerializer, AttLogSerializer, OtherLogSerializer) -from .services import mlog_submit, update_mtask, handover_submit, mlog_revert + GenHandoverSerializer, GenHandoverWmSerializer, MlogAnaSerializer, + AttLogSerializer, OtherLogSerializer, MlogInitSerializer) +from .services import mlog_submit, update_mtask, handover_submit, mlog_revert, cal_material_count_from_mlog, cal_mtask_progress_from_mlog +from apps.utils.thread import MyThread from apps.monitor.services import create_auditlog, delete_auditlog # Create your views here. @@ -166,8 +168,17 @@ class MlogViewSet(CustomModelViewSet): val_new = MlogSerializer(instance=ins).data create_auditlog('update', ins, val_new, val_old) + @action(methods=['post'], detail=False, perms_map={'post': 'mlog.init'}, serializer_class=MlogInitSerializer) + def init(self, request, *args, **kwargs): + """ + 先初始化创建生产日志 + """ + sr = MlogInitSerializer(data=request.data) + sr.is_valid(raise_exception=True) + ins = sr.save() + return Response(MlogSerializer(ins).data) + @action(methods=['post'], detail=True, perms_map={'post': 'mlog.submit'}, serializer_class=Serializer) - @transaction.atomic def submit(self, request, *args, **kwargs): """日志提交(变动车间库存) @@ -180,16 +191,17 @@ class MlogViewSet(CustomModelViewSet): raise ParseError('该日志已提交!') if ins.mtask and ins.mtask.state == Mtask.MTASK_STOP: raise ParseError('该任务已停止!') - mlog_submit(ins, self.request.user, now) - if ins.mtask: - update_mtask(ins.mtask) - vdata_new = MlogSerializer(ins).data - create_auditlog('submit', ins, vdata_new, - vdata_old, now, self.request.user) - return Response(MlogSerializer(instance=ins).data) + with transaction.atomic(): + mlog_submit(ins, self.request.user, now) + if ins.mtask: + update_mtask(ins.mtask) + vdata_new = MlogSerializer(ins).data + create_auditlog('submit', ins, vdata_new, + vdata_old, now, self.request.user) + MyThread(cal_material_count_from_mlog,args=(ins,)).start() + return Response(vdata_new) @action(methods=['post'], detail=True, perms_map={'post': 'mlog.submit'}, serializer_class=MlogRevertSerializer) - @transaction.atomic def revert(self, request, *args, **kwargs): """撤回日志提交 @@ -202,15 +214,17 @@ class MlogViewSet(CustomModelViewSet): if user != ins.submit_user: raise ParseError('非提交人不可撤销!') now = timezone.now() - mlog_revert(ins, user, now) - if ins.mtask: - mtask = ins.mtask - if mtask.state == Mtask.MTASK_SUBMIT: - mtask.state = Mtask.MTASK_ASSGINED - mtask.save() - update_mtask(ins.mtask) - create_auditlog('revert', ins, {}, {}, now, user, + with transaction.atomic(): + mlog_revert(ins, user, now) + if ins.mtask: + mtask = ins.mtask + if mtask.state == Mtask.MTASK_SUBMIT: + mtask.state = Mtask.MTASK_ASSGINED + mtask.save() + update_mtask(ins.mtask) + create_auditlog('revert', ins, {}, {}, now, user, request.data.get('change_reason', '')) + MyThread(cal_material_count_from_mlog,args=(ins,)).start() return Response(MlogSerializer(instance=ins).data) @action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=MlogRelatedSerializer)