feat: 优化mtask创建

This commit is contained in:
caoqianming 2023-10-18 16:28:47 +08:00
parent e8a8c1d078
commit 93d0c43b05
4 changed files with 78 additions and 64 deletions

View File

@ -21,6 +21,7 @@ class MtaskFilter(filters.FilterSet):
"material_out": ["exact"], "material_out": ["exact"],
"material_out__type": ["exact"], "material_out__type": ["exact"],
"material_out__is_hidden": ["exact"], "material_out__is_hidden": ["exact"],
"mgroup__belong_dept__name": ["exact"],
"parent": ["exact", "isnull"] "parent": ["exact", "isnull"]
} }

View File

@ -9,7 +9,7 @@ from apps.utils.serializers import CustomModelSerializer
class MtaskSerializer(CustomModelSerializer): class MtaskSerializer(CustomModelSerializer):
material_ = MaterialSerializer(source='material', read_only=True) material_ = MaterialSerializer(source='material', read_only=True)
mgroup__name = serializers.CharField(source='mgroup.name', read_only=True) mgroup_name = serializers.CharField(source='mgroup.name', read_only=True)
class Meta: class Meta:
model = Mtask model = Mtask

View File

@ -10,6 +10,7 @@ from typing import List
class PmService: class PmService:
@classmethod
def check_orderitems(cls, orderitems: QuerySet[OrderItem]): def check_orderitems(cls, orderitems: QuerySet[OrderItem]):
""" """
校验orderitems并返回整合后的字典以productId为key, [product, count, end_date, orderitems] 为value 校验orderitems并返回整合后的字典以productId为key, [product, count, end_date, orderitems] 为value
@ -39,73 +40,85 @@ class PmService:
rdict = cls.check_orderitems(orderitems) rdict = cls.check_orderitems(orderitems)
start_date_str = start_date.strftime('%Y%m%d') start_date_str = start_date.strftime('%Y%m%d')
for k, v in rdict.items(): for k, v in rdict.items():
product, count, end_date_cal, orderitemId_list = v xproduct, xcount, end_date_cal, orderitemId_list = v
if end_date is None: if end_date is None:
end_date = end_date_cal end_date = end_date_cal
if start_date >= end_date: if start_date >= end_date:
raise ParseError('开始时间不可大于结束时间') raise ParseError('开始时间不可大于结束时间')
# 计算相差天数 # 计算相差天数
rela_days = (end_date - start_date).days + 1 rela_days = (end_date - start_date).days + 1
# 获取工艺路线 make_list = []
rqs = Route.get_routes(product) if xproduct.is_assemb:
# 创建父任务 for key in xproduct.components:
for ind, val in enumerate(rqs): make_list.append([Material.objects.get(
if val.material_out: id=key), xcount*xproduct.components[key], end_date, orderitemId_list])
halfgood = val.material_out else:
else: make_list = [[xproduct, xcount, end_date, orderitemId_list]]
raise ParseError(f'{ind+1}步-无输出物料') for i in make_list:
if val.material_in: product, count, end_date, orderitemId_list = i
material_before = val.material_in # 获取每个产品的加工路线
elif ind > 0: rqs = Route.get_routes(product)
material_before = rqs[ind-1].material_out lasttask = None
if val.is_autotask: # 创建父任务
# 找到工段 for ind, val in enumerate(rqs):
mgroups = val.mgroups if val.material_out:
mgroups_count = len(mgroups) halfgood = val.material_out
if mgroups_count == 1: else:
mgroup = mgroups.first() raise ParseError(f'{ind+1}步-无输出物料')
elif mgroups_count == 0: if val.material_in:
raise ParseError(f'{ind+1}步-工段不存在!') material_in = val.material_in
else: # 后面可能会指定车间 elif ind > 0:
raise ParseError(f'{ind+1}步-工段存在多个!') material_in = rqs[ind-1].material_out
task_count = count if val.is_autotask:
if val.out_rate: # 找到工段
if val.out_rate > 1: mgroups = Mgroup.objects.filter(process=val.process)
task_count = math.ceil(count / (val.out_rate/100)) mgroups_count = mgroups.count()
else: if mgroups_count == 1:
task_count = math.ceil(count / val.out_rate) mgroup = mgroups.first()
fmtask, _ = Mtask.objects.get_or_create(mgroup=mgroup, material=halfgood, defaults={ elif mgroups_count == 0:
'number': f'{product.number}_r{ind+1}_{start_date_str}', raise ParseError(f'{ind+1}步-工段不存在!')
'material': halfgood, else: # 后面可能会指定车间
'material_before': material_before, raise ParseError(f'{ind+1}步-工段存在多个!')
'mgroup': mgroup, task_count = count
'count': task_count, if val.out_rate:
'start_date': start_date, if val.out_rate > 1:
'end_date': end_date, task_count = math.ceil(
'create_by': user, count / (val.out_rate/100))
'update_by': user, else:
}) task_count = math.ceil(count / val.out_rate)
task_count_day = math.ceil(task_count/rela_days) print(halfgood)
if fmtask.parent is None: fmtask = Mtask.objects.create(**{
for i in range(rela_days): 'number': f'{product.number}_{start_date_str}_r{ind+1}',
task_date = start_date + timedelta(days=i+1) 'material_out': halfgood,
Mtask.objects.get_or_create(mgroup=mgroup, material=halfgood, parent=fmtask, defaults={ 'material_in': material_in,
'number': f'{fmtask.number}_{i+1}', 'mgroup': mgroup,
'material': halfgood, 'count': task_count,
'material_before': material_before, 'start_date': start_date,
'mgroup': mgroup, 'end_date': end_date,
'count': task_count_day, 'create_by': user,
'start_date': task_date, 'update_by': user,
'end_date': task_date, })
'parent': fmtask, task_count_day = math.ceil(task_count/rela_days)
'create_by': user, if rela_days > 1:
'update_by': user for i in range(rela_days):
}) task_date = start_date + timedelta(days=i)
OrderItem.objects.filter( Mtask.objects.get_or_create(mgroup=mgroup, material_out=halfgood, parent=fmtask, start_date=task_date, defaults={
id__in=orderitemId_list).update(mtask=fmtask) 'number': f'{fmtask.number}_{i+1}',
'material_out': halfgood,
'material_in': material_in,
'mgroup': mgroup,
'count': task_count_day,
'start_date': task_date,
'end_date': task_date,
'parent': fmtask,
'create_by': user,
'update_by': user
})
lasttask = fmtask
OrderItem.objects.filter(
id__in=orderitemId_list).update(mtask=lasttask)
from apps.sam.tasks import change_order_state_when_schedue from apps.sam.tasks import change_order_state_when_schedue
change_order_state_when_schedue.delay(orderitemId_list) change_order_state_when_schedue(orderitemIds)
@classmethod @classmethod
def mtasks_submit(cls, mtasks: QuerySet[Mtask]): def mtasks_submit(cls, mtasks: QuerySet[Mtask]):

View File

@ -25,7 +25,7 @@ class MtaskViewSet(CustomModelViewSet):
filterset_class = MtaskFilter filterset_class = MtaskFilter
select_related_fields = ['material_in', 'material_out', 'mgroup'] select_related_fields = ['material_in', 'material_out', 'mgroup']
ordering_fields = ['start_date', 'mgroup__process__sort'] ordering_fields = ['start_date', 'mgroup__process__sort']
ordering = ['mgroup__process__sort', '-start_date', '-create_time'] ordering = ['-start_date', 'mgroup__process__sort', '-create_time']
@action(methods=['post'], detail=False, perms_map={'post': 'mtask.schedue'}, serializer_class=SchedueSerializer) @action(methods=['post'], detail=False, perms_map={'post': 'mtask.schedue'}, serializer_class=SchedueSerializer)
@transaction.atomic @transaction.atomic
@ -38,7 +38,7 @@ class MtaskViewSet(CustomModelViewSet):
sr.is_valid(raise_exception=True) sr.is_valid(raise_exception=True)
vdata = sr.validated_data vdata = sr.validated_data
PmService.schedue_from_orderitems(request.user, PmService.schedue_from_orderitems(request.user,
vdata['orderitems'], vdata['start_date'], vdata.get('end_date', None)) request.data['orderitems'], vdata['start_date'], vdata.get('end_date', None))
return Response() return Response()
def perform_destroy(self, instance): def perform_destroy(self, instance):
@ -46,7 +46,7 @@ class MtaskViewSet(CustomModelViewSet):
raise ParseError('该任务非创建中不可删除') raise ParseError('该任务非创建中不可删除')
return super().perform_destroy(instance) return super().perform_destroy(instance)
@action(methods=['post'], detail=False, perms_map={'post': 'mtask.asgin'}, serializer_class=PkSerializer) @action(methods=['post'], detail=False, perms_map={'post': 'mtask.assgin'}, serializer_class=PkSerializer)
@transaction.atomic @transaction.atomic
def assgin(self, request): def assgin(self, request):
"""下达任务 """下达任务