From 3ed794ec7e3e6b0d34a509714d0d03ba932a090d Mon Sep 17 00:00:00 2001
From: Eduardo De Miguel
Date: Wed, 4 Dec 2024 13:06:00 +0100
Subject: [PATCH] [MIG] account_invoice_clearing: Migration to 16.0
---
account_invoice_clearing/README.rst | 10 +-
account_invoice_clearing/__manifest__.py | 2 +-
.../static/description/index.html | 18 +--
.../tests/test_clearing_wizard.py | 47 ++++----
.../account_invoice_clearing_wizard.py | 53 ++++-----
.../account_invoice_clearing_wizard_views.xml | 106 ++++++++----------
6 files changed, 113 insertions(+), 123 deletions(-)
diff --git a/account_invoice_clearing/README.rst b/account_invoice_clearing/README.rst
index cb59b6294c6..9e00c59caa4 100644
--- a/account_invoice_clearing/README.rst
+++ b/account_invoice_clearing/README.rst
@@ -17,13 +17,13 @@ Account Invoice Clearing
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Faccount--invoicing-lightgray.png?logo=github
- :target: https://github.com/OCA/account-invoicing/tree/15.0/account_invoice_clearing
+ :target: https://github.com/OCA/account-invoicing/tree/16.0/account_invoice_clearing
:alt: OCA/account-invoicing
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
- :target: https://translation.odoo-community.org/projects/account-invoicing-15-0/account-invoicing-15-0-account_invoice_clearing
+ :target: https://translation.odoo-community.org/projects/account-invoicing-16-0/account-invoicing-16-0-account_invoice_clearing
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
- :target: https://runboat.odoo-community.org/builds?repo=OCA/account-invoicing&target_branch=15.0
+ :target: https://runboat.odoo-community.org/builds?repo=OCA/account-invoicing&target_branch=16.0
:alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5|
@@ -72,7 +72,7 @@ Bug Tracker
Bugs are tracked on `GitHub Issues `_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
-`feedback `_.
+`feedback `_.
Do not contact contributors directly about support or help with technical issues.
@@ -118,6 +118,6 @@ Current `maintainer `__:
|maintainer-Shide|
-This module is part of the `OCA/account-invoicing `_ project on GitHub.
+This module is part of the `OCA/account-invoicing `_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/account_invoice_clearing/__manifest__.py b/account_invoice_clearing/__manifest__.py
index b6986e4f74e..067bb2a12b3 100644
--- a/account_invoice_clearing/__manifest__.py
+++ b/account_invoice_clearing/__manifest__.py
@@ -4,7 +4,7 @@
{
"name": "Account Invoice Clearing",
"summary": "Account invoice clearing wizard",
- "version": "15.0.0.1.3",
+ "version": "16.0.1.0.0",
"development_status": "Alpha",
"category": "Accounting/Accounting",
"website": "https://github.com/OCA/account-invoicing",
diff --git a/account_invoice_clearing/static/description/index.html b/account_invoice_clearing/static/description/index.html
index 9d0c3e14df4..cf24010a06c 100644
--- a/account_invoice_clearing/static/description/index.html
+++ b/account_invoice_clearing/static/description/index.html
@@ -1,4 +1,3 @@
-
@@ -9,10 +8,11 @@
/*
:Author: David Goodger (goodger@python.org)
-:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $
+:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
+Despite the name, some widely supported CSS2 features are used.
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
@@ -275,7 +275,7 @@
margin-left: 2em ;
margin-right: 2em }
-pre.code .ln { color: grey; } /* line numbers */
+pre.code .ln { color: gray; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
@@ -301,7 +301,7 @@
span.pre {
white-space: pre }
-span.problematic {
+span.problematic, pre.problematic {
color: red }
span.section-subtitle {
@@ -369,7 +369,7 @@ Account Invoice Clearing
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:92e9f3c4fed7e9092315ca511cc7ec5bb4af3700968dedcaa5c9de0eff4a58cd
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
-
+
This module complements the functionality of Automatic Entries in Accounting.
It provides a Wizard to clear invoices by creating an intermediate journal entry.
It allows to clear any invoice with its opposite types. out_ types are cleared with in_ types and vice versa.
@@ -422,7 +422,7 @@
Bugs are tracked on GitHub Issues .
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
-feedback .
+feedback .
Do not contact contributors directly about support or help with technical issues.
@@ -450,13 +450,15 @@
This module is maintained by the OCA.
-
+
+
+
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
Current maintainer :
-
This module is part of the OCA/account-invoicing project on GitHub.
+
This module is part of the OCA/account-invoicing project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute .
diff --git a/account_invoice_clearing/tests/test_clearing_wizard.py b/account_invoice_clearing/tests/test_clearing_wizard.py
index 54a01cdc9e8..d3b9d16c106 100644
--- a/account_invoice_clearing/tests/test_clearing_wizard.py
+++ b/account_invoice_clearing/tests/test_clearing_wizard.py
@@ -30,42 +30,51 @@ def test_clearing_wizard(self):
"""Test clearing wizard with different move types."""
def sorted_by_sequence(lines):
- return sorted(lines, key=lambda l: l.sequence)
+ return sorted(lines, key=lambda line: line.sequence)
+ t = fields.Date.today()
+ t_5 = t + timedelta(days=5)
+ t_10 = t + timedelta(days=10)
move_types = ["out_invoice", "in_invoice"]
for init_move_type, clearing_move_type in [move_types, move_types[::-1]]:
with self.subTest(
init_move_type=init_move_type, clearing_move_type=clearing_move_type
):
init_inv = self.init_invoice(
- invoice_date=fields.Date.today(),
+ invoice_date=t,
move_type=init_move_type,
partner=self.cl_partner,
amounts=[100, 200],
post=True,
)
cl_inv_1 = self.init_invoice(
- invoice_date=fields.Date.today() + timedelta(days=5),
+ invoice_date=t_5,
move_type=clearing_move_type,
partner=self.cl_partner.child_ids[0],
amounts=[100],
- post=True,
+ post=False,
)
cl_inv_2 = self.init_invoice(
invoice_date=fields.Date.today() + timedelta(days=10),
move_type=clearing_move_type,
partner=self.cl_partner.child_ids[1],
amounts=[200],
- post=True,
+ post=False,
)
+ # Set date maturities
+ cl_inv_1.invoice_date_due = t_5
+ cl_inv_2.invoice_date_due = t_10
+ # Post clearing invoices
+ cl_inv_1.action_post()
+ cl_inv_2.action_post()
# Create wizard
cw_action = init_inv.action_open_invoice_clearing_wizard()
wizard = self.env[cw_action["res_model"]].browse(cw_action["res_id"])
# Test Action: Unlink Lines
- wizard.action_unlink_lines()
+ wizard._action_unlink_lines()
self.assertFalse(wizard.line_ids)
# Test Action: Add Lines
- wizard.action_add_lines()
+ wizard._action_add_lines()
self.assertTrue(wizard.line_ids)
# Test Action: Sort Lines by Date Due
wizard.action_sort_by_date_due_asc()
@@ -83,7 +92,7 @@ def sorted_by_sequence(lines):
self.assertTrue(slines[0].amount_residual > slines[1].amount_residual)
# Test Action: Fill Amount to Clear
wizard.action_fill_amount_to_clear()
- wizard.refresh()
+ wizard.invalidate_recordset()
self.assertTrue(
float_is_zero(
wizard.amount_to_clear,
@@ -92,7 +101,7 @@ def sorted_by_sequence(lines):
)
# Test Action: Reset Lines
wizard.action_reset_lines()
- wizard.refresh()
+ wizard.invalidate_recordset()
self.assertTrue(
not float_is_zero(
wizard.amount_to_clear,
@@ -101,37 +110,37 @@ def sorted_by_sequence(lines):
)
# Create moves
wizard.action_fill_amount_to_clear()
- wizard.refresh()
+ wizard.invalidate_recordset()
wizard.button_confirm()
self.assertEqual(init_inv.payment_state, "paid")
self.assertEqual(cl_inv_1.payment_state, "paid")
self.assertEqual(cl_inv_2.payment_state, "paid")
- def test_internal_types(self):
+ def test_account_types(self):
aicw_model = self.env["account.invoice.clearing.wizard"]
# For lines to clear
self.assertEqual(
- "payable",
- aicw_model._get_internal_type_from_move_type(
+ "liability_payable",
+ aicw_model._get_account_type_from_move_type(
"in_invoice", is_counterpart=False
),
)
self.assertEqual(
- "receivable",
- aicw_model._get_internal_type_from_move_type(
+ "asset_receivable",
+ aicw_model._get_account_type_from_move_type(
"out_invoice", is_counterpart=False
),
)
# For counterpart lines
self.assertEqual(
- "receivable",
- aicw_model._get_internal_type_from_move_type(
+ "asset_receivable",
+ aicw_model._get_account_type_from_move_type(
"in_invoice", is_counterpart=True
),
)
self.assertEqual(
- "payable",
- aicw_model._get_internal_type_from_move_type(
+ "liability_payable",
+ aicw_model._get_account_type_from_move_type(
"out_invoice", is_counterpart=True
),
)
diff --git a/account_invoice_clearing/wizards/account_invoice_clearing_wizard.py b/account_invoice_clearing/wizards/account_invoice_clearing_wizard.py
index c0581856e75..3ea18aa4faf 100644
--- a/account_invoice_clearing/wizards/account_invoice_clearing_wizard.py
+++ b/account_invoice_clearing/wizards/account_invoice_clearing_wizard.py
@@ -3,10 +3,9 @@
import json
from collections import OrderedDict
-from itertools import groupby
from odoo import _, api, exceptions, fields, models
-from odoo.tools import float_is_zero
+from odoo.tools import float_is_zero, groupby
class AccountInvoiceClearingWizard(models.TransientModel):
@@ -104,8 +103,8 @@ def default_get(self, fields):
return res
@api.model
- def _get_internal_type_from_move_type(self, move_type, is_counterpart=False):
- move_types = ["payable", "receivable"]
+ def _get_account_type_from_move_type(self, move_type, is_counterpart=False):
+ move_types = ["liability_payable", "asset_receivable"]
if is_counterpart and "refund" not in move_type:
move_types.reverse()
if move_type.startswith("out_"):
@@ -135,12 +134,12 @@ def _compute_initial_data(self):
)[0]
record.company_id = company
record.company_currency_id = company.currency_id
- internal_type = self._get_internal_type_from_move_type(record.move_type)
+ account_type = self._get_account_type_from_move_type(record.move_type)
record.move_line_ids = self.invoice_ids.mapped("line_ids").filtered(
- lambda ml: not ml.full_reconcile_id
+ lambda ml, acc_type=account_type: not ml.full_reconcile_id
and ml.balance
and ml.account_id.reconcile
- and ml.account_id.internal_type == internal_type
+ and ml.account_id.account_type == acc_type
)
@api.depends("move_line_ids", "line_ids")
@@ -233,8 +232,8 @@ def action_reopen_wizard(self):
def action_reset_lines(self):
"""Reset all lines."""
self.ensure_one()
- self.action_unlink_lines()
- self.action_add_lines()
+ self._action_unlink_lines()
+ self._action_add_lines()
return self.action_reopen_wizard()
def action_fill_amount_to_clear(self):
@@ -242,7 +241,7 @@ def action_fill_amount_to_clear(self):
self.ensure_one()
# Always inverse sign because move lines has negative residual amounts
amount_to_clear = -self.amount_to_clear
- for line in self.line_ids.filtered(lambda l: not l.amount_to_clear):
+ for line in self.line_ids.filtered(lambda line: not line.amount_to_clear):
cmp_fnc = float.__le__ if line.amount_residual < 0.0 else float.__ge__
if float_is_zero(
amount_to_clear, precision_rounding=line.company_currency_id.rounding
@@ -256,13 +255,13 @@ def action_fill_amount_to_clear(self):
amount_to_clear = 0.0
return self.action_reopen_wizard()
- def action_unlink_lines(self):
+ def _action_unlink_lines(self):
"""Unlink all lines."""
self.ensure_one()
self.line_ids = [(5, 0, 0)]
return self.action_reopen_wizard()
- def action_add_lines(self):
+ def _action_add_lines(self):
"""Add all possible lines."""
self.ensure_one()
existing_move_lines = self.line_ids.mapped("move_line_id")
@@ -281,11 +280,11 @@ def action_add_lines(self):
self.line_ids = new_lines
return self.action_reopen_wizard()
- def action_sort_by_date_due(self, reverse=False):
+ def _action_sort_by_date_due(self, reverse=False):
"""Sort lines by date due."""
self.ensure_one()
sorted_lines = self.line_ids.sorted(
- key=lambda l: l.date_maturity, reverse=reverse
+ key=lambda line: line.date_maturity, reverse=reverse
)
for seq, line in enumerate(sorted_lines, start=10):
line.sequence = seq
@@ -293,17 +292,17 @@ def action_sort_by_date_due(self, reverse=False):
def action_sort_by_date_due_asc(self):
"""Sort lines by date due ascending."""
- return self.action_sort_by_date_due(reverse=False)
+ return self._action_sort_by_date_due(reverse=False)
def action_sort_by_date_due_desc(self):
"""Sort lines by date due descending."""
- return self.action_sort_by_date_due(reverse=True)
+ return self._action_sort_by_date_due(reverse=True)
- def action_sort_by_residual(self, reverse=False):
+ def _action_sort_by_residual(self, reverse=False):
"""Sort lines by residual amount."""
self.ensure_one()
sorted_lines = self.line_ids.sorted(
- key=lambda l: l.amount_residual, reverse=reverse
+ key=lambda line: line.amount_residual, reverse=reverse
)
for seq, line in enumerate(sorted_lines, start=10):
line.sequence = seq
@@ -311,11 +310,11 @@ def action_sort_by_residual(self, reverse=False):
def action_sort_by_residual_asc(self):
"""Sort lines by residual amount ascending."""
- return self.action_sort_by_residual(reverse=False)
+ return self._action_sort_by_residual(reverse=False)
def action_sort_by_residual_desc(self):
"""Sort lines by residual amount descending."""
- return self.action_sort_by_residual(reverse=True)
+ return self._action_sort_by_residual(reverse=True)
def button_confirm(self):
"""Create the clearing move."""
@@ -379,7 +378,7 @@ def _get_move_types(self, invoices):
@api.model
def _get_available_clearing_move_lines(self, move_type, partner, move_lines):
"""Get the move lines that can be used for clearing."""
- counterpart_internal_type = self._get_internal_type_from_move_type(
+ counterpart_account_type = self._get_account_type_from_move_type(
move_type, is_counterpart=True
)
debit_credit_field = (
@@ -391,7 +390,7 @@ def _get_available_clearing_move_lines(self, move_type, partner, move_lines):
.search(
[
("id", "not in", move_lines.ids),
- ("account_id.internal_type", "=", counterpart_internal_type),
+ ("account_id.account_type", "=", counterpart_account_type),
("reconciled", "=", False),
("partner_id", "child_of", partner.id),
("parent_state", "=", "posted"),
@@ -441,7 +440,7 @@ def get_clear_sign_modifier(a, b):
return -1.0 if different_sign else 1.0
clear_lines_availability = OrderedDict()
- for cl in self.line_ids.filtered(lambda l: l.amount_to_clear):
+ for cl in self.line_ids.filtered(lambda line: line.amount_to_clear):
clear_lines_availability[cl.move_line_id] = cl.amount_to_clear
move_vals = []
@@ -598,14 +597,6 @@ class AccountInvoiceClearingLinesWizard(models.TransientModel):
related="move_line_id.product_id",
readonly=True,
)
- analytic_account_id = fields.Many2one(
- related="move_line_id.analytic_account_id",
- readonly=True,
- )
- analytic_tag_ids = fields.Many2many(
- related="move_line_id.analytic_tag_ids",
- readonly=True,
- )
amount_to_clear = fields.Monetary(
string="Clearing amount",
currency_field="company_currency_id",
diff --git a/account_invoice_clearing/wizards/account_invoice_clearing_wizard_views.xml b/account_invoice_clearing/wizards/account_invoice_clearing_wizard_views.xml
index bb6aec1df1e..d54c7713402 100644
--- a/account_invoice_clearing/wizards/account_invoice_clearing_wizard_views.xml
+++ b/account_invoice_clearing/wizards/account_invoice_clearing_wizard_views.xml
@@ -19,41 +19,51 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
-
+
-
-