diff --git a/account_move_line_purchase_info/README.rst b/account_move_line_purchase_info/README.rst
index 93d745ea289..a72cb964d33 100644
--- a/account_move_line_purchase_info/README.rst
+++ b/account_move_line_purchase_info/README.rst
@@ -33,6 +33,13 @@ This module will add the purchase order line to journal items.
The ultimate goal is to establish the purchase order line as one of the key
fields to reconcile the Goods Received Not Invoiced accrual account.
+Field oca_purchase_line_id it's necessary. In Odoo >=16 automatic
+revaluation for a product with FIFO costing method only works if invoice
+lines related to a purchase order line do not include stock journal items.
+To avoid that oca_purchase_line_id includes invoice and stock journal items,
+and we keep Odoo field invoice_lines just with bill lines.
+- Check issue https://github.com/OCA/account-financial-tools/issues/2017
+
**Table of contents**
.. contents::
diff --git a/account_move_line_purchase_info/__manifest__.py b/account_move_line_purchase_info/__manifest__.py
index 0b5dba7c84d..6354eb111a5 100644
--- a/account_move_line_purchase_info/__manifest__.py
+++ b/account_move_line_purchase_info/__manifest__.py
@@ -5,7 +5,7 @@
{
"name": "Account Move Line Purchase Info",
"summary": "Introduces the purchase order line to the journal items",
- "version": "16.0.1.0.0",
+ "version": "16.0.2.0.0",
"author": "ForgeFlow, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/account-financial-tools",
"category": "Generic",
diff --git a/account_move_line_purchase_info/migrations/16.0.2.0.0/post-migration.py b/account_move_line_purchase_info/migrations/16.0.2.0.0/post-migration.py
new file mode 100644
index 00000000000..e07dcf83181
--- /dev/null
+++ b/account_move_line_purchase_info/migrations/16.0.2.0.0/post-migration.py
@@ -0,0 +1,34 @@
+import logging
+
+from openupgradelib import openupgrade
+
+_logger = logging.getLogger(__name__)
+
+
+@openupgrade.migrate()
+def migrate(env, version):
+ purchase_orders = env["purchase.order"].search([("state", "=", "purchase")])
+ for order in purchase_orders:
+ try:
+ _logger.info(f"Processing Purchase Order: {order.name} (ID: {order.id})")
+ valued_lines = order.order_line.invoice_lines.filtered(
+ lambda l: l.product_id
+ and l.product_id.cost_method != "standard"
+ and (
+ not l.company_id.tax_lock_date
+ or l.date > l.company_id.tax_lock_date
+ )
+ )
+ svls, _amls = valued_lines._apply_price_difference()
+
+ if svls:
+ svls._validate_accounting_entries()
+
+ bills = order.invoice_ids.filtered(lambda bill: bill.state == "posted")
+ bills._stock_account_anglo_saxon_reconcile_valuation()
+
+ except Exception as e:
+ _logger.error(
+ f"Error processing Purchase Order {order.name} (ID: {order.id}): {str(e)}",
+ exc_info=True,
+ )
diff --git a/account_move_line_purchase_info/migrations/16.0.2.0.0/pre-migration.py b/account_move_line_purchase_info/migrations/16.0.2.0.0/pre-migration.py
new file mode 100644
index 00000000000..91335613f1e
--- /dev/null
+++ b/account_move_line_purchase_info/migrations/16.0.2.0.0/pre-migration.py
@@ -0,0 +1,31 @@
+from openupgradelib import openupgrade
+
+
+@openupgrade.migrate()
+def migrate(env, version):
+ openupgrade.logged_query(
+ env.cr,
+ """
+ ALTER TABLE account_move_line
+ ADD COLUMN IF NOT EXISTS oca_purchase_line_id INTEGER;
+ """,
+ )
+
+ openupgrade.logged_query(
+ env.cr,
+ """
+ UPDATE account_move_line
+ SET oca_purchase_line_id = purchase_line_id;
+ """,
+ )
+
+ openupgrade.logged_query(
+ env.cr,
+ """
+ UPDATE account_move_line
+ SET purchase_line_id = NULL
+ FROM account_move
+ WHERE account_move_line.move_id = account_move.id
+ AND account_move.move_type = 'entry';
+ """,
+ )
diff --git a/account_move_line_purchase_info/models/account_move.py b/account_move_line_purchase_info/models/account_move.py
index b8a6e1bbebd..d952b913a26 100644
--- a/account_move_line_purchase_info/models/account_move.py
+++ b/account_move_line_purchase_info/models/account_move.py
@@ -2,14 +2,38 @@
# (https://www.forgeflow.com)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
-from odoo import fields, models
+from odoo import api, fields, models
class AccountMoveLine(models.Model):
_inherit = "account.move.line"
+ # Set related None, to make it compute and avoid base related to purchase_line_id
purchase_order_id = fields.Many2one(
comodel_name="purchase.order",
+ related=None,
store=True,
index=True,
+ compute="_compute_purchase_id",
)
+
+ oca_purchase_line_id = fields.Many2one(
+ comodel_name="purchase.order.line",
+ string="OCA Purchase Line",
+ store=True,
+ index=True,
+ compute="_compute_oca_purchase_line_id",
+ )
+
+ @api.depends("purchase_line_id")
+ def _compute_oca_purchase_line_id(self):
+ for rec in self:
+ if rec.purchase_line_id:
+ rec.oca_purchase_line_id = rec.purchase_line_id
+
+ @api.depends("purchase_line_id", "oca_purchase_line_id")
+ def _compute_purchase_id(self):
+ for rec in self:
+ rec.purchase_order_id = (
+ rec.purchase_line_id.order_id.id or rec.oca_purchase_line_id.order_id.id
+ )
diff --git a/account_move_line_purchase_info/models/purchase_order.py b/account_move_line_purchase_info/models/purchase_order.py
index 11a05644e17..ce81c60a6b5 100644
--- a/account_move_line_purchase_info/models/purchase_order.py
+++ b/account_move_line_purchase_info/models/purchase_order.py
@@ -4,12 +4,12 @@
class PurchaseOrder(models.Model):
_inherit = "purchase.order"
- @api.depends("order_line.invoice_lines.move_id")
+ @api.depends("order_line.stock_invoice_lines.move_id")
def _compute_journal_entries(self):
for order in self:
- journal_entries = order.mapped("order_line.invoice_lines.move_id").filtered(
- lambda r: r.move_type == "entry"
- )
+ journal_entries = order.mapped(
+ "order_line.stock_invoice_lines.move_id"
+ ).filtered(lambda r: r.move_type == "entry")
order.journal_entry_ids = journal_entries
order.journal_entries_count = len(journal_entries)
@@ -21,17 +21,6 @@ def _compute_journal_entries(self):
string="Journal Entries",
)
- @api.depends("order_line.invoice_lines.move_id")
- def _compute_invoice(self):
- """Overwritten compute to avoid show all Journal Entries with
- purchase_order_line as invoice_lines One2many would take them into account."""
- for order in self:
- invoices = order.order_line.invoice_lines.move_id.filtered(
- lambda m: m.is_invoice(include_receipts=True)
- )
- order.invoice_ids = invoices
- order.invoice_count = len(invoices)
-
def action_view_journal_entries(self, invoices=False):
"""This function returns an action that display existing journal entries of
given purchase order ids. When only one found, show the journal entry
diff --git a/account_move_line_purchase_info/models/purchase_order_line.py b/account_move_line_purchase_info/models/purchase_order_line.py
index 835259d2b3f..048e0500b72 100644
--- a/account_move_line_purchase_info/models/purchase_order_line.py
+++ b/account_move_line_purchase_info/models/purchase_order_line.py
@@ -1,12 +1,16 @@
# Copyright 2019-2020 ForgeFlow S.L.
# (https://www.forgeflow.com)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
-from odoo import models
+from odoo import fields, models
class PurchaseOrderLine(models.Model):
_inherit = "purchase.order.line"
+ stock_invoice_lines = fields.One2many(
+ "account.move.line", "oca_purchase_line_id", readonly=True, copy=False
+ )
+
def name_get(self):
result = []
orig_name = dict(super(PurchaseOrderLine, self).name_get())
diff --git a/account_move_line_purchase_info/models/stock_move.py b/account_move_line_purchase_info/models/stock_move.py
index f5a4841594f..041a7eadf1a 100644
--- a/account_move_line_purchase_info/models/stock_move.py
+++ b/account_move_line_purchase_info/models/stock_move.py
@@ -15,5 +15,5 @@ def _prepare_account_move_line(
qty, cost, credit_account_id, debit_account_id, svl_id, description
)
for line in res:
- line[2]["purchase_line_id"] = self.purchase_line_id.id
+ line[2]["oca_purchase_line_id"] = self.purchase_line_id.id
return res
diff --git a/account_move_line_purchase_info/readme/DESCRIPTION.rst b/account_move_line_purchase_info/readme/DESCRIPTION.rst
index feda547b9a1..ccd288542d4 100644
--- a/account_move_line_purchase_info/readme/DESCRIPTION.rst
+++ b/account_move_line_purchase_info/readme/DESCRIPTION.rst
@@ -2,3 +2,10 @@ This module will add the purchase order line to journal items.
The ultimate goal is to establish the purchase order line as one of the key
fields to reconcile the Goods Received Not Invoiced accrual account.
+
+Field oca_purchase_line_id it's necessary. In Odoo >=16 automatic
+revaluation for a product with FIFO costing method only works if invoice
+lines related to a purchase order line do not include stock journal items.
+To avoid that oca_purchase_line_id includes invoice and stock journal items,
+and we keep Odoo field invoice_lines just with bill lines.
+- Check issue https://github.com/OCA/account-financial-tools/issues/2017
diff --git a/account_move_line_purchase_info/static/description/index.html b/account_move_line_purchase_info/static/description/index.html
index 83ab814c3d8..0d0f039e4bf 100644
--- a/account_move_line_purchase_info/static/description/index.html
+++ b/account_move_line_purchase_info/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 {
@@ -373,6 +373,12 @@ Account Move Line Purchase Info
This module will add the purchase order line to journal items.
The ultimate goal is to establish the purchase order line as one of the key
fields to reconcile the Goods Received Not Invoiced accrual account.
+Field oca_purchase_line_id it’s necessary. In Odoo >=16 automatic
+revaluation for a product with FIFO costing method only works if invoice
+lines related to a purchase order line do not include stock journal items.
+To avoid that oca_purchase_line_id includes invoice and stock journal items,
+and we keep Odoo field invoice_lines just with bill lines.
+- Check issue https://github.com/OCA/account-financial-tools/issues/2017
Table of contents
@@ -423,7 +429,9 @@
This module is maintained by the OCA.
-
![Odoo Community Association](https://odoo-community.org/logo.png)
+
+
+
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.
diff --git a/account_move_line_purchase_info/tests/test_account_move_line_purchase_info.py b/account_move_line_purchase_info/tests/test_account_move_line_purchase_info.py
index 8dc0a807469..bdfaafa3371 100644
--- a/account_move_line_purchase_info/tests/test_account_move_line_purchase_info.py
+++ b/account_move_line_purchase_info/tests/test_account_move_line_purchase_info.py
@@ -153,7 +153,7 @@ def _check_account_balance(
"""
domain = [("account_id", "=", account_id)]
if purchase_line:
- domain.extend([("purchase_line_id", "=", purchase_line.id)])
+ domain.extend([("oca_purchase_line_id", "=", purchase_line.id)])
balance = self._get_balance(domain)
if purchase_line: