From c26bda6d245816f2f0961c10f76f849a8d9e7916 Mon Sep 17 00:00:00 2001 From: JasminSForgeFlow Date: Thu, 13 Jul 2023 17:43:11 +0530 Subject: [PATCH 1/3] [ADD] base_product_merge --- base_product_merge/README.rst | 91 ++++ base_product_merge/__init__.py | 3 + base_product_merge/__manifest__.py | 23 + .../i18n/base_product_merge.pot | 135 ++++++ base_product_merge/readme/CONFIGURE.rst | 0 base_product_merge/readme/CONTRIBUTORS.rst | 1 + base_product_merge/readme/DESCRIPTION.rst | 1 + base_product_merge/readme/USAGE.rst | 3 + .../security/ir.model.access.csv | 2 + base_product_merge/security/res_groups.xml | 6 + .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 429 ++++++++++++++++++ base_product_merge/tests/__init__.py | 4 + .../tests/test_base_product_merge.py | 37 ++ base_product_merge/wizard/__init__.py | 4 + .../wizard/base_product_merge.py | 91 ++++ .../wizard/base_product_merge_view.xml | 82 ++++ 17 files changed, 912 insertions(+) create mode 100644 base_product_merge/README.rst create mode 100644 base_product_merge/__init__.py create mode 100644 base_product_merge/__manifest__.py create mode 100644 base_product_merge/i18n/base_product_merge.pot create mode 100644 base_product_merge/readme/CONFIGURE.rst create mode 100644 base_product_merge/readme/CONTRIBUTORS.rst create mode 100644 base_product_merge/readme/DESCRIPTION.rst create mode 100644 base_product_merge/readme/USAGE.rst create mode 100644 base_product_merge/security/ir.model.access.csv create mode 100644 base_product_merge/security/res_groups.xml create mode 100644 base_product_merge/static/description/icon.png create mode 100644 base_product_merge/static/description/index.html create mode 100644 base_product_merge/tests/__init__.py create mode 100644 base_product_merge/tests/test_base_product_merge.py create mode 100644 base_product_merge/wizard/__init__.py create mode 100644 base_product_merge/wizard/base_product_merge.py create mode 100644 base_product_merge/wizard/base_product_merge_view.xml diff --git a/base_product_merge/README.rst b/base_product_merge/README.rst new file mode 100644 index 000000000..2846525b9 --- /dev/null +++ b/base_product_merge/README.rst @@ -0,0 +1,91 @@ +=================== +Base Products Merge +=================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:b7b89aa2d12bfa897bc0a6587324fb6a013b3410c47e7e2733779da135813019 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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 + :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--warehouse-lightgray.png?logo=github + :target: https://github.com/OCA/stock-logistics-warehouse/tree/15.0/base_product_merge + :alt: OCA/stock-logistics-warehouse +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/stock-logistics-warehouse-15-0/stock-logistics-warehouse-15-0-base_product_merge + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/stock-logistics-warehouse&target_branch=15.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +We can merge duplicates products into single product + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +Select products or templates then click on Merge products in Action menu. +Select Destination product in which need to merge all other products +Then click on Merge Product, it will merge all the products. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* ForgeFlow + +Contributors +~~~~~~~~~~~~ + +* Jasmin Solanki + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +.. |maintainer-JasminSForgeFlow| image:: https://github.com/JasminSForgeFlow.png?size=40px + :target: https://github.com/JasminSForgeFlow + :alt: JasminSForgeFlow + +Current `maintainer `__: + +|maintainer-JasminSForgeFlow| + +This module is part of the `OCA/stock-logistics-warehouse `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/base_product_merge/__init__.py b/base_product_merge/__init__.py new file mode 100644 index 000000000..c0bc62fe0 --- /dev/null +++ b/base_product_merge/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from . import wizard diff --git a/base_product_merge/__manifest__.py b/base_product_merge/__manifest__.py new file mode 100644 index 000000000..8b3d76938 --- /dev/null +++ b/base_product_merge/__manifest__.py @@ -0,0 +1,23 @@ +# Copyright 2023 ForgeFlow S.L. (https://www.forgeflow.com) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +{ + "name": "Base Products Merge", + "summary": "Merge duplicate products", + "version": "15.0.1.0.0", + "license": "AGPL-3", + "website": "https://github.com/OCA/stock-logistics-warehouse", + "author": "ForgeFlow, " "Odoo Community Association (OCA)", + "category": "Sales/Sales", + "depends": ["product"], + "data": [ + "security/res_groups.xml", + "security/ir.model.access.csv", + "wizard/base_product_merge_view.xml", + ], + "installable": True, + "external_dependencies": { + "python": ["openupgradelib"], + }, + "maintainers": ["JasminSForgeFlow"], +} diff --git a/base_product_merge/i18n/base_product_merge.pot b/base_product_merge/i18n/base_product_merge.pot new file mode 100644 index 000000000..7754743b5 --- /dev/null +++ b/base_product_merge/i18n/base_product_merge.pot @@ -0,0 +1,135 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * base_product_merge +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 15.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: base_product_merge +#: model_terms:ir.ui.view,arch_db:base_product_merge.view_base_product_merge_form +msgid "Cancel" +msgstr "" + +#. module: base_product_merge +#: model:ir.model.fields,field_description:base_product_merge.field_base_product_merge__create_uid +msgid "Created by" +msgstr "" + +#. module: base_product_merge +#: model:ir.model.fields,field_description:base_product_merge.field_base_product_merge__create_date +msgid "Created on" +msgstr "" + +#. module: base_product_merge +#: model:ir.model.fields,field_description:base_product_merge.field_base_product_merge__dst_product_id +#: model:ir.model.fields,field_description:base_product_merge.field_base_product_merge__dst_product_tmpl_id +msgid "Destination product" +msgstr "" + +#. module: base_product_merge +#: model:ir.model.fields,field_description:base_product_merge.field_base_product_merge__display_name +msgid "Display Name" +msgstr "" + +#. module: base_product_merge +#: code:addons/base_product_merge/wizard/base_product_merge.py:0 +#, python-format +msgid "Error occurred while merging products." +msgstr "" + +#. module: base_product_merge +#: model:ir.model.fields,field_description:base_product_merge.field_base_product_merge__id +msgid "ID" +msgstr "" + +#. module: base_product_merge +#: model:ir.model.fields,field_description:base_product_merge.field_base_product_merge____last_update +msgid "Last Modified on" +msgstr "" + +#. module: base_product_merge +#: model:ir.model.fields,field_description:base_product_merge.field_base_product_merge__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: base_product_merge +#: model:ir.model.fields,field_description:base_product_merge.field_base_product_merge__write_date +msgid "Last Updated on" +msgstr "" + +#. module: base_product_merge +#: model:ir.model.fields,field_description:base_product_merge.field_base_product_merge__merge_method +msgid "Merge Method" +msgstr "" + +#. module: base_product_merge +#: model:ir.actions.act_window,name:base_product_merge.action_product_merge +#: model:ir.actions.act_window,name:base_product_merge.action_product_template_merge +#: model_terms:ir.ui.view,arch_db:base_product_merge.view_base_product_merge_form +msgid "Merge Products" +msgstr "" + +#. module: base_product_merge +#: model:res.groups,name:base_product_merge.res_group_merge_duplicate_product +msgid "Merge duplicate products" +msgstr "" + +#. module: base_product_merge +#: model:ir.model,name:base_product_merge.model_base_product_merge +msgid "Merges two products" +msgstr "" + +#. module: base_product_merge +#: model:ir.model.fields.selection,name:base_product_merge.selection__base_product_merge__merge_method__orm +msgid "ORM" +msgstr "" + +#. module: base_product_merge +#: model:ir.model.fields.selection,name:base_product_merge.selection__base_product_merge__ptype__product_product +msgid "Product" +msgstr "" + +#. module: base_product_merge +#: model:ir.model.fields,field_description:base_product_merge.field_base_product_merge__product_ids +#: model:ir.model.fields,field_description:base_product_merge.field_base_product_merge__product_tmpl_ids +msgid "Products to merge" +msgstr "" + +#. module: base_product_merge +#: model:ir.model.fields,field_description:base_product_merge.field_base_product_merge__ptype +msgid "Ptype" +msgstr "" + +#. module: base_product_merge +#: model:ir.model.fields.selection,name:base_product_merge.selection__base_product_merge__merge_method__sql +msgid "SQL" +msgstr "" + +#. module: base_product_merge +#: model:ir.model.fields.selection,name:base_product_merge.selection__base_product_merge__ptype__product_template +msgid "Template" +msgstr "" + +#. module: base_product_merge +#: model_terms:ir.ui.view,arch_db:base_product_merge.view_base_product_merge_form +msgid "" +"The selected products will be merged together. All\n" +" documents linking to one of these products will be\n" +" redirected to the aggregated product. You can remove\n" +" products from this list to avoid merging them." +msgstr "" + +#. module: base_product_merge +#: code:addons/base_product_merge/wizard/base_product_merge.py:0 +#: code:addons/base_product_merge/wizard/base_product_merge.py:0 +#, python-format +msgid "You cannot merge product to it self." +msgstr "" diff --git a/base_product_merge/readme/CONFIGURE.rst b/base_product_merge/readme/CONFIGURE.rst new file mode 100644 index 000000000..e69de29bb diff --git a/base_product_merge/readme/CONTRIBUTORS.rst b/base_product_merge/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..205106e55 --- /dev/null +++ b/base_product_merge/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Jasmin Solanki diff --git a/base_product_merge/readme/DESCRIPTION.rst b/base_product_merge/readme/DESCRIPTION.rst new file mode 100644 index 000000000..d98c9742c --- /dev/null +++ b/base_product_merge/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +We can merge duplicates products into single product diff --git a/base_product_merge/readme/USAGE.rst b/base_product_merge/readme/USAGE.rst new file mode 100644 index 000000000..e5276c949 --- /dev/null +++ b/base_product_merge/readme/USAGE.rst @@ -0,0 +1,3 @@ +Select products or templates then click on Merge products in Action menu. +Select Destination product in which need to merge all other products +Then click on Merge Product, it will merge all the products. diff --git a/base_product_merge/security/ir.model.access.csv b/base_product_merge/security/ir.model.access.csv new file mode 100644 index 000000000..898a13489 --- /dev/null +++ b/base_product_merge/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +base_product_merge.access_base_product_merge,access_base_product_merge,base_product_merge.model_base_product_merge,base_product_merge.res_group_merge_duplicate_product,1,1,1,1 diff --git a/base_product_merge/security/res_groups.xml b/base_product_merge/security/res_groups.xml new file mode 100644 index 000000000..d1dfc8d2e --- /dev/null +++ b/base_product_merge/security/res_groups.xml @@ -0,0 +1,6 @@ + + + + Merge duplicate products + + diff --git a/base_product_merge/static/description/icon.png b/base_product_merge/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/base_product_merge/static/description/index.html b/base_product_merge/static/description/index.html new file mode 100644 index 000000000..d7e9702ea --- /dev/null +++ b/base_product_merge/static/description/index.html @@ -0,0 +1,429 @@ + + + + + +Base Products Merge + + + +
+

