async def get_plan_list(self, query):
     plan_data_list = []
     plan_collection = get_plan_db_collection()
     columns = {
         "task_no": 1,
         "material_name": 1,
         "plan_count": 1,
         "plan_start_date": 1,
         "workshop_name": 1,
         "product_line_code": 1,
         "operator": 1,
         "create_time": 1,
         "modified_time": 1,
         "plan_status": 1,
         "plan_type": 1,
         "real_end_date": 1,
         "_id": 0
     }
     for column in get_custom_field_config().keys():
         columns.update({column: 1})
     try:
         async for document in plan_collection.find(query, columns).sort(
                 "real_end_date", -1):
             plan_data_list.append(document)
         self.send_response_data(MesCode.success, plan_data_list,
                                 '获取历史任务成功')
         get_logger().info('获取历史任务成功, 数据: {}'.format(plan_data_list))
     except Exception as e:
         log_exception(e, '获取历史任务失败')
         self.send_response_data(MesCode.fail, None, '获取历史任务失败')
Example #2
0
 async def get_process(self, product_line, plan_start_date):
     """
     url: GET /api/plan_management/manage/(?P<product_line>.*)/(?P<plan_start_date>.*)/dispatched_plan/list
     :param product_line: 产线编码
     :param plan_start_date: 计划开始日期
     :return: 该产线在该计划开始日期当天其余所有已下发过的计划
     {
         "code":"success",
         "info": "",
         "data":
         [
             {
                 "task_no": "11111",
                 "material_name": "物料A",
                 "plan_status": 2, //已下发/1, 进行中/2, 已完工/4
             }
         ]
     }
     """
     plan_list = []
     try:
         # 获取该产线该天所有状态为已下发,进行中和已完工的计划
         query = {
             '$and': [{
                 '$or': [{
                     'plan_status': PlanStatusType.dispatched.value
                 }, {
                     'plan_status': PlanStatusType.in_progress.value
                 }, {
                     'plan_status': PlanStatusType.finished.value
                 }]
             }, {
                 'product_line_code': product_line,
                 'plan_start_date': plan_start_date
             }]
         }
         plan_collection = get_plan_db_collection()
         async for document in plan_collection.find(query).sort(
                 'plan_seq_no', ASCENDING):
             task_no = document['task_no']
             material_name = document['material_name']
             plan_status = document['plan_status']
             plan_data = {
                 'task_no': task_no,
                 'material_name': material_name,
                 'plan_status': plan_status
             }
             plan_list.append(plan_data)
         self.send_response_data(MesCode.success, plan_list, '')
         get_logger().info('获取产线:{}, 计划开工日期:{}其他已下发过的计划成功: {}'.format(
             product_line, plan_start_date, plan_list))
     except Exception as e:
         log_exception(
             e,
             '获取产线:{}, 计划开工日期:{}其他已下发过的计划失败'.format(product_line,
                                                    plan_start_date))
         self.send_response_data(
             MesCode.fail, None,
             '获取产线:{}, 计划开工日期:{}其他已下发过的计划失败'.format(product_line,
                                                    plan_start_date))
