feat: 一二级日志录入

This commit is contained in:
caoqianming 2024-09-04 15:25:14 +08:00
parent e77f3159f5
commit 6e7e6c584e
4 changed files with 93 additions and 33 deletions

View File

@ -1,7 +1,7 @@
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, Route from apps.mtm.models import Mgroup, Team, Shift, Material, Route
from apps.pm.models import Mtask from apps.pm.models import Mtask, Mtaskb
from apps.system.models import User from apps.system.models import User
from django.utils.timezone import localtime from django.utils.timezone import localtime
from apps.em.models import Equipment from apps.em.models import Equipment
@ -118,12 +118,14 @@ class Mlog(CommonADModel):
生产日志 生产日志
""" """
# 变成父级的字段 # 变成父级的字段
MLOG_ONETIME = 10 MLOG_2 = 10
MLOG_STEP = 20 MLOG_23 = 20
MLOG_12 = 30
MTYPE_SELF = 10 MTYPE_SELF = 10
MTYPE_OUT = 20 MTYPE_OUT = 20
fmlog = models.ForeignKey(Fmlog, verbose_name='关联生产日志', on_delete=models.SET_NULL, null=True, blank=True, related_name='mlog_fmlog') fmlog = models.ForeignKey(Fmlog, verbose_name='关联生产日志', on_delete=models.SET_NULL, null=True, blank=True, related_name='mlog_fmlog')
fill_way = models.PositiveSmallIntegerField("填写方式", default=10, help_text='10:一次填写;20:分步填写') mtaskb = models.ForeignKey(Mtaskb, verbose_name='关联个人任务', on_delete=models.CASCADE, related_name='mlog_mtaskb', null=True, blank=True)
fill_way = models.PositiveSmallIntegerField("填写方式", default=10, help_text='10:仅二级;20:二三级;30:一二级')
mtype = models.PositiveSmallIntegerField('生产类型', default=10, help_text='10:自生产;20:外协生产', choices=((10, '自生产'), (20, '外协生产'))) mtype = models.PositiveSmallIntegerField('生产类型', default=10, help_text='10:自生产;20:外协生产', choices=((10, '自生产'), (20, '外协生产')))
supplier = models.ForeignKey(Supplier, verbose_name='外协供应商', on_delete=models.SET_NULL, null=True, blank=True) supplier = models.ForeignKey(Supplier, verbose_name='外协供应商', on_delete=models.SET_NULL, null=True, blank=True)
work_start_time = models.DateTimeField('生产开始时间', null=True, blank=True) work_start_time = models.DateTimeField('生产开始时间', null=True, blank=True)
@ -223,6 +225,9 @@ class Mlog(CommonADModel):
ticket = models.ForeignKey('wf.ticket', verbose_name='关联工单', ticket = models.ForeignKey('wf.ticket', verbose_name='关联工单',
on_delete=models.SET_NULL, related_name='mlog_ticket', null=True, blank=True, db_constraint=False) on_delete=models.SET_NULL, related_name='mlog_ticket', null=True, blank=True, db_constraint=False)
test_file = models.TextField('检验文件', null=True, blank=True) test_file = models.TextField('检验文件', null=True, blank=True)
test_user = models.ForeignKey(
User, verbose_name='检验人', on_delete=models.CASCADE, null=True, blank=True, related_name='mlog_test_user')
test_time = models.DateTimeField('检验时间', null=True, blank=True)
@property @property
def mlogb(self): def mlogb(self):

View File

@ -7,9 +7,9 @@ from datetime import datetime
from .models import SfLog, StLog, SfLogExp, WMaterial, Mlog, Handover, Mlogb, AttLog, OtherLog, Fmlog from .models import SfLog, StLog, SfLogExp, WMaterial, Mlog, Handover, Mlogb, AttLog, OtherLog, Fmlog
from apps.system.models import Dept, User from apps.system.models import Dept, User
from apps.system.serializers import UserSimpleSerializer from apps.system.serializers import UserSimpleSerializer
from apps.pm.models import Mtask from apps.pm.models import Mtask, Mtaskb
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, find_material_can_change from apps.wpm.services import get_sflog, find_material_can_change, generate_new_batch
from apps.mtm.models import Mgroup, TeamMember, Shift, Material, Route 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
@ -275,12 +275,19 @@ class MlogSerializer(CustomModelSerializer):
} }
def create(self, validated_data): def create(self, validated_data):
mtaskb: Mtaskb = validated_data.get('mtaskb', None)
if mtaskb:
mtask = mtaskb.mtask
validated_data['mtask'] = mtask
validated_data['handle_user'] = mtaskb.handle_user
else:
mtask: Mtask = validated_data.get('mtask', None) mtask: Mtask = validated_data.get('mtask', None)
if mtask: if mtask:
validated_data['mgroup'] = mtask.mgroup validated_data['mgroup'] = mtask.mgroup
validated_data['material_in'] = mtask.material_in validated_data['material_in'] = mtask.material_in
material_out = mtask.material_out material_out = mtask.material_out
validated_data['material_out'] = material_out validated_data['material_out'] = material_out
if mtask.start_date == mtask.end_date:
validated_data['handle_date'] = mtask.end_date validated_data['handle_date'] = mtask.end_date
else: else:
mgroup = validated_data['mgroup'] mgroup = validated_data['mgroup']
@ -290,6 +297,19 @@ class MlogSerializer(CustomModelSerializer):
with transaction.atomic(): with transaction.atomic():
mlogb = validated_data.pop('mlogb', []) mlogb = validated_data.pop('mlogb', [])
instance: Mlog = super().create(validated_data) instance: Mlog = super().create(validated_data)
# 自动生成mlogb
batch_in = instance.batch
if instance.wm_in:
batch_in = instance.wm_in.batch
add_dict = {
'mlog': instance, 'batch': batch_in, 'wm_in': instance.wm_in,
'mtask': instance.mtask, 'material_in': instance.material_in,
'count_use': instance.count_use, 'count_break': instance.count_break,
'count_n_jgqbl': instance.count_n_jgqbl
}
Mlogb.objects.create(**add_dict)
# mlogb只用于组合件输出物填写
brotherId_should_list = material_out.brothers brotherId_should_list = material_out.brothers
if brotherId_should_list: if brotherId_should_list:
if mlogb: if mlogb:
@ -299,9 +319,29 @@ class MlogSerializer(CustomModelSerializer):
mlog=instance, batch=instance.batch, mtask=instance.mtask, material_out=item['material_out'], count_ok=item['count_ok']) mlog=instance, batch=instance.batch, mtask=instance.mtask, material_out=item['material_out'], count_ok=item['count_ok'])
else: else:
raise ValidationError('缺少产出物信息') raise ValidationError('缺少产出物信息')
else:
# 生成产出物
batch_out = validated_data.get('batch', None)
if batch_out:
pass
else:
batch_out = generate_new_batch(batch_in, instance)
add_dict_2 = {
'mlog': instance, 'batch': batch_out,
'mtask': instance.mtask, 'material_out': instance.material_out,
'count_ok': instance.count_ok, 'count_notok': instance.count_notok,
'count_break_t': instance.count_break_t
}
for f in Mlogb._meta.fields:
if 'count_n_' in f.name and f.name != 'count_n_jgqbl':
add_dict_2[f.name] = getattr(instance, f.name)
Mlogb.objects.create(**add_dict_2)
return instance return instance
def update(self, instance, validated_data): def update(self, instance, validated_data):
if instance.fill_way != Mlog.MLOG_2:
raise ValidationError('不支持编辑!')
validated_data.pop('mtask', None) validated_data.pop('mtask', None)
validated_data.pop('mgroup', None) validated_data.pop('mgroup', None)
if instance.mtask: if instance.mtask:
@ -318,8 +358,16 @@ class MlogSerializer(CustomModelSerializer):
return instance return instance
def validate(self, attrs): def validate(self, attrs):
attrs['fill_way'] = Mlog.MLOG_ONETIME attrs['fill_way'] = Mlog.MLOG_2
attrs['mtype'] = Mlog.MTYPE_SELF # 默认为自生产 attrs['mtype'] = Mlog.MTYPE_SELF # 默认为自生产
fmlog = attrs.get('fmlog', None)
mtaskb = attrs.get('mtaskb', None)
if fmlog:
attrs['route'] = fmlog.route
attrs['mgroup'] = fmlog.mgroup
attrs['mtask'] = fmlog.mtask
if mtaskb and mtaskb.mtask != fmlog.mtask:
raise ValidationError('子任务不一致')
mtask = attrs.get('mtask', None) mtask = attrs.get('mtask', None)
count_notok = 0 count_notok = 0
for i in attrs: for i in attrs:
@ -361,7 +409,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 attrs['fill_way'] = Mlog.MLOG_23
if mtype == Mlog.MTYPE_OUT: if mtype == Mlog.MTYPE_OUT:
supplier = attrs.get('supplier', None) supplier = attrs.get('supplier', None)
if not supplier: if not supplier:
@ -371,7 +419,7 @@ class MlogInitSerializer(CustomModelSerializer):
class MlogChangeSerializer(CustomModelSerializer): class MlogChangeSerializer(CustomModelSerializer):
class Meta: class Meta:
model = Mlog model = Mlog
fields = ['id', 'work_end_time', 'handle_user', 'note', 'oinfo_json', 'test_file'] fields = ['id', 'work_end_time', 'handle_user', 'note', 'oinfo_json', 'test_file', 'test_user', 'test_time']
def validate(self, attrs): def validate(self, attrs):
if attrs.get('work_end_time', None): if attrs.get('work_end_time', None):
@ -621,3 +669,7 @@ class FmlogUpdateSerializer(CustomModelSerializer):
class Meta: class Meta:
model = Fmlog model = Fmlog
fields = ['id', 'note'] fields = ['id', 'note']
class MlogTCreateSerializer(CustomModelSerializer):
pass