Base Products Merge

+ + +

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

+

We can merge duplicates products into single product

+

Table of contents

+ +
+

Usage

+

Select products or templates then click on Merge products in Action menu. +Select Destination product in which need to merge all other products +Then click on Merge Product, it will merge all the products.

+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • ForgeFlow
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

Current maintainer:

+

JasminSForgeFlow

+

This module is part of the OCA/stock-logistics-warehouse project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/base_product_merge/tests/__init__.py b/base_product_merge/tests/__init__.py new file mode 100644 index 000000000..287c6c789 --- /dev/null +++ b/base_product_merge/tests/__init__.py @@ -0,0 +1,4 @@ +# Copyright 2023 ForgeFlow S.L. (https://www.forgeflow.com) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from . import test_base_product_merge diff --git a/base_product_merge/tests/test_base_product_merge.py b/base_product_merge/tests/test_base_product_merge.py new file mode 100644 index 000000000..da45fd77b --- /dev/null +++ b/base_product_merge/tests/test_base_product_merge.py @@ -0,0 +1,37 @@ +# Copyright 2023 ForgeFlow S.L. (https://www.forgeflow.com) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from odoo.tests.common import TransactionCase + + +class TestBaseProductMerge(TransactionCase): + @classmethod + def setUpClass(cls): + super(TestBaseProductMerge, cls).setUpClass() + cls.product_model = cls.env["product.product"] + cls.base_product_merge_model = cls.env["base.product.merge"] + + def test_product_merge(self): + # take current product count + total_products = len(self.product_model.search([])) + # create products + product_1 = self.product_model.create({"name": "test product 1"}) + product_2 = self.product_model.create({"name": "test product 2"}) + product_3 = self.product_model.create({"name": "test product 3"}) + product_4 = self.product_model.create({"name": "test product 4"}) + + # check product count before merge + self.assertEqual(len(self.product_model.search([])), total_products + 4) + + # merge product_2 and product_4 with product_1 + product_merge = self.base_product_merge_model.with_context( + active_ids=[product_1.id, product_2.id, product_4.id], + active_model="product.product", + ).create({}) + product_merge.dst_product_id = product_1 + product_merge.action_merge() + + # check product count before merge + self.assertEqual(len(self.product_model.search([])), total_products + 2) + # check product_3 exists + self.assertTrue(product_3.exists()) diff --git a/base_product_merge/wizard/__init__.py b/base_product_merge/wizard/__init__.py new file mode 100644 index 000000000..06e9996fa --- /dev/null +++ b/base_product_merge/wizard/__init__.py @@ -0,0 +1,4 @@ +# Copyright 2023 ForgeFlow S.L. (https://www.forgeflow.com) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from . import base_product_merge diff --git a/base_product_merge/wizard/base_product_merge.py b/base_product_merge/wizard/base_product_merge.py new file mode 100644 index 000000000..d9dcfd229 --- /dev/null +++ b/base_product_merge/wizard/base_product_merge.py @@ -0,0 +1,91 @@ +# Copyright 2023 ForgeFlow S.L. (https://www.forgeflow.com) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +import logging + +from openupgradelib import openupgrade_merge_records + +from odoo import _, api, fields, models +from odoo.exceptions import UserError + +_logger = logging.getLogger(__name__) + + +class BaseProductMerge(models.Model): + _name = "base.product.merge" + _description = "Merges two products" + + @api.model + def default_get(self, fields): + rec = super().default_get(fields) + active_ids = self.env.context.get("active_ids", False) + active_model = self.env.context.get("active_model", False) + ptype = active_model + rec.update({"ptype": ptype}) + if ptype == "product.product": + products = self.env[active_model].browse(active_ids) + rec.update({"product_ids": [(6, 0, products.ids)]}) + else: + product_templates = self.env[active_model].browse(active_ids) + rec.update({"product_tmpl_ids": [(6, 0, product_templates.ids)]}) + return rec + + dst_product_id = fields.Many2one("product.product", string="Destination product") + product_ids = fields.Many2many( + "product.product", + "product_rel", + "product_merge_id", + "product_id", + string="Products to merge", + ) + ptype = fields.Selection( + [("product.product", "Product"), ("product.template", "Template")] + ) + dst_product_tmpl_id = fields.Many2one( + "product.template", string="Destination product" + ) + product_tmpl_ids = fields.Many2many( + "product.template", + "product_tmpl_rel", + "product_tmpl_merge_id", + "product_tmpl_id", + string="Products to merge", + ) + merge_method = fields.Selection([("sql", "SQL"), ("orm", "ORM")], default="sql") + + def action_merge(self): + if self.ptype == "product.product": + dst_product = self.dst_product_id + products_to_merge = self.product_ids - dst_product + else: + dst_product = self.dst_product_tmpl_id + products_to_merge = self.product_tmpl_ids - dst_product + # merge product first when there is template with single product + if not any( + products_to_merge.product_variant_ids.mapped("combination_indices") + ): + dst_product_product = self.dst_product_tmpl_id.product_variant_id + product_product_to_merge = ( + self.product_tmpl_ids.product_variant_ids - dst_product_product + ) + if not product_product_to_merge: + raise UserError(_("You cannot merge product to it self.")) + self.merge_products( + "product.product", product_product_to_merge, dst_product_product + ) + self.merge_products(self.ptype, products_to_merge, dst_product) + + def merge_products(self, model, products_to_merge, dst_product): + try: + if not products_to_merge: + raise UserError(_("You cannot merge product to it self.")) + openupgrade_merge_records.merge_records( + self.env, + model, + products_to_merge.ids, + dst_product.id, + method=self.merge_method, + ) + except Exception as e: + _logger.warning(e) + raise UserError(_("Error occurred while merging products.")) from e diff --git a/base_product_merge/wizard/base_product_merge_view.xml b/base_product_merge/wizard/base_product_merge_view.xml new file mode 100644 index 000000000..e87fac147 --- /dev/null +++ b/base_product_merge/wizard/base_product_merge_view.xml @@ -0,0 +1,82 @@ + + + + + base.product.merge.form + base.product.merge + form + +
+ +