Example #3
0
 async def post_process(self):
     """
     url: POST /api/plan_management/manage/plan/delete
     前端请求后端的数据结构:
     {
         "task_no": "11111"  //需要删除的计划任务单号
     }
     :return:
     {
         "code":"success",
         "info": "",
         "data": null
     }
     """
     try:
         req_data = self.data
         plan_collection = get_plan_db_collection()
         query = {'task_no': req_data['task_no']}
         document = await plan_collection.find_one(query)
         if document:
             plan_status = document['plan_status']
             plan_type = document['plan_type']
             if plan_type == PlanType.erp_import:
                 self.send_response_data(
                     MesCode.fail, None,
                     '删除计划失败: {}, 当前计划为erp导入计划'.format(self.data))
                 get_logger().info('删除计划失败: {}, 当前计划为erp导入计划'.format(
                     self.data))
             elif plan_status == PlanStatusType.in_progress or plan_status == PlanStatusType.paused:
                 self.send_response_data(
                     MesCode.fail, None,
                     '删除计划失败: {}, 当前计划已开始加工'.format(self.data))
                 get_logger().info('删除计划失败: {}, 当前计划已开始加工'.format(
                     self.data))
             else:
                 # 删除该计划,仅当该计划是自定义计划,且未开始加工才能删除
                 plan_collection.delete_one(query)
                 self.send_response_data(MesCode.success, None, '')
         else:
             self.send_response_data(
                 MesCode.success, None,
                 '删除计划失败: {}, 找不到当前计划记录'.format(self.data))
             get_logger().info('删除计划失败: {}, 找不到当前计划记录'.format(self.data))
     except Exception as e:
         log_exception(e, '删除计划失败: {}'.format(self.data))
         self.send_response_data(MesCode.fail, None,
                                 '删除计划失败: {}'.format(self.data))
    async def post_process(self):
        """
        url: POST /api/plan_management/plan/status_update
        监控app发往计划管理app的数据结构:
        [
            {
                "plan_no": "A181120203-00",
                "status": 2, //2表示进行中,3表示暂停,4表示已完工
                "progress_detail":  //仅更新状态为暂停和已完工时传合格数和不合格数,对于进行中没有这个字段
                {
                    "qualified_count": 1000,
                    "unqualified_count": 2
                }
            }
        ]
        :return:
        {
            "code":"success",
            "info": "",
            "data": null
        }
        """
        req_data_list = json.loads(self.request.body)
        try:
            plan_collection = get_plan_db_collection()
            # 转存成字典方便操作
            status_data_dict = dict()
            for req_data in req_data_list:
                plan_no = req_data['plan_no']
                status_data_dict[plan_no] = req_data

            task_no_list = [
                status_data['plan_no'] for status_data in req_data_list
            ]
            query = {'task_no': {'$in': task_no_list}}
            update_plan_list = []
            async for document in plan_collection.find(query):
                document_id = document['_id']
                task_no = document['task_no']
                status_data = status_data_dict[task_no]
                updated_status = status_data['status']
                update_clause = {'plan_status': updated_status}
                if updated_status == PlanStatusType.in_progress.value:
                    real_start_date = document['real_start_date']
                    if not real_start_date:
                        # 如果是计划刚开始加工了,则设置真实开工时间为当前日期
                        update_clause['real_start_date'] = str(
                            datetime.now().date())
                if 'progress_detail' in status_data:
                    # 如果是暂停或者可完工,则会传过来合格数和不合格数
                    qualified_count = status_data['progress_detail'][
                        'qualified_count']
                    unqualified_count = status_data['progress_detail'][
                        'unqualified_count']
                    update_clause['qualified_count'] = qualified_count
                    update_clause['unqualified_count'] = unqualified_count

                update_data = UpdateOne({'_id': document_id},
                                        {'$set': update_clause})
                update_plan_list.append(update_data)
            if update_plan_list:
                # 批量更新计划
                plan_collection.bulk_write(update_plan_list)
                self.send_response_data(MesCode.success, None, '')
                get_logger().info('更新计划状态成功: {}'.format(req_data_list))
        except Exception as e:
            log_exception(e, '更新计划状态数据失败')
            self.send_response_data(MesCode.fail, None,
                                    '更新计划状态数据失败: {}'.format(req_data_list))
