feat: mlog init
This commit is contained in:
parent
4c93bb98de
commit
2f5edc041c
|
@ -5,9 +5,6 @@ from apps.mtm.models import Material, Process
|
||||||
from rest_framework.exceptions import ParseError
|
from rest_framework.exceptions import ParseError
|
||||||
from apps.utils.tools import ranstr
|
from apps.utils.tools import ranstr
|
||||||
from datetime import datetime
|
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 apps.wf.models import Ticket
|
||||||
from django.db.models import Sum
|
from django.db.models import Sum
|
||||||
from typing import List
|
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.is_running = new_run
|
||||||
mgroup.save(update_fields=["is_running"])
|
mgroup.save(update_fields=["is_running"])
|
||||||
|
|
||||||
|
|
|
@ -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='生产路线'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -1,6 +1,6 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from apps.utils.models import CommonADModel, CommonBDModel, BaseModel
|
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.pm.models import Mtask
|
||||||
from apps.system.models import User
|
from apps.system.models import User
|
||||||
from django.utils.timezone import localtime
|
from django.utils.timezone import localtime
|
||||||
|
@ -106,7 +106,8 @@ class Mlog(CommonADModel):
|
||||||
work_start_time = models.DateTimeField('生产开始时间', null=True, blank=True)
|
work_start_time = models.DateTimeField('生产开始时间', null=True, blank=True)
|
||||||
work_end_time = models.DateTimeField('生产结束时间', null=True, blank=True)
|
work_end_time = models.DateTimeField('生产结束时间', null=True, blank=True)
|
||||||
hour_work = models.FloatField('预计工时', 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 = models.ForeignKey(
|
||||||
Mtask, verbose_name='关联任务', on_delete=models.CASCADE, null=True, blank=True, related_name='mlog_mtask')
|
Mtask, verbose_name='关联任务', on_delete=models.CASCADE, null=True, blank=True, related_name='mlog_mtask')
|
||||||
mgroup = models.ForeignKey(
|
mgroup = models.ForeignKey(
|
||||||
|
|
|
@ -10,7 +10,7 @@ from apps.system.serializers import UserSimpleSerializer
|
||||||
from apps.pm.models import Mtask
|
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.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.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 apps.mtm.serializers import MaterialSimpleSerializer
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
@ -310,7 +310,24 @@ class MlogSerializer(CustomModelSerializer):
|
||||||
|
|
||||||
|
|
||||||
class MlogInitSerializer(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):
|
class MlogRevertSerializer(serializers.Serializer):
|
||||||
change_reason = serializers.CharField(label='撤回原因')
|
change_reason = serializers.CharField(label='撤回原因')
|
||||||
|
|
|
@ -15,6 +15,7 @@ from apps.mtm.models import Mgroup, Shift, Material, Route
|
||||||
|
|
||||||
from .models import SfLog, SfLogExp, WMaterial, Mlog, Mlogb, Handover
|
from .models import SfLog, SfLogExp, WMaterial, Mlog, Mlogb, Handover
|
||||||
from apps.mtm.models import Process
|
from apps.mtm.models import Process
|
||||||
|
from apps.mtm.services import cal_material_count
|
||||||
|
|
||||||
|
|
||||||
def get_sflog(mgroup: Mgroup, happen_time: datetime):
|
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()
|
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):
|
def update_mtask(mtask: Mtask):
|
||||||
from apps.pm.models import Utask
|
from apps.pm.models import Utask
|
||||||
|
|
|
@ -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 .models import SfLog, SfLogExp, StLog, WMaterial, Mlog, Handover, Mlogb, AttLog, OtherLog
|
||||||
from .serializers import (SflogExpSerializer, SfLogSerializer, StLogSerializer, WMaterialSerializer, MlogRevertSerializer,
|
from .serializers import (SflogExpSerializer, SfLogSerializer, StLogSerializer, WMaterialSerializer, MlogRevertSerializer,
|
||||||
MlogSerializer, MlogRelatedSerializer, DeptBatchSerializer, HandoverSerializer,
|
MlogSerializer, MlogRelatedSerializer, DeptBatchSerializer, HandoverSerializer,
|
||||||
GenHandoverSerializer, GenHandoverWmSerializer, MlogAnaSerializer, AttLogSerializer, OtherLogSerializer)
|
GenHandoverSerializer, GenHandoverWmSerializer, MlogAnaSerializer,
|
||||||
from .services import mlog_submit, update_mtask, handover_submit, mlog_revert
|
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
|
from apps.monitor.services import create_auditlog, delete_auditlog
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
|
|
||||||
|
@ -166,8 +168,17 @@ class MlogViewSet(CustomModelViewSet):
|
||||||
val_new = MlogSerializer(instance=ins).data
|
val_new = MlogSerializer(instance=ins).data
|
||||||
create_auditlog('update', ins, val_new, val_old)
|
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)
|
@action(methods=['post'], detail=True, perms_map={'post': 'mlog.submit'}, serializer_class=Serializer)
|
||||||
@transaction.atomic
|
|
||||||
def submit(self, request, *args, **kwargs):
|
def submit(self, request, *args, **kwargs):
|
||||||
"""日志提交(变动车间库存)
|
"""日志提交(变动车间库存)
|
||||||
|
|
||||||
|
@ -180,16 +191,17 @@ class MlogViewSet(CustomModelViewSet):
|
||||||
raise ParseError('该日志已提交!')
|
raise ParseError('该日志已提交!')
|
||||||
if ins.mtask and ins.mtask.state == Mtask.MTASK_STOP:
|
if ins.mtask and ins.mtask.state == Mtask.MTASK_STOP:
|
||||||
raise ParseError('该任务已停止!')
|
raise ParseError('该任务已停止!')
|
||||||
mlog_submit(ins, self.request.user, now)
|
with transaction.atomic():
|
||||||
if ins.mtask:
|
mlog_submit(ins, self.request.user, now)
|
||||||
update_mtask(ins.mtask)
|
if ins.mtask:
|
||||||
vdata_new = MlogSerializer(ins).data
|
update_mtask(ins.mtask)
|
||||||
create_auditlog('submit', ins, vdata_new,
|
vdata_new = MlogSerializer(ins).data
|
||||||
vdata_old, now, self.request.user)
|
create_auditlog('submit', ins, vdata_new,
|
||||||
return Response(MlogSerializer(instance=ins).data)
|
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)
|
@action(methods=['post'], detail=True, perms_map={'post': 'mlog.submit'}, serializer_class=MlogRevertSerializer)
|
||||||
@transaction.atomic
|
|
||||||
def revert(self, request, *args, **kwargs):
|
def revert(self, request, *args, **kwargs):
|
||||||
"""撤回日志提交
|
"""撤回日志提交
|
||||||
|
|
||||||
|
@ -202,15 +214,17 @@ class MlogViewSet(CustomModelViewSet):
|
||||||
if user != ins.submit_user:
|
if user != ins.submit_user:
|
||||||
raise ParseError('非提交人不可撤销!')
|
raise ParseError('非提交人不可撤销!')
|
||||||
now = timezone.now()
|
now = timezone.now()
|
||||||
mlog_revert(ins, user, now)
|
with transaction.atomic():
|
||||||
if ins.mtask:
|
mlog_revert(ins, user, now)
|
||||||
mtask = ins.mtask
|
if ins.mtask:
|
||||||
if mtask.state == Mtask.MTASK_SUBMIT:
|
mtask = ins.mtask
|
||||||
mtask.state = Mtask.MTASK_ASSGINED
|
if mtask.state == Mtask.MTASK_SUBMIT:
|
||||||
mtask.save()
|
mtask.state = Mtask.MTASK_ASSGINED
|
||||||
update_mtask(ins.mtask)
|
mtask.save()
|
||||||
create_auditlog('revert', ins, {}, {}, now, user,
|
update_mtask(ins.mtask)
|
||||||
|
create_auditlog('revert', ins, {}, {}, now, user,
|
||||||
request.data.get('change_reason', ''))
|
request.data.get('change_reason', ''))
|
||||||
|
MyThread(cal_material_count_from_mlog,args=(ins,)).start()
|
||||||
return Response(MlogSerializer(instance=ins).data)
|
return Response(MlogSerializer(instance=ins).data)
|
||||||
|
|
||||||
@action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=MlogRelatedSerializer)
|
@action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=MlogRelatedSerializer)
|
||||||
|
|
Loading…
Reference in New Issue