diff --git a/setup/web_widget_one2many_product_picker_sale_elaboration/odoo/addons/web_widget_one2many_product_picker_sale_elaboration b/setup/web_widget_one2many_product_picker_sale_elaboration/odoo/addons/web_widget_one2many_product_picker_sale_elaboration new file mode 120000 index 000000000000..b954136834dd --- /dev/null +++ b/setup/web_widget_one2many_product_picker_sale_elaboration/odoo/addons/web_widget_one2many_product_picker_sale_elaboration @@ -0,0 +1 @@ +../../../../web_widget_one2many_product_picker_sale_elaboration \ No newline at end of file diff --git a/setup/web_widget_one2many_product_picker_sale_elaboration/setup.py b/setup/web_widget_one2many_product_picker_sale_elaboration/setup.py new file mode 100644 index 000000000000..28c57bb64031 --- /dev/null +++ b/setup/web_widget_one2many_product_picker_sale_elaboration/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/web_widget_one2many_product_picker_sale_elaboration/README.rst b/web_widget_one2many_product_picker_sale_elaboration/README.rst new file mode 100644 index 000000000000..a654fea034f5 --- /dev/null +++ b/web_widget_one2many_product_picker_sale_elaboration/README.rst @@ -0,0 +1,136 @@ +================================== +Web Widget One2Many Product Picker +================================== + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Fweb-lightgray.png?logo=github + :target: https://github.com/OCA/web/tree/12.0/web_widget_one2many_product_picker + :alt: OCA/web +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/web-12-0/web-12-0-web_widget_one2many_product_picker + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/162/12.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Adds the 'one2many_product_picker' friendly mobile widget to create one2many lines linked with product.template records. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +Create or edit a new view and use the new widget called 'one2many_product_picker'. + +Widget options: +~~~~~~~~~~~~~~~ + +* product_per_page > Integer -> Used to control the auto-load behaviour (scroll-pagination) +* groups > Array of dictionaries -> Declare the groups +* field_map > Dictionary: + + * product -> The field that represent the product_id + * name -> The field that represent a name + * product_uom -> The field that represent a product_uom + * product_uom_qty -> The field that represent a product_uom_qty + * price_unit -> The field that represent a price_unit + * parent_id -> The field that represent the main record + + +Group dictionary definition: + +* name -> The group name +* domain -> Forced domain to use +* order -> The order + + * name -> The field name to order + * asc -> Flag to use 'asc' order + + +Example: + +```t-options="{'groups': [{'name': 'Cheap', 'domain': [('list_price', '<', 10.0)], 'field_map': { 'product': 'my_product_id' }}]}"``` + + +Also you need define the view fields. The view must be an 'kanban' view. +This is an example that uses the 'sale.order.line' fields: + +.. code:: xml + + + + + + + + + + + + + +** In this example we don't use 'field_map' option because the default match with the sale.order.line field names. + +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 smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Tecnativa + +Contributors +~~~~~~~~~~~~ + +* `Tecnativa `_: + + * Alexandre D. Díaz + * Pedro M. Baeza + +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. + +This module is part of the `OCA/web `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/web_widget_one2many_product_picker_sale_elaboration/__init__.py b/web_widget_one2many_product_picker_sale_elaboration/__init__.py new file mode 100644 index 000000000000..d9d1f13deb58 --- /dev/null +++ b/web_widget_one2many_product_picker_sale_elaboration/__init__.py @@ -0,0 +1 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). diff --git a/web_widget_one2many_product_picker_sale_elaboration/__manifest__.py b/web_widget_one2many_product_picker_sale_elaboration/__manifest__.py new file mode 100644 index 000000000000..a4538471475a --- /dev/null +++ b/web_widget_one2many_product_picker_sale_elaboration/__manifest__.py @@ -0,0 +1,18 @@ +# Copyright 2020 Tecnativa - Alexandre D. Díaz +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "Web Widget One2Many Product Picker Sale Elaboration", + "summary": "Adds support for sale elaboration in the" + " one2many product picker widget", + "version": "13.0.1.0.0", + "category": "Website", + "author": "Tecnativa, " "Odoo Community Association (OCA)", + "website": "https://www.tecnativa.com", + "license": "AGPL-3", + "depends": ["web_widget_one2many_product_picker", "sale_elaboration"], + "data": ["templates/assets.xml"], + "qweb": ["static/src/xml/one2many_product_picker.xml"], + "installable": True, + "auto_install": False, +} diff --git a/web_widget_one2many_product_picker_sale_elaboration/readme/CONTRIBUTORS.rst b/web_widget_one2many_product_picker_sale_elaboration/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000000..ff417a6ae3e6 --- /dev/null +++ b/web_widget_one2many_product_picker_sale_elaboration/readme/CONTRIBUTORS.rst @@ -0,0 +1,3 @@ +* `Tecnativa `_: + + * Alexandre D. Díaz diff --git a/web_widget_one2many_product_picker_sale_elaboration/readme/DESCRIPTION.rst b/web_widget_one2many_product_picker_sale_elaboration/readme/DESCRIPTION.rst new file mode 100644 index 000000000000..8ab664f56e9d --- /dev/null +++ b/web_widget_one2many_product_picker_sale_elaboration/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +Adds support for 'sale_elaboration' in the product picker diff --git a/web_widget_one2many_product_picker_sale_elaboration/static/description/index.html b/web_widget_one2many_product_picker_sale_elaboration/static/description/index.html new file mode 100644 index 000000000000..05d8aa6d9d96 --- /dev/null +++ b/web_widget_one2many_product_picker_sale_elaboration/static/description/index.html @@ -0,0 +1,493 @@ + + + + + + +Web Widget One2Many Product Picker + + + +
+