+ The selected products will be merged together. All + documents linking to one of these products will be + redirected to the aggregated product. You can remove + products from this list to avoid merging them. +

+ + + + + + + + + + + + + + + +
+
+
+
+
+
+ + + + Merge Products + + base.product.merge + form + new + + + + Merge Products + + base.product.merge + form + new + +
From 2d12b8d2e47c7b45f513fe47f2de058aa5a85c1e Mon Sep 17 00:00:00 2001 From: Guillaume MASSON Date: Tue, 2 Jul 2024 18:22:14 +0200 Subject: [PATCH 2/3] [IMP] base_product_merge: pre-commit stuff --- requirements.txt | 2 ++ setup/base_product_merge/odoo/addons/base_product_merge | 1 + setup/base_product_merge/setup.py | 6 ++++++ 3 files changed, 9 insertions(+) create mode 100644 requirements.txt create mode 120000 setup/base_product_merge/odoo/addons/base_product_merge create mode 100644 setup/base_product_merge/setup.py diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 000000000..180fc4978 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +# generated from manifests external_dependencies +openupgradelib diff --git a/setup/base_product_merge/odoo/addons/base_product_merge b/setup/base_product_merge/odoo/addons/base_product_merge new file mode 120000 index 000000000..2e2f3204e --- /dev/null +++ b/setup/base_product_merge/odoo/addons/base_product_merge @@ -0,0 +1 @@ +../../../../base_product_merge \ No newline at end of file diff --git a/setup/base_product_merge/setup.py b/setup/base_product_merge/setup.py new file mode 100644 index 000000000..28c57bb64 --- /dev/null +++ b/setup/base_product_merge/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) From f1e603713148bf0b6330dca7f3492bf3977ff105 Mon Sep 17 00:00:00 2001 From: Guillaume MASSON Date: Tue, 2 Jul 2024 18:26:21 +0200 Subject: [PATCH 3/3] [MIG] base_product_merge: Migration to 16.0 --- base_product_merge/README.rst | 10 +++++----- base_product_merge/__manifest__.py | 2 +- .../static/description/index.html | 17 ++++++++++------- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/base_product_merge/README.rst b/base_product_merge/README.rst index 2846525b9..d4fa446f6 100644 --- a/base_product_merge/README.rst +++ b/base_product_merge/README.rst @@ -17,13 +17,13 @@ Base Products Merge :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--warehouse-lightgray.png?logo=github - :target: https://github.com/OCA/stock-logistics-warehouse/tree/15.0/base_product_merge + :target: https://github.com/OCA/stock-logistics-warehouse/tree/16.0/base_product_merge :alt: OCA/stock-logistics-warehouse .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/stock-logistics-warehouse-15-0/stock-logistics-warehouse-15-0-base_product_merge + :target: https://translation.odoo-community.org/projects/stock-logistics-warehouse-16-0/stock-logistics-warehouse-16-0-base_product_merge :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/builds?repo=OCA/stock-logistics-warehouse&target_branch=15.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/stock-logistics-warehouse&target_branch=16.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| @@ -48,7 +48,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -86,6 +86,6 @@ Current `maintainer `__: |maintainer-JasminSForgeFlow| -This module is part of the `OCA/stock-logistics-warehouse `_ project on GitHub. +This module is part of the `OCA/stock-logistics-warehouse `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/base_product_merge/__manifest__.py b/base_product_merge/__manifest__.py index 8b3d76938..50e78e415 100644 --- a/base_product_merge/__manifest__.py +++ b/base_product_merge/__manifest__.py @@ -4,7 +4,7 @@ { "name": "Base Products Merge", "summary": "Merge duplicate products", - "version": "15.0.1.0.0", + "version": "16.0.1.0.0", "license": "AGPL-3", "website": "https://github.com/OCA/stock-logistics-warehouse", "author": "ForgeFlow, " "Odoo Community Association (OCA)", diff --git a/base_product_merge/static/description/index.html b/base_product_merge/static/description/index.html index d7e9702ea..601b1c29e 100644 --- a/base_product_merge/static/description/index.html +++ b/base_product_merge/static/description/index.html @@ -8,10 +8,11 @@ /* :Author: David Goodger (goodger@python.org) -:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $ +:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $ :Copyright: This stylesheet has been placed in the public domain. Default cascading style sheet for the HTML output of Docutils. +Despite the name, some widely supported CSS2 features are used. See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to customize this style sheet. @@ -274,7 +275,7 @@ pre.literal-block, pre.doctest-block, pre.math, pre.code { margin-left: 2em ; margin-right: 2em } -pre.code .ln { color: grey; } /* line numbers */ +pre.code .ln { color: gray; } /* line numbers */ pre.code, code { background-color: #eeeeee } pre.code .comment, code .comment { color: #5C6576 } pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold } @@ -300,7 +301,7 @@ span.option { span.pre { white-space: pre } -span.problematic { +span.problematic, pre.problematic { color: red } span.section-subtitle { @@ -368,7 +369,7 @@ ul.auto-toc { !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! source digest: sha256:b7b89aa2d12bfa897bc0a6587324fb6a013b3410c47e7e2733779da135813019 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

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

+

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

We can merge duplicates products into single product

Table of contents

@@ -394,7 +395,7 @@ Then click on Merge Product, it will merge all the products.

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -feedback.

+feedback.

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

@@ -414,13 +415,15 @@ If you spotted it first, help us to smash it by providing a detailed and welcome

Maintainers

This module is maintained by the OCA.

-Odoo Community Association + +Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.

Current maintainer:

JasminSForgeFlow

-

This module is part of the OCA/stock-logistics-warehouse project on GitHub.

+

This module is part of the OCA/stock-logistics-warehouse project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.