from datetime import datetime, timedelta from odoo import models, fields, api, _ import logging, json import requests from odoo.addons.sf_base.commons.common import Common from urllib.parse import urlencode _logger = logging.getLogger(__name__) class SFMessageWork(models.Model): _name = 'mrp.workorder' _inherit = ['mrp.workorder', 'jikimo.message.dispatch'] @api.depends('production_availability', 'blocked_by_workorder_ids.state') def _compute_state(self): super(SFMessageWork, self)._compute_state() for workorder in self: if workorder.state == 'ready' and workorder.routing_type == '装夹预调': jikimo_message_queue = self.env['jikimo.message.queue'].sudo().search( [('res_id', '=', workorder.id), ("message_status", "=", "pending")]) if not jikimo_message_queue: workorder.add_queue('工单已下发通知') def _get_message(self, message_queue_ids): contents = [] product_id = [] bussiness_node = None url = self.env['ir.config_parameter'].get_param('web.base.url') current_time_strf = datetime.now().strftime("%Y-%m-%d %H:%M:%S") current_time = self.env['sf.sync.common'].sudo().get_add_time(current_time_strf) current_time_datetime = datetime.strptime(current_time, '%Y-%m-%d %H:%M:%S') time_range = timedelta(minutes=2) template_names = { '预警': ['装夹预调工单逾期预警', 'CNC加工工单逾期预警', '解除装夹工单逾期预警', '表面工艺工单逾期预警'], '已逾期': ['装夹预调工单已逾期', 'CNC加工工单已逾期', '解除装夹工单已逾期', '表面工艺工单已逾期'] } i = 0 for message_queue_id in message_queue_ids: if message_queue_id.message_template_id.name == '工单已下发通知': content = message_queue_id.message_template_id.content mrp_workorder_line = self.env['mrp.workorder'].search([('id', '=', int(message_queue_id.res_id))]) mrp_workorder_list = self.env['mrp.workorder'].search( [('product_id', '=', mrp_workorder_line.product_id.id), ('state', '=', 'ready'), ('routing_type', '=', '装夹预调')]) if len(mrp_workorder_list) > 0 and mrp_workorder_line.product_id.id not in product_id: url = self.request_url() content = content.replace('{{product_id}}', mrp_workorder_line.product_id.name).replace( '{{number}}', str(len(mrp_workorder_list))).replace( '{{request_url}}', url) product_id.append(mrp_workorder_line.product_id.id) contents.append(content) elif message_queue_id.message_template_id.name in template_names['预警'] + template_names['已逾期']: item = message_queue_id.message_template_id bussiness_node = item.bussiness_node_id.name for reminder_time in item.reminder_time_ids: content = item.content target_time = datetime.combine(current_time_datetime.date(), datetime.min.time()).replace( hour=reminder_time.time_point, minute=0, second=0, microsecond=0 ) logging.info(current_time) logging.info(target_time) logging.info(target_time - time_range) logging.info(target_time + time_range) if target_time - time_range <= current_time_datetime <= target_time + time_range: search_condition = [ ('delivery_warning', '=', 'warning')] if bussiness_node in template_names['预警'] else [ ('delivery_warning', '=', 'overdue')] record = self.sudo().search(search_condition + [('id', '=', int(item.res_id))]) if record: i += 1 if i >= 1: action_id = self.env.ref('sf_manufacturing.mrp_workorder_action_tablet').id url_with_id = f"{url}/web#view_type=list&action={action_id}" content_template = content.replace('{{url}}', url_with_id) if bussiness_node in template_names['预警']: content = content_template.replace('{{warning_num}}', str(i)) elif bussiness_node in template_names['已逾期']: content = content_template.replace('{{overdue_num}}', str(i)) contents.append(content) return contents def request_url(self): we_config_info = self.env['we.config'].sudo().search([], limit=1) redirect_domain = self.env['we.app'].sudo().search([('id', '=', we_config_info.odoo_app_id.id)]).redirect_domain full_url = 'https://%s/' % redirect_domain action_id = self.env.ref('sf_manufacturing.mrp_workorder_action_tablet').id menu_id = self.env['ir.model.data'].search([('name', '=', 'module_stock_dropshipping')]).id # 查询参数 params = {'menu_id': menu_id, 'action': action_id, 'model': 'mrp.workorder', 'view_type': 'list', 'active_id': 1} # 拼接查询参数 query_string = urlencode(params) # 拼接URL full_url = full_url + "web#" + query_string return full_url def _overdue_or_warning_func(self): workorders = self.env['mrp.workorder'].search([("state", "in", ["ready", "progress", "to be detected"])]) grouped_workorders = {} for workorder in workorders: routing_type = workorder.routing_type if routing_type not in grouped_workorders: grouped_workorders[routing_type] = [] grouped_workorders[routing_type].append(workorder) for routing_type, orders in grouped_workorders.items(): print(f"Routing Type: {routing_type}, Orders: {len(orders)}") for item in orders: if item.date_planned_finished: current_time_str = datetime.now().strftime("%Y-%m-%d %H:%M:%S") current_time_datetime = datetime.strptime(current_time_str, '%Y-%m-%d %H:%M:%S') date_planned_finished_str = self.env['sf.sync.common'].sudo().get_add_time( item.date_planned_finished.strftime("%Y-%m-%d %H:%M:%S")) date_planned_finished = datetime.strptime(date_planned_finished_str, '%Y-%m-%d %H:%M:%S') logging.info(f"Workorder: {item.production_id.name}, Current Time: {current_time_datetime}, " f"Planned Finish: {date_planned_finished}") twelve_hours_ago = current_time_datetime - timedelta(hours=12) if current_time_datetime >= date_planned_finished: item.delivery_warning = 'overdue' elif twelve_hours_ago <= current_time_datetime <= date_planned_finished: item.delivery_warning = 'warning' business_node_ids = { '装夹预调': self.env.ref('sf_message.bussiness_mrp_workorder_pre_overdue_warning').id, 'CNC加工': self.env.ref('sf_message.bussiness_mrp_workorder_cnc_overdue_warning').id, '解除装夹': self.env.ref('sf_message.bussiness_mrp_workorder_unclamp_overdue_warning').id, '表面工艺': self.env.ref('sf_message.bussiness_mrp_workorder_surface_overdue_warning').id, } message_templates = {key: self.env["jikimo.message.template"].sudo().search([ ("model", "=", self._name), ("bussiness_node_id", "=", business_node_ids[key]) ]) for key in business_node_ids} for item in orders: if item.delivery_warning in ['overdue', 'warning']: bussiness_node_id = business_node_ids.get(item.routing_type) if bussiness_node_id and message_templates[item.routing_type]: message_queue_ids = self.env["jikimo.message.queue"].sudo().search([ ("message_template_id", "=", message_templates[item.routing_type].id), ("message_status", "=", "pending"), ("res_id", "=", item.id) ]) if not message_queue_ids: overdue_message = '工单已逾期' if item.delivery_warning == 'overdue' else '工单逾期预警' queue_method_name = f'add_queue' # 构建参数列表,其中包含item.routing_type和overdue_message args = [f'{item.routing_type}{overdue_message}'] # 获取add_queue方法并调用它,传入参数列表 getattr(item, queue_method_name)(*args)