Web Widget One2Many Product Picker

+ + +

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

+

Adds the ‘one2many_product_picker’ friendly mobile widget to create one2many lines linked with product.template records.

+

Table of contents

+ +
+

Usage

+

Create or edit a new view and use the new widget called ‘one2many_product_picker’.

+
+

Widget options:

+
    +
  • product_per_page > Integer -> Used to control the auto-load behaviour (scroll-pagination)

    +
  • +
  • groups > Array of dictionaries -> Declare the groups

    +
  • +
  • field_map > Dictionary:

    +
    +
      +
    • product -> The field that represent the product_id
    • +
    • name -> The field that represent a name
    • +
    • product_uom -> The field that represent a product_uom
    • +
    • product_uom_qty -> The field that represent a product_uom_qty
    • +
    • price_unit -> The field that represent a price_unit
    • +
    • parent_id -> The field that represent the main record
    • +
    +
    +
  • +
+

Group dictionary definition:

+
    +
  • name -> The group name

    +
  • +
  • domain -> Forced domain to use

    +
  • +
  • order -> The order

    +
    +
      +
    • name -> The field name to order
    • +
    • asc -> Flag to use ‘asc’ order
    • +
    +
    +
  • +
+

Example:

+

`t-options="{'groups': [{'name': 'Cheap', 'domain': [('list_price', '<', 10.0)], 'field_map': { 'product': 'my_product_id' }}]}"`

+

Also you need define the view fields. The view must be an ‘kanban’ view. +This is an example that uses the ‘sale.order.line’ fields:

+
+<field
+    name="order_line"
+    attrs="{'readonly': [('state', 'in', ('done','cancel'))]}"
+    nolabel="1"
+    widget="one2many_product_picker"
+    options="{'groups': [{'name': 'Desk', 'domain': [('name', 'ilike', '%desk%')], 'order': {'name': 'id', 'asc': true}}, {'name': 'Chairs', 'domain': [('name', 'ilike', '%chair%')]}]}"
+>
+    <kanban>
+        <field name="name"/>
+        <field name="product_id" />
+        <field name="product_uom_qty" />
+        <field name="product_uom"/>
+        <field name="price_unit"/>
+        <field name="order_id"/>
+    </kanban>
+</field>
+
+

** In this example we don’t use ‘field_map’ option because the default match with the sale.order.line field names.

+
+
+
+

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 smashing it by providing a detailed and welcomed +feedback.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Tecnativa
  • +
+
+
+

Contributors

+
    +
  • Tecnativa:

    +
    +
      +
    • Alexandre D. Díaz
    • +
    • Pedro M. Baeza
    • +
    +
    +
  • +
+
+
+

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.

+

This module is part of the OCA/web project on GitHub.

+

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

