92 lines
3.4 KiB
Python
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',
|
|
}
|