From 03112c9f78d095722e73649201db3c3f204caa55 Mon Sep 17 00:00:00 2001 From: Aungkokolin1997 Date: Fri, 22 May 2026 08:36:35 +0000 Subject: [PATCH 01/25] [DEV-456][IMP] account_billing: reflect OCA changes --- account_billing/README.rst | 16 ++-- account_billing/__manifest__.py | 2 +- account_billing/models/account_billing.py | 94 +++++++++++-------- account_billing/models/account_move.py | 18 ++-- account_billing/static/description/index.html | 28 +++--- account_billing/tests/test_account_billing.py | 49 +--------- .../views/account_billing_views.xml | 32 ++++++- 7 files changed, 126 insertions(+), 113 deletions(-) diff --git a/account_billing/README.rst b/account_billing/README.rst index 23b57f5..05a7a4f 100644 --- a/account_billing/README.rst +++ b/account_billing/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + =============== Billing Process =============== @@ -7,13 +11,13 @@ Billing Process !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:92c644c45d119de640798ae4ef9b43eb634e6b78de5811a1ac6c5f3d647499f0 + !! source digest: sha256:50d733e0ce5080841df88469b4939fc61943ac75ba37cb787877b142628c7554 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png :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 @@ -79,10 +83,10 @@ Authors Contributors ------------ -- Kitti U. -- Saran Lim. -- Rattapong Chokmasermkul -- Komsan Somwong +- Kitti U. +- Saran Lim. +- Rattapong Chokmasermkul +- Komsan Somwong Maintainers ----------- diff --git a/account_billing/__manifest__.py b/account_billing/__manifest__.py index c3bfdf3..e253f7f 100644 --- a/account_billing/__manifest__.py +++ b/account_billing/__manifest__.py @@ -4,7 +4,7 @@ { "name": "Billing Process", "summary": "Group invoice as billing before payment", - "version": "18.0.1.1.1", + "version": "18.0.1.3.0", "author": "Ecosoft, Odoo Community Association (OCA)", "license": "AGPL-3", "website": "https://github.com/OCA/account-invoicing", diff --git a/account_billing/models/account_billing.py b/account_billing/models/account_billing.py index 48891cb..2f22783 100644 --- a/account_billing/models/account_billing.py +++ b/account_billing/models/account_billing.py @@ -1,8 +1,6 @@ # Copyright 2019 Ecosoft Co., Ltd (https://ecosoft.co.th/) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) -from datetime import date - from odoo import _, api, fields, models from odoo.exceptions import UserError, ValidationError @@ -93,7 +91,7 @@ class AccountBilling(models.Model): selection=[("invoice_date_due", "Due Date"), ("invoice_date", "Invoice Date")], required=True, readonly=True, - default=lambda self: self._get_default_threshold_date_type(), + default="invoice_date_due", help="All invoices with date (threshold date type) before and equal to " "threshold date will be listed in billing lines", ) @@ -101,10 +99,26 @@ class AccountBilling(models.Model): compute="_compute_payment_paid_all", store=True, ) - - @api.model - def _get_default_threshold_date_type(self): - return "invoice_date_due" + amount_untaxed = fields.Monetary( + string="Untaxed Amount", + compute="_compute_tax_totals", + store=True, + ) + amount_tax = fields.Monetary( + string="Tax Amount", + compute="_compute_tax_totals", + store=True, + ) + amount_total = fields.Monetary( + string="Total Amount", + compute="_compute_tax_totals", + store=True, + ) + amount_total_residual = fields.Monetary( + string="Total Amount Residual", + compute="_compute_amount_total_residual", + store=True, + ) @api.depends("billing_line_ids.payment_state") def _compute_payment_paid_all(self): @@ -116,35 +130,47 @@ def _compute_payment_paid_all(self): line.payment_state == "paid" for line in rec.billing_line_ids ) + def _get_moves_domain(self, date, types=False): + return [ + ("partner_id", "=", self.partner_id.id), + ("state", "=", "posted"), + ("payment_state", "!=", "paid"), + ("currency_id", "=", self.currency_id.id), + (date, "<=", self.threshold_date), + ("move_type", "in", types), + ] + def _get_moves(self, date, types=False): - moves = self.env["account.move"].search( - [ - ("partner_id", "=", self.partner_id.id), - ("state", "=", "posted"), - ("payment_state", "!=", "paid"), - ("currency_id", "=", self.currency_id.id), - (date, "<=", self.threshold_date), - ("move_type", "in", types), - ] - ) - return moves._sort_for_billing(self.threshold_date_type) + domain = self._get_moves_domain(date, types=types) + return self.env["account.move"].search(domain) def _compute_invoice_related_count(self): self.invoice_related_count = len(self.billing_line_ids) - @api.onchange("threshold_date_type") - def _onchange_threshold_date_type(self): - self._sort_billing_lines() + @api.depends("billing_line_ids.amount_residual") + def _compute_amount_total_residual(self): + for rec in self: + rec.amount_total_residual = sum( + rec.billing_line_ids.mapped("amount_residual") + ) - def _sort_billing_lines(self): - if not self.billing_line_ids: - return - sorted_lines = self.billing_line_ids.sorted( - key=lambda x: (x.invoice_date or date.min, x.name or "", x.id) - ) - for idx, line in enumerate(sorted_lines, start=1): - line.sequence = idx * 10 - self.invalidate_recordset(["billing_line_ids"]) + @api.depends( + "billing_line_ids.move_id.amount_untaxed", "billing_line_ids.move_id.amount_tax" + ) + def _compute_tax_totals(self): + for bill in self: + bill.amount_untaxed = 0.0 + bill.amount_tax = 0.0 + bill.amount_total = 0.0 + + for line in bill.billing_line_ids: + sign = ( + -1 if line.move_id.move_type in ["out_refund", "in_refund"] else 1 + ) + bill.amount_untaxed += line.move_id.amount_untaxed * sign + bill.amount_tax += line.move_id.amount_tax * sign + + bill.amount_total = bill.amount_untaxed + bill.amount_tax def name_get(self): result = [(billing.id, (billing.name or "Draft")) for billing in self] @@ -234,15 +260,12 @@ def compute_lines(self): moves = self._get_moves(self.threshold_date_type, types) billing_line_dict = self._get_billing_line_dict(moves) self.billing_line_ids.create(billing_line_dict) - self._sort_billing_lines() class AccountBillingLine(models.Model): _name = "account.billing.line" _description = "Billing Line" - _order = "sequence, id" - sequence = fields.Integer(default=10) billing_id = fields.Many2one(comodel_name="account.billing") move_id = fields.Many2one( comodel_name="account.move", @@ -264,11 +287,6 @@ class AccountBillingLine(models.Model): state = fields.Selection(related="move_id.state") payment_state = fields.Selection(related="move_id.payment_state") - @api.depends( - "billing_id.threshold_date_type", - "move_id.invoice_date", - "move_id.invoice_date_due", - ) def _compute_invoice_date(self): for line in self: if line.billing_id.threshold_date_type == "invoice_date_due": diff --git a/account_billing/models/account_move.py b/account_billing/models/account_move.py index 690ea9b..8677ea1 100644 --- a/account_billing/models/account_move.py +++ b/account_billing/models/account_move.py @@ -8,29 +8,30 @@ class AccountMove(models.Model): _inherit = "account.move" + billing_line_ids = fields.One2many( + comodel_name="account.billing.line", + inverse_name="move_id", + string="Billing Lines", + help="Billing lines that reference this invoice", + ) billing_ids = fields.Many2many( comodel_name="account.billing", string="Billings", compute="_compute_billing_ids", + groups="account.group_account_invoice", help="Relationship between invoice and billing", ) def _compute_billing_ids(self): - bl_obj = self.env["account.billing.line"] for rec in self: - billing_lines = bl_obj.search([("move_id", "=", rec.id)]) - rec.billing_ids = billing_lines.mapped("billing_id") + rec.billing_ids = rec.billing_line_ids.mapped("billing_id") def _get_billing_type(self): outbound_types = {"out_invoice", "out_refund", "out_receipt"} move_types = set(self.mapped("move_type")) return "out_invoice" if move_types.issubset(outbound_types) else "in_invoice" - def _sort_for_billing(self, date_field): - return self.sorted(key=lambda m: (m[date_field], m.name, m.id)) - def _create_billing(self, partner): - date_field = self.env["account.billing"]._get_default_threshold_date_type() billing = self.env["account.billing"].create( { "partner_id": partner.id, @@ -46,11 +47,10 @@ def _create_billing(self, partner): * (-1 if m.move_type in ["out_refund", "in_refund"] else 1), } ) - for m in self._sort_for_billing(date_field) + for m in self ], } ) - billing._sort_billing_lines() return billing def action_create_billing(self): diff --git a/account_billing/static/description/index.html b/account_billing/static/description/index.html index 83c36ea..2bc9a2f 100644 --- a/account_billing/static/description/index.html +++ b/account_billing/static/description/index.html @@ -3,7 +3,7 @@ -Billing Process +README.rst -
-

Billing Process

+
+ + +Odoo Community Association + +
+

Billing Process

-

Beta License: AGPL-3 OCA/account-invoicing Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/account-invoicing Translate me on Weblate Try me on Runboat

In some countries, there is a customary practice for companies to collect money from their customers only once in a month. For example, the customer has 3 payments due in a given month, the vendor or billing @@ -393,7 +398,7 @@

Billing Process

-

Usage

+

Usage

To use this module, you have 2 ways:

  1. @@ -411,7 +416,7 @@

    Usage

-

Bug Tracker

+

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 @@ -419,15 +424,15 @@

Bug Tracker

Do not contact contributors directly about support or help with technical issues.

-

Credits

+

Credits

-

Authors

+

Authors

  • Ecosoft
-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -451,5 +456,6 @@

Maintainers

+
diff --git a/account_billing/tests/test_account_billing.py b/account_billing/tests/test_account_billing.py index 753c4ba..f753fa6 100644 --- a/account_billing/tests/test_account_billing.py +++ b/account_billing/tests/test_account_billing.py @@ -90,22 +90,16 @@ def create_invoice( currency_id=None, partner=None, account_id=None, - invoice_date=None, - invoice_date_due=None, ): """Returns an open invoice""" - inv_date = invoice_date or fields.Date.context_today(self.env.user) invoice = self.invoice_model.create( { "partner_id": partner or self.partner_agrolait.id, "currency_id": currency_id or self.currency_eur_id, "move_type": invoice_type, - "invoice_date": inv_date, - "date": inv_date, - "invoice_date_due": invoice_date_due, - "invoice_payment_term_id": ( - False if invoice_date_due else self.payment_term.id - ), + "invoice_date": fields.Date.context_today(self.env.user), + "date": fields.Date.context_today(self.env.user), + "invoice_payment_term_id": self.payment_term.id, "invoice_line_ids": [ Command.create( { @@ -291,40 +285,3 @@ def test_account_billing_currency(self): action = invoices.action_create_billing() customer_billing = self.billing_model.browse(action["res_id"]) self.assertEqual(customer_billing.currency_id.id, self.currency_eur_id) - - def test_sort_billing_lines(self): - inv_a = self.create_invoice( - amount=100, - invoice_date=fields.Date.from_string("2024-04-03"), - invoice_date_due=fields.Date.from_string("2024-05-04"), - ) - inv_b = self.create_invoice( - amount=200, - invoice_date=fields.Date.from_string("2024-04-01"), - invoice_date_due=fields.Date.from_string("2024-05-02"), - ) - inv_c = self.create_invoice( - amount=300, - invoice_date=fields.Date.from_string("2024-04-02"), - invoice_date_due=fields.Date.from_string("2024-05-01"), - ) - inv_d = self.create_invoice( - amount=400, - invoice_date=fields.Date.from_string("2024-04-02"), - invoice_date_due=fields.Date.from_string("2024-05-01"), - ) - invoices = inv_a + inv_b + inv_c + inv_d - action = invoices.action_create_billing() - billing = self.billing_model.browse(action["res_id"]) - self.assertEqual( - billing.billing_line_ids.mapped("move_id").ids, - (inv_c + inv_d + inv_b + inv_a).ids, - ) - - # Onchange triggers re-sort - billing.threshold_date_type = "invoice_date" - billing._onchange_threshold_date_type() - self.assertEqual( - billing.billing_line_ids.mapped("move_id").ids, - (inv_b + inv_c + inv_d + inv_a).ids, - ) diff --git a/account_billing/views/account_billing_views.xml b/account_billing/views/account_billing_views.xml index 6c8a50d..24f26e1 100644 --- a/account_billing/views/account_billing_views.xml +++ b/account_billing/views/account_billing_views.xml @@ -10,6 +10,8 @@ > + + @@ -34,6 +36,8 @@ > + + @@ -145,7 +149,6 @@ class="oe_stat_button" name="invoice_relate_billing_tree_view" type="object" - invisible="state != 'billed'" icon="fa-pencil-square-o" > - @@ -231,6 +233,32 @@ /> + + + + + + + + From 54925572d55036b4f37e0a5bdd97a585d7f85e6e Mon Sep 17 00:00:00 2001 From: Aungkokolin1997 Date: Fri, 22 May 2026 08:36:35 +0000 Subject: [PATCH 02/25] [DEV-456][IMP] account_move_order_partner: reflect OCA changes --- account_move_order_partner/README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/account_move_order_partner/README.rst b/account_move_order_partner/README.rst index 4163a3a..ec3c96a 100644 --- a/account_move_order_partner/README.rst +++ b/account_move_order_partner/README.rst @@ -75,9 +75,9 @@ Authors Contributors ------------ -- Quartile +- Quartile - - Aung Ko Ko Lin + - Aung Ko Ko Lin Maintainers ----------- From 050f532098fad27a7deac50398c48b34360e36c7 Mon Sep 17 00:00:00 2001 From: Aungkokolin1997 Date: Fri, 22 May 2026 08:36:35 +0000 Subject: [PATCH 03/25] [DEV-456][IMP] auditlog: reflect OCA changes --- auditlog/README.rst | 2 +- auditlog/__manifest__.py | 2 +- auditlog/static/description/index.html | 2 +- auditlog/tests/test_auditlog.py | 10 +++++++++- auditlog/tests/test_autovacuum.py | 3 +++ auditlog/tests/test_http.py | 6 +++++- 6 files changed, 20 insertions(+), 5 deletions(-) diff --git a/auditlog/README.rst b/auditlog/README.rst index dc4721d..4807802 100644 --- a/auditlog/README.rst +++ b/auditlog/README.rst @@ -11,7 +11,7 @@ Audit Log !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:e0e544c7a26986bb9117c221de2a8725c1ac094fd65ad0b4719fc51df383d7e2 + !! source digest: sha256:a0543c8ac1272df7c45f3f3ab1e658d0031331b342ea25d7eb5fccc3c23e05df !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/auditlog/__manifest__.py b/auditlog/__manifest__.py index a36026b..2b39101 100644 --- a/auditlog/__manifest__.py +++ b/auditlog/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Audit Log", - "version": "18.0.2.0.7", + "version": "18.0.2.0.9", "author": "ABF OSIELL, Odoo Community Association (OCA)", "license": "AGPL-3", "website": "https://github.com/OCA/server-tools", diff --git a/auditlog/static/description/index.html b/auditlog/static/description/index.html index b85c2a8..015bbbc 100644 --- a/auditlog/static/description/index.html +++ b/auditlog/static/description/index.html @@ -372,7 +372,7 @@

Audit Log

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:e0e544c7a26986bb9117c221de2a8725c1ac094fd65ad0b4719fc51df383d7e2 +!! source digest: sha256:a0543c8ac1272df7c45f3f3ab1e658d0031331b342ea25d7eb5fccc3c23e05df !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/server-tools Translate me on Weblate Try me on Runboat

This module allows the administrator to log user operations performed on diff --git a/auditlog/tests/test_auditlog.py b/auditlog/tests/test_auditlog.py index 67fea7b..ecee510 100644 --- a/auditlog/tests/test_auditlog.py +++ b/auditlog/tests/test_auditlog.py @@ -2,7 +2,7 @@ # © 2018 Pieter Paulussen # © 2021 Stefan Rijnhart # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). - +from odoo.tests import tagged from odoo.tools import mute_logger from odoo.addons.base.models.ir_model import MODULE_UNINSTALL_FLAG @@ -280,6 +280,7 @@ def test_LogDelete(self): ) +@tagged("-at_install", "post_install") class TestAuditlogFull(AuditLogRuleCommon, AuditlogCommon): @classmethod def setUpClass(cls): @@ -298,6 +299,7 @@ def setUpClass(cls): ) +@tagged("-at_install", "post_install") class TestAuditlogExportData(AuditLogRuleCommon): @classmethod def setUpClass(cls): @@ -329,6 +331,7 @@ def test_LogExport(self): self.assertIsInstance(domain[0][2], list) +@tagged("-at_install", "post_install") class TestAuditlogFast(AuditLogRuleCommon, AuditlogCommon): @classmethod def setUpClass(cls): @@ -347,6 +350,7 @@ def setUpClass(cls): ) +@tagged("-at_install", "post_install") class TestFieldRemoval(AuditLogRuleCommon): @classmethod def setUpClass(cls): @@ -444,6 +448,7 @@ def test_01_field_and_model_removal(self): self.assertFalse(self.auditlog_rule.model_id) +@tagged("-at_install", "post_install") class TestAuditlogFullCaptureRecord(AuditLogRuleCommon, AuditlogCommon): @classmethod def setUpClass(cls): @@ -463,6 +468,7 @@ def setUpClass(cls): ) +@tagged("-at_install", "post_install") class AuditLogRuleTestForUserFields(AuditLogRuleCommon): @classmethod def setUpClass(cls): @@ -647,6 +653,7 @@ def test_06_AuditlogFull_unlink_log(self): self.assertTrue(delete_log_record) +@tagged("-at_install", "post_install") class AuditLogRuleTestForUserModel(AuditLogRuleCommon): @classmethod def setUpClass(cls): @@ -723,6 +730,7 @@ def test_02_AuditlogFull_field_group_write_log(self): self.assertTrue(write_log_record) +@tagged("-at_install", "post_install") class AuditlogFast_excluded_fields(AuditLogRuleCommon): @classmethod def setUpClass(cls): diff --git a/auditlog/tests/test_autovacuum.py b/auditlog/tests/test_autovacuum.py index e483122..b8a1337 100644 --- a/auditlog/tests/test_autovacuum.py +++ b/auditlog/tests/test_autovacuum.py @@ -2,9 +2,12 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). import time +from odoo.tests import tagged + from .common import AuditLogRuleCommon +@tagged("-at_install", "post_install") class TestAuditlogAutovacuum(AuditLogRuleCommon): def setUp(self): super().setUp() diff --git a/auditlog/tests/test_http.py b/auditlog/tests/test_http.py index df31799..b1d2733 100644 --- a/auditlog/tests/test_http.py +++ b/auditlog/tests/test_http.py @@ -31,7 +31,11 @@ def test_compute_display_name(self): }, ) logs = self.env["auditlog.log"].search( - [("model_id", "=", rule.model_id.id), ("res_id", "=", partner.id)] + [ + ("model_id", "=", rule.model_id.id), + ("res_id", "=", partner.id), + ("line_ids.field_name", "=", "name"), + ] ) self.assertEqual(len(logs), 1) http_request_id = logs[0]["http_request_id"] From d1e73b84b2c773d2d7c655305cea19331c0113f7 Mon Sep 17 00:00:00 2001 From: Aungkokolin1997 Date: Fri, 22 May 2026 08:36:35 +0000 Subject: [PATCH 04/25] [DEV-456][IMP] base_user_role: reflect OCA changes --- base_user_role/README.rst | 2 +- base_user_role/__manifest__.py | 2 +- base_user_role/models/role.py | 6 +- base_user_role/models/user.py | 12 ++- base_user_role/static/description/index.html | 2 +- base_user_role/tests/test_user_role.py | 84 +++++++++++++++----- 6 files changed, 83 insertions(+), 25 deletions(-) diff --git a/base_user_role/README.rst b/base_user_role/README.rst index 6ae4a1b..ec8a516 100644 --- a/base_user_role/README.rst +++ b/base_user_role/README.rst @@ -11,7 +11,7 @@ User roles !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:b3aa00f609d45dcd82a69b2a3e13b327096ab1d25883b543e3e45538e854d40c + !! source digest: sha256:99ab17708d54615c87b2764f44327b9a8908fbf188fdcfbd80b301b453c8207a !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png diff --git a/base_user_role/__manifest__.py b/base_user_role/__manifest__.py index 1a06e06..2c70a95 100644 --- a/base_user_role/__manifest__.py +++ b/base_user_role/__manifest__.py @@ -4,7 +4,7 @@ { "name": "User roles", - "version": "18.0.1.0.5", + "version": "18.0.1.0.7", "category": "Tools", "author": "ABF OSIELL, Odoo Community Association (OCA)", "license": "LGPL-3", diff --git a/base_user_role/models/role.py b/base_user_role/models/role.py index 4cf1666..2a24197 100644 --- a/base_user_role/models/role.py +++ b/base_user_role/models/role.py @@ -21,7 +21,10 @@ class ResUsersRole(models.Model): string="Associated group", ) line_ids = fields.One2many( - comodel_name="res.users.role.line", inverse_name="role_id", string="Role lines" + comodel_name="res.users.role.line", + inverse_name="role_id", + string="Role lines", + domain=[("user_id.active", "=", True)], ) user_ids = fields.One2many( comodel_name="res.users", string="Users list", compute="_compute_user_ids" @@ -134,7 +137,6 @@ class ResUsersRoleLine(models.Model): _name = "res.users.role.line" _description = "Users associated to a role" - active = fields.Boolean(related="user_id.active") role_id = fields.Many2one( comodel_name="res.users.role", required=True, string="Role", ondelete="cascade" ) diff --git a/base_user_role/models/user.py b/base_user_role/models/user.py index d3264e5..90a759f 100644 --- a/base_user_role/models/user.py +++ b/base_user_role/models/user.py @@ -102,6 +102,16 @@ def set_groups_from_roles(self, force=False): to_remove = [(3, gr) for gr in groups_to_remove] groups = to_remove + to_add if groups: - vals = {"groups_id": groups} + # Prevent tiggering res_users_notification_type for share users + vals = {} + if ( + self.env.ref("base.group_user").id in groups_to_remove + and "notification_type" in user._fields + and user.notification_type == "inbox" + ): + vals["notification_type"] = "email" + pass + + vals["groups_id"] = groups super(ResUsers, user).write(vals) return True diff --git a/base_user_role/static/description/index.html b/base_user_role/static/description/index.html index 00038a4..4c59134 100644 --- a/base_user_role/static/description/index.html +++ b/base_user_role/static/description/index.html @@ -372,7 +372,7 @@

User roles

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:b3aa00f609d45dcd82a69b2a3e13b327096ab1d25883b543e3e45538e854d40c +!! source digest: sha256:99ab17708d54615c87b2764f44327b9a8908fbf188fdcfbd80b301b453c8207a !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Production/Stable License: LGPL-3 OCA/server-backend Translate me on Weblate Try me on Runboat

This module was written to extend the standard functionality regarding diff --git a/base_user_role/tests/test_user_role.py b/base_user_role/tests/test_user_role.py index 1033186..4b46c29 100644 --- a/base_user_role/tests/test_user_role.py +++ b/base_user_role/tests/test_user_role.py @@ -4,17 +4,16 @@ from odoo import fields from odoo.exceptions import AccessError +from odoo.fields import Command from odoo.tests import tagged -from odoo.tests.common import TransactionCase +from odoo.addons.base.tests.common import BaseCommon -class TestUserRole(TransactionCase): + +class TestUserRoleCommon(BaseCommon): @classmethod def setUpClass(cls): super().setUpClass() - cls.env = cls.env( - context=dict(cls.env.context, tracking_disable=True, no_reset_password=True) - ) cls.user_model = cls.env["res.users"] cls.role_model = cls.env["res.users.role"] cls.wiz_model = cls.env["wizard.groups.into.role"] @@ -59,7 +58,7 @@ def setUpClass(cls): # Setup for multi-company testing cls.multicompany_user_1 = cls.user_model.create( { - "name": "User 2", + "name": "multicompany_user_1", "company_id": cls.company1.id, "company_ids": [(6, 0, [cls.company1.id, cls.company2.id])], "groups_id": [(6, 0, cls.env.ref("base.group_erp_manager").ids)], @@ -68,7 +67,7 @@ def setUpClass(cls): ) cls.multicompany_user_2 = cls.user_model.create( { - "name": "User 2", + "name": "multicompany_user_2", "company_id": cls.company2.id, "company_ids": [(6, 0, [cls.company2.id])], "groups_id": [(6, 0, cls.env.ref("base.group_user").ids)], @@ -83,6 +82,8 @@ def setUpClass(cls): } ) + +class TestUserRole(TestUserRoleCommon): def test_role_1(self): self.user_id.write({"role_line_ids": [(0, 0, {"role_id": self.role1_id.id})]}) user_group_ids = sorted({group.id for group in self.user_id.groups_id}) @@ -232,18 +233,6 @@ def test_role_multicompany(self): ): role.read() - @tagged("-at_install", "post_install") - def test_notification_type_not_reset(self): - """Test that roles don't reset notification settings.""" - if self.env["ir.module.module"]._get("mail").state != "installed": - self.skipTest("Mail module is not installed.") - notification_group = self.env.ref("mail.group_mail_notification_type_inbox") - self.assertNotIn(notification_group, self.user_id.groups_id) - self.user_id.notification_type = "inbox" - self.assertIn(notification_group, self.user_id.groups_id) - self.user_id.write({"role_line_ids": [(0, 0, {"role_id": self.role1_id.id})]}) - self.assertIn(notification_group, self.user_id.groups_id) - def test_create_role_from_user(self): # Use a wizard instance to create a new role based on the user. # We use assign_to_user = False, as otherwise this module forcibly @@ -287,3 +276,60 @@ def test_group_groups_into_role(self): self.assertEqual(new_role.name, "Test Role") # Check that the role has the correct groups (even if the order is not equal) self.assertEqual(set(new_role.implied_ids.ids), set(user_group_ids)) + + +@tagged("post_install", "-at_install") +class TestUserRoleMail(TestUserRoleCommon): + def test_notification_type_not_reset(self): + """Test that roles don't reset notification settings.""" + if self.env["ir.module.module"]._get("mail").state != "installed": + self.skipTest("Mail module is not installed.") + notification_group = self.env.ref("mail.group_mail_notification_type_inbox") + self.assertNotIn(notification_group, self.user_id.groups_id) + self.user_id.notification_type = "inbox" + self.assertIn(notification_group, self.user_id.groups_id) + self.user_id.write( + {"role_line_ids": [Command.create({"role_id": self.role1_id.id})]} + ) + self.assertIn(notification_group, self.user_id.groups_id) + + def test_notification_type_reset(self): + """When user is demoted to share user, update notification settings. + + The issue only occurs when the writing user is not the superuser, and + if an intermittent flush is triggered by for instance + `_check_one_user_type` in website's res.users override. This triggers + constraint res_users_notification_type as Odoo has not yet recomputed + this at that point. + """ + # Notification settings depend on mail being installed + if self.env["ir.module.module"]._get("mail").state != "installed": + self.skipTest("Mail module is not installed.") + + # Set up a non-superuser user + admin_user = self.env["res.users"].create( + { + "name": "Some admin", + "login": "admin@example.com", + }, + ) + admin_user.groups_id += self.env.ref("base.group_system") + + self.user_id.write( + { + "role_line_ids": [Command.create({"role_id": self.role1_id.id})], + "notification_type": "inbox", + }, + ) + + # As non-superuser, delete all roles from the user + user = self.user_id.with_user(admin_user) + user.write( + { + "role_line_ids": [ + Command.delete(rl.id) for rl in self.user_id.role_line_ids + ], + }, + ) + # Database constraint has not been triggered + self.assertEqual(user.notification_type, "email") From 7720ebca352789e20f5d4e777b9ac081f6b943fc Mon Sep 17 00:00:00 2001 From: Aungkokolin1997 Date: Fri, 22 May 2026 08:36:35 +0000 Subject: [PATCH 05/25] [DEV-456][IMP] l10n_jp_country_state: reflect OCA changes --- l10n_jp_country_state/README.rst | 11 ++- l10n_jp_country_state/__manifest__.py | 5 +- .../data/res.country.state.csv | 48 +++++++++ l10n_jp_country_state/i18n_extra/ja.po | 99 +++++++++---------- l10n_jp_country_state/readme/DESCRIPTION.md | 8 +- .../static/description/index.html | 11 ++- 6 files changed, 123 insertions(+), 59 deletions(-) create mode 100644 l10n_jp_country_state/data/res.country.state.csv diff --git a/l10n_jp_country_state/README.rst b/l10n_jp_country_state/README.rst index 782254a..3ba94e6 100644 --- a/l10n_jp_country_state/README.rst +++ b/l10n_jp_country_state/README.rst @@ -11,7 +11,7 @@ Japan Country States !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:b2117b837ac8bdbe84219bddad8c240ef6346fd60db9ee433b30c864a8e1380f + !! source digest: sha256:58dad6de76321726c50c6e037797585b0718dd19ac54915f6634338cc60222f4 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png @@ -32,8 +32,13 @@ Japan Country States |badge1| |badge2| |badge3| |badge4| |badge5| -This module only adds translations to country state records for Japan, -for the sake of convenience. +As of Odoo 17, the Japan prefecture (``res.country.state``) records are +shipped with their native Japanese names (e.g. ``東京都``, ``北海道``) +as the source value. This module overrides those records to use English +names (e.g. ``Tokyo``, ``Hokkaido``) as the source and provides Japanese +translations, so users with ``ja_JP`` selected continue to see the +native prefecture names while other users see the romanized English +names. **Table of contents** diff --git a/l10n_jp_country_state/__manifest__.py b/l10n_jp_country_state/__manifest__.py index db1b43b..598a39e 100644 --- a/l10n_jp_country_state/__manifest__.py +++ b/l10n_jp_country_state/__manifest__.py @@ -2,11 +2,14 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). { "name": "Japan Country States", - "version": "18.0.1.0.0", + "version": "18.0.1.1.0", "depends": ["base_country_state_translatable"], "author": "Quartile, Odoo Community Association (OCA)", "license": "AGPL-3", "website": "https://github.com/OCA/l10n-japan", "category": "Localization", + "data": [ + "data/res.country.state.csv", + ], "installable": True, } diff --git a/l10n_jp_country_state/data/res.country.state.csv b/l10n_jp_country_state/data/res.country.state.csv new file mode 100644 index 0000000..b506141 --- /dev/null +++ b/l10n_jp_country_state/data/res.country.state.csv @@ -0,0 +1,48 @@ +id,name +base.state_jp_jp-01,"Hokkaido" +base.state_jp_jp-02,"Aomori" +base.state_jp_jp-03,"Iwate" +base.state_jp_jp-04,"Miyagi" +base.state_jp_jp-05,"Akita" +base.state_jp_jp-06,"Yamagata" +base.state_jp_jp-07,"Fukushima" +base.state_jp_jp-08,"Ibaraki" +base.state_jp_jp-09,"Tochigi" +base.state_jp_jp-10,"Gunma" +base.state_jp_jp-11,"Saitama" +base.state_jp_jp-12,"Chiba" +base.state_jp_jp-13,"Tokyo" +base.state_jp_jp-14,"Kanagawa" +base.state_jp_jp-15,"Niigata" +base.state_jp_jp-16,"Toyama" +base.state_jp_jp-17,"Ishikawa" +base.state_jp_jp-18,"Fukui" +base.state_jp_jp-19,"Yamanashi" +base.state_jp_jp-20,"Nagano" +base.state_jp_jp-21,"Gifu" +base.state_jp_jp-22,"Shizuoka" +base.state_jp_jp-23,"Aichi" +base.state_jp_jp-24,"Mie" +base.state_jp_jp-25,"Shiga" +base.state_jp_jp-26,"Kyoto" +base.state_jp_jp-27,"Osaka" +base.state_jp_jp-28,"Hyogo" +base.state_jp_jp-29,"Nara" +base.state_jp_jp-30,"Wakayama" +base.state_jp_jp-31,"Tottori" +base.state_jp_jp-32,"Shimane" +base.state_jp_jp-33,"Okayama" +base.state_jp_jp-34,"Hiroshima" +base.state_jp_jp-35,"Yamaguchi" +base.state_jp_jp-36,"Tokushima" +base.state_jp_jp-37,"Kagawa" +base.state_jp_jp-38,"Ehime" +base.state_jp_jp-39,"Kochi" +base.state_jp_jp-40,"Fukuoka" +base.state_jp_jp-41,"Saga" +base.state_jp_jp-42,"Nagasaki" +base.state_jp_jp-43,"Kumamoto" +base.state_jp_jp-44,"Oita" +base.state_jp_jp-45,"Miyazaki" +base.state_jp_jp-46,"Kagoshima" +base.state_jp_jp-47,"Okinawa" diff --git a/l10n_jp_country_state/i18n_extra/ja.po b/l10n_jp_country_state/i18n_extra/ja.po index f8bfa5c..a043e48 100644 --- a/l10n_jp_country_state/i18n_extra/ja.po +++ b/l10n_jp_country_state/i18n_extra/ja.po @@ -1,12 +1,11 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: +# * l10n_jp_country_state # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 18.0+e\n" +"Project-Id-Version: Odoo Server 17.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-06-06 06:15+0000\n" -"PO-Revision-Date: 2025-06-06 06:15+0000\n" "Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -14,237 +13,237 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: \n" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-01 msgid "Hokkaido" msgstr "北海道" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-02 msgid "Aomori" msgstr "青森県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-03 msgid "Iwate" msgstr "岩手県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-04 msgid "Miyagi" msgstr "宮城県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-05 msgid "Akita" msgstr "秋田県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-06 msgid "Yamagata" msgstr "山形県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-07 msgid "Fukushima" msgstr "福島県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-08 msgid "Ibaraki" msgstr "茨城県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-09 msgid "Tochigi" msgstr "栃木県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-10 msgid "Gunma" msgstr "群馬県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-11 msgid "Saitama" msgstr "埼玉県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-12 msgid "Chiba" msgstr "千葉県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-13 msgid "Tokyo" msgstr "東京都" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-14 msgid "Kanagawa" msgstr "神奈川県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-15 msgid "Niigata" msgstr "新潟県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-16 msgid "Toyama" msgstr "富山県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-17 msgid "Ishikawa" msgstr "石川県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-18 msgid "Fukui" msgstr "福井県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-19 msgid "Yamanashi" msgstr "山梨県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-20 msgid "Nagano" msgstr "長野県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-21 msgid "Gifu" msgstr "岐阜県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-22 msgid "Shizuoka" msgstr "静岡県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-23 msgid "Aichi" msgstr "愛知県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-24 msgid "Mie" msgstr "三重県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-25 msgid "Shiga" msgstr "滋賀県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-26 msgid "Kyoto" msgstr "京都府" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-27 msgid "Osaka" msgstr "大阪府" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-28 msgid "Hyogo" msgstr "兵庫県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-29 msgid "Nara" msgstr "奈良県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-30 msgid "Wakayama" msgstr "和歌山県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-31 msgid "Tottori" msgstr "鳥取県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-32 msgid "Shimane" msgstr "島根県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-33 msgid "Okayama" msgstr "岡山県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-34 msgid "Hiroshima" msgstr "広島県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-35 msgid "Yamaguchi" msgstr "山口県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-36 msgid "Tokushima" msgstr "徳島県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-37 msgid "Kagawa" msgstr "香川県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-38 msgid "Ehime" msgstr "愛媛県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-39 msgid "Kochi" msgstr "高知県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-40 msgid "Fukuoka" msgstr "福岡県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-41 msgid "Saga" msgstr "佐賀県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-42 msgid "Nagasaki" msgstr "長崎県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-43 msgid "Kumamoto" msgstr "熊本県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-44 msgid "Oita" msgstr "大分県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-45 msgid "Miyazaki" msgstr "宮崎県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-46 msgid "Kagoshima" msgstr "鹿児島県" -#. module: base +#. module: l10n_jp_country_state #: model:res.country.state,name:base.state_jp_jp-47 msgid "Okinawa" msgstr "沖縄県" diff --git a/l10n_jp_country_state/readme/DESCRIPTION.md b/l10n_jp_country_state/readme/DESCRIPTION.md index 24b8c64..cd5d653 100644 --- a/l10n_jp_country_state/readme/DESCRIPTION.md +++ b/l10n_jp_country_state/readme/DESCRIPTION.md @@ -1,2 +1,6 @@ -This module only adds translations to country state records for Japan, -for the sake of convenience. +As of Odoo 17, the Japan prefecture (`res.country.state`) records are +shipped with their native Japanese names (e.g. `東京都`, `北海道`) as the +source value. This module overrides those records to use English names +(e.g. `Tokyo`, `Hokkaido`) as the source and provides Japanese +translations, so users with `ja_JP` selected continue to see the native +prefecture names while other users see the romanized English names. diff --git a/l10n_jp_country_state/static/description/index.html b/l10n_jp_country_state/static/description/index.html index 41a220f..c9d0da7 100644 --- a/l10n_jp_country_state/static/description/index.html +++ b/l10n_jp_country_state/static/description/index.html @@ -372,11 +372,16 @@

Japan Country States

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:b2117b837ac8bdbe84219bddad8c240ef6346fd60db9ee433b30c864a8e1380f +!! source digest: sha256:58dad6de76321726c50c6e037797585b0718dd19ac54915f6634338cc60222f4 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/l10n-japan Translate me on Weblate Try me on Runboat

-

This module only adds translations to country state records for Japan, -for the sake of convenience.

+

As of Odoo 17, the Japan prefecture (res.country.state) records are +shipped with their native Japanese names (e.g. 東京都, 北海道) +as the source value. This module overrides those records to use English +names (e.g. Tokyo, Hokkaido) as the source and provides Japanese +translations, so users with ja_JP selected continue to see the +native prefecture names while other users see the romanized English +names.

Table of contents

    From 9cb9fdcb5b45e87e98d37187d3a1f67cf4c76c29 Mon Sep 17 00:00:00 2001 From: Aungkokolin1997 Date: Fri, 22 May 2026 08:36:35 +0000 Subject: [PATCH 06/25] [DEV-456][IMP] l10n_jp_summary_invoice: reflect OCA changes --- l10n_jp_summary_invoice/README.rst | 49 +++++++++++-------- l10n_jp_summary_invoice/__manifest__.py | 2 +- .../models/account_billing.py | 3 ++ .../models/account_move.py | 6 --- .../report_summary_invoice_templates.xml | 3 ++ .../static/description/index.html | 38 ++++++++------ .../tests/test_l10n_jp_summary_invoice.py | 26 +++++----- .../views/account_billing_views.xml | 1 + 8 files changed, 71 insertions(+), 57 deletions(-) diff --git a/l10n_jp_summary_invoice/README.rst b/l10n_jp_summary_invoice/README.rst index 230aae7..690f4c9 100644 --- a/l10n_jp_summary_invoice/README.rst +++ b/l10n_jp_summary_invoice/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ===================== Japan Summary Invoice ===================== @@ -7,13 +11,13 @@ Japan Summary Invoice !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:e6e9907d975dd745a0204630a2c47c0952c4dde7c5df8e7f06ee5fc94e1d361b + !! source digest: sha256:383b2c659d9ba8cabd01df1832910525f2878f0f18964c4d6023edee29c57747 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png :target: https://odoo-community.org/page/development-status :alt: Alpha -.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fl10n--japan-lightgray.png?logo=github @@ -52,19 +56,19 @@ Configuration Go to *Invoicing/Accounting > Configuration > Settings* and update the following settings as necessary: -- **Summary Invoice Remark**: The remark that shows in the header part - of the summary invoice, such as '下記の通り御請求申し上げます。'. -- **Show Sales Order Number**: If selected, the sales order number will - be shown for each line in the summary invoice. -- **Show Invoice Narration**: If selected, the narration will appear - for each invoice in the summary invoice report. -- **Show Invoice Total Amount**: If selected, the total amount per - invoice will appear in the summary invoice report. +- **Summary Invoice Remark**: The remark that shows in the header part + of the summary invoice, such as '下記の通り御請求申し上げます。'. +- **Show Sales Order Number**: If selected, the sales order number will + be shown for each line in the summary invoice. +- **Show Invoice Narration**: If selected, the narration will appear for + each invoice in the summary invoice report. +- **Show Invoice Total Amount**: If selected, the total amount per + invoice will appear in the summary invoice report. To exclude billing for invoices created for a particular partner: -- Go to Contacts and select the partner. -- In the Invoicing (or Accounting) tab, enable 'Is Not For Billing'. +- Go to Contacts and select the partner. +- In the Invoicing (or Accounting) tab, enable 'Is Not For Billing'. Usage ===== @@ -72,12 +76,15 @@ Usage 1. Create a billing for customer invoices using the functionality of the account_billing module, and make adjustments as necessary. - - **Remit-to Bank**: If not selected, the bank account related to - the company with the smallest sequence will show in the printed - document. - - **Due Date**: The earliest due date among the selected invoices - will be proposed. Adjust this as necessary as it will show in the - printed document. + - **Remit-to Bank**: If not selected, the bank account related to the + company with the smallest sequence will show in the printed + document. + - **Due Date**: The earliest due date among the selected invoices + will be proposed. Adjust this as necessary as it will show in the + printed document. + - **Exclude invoices from billing**: On each invoice form, you can + check the "Is not for billing" field in the Billing tab to exclude + specific invoices from the billing process. 2. Validate the billing. An invoice for tax adjustment will be created automatically in case the recalculated tax amount is different from @@ -106,10 +113,10 @@ Authors Contributors ------------ -- `Quartile `__: +- `Quartile `__: - - Aung Ko Ko Lin - - Yoshi Tashiro + - Aung Ko Ko Lin + - Yoshi Tashiro Maintainers ----------- diff --git a/l10n_jp_summary_invoice/__manifest__.py b/l10n_jp_summary_invoice/__manifest__.py index 980247e..b253bb7 100644 --- a/l10n_jp_summary_invoice/__manifest__.py +++ b/l10n_jp_summary_invoice/__manifest__.py @@ -2,7 +2,7 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). { "name": "Japan Summary Invoice", - "version": "18.0.1.1.1", + "version": "18.0.1.5.0", "category": "Japanese Localization", "author": "Quartile, Odoo Community Association (OCA)", "website": "https://github.com/OCA/l10n-japan", diff --git a/l10n_jp_summary_invoice/models/account_billing.py b/l10n_jp_summary_invoice/models/account_billing.py index 295e4d6..cd3dde7 100644 --- a/l10n_jp_summary_invoice/models/account_billing.py +++ b/l10n_jp_summary_invoice/models/account_billing.py @@ -49,6 +49,9 @@ class AccountBilling(models.Model): help="If not specified, the first bank account linked to the company will show " "in the report.", ) + report_subtitle = fields.Char( + help="Subtitle to be printed below the title of the summary invoice report.", + ) @api.constrains("state", "billing_line_ids") def _check_account_move_billability(self): diff --git a/l10n_jp_summary_invoice/models/account_move.py b/l10n_jp_summary_invoice/models/account_move.py index 30ee6e6..3097b68 100644 --- a/l10n_jp_summary_invoice/models/account_move.py +++ b/l10n_jp_summary_invoice/models/account_move.py @@ -14,12 +14,6 @@ class AccountMove(models.Model): readonly=False, help="If selected, the invoice is excluded from the billing process.", ) - # TODO: This field should be moved to account_billing module. - billing_line_ids = fields.One2many( - comodel_name="account.billing.line", - inverse_name="move_id", - string="Billing Lines", - ) billing_id = fields.Many2one( comodel_name="account.billing", compute="_compute_billing_id", diff --git a/l10n_jp_summary_invoice/reports/report_summary_invoice_templates.xml b/l10n_jp_summary_invoice/reports/report_summary_invoice_templates.xml index c6a489d..9485d1b 100644 --- a/l10n_jp_summary_invoice/reports/report_summary_invoice_templates.xml +++ b/l10n_jp_summary_invoice/reports/report_summary_invoice_templates.xml @@ -151,6 +151,9 @@ >Cancelled Summary Invoice +

    + +

    diff --git a/l10n_jp_summary_invoice/static/description/index.html b/l10n_jp_summary_invoice/static/description/index.html index b636a6d..20f75a9 100644 --- a/l10n_jp_summary_invoice/static/description/index.html +++ b/l10n_jp_summary_invoice/static/description/index.html @@ -3,7 +3,7 @@ -Japan Summary Invoice +README.rst -
    -

    Japan Summary Invoice

    +
    + + +Odoo Community Association + +
    +

    Japan Summary Invoice

    -

    Alpha License: AGPL-3 OCA/l10n-japan Translate me on Weblate Try me on Runboat

    +

    Alpha License: AGPL-3 OCA/l10n-japan Translate me on Weblate Try me on Runboat

    This module adds a summary invoice report print functionality based on the account_billing module.

    The printed summary invoice is intended to serve as the Qualified Tax @@ -397,7 +402,7 @@

    Japan Summary Invoice

-

Configuration

+

Configuration

Go to Invoicing/Accounting > Configuration > Settings and update the following settings as necessary:

    @@ -405,8 +410,8 @@

    Configuration

    of the summary invoice, such as ‘下記の通り御請求申し上げます。’.
  • Show Sales Order Number: If selected, the sales order number will be shown for each line in the summary invoice.
  • -
  • Show Invoice Narration: If selected, the narration will appear -for each invoice in the summary invoice report.
  • +
  • Show Invoice Narration: If selected, the narration will appear for +each invoice in the summary invoice report.
  • Show Invoice Total Amount: If selected, the total amount per invoice will appear in the summary invoice report.
@@ -417,12 +422,12 @@

Configuration

-

Usage

+

Usage

  1. Create a billing for customer invoices using the functionality of the account_billing module, and make adjustments as necessary.
      -
    • Remit-to Bank: If not selected, the bank account related to -the company with the smallest sequence will show in the printed +
    • Remit-to Bank: If not selected, the bank account related to the +company with the smallest sequence will show in the printed document.
    • Due Date: The earliest due date among the selected invoices will be proposed. Adjust this as necessary as it will show in the @@ -440,7 +445,7 @@

      Usage

-

Bug Tracker

+

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 @@ -448,15 +453,15 @@

Bug Tracker

Do not contact contributors directly about support or help with technical issues.

-

Credits

+

Credits

-

Authors

+

Authors

  • Quartile
-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -479,5 +484,6 @@

Maintainers

+ diff --git a/l10n_jp_summary_invoice/tests/test_l10n_jp_summary_invoice.py b/l10n_jp_summary_invoice/tests/test_l10n_jp_summary_invoice.py index 0525903..13b7e37 100644 --- a/l10n_jp_summary_invoice/tests/test_l10n_jp_summary_invoice.py +++ b/l10n_jp_summary_invoice/tests/test_l10n_jp_summary_invoice.py @@ -241,19 +241,6 @@ def test_create_tax_adjustment_entry_child_partner(self): billing.with_company(self.company).validate_billing() self.assertTrue(billing.tax_adjustment_entry_id) - def test_is_not_for_billing(self): - self.partner.is_not_for_billing = True - invoice = self._create_invoice(50, self.tax_10) - invoice = invoice.with_context(skip_readonly_check=True) - self.assertTrue(invoice.is_not_for_billing) - partner_2 = self.env["res.partner"].create({"name": "Test Partner 2"}) - invoice.partner_id = partner_2 - self.assertFalse(invoice.is_not_for_billing) - partner_2.is_not_for_billing = True - self.assertFalse(invoice.is_not_for_billing) - invoice.partner_id = self.partner - self.assertTrue(invoice.is_not_for_billing) - def test_compute_billing_id(self): inv1 = self._create_invoice(100, self.tax_10) inv2 = self._create_invoice(200, self.tax_10) @@ -301,3 +288,16 @@ def test_check_tax_adjustment_with_currency_rounding_issue(self): billing.with_company(self.company).validate_billing() self.assertEqual(billing.state, "billed") self.assertFalse(billing.tax_adjustment_entry_id) + + def test_is_not_for_billing(self): + self.partner.is_not_for_billing = True + invoice = self._create_invoice(50, self.tax_10) + invoice = invoice.with_context(skip_readonly_check=True) + self.assertTrue(invoice.is_not_for_billing) + partner_2 = self.env["res.partner"].create({"name": "Test Partner 2"}) + invoice.partner_id = partner_2 + self.assertFalse(invoice.is_not_for_billing) + partner_2.is_not_for_billing = True + self.assertFalse(invoice.is_not_for_billing) + invoice.partner_id = self.partner + self.assertTrue(invoice.is_not_for_billing) diff --git a/l10n_jp_summary_invoice/views/account_billing_views.xml b/l10n_jp_summary_invoice/views/account_billing_views.xml index dcda96d..8a39ad6 100644 --- a/l10n_jp_summary_invoice/views/account_billing_views.xml +++ b/l10n_jp_summary_invoice/views/account_billing_views.xml @@ -52,6 +52,7 @@ + From befc1665e1d0a204855af7ad75f1fc6584383bb8 Mon Sep 17 00:00:00 2001 From: Aungkokolin1997 Date: Fri, 22 May 2026 08:36:35 +0000 Subject: [PATCH 07/25] [DEV-456][IMP] mail_layout_force: reflect OCA changes --- mail_layout_force/README.rst | 42 ++++++++++--------- .../static/description/index.html | 28 ++++++++----- 2 files changed, 40 insertions(+), 30 deletions(-) diff --git a/mail_layout_force/README.rst b/mail_layout_force/README.rst index 47f0167..aa5b2c9 100644 --- a/mail_layout_force/README.rst +++ b/mail_layout_force/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ================= Mail Layout Force ================= @@ -7,13 +11,13 @@ Mail Layout Force !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:988dd474248a3c1d5cf299ddbbe938b3706c0ebaca05219cede46dc6a2eed89a + !! source digest: sha256:baadb7cfc76ac450e9fdd0b52f04a5ea57a275da88e050ae8ad80ffdbb90bb6e !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fmail-lightgray.png?logo=github @@ -39,9 +43,9 @@ There are notably three main layouts used in Odoo, and the user can't control when they're used, as it's hardcoded into the different applications. -- ``mail.mail_notification_layout`` -- ``mail.mail_notification_layout_with_responsible_signature`` -- ``mail.mail_notification_light`` +- ``mail.mail_notification_layout`` +- ``mail.mail_notification_layout_with_responsible_signature`` +- ``mail.mail_notification_light`` This module allows to force a specific layout for a given ``email.template``, effectively overwriting the one hardcoded by Odoo. @@ -74,9 +78,9 @@ To configure a custom layout of your own, some technical knowledge is needed. You can see how the existing layouts are defined for details or inspiration: -- ``mail.mail_notification_layout`` -- ``mail.mail_notification_layout_with_responsible_signature`` -- ``mail.mail_notification_light`` +- ``mail.mail_notification_layout`` +- ``mail.mail_notification_layout_with_responsible_signature`` +- ``mail.mail_notification_light`` To force a custom layout for emails that do not use an existing ``email.template`` record (e.g., emails sent from the chatter) or for @@ -91,11 +95,11 @@ opening the mail composer (e.g., invoice send actions like 3. Open the original layout view that you want to replace. Under the *Layout Mapping* tab: - - Click *Add a line* - - Set *Substitute Layout* to the new custom layout you created - - Set *Models* if you want to apply the replacement only to specific - models. If left empty, the email layout will be replaced for all - models + - Click *Add a line* + - Set *Substitute Layout* to the new custom layout you created + - Set *Models* if you want to apply the replacement only to specific + models. If left empty, the email layout will be replaced for all + models Bug Tracker =========== @@ -118,16 +122,16 @@ Authors Contributors ------------ -- ``Camptocamp ``\ \_ +- ``Camptocamp ``\ \_ - - Iván Todorovich ivan.todorovich@camptocamp.com + - Iván Todorovich ivan.todorovich@camptocamp.com -- Abraham Anes abrahamanes@gmail.com +- Abraham Anes abrahamanes@gmail.com -- ``Quartile ``\ \_ +- ``Quartile ``\ \_ - - Aung Ko Ko Lin - - Yoshi Tashiro + - Aung Ko Ko Lin + - Yoshi Tashiro Maintainers ----------- diff --git a/mail_layout_force/static/description/index.html b/mail_layout_force/static/description/index.html index a06a634..bee82b7 100644 --- a/mail_layout_force/static/description/index.html +++ b/mail_layout_force/static/description/index.html @@ -3,7 +3,7 @@ -Mail Layout Force +README.rst -
-

Mail Layout Force

+
+ + +Odoo Community Association + +
+

Mail Layout Force

-

Beta License: AGPL-3 OCA/mail Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/mail Translate me on Weblate Try me on Runboat

Odoo will add a default email layout on most commercial communications.

The email layout is a QWeb view that ends up wrapping the message body when sending an email. It usually displays the related document @@ -404,7 +409,7 @@

Mail Layout Force

-

Configuration

+

Configuration

To configure a forced layout for email templates:

  1. Go to Settings > Technical > Email > Email Templates
  2. @@ -444,7 +449,7 @@

    Configuration

-

Bug Tracker

+

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 @@ -452,15 +457,15 @@

Bug Tracker

Do not contact contributors directly about support or help with technical issues.

-

Credits

+

Credits

-

Authors

+

Authors

  • Camptocamp
-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -490,5 +495,6 @@

Maintainers

+
From 74a2295149f48a9793e398e8b594c75e32d56e33 Mon Sep 17 00:00:00 2001 From: Aungkokolin1997 Date: Fri, 22 May 2026 08:36:35 +0000 Subject: [PATCH 08/25] [DEV-456][IMP] partner_bank_acc_holder_name: reflect OCA changes --- .../static/description/icon.png | Bin 0 -> 10254 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 partner_bank_acc_holder_name/static/description/icon.png diff --git a/partner_bank_acc_holder_name/static/description/icon.png b/partner_bank_acc_holder_name/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1dcc49c24f364e9adf0afbc6fc0bac6dbecdeb11 GIT binary patch literal 10254 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 Date: Fri, 22 May 2026 08:36:35 +0000 Subject: [PATCH 09/25] [DEV-456][IMP] partner_contact_address_default: reflect OCA changes --- partner_contact_address_default/README.rst | 30 +++++++++++-------- .../__manifest__.py | 2 +- .../models/res_partner.py | 2 +- .../static/description/index.html | 30 +++++++++++-------- 4 files changed, 37 insertions(+), 27 deletions(-) diff --git a/partner_contact_address_default/README.rst b/partner_contact_address_default/README.rst index 7cdefaf..ee512f0 100644 --- a/partner_contact_address_default/README.rst +++ b/partner_contact_address_default/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + =============================== Partner Contact address default =============================== @@ -7,13 +11,13 @@ Partner Contact address default !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:81d150284a7193759bbb0a4b2be19dd6f45b76d3d3c403f1823b936ccdeefb0f + !! source digest: sha256:67038546311e88f2bf8758410a350d0cd6fd0ac04d6b000eb5c2b5c5b9c89304 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fpartner--contact-lightgray.png?logo=github @@ -73,26 +77,26 @@ Authors Contributors ------------ -- `Tecnativa `__: +- `Tecnativa `__: - - Carlos Dauden - - Sergio Teruel + - Carlos Dauden + - Sergio Teruel -- `Sygel `__: +- `Sygel `__: - - Manuel Regidor + - Manuel Regidor -- `Studio73 `__: +- `Studio73 `__: - - Carlos Reyes + - Carlos Reyes -- `ForgeFlow `__: +- `ForgeFlow `__: - - Laura Cazorla + - Laura Cazorla -- `Quartile `__: +- `Quartile `__: - - Aung Ko Ko Lin + - Aung Ko Ko Lin Maintainers ----------- diff --git a/partner_contact_address_default/__manifest__.py b/partner_contact_address_default/__manifest__.py index 386933e..66c616c 100644 --- a/partner_contact_address_default/__manifest__.py +++ b/partner_contact_address_default/__manifest__.py @@ -5,7 +5,7 @@ "name": "Partner Contact address default", "summary": "Set a default delivery address, " "invoice address and contact for contacts", - "version": "18.0.1.0.0", + "version": "18.0.1.0.1", "development_status": "Beta", "category": "Generic Modules/Base", "website": "https://github.com/OCA/partner-contact", diff --git a/partner_contact_address_default/models/res_partner.py b/partner_contact_address_default/models/res_partner.py index ce13203..b5483bb 100644 --- a/partner_contact_address_default/models/res_partner.py +++ b/partner_contact_address_default/models/res_partner.py @@ -25,7 +25,7 @@ class ResPartner(models.Model): partner_invoice_domain = fields.Binary(compute="_compute_partner_domains") partner_contact_domain = fields.Binary(compute="_compute_partner_domains") - @api.depends_context("company") + @api.depends_context("allowed_company_ids") @api.depends("commercial_partner_id") def _compute_partner_domains(self): for partner in self: diff --git a/partner_contact_address_default/static/description/index.html b/partner_contact_address_default/static/description/index.html index efd5f5c..aff3a64 100644 --- a/partner_contact_address_default/static/description/index.html +++ b/partner_contact_address_default/static/description/index.html @@ -3,7 +3,7 @@ -Partner Contact address default +README.rst -
-

Partner Contact address default

+
+ + +Odoo Community Association + +
+

Partner Contact address default

-

Beta License: AGPL-3 OCA/partner-contact Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/partner-contact Translate me on Weblate Try me on Runboat

This module extends the functionality of base partner module to allow to set a default delivery and invoice address and a default contact for contacts.

@@ -388,7 +393,7 @@

Partner Contact address default

-

Configuration

+

Configuration

  1. Go to Settings.
  2. Under Contact Category, enable Contact Address Default Allow All @@ -397,7 +402,7 @@

    Configuration

-

Usage

+

Usage

  1. Go to Contacts.
  2. Select default delivery address, invoice address or contact for @@ -405,7 +410,7 @@

    Usage

-

Bug Tracker

+

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 @@ -413,15 +418,15 @@

Bug Tracker

Do not contact contributors directly about support or help with technical issues.

-

Credits

+

Credits

-

Authors

+

Authors

  • Tecnativa
-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -460,5 +465,6 @@

Maintainers

+
From 40763c1bc6860c1a84acc4db4da15746bac38d15 Mon Sep 17 00:00:00 2001 From: Aungkokolin1997 Date: Fri, 22 May 2026 08:36:35 +0000 Subject: [PATCH 10/25] [DEV-456][IMP] purchase_order_etd_eta: reflect OCA changes --- purchase_order_etd_eta/README.rst | 12 ++++--- .../migrations/18.0.1.0.0/post-migrate.py | 15 --------- .../report/purchase_order_templates.xml | 2 +- .../static/description/icon.png | Bin 0 -> 10254 bytes .../static/description/index.html | 30 +++++++++++------- 5 files changed, 27 insertions(+), 32 deletions(-) delete mode 100644 purchase_order_etd_eta/migrations/18.0.1.0.0/post-migrate.py create mode 100644 purchase_order_etd_eta/static/description/icon.png diff --git a/purchase_order_etd_eta/README.rst b/purchase_order_etd_eta/README.rst index bd95c9f..8f76176 100644 --- a/purchase_order_etd_eta/README.rst +++ b/purchase_order_etd_eta/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ====================== Purchase Order ETD/ETA ====================== @@ -7,13 +11,13 @@ Purchase Order ETD/ETA !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:38890cab558012aca5ba0396b59d0116ea743611b7c0bcb74fdda76da3465194 + !! source digest: sha256:e2bd2f6c01420f0876484077e5a12425d4c3e02fb9441f4be395699eaaeb3247 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fpurchase--workflow-lightgray.png?logo=github @@ -76,9 +80,9 @@ Authors Contributors ------------ -- `Quartile `__: +- `Quartile `__: - - Aung Ko Ko Lin + - Aung Ko Ko Lin Maintainers ----------- diff --git a/purchase_order_etd_eta/migrations/18.0.1.0.0/post-migrate.py b/purchase_order_etd_eta/migrations/18.0.1.0.0/post-migrate.py deleted file mode 100644 index 86d4485..0000000 --- a/purchase_order_etd_eta/migrations/18.0.1.0.0/post-migrate.py +++ /dev/null @@ -1,15 +0,0 @@ -def migrate(cr, version): - """Copy eta_date and etd_date values to shipping_schedule_note field.""" - cr.execute(""" - UPDATE purchase_order - SET shipping_schedule_note = - CASE - WHEN etd_date IS NOT NULL AND eta_date IS NOT NULL - THEN 'ETD: ' || TRIM(etd_date) || ' ETA: ' || TRIM(eta_date) - WHEN etd_date IS NOT NULL - THEN 'ETD: ' || TRIM(etd_date) - WHEN eta_date IS NOT NULL - THEN 'ETA: ' || TRIM(eta_date) - END - WHERE etd_date IS NOT NULL OR eta_date IS NOT NULL - """) diff --git a/purchase_order_etd_eta/report/purchase_order_templates.xml b/purchase_order_etd_eta/report/purchase_order_templates.xml index f725512..0a39893 100644 --- a/purchase_order_etd_eta/report/purchase_order_templates.xml +++ b/purchase_order_etd_eta/report/purchase_order_templates.xml @@ -10,7 +10,7 @@ ETA:

-

+
Shipping Schedule Note:

c**=lnR&y+1yw{;I3Hy6Ua2{<d0kcR+VvBo; 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 -Purchase Order ETD/ETA +README.rst -

-

Purchase Order ETD/ETA

+
+ + +Odoo Community Association + +
+

Purchase Order ETD/ETA

-

Beta License: AGPL-3 OCA/purchase-workflow Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/purchase-workflow Translate me on Weblate Try me on Runboat

The module adds ETD, ETA, and Shipping Schedule Note fields to purchase orders and displays them in the purchase order and RFQ reports.

Table of contents

@@ -387,14 +392,14 @@

Purchase Order ETD/ETA

-

Use Cases / Context

+

Use Cases / Context

Some companies need to store ETD and ETA information on Purchase Orders for communication with suppliers and for printing on reports.

These values are informational and may include simple instructions such as “ASAP” or “TBD”.

-

Configuration

+

Configuration

To hide the Expected Arrival in purchase reports when ETA is set:

  1. Go to Purchase ‣ Configuration ‣ Settings.
  2. @@ -404,7 +409,7 @@

    Configuration

-

Bug Tracker

+

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 @@ -412,15 +417,15 @@

Bug Tracker

Do not contact contributors directly about support or help with technical issues.

-

Credits

+

Credits

-

Authors

+

Authors

  • Quartile
-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -444,5 +449,6 @@

Maintainers

+
From 9c22fa605ed4ad27b96486418037a6972a39096e Mon Sep 17 00:00:00 2001 From: Aungkokolin1997 Date: Fri, 22 May 2026 08:36:35 +0000 Subject: [PATCH 11/25] [DEV-456][IMP] purchase_order_secondary_unit: reflect OCA changes --- purchase_order_secondary_unit/README.rst | 55 ++++------- purchase_order_secondary_unit/__manifest__.py | 4 +- .../readme/CONFIGURE.md | 14 --- .../reports/purchase_order_templates.xml | 52 +--------- .../reports/purchase_quotation_templates.xml | 47 +-------- .../purchase_order_secondary_unit_groups.xml | 9 -- .../static/description/index.html | 71 ++++++-------- .../views/purchase_order_portal_templates.xml | 95 ------------------- 8 files changed, 57 insertions(+), 290 deletions(-) delete mode 100644 purchase_order_secondary_unit/security/purchase_order_secondary_unit_groups.xml delete mode 100644 purchase_order_secondary_unit/views/purchase_order_portal_templates.xml diff --git a/purchase_order_secondary_unit/README.rst b/purchase_order_secondary_unit/README.rst index f0dc232..e321456 100644 --- a/purchase_order_secondary_unit/README.rst +++ b/purchase_order_secondary_unit/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ============================= Purchase Order Secondary Unit ============================= @@ -7,13 +11,13 @@ Purchase Order Secondary Unit !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:2b71909b287e9e5c437aea172c4c165ed1bee7b3e981d1c44d99c8bfaae5740d + !! source digest: sha256:931f6f1aa647d4627f4c32d5a657bb5fcbfef63f595c2c84f0790ff27a44ee7d !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fpurchase--workflow-lightgray.png?logo=github @@ -50,23 +54,6 @@ For configuration of displaying secondary unit information in purchase reports and the Purchase Order portal, see the guidelines provided in product_secondary_unit. -Settings Visibility -------------------- - -When installing this module, all internal users are automatically added -to the ``product_secondary_unit.group_purchase_secondary_unit`` security -group. This makes the Purchase-related "Hide Secondary Qty Column" and -"Secondary Unit Price Display" settings visible in **Settings > Units of -Measure**. - -If you installed this module before these report presentation settings -were introduced in ``product_secondary_unit``, users may not see these -configuration options. To fix this: - -1. Go to **Settings > Users & Companies > Groups** -2. Search for "Purchase Secondary Unit" -3. Add the relevant users to that group - Usage ===== @@ -81,13 +68,13 @@ To use this module you need to: **Vendor Pricelist Integration** -- When adding a vendor to a product's pricelist (via *Purchase tab > - Vendors*), the secondary unit of measure is automatically defaulted - from the product variant's purchase secondary UOM, or from the - product template if not set on the variant. -- When a new vendor pricelist record is created from purchase order - confirmation, the secondary UOM from the purchase order line is - automatically stored in the vendor pricelist entry. +- When adding a vendor to a product's pricelist (via *Purchase tab > + Vendors*), the secondary unit of measure is automatically defaulted + from the product variant's purchase secondary UOM, or from the product + template if not set on the variant. +- When a new vendor pricelist record is created from purchase order + confirmation, the secondary UOM from the purchase order line is + automatically stored in the vendor pricelist entry. Known issues / Roadmap ====================== @@ -118,17 +105,17 @@ Authors Contributors ------------ -- `Tecnativa `__: +- `Tecnativa `__: - - Sergio Teruel - - Ernesto Tejeda + - Sergio Teruel + - Ernesto Tejeda -- Nikul Chaudhary -- Pimolnat Suntian -- Miguel Ángel Gómez -- `Quartile `__: +- Nikul Chaudhary +- Pimolnat Suntian +- Miguel Ángel Gómez +- `Quartile `__: - - Yoshi Tashiro + - Yoshi Tashiro Maintainers ----------- diff --git a/purchase_order_secondary_unit/__manifest__.py b/purchase_order_secondary_unit/__manifest__.py index 7368f53..04badf6 100644 --- a/purchase_order_secondary_unit/__manifest__.py +++ b/purchase_order_secondary_unit/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Purchase Order Secondary Unit", "summary": "Purchase product in a secondary unit", - "version": "18.0.1.2.1", + "version": "18.0.1.2.2", "development_status": "Beta", "category": "Purchase", "website": "https://github.com/OCA/purchase-workflow", @@ -14,10 +14,8 @@ "auto_install": True, "depends": ["purchase", "product_secondary_unit"], "data": [ - "security/purchase_order_secondary_unit_groups.xml", "views/product_views.xml", "views/product_supplierinfo_views.xml", - "views/purchase_order_portal_templates.xml", "views/purchase_order_views.xml", "reports/purchase_order_templates.xml", "reports/purchase_quotation_templates.xml", diff --git a/purchase_order_secondary_unit/readme/CONFIGURE.md b/purchase_order_secondary_unit/readme/CONFIGURE.md index d50c70c..2ba195b 100644 --- a/purchase_order_secondary_unit/readme/CONFIGURE.md +++ b/purchase_order_secondary_unit/readme/CONFIGURE.md @@ -1,16 +1,2 @@ For configuration of displaying secondary unit information in purchase reports and the Purchase Order portal, see the guidelines provided in product_secondary_unit. - -## Settings Visibility - -When installing this module, all internal users are automatically added to the -`product_secondary_unit.group_purchase_secondary_unit` security group. This makes -the Purchase-related "Hide Secondary Qty Column" and "Secondary Unit Price Display" -settings visible in **Settings > Units of Measure**. - -If you installed this module before these report presentation settings were introduced -in `product_secondary_unit`, users may not see these configuration options. To fix this: - -1. Go to **Settings > Users & Companies > Groups** -2. Search for "Purchase Secondary Unit" -3. Add the relevant users to that group diff --git a/purchase_order_secondary_unit/reports/purchase_order_templates.xml b/purchase_order_secondary_unit/reports/purchase_order_templates.xml index 86425de..b79d2fc 100644 --- a/purchase_order_secondary_unit/reports/purchase_order_templates.xml +++ b/purchase_order_secondary_unit/reports/purchase_order_templates.xml @@ -6,64 +6,16 @@ > - + Second Qty - + - - - line.get_secondary_uom_display_mode() != 'secondary' - - - line.get_secondary_uom_display_mode() != 'secondary' - - - - - - - - - - - -
- - ( - ) - -
-
- - - line.get_secondary_uom_display_mode() != 'secondary' - - - - diff --git a/purchase_order_secondary_unit/reports/purchase_quotation_templates.xml b/purchase_order_secondary_unit/reports/purchase_quotation_templates.xml index 41661d3..ef64f13 100644 --- a/purchase_order_secondary_unit/reports/purchase_quotation_templates.xml +++ b/purchase_order_secondary_unit/reports/purchase_quotation_templates.xml @@ -4,57 +4,18 @@ id="report_purchasequotation_document" inherit_id="purchase.report_purchasequotation_document" > - + - + Second Qty - + - + - - - order_line.get_secondary_uom_display_mode() != 'secondary' - - - order_line.get_secondary_uom_display_mode() != 'secondary' - - - - - - - - - - - -
- - ( - ) - -
-
diff --git a/purchase_order_secondary_unit/security/purchase_order_secondary_unit_groups.xml b/purchase_order_secondary_unit/security/purchase_order_secondary_unit_groups.xml deleted file mode 100644 index 3467b8c..0000000 --- a/purchase_order_secondary_unit/security/purchase_order_secondary_unit_groups.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/purchase_order_secondary_unit/static/description/index.html b/purchase_order_secondary_unit/static/description/index.html index 27a815c..21fc85d 100644 --- a/purchase_order_secondary_unit/static/description/index.html +++ b/purchase_order_secondary_unit/static/description/index.html @@ -3,7 +3,7 @@ -Purchase Order Secondary Unit +README.rst -
-

Purchase Order Secondary Unit

+
+ + +Odoo Community Association + +
+

Purchase Order Secondary Unit

-

Beta License: AGPL-3 OCA/purchase-workflow Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/purchase-workflow Translate me on Weblate Try me on Runboat

This module extends the functionality of purchase orders to allow buy products in secondary unit of distinct category.

Users can enter quantities and prices in secondary units on purchase @@ -380,45 +385,26 @@

Purchase Order Secondary Unit

Table of contents

-

Configuration

+

Configuration

For configuration of displaying secondary unit information in purchase reports and the Purchase Order portal, see the guidelines provided in product_secondary_unit.

-
-

Settings Visibility

-

When installing this module, all internal users are automatically added -to the product_secondary_unit.group_purchase_secondary_unit security -group. This makes the Purchase-related “Hide Secondary Qty Column” and -“Secondary Unit Price Display” settings visible in Settings > Units of -Measure.

-

If you installed this module before these report presentation settings -were introduced in product_secondary_unit, users may not see these -configuration options. To fix this:

-
    -
  1. Go to Settings > Users & Companies > Groups
  2. -
  3. Search for “Purchase Secondary Unit”
  4. -
  5. Add the relevant users to that group
  6. -
-
-

Usage

+

Usage

To use this module you need to:

  1. Go to a Product > General Information tab.
  2. @@ -432,22 +418,22 @@

    Usage

    • When adding a vendor to a product’s pricelist (via Purchase tab > Vendors), the secondary unit of measure is automatically defaulted -from the product variant’s purchase secondary UOM, or from the -product template if not set on the variant.
    • +from the product variant’s purchase secondary UOM, or from the product +template if not set on the variant.
    • When a new vendor pricelist record is created from purchase order confirmation, the secondary UOM from the purchase order line is automatically stored in the vendor pricelist entry.
-

Known issues / Roadmap

+

Known issues / Roadmap

Updating existing vendor pricelist records from purchase order confirmation does not currently support secondary UOM or secondary UOM pricing. This is not included in the current scope and may be considered in future improvements.

-

Bug Tracker

+

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 @@ -455,15 +441,15 @@

Bug Tracker

Do not contact contributors directly about support or help with technical issues.

-

Credits

+

Credits

-

Authors

+

Authors

  • Tecnativa
-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -493,5 +479,6 @@

Maintainers

+
diff --git a/purchase_order_secondary_unit/views/purchase_order_portal_templates.xml b/purchase_order_secondary_unit/views/purchase_order_portal_templates.xml deleted file mode 100644 index 3f01e80..0000000 --- a/purchase_order_secondary_unit/views/purchase_order_portal_templates.xml +++ /dev/null @@ -1,95 +0,0 @@ - - - - - From ffad14bb01cdaa7a65c31c16e1744587d37f75ce Mon Sep 17 00:00:00 2001 From: Aungkokolin1997 Date: Fri, 22 May 2026 08:36:35 +0000 Subject: [PATCH 12/25] [DEV-456][IMP] report_pdf_zip_download: reflect OCA changes --- .../static/src/js/action_manager_report.esm.js | 1 + 1 file changed, 1 insertion(+) diff --git a/report_pdf_zip_download/static/src/js/action_manager_report.esm.js b/report_pdf_zip_download/static/src/js/action_manager_report.esm.js index 930dda5..6983ca5 100644 --- a/report_pdf_zip_download/static/src/js/action_manager_report.esm.js +++ b/report_pdf_zip_download/static/src/js/action_manager_report.esm.js @@ -1,6 +1,7 @@ // © 2017 Creu Blanca // Copyright 2024 Quartile (https://www.quartile.co) // License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +/* global URLSearchParams */ import {download} from "@web/core/network/download"; import {registry} from "@web/core/registry"; import {user} from "@web/core/user"; From 2ba436a77a4d7241afe01814f25dc12bdd555d5d Mon Sep 17 00:00:00 2001 From: Aungkokolin1997 Date: Fri, 22 May 2026 08:36:35 +0000 Subject: [PATCH 13/25] [DEV-456][IMP] report_positioned_image: reflect OCA changes --- report_positioned_image/README.rst | 52 +++++----- .../models/ir_actions_report.py | 89 +++++++++--------- .../models/report_positioned_image.py | 43 ++++++--- report_positioned_image/readme/CONFIGURE.md | 2 + report_positioned_image/readme/DESCRIPTION.md | 3 + .../static/description/icon.png | Bin 0 -> 10254 bytes .../static/description/index.html | 41 ++++---- .../tests/test_report_positioned_image.py | 40 ++++++++ .../views/report_positioned_image_views.xml | 7 +- .../views/res_company_views.xml | 8 +- 10 files changed, 182 insertions(+), 103 deletions(-) create mode 100644 report_positioned_image/static/description/icon.png diff --git a/report_positioned_image/README.rst b/report_positioned_image/README.rst index 1be5aeb..d55eb0d 100644 --- a/report_positioned_image/README.rst +++ b/report_positioned_image/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ======================= Report Positioned Image ======================= @@ -7,13 +11,13 @@ Report Positioned Image !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:8bc2f08c57ac7bd7e62467501b1ac95394b9e6047b1a4fa48e08a4a99a760e2e + !! source digest: sha256:7492b81c95084617eacd2468003a6783881838c17e7ef230b84bf4d6733dc0e3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Freporting--engine-lightgray.png?logo=github @@ -35,11 +39,13 @@ they appear on all pages or only the first page. The module supports two types of images: -- *Company-level Images*: Define images at the company level that can - be included in reports by enabling the *Include Company Images* - option -- *Report-specific Images*: Configure specific images for individual - reports, filtered by company context and always shown when configured +- *Company-level Images*: Define images at the company level that can be + included in reports by enabling the *Include Company Images* option +- *Report-specific Images*: Configure specific images for individual + reports, filtered by company context and always shown when configured + +Images can be assigned to a specific company or left as shared records +(without company assignment) for use across multiple companies **Table of contents** @@ -56,18 +62,20 @@ To configure company-level images: 3. Navigate to the *Report Images* tab 4. Add images with position settings: - - Upload an image - width defaults to 50mm and height is - automatically calculated to maintain the original aspect ratio - - *Top (mm)*: Distance from the top of the page - - *Left (mm)*: Distance from the left edge of the page - - *Width (mm)*: Width of the image (changing this auto-adjusts - height) - - *Height (mm)*: Height of the image (changing this auto-adjusts - width) - - *Respect Image Ratio*: When enabled (default), changing width or - height automatically adjusts the other dimension to maintain - aspect ratio. Uncheck for manual control of both dimensions. - - *First Page Only*: Check to show only on the first page + - Upload an image - width defaults to 50mm and height is + automatically calculated to maintain the original aspect ratio + - *Top (mm)*: Distance from the top of the page + - *Left (mm)*: Distance from the left edge of the page + - *Width (mm)*: Width of the image (changing this auto-adjusts + height) + - *Height (mm)*: Height of the image (changing this auto-adjusts + width) + - *Respect Image Ratio*: When enabled (default), changing width or + height automatically adjusts the other dimension to maintain aspect + ratio. Uncheck for manual control of both dimensions. + - *First Page Only*: Check to show only on the first page + - *Company*: Automatically set to the current company when creating + from the company form. To create shared images, leave empty. To configure report-specific images: @@ -105,10 +113,10 @@ Authors Contributors ------------ -- Quartile +- Quartile - - Tatsuki Kanda - - Aung Ko Ko Lin + - Tatsuki Kanda + - Aung Ko Ko Lin Maintainers ----------- diff --git a/report_positioned_image/models/ir_actions_report.py b/report_positioned_image/models/ir_actions_report.py index 979a727..9fdca59 100644 --- a/report_positioned_image/models/ir_actions_report.py +++ b/report_positioned_image/models/ir_actions_report.py @@ -22,42 +22,6 @@ class IrActionsReport(models.Model): string="Report Images", ) - def _render_qweb_pdf(self, report_ref, res_ids=None, data=None): - """Set company context so _get_positioned_image_configs uses the - correct company. - """ - company = self._get_report_company(res_ids) - return super(IrActionsReport, self.with_company(company))._render_qweb_pdf( - report_ref, res_ids, data - ) - - def _prepare_html(self, html, report_model=False): - image_configs = self._get_positioned_image_configs() - if not image_configs: - return super()._prepare_html(html, report_model=report_model) - result = super()._prepare_html(html, report_model=report_model) - if not isinstance(result, tuple): - return result - bodies, res_ids, header, footer, specific_paperformat_args = result - if image_configs: - header = self._inject_images_into_header(header, image_configs) - return bodies, res_ids, header, footer, specific_paperformat_args - - def _inject_images_into_header(self, header, image_configs): - image_html = self._build_image_html(image_configs) - return self._insert_html_into_header(header, image_html) - - def _insert_html_into_header(self, header, html_to_inject): - if Markup("") in header: - return header.replace( - Markup(""), html_to_inject + Markup(""), 1 - ) - if Markup("") in header: - return header.replace( - Markup(""), Markup("") + html_to_inject, 1 - ) - return header + html_to_inject - @staticmethod def _build_image_html(images): parts = [] @@ -85,15 +49,20 @@ def _build_image_html(images): ) return Markup("".join(parts)) - def _get_report_company(self, res_ids): - if not res_ids or not self.model: - return self.env.company - model = self.env[self.model] - if "company_id" not in model._fields: - return self.env.company - records = model.browse(res_ids).exists() - companies = records.mapped("company_id") - return companies[0] if len(companies) == 1 else self.env.company + def _insert_html_into_header(self, header, html_to_inject): + if Markup("") in header: + return header.replace( + Markup(""), html_to_inject + Markup(""), 1 + ) + if Markup("") in header: + return header.replace( + Markup(""), Markup("") + html_to_inject, 1 + ) + return header + html_to_inject + + def _inject_images_into_header(self, header, image_configs): + image_html = self._build_image_html(image_configs) + return self._insert_html_into_header(header, image_html) def _get_positioned_image_configs(self): company = self.env.company @@ -114,3 +83,33 @@ def _get_positioned_image_configs(self): for img in images if img.image ] + + def _prepare_html(self, html, report_model=False): + image_configs = self._get_positioned_image_configs() + if not image_configs: + return super()._prepare_html(html, report_model=report_model) + result = super()._prepare_html(html, report_model=report_model) + if not isinstance(result, tuple): + return result + bodies, res_ids, header, footer, specific_paperformat_args = result + header = self._inject_images_into_header(header, image_configs) + return bodies, res_ids, header, footer, specific_paperformat_args + + def _get_report_company(self, res_ids): + if not res_ids or not self.model: + return self.env.company + model = self.env[self.model] + if "company_id" not in model._fields: + return self.env.company + records = model.browse(res_ids).exists() + companies = records.mapped("company_id") + return companies[0] if len(companies) == 1 else self.env.company + + def _render_qweb_pdf(self, report_ref, res_ids=None, data=None): + """Set company context so _get_positioned_image_configs uses the + correct company. + """ + company = self._get_report_company(res_ids) + return super(IrActionsReport, self.with_company(company))._render_qweb_pdf( + report_ref, res_ids, data + ) diff --git a/report_positioned_image/models/report_positioned_image.py b/report_positioned_image/models/report_positioned_image.py index 2a283f0..edfb5f9 100644 --- a/report_positioned_image/models/report_positioned_image.py +++ b/report_positioned_image/models/report_positioned_image.py @@ -36,6 +36,19 @@ class ReportPositionedImage(models.Model): def _default_company_id(self): return self.env.context.get("default_company_id") + @api.constrains("pos_top", "pos_left", "width", "height") + def _check_positive_values(self): + """Ensure position and dimension fields have positive values.""" + for record in self: + if record.pos_top < 0: + raise ValidationError(_("Top position must be a positive value.")) + if record.pos_left < 0: + raise ValidationError(_("Left position must be a positive value.")) + if record.width <= 0: + raise ValidationError(_("Width must be greater than zero.")) + if record.height <= 0: + raise ValidationError(_("Height must be greater than zero.")) + def _get_aspect_ratio(self): """Get image aspect ratio (width/height).""" if not self.image: @@ -83,15 +96,21 @@ def _onchange_height(self): self.height * ratio, 2 ) - @api.constrains("pos_top", "pos_left", "width", "height") - def _check_positive_values(self): - """Ensure position and dimension fields have positive values.""" - for record in self: - if record.pos_top < 0: - raise ValidationError(_("Top position must be a positive value.")) - if record.pos_left < 0: - raise ValidationError(_("Left position must be a positive value.")) - if record.width <= 0: - raise ValidationError(_("Width must be greater than zero.")) - if record.height <= 0: - raise ValidationError(_("Height must be greater than zero.")) + @api.onchange("company_id") + def _onchange_company_id(self): + """Prevent assigning to a different company when created from company form.""" + default_company_id = self.env.context.get("default_company_id") + if not default_company_id: + return + if self.company_id and self.company_id.id != default_company_id: + self.company_id = default_company_id + return { + "warning": { + "title": _("Company Assignment"), + "message": _( + "You cannot assign this image to a different company. " + "Please use the dedicated wizard to assign images to other " + "companies." + ), + } + } diff --git a/report_positioned_image/readme/CONFIGURE.md b/report_positioned_image/readme/CONFIGURE.md index 9ffc4d6..0342fbd 100644 --- a/report_positioned_image/readme/CONFIGURE.md +++ b/report_positioned_image/readme/CONFIGURE.md @@ -14,6 +14,8 @@ To configure company-level images: automatically adjusts the other dimension to maintain aspect ratio. Uncheck for manual control of both dimensions. - *First Page Only*: Check to show only on the first page + - *Company*: Automatically set to the current company when creating from + the company form. To create shared images, leave empty. To configure report-specific images: diff --git a/report_positioned_image/readme/DESCRIPTION.md b/report_positioned_image/readme/DESCRIPTION.md index ddc3864..0220a9c 100644 --- a/report_positioned_image/readme/DESCRIPTION.md +++ b/report_positioned_image/readme/DESCRIPTION.md @@ -9,3 +9,6 @@ The module supports two types of images: included in reports by enabling the *Include Company Images* option - *Report-specific Images*: Configure specific images for individual reports, filtered by company context and always shown when configured + +Images can be assigned to a specific company or left as shared records +(without company assignment) for use across multiple companies diff --git a/report_positioned_image/static/description/icon.png b/report_positioned_image/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1dcc49c24f364e9adf0afbc6fc0bac6dbecdeb11 GIT binary patch literal 10254 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 -Report Positioned Image +README.rst -
-

Report Positioned Image

+
+ + +Odoo Community Association + +
+

Report Positioned Image

-

Beta License: AGPL-3 OCA/reporting-engine Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/reporting-engine Translate me on Weblate Try me on Runboat

This module allows you to add positioned images (such as watermarks, logos, or stamps) to PDF reports. Images can be precisely positioned using millimeter coordinates (top, left) and you can control whether they appear on all pages or only the first page.

The module supports two types of images:

    -
  • Company-level Images: Define images at the company level that can -be included in reports by enabling the Include Company Images -option
  • +
  • Company-level Images: Define images at the company level that can be +included in reports by enabling the Include Company Images option
  • Report-specific Images: Configure specific images for individual reports, filtered by company context and always shown when configured
+

Images can be assigned to a specific company or left as shared records +(without company assignment) for use across multiple companies

Table of contents

    @@ -396,7 +402,7 @@

    Report Positioned Image

-

Configuration

+

Configuration

To configure company-level images:

  1. Go to Settings / Companies
  2. @@ -412,9 +418,11 @@

    Configuration

  3. Height (mm): Height of the image (changing this auto-adjusts width)
  4. Respect Image Ratio: When enabled (default), changing width or -height automatically adjusts the other dimension to maintain -aspect ratio. Uncheck for manual control of both dimensions.
  5. +height automatically adjusts the other dimension to maintain aspect +ratio. Uncheck for manual control of both dimensions.
  6. First Page Only: Check to show only on the first page
  7. +
  8. Company: Automatically set to the current company when creating +from the company form. To create shared images, leave empty.
@@ -434,7 +442,7 @@

Configuration

will update automatically to prevent distortion.

-

Bug Tracker

+

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 @@ -442,15 +450,15 @@

Bug Tracker

Do not contact contributors directly about support or help with technical issues.

-

Credits

+

Credits

-

Authors

+

Authors

  • Quartile
-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -473,5 +481,6 @@

Maintainers

+
diff --git a/report_positioned_image/tests/test_report_positioned_image.py b/report_positioned_image/tests/test_report_positioned_image.py index a76a99f..e52e530 100644 --- a/report_positioned_image/tests/test_report_positioned_image.py +++ b/report_positioned_image/tests/test_report_positioned_image.py @@ -232,3 +232,43 @@ def test_global_images_appear_for_all_companies(self): self.company_b )._get_positioned_image_configs() self.assertEqual(len(configs_b), 1) + + def test_company_id_onchange_with_context(self): + image = ( + self.env["report.positioned.image"] + .with_context(default_company_id=self.company_a.id) + .new( + { + "name": "Test Image", + "image": self.test_image, + "width": 10.0, + "height": 10.0, + "company_id": self.company_a.id, + } + ) + ) + image.company_id = self.company_b + result = image._onchange_company_id() + self.assertIsNotNone(result) + self.assertIn("warning", result) + self.assertEqual(image.company_id, self.company_a) + image.company_id = self.company_a + result = image._onchange_company_id() + self.assertIsNone(result) + self.assertEqual(image.company_id, self.company_a) + image.company_id = False + result = image._onchange_company_id() + self.assertIsNone(result) + self.assertFalse(image.company_id) + image_no_context = self.env["report.positioned.image"].new( + { + "name": "Free Image", + "image": self.test_image, + "width": 10.0, + "height": 10.0, + "company_id": self.company_b.id, + } + ) + result = image_no_context._onchange_company_id() + self.assertIsNone(result) + self.assertEqual(image_no_context.company_id, self.company_b) diff --git a/report_positioned_image/views/report_positioned_image_views.xml b/report_positioned_image/views/report_positioned_image_views.xml index f98dc7c..25e21fa 100644 --- a/report_positioned_image/views/report_positioned_image_views.xml +++ b/report_positioned_image/views/report_positioned_image_views.xml @@ -10,7 +10,10 @@ - + @@ -31,7 +34,7 @@ - + diff --git a/report_positioned_image/views/res_company_views.xml b/report_positioned_image/views/res_company_views.xml index a14398b..d69a373 100644 --- a/report_positioned_image/views/res_company_views.xml +++ b/report_positioned_image/views/res_company_views.xml @@ -11,7 +11,7 @@ name="report_positioned_image_ids" nolabel="1" context="{'default_company_id': id}" - domain="[('company_id', '=', id)]" + domain="['|', ('company_id', '=', id), ('company_id', '=', False)]" > @@ -26,11 +26,7 @@ - + From 2408950daa1eec1f50a39a358a1a9d41f5b11410 Mon Sep 17 00:00:00 2001 From: Aungkokolin1997 Date: Fri, 22 May 2026 08:36:35 +0000 Subject: [PATCH 14/25] [DEV-456][IMP] report_qweb_field_option: reflect OCA changes --- report_qweb_field_option/README.rst | 38 ++++++++++--------- report_qweb_field_option/__manifest__.py | 2 +- .../models/qweb_field_options.py | 1 - report_qweb_field_option/readme/CONFIGURE.md | 4 +- .../static/description/index.html | 38 +++++++++++-------- .../tests/test_report_qweb_field_options.py | 27 ++++++------- .../views/qweb_field_options_views.xml | 1 + 7 files changed, 58 insertions(+), 53 deletions(-) diff --git a/report_qweb_field_option/README.rst b/report_qweb_field_option/README.rst index fe62b23..0905565 100644 --- a/report_qweb_field_option/README.rst +++ b/report_qweb_field_option/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ======================== Report Qweb Field Option ======================== @@ -7,13 +11,13 @@ Report Qweb Field Option !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:6a839e0b8361541500cea7946ac9d7bfbcbe37ab2a102576061a2940c4343c5c + !! source digest: sha256:2e6250e04e346bc7f61b36e4fb244e8f744f480b1e42e0ba753a71342ebd648f !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Freporting--engine-lightgray.png?logo=github @@ -45,18 +49,18 @@ create records according to your needs. For each record: -- Set **Model** and **Field** (required) -- Set **UoM** and **UoM Field**, or **Currency** and **Currency Field** - only for fields of float type (optional) -- Set **Additional Conditions** to specify a domain for more specific - filtering (e.g., ``[('secondary_uom_id', '=', 1)]`` to apply only - when a specific secondary UoM is used) (optional) -- Set **Company** (optional) -- Set **Options** as a string representation of a dictionary. E.g., - ``{"widget": "date"}``, ``{"widget": "monetary"}``, or - ``{"widget": "contact", "fields": ["name", "phone"]}`` -- Set **Digits** (only for float-type fields). The value is ignored if - Options is set +- Set **Model** and **Field** (required) +- Set **UoM** and **UoM Field**, or **Currency** and **Currency Field** + only for fields of float type (optional) +- Set **Domain** to specify a domain for more specific filtering (e.g., + ``[('secondary_uom_id', '=', 1)]`` to apply only when a specific + secondary UoM is used) (optional) +- Set **Company** (optional) +- Set **Options** as a string representation of a dictionary. E.g., + ``{"widget": "date"}``, ``{"widget": "monetary"}``, or + ``{"widget": "contact", "fields": ["name", "phone"]}`` +- Set **Digits** (only for float-type fields). The value is ignored if + Options is set Usage ===== @@ -114,10 +118,10 @@ Authors Contributors ------------ -- `Quartile `__: +- `Quartile `__: - - Yoshi Tashiro - - Aung Ko Ko Lin + - Yoshi Tashiro + - Aung Ko Ko Lin Maintainers ----------- diff --git a/report_qweb_field_option/__manifest__.py b/report_qweb_field_option/__manifest__.py index 10d68fd..e88ab83 100644 --- a/report_qweb_field_option/__manifest__.py +++ b/report_qweb_field_option/__manifest__.py @@ -2,7 +2,7 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). { "name": "Report Qweb Field Option", - "version": "18.0.1.0.1", + "version": "18.0.1.1.0", "category": "Technical Settings", "license": "AGPL-3", "author": "Quartile, Odoo Community Association (OCA)", diff --git a/report_qweb_field_option/models/qweb_field_options.py b/report_qweb_field_option/models/qweb_field_options.py index 0ef9e1f..2dc6251 100644 --- a/report_qweb_field_option/models/qweb_field_options.py +++ b/report_qweb_field_option/models/qweb_field_options.py @@ -55,7 +55,6 @@ class QwebFieldOptions(models.Model): digits = fields.Integer() company_id = fields.Many2one("res.company", string="Company") domain = fields.Char( - "Additional Conditions", help="Optional domain for additional filtering conditions.\n" "This is evaluated in addition to UoM/Currency conditions.\n" "Examples:\n" diff --git a/report_qweb_field_option/readme/CONFIGURE.md b/report_qweb_field_option/readme/CONFIGURE.md index d8de22e..35be096 100644 --- a/report_qweb_field_option/readme/CONFIGURE.md +++ b/report_qweb_field_option/readme/CONFIGURE.md @@ -6,8 +6,8 @@ For each record: - Set **Model** and **Field** (required) - Set **UoM** and **UoM Field**, or **Currency** and **Currency Field** only for fields of float type (optional) -- Set **Additional Conditions** to specify a domain for more specific - filtering (e.g., `[('secondary_uom_id', '=', 1)]` to apply only when +- Set **Domain** to specify a domain for more specific filtering + (e.g., `[('secondary_uom_id', '=', 1)]` to apply only when a specific secondary UoM is used) (optional) - Set **Company** (optional) - Set **Options** as a string representation of a dictionary. E.g., diff --git a/report_qweb_field_option/static/description/index.html b/report_qweb_field_option/static/description/index.html index c5ec998..0595bfb 100644 --- a/report_qweb_field_option/static/description/index.html +++ b/report_qweb_field_option/static/description/index.html @@ -3,7 +3,7 @@ -Report Qweb Field Option +README.rst -
-

Report Qweb Field Option

+
+ + +Odoo Community Association + +
+

Report Qweb Field Option

-

Beta License: AGPL-3 OCA/reporting-engine Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/reporting-engine Translate me on Weblate Try me on Runboat

This module allows administrators to define the decimal precision of float fields and add option values to fields (e.g., adding a date widget option to datetime fields) for QWeb report and view presentation.

@@ -389,7 +394,7 @@

Report Qweb Field Option

-

Configuration

+

Configuration

Go to Settings > Technical > Reporting > Qweb Field Options, and create records according to your needs.

For each record:

@@ -397,9 +402,9 @@

Configuration

  • Set Model and Field (required)
  • Set UoM and UoM Field, or Currency and Currency Field only for fields of float type (optional)
  • -
  • Set Additional Conditions to specify a domain for more specific -filtering (e.g., [('secondary_uom_id', '=', 1)] to apply only -when a specific secondary UoM is used) (optional)
  • +
  • Set Domain to specify a domain for more specific filtering (e.g., +[('secondary_uom_id', '=', 1)] to apply only when a specific +secondary UoM is used) (optional)
  • Set Company (optional)
  • Set Options as a string representation of a dictionary. E.g., {"widget": "date"}, {"widget": "monetary"}, or @@ -409,7 +414,7 @@

    Configuration

  • -

    Usage

    +

    Usage

    Print a QWeb report (quotation, invoice, purchase order, etc.), and the value presentation for fields like line quantity, price unit and date order are adjusted according to the Qweb Field Options configuration.

    @@ -417,7 +422,7 @@

    Usage

    strictest condition will be applied.

    -

    Known issues / Roadmap

    +

    Known issues / Roadmap

    #. QWeb field option settings only apply to fields rendered with t-field.
    @@ -439,7 +444,7 @@

    Known issues / Roadmap

    https://github.com/odoo/odoo/blob/5eec379/addons/purchase/views/portal_templates.xml#L101-L102

    -

    Bug Tracker

    +

    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 @@ -447,15 +452,15 @@

    Bug Tracker

    Do not contact contributors directly about support or help with technical issues.

    -

    Credits

    +

    Credits

    -

    Authors

    +

    Authors

    • Quartile
    -

    Contributors

    +

    Contributors

    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    Odoo Community Association @@ -478,5 +483,6 @@

    Maintainers

    +
    diff --git a/report_qweb_field_option/tests/test_report_qweb_field_options.py b/report_qweb_field_option/tests/test_report_qweb_field_options.py index cd95268..c5670ab 100644 --- a/report_qweb_field_option/tests/test_report_qweb_field_options.py +++ b/report_qweb_field_option/tests/test_report_qweb_field_options.py @@ -168,29 +168,24 @@ def test_domain_validation(self): def test_qweb_field_option_with_domain(self): values = {"report_type": "pdf"} - box_uom = self.env["uom.uom"].create( - { - "name": "Box", - "category_id": self.env.ref("uom.product_uom_categ_unit").id, - "uom_type": "bigger", - "factor_inv": 12.0, - } - ) + jpy_currency = self.env.ref("base.JPY") + jpy_currency.active = True + self.qweb_options_rec.digits = 2 self.env["qweb.field.options"].create( { "res_model_id": self.test_model.id, - "field_id": self.quantity_field.id, - "domain": f"[('uom_id', '=', {box_uom.id})]", + "field_id": self.value_field.id, + "domain": f"[('currency_id', '=', {jpy_currency.id})]", "digits": 0, } ) - self.test_record.write({"uom_id": self.unit_uom.id, "quantity": 12.56}) _, content, _ = self.IrQweb._get_field( - self.test_record, "quantity", False, False, {}, values + self.test_record, "value", False, False, {}, values ) - self.assertEqual(content, "12.560") - self.test_record.uom_id = box_uom.id + self.assertEqual(content, "1.00") + # Test with JPY: domain matches, uses JPY-specific option (0 digits) + self.test_record.currency_id = jpy_currency.id _, content, _ = self.IrQweb._get_field( - self.test_record, "quantity", False, False, {}, values + self.test_record, "value", False, False, {}, values ) - self.assertEqual(content, "13") + self.assertEqual(content, "1") diff --git a/report_qweb_field_option/views/qweb_field_options_views.xml b/report_qweb_field_option/views/qweb_field_options_views.xml index 49644c4..776a4c1 100644 --- a/report_qweb_field_option/views/qweb_field_options_views.xml +++ b/report_qweb_field_option/views/qweb_field_options_views.xml @@ -32,6 +32,7 @@ name="domain" widget="domain" options="{'model': 'res_model_name'}" + optional="hide" /> Date: Fri, 22 May 2026 08:36:35 +0000 Subject: [PATCH 15/25] [DEV-456][IMP] sale_commercial_partner: reflect OCA changes --- sale_commercial_partner/README.rst | 52 +++++++++++-------- sale_commercial_partner/__manifest__.py | 2 +- sale_commercial_partner/models/sale_order.py | 6 +++ sale_commercial_partner/readme/DESCRIPTION.md | 6 ++- .../static/description/index.html | 43 +++++++++------ sale_commercial_partner/views/sale_order.xml | 1 + 6 files changed, 67 insertions(+), 43 deletions(-) diff --git a/sale_commercial_partner/README.rst b/sale_commercial_partner/README.rst index 160719f..877e34f 100644 --- a/sale_commercial_partner/README.rst +++ b/sale_commercial_partner/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ======================= Sale Commercial Partner ======================= @@ -7,13 +11,13 @@ Sale Commercial Partner !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:48f78e60baa0b6a612d1932de433448fab832ca569de6d1604c783e1704a6d66 + !! source digest: sha256:d83afc0a38a3d4e3d8baa1b6aa24dfc827f15efb214581dc66630432c82c7762 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png :target: https://odoo-community.org/page/development-status :alt: Production/Stable -.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsale--workflow-lightgray.png?logo=github @@ -28,8 +32,10 @@ Sale Commercial Partner |badge1| |badge2| |badge3| |badge4| |badge5| -This module adds a related stored field *Commercial Entity* on sale -orders. +This module adds 2 hidden fields on sale orders: + +- a related stored field *Customer Entity*, +- a related stored field *Invoice Entity*. This module is the twin brother of the OCA module *purchase_commercial_partner* located in the `purchase-workflow @@ -46,14 +52,14 @@ Configuration To restrict the invoice address selection to partners whose commercial partner matches the sales order’s customer: -- Go to *Sales → Configuration → Settings*, and enable **Filter Invoice - Address by Customer’s Commercial Partner**. +- Go to *Sales → Configuration → Settings*, and enable **Filter Invoice + Address by Customer’s Commercial Partner**. To restrict the shipping address selection to partners whose commercial partner matches the sales order’s customer: -- Go to *Sales → Configuration → Settings*, and enable **Filter - Shipping Address by Customer’s Commercial Partner**. +- Go to *Sales → Configuration → Settings*, and enable **Filter Shipping + Address by Customer’s Commercial Partner**. Note: These options are not compatible with the sale_partner_address_restrict module. Do not enable them together, as @@ -64,9 +70,9 @@ Usage You can group by *Commercial Entity*: -- in *Sales > Orders > Quotations*, -- in *Sales > Orders > Orders*, -- in *Sales > Reporting > Sales* (it is a native feature in this menu) +- in *Sales > Orders > Quotations*, +- in *Sales > Orders > Orders*, +- in *Sales > Reporting > Sales* (it is a native feature in this menu) Bug Tracker =========== @@ -89,25 +95,25 @@ Authors Contributors ------------ -- Alexis de Lattre -- Serpent Consulting Services Pvt. Ltd. -- Rattapong Chokmasermkul -- Tharathip Chaweewongphan -- `APSL `__: +- Alexis de Lattre +- Serpent Consulting Services Pvt. Ltd. +- Rattapong Chokmasermkul +- Tharathip Chaweewongphan +- `APSL `__: - - Antoni Marroig + - Antoni Marroig -- `Dynapps `__: +- `Dynapps `__: - - Bert Van Groenendael + - Bert Van Groenendael -- `Trobz `__: +- `Trobz `__: - - Nhan Tran + - Nhan Tran -- `Quartile `__: +- `Quartile `__: - - Aung Ko Ko Lin + - Aung Ko Ko Lin Other credits ------------- diff --git a/sale_commercial_partner/__manifest__.py b/sale_commercial_partner/__manifest__.py index 461a439..7c51e02 100644 --- a/sale_commercial_partner/__manifest__.py +++ b/sale_commercial_partner/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Sale Commercial Partner", "summary": "Add stored related field 'Commercial Entity' on sale orders", - "version": "18.0.1.0.1", + "version": "18.0.1.2.0", "development_status": "Production/Stable", "author": "Akretion,Odoo Community Association (OCA)", "maintainers": ["alexis-via"], diff --git a/sale_commercial_partner/models/sale_order.py b/sale_commercial_partner/models/sale_order.py index c1d2db5..e11e1a7 100644 --- a/sale_commercial_partner/models/sale_order.py +++ b/sale_commercial_partner/models/sale_order.py @@ -15,6 +15,12 @@ class SaleOrder(models.Model): store=True, index=True, ) + commercial_partner_invoice_id = fields.Many2one( + comodel_name="res.partner", + related="partner_invoice_id.commercial_partner_id", + string="Invoice Entity", + store=True, + ) partner_invoice_domain = fields.Binary(compute="_compute_partner_domains") partner_shipping_domain = fields.Binary(compute="_compute_partner_domains") diff --git a/sale_commercial_partner/readme/DESCRIPTION.md b/sale_commercial_partner/readme/DESCRIPTION.md index 697c4ed..2362159 100644 --- a/sale_commercial_partner/readme/DESCRIPTION.md +++ b/sale_commercial_partner/readme/DESCRIPTION.md @@ -1,5 +1,7 @@ -This module adds a related stored field *Commercial Entity* on sale -orders. +This module adds 2 hidden fields on sale orders: + +- a related stored field *Customer Entity*, +- a related stored field *Invoice Entity*. This module is the twin brother of the OCA module *purchase_commercial_partner* located in the [purchase-workflow diff --git a/sale_commercial_partner/static/description/index.html b/sale_commercial_partner/static/description/index.html index b19368a..f9591f3 100644 --- a/sale_commercial_partner/static/description/index.html +++ b/sale_commercial_partner/static/description/index.html @@ -3,7 +3,7 @@ -Sale Commercial Partner +README.rst -
    -

    Sale Commercial Partner

    +
    + + +Odoo Community Association + +
    +

    Sale Commercial Partner

    -

    Production/Stable License: AGPL-3 OCA/sale-workflow Translate me on Weblate Try me on Runboat

    -

    This module adds a related stored field Commercial Entity on sale -orders.

    +

    Production/Stable License: AGPL-3 OCA/sale-workflow Translate me on Weblate Try me on Runboat

    +

    This module adds 2 hidden fields on sale orders:

    +
      +
    • a related stored field Customer Entity,
    • +
    • a related stored field Invoice Entity.
    • +

    This module is the twin brother of the OCA module purchase_commercial_partner located in the purchase-workflow project.

    @@ -391,7 +399,7 @@

    Sale Commercial Partner

    -

    Configuration

    +

    Configuration

    To restrict the invoice address selection to partners whose commercial partner matches the sales order’s customer:

      @@ -401,15 +409,15 @@

      Configuration

      To restrict the shipping address selection to partners whose commercial partner matches the sales order’s customer:

        -
      • Go to Sales → Configuration → Settings, and enable Filter -Shipping Address by Customer’s Commercial Partner.
      • +
      • Go to Sales → Configuration → Settings, and enable Filter Shipping +Address by Customer’s Commercial Partner.

      Note: These options are not compatible with the sale_partner_address_restrict module. Do not enable them together, as their address filtering logic conflicts.

    -

    Usage

    +

    Usage

    You can group by Commercial Entity:

    • in Sales > Orders > Quotations,
    • @@ -418,7 +426,7 @@

      Usage

    -

    Bug Tracker

    +

    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 @@ -426,15 +434,15 @@

    Bug Tracker

    Do not contact contributors directly about support or help with technical issues.

    -

    Credits

    +

    Credits

    -

    Authors

    +

    Authors

    • Akretion
    -

    Contributors

    +

    Contributors

    -

    Other credits

    +

    Other credits

    The migration of this module from 17.0 to 18.0 was financially supported by Camptocamp

    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    Odoo Community Association @@ -479,5 +487,6 @@

    Maintainers

    +
    diff --git a/sale_commercial_partner/views/sale_order.xml b/sale_commercial_partner/views/sale_order.xml index efffd98..8b99bde 100644 --- a/sale_commercial_partner/views/sale_order.xml +++ b/sale_commercial_partner/views/sale_order.xml @@ -20,6 +20,7 @@ + From e9f8cc8be887cf360d869131eb26c7d69cc14307 Mon Sep 17 00:00:00 2001 From: Aungkokolin1997 Date: Fri, 22 May 2026 08:36:35 +0000 Subject: [PATCH 16/25] [DEV-456][IMP] sale_line_name_option: reflect OCA changes --- sale_line_name_option/README.rst | 20 ++++++----- sale_line_name_option/__manifest__.py | 1 + .../static/description/icon.png | Bin 0 -> 10254 bytes .../static/description/index.html | 32 +++++++++++------- 4 files changed, 32 insertions(+), 21 deletions(-) create mode 100644 sale_line_name_option/static/description/icon.png diff --git a/sale_line_name_option/README.rst b/sale_line_name_option/README.rst index b0227b6..0474eec 100644 --- a/sale_line_name_option/README.rst +++ b/sale_line_name_option/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ===================== Sale Line Name Option ===================== @@ -7,13 +11,13 @@ Sale Line Name Option !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:8b7cc32533225a4a9ccf8f4f0f53a04b46d43d43b23ab5ece6af2c953397a6cd + !! source digest: sha256:4256d155a4a3b72102bfa4d54b6f028947205a586818fe4066151b76a95102f3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsale--workflow-lightgray.png?logo=github @@ -45,9 +49,9 @@ description because it is not identical to the product display name. Configuration ============= -- Go to Sales → Configuration → Settings -- Enable “No Product Code in Sale Line Name” to hide the product code - in sale order lines. +- Go to Sales → Configuration → Settings +- Enable “No Product Code in Sale Line Name” to hide the product code in + sale order lines. Bug Tracker =========== @@ -70,10 +74,10 @@ Authors Contributors ------------ -- Quartile <> +- Quartile <> - - Yoshi Tashiro - - Aung Ko Ko Lin + - Yoshi Tashiro + - Aung Ko Ko Lin Maintainers ----------- diff --git a/sale_line_name_option/__manifest__.py b/sale_line_name_option/__manifest__.py index 45e48da..8bbc601 100644 --- a/sale_line_name_option/__manifest__.py +++ b/sale_line_name_option/__manifest__.py @@ -2,6 +2,7 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). { "name": "Sale Line Name Option", + "summary": "Display product description without reference code on sale order lines", "author": "Quartile, Odoo Community Association (OCA)", "website": "https://github.com/OCA/sale-workflow", "category": "Sales", diff --git a/sale_line_name_option/static/description/icon.png b/sale_line_name_option/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1dcc49c24f364e9adf0afbc6fc0bac6dbecdeb11 GIT binary patch literal 10254 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 -Sale Line Name Option +README.rst -
    -

    Sale Line Name Option

    +
    + + +Odoo Community Association + +
    +

    Sale Line Name Option

    -

    Beta License: AGPL-3 OCA/sale-workflow Translate me on Weblate Try me on Runboat

    +

    Beta License: AGPL-3 OCA/sale-workflow Translate me on Weblate Try me on Runboat

    This module adds an option to display the product description without the reference code in the sale order line.

    Note: The standard behavior removes duplicate product display names from @@ -391,15 +396,15 @@

    Sale Line Name Option

    -

    Configuration

    +

    Configuration

    • Go to Sales → Configuration → Settings
    • -
    • Enable “No Product Code in Sale Line Name” to hide the product code -in sale order lines.
    • +
    • Enable “No Product Code in Sale Line Name” to hide the product code in +sale order lines.
    -

    Bug Tracker

    +

    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 @@ -407,15 +412,15 @@

    Bug Tracker

    Do not contact contributors directly about support or help with technical issues.

    -

    Credits

    +

    Credits

    -

    Authors

    +

    Authors

    • Quartile
    -

    Contributors

    +

    Contributors

    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    Odoo Community Association @@ -440,5 +445,6 @@

    Maintainers

    +
    From df6804914a2d4eb727b8037f7608bc3cdfadc0fe Mon Sep 17 00:00:00 2001 From: Aungkokolin1997 Date: Fri, 22 May 2026 08:36:35 +0000 Subject: [PATCH 17/25] [DEV-456][IMP] sale_partner_shipping_default_partner_invoice: reflect OCA changes --- .../README.rst | 14 +++++---- .../__manifest__.py | 1 + .../static/description/icon.png | Bin 0 -> 10254 bytes .../static/description/index.html | 28 +++++++++++------- 4 files changed, 27 insertions(+), 16 deletions(-) create mode 100644 sale_partner_shipping_default_partner_invoice/static/description/icon.png diff --git a/sale_partner_shipping_default_partner_invoice/README.rst b/sale_partner_shipping_default_partner_invoice/README.rst index b583af9..6b44445 100644 --- a/sale_partner_shipping_default_partner_invoice/README.rst +++ b/sale_partner_shipping_default_partner_invoice/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ============================================= Sale Partner Shipping Default Partner Invoice ============================================= @@ -7,13 +11,13 @@ Sale Partner Shipping Default Partner Invoice !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:6cd7a702a36cee6bfe335cc52c258eb5e5e2ea14c2bc217bbc10fce45941bc19 + !! source digest: sha256:291194120d028afb3680cc16ef39a3d16467b4f56b7d3cea8066bc0d9e52e282 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsale--workflow-lightgray.png?logo=github @@ -62,10 +66,10 @@ Authors Contributors ------------ -- Quartile +- Quartile - - Yoshi Tashiro - - Aung Ko Ko Lin + - Yoshi Tashiro + - Aung Ko Ko Lin Maintainers ----------- diff --git a/sale_partner_shipping_default_partner_invoice/__manifest__.py b/sale_partner_shipping_default_partner_invoice/__manifest__.py index 8458299..f73929a 100644 --- a/sale_partner_shipping_default_partner_invoice/__manifest__.py +++ b/sale_partner_shipping_default_partner_invoice/__manifest__.py @@ -2,6 +2,7 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). { "name": "Sale Partner Shipping Default Partner Invoice", + "summary": "Set invoice address based on shipping address for sales orders", "author": "Quartile, Odoo Community Association (OCA)", "website": "https://github.com/OCA/sale-workflow", "category": "Sales", diff --git a/sale_partner_shipping_default_partner_invoice/static/description/icon.png b/sale_partner_shipping_default_partner_invoice/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1dcc49c24f364e9adf0afbc6fc0bac6dbecdeb11 GIT binary patch literal 10254 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 -Sale Partner Shipping Default Partner Invoice +README.rst -
    -

    Sale Partner Shipping Default Partner Invoice

    +
    + + +Odoo Community Association + +
    +

    Sale Partner Shipping Default Partner Invoice

    -

    Beta License: AGPL-3 OCA/sale-workflow Translate me on Weblate Try me on Runboat

    +

    Beta License: AGPL-3 OCA/sale-workflow Translate me on Weblate Try me on Runboat

    This module assigns the invoice partner in the sales order based on its shipping partner.

    Table of contents

    @@ -386,11 +391,11 @@

    Sale Partner Shipping Default Partner Invoice

    -

    Configuration

    +

    Configuration

    Open a partner record and assign the Default Invoice Address.

    -

    Bug Tracker

    +

    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 @@ -398,15 +403,15 @@

    Bug Tracker

    Do not contact contributors directly about support or help with technical issues.

    -

    Credits

    +

    Credits

    -

    Authors

    +

    Authors

    • Quartile
    -

    Contributors

    +

    Contributors

    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    Odoo Community Association @@ -431,5 +436,6 @@

    Maintainers

    +
    From e97f4e2d15d8147294ced2aa35ceef66d6f24640 Mon Sep 17 00:00:00 2001 From: Aungkokolin1997 Date: Fri, 22 May 2026 08:36:35 +0000 Subject: [PATCH 18/25] [DEV-456][IMP] sale_pricelist_from_commitment_date: reflect OCA changes --- .../README.rst | 22 +++++++++------ .../static/description/index.html | 28 +++++++++++-------- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/sale_pricelist_from_commitment_date/README.rst b/sale_pricelist_from_commitment_date/README.rst index 4bec0d9..b96cfd1 100644 --- a/sale_pricelist_from_commitment_date/README.rst +++ b/sale_pricelist_from_commitment_date/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + =================================== Sale Pricelist From Commitment Date =================================== @@ -7,13 +11,13 @@ Sale Pricelist From Commitment Date !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:f7cb9a3371d9e916481865df469b90de09062e21e5d03d9af3d450927153ab7c + !! source digest: sha256:dc2e175c722d20b02e262409cb7f948138c18f614c1cfa367b77a1a8202eaf61 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsale--workflow-lightgray.png?logo=github @@ -49,12 +53,12 @@ options: **Show Delivery Date in Header** -- Display the Delivery Date field in header (after the Quotation/Order - Date field) on the sales order form for better visibility. +- Display the Delivery Date field in header (after the Quotation/Order + Date field) on the sales order form for better visibility. **Require Delivery Date** -- Make the Delivery Date field mandatory on sales orders. +- Make the Delivery Date field mandatory on sales orders. Bug Tracker =========== @@ -77,11 +81,11 @@ Authors Contributors ------------ -- Julien Coux -- Quartile +- Julien Coux +- Quartile - - Yoshi Tashiro - - Aung Ko Ko Lin + - Yoshi Tashiro + - Aung Ko Ko Lin Maintainers ----------- diff --git a/sale_pricelist_from_commitment_date/static/description/index.html b/sale_pricelist_from_commitment_date/static/description/index.html index 9f4ce13..240df93 100644 --- a/sale_pricelist_from_commitment_date/static/description/index.html +++ b/sale_pricelist_from_commitment_date/static/description/index.html @@ -3,7 +3,7 @@ -Sale Pricelist From Commitment Date +README.rst -
    -

    Sale Pricelist From Commitment Date

    +
    + + +Odoo Community Association + +
    +

    Sale Pricelist From Commitment Date

    -

    Beta License: AGPL-3 OCA/sale-workflow Translate me on Weblate Try me on Runboat

    +

    Beta License: AGPL-3 OCA/sale-workflow Translate me on Weblate Try me on Runboat

    When the sale order commitment date is set, this date is used by pricelist to compute price unit instead of using order date.

    This module also provides configuration options to enhance the Delivery @@ -390,7 +395,7 @@

    Sale Pricelist From Commitment Date

    -

    Configuration

    +

    Configuration

    Go to Sales → Configuration → Settings to configure the following options:

    Show Delivery Date in Header

    @@ -404,7 +409,7 @@

    Configuration

    -

    Bug Tracker

    +

    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 @@ -412,15 +417,15 @@

    Bug Tracker

    Do not contact contributors directly about support or help with technical issues.

    -

    Credits

    +

    Credits

    -

    Authors

    +

    Authors

    • Camptocamp
    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    Odoo Community Association @@ -444,5 +449,6 @@

    Maintainers

    +
    From 6cc64fc996cf2c0386b1c08da9713dea701acdd2 Mon Sep 17 00:00:00 2001 From: Aungkokolin1997 Date: Fri, 22 May 2026 08:36:36 +0000 Subject: [PATCH 19/25] [DEV-456][IMP] sale_stock_partner_warehouse: reflect OCA changes --- sale_stock_partner_warehouse/README.rst | 20 ++++++++----- sale_stock_partner_warehouse/__manifest__.py | 2 +- .../static/description/index.html | 30 +++++++++++-------- 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/sale_stock_partner_warehouse/README.rst b/sale_stock_partner_warehouse/README.rst index 523dc72..eb3419c 100644 --- a/sale_stock_partner_warehouse/README.rst +++ b/sale_stock_partner_warehouse/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ============================= sale stock partner wharehouse ============================= @@ -7,13 +11,13 @@ sale stock partner wharehouse !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:dbaa850925f0b5b11b70399def5af8275337d1e69a6157981af79407962e6cc2 + !! source digest: sha256:e24b3bd4bdb02ff42b0d24051d3010119795f1fa49490080c976055b5cf86c6f !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsale--workflow-lightgray.png?logo=github @@ -46,8 +50,8 @@ Configuration To set a company-wide default that prioritizes the shipping address’s warehouse (falling back to the customer’s): -- Go to Sales → Configuration → Settings -- Enable "Prioritize Shipping Partner in Sale Warehouse Proposal" +- Go to Sales → Configuration → Settings +- Enable "Prioritize Shipping Partner in Sale Warehouse Proposal" On the partner, choose the default warehouse. @@ -81,11 +85,11 @@ Authors Contributors ------------ -- Telmo Santos -- Jacques-Etienne Baudoux (BCIM) -- Quartile +- Telmo Santos +- Jacques-Etienne Baudoux (BCIM) +- Quartile - - Aung Ko Ko Lin + - Aung Ko Ko Lin Maintainers ----------- diff --git a/sale_stock_partner_warehouse/__manifest__.py b/sale_stock_partner_warehouse/__manifest__.py index f4e5450..c108127 100644 --- a/sale_stock_partner_warehouse/__manifest__.py +++ b/sale_stock_partner_warehouse/__manifest__.py @@ -4,7 +4,7 @@ "name": "sale stock partner wharehouse", "summary": "Allow to choose by default a warehouse on SO " "based on a Partner parameter", - "version": "18.0.1.0.0", + "version": "18.0.1.1.0", "development_status": "Beta", "category": "Warehouse Management", "website": "https://github.com/OCA/sale-workflow", diff --git a/sale_stock_partner_warehouse/static/description/index.html b/sale_stock_partner_warehouse/static/description/index.html index 43970ba..d99edea 100644 --- a/sale_stock_partner_warehouse/static/description/index.html +++ b/sale_stock_partner_warehouse/static/description/index.html @@ -3,7 +3,7 @@ -sale stock partner wharehouse +README.rst -
    -

    sale stock partner wharehouse

    +
    + + +Odoo Community Association + +
    +

    sale stock partner wharehouse

    -

    Beta License: AGPL-3 OCA/sale-workflow Translate me on Weblate Try me on Runboat

    +

    Beta License: AGPL-3 OCA/sale-workflow Translate me on Weblate Try me on Runboat

    Allow to choose by default a warehouse on SO based on a Partner parameter.

    If the warehouse parameter is completed, then this value would be the @@ -390,7 +395,7 @@

    sale stock partner wharehouse

    -

    Configuration

    +

    Configuration

    To set a company-wide default that prioritizes the shipping address’s warehouse (falling back to the customer’s):

    -

    Usage

    +

    Usage

    You need at least to manage 2 different warehouses.

    -

    Bug Tracker

    +

    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 @@ -414,16 +419,16 @@

    Bug Tracker

    Do not contact contributors directly about support or help with technical issues.

    -

    Credits

    +

    Credits

    -

    Authors

    +

    Authors

    • Camptocamp
    • BCIM
    -

    Contributors

    +

    Contributors

    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    Odoo Community Association @@ -447,5 +452,6 @@

    Maintainers

    +
    From eea22a5d06adaeadd09d11a6b6228769015d606b Mon Sep 17 00:00:00 2001 From: Aungkokolin1997 Date: Fri, 22 May 2026 08:36:36 +0000 Subject: [PATCH 20/25] [DEV-456][IMP] stock_move_actual_date: reflect OCA changes --- stock_move_actual_date/README.rst | 49 +++++++++-------- stock_move_actual_date/__manifest__.py | 2 +- stock_move_actual_date/models/stock_move.py | 5 +- .../models/stock_picking.py | 5 ++ .../static/description/index.html | 53 ++++++++++--------- .../tests/test_stock_move_actual_date.py | 24 +++++++-- .../views/stock_valuation_layer_views.xml | 14 +++++ 7 files changed, 99 insertions(+), 53 deletions(-) diff --git a/stock_move_actual_date/README.rst b/stock_move_actual_date/README.rst index 8e4ea72..ed3440c 100644 --- a/stock_move_actual_date/README.rst +++ b/stock_move_actual_date/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ====================== Stock Move Actual Date ====================== @@ -7,13 +11,13 @@ Stock Move Actual Date !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:542dce805f57e02c2591a7f294a99014d5403db35500251cf01cdb3e8b6a7372 + !! source digest: sha256:503c8df4ebebe42cf83cb42803c51f4c65a437cb2158e0c521745f5ae438c3d4 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstock--logistics--workflow-lightgray.png?logo=github @@ -37,11 +41,10 @@ It also adds an Actual Date field to the Stock Valuation Layer model, enabling reporting based on this field. This field is computed and stored according to the following logic: -- If a posted journal entry exists, its date is used. -- If there is no journal entry, the stock move's actual date is used -- Otherwise, convert create_date (datetime) of the - stock.valuation.layer record to date, with consideration to user's - timezone. +- If a posted journal entry exists, its date is used. +- If there is no journal entry, the stock move's actual date is used +- Otherwise, convert create_date (datetime) of the stock.valuation.layer + record to date, with consideration to user's timezone. It also provides stock quantity history reporting based on the actual date. @@ -54,25 +57,25 @@ date. Configuration ============= -- Go to Settings > Users & Companies > Groups. -- Open 'Modify Actual Date' and add the users who are allowed to edit - the actual date of completed records (e.g., pickings, scraps). +- Go to Settings > Users & Companies > Groups. +- Open 'Modify Actual Date' and add the users who are allowed to edit + the actual date of completed records (e.g., pickings, scraps). Usage ===== Use the Actual Date field in the following transfer and scrap scenarios: -- If you are late in processing a transfer or scrap in Odoo and wish to - record the transaction with the actual transfer date, fill in the - Actual Date field in the picking or scrap form. The Actual Date of - the picking or scrap is then propagated to its corresponding stock - moves and stock move lines, and is also passed to the journal entry - as the date. -- You can also update the Actual Date of a completed picking or scrap - if you belong to the 'Modify Actual Date' group. This operation - updates the date of the related journal entries, re-proposing a new - sequence to them as necessary. +- If you are late in processing a transfer or scrap in Odoo and wish to + record the transaction with the actual transfer date, fill in the + Actual Date field in the picking or scrap form. The Actual Date of the + picking or scrap is then propagated to its corresponding stock moves + and stock move lines, and is also passed to the journal entry as the + date. +- You can also update the Actual Date of a completed picking or scrap if + you belong to the 'Modify Actual Date' group. This operation updates + the date of the related journal entries, re-proposing a new sequence + to them as necessary. Use the Actual Date field in the following stock valuation reporting scenarios: @@ -128,10 +131,10 @@ Authors Contributors ------------ -- `Quartile `__: +- `Quartile `__: - - Aung Ko Ko Lin - - Yoshi Tashiro + - Aung Ko Ko Lin + - Yoshi Tashiro Maintainers ----------- diff --git a/stock_move_actual_date/__manifest__.py b/stock_move_actual_date/__manifest__.py index bbfbe59..c6a27ff 100644 --- a/stock_move_actual_date/__manifest__.py +++ b/stock_move_actual_date/__manifest__.py @@ -2,7 +2,7 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). { "name": "Stock Move Actual Date", - "version": "18.0.1.0.0", + "version": "18.0.1.0.1", "author": "Quartile, Odoo Community Association (OCA)", "website": "https://github.com/OCA/stock-logistics-workflow", "category": "Stock", diff --git a/stock_move_actual_date/models/stock_move.py b/stock_move_actual_date/models/stock_move.py index 9f38936..281a57e 100644 --- a/stock_move_actual_date/models/stock_move.py +++ b/stock_move_actual_date/models/stock_move.py @@ -12,7 +12,8 @@ class StockMove(models.Model): store=True, ) actual_date_source = fields.Date( - help="Technical field to store the actual_date of the source document." + copy=False, + help="Technical field to store the actual_date of the source document.", ) def _get_timezone(self): @@ -74,7 +75,7 @@ def _read_group( ) def _action_done(self, cancel_backorder=False): - moves = super()._action_done(cancel_backorder) + moves = super()._action_done(cancel_backorder=cancel_backorder) # i.e. Inventory adjustments with actual date if self.env.context.get("force_period_date"): self.write({"actual_date_source": self.env.context["force_period_date"]}) diff --git a/stock_move_actual_date/models/stock_picking.py b/stock_move_actual_date/models/stock_picking.py index 95061e0..b695a7e 100644 --- a/stock_move_actual_date/models/stock_picking.py +++ b/stock_move_actual_date/models/stock_picking.py @@ -14,3 +14,8 @@ def _get_actual_date_update_triggers(self): def _get_stock_moves(self): self.ensure_one() return self.move_ids + + def _create_backorder(self, backorder_moves=None): + backorders = super()._create_backorder(backorder_moves=backorder_moves) + backorders.move_ids.filtered("actual_date_source").actual_date_source = False + return backorders diff --git a/stock_move_actual_date/static/description/index.html b/stock_move_actual_date/static/description/index.html index 810df09..d48b8aa 100644 --- a/stock_move_actual_date/static/description/index.html +++ b/stock_move_actual_date/static/description/index.html @@ -3,7 +3,7 @@ -Stock Move Actual Date +README.rst -
    -

    Stock Move Actual Date

    +
    + + +Odoo Community Association + +
    +

    Stock Move Actual Date

    -

    Beta License: AGPL-3 OCA/stock-logistics-workflow Translate me on Weblate Try me on Runboat

    +

    Beta License: AGPL-3 OCA/stock-logistics-workflow Translate me on Weblate Try me on Runboat

    This module adds an Actual Date field to the stock picking, stock scrap, stock move, and stock move line models. This field allows users to record the actual date on which a stock transfer or stock scrap took @@ -380,9 +385,8 @@

    Stock Move Actual Date

    • If a posted journal entry exists, its date is used.
    • If there is no journal entry, the stock move’s actual date is used
    • -
    • Otherwise, convert create_date (datetime) of the -stock.valuation.layer record to date, with consideration to user’s -timezone.
    • +
    • Otherwise, convert create_date (datetime) of the stock.valuation.layer +record to date, with consideration to user’s timezone.

    It also provides stock quantity history reporting based on the actual date.

    @@ -402,7 +406,7 @@

    Stock Move Actual Date

    -

    Configuration

    +

    Configuration

    • Go to Settings > Users & Companies > Groups.
    • Open ‘Modify Actual Date’ and add the users who are allowed to edit @@ -410,19 +414,19 @@

      Configuration

    -

    Usage

    +

    Usage

    Use the Actual Date field in the following transfer and scrap scenarios:

    • If you are late in processing a transfer or scrap in Odoo and wish to record the transaction with the actual transfer date, fill in the -Actual Date field in the picking or scrap form. The Actual Date of -the picking or scrap is then propagated to its corresponding stock -moves and stock move lines, and is also passed to the journal entry -as the date.
    • -
    • You can also update the Actual Date of a completed picking or scrap -if you belong to the ‘Modify Actual Date’ group. This operation -updates the date of the related journal entries, re-proposing a new -sequence to them as necessary.
    • +Actual Date field in the picking or scrap form. The Actual Date of the +picking or scrap is then propagated to its corresponding stock moves +and stock move lines, and is also passed to the journal entry as the +date. +
    • You can also update the Actual Date of a completed picking or scrap if +you belong to the ‘Modify Actual Date’ group. This operation updates +the date of the related journal entries, re-proposing a new sequence +to them as necessary.

    Use the Actual Date field in the following stock valuation reporting scenarios:

    @@ -445,7 +449,7 @@

    Usage

    stock_quantity_history_location.

    -

    Known issues / Roadmap

    +

    Known issues / Roadmap

    Updating the Actual Date of a completed receipt picking for a foreign currency purchase does not trigger a recalculation of the amounts in the associated journal entries, even if the currency rate for the new date @@ -456,7 +460,7 @@

    Known issues / Roadmap

    timezone will be assigned.

    -

    Bug Tracker

    +

    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 @@ -464,15 +468,15 @@

    Bug Tracker

    Do not contact contributors directly about support or help with technical issues.

    -

    Credits

    +

    Credits

    -

    Authors

    +

    Authors

    • Quartile
    -

    Contributors

    +

    Contributors

    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    Odoo Community Association @@ -497,5 +501,6 @@

    Maintainers

    +
    diff --git a/stock_move_actual_date/tests/test_stock_move_actual_date.py b/stock_move_actual_date/tests/test_stock_move_actual_date.py index f15d877..13becb4 100644 --- a/stock_move_actual_date/tests/test_stock_move_actual_date.py +++ b/stock_move_actual_date/tests/test_stock_move_actual_date.py @@ -40,7 +40,7 @@ def setUpClass(cls): cls.supplier_location = cls.env.ref("stock.stock_location_suppliers") cls.stock_location = cls.env.ref("stock.stock_location_stock") - def create_picking(self, actual_date=False): + def create_picking(self, actual_date=False, is_done=True): receipt = self.env["stock.picking"].create( { "location_id": self.supplier_location.id, @@ -72,8 +72,9 @@ def create_picking(self, actual_date=False): } ) receipt.move_ids._action_confirm() - receipt.move_ids.picked = True - receipt.move_ids._action_done() + if is_done: + receipt.move_ids.picked = True + receipt.move_ids._action_done() return receipt, receipt.move_ids def create_scrap(self, receipt, actual_date=False): @@ -207,3 +208,20 @@ def test_open_qty_at_actual_date(self): self.assertEqual( self.product_1.with_context(**action["context"]).qty_available, 10.0 ) + + def test_backorder_picking_actual_date(self): + picking, move = self.create_picking(date(2025, 3, 10), is_done=False) + move.move_line_ids.quantity = 5.0 + backorder_wizard_values = picking.button_validate() + backorder_wizard = ( + self.env[(backorder_wizard_values.get("res_model"))] + .browse(backorder_wizard_values.get("res_id")) + .with_context(**backorder_wizard_values["context"]) + ) + backorder_wizard.process() + backorder = self.env["stock.picking"].search( + [("backorder_id", "=", picking.id)], limit=1 + ) + self.assertTrue(backorder, "Backorder picking should be created.") + self.assertFalse(backorder.actual_date) + self.assertFalse(backorder.move_ids.actual_date_source) diff --git a/stock_move_actual_date/views/stock_valuation_layer_views.xml b/stock_move_actual_date/views/stock_valuation_layer_views.xml index a2884c0..6cb1d1d 100644 --- a/stock_move_actual_date/views/stock_valuation_layer_views.xml +++ b/stock_move_actual_date/views/stock_valuation_layer_views.xml @@ -19,4 +19,18 @@
    + + stock.valuation.layer.search + stock.valuation.layer + + + + + + + From e1a670a9aa45e4b6d736c36ca6ef6c94cf0fecd1 Mon Sep 17 00:00:00 2001 From: Aungkokolin1997 Date: Fri, 22 May 2026 08:36:36 +0000 Subject: [PATCH 21/25] [DEV-456][IMP] stock_secondary_unit: reflect OCA changes --- stock_secondary_unit/README.rst | 6 +-- stock_secondary_unit/__manifest__.py | 1 - stock_secondary_unit/models/__init__.py | 1 - .../models/product_template.py | 13 +---- stock_secondary_unit/models/stock_move.py | 8 +++- stock_secondary_unit/models/stock_quant.py | 23 --------- stock_secondary_unit/readme/CONTRIBUTORS.md | 2 - stock_secondary_unit/readme/DESCRIPTION.md | 2 - .../static/description/index.html | 7 +-- .../tests/test_stock_secondary_unit.py | 47 ------------------- .../views/stock_quant_views.xml | 36 -------------- 11 files changed, 9 insertions(+), 137 deletions(-) delete mode 100644 stock_secondary_unit/models/stock_quant.py delete mode 100644 stock_secondary_unit/views/stock_quant_views.xml diff --git a/stock_secondary_unit/README.rst b/stock_secondary_unit/README.rst index ac252a2..743f152 100644 --- a/stock_secondary_unit/README.rst +++ b/stock_secondary_unit/README.rst @@ -29,8 +29,7 @@ Stock Secondary Unit |badge1| |badge2| |badge3| |badge4| |badge5| This module extends the functionality of stock module to allow define -other units with their conversion factor. It also introduces a secondary -UoM on stock quants and displays the corresponding converted quantity. +other units with their conversion factor. **Table of contents** @@ -87,9 +86,6 @@ Contributors - Kitti Upariphutthiphong - Pimolnat Suntian - Alan Ramos -- `Quartile `__: - - - Aung Ko Ko Lin Maintainers ----------- diff --git a/stock_secondary_unit/__manifest__.py b/stock_secondary_unit/__manifest__.py index c75aa20..a0fc273 100644 --- a/stock_secondary_unit/__manifest__.py +++ b/stock_secondary_unit/__manifest__.py @@ -16,7 +16,6 @@ "views/product_views.xml", "views/stock_move_views.xml", "views/stock_picking_views.xml", - "views/stock_quant_views.xml", "report/report_deliveryslip.xml", ], } diff --git a/stock_secondary_unit/models/__init__.py b/stock_secondary_unit/models/__init__.py index 643b81f..d342115 100644 --- a/stock_secondary_unit/models/__init__.py +++ b/stock_secondary_unit/models/__init__.py @@ -4,4 +4,3 @@ from . import product_product from . import product_template from . import stock_move -from . import stock_quant diff --git a/stock_secondary_unit/models/product_template.py b/stock_secondary_unit/models/product_template.py index 8012aa0..c8b1845 100644 --- a/stock_secondary_unit/models/product_template.py +++ b/stock_secondary_unit/models/product_template.py @@ -1,6 +1,6 @@ # Copyright 2018 Tecnativa - Sergio Teruel # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -from odoo import api, fields, models +from odoo import fields, models class ProductTemplate(models.Model): @@ -11,15 +11,4 @@ class ProductTemplate(models.Model): comodel_name="product.secondary.unit", domain="[('product_tmpl_id', '=', id), ('product_id', '=', False)]", string="Second unit for inventory", - compute="_compute_stock_secondary_uom_id", - inverse="_inverse_stock_secondary_uom_id", - store=True, - readonly=False, ) - - @api.depends("product_variant_ids.stock_secondary_uom_id") - def _compute_stock_secondary_uom_id(self): - self._compute_template_secondary_uom_field("stock_secondary_uom_id") - - def _inverse_stock_secondary_uom_id(self): - self._inverse_template_secondary_uom_field("stock_secondary_uom_id") diff --git a/stock_secondary_unit/models/stock_move.py b/stock_secondary_unit/models/stock_move.py index 7493ce4..599039e 100644 --- a/stock_secondary_unit/models/stock_move.py +++ b/stock_secondary_unit/models/stock_move.py @@ -84,8 +84,12 @@ def default_get(self, fields_list): res = super().default_get(fields_list) move_id = self.env.context.get("default_move_id") or res.get("move_id") if move_id and not res.get("secondary_uom_id"): - move = self.env["stock.move"].browse(move_id) - if move.secondary_uom_id: + # default_move_id may resolve to the MO id instead of the stock.move id + # when saving the detailed operations dialog from an MO component line + # (https://github.com/odoo/odoo/issues/261740); a wrong default here + # should be harmless as it only pre-fills the line + move = self.env["stock.move"].browse(move_id).exists() + if move and move.secondary_uom_id: res["secondary_uom_id"] = move.secondary_uom_id.id return res diff --git a/stock_secondary_unit/models/stock_quant.py b/stock_secondary_unit/models/stock_quant.py deleted file mode 100644 index cf8a6b2..0000000 --- a/stock_secondary_unit/models/stock_quant.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2025 Quartile (https://wwww.quartile.co) -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). - -from odoo import api, fields, models - - -class StockQuant(models.Model): - _inherit = ["stock.quant", "product.secondary.unit.mixin"] - _name = "stock.quant" - _secondary_unit_fields = {"qty_field": "quantity", "uom_field": "product_uom_id"} - - secondary_uom_id = fields.Many2one( - related="product_id.stock_secondary_uom_id", - store=True, - default=None, - ) - # Need precompute=False since secondary_uom_id is not precompute field and we - # shouldn't depend for compute method of precompute field. - secondary_uom_qty = fields.Float(precompute=False) - - @api.model - def _get_secondary_uom_qty_depends(self): - return super()._get_secondary_uom_qty_depends() + ["secondary_uom_id"] diff --git a/stock_secondary_unit/readme/CONTRIBUTORS.md b/stock_secondary_unit/readme/CONTRIBUTORS.md index 1d7af65..e72adc2 100644 --- a/stock_secondary_unit/readme/CONTRIBUTORS.md +++ b/stock_secondary_unit/readme/CONTRIBUTORS.md @@ -5,5 +5,3 @@ - Kitti Upariphutthiphong \<\> - Pimolnat Suntian \<\> - Alan Ramos \<\> -- [Quartile](https://www.quartile.co): - - Aung Ko Ko Lin diff --git a/stock_secondary_unit/readme/DESCRIPTION.md b/stock_secondary_unit/readme/DESCRIPTION.md index 2ccb98c..ce69e85 100644 --- a/stock_secondary_unit/readme/DESCRIPTION.md +++ b/stock_secondary_unit/readme/DESCRIPTION.md @@ -1,4 +1,2 @@ This module extends the functionality of stock module to allow define other units with their conversion factor. -It also introduces a secondary UoM on stock quants and displays the corresponding -converted quantity. diff --git a/stock_secondary_unit/static/description/index.html b/stock_secondary_unit/static/description/index.html index 80a97ad..49b56f6 100644 --- a/stock_secondary_unit/static/description/index.html +++ b/stock_secondary_unit/static/description/index.html @@ -371,8 +371,7 @@

    Stock Secondary Unit

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Production/Stable License: AGPL-3 OCA/stock-logistics-warehouse Translate me on Weblate Try me on Runboat

    This module extends the functionality of stock module to allow define -other units with their conversion factor. It also introduces a secondary -UoM on stock quants and displays the corresponding converted quantity.

    +other units with their conversion factor.

    Table of contents

    diff --git a/stock_secondary_unit/tests/test_stock_secondary_unit.py b/stock_secondary_unit/tests/test_stock_secondary_unit.py index 287c4f3..837f8da 100644 --- a/stock_secondary_unit/tests/test_stock_secondary_unit.py +++ b/stock_secondary_unit/tests/test_stock_secondary_unit.py @@ -245,53 +245,6 @@ def test_secondary_unit_merge_move_same_uom(self): self.assertEqual(len(picking.move_ids), 1) self.assertEqual(picking.move_ids.secondary_uom_qty, 2) - def test_stock_quant_secondary_uom_qty(self): - template = self.env["product.template"].create( - { - "name": "test", - "uom_id": self.product_uom_unit.id, - "is_storable": True, - "secondary_uom_ids": [ - Command.create( - { - "code": "T", - "name": "unit-2", - "uom_id": self.product_uom_unit.id, - "factor": 0.5, - }, - ), - Command.create( - { - "code": "U", - "name": "unit-4", - "uom_id": self.product_uom_unit.id, - "factor": 0.25, - }, - ), - ], - } - ) - secondary_uom_1 = template.secondary_uom_ids[0] - secondary_uom_2 = template.secondary_uom_ids[1] - product = template.product_variant_ids[0] - # Test variant's secondary UoM is applied to quant - product.stock_secondary_uom_id = secondary_uom_1 - quant = self.env["stock.quant"].create( - { - "location_id": self.location_stock.id, - "product_id": product.id, - "inventory_quantity": 10, - } - ) - quant.action_apply_inventory() - self.assertEqual(quant.secondary_uom_id, secondary_uom_1) - self.assertEqual(quant.secondary_uom_qty, 20) - # Test template's secondary UoM syncs to variant (single-variant product) - template.stock_secondary_uom_id = secondary_uom_2 - self.assertEqual(product.stock_secondary_uom_id, secondary_uom_2) - self.assertEqual(quant.secondary_uom_id, secondary_uom_2) - self.assertEqual(quant.secondary_uom_qty, 40) - def test_action_generate_lot_line_vals(self): picking = self.env["stock.picking"].create( { diff --git a/stock_secondary_unit/views/stock_quant_views.xml b/stock_secondary_unit/views/stock_quant_views.xml deleted file mode 100644 index 87dd126..0000000 --- a/stock_secondary_unit/views/stock_quant_views.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - stock.quant.inventory.list.editable - stock.quant - - - - - - - - - - stock.quant.list.editable - stock.quant - - - - - - - - - From 9f4558fa77c2b4e51f7a4f1c1208cb11b62866fd Mon Sep 17 00:00:00 2001 From: Aungkokolin1997 Date: Fri, 22 May 2026 08:36:36 +0000 Subject: [PATCH 22/25] [DEV-456][IMP] template_content_swapper: reflect OCA changes --- .../models/template_content_mapping.py | 2 +- .../views/template_content_mapping_views.xml | 32 ++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/template_content_swapper/models/template_content_mapping.py b/template_content_swapper/models/template_content_mapping.py index 64d5481..6825bbb 100644 --- a/template_content_swapper/models/template_content_mapping.py +++ b/template_content_swapper/models/template_content_mapping.py @@ -113,6 +113,6 @@ def open_template_mapping(self): "type": "ir.actions.act_window", "name": "Template Content Mappings", "res_model": "template.content.mapping", - "view_mode": "list", + "view_mode": "list,form", "context": {"multi_lang": multi_lang}, } diff --git a/template_content_swapper/views/template_content_mapping_views.xml b/template_content_swapper/views/template_content_mapping_views.xml index 8602b74..5324761 100644 --- a/template_content_swapper/views/template_content_mapping_views.xml +++ b/template_content_swapper/views/template_content_mapping_views.xml @@ -4,7 +4,7 @@ template.content.mapping.list template.content.mapping - + @@ -21,6 +21,36 @@ + + template.content.mapping.form + template.content.mapping + +
    + + + + + + + + + + + + + + + + + + + +
    +
    +
    template.content.mapping.search template.content.mapping From 462c07a548cd9d8c7f3e3bcf5038c16ab79076e8 Mon Sep 17 00:00:00 2001 From: Aungkokolin1997 Date: Fri, 22 May 2026 08:36:36 +0000 Subject: [PATCH 23/25] [DEV-456][IMP] web_favicon: reflect OCA changes --- web_favicon/README.rst | 8 ++++-- web_favicon/__manifest__.py | 2 +- web_favicon/models/res_company.py | 4 +-- web_favicon/static/description/index.html | 30 ++++++++++++++--------- web_favicon/tests/test_web_favicon.py | 9 ++++--- 5 files changed, 32 insertions(+), 21 deletions(-) diff --git a/web_favicon/README.rst b/web_favicon/README.rst index 915a91a..fdbc9b5 100644 --- a/web_favicon/README.rst +++ b/web_favicon/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ==================== Custom shortcut icon ==================== @@ -7,13 +11,13 @@ Custom shortcut icon !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:fa990988a68288b8264800bce0451c78b1223106dbcd4996b260a5e9743fc460 + !! source digest: sha256:298837fb4ce178618580cba6cfa0f6d5e1d3c41ef4d05ab89807f73255c1fd26 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fweb-lightgray.png?logo=github diff --git a/web_favicon/__manifest__.py b/web_favicon/__manifest__.py index 4f55e4a..a0d7c9a 100644 --- a/web_favicon/__manifest__.py +++ b/web_favicon/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Custom shortcut icon", - "version": "18.0.1.0.0", + "version": "18.0.1.0.1", "author": "Therp BV, " "Tecnativa, " "OERP Canada," diff --git a/web_favicon/models/res_company.py b/web_favicon/models/res_company.py index f0f468a..f40eeb6 100644 --- a/web_favicon/models/res_company.py +++ b/web_favicon/models/res_company.py @@ -72,9 +72,7 @@ def _get_favicon(self): website = self.env["website"].browse(self.env.context.get("website_id")) return website.image_url(website, "favicon") company_id = ( - request.httprequest.cookies.get("cids") - if request.httprequest.cookies.get("cids") - else False + request.cookies.get("cids") if request.cookies.get("cids") else False ) company = ( self.browse(int(company_id.split("-")[0])).sudo() diff --git a/web_favicon/static/description/index.html b/web_favicon/static/description/index.html index fa620bc..f274f76 100644 --- a/web_favicon/static/description/index.html +++ b/web_favicon/static/description/index.html @@ -3,7 +3,7 @@ -Custom shortcut icon +README.rst -
    -

    Custom shortcut icon

    +
    + + +Odoo Community Association + +
    +

    Custom shortcut icon

    -

    Beta License: AGPL-3 OCA/web Translate me on Weblate Try me on Runboat

    +

    Beta License: AGPL-3 OCA/web Translate me on Weblate Try me on Runboat

    This module was written to allow you to customize your Odoo instance’s shortcut icon (aka favicon). This is useful for branding purposes, but also for integrators who have many different Odoo instances running and @@ -392,7 +397,7 @@

    Custom shortcut icon

    -

    Configuration

    +

    Configuration

    Upload your favicon (16x16, 32x32, 64x64 or “as big as possible”) on the company form. The file format would be ico, gif or png with 16x16, 32x32 or 64x64 pixels and 16 colors. Highers resolutions or colors support @@ -408,7 +413,7 @@

    Configuration

    “Administration / Settings”.

    -

    Known issues / Roadmap

    +

    Known issues / Roadmap

    • Allow to upload some big icon (preferrably SVG or the like) and generate all the icons from it
    • @@ -421,7 +426,7 @@

      Known issues / Roadmap

    -

    Bug Tracker

    +

    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 @@ -429,9 +434,9 @@

    Bug Tracker

    Do not contact contributors directly about support or help with technical issues.

    -

    Credits

    +

    Credits

    -

    Authors

    +

    Authors

    • Therp BV
    • Tecnativa
    • @@ -439,7 +444,7 @@

      Authors

    -

    Contributors

    +

    Contributors

    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    Odoo Community Association @@ -461,5 +466,6 @@

    Maintainers

    +
    diff --git a/web_favicon/tests/test_web_favicon.py b/web_favicon/tests/test_web_favicon.py index 387c53b..afc8eeb 100644 --- a/web_favicon/tests/test_web_favicon.py +++ b/web_favicon/tests/test_web_favicon.py @@ -38,7 +38,7 @@ def test_01_web_favicon(self): self.assertEqual(image.size, (1920, 1080)) self.assertEqual(image.getpixel((0, 0)), bg_color) with MockRequest(self.env) as mock_request: - mock_request.httprequest.cookies = {"cids": str(company.id)} + mock_request.cookies = {"cids": str(company.id)} self.assertTrue(Company._get_favicon()) def test_02_default_favicon_creation(self): @@ -83,10 +83,13 @@ def test_04_favicon_multiple_companies(self): company_2 = Company.create( {"name": "Company 2", "favicon": Company._get_default_favicon()} ) + company_3 = Company.create( + {"name": "Company 3", "favicon": Company._get_default_favicon()} + ) with MockRequest(self.env) as mock_request: - mock_request.httprequest.cookies = { - "cids": f"{company_1.id}-{company_2.id}" + mock_request.cookies = { + "cids": f"{company_1.id}-{company_2.id}-{company_3.id}" } favicon_url = Company._get_favicon() From c686636b947254ac3589d7cd109d3ce439a7eebc Mon Sep 17 00:00:00 2001 From: Aungkokolin1997 Date: Fri, 22 May 2026 08:36:36 +0000 Subject: [PATCH 24/25] [DEV-456][IMP] web_form_banner: reflect OCA changes --- web_form_banner/README.rst | 2 +- web_form_banner/__manifest__.py | 2 +- web_form_banner/static/description/index.html | 2 +- .../static/src/js/web_form_banner.esm.js | 20 +++++++++++-------- .../views/web_form_banner_rule_views.xml | 2 +- 5 files changed, 16 insertions(+), 12 deletions(-) diff --git a/web_form_banner/README.rst b/web_form_banner/README.rst index 54d2f8e..94b6c0c 100644 --- a/web_form_banner/README.rst +++ b/web_form_banner/README.rst @@ -11,7 +11,7 @@ Web Form Banner !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:1906dbf6835e99a279704d8927db5c2e74b3583721880d44069dc0e1f9cfe84c + !! source digest: sha256:d5dd848e3f2205d7a480f4606bad02c27855e9a060c2593c209f79dbdfa14a0d !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/web_form_banner/__manifest__.py b/web_form_banner/__manifest__.py index 5b070aa..1b0c230 100644 --- a/web_form_banner/__manifest__.py +++ b/web_form_banner/__manifest__.py @@ -2,7 +2,7 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). { "name": "Web Form Banner", - "version": "18.0.1.0.0", + "version": "18.0.1.1.0", "category": "Web", "author": "Quartile, Odoo Community Association (OCA)", "website": "https://github.com/OCA/web", diff --git a/web_form_banner/static/description/index.html b/web_form_banner/static/description/index.html index 457e033..ac269e1 100644 --- a/web_form_banner/static/description/index.html +++ b/web_form_banner/static/description/index.html @@ -372,7 +372,7 @@

    Web Form Banner

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:1906dbf6835e99a279704d8927db5c2e74b3583721880d44069dc0e1f9cfe84c +!! source digest: sha256:d5dd848e3f2205d7a480f4606bad02c27855e9a060c2593c209f79dbdfa14a0d !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: AGPL-3 OCA/web Translate me on Weblate Try me on Runboat

    The module adds configurable banners for backend form views. Define diff --git a/web_form_banner/static/src/js/web_form_banner.esm.js b/web_form_banner/static/src/js/web_form_banner.esm.js index 8211caa..8cc0760 100644 --- a/web_form_banner/static/src/js/web_form_banner.esm.js +++ b/web_form_banner/static/src/js/web_form_banner.esm.js @@ -1,4 +1,3 @@ -/** @odoo-module **/ // Copyright 2025 Quartile (https://www.quartile.co) // License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). @@ -30,19 +29,24 @@ const safe = async (fn, fb) => { return fb; }; -/* eslint-disable no-inline-comments */ function normalizeValue(v) { - if (v === null || v === undefined) return v; // Null/undefined + // Null/undefined + if (v === null || v === undefined) return v; const t = typeof v; if (t === "string" || t === "number" || t === "boolean") return v; if (Array.isArray(v)) - return v.length === 2 && typeof v[1] === "string" ? v[0] : [...v]; // M2o id or cloned m2m ids + // M2o id or cloned m2m ids + return v.length === 2 && typeof v[1] === "string" ? v[0] : [...v]; if (t === "object") { - if (typeof v.res_id === "number") return v.res_id; // M2o snapshot - if (typeof v.id === "number") return v.id; // M2o env - if (Array.isArray(v._currentIds)) return [...v._currentIds]; // M2m + // M2o snapshot + if (typeof v.res_id === "number") return v.res_id; + // M2o env + if (typeof v.id === "number") return v.id; + // M2m + if (Array.isArray(v._currentIds)) return [...v._currentIds]; } - return undefined; // Ignore others (e.g., command lists) + // Ignore others (e.g., command lists) + return undefined; } function shrink(data) { const out = {}; diff --git a/web_form_banner/views/web_form_banner_rule_views.xml b/web_form_banner/views/web_form_banner_rule_views.xml index 7db6561..0697efc 100644 --- a/web_form_banner/views/web_form_banner_rule_views.xml +++ b/web_form_banner/views/web_form_banner_rule_views.xml @@ -113,7 +113,7 @@ (one2many/reference, etc).

  • current_id: Integer id of the record being edited, or record_id: Integer id of the record being edited, or False if the form is creating a new record.
  • From 42722a606b2972fadb4ef1d7b2f5b9aecb377f12 Mon Sep 17 00:00:00 2001 From: Aungkokolin1997 Date: Fri, 22 May 2026 08:36:36 +0000 Subject: [PATCH 25/25] [DEV-456][IMP] web_m2x_options: reflect OCA changes --- web_m2x_options/README.rst | 2 +- web_m2x_options/__manifest__.py | 2 +- web_m2x_options/static/description/index.html | 2 +- .../static/src/components/form.esm.js | 63 ++++++++++++------- 4 files changed, 44 insertions(+), 25 deletions(-) diff --git a/web_m2x_options/README.rst b/web_m2x_options/README.rst index 25df0b2..84c42c5 100644 --- a/web_m2x_options/README.rst +++ b/web_m2x_options/README.rst @@ -11,7 +11,7 @@ web_m2x_options !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:881a75e6602b8037ae91fff6ff77e99caff9cba4b1ccda3dff174f64f4e42824 + !! source digest: sha256:72edae262a5750aa942302a30dfa960c912c99d637f4777222243f3e021f3924 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/web_m2x_options/__manifest__.py b/web_m2x_options/__manifest__.py index 47ddd26..e075c44 100644 --- a/web_m2x_options/__manifest__.py +++ b/web_m2x_options/__manifest__.py @@ -6,7 +6,7 @@ { "name": "web_m2x_options", - "version": "18.0.1.0.1", + "version": "18.0.1.0.3", "category": "Web", "author": "initOS GmbH," "ACSONE SA/NV, " diff --git a/web_m2x_options/static/description/index.html b/web_m2x_options/static/description/index.html index 3330f38..181a3ea 100644 --- a/web_m2x_options/static/description/index.html +++ b/web_m2x_options/static/description/index.html @@ -372,7 +372,7 @@

    web_m2x_options

    !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:881a75e6602b8037ae91fff6ff77e99caff9cba4b1ccda3dff174f64f4e42824 +!! source digest: sha256:72edae262a5750aa942302a30dfa960c912c99d637f4777222243f3e021f3924 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

    Beta License: AGPL-3 OCA/web Translate me on Weblate Try me on Runboat

    This modules modifies “many2one” and “many2manytags” form widgets so as diff --git a/web_m2x_options/static/src/components/form.esm.js b/web_m2x_options/static/src/components/form.esm.js index 4811046..32d3875 100644 --- a/web_m2x_options/static/src/components/form.esm.js +++ b/web_m2x_options/static/src/components/form.esm.js @@ -27,41 +27,57 @@ function evaluateSystemParameterDefaultTrue(option) { return isOptionSet ? evaluateBooleanExpr(isOptionSet) : true; } +function evaluateHasCreatePermission(attrs) { + return attrs.can_create ? evaluateBooleanExpr(attrs.can_create) : true; +} + +function evaluateFieldBooleanOption(option) { + if (typeof option === "boolean") { + return option; + } + if (typeof option === "string") { + return evaluateBooleanExpr(option); + } + return true; +} + patch(many2OneField, { m2o_options_props_create(props, attrs, options) { const canQuickCreate = evaluateSystemParameterDefaultTrue("create"); + const hasCreatePermission = evaluateHasCreatePermission(attrs); if (options.no_quick_create) { props.canQuickCreate = false; } else if ("no_quick_create" in options) { - props.canQuickCreate = attrs.can_create - ? evaluateBooleanExpr(attrs.can_create) - : true; + props.canQuickCreate = hasCreatePermission; + } else if ("create" in options) { + // Field option set, but must respect can_create security attribute + props.canQuickCreate = + hasCreatePermission && evaluateFieldBooleanOption(options.create); } else if (!canQuickCreate && props.canQuickCreate) { props.canQuickCreate = false; } else if (canQuickCreate && !props.canQuickCreate) { - props.canQuickCreate = attrs.can_create - ? evaluateBooleanExpr(attrs.can_create) - : true; + props.canQuickCreate = hasCreatePermission; } return props; }, m2o_options_props_create_edit(props, attrs, options) { const canCreateEdit = evaluateSystemParameterDefaultTrue("create_edit"); + const hasCreatePermission = evaluateHasCreatePermission(attrs); if (options.no_create_edit) { props.canCreateEdit = false; } else if ("no_create_edit" in options) { // Same condition set in web/views/fields/many2one/many2one_field - props.canCreateEdit = attrs.can_create - ? evaluateBooleanExpr(attrs.can_create) - : true; + props.canCreateEdit = hasCreatePermission; + } else if ("create_edit" in options) { + // Field option set, but must respect can_create security attribute + props.canCreateEdit = + hasCreatePermission && evaluateFieldBooleanOption(options.create_edit); } else if (!canCreateEdit && props.canCreateEdit) { props.canCreateEdit = false; } else if (canCreateEdit && !props.canCreateEdit) { // Same condition set in web/views/fields/many2one/many2one_field - props.canCreateEdit = attrs.can_create - ? evaluateBooleanExpr(attrs.can_create) - : true; + props.canCreateEdit = hasCreatePermission; } return props; }, @@ -152,14 +168,17 @@ patch(Many2OneField.prototype, { patch(many2ManyTagsField, { m2m_options_props_create(props, attrs, options) { const canQuickCreate = evaluateSystemParameterDefaultTrue("create"); + const hasCreatePermission = evaluateHasCreatePermission(attrs); // Create option already available for m2m fields if (!options.no_quick_create) { - if (!canQuickCreate && props.canQuickCreate) { + if ("create" in options) { + // Field option set, but must respect can_create security attribute + props.canQuickCreate = + hasCreatePermission && evaluateFieldBooleanOption(options.create); + } else if (!canQuickCreate && props.canQuickCreate) { props.canQuickCreate = false; } else if (canQuickCreate && !props.canQuickCreate) { - props.canQuickCreate = attrs.can_create - ? evaluateBooleanExpr(attrs.can_create) - : true; + props.canQuickCreate = hasCreatePermission; } } return props; @@ -167,20 +186,20 @@ patch(many2ManyTagsField, { m2m_options_props_create_edit(props, attrs, options) { const canCreateEdit = evaluateSystemParameterDefaultTrue("create_edit"); + const hasCreatePermission = evaluateHasCreatePermission(attrs); if (options.no_create_edit) { props.canCreateEdit = false; } else if ("no_create_edit" in options) { // Same condition set in web/views/fields/many2one/many2one_field - props.canCreateEdit = attrs.can_create - ? evaluateBooleanExpr(attrs.can_create) - : true; + props.canCreateEdit = hasCreatePermission; + } else if ("create_edit" in options) { + props.canCreateEdit = + hasCreatePermission && evaluateFieldBooleanOption(options.create_edit); } else if (!canCreateEdit && props.canCreateEdit) { props.canCreateEdit = false; } else if (canCreateEdit && !props.canCreateEdit) { // Same condition set in web/views/fields/many2one/many2one_field - props.canCreateEdit = attrs.can_create - ? evaluateBooleanExpr(attrs.can_create) - : true; + props.canCreateEdit = hasCreatePermission; } return props; },