+
+
+
+ + diff --git a/web_widget_one2many_product_picker_sale_elaboration/static/src/js/views/abstract_view.js b/web_widget_one2many_product_picker_sale_elaboration/static/src/js/views/abstract_view.js new file mode 100644 index 000000000000..432fb1b4f611 --- /dev/null +++ b/web_widget_one2many_product_picker_sale_elaboration/static/src/js/views/abstract_view.js @@ -0,0 +1,137 @@ +// Copyright 2020 Tecnativa - Alexandre Díaz +// License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +odoo.define( + "web_widget_one2many_product_picker_sale_elaboration.AbstractView", + function(require) { + "use strict"; + + const core = require("web.core"); + const AbstractView = require("web.AbstractView"); + + const _t = core._t; + + /** + * Helper function to create field view definitions + * + * @private + * @param {Object} params + * @returns {Object} + */ + function _constructFakeFieldDef(params) { + return _.extend( + { + change_default: false, + company_dependent: false, + manual: false, + views: {}, + searchable: true, + store: false, + readonly: true, + required: false, + sortable: false, + }, + params + ); + } + + /** + * This is pure hard-coded magic. Adds new fields to the widget form view. + */ + AbstractView.include({ + /** + * @override + */ + init: function(viewInfo, params) { + if (viewInfo.model === "sale.order") { + const widget_name = $(viewInfo.arch) + .find("field[name='order_line']") + .attr("widget"); + if (widget_name === "one2many_product_picker") { + this._injectSaleElaborationFields(viewInfo); + } + return this._super(viewInfo, params); + } + this._super.apply(this, arguments); + }, + + /** + * @private + * @param {Object} viewInfo + */ + _injectSaleElaborationFields: function(viewInfo) { + const to_inject = { + is_elaboration: _constructFakeFieldDef({ + depends: [], + type: "boolean", + }), + elaboration_id: _constructFakeFieldDef({ + depends: [], + relation: "product.elaboration", + string: _t("Elaboration"), + store: true, + sortable: false, + readonly: false, + type: "many2one", + }), + elaboration_note: _constructFakeFieldDef({ + depends: [], + translate: false, + string: _t("Elaboration Note"), + store: true, + sortable: false, + readonly: false, + type: "char", + }), + }; + viewInfo.viewFields.order_line.views.form.fields = _.extend( + {}, + to_inject, + viewInfo.viewFields.order_line.views.form.fields + ); + + // Add fields to arch + const $arch = $(viewInfo.viewFields.order_line.views.form.arch); + + // Add is_elaboration? + let $field = $arch.find("field[name='is_elaboration']"); + if (!$field.length) { + $("", { + name: "is_elaboration", + invisible: 1, + force_save: 1, + modifiers: '{"invisible": true}', + }).appendTo($arch); + } + // Add elaboration_id? + $field = $arch.find("field[name='elaboration_id']"); + if (!$field.length) { + $("", { + name: "elaboration_id", + on_change: 1, + can_create: "true", + can_write: "true", + class: "mb-1", + attrs: + "{'invisible': [['is_elaboration', '!=', True]], 'readonly': [('state', 'in', ('done', 'cancel'))}", + modifiers: + '{"invisible": [["is_elaboration", "!=", true]], "readonly": [["state", "in", ["done", "cancel"]]]}', + }).appendTo($arch); + } + // Add elaboration_note? + $field = $arch.find("field[name='elaboration_note']"); + if (!$field.length) { + $("", { + name: "elaboration_note", + class: "mb-1", + attrs: + "{'invisible': [['is_elaboration', '!=', True]], 'readonly': [('state', 'in', ('done', 'cancel'))]}", + modifiers: + '{"invisible": [["is_elaboration", "!=", true]], "readonly": [["state", "in", ["done", "cancel"]]]}', + }).appendTo($arch); + } + + viewInfo.viewFields.order_line.views.form.arch = $arch[0].outerHTML; + }, + }); + } +); diff --git a/web_widget_one2many_product_picker_sale_elaboration/static/src/scss/_variables.scss b/web_widget_one2many_product_picker_sale_elaboration/static/src/scss/_variables.scss new file mode 100644 index 000000000000..1ab5a159f901 --- /dev/null +++ b/web_widget_one2many_product_picker_sale_elaboration/static/src/scss/_variables.scss @@ -0,0 +1 @@ +$one2many-product-picker-card-max-height: $one2many-product-picker-card-max-height + 40; diff --git a/web_widget_one2many_product_picker_sale_elaboration/static/src/xml/one2many_product_picker.xml b/web_widget_one2many_product_picker_sale_elaboration/static/src/xml/one2many_product_picker.xml new file mode 100644 index 000000000000..fb2ea33897a8 --- /dev/null +++ b/web_widget_one2many_product_picker_sale_elaboration/static/src/xml/one2many_product_picker.xml @@ -0,0 +1,19 @@ + + diff --git a/web_widget_one2many_product_picker_sale_elaboration/templates/assets.xml b/web_widget_one2many_product_picker_sale_elaboration/templates/assets.xml new file mode 100644 index 000000000000..66e4c0dd60c3 --- /dev/null +++ b/web_widget_one2many_product_picker_sale_elaboration/templates/assets.xml @@ -0,0 +1,27 @@ + + +