View File

@ -18,6 +18,20 @@ from apps.wf.models import Ticket
from django.db import transaction from django.db import transaction
from apps.utils.thread import MyThread from apps.utils.thread import MyThread
def generate_new_batch(old_batch: str, mlog: Mlog):
new_batch = old_batch
supplier = mlog.supplier
process = mlog.mgroup.process
if mlog.mtype == Mlog.MTYPE_OUT:
supplier_number = supplier.number if supplier else ''
if supplier_number:
new_batch = f'{new_batch}-{supplier_number}'
elif process.batch_append_equip:
number = mlog.equipment.number if mlog.equipment else ''
if number:
new_batch = f'{new_batch}-{number}'
return new_batch
def find_material_can_change(material: Material, mgroup_to: Mgroup): def find_material_can_change(material: Material, mgroup_to: Mgroup):
""" """
找到可转变为的物料(返工交接用) 找到可转变为的物料(返工交接用)
@ -424,7 +438,7 @@ def cal_mlog_count_from_mlogb(mlog: Mlog):
""" """
通过mlogb计算mlog count 合计 通过mlogb计算mlog count 合计
""" """
if mlog.fill_way == Mlog.MLOG_STEP: if mlog.fill_way == Mlog.MLOG_23:
a_dict = { a_dict = {
"total_count_use": Sum('count_use'), "total_count_use": Sum('count_use'),
"total_count_break": Sum('count_break'), "total_count_break": Sum('count_break'),
@ -455,9 +469,9 @@ def cal_mtask_progress_from_mlog(mlog: Mlog):
""" """
更新mlog关联的任务进度(可线程中执行) 更新mlog关联的任务进度(可线程中执行)
""" """
if mlog.fill_way == Mlog.MLOG_ONETIME and mlog.mtask: if mlog.fill_way in [Mlog.MLOG_2, Mlog.MLOG_12] and mlog.mtask:
update_mtask(mlog.mtask, fill_way=Mlog.MLOG_ONETIME) update_mtask(mlog.mtask, fill_way=mlog.fill_way)
elif mlog.fill_way == Mlog.MLOG_STEP: elif mlog.fill_way == Mlog.MLOG_23:
cal_mlog_count_from_mlogb(mlog) cal_mlog_count_from_mlogb(mlog)
m_outs_qs = Mlogb.objects.filter(mlog=mlog, material_out__isnull=False) m_outs_qs = Mlogb.objects.filter(mlog=mlog, material_out__isnull=False)
caled_mtask = [] caled_mtask = []
@ -465,7 +479,7 @@ def cal_mtask_progress_from_mlog(mlog: Mlog):
mtask = item.mtask mtask = item.mtask
if mtask in caled_mtask: if mtask in caled_mtask:
continue continue
update_mtask(mtask, fill_way=Mlog.MLOG_STEP) update_mtask(mtask, fill_way=mlog.fill_way)
caled_mtask.append(mtask) caled_mtask.append(mtask)
def cal_material_count_from_mlog(mlog: Mlog): def cal_material_count_from_mlog(mlog: Mlog):
@ -488,7 +502,7 @@ def cal_material_count_from_mlog(mlog: Mlog):
def update_mtask(mtask: Mtask, fill_way: int = 10): def update_mtask(mtask: Mtask, fill_way: int = 10):
from apps.pm.models import Utask from apps.pm.models import Utask
if fill_way == Mlog.MLOG_ONETIME: if fill_way == Mlog.MLOG_2:
res = Mlog.objects.filter(mtask=mtask).exclude(submit_time=None).aggregate(sum_count_real=Sum( res = Mlog.objects.filter(mtask=mtask).exclude(submit_time=None).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'))
mtask.count_real = res['sum_count_real'] if res['sum_count_real'] else 0 mtask.count_real = res['sum_count_real'] if res['sum_count_real'] else 0
@ -507,7 +521,7 @@ def update_mtask(mtask: Mtask, fill_way: int = 10):
if Mtask.objects.filter(utask=utask).exclude(state=Mtask.MTASK_SUBMIT).count() == 0: if Mtask.objects.filter(utask=utask).exclude(state=Mtask.MTASK_SUBMIT).count() == 0:
utask.state = Utask.UTASK_SUBMIT utask.state = Utask.UTASK_SUBMIT
utask.save() utask.save()
elif fill_way == Mlog.MLOG_STEP: elif fill_way in [Mlog.MLOG_23, Mlog.MLOG_12]:
# 已经提交的日志 # 已经提交的日志
m_outs_qs_mtask = Mlogb.objects.filter(mtask=mtask, material_out__isnull=False, mlog__submit_time__isnull=False) m_outs_qs_mtask = Mlogb.objects.filter(mtask=mtask, material_out__isnull=False, mlog__submit_time__isnull=False)
res = m_outs_qs_mtask.aggregate( res = m_outs_qs_mtask.aggregate(
@ -640,7 +654,7 @@ def mlog_submit_validate(ins: Mlog):
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('该任务已停止!')
if ins.fill_way == Mlog.MLOG_STEP: if ins.fill_way == Mlog.MLOG_23:
if not Mlogb.objects.filter(material_out__isnull=False, mlog=ins).exists(): if not Mlogb.objects.filter(material_out__isnull=False, mlog=ins).exists():
raise ParseError('该日志未指定产出!') raise ParseError('该日志未指定产出!')
if not Mlogb.objects.filter(material_in__isnull=False, mlog=ins).exists(): if not Mlogb.objects.filter(material_in__isnull=False, mlog=ins).exists():

View File

@ -26,7 +26,7 @@ from .serializers import (SflogExpSerializer, SfLogSerializer, StLogSerializer,
from .services import mlog_submit, update_mtask, handover_submit, mlog_revert, cal_material_count_from_mlog, cal_mtask_progress_from_mlog 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.utils.thread import MyThread
from apps.monitor.services import create_auditlog, delete_auditlog from apps.monitor.services import create_auditlog, delete_auditlog
from apps.wpm.services import mlog_submit_validate from apps.wpm.services import mlog_submit_validate, generate_new_batch
# Create your views here. # Create your views here.
@ -470,8 +470,6 @@ class MlogbInViewSet(CreateModelMixin, UpdateModelMixin, DestroyModelMixin, Cust
def perform_create(self, serializer): def perform_create(self, serializer):
ins: Mlogb = serializer.save() ins: Mlogb = serializer.save()
mlog: Mlog = ins.mlog mlog: Mlog = ins.mlog
process: Process = mlog.mgroup.process
supplier = mlog.supplier
# 创建输出 # 创建输出
if ins.mtask and ins.material_in: if ins.mtask and ins.material_in:
material_out = mlog.material_out material_out = mlog.material_out
@ -482,16 +480,7 @@ class MlogbInViewSet(CreateModelMixin, UpdateModelMixin, DestroyModelMixin, Cust
"mlog": ins.mlog, "mlog": ins.mlog,
"material_out": ins.mlog.material_out "material_out": ins.mlog.material_out
} }
new_batch = ins.batch m_dict['batch'] = generate_new_batch(ins.batch, mlog)
if mlog.mtype == Mlog.MTYPE_OUT:
supplier_number = supplier.number if supplier else ''
if supplier_number:
new_batch = f'{new_batch}-{supplier_number}'
elif process.batch_append_equip:
number = mlog.equipment.number if mlog.equipment else ''
if number:
new_batch = f'{new_batch}-{number}'
m_dict['batch'] = new_batch
Mlogb.objects.get_or_create(**m_dict, defaults=m_dict) Mlogb.objects.get_or_create(**m_dict, defaults=m_dict)