Files
gsinghpal 9ebf89bde2 changes
2026-05-16 13:18:52 -04:00

92 lines
3.4 KiB
Python

"""Batch send follow-ups to selected partners (or all overdue)."""
from datetime import date
from odoo import _, api, fields, models
from odoo.exceptions import UserError
class FusionBatchFollowupWizard(models.TransientModel):
_name = "fusion.batch.followup.wizard"
_description = "Batch Send Follow-ups Wizard"
scope = fields.Selection([
('selected', 'Selected partners only'),
('all_overdue', 'All overdue partners'),
], required=True, default='selected')
partner_ids = fields.Many2many('res.partner',
default=lambda self: self._default_partner_ids())
force = fields.Boolean(string='Force (override pause + manual review)',
default=False)
auto_resolve_level = fields.Boolean(
string='Auto-resolve level',
default=True,
help="If True, engine picks the appropriate level per partner. "
"If False, use the chosen override level for all.")
override_level_id = fields.Many2one('fusion.followup.level')
# Results
state = fields.Selection([('draft', 'Draft'), ('done', 'Done')], default='draft')
sent_count = fields.Integer(readonly=True)
skipped_count = fields.Integer(readonly=True)
error_count = fields.Integer(readonly=True)
summary = fields.Text(readonly=True)
@api.model
def _default_partner_ids(self):
ctx = self.env.context
if ctx.get('active_model') == 'res.partner':
return ctx.get('active_ids', [])
return []
def action_run(self):
self.ensure_one()
if self.scope == 'selected' and not self.partner_ids:
raise UserError(_("No partners selected."))
partners = self.partner_ids
if self.scope == 'all_overdue':
Line = self.env['account.move.line'].sudo()
overdue_partner_ids = Line.search([
('parent_state', '=', 'posted'),
('account_id.account_type', '=', 'asset_receivable'),
('reconciled', '=', False),
('amount_residual', '>', 0),
('date_maturity', '<', date.today()),
('company_id', '=', self.env.company.id),
]).mapped('partner_id').ids
partners = self.env['res.partner'].sudo().browse(overdue_partner_ids)
engine = self.env['fusion.followup.engine']
sent = 0
skipped = 0
errors = []
for partner in partners:
try:
with self.env.cr.savepoint():
level = self.override_level_id if not self.auto_resolve_level else None
result = engine.send_followup_email(
partner, level=level, force=self.force)
status = result.get('status', '')
if status == 'sent':
sent += 1
else:
skipped += 1
except Exception as e:
errors.append(f"{partner.name}: {e}")
self.write({
'state': 'done',
'sent_count': sent,
'skipped_count': skipped,
'error_count': len(errors),
'summary': '\n'.join(errors[:20]) if errors else False,
})
return {
'type': 'ir.actions.act_window',
'res_model': self._name,
'res_id': self.id,
'view_mode': 'form',
'target': 'new',
}