from odoo import models, fields from datetime import datetime, timedelta import logging, time, traceback # <-- tambah traceback _logger = logging.getLogger(__name__) class ApacheSolrQueue(models.Model): _name = 'apache.solr.queue' display_name = fields.Char('Display Name', compute="_compute_display_name") res_model = fields.Char('Resource Model') res_id = fields.Integer('Resource ID') function_name = fields.Char('Function Name') execute_status = fields.Selection([ ('success', 'Success'), ('failed', 'Failed'), ('not_found', 'Record not found') ], 'Execute Status') execute_date = fields.Datetime('Execute Date') description = fields.Text('Description') log = fields.Text('Log') def _compute_display_name(self): for rec in self: try: res_model = rec.res_model res_id = int(rec.res_id) model_instance = self.env[res_model].browse(res_id) rec.display_name = model_instance.display_name or '' except: rec.display_name = '' def process_queue_item(self, limit=100, max_exec_time=30): records = self.search([('execute_status', '=', False)], order='create_date asc', limit=limit) start_time = time.time() for rec in records: end_time = time.time() elapsed_time = end_time - start_time if elapsed_time > max_exec_time: break rec.execute_queue() def open_target_record(self): return { 'name': '', 'view_mode': 'form', 'res_model': self.res_model, 'target': 'current', 'type': 'ir.actions.act_window', 'res_id': self.res_id } def execute_queue(self): for rec in self: try: res_model = rec.res_model res_id = int(rec.res_id) function_name = rec.function_name _logger.info(f'Execute Queue: {res_model}.{function_name}() -> {res_id}') domain = [('id', '=', res_id)] model_incl_archive = ['product.template', 'promotion.program.line'] if res_model in model_incl_archive: domain.append(('active', 'in', [True, False])) model_instance = self.env[res_model].search(domain) if model_instance: getattr(model_instance, function_name)() rec.execute_status = 'success' rec.log = traceback.format_exc() else: rec.execute_status = 'not_found' except Exception as e: # simpan error ringkas + traceback lengkap rec.description = str(e) rec.log = traceback.format_exc() rec.execute_status = 'failed' rec.execute_date = datetime.utcnow() self.env.cr.commit() def create_unique(self, payload={}): count = self.search_count([ ('res_model', '=', payload['res_model']), ('res_id', '=', payload['res_id']), ('function_name', '=', payload['function_name']), ('execute_status', '=', False) ]) if count == 0: self.create(payload) def delete_weekly_solr(self, limit=500, days_after=30): solr = self.search([ ('execute_status', '=', 'success'), ('execute_date', '>=', (datetime.utcnow() - timedelta(days=days_after))), ], limit=limit) for rec in solr: rec.unlink()