diff --git a/sf_machine_connect/controllers/controllers.py b/sf_machine_connect/controllers/controllers.py index 4f8fdce3..1ba59c6b 100644 --- a/sf_machine_connect/controllers/controllers.py +++ b/sf_machine_connect/controllers/controllers.py @@ -417,21 +417,15 @@ class Sf_Dashboard_Connect(http.Controller): if line == '业绩总览': work_order_domain = [('routing_type', 'in', ['人工线下加工', 'CNC加工'])] plan_domain = [] - quality_check_domain = [('production_line_id.name', 'in', cnc_line_list + ['人工线下加工中心'])] - # production_domain = [] elif line == '人工线下加工中心': work_order_domain = [('routing_type', '=', '人工线下加工')] plan_domain = [('production_type', '=', '人工线下加工')] - quality_check_domain = [('production_line_id.name', '=', line)] - # production_domain = [] else: work_order_domain = [ ('production_line_id.name', '=', line), ('routing_type', '=', 'CNC加工') ] plan_domain = [('production_line_id.name', '=', line)] - quality_check_domain = [('operation_id.name', '=', 'CNC加工')] - # production_domain = [] # # 工单计划量 # plan_data_total_counts = production_obj.search_count( # [('production_line_id.name', '=', line), ('state', 'not in', ['cancel']), @@ -472,15 +466,15 @@ class Sf_Dashboard_Connect(http.Controller): plan_data_overtime_counts = sum(plan_data_overtime_counts.mapped('qty_produced')) # 查找符合条件的生产计划记录 - plan_data = plan_obj.search(plan_domain) + # plan_data = plan_obj.search(plan_domain) # 过滤出那些检测结果状态为 '返工' 或 '报废' 的记录 # faulty_plans = plan_data.filtered(lambda p: any( # result.test_results in ['返工', '报废'] for result in p.production_id.detection_result_ids # )) - faulty_plans = request.env['quality.check'].sudo().search(quality_check_domain + [ - ('quality_state', 'in', ['fail']) + faulty_plans = work_order_obj.search(work_order_domain + [ + ('state', 'in', ['scrap', 'rework']) ]) # 查找制造订单取消与归档的数量 @@ -491,14 +485,16 @@ class Sf_Dashboard_Connect(http.Controller): # 计算符合条件的记录数量 # plan_data_fault_counts = len(faulty_plans) + cancel_order_count # plan_data_fault_counts = len(faulty_plans) - plan_data_fault_counts = sum(faulty_plans.workorder_id.mapped('qty_produced')) + plan_data_fault_counts = sum(faulty_plans.mapped('qty_produced')) # 工单返工数量 - plan_data_rework_counts = plan_obj.search_count(plan_domain + [ - ('production_id.state', 'in', ['rework']) + plan_data_rework = work_order_obj.search(plan_domain + [ + ('state', 'in', ['rework']) ]) + plan_data_rework_counts = sum(plan_data_rework.mapped('qty_produced')) + # 工单完成率 finishe_rate = round( (plan_data_finish_counts / plan_data_total_counts if plan_data_total_counts > 0 else 0), 3) @@ -563,25 +559,25 @@ class Sf_Dashboard_Connect(http.Controller): delay_rate = round((delay_num / plan_data_finish_counts if plan_data_finish_counts > 0 else 0), 3) on_time_rate = 1 - delay_rate - if plan_data: - data = { - 'plan_data_total_counts': plan_data_total_counts, - 'plan_data_finish_counts': plan_data_finish_counts, - 'plan_data_plan_counts': plan_data_total_counts, - 'plan_data_fault_counts': plan_data_fault_counts, - 'nopass_orders_counts': detection_data - len(pass_nums), - 'finishe_rate': finishe_rate, - 'plan_data_progress_deviation': plan_data_progress_deviation, - 'plan_data_rework_counts': plan_data_rework_counts, - 'on_time_rate': on_time_rate, - # 'detection_data': detection_data, - 'detection_data': plan_data_finish_counts, - 'pass_rate': (plan_data_finish_counts - plan_data_fault_counts) / plan_data_finish_counts, - 'plan_data_overtime_counts': plan_data_overtime_counts, - 'overtime_rate': plan_data_overtime_counts / plan_data_finish_counts - if plan_data_finish_counts > 0 else 0, - } - res['data'][line] = data + # if plan_data: + data = { + 'plan_data_total_counts': plan_data_total_counts, + 'plan_data_finish_counts': plan_data_finish_counts, + 'plan_data_plan_counts': plan_data_total_counts, + 'plan_data_fault_counts': plan_data_fault_counts, + 'nopass_orders_counts': detection_data - len(pass_nums), + 'finishe_rate': finishe_rate, + 'plan_data_progress_deviation': plan_data_progress_deviation, + 'plan_data_rework_counts': plan_data_rework_counts, + 'on_time_rate': on_time_rate, + # 'detection_data': detection_data, + 'detection_data': plan_data_finish_counts, + 'pass_rate': (plan_data_finish_counts - plan_data_fault_counts) / plan_data_finish_counts, + 'plan_data_overtime_counts': plan_data_overtime_counts, + 'overtime_rate': plan_data_overtime_counts / plan_data_finish_counts + if plan_data_finish_counts > 0 else 0, + } + res['data'][line] = data return json.dumps(res) # 注意使用 json.dumps 而不是直接用 json.JSONEncoder().encode() @@ -677,7 +673,8 @@ class Sf_Dashboard_Connect(http.Controller): # 使用小时和分钟作为键,确保每个小时的数据有独立的键 key = start_time.strftime('%H:%M:%S') # 只取小时:分钟:秒作为键 - time_count_dict[key] = len(orders) + # time_count_dict[key] = len(orders) + time_count_dict[key] = sum(orders.mapped('qty_produced')) # order_counts.append() res['data'][line] = { 'finish_order_nums': time_count_dict, @@ -707,9 +704,9 @@ class Sf_Dashboard_Connect(http.Controller): ]) order_counts.append({ 'date': date.strftime('%Y-%m-%d'), - 'order_count': len(orders), - 'rework_orders': len(rework_orders), - 'not_passed_orders': len(not_passed_orders) + 'order_count': sum(orders.mapped('qty_produced')), + 'rework_orders': sum(rework_orders.mapped('qty_produced')), + 'not_passed_orders': sum(not_passed_orders.mapped('qty_produced')) }) # 外面包一层,没什么是包一层不能解决的,包一层就能区分了,类似于包一层div # 外面包一层的好处是,可以把多个数据结构打包在一起,方便前端处理 @@ -723,7 +720,7 @@ class Sf_Dashboard_Connect(http.Controller): @http.route('/api/RealTimeProduct', type='http', auth='public', methods=['GET', 'POST'], csrf=False, cors="*") def RealTimeProduct(self, **kw): """ - 获取实时产量 + 获取实时产量(作废) :param kw: :return: """ @@ -746,6 +743,21 @@ class Sf_Dashboard_Connect(http.Controller): # 当班计划量 for line in line_list: + + if line == '业绩总览': + work_order_domain = [('routing_type', 'in', ['人工线下加工', 'CNC加工'])] + plan_domain = [] + elif line == '人工线下加工中心': + work_order_domain = [('routing_type', '=', '人工线下加工')] + plan_domain = [('production_type', '=', '人工线下加工')] + else: + work_order_domain = [ + ('production_line_id.name', '=', line), + ('routing_type', '=', 'CNC加工') + ] + plan_domain = [('production_line_id.name', '=', line)] + + plan_order_nums = plan_obj.search_count( [('production_line_id.name', '=', line), ('state', 'not in', ['draft']), ('date_planned_start', '>=', begin_time), @@ -791,6 +803,7 @@ class Sf_Dashboard_Connect(http.Controller): # res = {'status': 1, 'message': '成功', 'not_done_data': [], 'done_data': []} res = {'status': 1, 'message': '成功', 'data': {}} plan_obj = request.env['sf.production.plan'].sudo() + work_order_obj = request.env['mrp.workorder'].sudo() line_list = ast.literal_eval(kw['line_list']) begin_time_str = kw['begin_time'].strip('"') end_time_str = kw['end_time'].strip('"') @@ -800,28 +813,39 @@ class Sf_Dashboard_Connect(http.Controller): not_done_data = [] done_data = [] final_data = {} + not_done_index = 1 + done_index = 1 for line in line_list: + + if line == '业绩总览': + work_order_domain = [('routing_type', 'in', ['人工线下加工', 'CNC加工'])] + elif line == '人工线下加工中心': + work_order_domain = [('routing_type', '=', '人工线下加工')] + else: + work_order_domain = [ + ('production_line_id.name', '=', line), + ('routing_type', '=', 'CNC加工') + ] # 未完成订单 # not_done_orders = plan_obj.search( # [('production_line_id.name', '=', line), ('state', 'not in', ['finished']), # ('production_id.state', 'not in', ['cancel', 'done']), ('active', '=', True) # ]) - not_done_orders = request.env['mrp.workorder'].sudo().search( - [('production_line_id.name', '=', line), ('state', 'in', ['ready', 'progress']), - ('routing_type', '=', 'CNC加工') - ]) + not_done_orders = work_order_obj.search(work_order_domain + + [('state', 'in', ['ready', 'progress'])], order='id asc' + ) # 完成订单 # 获取当前时间,并计算24小时前的时间 current_time = datetime.now() time_24_hours_ago = current_time - timedelta(hours=24) - finish_orders = plan_obj.search([ - ('production_line_id.name', '=', line), ('state', 'in', ['finished']), - ('production_id.state', 'not in', ['cancel']), ('active', '=', True), - ('actual_end_time', '>=', time_24_hours_ago) - ]) + finish_orders = work_order_obj.search(work_order_domain + [ + ('state', 'in', ['finished']), + ('production_id.state', 'not in', ['cancel']), + ('date_finished', '>=', time_24_hours_ago) + ], order='id asc') # print(finish_orders) # 获取所有未完成订单的ID列表 @@ -830,14 +854,14 @@ class Sf_Dashboard_Connect(http.Controller): finish_order_ids = [order.id for order in finish_orders] # 对ID进行排序 - sorted_order_ids = sorted(order_ids) + # sorted_order_ids = sorted(order_ids) - finish_sorted_order_ids = sorted(finish_order_ids) + # finish_sorted_order_ids = sorted(finish_order_ids) # 创建ID与序号的对应关系 - id_to_sequence = {order_id: index + 1 for index, order_id in enumerate(sorted_order_ids)} + # id_to_sequence = {order_id: index + 1 for index, order_id in enumerate(sorted_order_ids)} - finish_id_to_sequence = {order_id: index + 1 for index, order_id in enumerate(finish_sorted_order_ids)} + # finish_id_to_sequence = {order_id: index + 1 for index, order_id in enumerate(finish_sorted_order_ids)} # # 输出结果或进一步处理 # for order_id, sequence in id_to_sequence.items(): @@ -868,16 +892,17 @@ class Sf_Dashboard_Connect(http.Controller): } line_dict = { - 'sequence': id_to_sequence[order.id], + 'sequence': not_done_index, 'workorder_name': order.production_id.name, 'blank_name': blank_name, 'material': material, 'dimensions': dimensions, - 'order_qty': 1, + 'order_qty': order.qty_production, 'state': state_dict[order.state], } not_done_data.append(line_dict) + not_done_index += 1 for finish_order in finish_orders: if not finish_order.actual_end_time: @@ -896,17 +921,18 @@ class Sf_Dashboard_Connect(http.Controller): material = material_match.group(1) if material_match else 'No match found' line_dict = { - 'sequence': finish_id_to_sequence[finish_order.id], + 'sequence': done_index, 'workorder_name': finish_order.name, 'blank_name': blank_name, 'material': material, 'dimensions': dimensions, - 'order_qty': finish_order.product_qty, + 'order_qty': order.qty_produced, 'finish_time': finish_order.actual_end_time.strftime( '%Y-%m-%d %H:%M:%S') if finish_order.actual_end_time else ' ' } done_data.append(line_dict) + done_index += 1 # 开始包一层 res['data'][line] = {'not_done_data': not_done_data, 'done_data': done_data}