Example #5
0
 async def post_process(self):
     """
     url: POST /api/plan_management/manage/plan/add
     前端请求的数据结构:
     {
       "task_no": "11111",   //必填
       "material_code": "557", //必填,选择
       "material_name": "物料A",  //必填,选择
       "material_unit": "个", //必填,选择
       "plan_count": 100,  //必填
       "plan_start_date": "2018-12-12",
       "comment": "",
       "workshop_name": "车间1",  //必填,选择
       "workshop_code": "workshop_6",
       "main_plan_no": "4545545",
       "material_spec": "NNC",
       "special_requirements": ""
     }
     :return:
     {
         "code":"success",
         "info": "",
         "data":
         {
           "task_no": "11111",
           "material_code": "557",
           "material_name": "物料A",
           "material_unit": "个",
           "plan_count": 100,
           "plan_start_date": "2018-12-12",
           "comment": "",
           "workshop_name": "车间1",
           "workshop_code": "workshop_6",
           "product_line_code": "6t90",
           "operator": "admin",
           "create_time": "2018-12-10: 10:00:00",
           "modify_time": "2018-12-20: 13:10:20",
           "plan_status": "0",
           "plan_type": 0,
           "dzzd_task_type": "常规产品",
           "dzzd_task_date": "2019-01-10",
           "dzzd_plan_no": "11111",
           "dzzd_main_plan_no": "4545545",
           "dzzd_material_spec": "NNC",
           "dzzd_special_requirements": ""
         }
     }
     """
     try:
         req_data = self.data
         plan_collection = get_plan_db_collection()
         task_no = req_data['task_no']
         existing_plan = await plan_collection.find_one(
             {'task_no': task_no})
         if existing_plan:
             get_logger().info('任务单号:{}对应的计划已存在'.format(task_no))
             self.send_response_data(MesCode.fail, None,
                                     '任务单号:{}对应的计划已存在'.format(task_no))
             return
         else:
             req_data['real_start_date'] = ''
             req_data['operator'] = await self.login_name
             req_data['create_time'] = str(datetime.now())
             req_data['modified_time'] = ''
             req_data['plan_status'] = PlanStatusType.not_dispatched.value
             req_data['plan_type'] = PlanType.manual_input.value
             req_data['plan_end_date'] = ''
             req_data['real_start_date'] = ''
             req_data['real_end_date'] = ''
             req_data['product_line_code'] = ''
             req_data['dispatch_time'] = ''
             req_data['erp_plan_status'] = ''
             req_data['qualified_count'] = 0
             req_data['unqualified_count'] = 0
             inserted_result = await plan_collection.insert_one(req_data)
             inserted_id = inserted_result.inserted_id
             get_logger().info('新增自定义计划成功:{}'.format(req_data))
             inserted_document = await plan_collection.find_one(
                 {'_id': inserted_id})
             del inserted_document['_id']
             del inserted_document['plan_end_date']
             del inserted_document['real_start_date']
             del inserted_document['real_end_date']
             del inserted_document['qualified_count']
             del inserted_document['unqualified_count']
             polish_plan_display_time(inserted_document)
             self.send_response_data(MesCode.success, inserted_document, '')
     except Exception as e:
         log_exception(e, '添加自定义计划失败')
         self.send_response_data(MesCode.fail, None, '添加自定义计划失败')
Example #6
0
    async def post_process(self):
        """
        url: POST /api/plan_management/manage/plan/rollback
        前端请求后端的数据结构:
        {
            "task_no": "11111"  //需要回退的计划任务单号
        }
        :return:
        {
            "code":"success",
            "info": "",
            "data": null
        }
        """
        try:
            req_data = self.data
            plan_collection = get_plan_db_collection()
            task_no = req_data['task_no']
            query = {'task_no': task_no}
            document = await plan_collection.find_one(query)
            if document:
                plan_status = document['plan_status']
                if plan_status != PlanStatusType.dispatched.value:
                    self.send_response_data(
                        MesCode.fail, None,
                        '回退计划失败: {}, 当前计划状态不是已下发'.format(self.data))
                    get_logger().info('回退计划失败: {}, 当前计划状态不是已下发'.format(
                        self.data))
                    return
                else:
                    qualified_count = document['qualified_count']
                    unqualified_count = document['unqualified_count']
                    if qualified_count == 0 and unqualified_count == 0:
                        update_plan_status = PlanStatusType.not_dispatched.value
                    else:
                        update_plan_status = PlanStatusType.paused.value
                    # 回退时更新计划状态, 清空产线信息和计划开始日期
                    current_time = datetime.now()
                    modified_time = str(current_time)
                    document_to_rollback = await plan_collection.find_one(
                        {'task_no': task_no})
                    if document_to_rollback:
                        # 回退前获取该计划之前下发的产线和开始日期,用于更新计划到监控app
                        pl_code = document_to_rollback['product_line_code']
                        plan_start_date = document_to_rollback[
                            'plan_start_date']
                        # 回退该计划
                        document_to_rollback[
                            'plan_status'] = update_plan_status
                        document_to_rollback['product_line_code'] = ''
                        document_to_rollback['plan_start_date'] = ''
                        document_to_rollback['dispatch_time'] = ''
                        document_to_rollback['modified_time'] = modified_time
                        await plan_collection.replace_one(
                            query, document_to_rollback)
                        del document_to_rollback['_id']
                        polish_plan_display_time(document_to_rollback)
                        self.send_response_data(MesCode.success,
                                                document_to_rollback, '')
                        get_logger().info('回退计划:{}成功, 回退后数据: {}'.format(
                            task_no, document_to_rollback))

                        # 回退成功后更新改天该产线的计划数据到监控app
                        await dispatch_plans_to_monitor_app(
                            pl_code, plan_start_date)
            else:
                self.send_response_data(
                    MesCode.fail, None,
                    '回退计划失败: {}, 找不到当前计划记录'.format(self.data))
                get_logger().info('回退计划失败: {}, 找不到当前计划记录'.format(self.data))
        except Exception as e:
            log_exception(e, '回退计划失败: {}'.format(self.data))
            self.send_response_data(MesCode.fail, None,
                                    '回退计划失败: {}'.format(self.data))
