feat: cal_mtask_progress_from_mlog
This commit is contained in:
parent
6e904f083a
commit
07680704ec
|
@ -305,21 +305,17 @@ class PmService:
|
||||||
@classmethod
|
@classmethod
|
||||||
def mtask_submit(cls, mtask: Mtask, user: User):
|
def mtask_submit(cls, mtask: Mtask, user: User):
|
||||||
"""
|
"""
|
||||||
锁定生产任务
|
生产任务提交
|
||||||
"""
|
"""
|
||||||
from apps.wpm.models import Mlog
|
from apps.wpm.models import Mlog
|
||||||
from apps.wpm.services import mlog_submit, update_mtask
|
|
||||||
now = timezone.now()
|
now = timezone.now()
|
||||||
if mtask.state == Mtask.MTASK_ASSGINED:
|
if mtask.state == Mtask.MTASK_ASSGINED:
|
||||||
mlogs = Mlog.objects.filter(mtask=mtask)
|
mlogs = Mlog.objects.filter(mtask=mtask)|Mlog.objects.filter(b_mlog__mtask=mtask)
|
||||||
# if ignore_nologs is False and mlogs.count() == 0:
|
if mlogs.filter(submit_time__isnull=True).exists():
|
||||||
# raise ParseError(f'{mtask.mgroup.name}_未填写日志')
|
raise ParseError('存在未提交的日志')
|
||||||
for mlog in mlogs:
|
|
||||||
mlog_submit(mlog, user, now)
|
|
||||||
mtask.state = Mtask.MTASK_SUBMIT
|
mtask.state = Mtask.MTASK_SUBMIT
|
||||||
mtask.submit_time = now
|
mtask.submit_time = now
|
||||||
mtask.submit_user = user
|
mtask.submit_user = user
|
||||||
mtask.save()
|
mtask.save()
|
||||||
update_mtask(mtask)
|
|
||||||
else:
|
else:
|
||||||
raise ParseError('该任务状态不可提交')
|
raise ParseError('该任务状态不可提交')
|
||||||
|
|
|
@ -103,6 +103,9 @@ class Mlog(CommonADModel):
|
||||||
生产日志
|
生产日志
|
||||||
"""
|
"""
|
||||||
# 变成父级的字段
|
# 变成父级的字段
|
||||||
|
MLOG_ONETIME = 10
|
||||||
|
MLOG_STEP = 20
|
||||||
|
fill_way = models.PositiveSmallIntegerField("填写方式", default=10, help_text='10:一次填写;20:分步填写')
|
||||||
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)
|
||||||
|
@ -218,6 +221,7 @@ class Mlogb(BaseModel):
|
||||||
count_ok = models.PositiveIntegerField('合格数量', default=0)
|
count_ok = models.PositiveIntegerField('合格数量', default=0)
|
||||||
count_notok = models.PositiveIntegerField('不合格数', default=0)
|
count_notok = models.PositiveIntegerField('不合格数', default=0)
|
||||||
|
|
||||||
|
# 添加不合格字段后需要更改cal_mlog_count_from_mlogb
|
||||||
count_n_hs = models.PositiveIntegerField('划伤', default=0)
|
count_n_hs = models.PositiveIntegerField('划伤', default=0)
|
||||||
count_n_qp = models.PositiveIntegerField('气泡', default=0)
|
count_n_qp = models.PositiveIntegerField('气泡', default=0)
|
||||||
count_n_swen = models.PositiveIntegerField('水纹', default=0)
|
count_n_swen = models.PositiveIntegerField('水纹', default=0)
|
||||||
|
|
|
@ -304,6 +304,7 @@ class MlogSerializer(CustomModelSerializer):
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
def validate(self, attrs):
|
def validate(self, attrs):
|
||||||
|
attrs['fill_way'] = Mlog.MLOG_ONETIME
|
||||||
mtask = attrs.get('mtask', None)
|
mtask = attrs.get('mtask', None)
|
||||||
count_notok = 0
|
count_notok = 0
|
||||||
for i in attrs:
|
for i in attrs:
|
||||||
|
@ -343,6 +344,7 @@ class MlogInitSerializer(CustomModelSerializer):
|
||||||
attrs['hour_work'] = route.hour_work
|
attrs['hour_work'] = route.hour_work
|
||||||
attrs['material_in'] = route.material_in
|
attrs['material_in'] = route.material_in
|
||||||
attrs['material_out'] = route.material_out
|
attrs['material_out'] = route.material_out
|
||||||
|
attrs['fill_way'] = Mlog.MLOG_STEP
|
||||||
return attrs
|
return attrs
|
||||||
|
|
||||||
class MlogChangeSerializer(CustomModelSerializer):
|
class MlogChangeSerializer(CustomModelSerializer):
|
||||||
|
|
|
@ -186,7 +186,6 @@ def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]):
|
||||||
belong_dept = mgroup.belong_dept
|
belong_dept = mgroup.belong_dept
|
||||||
material_out = mlog.material_out
|
material_out = mlog.material_out
|
||||||
material_in = mlog.material_in
|
material_in = mlog.material_in
|
||||||
|
|
||||||
if material_in: # 需要进行车间库存管理
|
if material_in: # 需要进行车间库存管理
|
||||||
m_ins = Mlogb.objects.filter(mlog=mlog, material_in__isnull=False)
|
m_ins = Mlogb.objects.filter(mlog=mlog, material_in__isnull=False)
|
||||||
if m_ins.exists():
|
if m_ins.exists():
|
||||||
|
@ -317,18 +316,63 @@ def mlog_revert(mlog: Mlog, user: User, now: Union[datetime.datetime, None]):
|
||||||
mlog.submit_user = None
|
mlog.submit_user = None
|
||||||
mlog.save()
|
mlog.save()
|
||||||
|
|
||||||
|
# mtask变更状态
|
||||||
|
update_mtaskIds = []
|
||||||
|
if mlog.mtask:
|
||||||
|
update_mtaskIds.append(mlog.mtask.id)
|
||||||
|
list_m = Mlogb.objects.filter(mlog=mlog).values_list('mtask__id', flat=True).distinct()
|
||||||
|
update_mtaskIds += list(list_m)
|
||||||
|
if update_mtaskIds:
|
||||||
|
Mtask.objects.filter(id__in=update_mtaskIds, state=Mtask.MTASK_SUBMIT).update(status=Mtask.MTASK_ASSGINED)
|
||||||
|
|
||||||
def cal_mtask_progress(mtask: Mtask):
|
|
||||||
"""
|
|
||||||
计算任务进度
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
|
def cal_mlog_count_from_mlogb(mlog: Mlog):
|
||||||
|
"""
|
||||||
|
通过mlogb计算mlog count 合计
|
||||||
|
"""
|
||||||
|
if mlog.fill_way == Mlog.MLOG_STEP:
|
||||||
|
a_dict = {
|
||||||
|
"total_count_use": Sum('count_use'),
|
||||||
|
"total_count_break": Sum('count_break'),
|
||||||
|
"total_count_break_t": Sum('count_break_t'),
|
||||||
|
"total_count_real": Sum('count_real'),
|
||||||
|
"total_count_ok": Sum('count_ok'),
|
||||||
|
"total_count_notok": Sum('count_notok'),
|
||||||
|
}
|
||||||
|
f_names = [f.name for f in Mlogb._meta.fields if 'count_n' in f.name]
|
||||||
|
for f in f_names:
|
||||||
|
a_dict[f'total_{f}'] = Sum(f)
|
||||||
|
mlogb_summary = Mlogb.objects.filter(mlog=mlog).aggregate(
|
||||||
|
**a_dict
|
||||||
|
)
|
||||||
|
# 更新Mlog对象的相应字段
|
||||||
|
mlog.count_use = mlogb_summary['total_count_use'] or 0
|
||||||
|
mlog.count_break = mlogb_summary['total_count_break'] or 0
|
||||||
|
mlog.count_break_t = mlogb_summary['total_count_break_t'] or 0
|
||||||
|
mlog.count_real = mlogb_summary['total_count_real'] or 0
|
||||||
|
mlog.count_ok = mlogb_summary['total_count_ok'] or 0
|
||||||
|
mlog.count_notok = mlogb_summary['total_count_notok'] or 0
|
||||||
|
for f in f_names:
|
||||||
|
setattr(mlog, f, mlogb_summary[f'total_{f}'] or 0)
|
||||||
|
# 保存更新后的Mlog对象
|
||||||
|
mlog.save()
|
||||||
|
|
||||||
def cal_mtask_progress_from_mlog(mlog: Mlog):
|
def cal_mtask_progress_from_mlog(mlog: Mlog):
|
||||||
"""
|
"""
|
||||||
更新mlog关联的任务进度(可线程中执行)
|
更新mlog关联的任务进度(可线程中执行)
|
||||||
"""
|
"""
|
||||||
|
if mlog.fill_way == Mlog.MLOG_ONETIME and mlog.mtask:
|
||||||
|
update_mtask(mlog.mtask, fill_way=Mlog.MLOG_ONETIME)
|
||||||
|
elif mlog.fill_way == Mlog.MLOG_STEP:
|
||||||
|
cal_mlog_count_from_mlogb(mlog)
|
||||||
|
m_outs_qs = Mlogb.objects.filter(mlog=mlog, material_out__isnull=False)
|
||||||
|
caled_mtask = []
|
||||||
|
for item in m_outs_qs.all():
|
||||||
|
mtask = item.mtask
|
||||||
|
if mtask in caled_mtask:
|
||||||
|
continue
|
||||||
|
update_mtask(mtask, fill_way=Mlog.MLOG_STEP)
|
||||||
|
caled_mtask.append(mtask)
|
||||||
|
|
||||||
def cal_material_count_from_mlog(mlog: Mlog):
|
def cal_material_count_from_mlog(mlog: Mlog):
|
||||||
"""
|
"""
|
||||||
|
@ -348,26 +392,58 @@ def cal_material_count_from_mlog(mlog: Mlog):
|
||||||
cal_material_count(matid_list)
|
cal_material_count(matid_list)
|
||||||
|
|
||||||
|
|
||||||
def update_mtask(mtask: Mtask):
|
def update_mtask(mtask: Mtask, fill_way: int = 10):
|
||||||
from apps.pm.models import Utask
|
from apps.pm.models import Utask
|
||||||
res = Mlog.objects.filter(mtask=mtask).exclude(submit_time=None).aggregate(sum_count_real=Sum(
|
if fill_way == Mlog.MLOG_ONETIME:
|
||||||
'count_real'), sum_count_ok=Sum('count_ok'), sum_count_notok=Sum('count_notok'))
|
res = Mlog.objects.filter(mtask=mtask).exclude(submit_time=None).aggregate(sum_count_real=Sum(
|
||||||
mtask.count_real = res['sum_count_real'] if res['sum_count_real'] else 0
|
|
||||||
mtask.count_ok = res['sum_count_ok'] if res['sum_count_ok'] else 0
|
|
||||||
mtask.count_notok = res['sum_count_notok'] if res['sum_count_notok'] else 0
|
|
||||||
mtask.save()
|
|
||||||
utask = mtask.utask
|
|
||||||
if utask and mtask.is_count_utask:
|
|
||||||
res2 = Mtask.objects.filter(utask=utask, mgroup=mtask.mgroup).aggregate(sum_count_real=Sum(
|
|
||||||
'count_real'), sum_count_ok=Sum('count_ok'), sum_count_notok=Sum('count_notok'))
|
'count_real'), sum_count_ok=Sum('count_ok'), sum_count_notok=Sum('count_notok'))
|
||||||
utask.count_real = res2['sum_count_real'] if res2['sum_count_real'] else 0
|
mtask.count_real = res['sum_count_real'] if res['sum_count_real'] else 0
|
||||||
utask.count_ok = res2['sum_count_ok'] if res2['sum_count_ok'] else 0
|
mtask.count_ok = res['sum_count_ok'] if res['sum_count_ok'] else 0
|
||||||
utask.count_notok = res2['sum_count_notok'] if res2['sum_count_notok'] else 0
|
mtask.count_notok = res['sum_count_notok'] if res['sum_count_notok'] else 0
|
||||||
if utask.count_ok > 0 and utask.state == Utask.UTASK_ASSGINED:
|
mtask.save()
|
||||||
utask.state = Utask.UTASK_WORKING
|
utask = mtask.utask
|
||||||
if Mtask.objects.filter(utask=utask).exclude(state=Mtask.MTASK_SUBMIT).count() == 0:
|
if utask and mtask.is_count_utask:
|
||||||
utask.state = Utask.UTASK_SUBMIT
|
res2 = Mtask.objects.filter(utask=utask, mgroup=mtask.mgroup).aggregate(sum_count_real=Sum(
|
||||||
utask.save()
|
'count_real'), sum_count_ok=Sum('count_ok'), sum_count_notok=Sum('count_notok'))
|
||||||
|
utask.count_real = res2['sum_count_real'] if res2['sum_count_real'] else 0
|
||||||
|
utask.count_ok = res2['sum_count_ok'] if res2['sum_count_ok'] else 0
|
||||||
|
utask.count_notok = res2['sum_count_notok'] if res2['sum_count_notok'] else 0
|
||||||
|
if utask.count_ok > 0 and utask.state == Utask.UTASK_ASSGINED:
|
||||||
|
utask.state = Utask.UTASK_WORKING
|
||||||
|
if Mtask.objects.filter(utask=utask).exclude(state=Mtask.MTASK_SUBMIT).count() == 0:
|
||||||
|
utask.state = Utask.UTASK_SUBMIT
|
||||||
|
utask.save()
|
||||||
|
elif fill_way == Mlog.MLOG_STEP:
|
||||||
|
# 已经提交的日志
|
||||||
|
m_outs_qs_mtask = Mlogb.objects.filter(mtask=mtask, material_out__isnull=False, mlog__submit_time__isnull=False)
|
||||||
|
res = m_outs_qs_mtask.aggregate(
|
||||||
|
sum_count_real=Sum('count_real', default=0),
|
||||||
|
sum_count_ok=Sum('count_ok', default=0),
|
||||||
|
sum_count_notok=Sum('count_notok', default=0)
|
||||||
|
)
|
||||||
|
mtask.count_real = res['sum_count_real'] or 0
|
||||||
|
mtask.count_ok = res['sum_count_ok'] or 0
|
||||||
|
mtask.count_notok = res['sum_count_notok'] or 0
|
||||||
|
mtask.save()
|
||||||
|
utask = mtask.utask
|
||||||
|
is_main_mgroup = False
|
||||||
|
if utask:
|
||||||
|
if utask.state == Utask.UTASK_ASSGINED:
|
||||||
|
utask.state = Utask.UTASK_WORKING
|
||||||
|
utask.save()
|
||||||
|
if mtask.is_count_utask:
|
||||||
|
is_main_mgroup = True
|
||||||
|
elif mtask.material_out == utask.material:
|
||||||
|
is_main_mgroup = True
|
||||||
|
if is_main_mgroup:
|
||||||
|
res2 = Mtask.objects.filter(utask=utask, mgroup=mtask.mgroup).aggregate(sum_count_real=Sum(
|
||||||
|
'count_real'), sum_count_ok=Sum('count_ok'), sum_count_notok=Sum('count_notok'))
|
||||||
|
utask.count_real = res2['sum_count_real'] if res2['sum_count_real'] else 0
|
||||||
|
utask.count_ok = res2['sum_count_ok'] if res2['sum_count_ok'] else 0
|
||||||
|
utask.count_notok = res2['sum_count_notok'] if res2['sum_count_notok'] else 0
|
||||||
|
if Mtask.objects.filter(utask=utask).exclude(state=Mtask.MTASK_SUBMIT).count() == 0:
|
||||||
|
utask.state = Utask.UTASK_SUBMIT
|
||||||
|
utask.save()
|
||||||
|
|
||||||
|
|
||||||
def handover_submit(handover: Handover, user: User, now: Union[datetime.datetime, None]):
|
def handover_submit(handover: Handover, user: User, now: Union[datetime.datetime, None]):
|
||||||
|
|
|
@ -207,11 +207,10 @@ class MlogViewSet(CustomModelViewSet):
|
||||||
raise ParseError('该任务已停止!')
|
raise ParseError('该任务已停止!')
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
mlog_submit(ins, self.request.user, now)
|
mlog_submit(ins, self.request.user, now)
|
||||||
if ins.mtask:
|
|
||||||
update_mtask(ins.mtask)
|
|
||||||
vdata_new = MlogSerializer(ins).data
|
vdata_new = MlogSerializer(ins).data
|
||||||
create_auditlog('submit', ins, vdata_new,
|
create_auditlog('submit', ins, vdata_new,
|
||||||
vdata_old, now, self.request.user)
|
vdata_old, now, self.request.user)
|
||||||
|
MyThread(cal_mtask_progress_from_mlog,args=(ins,)).start()
|
||||||
MyThread(cal_material_count_from_mlog,args=(ins,)).start()
|
MyThread(cal_material_count_from_mlog,args=(ins,)).start()
|
||||||
return Response(vdata_new)
|
return Response(vdata_new)
|
||||||
|
|
||||||
|
@ -230,14 +229,9 @@ class MlogViewSet(CustomModelViewSet):
|
||||||
now = timezone.now()
|
now = timezone.now()
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
mlog_revert(ins, user, 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,
|
create_auditlog('revert', ins, {}, {}, now, user,
|
||||||
request.data.get('change_reason', ''))
|
request.data.get('change_reason', ''))
|
||||||
|
MyThread(cal_mtask_progress_from_mlog,args=(ins,)).start()
|
||||||
MyThread(cal_material_count_from_mlog,args=(ins,)).start()
|
MyThread(cal_material_count_from_mlog,args=(ins,)).start()
|
||||||
return Response(MlogSerializer(instance=ins).data)
|
return Response(MlogSerializer(instance=ins).data)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue