feat: utask支持恢复任务/排产支持传入to_day

This commit is contained in:
caoqianming 2024-06-24 18:23:51 +08:00
parent 643efa448e
commit d766d880e7
3 changed files with 111 additions and 62 deletions

View File

@ -3,7 +3,7 @@ from rest_framework.exceptions import ValidationError, ParseError
import math
from apps.mtm.serializers import MaterialSimpleSerializer
from apps.pm.models import Mtask, Utask
from apps.pm.models import Mtask, Utask, SCHEDULE_TYPE
from apps.sam.models import OrderItem
from apps.utils.serializers import CustomModelSerializer
from apps.system.models import Dept
@ -80,6 +80,15 @@ class MtaskSerializer(CustomModelSerializer):
'number', 'count', 'start_date', 'end_date']}
return super().update(instance, new_data)
class SchedueMtasksSerializer(serializers.Serializer):
ids = serializers.ListField(
child=serializers.CharField(max_length=20), label="utask ID列表")
schedule_type = serializers.ChoiceField(label='排产类型', choices=SCHEDULE_TYPE, required=False)
def validate(self, attrs):
if "schedule_type" not in attrs:
attrs["schedule_type"] = "to_day"
return super().validate(attrs)
class SchedueSerializer(serializers.Serializer):
orderitems = serializers.PrimaryKeyRelatedField(

View File

@ -53,9 +53,10 @@ class PmService:
OrderItem.objects.filter(id__in=orderitemIds).update(utask=utask)
@classmethod
def schedue_mtasks(cls, user, utask: Utask):
def schedue_mtasks(cls, user, utask: Utask, schedule_type: str = "to_day"):
"""
从大任务自动排产出小任务
param schedule_type: to_day/to_mgroup
从大任务自动排产出小任务(按工段/按天分配)
"""
# from apps.wpm.services import make_sflogs
if utask.state != Utask.UTASK_CREATED:
@ -66,27 +67,42 @@ class PmService:
# 计算相差天数
rela_days = (end_date - start_date).days + 1
if utask.mgroup: # 如果存在指定的mgroup则直接排产
if rela_days >= 1:
task_count_day = math.ceil(count/rela_days)
for i in range(rela_days):
task_date = start_date + timedelta(days=i)
Mtask.objects.create(**{
'type': utask.type,
'number': f'{number}_{i+1}',
'material_out': utask.material,
'material_in': utask.material_in,
'mgroup': utask.mgroup,
'count': task_count_day,
'start_date': task_date,
'end_date': task_date,
'utask': utask,
'create_by': user,
'update_by': user,
'is_count_utask': True
})
# 先撤销有需要再加
# make_sflogs(mgroup=utask.mgroup,
# start_date=task_date, end_date=task_date, create_by=user)
if schedule_type == 'to_day':
if rela_days >= 1:
task_count_day = math.ceil(count/rela_days)
for i in range(rela_days):
task_date = start_date + timedelta(days=i)
Mtask.objects.create(**{
'type': utask.type,
'number': f'{number}_{i+1}',
'material_out': utask.material,
'material_in': utask.material_in,
'mgroup': utask.mgroup,
'count': task_count_day,
'start_date': task_date,
'end_date': task_date,
'utask': utask,
'create_by': user,
'update_by': user,
'is_count_utask': True
})
elif schedule_type == 'to_mgroup':
Mtask.objects.create(**{
'type': utask.type,
'number': f'{number}_r1',
'material_out': product,
'material_in': utask.material_in,
'mgroup': utask.mgroup,
'count': count,
'start_date': start_date,
'end_date': end_date,
'utask': utask,
'create_by': user,
'update_by': user,
'is_count_utask': True
})
else:
raise ParseError('不支持的排产类型')
else:
# 获取产品的加工路线
rqs = Route.get_routes(product)
@ -112,35 +128,50 @@ class PmService:
raise ParseError(f'{ind+1}步-工段不存在!')
else: # 后面可能会指定车间
raise ParseError(f'{ind+1}步-工段存在多个!')
task_count = count
if val.out_rate:
if val.out_rate > 1:
task_count = math.ceil(
count / (val.out_rate/100))
else:
task_count = math.ceil(count / val.out_rate)
task_count_day = math.ceil(task_count/rela_days)
if rela_days >= 1:
for i in range(rela_days):
task_date = start_date + timedelta(days=i)
Mtask.objects.create(**{
'number': f'{number}_r{ind+1}_{i+1}',
'type': utask.type,
'material_out': halfgood,
'material_in': material_in,
'mgroup': mgroup,
'count': task_count_day,
'start_date': task_date,
'end_date': task_date,
'utask': utask,
'create_by': user,
'update_by': user,
'is_count_utask': val.is_count_utask
})
# 先撤销,有需要再加
# make_sflogs(mgroup=mgroup,
# start_date=task_date, end_date=task_date, create_by=user)
if schedule_type == 'to_day':
task_count = count
if val.out_rate:
if val.out_rate > 1:
task_count = math.ceil(
count / (val.out_rate/100))
else:
task_count = math.ceil(count / val.out_rate)
task_count_day = math.ceil(task_count/rela_days)
if rela_days >= 1:
for i in range(rela_days):
task_date = start_date + timedelta(days=i)
Mtask.objects.create(**{
'number': f'{number}_r{ind+1}_{i+1}',
'type': utask.type,
'material_out': halfgood,
'material_in': material_in,
'mgroup': mgroup,
'count': task_count_day,
'start_date': task_date,
'end_date': task_date,
'utask': utask,
'create_by': user,
'update_by': user,
'is_count_utask': val.is_count_utask
})
elif schedule_type == 'to_mgroup':
Mtask.objects.create(**{
'number': f'{number}_r{ind+1}',
'type': utask.type,
'material_out': halfgood,
'material_in': material_in,
'mgroup': mgroup,
'count': count,
'start_date': start_date,
'end_date': end_date,
'utask': utask,
'create_by': user,
'update_by': user,
'hour_work': val.hour_work,
'is_count_utask': val.is_count_utask
})
else:
raise ParseError('不支持的排产类型')
@classmethod
def check_orderitems(cls, orderitems: QuerySet[OrderItem]):
"""

View File

@ -9,7 +9,8 @@ from apps.utils.viewsets import CustomModelViewSet
from .filters import MtaskFilter, UtaskFilter
from .models import Mtask, Utask
from .serializers import MtaskSerializer, SchedueSerializer, UtaskSerializer, MtaskDaySerializer, MtaskAddInfoSerializer
from .serializers import (MtaskSerializer, SchedueSerializer, UtaskSerializer,
MtaskDaySerializer, MtaskAddInfoSerializer, SchedueMtasksSerializer)
from .services import PmService
from django.utils import timezone
@ -33,12 +34,12 @@ class UtaskViewSet(CustomModelViewSet):
raise ParseError('该任务状态不可删除')
return super().perform_destroy(instance)
@action(methods=['post'], detail=True, perms_map={'post': 'utask.stop'}, serializer_class=Serializer)
@action(methods=['post'], detail=True, perms_map={'post': 'utask.toggle'}, serializer_class=Serializer)
@transaction.atomic
def stop(self, request, *args, **kwargs):
"""停止任务
def toggle(self, request, *args, **kwargs):
"""停止/恢复任务
停止任务
停止/恢复任务
"""
obj = self.get_object()
user = request.user
@ -51,8 +52,16 @@ class UtaskViewSet(CustomModelViewSet):
# 停止所有小任务
Mtask.objects.filter(
utask=obj, state=Mtask.MTASK_ASSGINED).update(state=Mtask.MTASK_STOP, update_by=user, update_time=now)
elif obj.state == Utask.UTASK_STOP:
obj.state = Utask.UTASK_WORKING
obj.update_by = user
obj.update_time = now
obj.save()
# 恢复所有小任务
Mtask.objects.filter(
utask=obj, state=Mtask.MTASK_STOP).update(state=Mtask.MTASK_ASSGINED, update_by=user, update_time=now)
else:
raise ParseError('该状态下不可停止')
raise ParseError('该状态下不可变更')
return Response()
@action(methods=['post'], detail=False, perms_map={'post': 'utask.schedue'}, serializer_class=SchedueSerializer)
@ -69,10 +78,10 @@ class UtaskViewSet(CustomModelViewSet):
request.data['orderitems'], vdata['start_date'], vdata['end_date'], vdata.get('belong_dept', None))
return Response()
@action(methods=['post'], detail=False, perms_map={'post': 'utask.schedue'}, serializer_class=PkSerializer)
@action(methods=['post'], detail=False, perms_map={'post': 'utask.schedue'}, serializer_class=SchedueMtasksSerializer)
@transaction.atomic
def schedue_mtasks(self, request, *args, **kwargs):
"""任务分解
"""任务分解(支持分解到天或仅仅到工段)
任务分解
"""
@ -82,7 +91,7 @@ class UtaskViewSet(CustomModelViewSet):
utasks = Utask.objects.filter(
id__in=vdata['ids'], state=Utask.UTASK_CREATED)
for i in utasks:
PmService.schedue_mtasks(request.user, i)
PmService.schedue_mtasks(request.user, i, vdata["schedule_type"])
return Response()
@action(methods=['post'], detail=False, perms_map={'post': 'utask.assgin'}, serializer_class=PkSerializer)