Example #7
0
    async def post_process(self):
        """
        url: POST /api/plan_management/manage/plan/dispatch
        前端请求后端的数据结构:
        {
            "task_no_list": ["task_no1", "task_no2"],   //需要下发的任务单号列表
            "task_seq_list": ["task_no3", "task_no2","task_no1", "task_no4"],  //所有当天该产线所有任务的生产顺序任务单号列表
            "product_line_code": "product_line_6t90",
            "plan_start_date": "2019-01-10"
        }

        :return:
        {
            "code":"success",
            "info": "",
            "data":
            [
                {
                    "task_no": "A181120203-00",
                    "task_type": "常规产品",
                    "task_date": "2019-01-10",
                    "material_code": "material_t901d40adc24v4",
                    "material_name": "T901D40ADC24V 4脚",
                    "material_spec": "NNC",
                    "material_unit": "个",
                    "plan_count": 4000,
                    "plan_no": "A181120203-00",
                    "plan_start_date": "2019-01-15",
                    "plan_end_date": "2019-01-16",
                    "real_start_date": "",
                    "real_end_date": "",
                    "workshop_name": "六车间",
                    "create_time": "2019-01-14 10:13:38.348108",
                    "erp_plan_status": "",
                    "plan_status": 1,
                    "main_plan_no": "",
                    "special_requirements": "",
                    "workshop_code": "workshop_6",
                    "comment": "",
                    "product_line_code": "product_line_6t90",
                    "operator": "admin",
                    "modified_time": "",
                    "dispatch_time": "2019-01-14 10:42:39.986123",
                    "qualified_count": 0,
                    "unqualified_count": 0,
                    "plan_type": 1
                }
            ]
        }
        """
        try:
            req_data = json.loads(self.request.body)
            task_no_list = req_data['task_no_list']
            task_seq_list = req_data['task_seq_list']
            pl_code = req_data['product_line_code']
            plan_start_date = req_data['plan_start_date']
            plan_collection = get_plan_db_collection()

            # 检查准备下发的计划是否为未下发或者暂停状态
            status_error_msg = await dispatch_plans_check(task_no_list)
            if status_error_msg:
                self.send_response_data(MesCode.fail, None,
                                        '下发计划失败: {}'.format(status_error_msg))
                get_logger().info('下发计划失败: {}'.format(status_error_msg))
                return
            # 计算需要下发的计划的顺序号
            seq_num = 0
            task_seq_dict = dict()
            for task_no in task_seq_list:
                seq_num += 1
                task_seq_dict[task_no] = seq_num

            update_plan_list = []
            query = {'task_no': {'$in': task_seq_list}}
            current_time = datetime.now()
            async for document in plan_collection.find(query):
                document_id = document['_id']
                modified_time = str(current_time)
                task_no = document['task_no']
                task_seq = task_seq_dict[task_no]
                update_clause = None
                if task_no in task_no_list:
                    # 如果是本次要下发的计划,则直接更新下发相关字段并赋予序号
                    dispatch_time = str(current_time)
                    update_clause = {
                        '$set': {
                            'dispatch_time': dispatch_time,
                            'modified_time': modified_time,
                            'plan_status': PlanStatusType.dispatched.value,
                            'plan_seq_no': task_seq,
                            'product_line_code': pl_code,
                            'plan_start_date': plan_start_date
                        }
                    }
                else:
                    # 如果是已下发的计划顺序调整了,则更新该计划顺序号
                    plan_status = document['plan_status']
                    plan_seq = document['plan_seq_no']
                    if plan_status == PlanStatusType.dispatched.value and plan_seq != task_seq:
                        update_clause = {'$set': {'plan_seq_no': task_seq}}
                if update_clause:
                    update_data = UpdateOne({'_id': document_id},
                                            update_clause)
                    update_plan_list.append(update_data)
                # 批量下发时,目前通过给下一个计划的下发时间添加1微秒来区别顺序
                current_time = current_time + relativedelta(microseconds=+1)
            if update_plan_list:
                # 批量更新计划状态和时间
                plan_collection.bulk_write(update_plan_list)

                updated_documents_cursor = plan_collection.find(
                    {'task_no': {
                        '$in': task_no_list
                    }})
                updated_documents = []
                async for updated_document in updated_documents_cursor:
                    del updated_document['_id']
                    polish_plan_display_time(updated_document)
                    updated_documents.append(updated_document)
                self.send_response_data(MesCode.success, updated_documents, '')
                get_logger().info('下发计划成功: {}'.format(updated_documents))
                # 下发成功后更新改天该产线的计划数据到监控app
                await dispatch_plans_to_monitor_app(pl_code, plan_start_date)
            else:
                self.send_response_data(MesCode.fail, None,
                                        '下发计划失败: {}'.format(self.data))
                get_logger().info('下发计划失败: {}'.format(self.data))
        except Exception as e:
            log_exception(e, '下发计划失败: {}'.format(self.data))
            self.send_response_data(MesCode.fail, None,
                                    '下发计划失败: {}'.format(self.data))
