feat(fusion_accounting_followup): inherit res.partner with follow-up state
Made-with: Cursor
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
'name': 'Fusion Accounting Follow-up',
|
'name': 'Fusion Accounting Follow-up',
|
||||||
'version': '19.0.1.0.8',
|
'version': '19.0.1.0.9',
|
||||||
'category': 'Accounting/Accounting',
|
'category': 'Accounting/Accounting',
|
||||||
'summary': 'AI-augmented customer follow-ups (dunning) for unpaid invoices.',
|
'summary': 'AI-augmented customer follow-ups (dunning) for unpaid invoices.',
|
||||||
'description': """
|
'description': """
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
from . import fusion_followup_level
|
from . import fusion_followup_level
|
||||||
from . import fusion_followup_run
|
from . import fusion_followup_run
|
||||||
from . import fusion_followup_text_cache
|
from . import fusion_followup_text_cache
|
||||||
|
from . import res_partner
|
||||||
|
|||||||
52
fusion_accounting_followup/models/res_partner.py
Normal file
52
fusion_accounting_followup/models/res_partner.py
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
"""Inherit res.partner: add follow-up state fields."""
|
||||||
|
|
||||||
|
from odoo import _, api, fields, models
|
||||||
|
|
||||||
|
|
||||||
|
FOLLOWUP_STATUS = [
|
||||||
|
('no_action', 'No Action Needed'),
|
||||||
|
('action_due', 'Action Due'),
|
||||||
|
('paused', 'Paused'),
|
||||||
|
('blocked', 'Blocked'),
|
||||||
|
('with_credit_team', 'With Credit Team'),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class ResPartner(models.Model):
|
||||||
|
_inherit = "res.partner"
|
||||||
|
|
||||||
|
fusion_followup_status = fields.Selection(
|
||||||
|
FOLLOWUP_STATUS, default='no_action', tracking=True,
|
||||||
|
help="Current follow-up status as computed by the engine.")
|
||||||
|
fusion_followup_paused_until = fields.Date(
|
||||||
|
tracking=True,
|
||||||
|
help="Pause follow-ups for this partner until this date.")
|
||||||
|
fusion_followup_last_level_id = fields.Many2one(
|
||||||
|
'fusion.followup.level',
|
||||||
|
help="The most-recent follow-up level this partner has been contacted at.")
|
||||||
|
fusion_followup_last_run_date = fields.Datetime(readonly=True)
|
||||||
|
fusion_followup_run_ids = fields.One2many(
|
||||||
|
'fusion.followup.run', 'partner_id', string='Follow-up History')
|
||||||
|
fusion_followup_run_count = fields.Integer(
|
||||||
|
compute='_compute_fusion_followup_run_count')
|
||||||
|
fusion_followup_risk_score = fields.Integer(
|
||||||
|
readonly=True, default=0,
|
||||||
|
help="Latest computed payment risk (0-100). Updated by cron.")
|
||||||
|
fusion_followup_risk_band = fields.Selection([
|
||||||
|
('low', 'Low'), ('medium', 'Medium'),
|
||||||
|
('high', 'High'), ('critical', 'Critical'),
|
||||||
|
], default='low', readonly=True)
|
||||||
|
|
||||||
|
def _compute_fusion_followup_run_count(self):
|
||||||
|
for partner in self:
|
||||||
|
partner.fusion_followup_run_count = len(partner.fusion_followup_run_ids)
|
||||||
|
|
||||||
|
def action_view_followup_history(self):
|
||||||
|
self.ensure_one()
|
||||||
|
return {
|
||||||
|
'type': 'ir.actions.act_window',
|
||||||
|
'res_model': 'fusion.followup.run',
|
||||||
|
'view_mode': 'list,form',
|
||||||
|
'domain': [('partner_id', '=', self.id)],
|
||||||
|
'context': {'default_partner_id': self.id},
|
||||||
|
}
|
||||||
@@ -6,3 +6,4 @@ from . import test_followup_text_generator
|
|||||||
from . import test_fusion_followup_level
|
from . import test_fusion_followup_level
|
||||||
from . import test_fusion_followup_run
|
from . import test_fusion_followup_run
|
||||||
from . import test_fusion_followup_text_cache
|
from . import test_fusion_followup_text_cache
|
||||||
|
from . import test_res_partner_inherit
|
||||||
|
|||||||
27
fusion_accounting_followup/tests/test_res_partner_inherit.py
Normal file
27
fusion_accounting_followup/tests/test_res_partner_inherit.py
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
from odoo.tests.common import TransactionCase
|
||||||
|
from odoo.tests import tagged
|
||||||
|
|
||||||
|
|
||||||
|
@tagged('post_install', '-at_install')
|
||||||
|
class TestResPartnerFollowup(TransactionCase):
|
||||||
|
|
||||||
|
def test_default_status_no_action(self):
|
||||||
|
partner = self.env['res.partner'].create({'name': 'Default Status'})
|
||||||
|
self.assertEqual(partner.fusion_followup_status, 'no_action')
|
||||||
|
self.assertEqual(partner.fusion_followup_risk_band, 'low')
|
||||||
|
self.assertEqual(partner.fusion_followup_risk_score, 0)
|
||||||
|
|
||||||
|
def test_run_count_reflects_history(self):
|
||||||
|
partner = self.env['res.partner'].create({'name': 'History Partner'})
|
||||||
|
self.assertEqual(partner.fusion_followup_run_count, 0)
|
||||||
|
for _ in range(3):
|
||||||
|
self.env['fusion.followup.run'].create({'partner_id': partner.id})
|
||||||
|
partner.invalidate_recordset(['fusion_followup_run_count', 'fusion_followup_run_ids'])
|
||||||
|
self.assertEqual(partner.fusion_followup_run_count, 3)
|
||||||
|
|
||||||
|
def test_action_view_followup_history_returns_action(self):
|
||||||
|
partner = self.env['res.partner'].create({'name': 'Action Partner'})
|
||||||
|
action = partner.action_view_followup_history()
|
||||||
|
self.assertEqual(action['res_model'], 'fusion.followup.run')
|
||||||
|
self.assertEqual(action['domain'], [('partner_id', '=', partner.id)])
|
||||||
|
self.assertEqual(action['context']['default_partner_id'], partner.id)
|
||||||
Reference in New Issue
Block a user