from odoo import models, fields, api from odoo.exceptions import UserError import traceback class QueueJob(models.Model): _name = 'queue.job' _description = 'Queueing Job Runner' _order = 'create_date desc' name = fields.Char(required=True) model_name = fields.Char(required=True) method_name = fields.Char(required=True) res_id = fields.Integer(string='Record ID') state = fields.Selection([ ('draft', 'Draft'), ('running', 'Running'), ('done', 'Done'), ('error', 'Error'), ], default='draft') error_message = fields.Text() def action_run_selected(self): for job in self: job.action_run() def action_run(self, limit=10): jobs = self.search([('state', '=', 'draft'), ('method_name', '=', 'get_order_id_and_create_detail_order')], order='create_date desc', limit=limit) if not jobs: jobs = self.search([('state', '=', 'draft'), ('method_name', '!=', 'get_order_id_and_create_detail_order')], order='create_date desc', limit=limit) for job in jobs: try: job.write({'state': 'running'}) self.env.cr.commit() record = self.env[job.model_name].browse(job.res_id) if not record.exists(): raise UserError('Target record not found') method = getattr(record, job.method_name, None) if not method: raise UserError('Method not found') with self.env.cr.savepoint(): method() job.write({'state': 'done'}) self.env.cr.commit() except Exception: job.write({ 'state': 'error', 'error_message': traceback.format_exc() }) self.env.cr.commit()