diff --git a/apps/pm/filters.py b/apps/pm/filters.py index 64fcfa29..2c57673d 100644 --- a/apps/pm/filters.py +++ b/apps/pm/filters.py @@ -21,6 +21,7 @@ class MtaskFilter(filters.FilterSet): "material_out": ["exact"], "material_out__type": ["exact"], "material_out__is_hidden": ["exact"], + "mgroup__belong_dept__name": ["exact"], "parent": ["exact", "isnull"] } diff --git a/apps/pm/serializers.py b/apps/pm/serializers.py index 21be6936..3c9c4e1d 100644 --- a/apps/pm/serializers.py +++ b/apps/pm/serializers.py @@ -9,7 +9,7 @@ from apps.utils.serializers import CustomModelSerializer class MtaskSerializer(CustomModelSerializer): 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: model = Mtask diff --git a/apps/pm/services.py b/apps/pm/services.py index db539c22..1bc6a484 100644 --- a/apps/pm/services.py +++ b/apps/pm/services.py @@ -10,6 +10,7 @@ from typing import List class PmService: + @classmethod def check_orderitems(cls, orderitems: QuerySet[OrderItem]): """ 校验orderitems并返回整合后的字典以productId为key, [product, count, end_date, orderitems] 为value @@ -39,73 +40,85 @@ class PmService: rdict = cls.check_orderitems(orderitems) start_date_str = start_date.strftime('%Y%m%d') 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: end_date = end_date_cal if start_date >= end_date: raise ParseError('开始时间不可大于结束时间') # 计算相差天数 rela_days = (end_date - start_date).days + 1 - # 获取工艺路线 - rqs = Route.get_routes(product) - # 创建父任务 - for ind, val in enumerate(rqs): - if val.material_out: - halfgood = val.material_out - else: - raise ParseError(f'第{ind+1}步-无输出物料') - if val.material_in: - material_before = val.material_in - elif ind > 0: - material_before = rqs[ind-1].material_out - if val.is_autotask: - # 找到工段 - mgroups = val.mgroups - mgroups_count = len(mgroups) - if mgroups_count == 1: - mgroup = mgroups.first() - elif mgroups_count == 0: - 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) - fmtask, _ = Mtask.objects.get_or_create(mgroup=mgroup, material=halfgood, defaults={ - 'number': f'{product.number}_r{ind+1}_{start_date_str}', - 'material': halfgood, - 'material_before': material_before, - 'mgroup': mgroup, - 'count': task_count, - 'start_date': start_date, - 'end_date': end_date, - 'create_by': user, - 'update_by': user, - }) - task_count_day = math.ceil(task_count/rela_days) - if fmtask.parent is None: - for i in range(rela_days): - task_date = start_date + timedelta(days=i+1) - Mtask.objects.get_or_create(mgroup=mgroup, material=halfgood, parent=fmtask, defaults={ - 'number': f'{fmtask.number}_{i+1}', - 'material': halfgood, - 'material_before': material_before, - 'mgroup': mgroup, - 'count': task_count_day, - 'start_date': task_date, - 'end_date': task_date, - 'parent': fmtask, - 'create_by': user, - 'update_by': user - }) - OrderItem.objects.filter( - id__in=orderitemId_list).update(mtask=fmtask) - + make_list = [] + if xproduct.is_assemb: + for key in xproduct.components: + make_list.append([Material.objects.get( + id=key), xcount*xproduct.components[key], end_date, orderitemId_list]) + else: + make_list = [[xproduct, xcount, end_date, orderitemId_list]] + for i in make_list: + product, count, end_date, orderitemId_list = i + # 获取每个产品的加工路线 + rqs = Route.get_routes(product) + lasttask = None + # 创建父任务 + for ind, val in enumerate(rqs): + if val.material_out: + halfgood = val.material_out + else: + raise ParseError(f'第{ind+1}步-无输出物料') + if val.material_in: + material_in = val.material_in + elif ind > 0: + material_in = rqs[ind-1].material_out + if val.is_autotask: + # 找到工段 + mgroups = Mgroup.objects.filter(process=val.process) + mgroups_count = mgroups.count() + if mgroups_count == 1: + mgroup = mgroups.first() + elif mgroups_count == 0: + 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) + print(halfgood) + fmtask = Mtask.objects.create(**{ + 'number': f'{product.number}_{start_date_str}_r{ind+1}', + 'material_out': halfgood, + 'material_in': material_in, + 'mgroup': mgroup, + 'count': task_count, + 'start_date': start_date, + 'end_date': end_date, + 'create_by': user, + 'update_by': user, + }) + 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.get_or_create(mgroup=mgroup, material_out=halfgood, parent=fmtask, start_date=task_date, defaults={ + '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 - change_order_state_when_schedue.delay(orderitemId_list) + change_order_state_when_schedue(orderitemIds) @classmethod def mtasks_submit(cls, mtasks: QuerySet[Mtask]): diff --git a/apps/pm/views.py b/apps/pm/views.py index 9cdf6c0a..f8a68709 100644 --- a/apps/pm/views.py +++ b/apps/pm/views.py @@ -25,7 +25,7 @@ class MtaskViewSet(CustomModelViewSet): filterset_class = MtaskFilter select_related_fields = ['material_in', 'material_out', 'mgroup'] 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) @transaction.atomic @@ -38,7 +38,7 @@ class MtaskViewSet(CustomModelViewSet): sr.is_valid(raise_exception=True) vdata = sr.validated_data 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() def perform_destroy(self, instance): @@ -46,7 +46,7 @@ class MtaskViewSet(CustomModelViewSet): raise ParseError('该任务非创建中不可删除') 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 def assgin(self, request): """下达任务