diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
| commit | 3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch) | |
| tree | a44932296ef4a9b71d5f010906253d8c53727726 /addons/sale_product_configurator/views | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/sale_product_configurator/views')
| -rw-r--r-- | addons/sale_product_configurator/views/assets.xml | 28 | ||||
| -rw-r--r-- | addons/sale_product_configurator/views/sale_views.xml | 43 | ||||
| -rw-r--r-- | addons/sale_product_configurator/views/templates.xml | 220 |
3 files changed, 291 insertions, 0 deletions
diff --git a/addons/sale_product_configurator/views/assets.xml b/addons/sale_product_configurator/views/assets.xml new file mode 100644 index 00000000..5665e7dd --- /dev/null +++ b/addons/sale_product_configurator/views/assets.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<odoo> + <template id="assets_backend" inherit_id="web.assets_backend" name="sale_product_configurator assets backend"> + <xpath expr="script[last()]" position="after"> + <script type="text/javascript" src="/sale/static/src/js/variant_mixin.js"></script> + <script type="text/javascript" src="/sale_product_configurator/static/src/js/product_configurator_renderer.js"></script> + <script type="text/javascript" src="/sale_product_configurator/static/src/js/product_configurator_controller.js"></script> + <script type="text/javascript" src="/sale_product_configurator/static/src/js/product_configurator_view.js"></script> + <script type="text/javascript" src="/sale_product_configurator/static/src/js/product_configurator_widget.js"/> + <script type="text/javascript" src="/sale_product_configurator/static/src/js/product_configurator_modal.js"></script> + </xpath> + </template> + <template id="assets_tests" name="Sale Product Configurator Assets Tests" inherit_id="web.assets_tests"> + <xpath expr="." position="inside"> + <script type="text/javascript" src="/sale_product_configurator/static/tests/tours/product_configurator_ui.js"/> + <script type="text/javascript" src="/sale_product_configurator/static/tests/tours/product_configurator_advanced_ui.js"/> + <script type="text/javascript" src="/sale_product_configurator/static/tests/tours/product_configurator_edition_ui.js"/> + <script type="text/javascript" src="/sale_product_configurator/static/tests/tours/product_configurator_single_custom_attribute_ui.js"/> + <script type="text/javascript" src="/sale_product_configurator/static/tests/tours/product_configurator_pricelist_ui.js"/> + <script type="text/javascript" src="/sale_product_configurator/static/tests/tours/product_configurator_optional_products_ui.js"/> + </xpath> + </template> + <template id="qunit_suite" inherit_id="web.qunit_suite_tests" name="sale_product_configurator_tests"> + <xpath expr="." position="inside"> + <script type="text/javascript" src="/sale_product_configurator/static/tests/product_configurator.test.js"></script> + </xpath> + </template> +</odoo> diff --git a/addons/sale_product_configurator/views/sale_views.xml b/addons/sale_product_configurator/views/sale_views.xml new file mode 100644 index 00000000..3e55deb1 --- /dev/null +++ b/addons/sale_product_configurator/views/sale_views.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="utf-8"?> +<odoo> + <record id="product_template_view_form" model="ir.ui.view"> + <field name="name">product.template.form.inherit.sale.product.configurator</field> + <field name="model">product.template</field> + <field name="inherit_id" ref="product.product_template_form_view"/> + <field name="arch" type="xml"> + <xpath expr="//group[@name='sale']" position="after"> + <group name="options" groups="product.group_product_variant"> + <group string="Options"> + <field name="optional_product_ids" widget="many2many_tags" options="{'color_field': 'color'}" domain="[('id', '!=', active_id), '|', ('company_id', '=', company_id), ('company_id', '=', False)]" /> + </group> + </group> + </xpath> + </field> + </record> + + <record id="sale_order_view_form" model="ir.ui.view"> + <field name="name">sale.order.form.inherit.sale.product.configurator</field> + <field name="model">sale.order</field> + <field name="inherit_id" ref="sale.view_order_form"/> + <field name="arch" type="xml"> + <xpath expr="//tree/field[@name='product_template_id']" position="attributes"> + <attribute name="invisible">0</attribute> + </xpath> + <xpath expr="//tree/field[@name='product_template_id']" position="after"> + <field name="product_template_attribute_value_ids" invisible="1" /> + <field name="product_custom_attribute_value_ids" invisible="1" > + <tree> + <field name="custom_product_template_attribute_value_id" /> + <field name="custom_value" /> + </tree> + </field> + <field name="product_no_variant_attribute_value_ids" invisible="1" /> + <field name="is_configurable_product" invisible="1" /> + </xpath> + <xpath expr="//tree/field[@name='product_id']" position="attributes"> + <attribute name="optional">hide</attribute> + <attribute name="string">Product Variant</attribute> + </xpath> + </field> + </record> +</odoo> diff --git a/addons/sale_product_configurator/views/templates.xml b/addons/sale_product_configurator/views/templates.xml new file mode 100644 index 00000000..11ad527c --- /dev/null +++ b/addons/sale_product_configurator/views/templates.xml @@ -0,0 +1,220 @@ +<?xml version="1.0" encoding="utf-8"?> +<odoo> + <template id="optional_products_modal" name="Optional Products"> + <main class="modal-body"> + <t t-call="sale_product_configurator.configure_optional_products" /> + </main> + </template> + + <!-- backend --> + <template id="configure" name="Configure"> + <div class="js_product main_product"> + + <t t-set="combination" t-value="product_combination if product_combination else product._get_first_possible_combination()"/> + <t t-set="combination_info" t-value="product._get_combination_info(combination, add_qty=add_qty or 1, pricelist=pricelist)"/> + <t t-set="product_variant" t-value="product.env['product.product'].browse(combination_info['product_id'])"/> + + <input type="hidden" class="product_template_id" t-att-value="product.id"/> + <input type="hidden" class="product_id" t-attf-name="product_id" t-att-value="product_variant.id"/> + <div class="col-lg-12 text-center mt-5"> + <t t-if="product._is_add_to_cart_possible()"> + <div class="col-lg-5 d-inline-block text-left"> + <t t-if="combination" t-call="sale.variants"> + <t t-set="parent_combination" t-value="None"/> + </t> + <h2> + <span t-attf-class="text-danger oe_default_price oe_striked_price {{'' if combination_info['has_discounted_price'] else 'd-none'}}" + t-esc="combination_info['list_price']" + t-options='{ + "widget": "monetary", + "display_currency": (pricelist or product).currency_id + }'/> + <span class="oe_price product_id mt-3" style="white-space: nowrap;" + t-att-data-product-id="product.id" + t-esc="combination_info['price']" + t-options='{ + "widget": "monetary", + "display_currency": (pricelist or product).currency_id + }'/> + </h2> + <div class="css_quantity input-group" t-if="product.visible_qty_configurator"> + <div class="input-group-prepend"> + <button t-attf-href="#" class="btn btn-primary js_add_cart_json d-none d-md-inline-block" aria-label="Remove one" title="Remove one"> + <i class="fa fa-minus"></i> + </button> + </div> + <input type="text" class="js_quantity form-control quantity" data-min="1" name="add_qty" t-att-value="add_qty or 1"/> + <div class="input-group-append"> + <button t-attf-href="#" class="btn btn-primary float_left js_add_cart_json d-none d-md-inline-block" aria-label="Add one" title="Add one"> + <i class="fa fa-plus"></i> + </button> + </div> + </div> + <p class="css_not_available_msg alert alert-warning">This combination does not exist.</p> + </div> + <div class="col-lg-1 d-inline-block"></div> + <div class="col-lg-5 d-inline-block align-top text-left"> + <img t-if="product_variant" t-att-src="'/web/image/product.product/%s/image_1024' % product_variant.id" class="d-block product_detail_img" alt="Product Image"/> + <img t-else="" t-att-src="'/web/image/product.template/%s/image_1024' % product.id" class="d-block product_detail_img" alt="Product Image"/> + </div> + </t> + <t t-else=""> + <div class="col-lg-5 d-inline-block text-left"> + <p class="alert alert-warning">This product has no valid combination.</p> + </div> + </t> + </div> + </div> + </template> + + <!-- modal: full table, currenclty selected products at top --> + <template id="configure_optional_products"> + <table class="table table-striped table-sm"> + <thead> + <tr> + <th class="td-img">Product</th> + <th></th> + <th class="text-center td-qty">Quantity</th> + <th class="text-center td-price">Price</th> + </tr> + </thead> + <tbody> + <tr class="js_product in_cart main_product"> + + <t t-set="combination_info" t-value="product.product_tmpl_id._get_combination_info(combination, product.id, add_qty or 1, pricelist)"/> + <t t-set="product_variant" t-value="product.env['product.product'].browse(combination_info['product_id'])"/> + + <input type="hidden" class="product_template_id" t-att-value="product.product_tmpl_id.id"/> + <input type="hidden" class="product_id" t-att-value="product_variant.id"/> + <td class='td-img'> + <img t-if="product_variant" t-att-src="'/web/image/product.product/%s/image_128' % product_variant.id" alt="Product Image"/> + <img t-else="" t-att-src="'/web/image/product.template/%s/image_128' % product.id" alt="Product Image"/> + </td> + <td class='td-product_name'> + <strong t-esc="combination_info['display_name']"/> + <div class="text-muted small"> + <div t-field="product.description_sale"/> + <div class="js_attributes"/> + </div> + </td> + <td class="text-center td-qty"> + <div class="css_quantity input-group"> + <div class="input-group-prepend"> + <button t-attf-href="#" class="btn btn-primary js_add_cart_json d-none d-md-inline-block" aria-label="Remove one" title="Remove one"> + <i class="fa fa-minus"></i> + </button> + </div> + <input type="text" class="js_quantity form-control quantity" data-min="1" name="add_qty" t-att-value="add_qty or 1"/> + <div class="input-group-append"> + <button t-attf-href="#" class="btn btn-primary float_left js_add_cart_json d-none d-md-inline-block" aria-label="Add one" title="Add one"> + <i class="fa fa-plus"></i> + </button> + </div> + </div> + </td> + <td class="text-center td-price" name="price"> + <ul class="d-none js_add_cart_variants" t-att-data-attribute_exclusions="{'exclusions: []'}"></ul> + <div class="d-none oe_unchanged_value_ids" t-att-data-unchanged_value_ids="variant_values" ></div> + <div t-attf-class="text-danger oe_default_price oe_striked_price {{'' if combination_info['has_discounted_price'] else 'd-none'}}" + t-esc="combination_info['list_price']" + t-options='{ + "widget": "monetary", + "display_currency": (pricelist or product).currency_id + }' + /> + <span class="oe_price product_id" style="white-space: nowrap;" + t-att-data-product-id="product.id" + t-esc="combination_info['price']" + t-options='{ + "widget": "monetary", + "display_currency": (pricelist or product).currency_id + }'/> + <span class="js_raw_price d-none" t-esc="product.price"/> + </td> + </tr> + <tr class="o_total_row"> + <td colspan="4" class="text-right"> + <strong>Total:</strong> + <span class="js_price_total font-weight-bold" style="white-space: nowrap;" + t-att-data-product-id="product.id" + t-esc="combination_info['price'] * (add_qty or 1)" + t-options='{ + "widget": "monetary", + "display_currency": (pricelist or product).currency_id + }'/> + </td> + </tr> + <tr t-if="product.optional_product_ids" class="o_select_options"><td colspan="4"><h4>Available Options:</h4></td></tr> + <t t-call="sale_product_configurator.optional_product_items"> + <t t-set="parent_combination" t-value="combination"/> + </t> + </tbody> + </table> + </template> + + <!-- modal: optional products --> + <template id="optional_product_items"> + <t t-foreach="product.optional_product_ids" t-as="product"> + <t t-set="combination" t-value="product._get_first_possible_combination(parent_combination)"/> + <t t-if="product._is_add_to_cart_possible(parent_combination)"> + + <t t-set="combination_info" t-value="product._get_combination_info(combination, add_qty=add_qty or 1, pricelist=pricelist)"/> + <t t-set="product_variant" t-value="product.env['product.product'].browse(combination_info['product_id'])"/> + + <tr class="js_product"> + <td class="td-img"> + <input type="hidden" class="product_template_id" t-att-value="product.id"/> + <input type="hidden" class="product_id" t-attf-name="optional-product-#{product.id}" t-att-value="product_variant.id"/> + <img t-if="product_variant" t-att-src="'/web/image/product.product/%s/image_128' % product_variant.id" class="variant_image" alt="Product Image"/> + <img t-else="" t-att-src="'/web/image/product.template/%s/image_128' % product.id" class="variant_image" alt="Product Image"/> + </td> + <td class='td-product_name' colspan="2"> + <div class="float-left"> + <strong class="product-name product_display_name" t-esc="combination_info['display_name']"/> + <div class="text-muted small" t-field="product.description_sale"/> + </div> + <div class="float-right"> + <t t-call="sale.variants"/> + </div> + </td> + <td class="text-center td-qty d-none"> + <div class="css_quantity input-group"> + <div class="input-group-prepend"> + <button t-attf-href="#" class="btn btn-primary float_left js_add_cart_json d-none d-md-inline-block" aria-label="Remove one" title="Remove one"> + <i class="fa fa-minus"></i> + </button> + </div> + <input type="text" class="js_quantity form-control quantity" data-min="1" name="add_qty" t-att-value="add_qty or 1"/> + <div class="input-group-append"> + <button t-attf-href="#" class="btn btn-primary float_left js_add_cart_json d-none d-md-inline-block" aria-label="Add one" title="Add one"> + <i class="fa fa-plus"></i> + </button> + </div> + </div> + </td> + <td class="text-center td-price"> + <div t-attf-class="text-danger oe_default_price oe_optional oe_striked_price {{'' if combination_info['has_discounted_price'] else 'd-none'}}" + t-esc="combination_info['list_price']" + t-options='{ + "widget": "monetary", + "display_currency": (pricelist or product).currency_id + }'/> + <div class="oe_price" style="white-space: nowrap;" + t-esc="combination_info['price']" + t-options='{ + "widget": "monetary", + "display_currency": (pricelist or product).currency_id + }'/> + <span class="js_raw_price d-none" t-esc="combination_info['price']" /> + <p class="css_not_available_msg alert alert-warning">Option not available</p> + + <a role="button" href="#" class="js_add btn btn-primary btn-sm"><i class="fa fa-shopping-cart add-optionnal-item"></i> Add to cart</a> + <span class="js_remove d-none"> + <a role="button" href="#" class="js_remove"><i class="fa fa-trash-o remove-optionnal-item"></i></a> + </span> + </td> + </tr> + </t> + </t> + </template> +</odoo> |
