You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
154 lines
7.3 KiB
Python
154 lines
7.3 KiB
Python
8 months ago
|
# -*- coding: utf-8 -*-
|
||
|
from freezegun import freeze_time
|
||
|
|
||
|
from odoo import Command, fields
|
||
|
from odoo.tests import tagged
|
||
|
from odoo.addons.account.tests.common import AccountTestInvoicingCommon
|
||
|
|
||
|
|
||
|
@tagged('post_install', '-at_install')
|
||
|
class TestAccountFollowupReports(AccountTestInvoicingCommon):
|
||
|
|
||
|
@classmethod
|
||
|
def setUpClass(cls, chart_template_ref=None):
|
||
|
super().setUpClass(chart_template_ref=chart_template_ref)
|
||
|
|
||
|
cls.env['account_followup.followup.line'].search([]).unlink()
|
||
|
|
||
|
cls.first_followup_line = cls.env['account_followup.followup.line'].create({
|
||
|
'name': 'first_followup_line',
|
||
|
'delay': -10,
|
||
|
'send_email': False,
|
||
|
'company_id': cls.company_data['company'].id
|
||
|
})
|
||
|
cls.second_followup_line = cls.env['account_followup.followup.line'].create({
|
||
|
'name': 'second_followup_line',
|
||
|
'delay': 10,
|
||
|
'send_email': False,
|
||
|
'company_id': cls.company_data['company'].id
|
||
|
})
|
||
|
cls.third_followup_line = cls.env['account_followup.followup.line'].create({
|
||
|
'name': 'third_followup_line',
|
||
|
'delay': 15,
|
||
|
'send_email': False,
|
||
|
'company_id': cls.company_data['company'].id
|
||
|
})
|
||
|
|
||
|
def assertPartnerFollowup(self, partner, status, line):
|
||
|
partner.invalidate_recordset(['followup_status', 'followup_line_id'])
|
||
|
res = partner._query_followup_data()
|
||
|
self.assertEqual(res.get(partner.id, {}).get('followup_status'), status)
|
||
|
self.assertEqual(res.get(partner.id, {}).get('followup_line_id'), line.id if line else None)
|
||
|
self.assertEqual(partner.followup_status, status or 'no_action_needed')
|
||
|
self.assertEqual(partner.followup_line_id.id if partner.followup_line_id else None, line.id if line else None)
|
||
|
|
||
|
def test_followup_responsible(self):
|
||
|
"""
|
||
|
Test that the responsible is correctly set
|
||
|
"""
|
||
|
user1 = self.env['res.users'].create({
|
||
|
'name': 'A User',
|
||
|
'login': 'a_user',
|
||
|
'email': 'a@user.com',
|
||
|
'groups_id': [(6, 0, [self.env.ref('account.group_account_user').id])]
|
||
|
})
|
||
|
user2 = self.env['res.users'].create({
|
||
|
'name': 'Another User',
|
||
|
'login': 'another_user',
|
||
|
'email': 'another@user.com',
|
||
|
'groups_id': [(6, 0, [self.env.ref('account.group_account_user').id])]
|
||
|
})
|
||
|
# 1- no info, use current user
|
||
|
self.assertEqual(self.partner_a._get_followup_responsible(), self.env.user)
|
||
|
|
||
|
# 2- set invoice user
|
||
|
invoice1 = self.init_invoice('out_invoice', partner=self.partner_a,
|
||
|
invoice_date=fields.Date.from_string('2000-01-01'),
|
||
|
amounts=[2000])
|
||
|
invoice2 = self.init_invoice('out_invoice', partner=self.partner_a,
|
||
|
invoice_date=fields.Date.from_string('2000-01-01'),
|
||
|
amounts=[1000])
|
||
|
invoice1.invoice_user_id = user1
|
||
|
invoice2.invoice_user_id = user2
|
||
|
(invoice1 + invoice2).action_post()
|
||
|
# Should pick invoice_user_id of the most delayed move, with highest residual amount in case of tie (invoice1)
|
||
|
self.assertEqual(self.partner_a._get_followup_responsible(), user1)
|
||
|
|
||
|
self.partner_a.followup_line_id = self.first_followup_line
|
||
|
|
||
|
# 3- A followup responsible user has been set on the partner
|
||
|
self.partner_a.followup_responsible_id = user2
|
||
|
self.assertEqual(self.partner_a._get_followup_responsible(), user2)
|
||
|
|
||
|
# 4- Modify the default responsible on followup level
|
||
|
self.partner_a.followup_line_id.activity_default_responsible_type = 'salesperson'
|
||
|
self.assertEqual(self.partner_a._get_followup_responsible(), user1)
|
||
|
|
||
|
self.partner_a.followup_line_id.activity_default_responsible_type = 'account_manager'
|
||
|
self.partner_a.user_id = user2
|
||
|
self.assertEqual(self.partner_a._get_followup_responsible(), self.partner_a.user_id)
|
||
|
|
||
|
def test_followup_line_and_status(self):
|
||
|
invoice_1 = self.env['account.move'].create({
|
||
|
'move_type': 'out_invoice',
|
||
|
'invoice_date': '2022-01-02',
|
||
|
'partner_id': self.partner_a.id,
|
||
|
'invoice_line_ids': [Command.create({
|
||
|
'quantity': 1,
|
||
|
'price_unit': 500,
|
||
|
'tax_ids': [],
|
||
|
})]
|
||
|
})
|
||
|
invoice_1.action_post()
|
||
|
|
||
|
with freeze_time('2021-12-20'):
|
||
|
# Today < due date + delay first followup level (negative delay -> reminder before due date)
|
||
|
self.assertPartnerFollowup(self.partner_a, 'no_action_needed', None)
|
||
|
|
||
|
with freeze_time('2021-12-24'):
|
||
|
# Today = due date + delay first followup level
|
||
|
self.assertPartnerFollowup(self.partner_a, 'in_need_of_action', self.first_followup_line)
|
||
|
|
||
|
# followup_next_action_date not exceeded but no invoice is overdue,
|
||
|
# we should not be in status 'with_overdue_invoices' but 'no action needed'
|
||
|
self.partner_a.followup_next_action_date = fields.Date.from_string('2021-12-25')
|
||
|
self.assertPartnerFollowup(self.partner_a, 'no_action_needed', self.first_followup_line)
|
||
|
|
||
|
with freeze_time('2022-01-13'):
|
||
|
# Today > due date + delay second followup level but first followup level not processed yet
|
||
|
self.assertPartnerFollowup(self.partner_a, 'in_need_of_action', self.first_followup_line)
|
||
|
|
||
|
self.partner_a._execute_followup_partner()
|
||
|
# Due date exceeded but first followup level processed
|
||
|
# followup_next_action_date set in 20 days (delay 2nd level - delay 1st level = 10 - (-10) = 20)
|
||
|
self.assertPartnerFollowup(self.partner_a, 'with_overdue_invoices', self.second_followup_line)
|
||
|
self.assertEqual(self.partner_a.followup_next_action_date, fields.Date.from_string('2022-02-02'))
|
||
|
|
||
|
with freeze_time('2022-02-03'):
|
||
|
# followup_next_action_date exceeded and invoice not reconciled yet
|
||
|
self.assertPartnerFollowup(self.partner_a, 'in_need_of_action', self.second_followup_line)
|
||
|
|
||
|
# Exclude every unreconciled invoice lines
|
||
|
for aml in self.partner_a.unreconciled_aml_ids:
|
||
|
aml.blocked = True
|
||
|
# Every unreconciled invoice lines are blocked, the result from the query will be None
|
||
|
self.assertPartnerFollowup(self.partner_a, None, None)
|
||
|
|
||
|
def test_followup_contacts(self):
|
||
|
followup_contacts = self.partner_a._get_all_followup_contacts()
|
||
|
self.assertEqual(self.env['res.partner'], followup_contacts)
|
||
|
|
||
|
followup_partner_1 = self.env['res.partner'].create({
|
||
|
'name': 'followup partner 1',
|
||
|
'parent_id': self.partner_a.id,
|
||
|
'type': 'followup',
|
||
|
})
|
||
|
followup_partner_2 = self.env['res.partner'].create({
|
||
|
'name': 'followup partner 2',
|
||
|
'parent_id': self.partner_a.id,
|
||
|
'type': 'followup',
|
||
|
})
|
||
|
expected_partners = followup_partner_1 + followup_partner_2
|
||
|
followup_contacts = self.partner_a._get_all_followup_contacts()
|
||
|
self.assertEqual(expected_partners, followup_contacts)
|