Example #8
0
 async def get_process(self):
     """
     url: GET /api/plan_management/manage/plan/list
     :return:
     {
         "code":"success",
         "info": "",
         "data":
          [
             {
               "task_no": "11111",  //任务单号
               "material_code": "557",  //物料编码
               "material_name": "物料A", //物料名
               "material_unit": "个", //物料单位
               "plan_count": 100,  //计划数量
               "plan_start_date": "2018-12-12",  //计划开工日期
               "comment": "",  //备注信息
               "workshop_name": "车间1",  //车间名
               "workshop_code": "workshop_6", //车间编码
               "product_line_code": "6t90",  //产线编码
               "operator": "admin",   //录入人员
               "create_time": "2018-12-10: 10:00:00",  //录入时间
               "modify_time": "2018-12-20: 13:10:20",  //修改时间
               "plan_status": 0,  //计划状态, 0表示未下发,1表示已下发
               "erp_plan_status": 2, //ERP导入计划原状态, 2.确认, 3.下达, 4.投放, 5.流转
               "plan_type": 0, //计划类型,0表示ERP导入,1表示自定义添加
               "dzzd_task_type": "常规产品", //任务类型,定制字段
               "dzzd_task_date": "2019-01-10", //开单日期,
               "dzzd_plan_no": "11111", //计划单号, 定制字段
               "dzzd_main_plan_no": "4545545",  //主计划号,定制字段
               "dzzd_material_spec": "NNC",     //规格,定制字段
               "dzzd_special_requirements": "" //特殊要求,定制字段
             }
          ]
     }
     """
     plan_data_list = []
     try:
         plan_collection = get_plan_db_collection()
         # 获取所有状态为未下发(0),已下发(1)和暂停的计划
         query = {
             '$or': [{
                 'plan_status': PlanStatusType.not_dispatched.value
             }, {
                 'plan_status': PlanStatusType.dispatched.value
             }, {
                 'plan_status': PlanStatusType.paused.value
             }]
         }
         async for document in plan_collection.find(query):
             del document['_id']
             del document['plan_end_date']
             del document['real_start_date']
             del document['real_end_date']
             del document['qualified_count']
             del document['unqualified_count']
             polish_plan_display_time(document)
             plan_data_list.append(document)
         self.send_response_data(MesCode.success, plan_data_list, '')
         get_logger().info('获取所有管理计划成功, 数据: {}'.format(plan_data_list))
     except Exception as e:
         log_exception(e, '获取所有管理计划失败')
         self.send_response_data(MesCode.fail, None, '获取所有管理计划失败')