summaryrefslogtreecommitdiff
path: root/addons/website_sale_product_configurator/static
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/website_sale_product_configurator/static
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/website_sale_product_configurator/static')
-rw-r--r--addons/website_sale_product_configurator/static/src/js/product_configurator_modal.js38
-rw-r--r--addons/website_sale_product_configurator/static/src/js/website_sale_options.js92
-rw-r--r--addons/website_sale_product_configurator/static/src/scss/website_sale_options.scss15
-rw-r--r--addons/website_sale_product_configurator/static/tests/tours/website_sale_buy.js19
-rw-r--r--addons/website_sale_product_configurator/static/tests/tours/website_sale_shop_custom_attributes_value.js67
5 files changed, 231 insertions, 0 deletions
diff --git a/addons/website_sale_product_configurator/static/src/js/product_configurator_modal.js b/addons/website_sale_product_configurator/static/src/js/product_configurator_modal.js
new file mode 100644
index 00000000..940d7e04
--- /dev/null
+++ b/addons/website_sale_product_configurator/static/src/js/product_configurator_modal.js
@@ -0,0 +1,38 @@
+odoo.define('website_sale_product_configurator.OptionalProductsModal', function (require) {
+ "use strict";
+
+var OptionalProductsModal = require('sale_product_configurator.OptionalProductsModal');
+
+OptionalProductsModal.include({
+ /**
+ * If the "isWebsite" param is true, will also disable the following events:
+ * - change [data-attribute_exclusions]
+ * - click button.js_add_cart_json
+ *
+ * This has to be done because those events are already registered at the "website_sale"
+ * component level.
+ * This modal is part of the form that has these events registered and we
+ * want to avoid duplicates.
+ *
+ * @override
+ * @param {$.Element} parent The parent container
+ * @param {Object} params
+ * @param {boolean} params.isWebsite If we're on a web shop page, we need some
+ * custom behavior
+ */
+ init: function (parent, params) {
+ this._super.apply(this, arguments);
+ this.isWebsite = params.isWebsite;
+
+ this.dialogClass = 'oe_optional_products_modal' + (params.isWebsite ? ' oe_website_sale' : '');
+ },
+ /**
+ * @override
+ * @private
+ */
+ _triggerPriceUpdateOnChangeQuantity: function () {
+ return !this.isWebsite;
+ }
+});
+
+});
diff --git a/addons/website_sale_product_configurator/static/src/js/website_sale_options.js b/addons/website_sale_product_configurator/static/src/js/website_sale_options.js
new file mode 100644
index 00000000..a95e1b06
--- /dev/null
+++ b/addons/website_sale_product_configurator/static/src/js/website_sale_options.js
@@ -0,0 +1,92 @@
+odoo.define('website_sale_options.website_sale', function (require) {
+'use strict';
+
+var ajax = require('web.ajax');
+var core = require('web.core');
+var publicWidget = require('web.public.widget');
+var OptionalProductsModal = require('sale_product_configurator.OptionalProductsModal');
+require('website_sale.website_sale');
+
+var _t = core._t;
+
+publicWidget.registry.WebsiteSale.include({
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ _onProductReady: function () {
+ if (this.isBuyNow) {
+ return this._submitForm();
+ }
+ this.optionalProductsModal = new OptionalProductsModal(this.$form, {
+ rootProduct: this.rootProduct,
+ isWebsite: true,
+ okButtonText: _t('Proceed to Checkout'),
+ cancelButtonText: _t('Continue Shopping'),
+ title: _t('Add to cart'),
+ context: this._getContext(),
+ }).open();
+
+ this.optionalProductsModal.on('options_empty', null, this._submitForm.bind(this));
+ this.optionalProductsModal.on('update_quantity', null, this._onOptionsUpdateQuantity.bind(this));
+ this.optionalProductsModal.on('confirm', null, this._onModalSubmit.bind(this, true));
+ this.optionalProductsModal.on('back', null, this._onModalSubmit.bind(this, false));
+
+ return this.optionalProductsModal.opened();
+ },
+
+ /**
+ * Update web shop base form quantity
+ * when quantity is updated in the optional products window
+ *
+ * @private
+ * @param {integer} quantity
+ */
+ _onOptionsUpdateQuantity: function (quantity) {
+ var $qtyInput = this.$form
+ .find('.js_main_product input[name="add_qty"]')
+ .first();
+
+ if ($qtyInput.length) {
+ $qtyInput.val(quantity).trigger('change');
+ } else {
+ // This handles the case when the "Select Quantity" customize show
+ // is disabled, and therefore the above selector does not find an
+ // element.
+ // To avoid duplicating all RPC, only trigger the variant change if
+ // it is not already done from the above trigger.
+ this.optionalProductsModal.triggerVariantChange(this.optionalProductsModal.$el);
+ }
+ },
+
+ /**
+ * Submits the form with additional parameters
+ * - lang
+ * - product_custom_attribute_values: The products custom variant values
+ *
+ * @private
+ * @param {Boolean} goToShop Triggers a page refresh to the url "shop/cart"
+ */
+ _onModalSubmit: function (goToShop) {
+ var productAndOptions = JSON.stringify(
+ this.optionalProductsModal.getSelectedProducts()
+ );
+
+ ajax.post('/shop/cart/update_option', {
+ product_and_options: productAndOptions
+ }).then(function (quantity) {
+ if (goToShop) {
+ var path = "/shop/cart";
+ window.location.pathname = path;
+ }
+ var $quantity = $(".my_cart_quantity");
+ $quantity.parent().parent().removeClass('d-none');
+ $quantity.html(quantity).hide().fadeIn(600);
+ });
+ },
+});
+
+return publicWidget.registry.WebsiteSaleOptions;
+
+});
diff --git a/addons/website_sale_product_configurator/static/src/scss/website_sale_options.scss b/addons/website_sale_product_configurator/static/src/scss/website_sale_options.scss
new file mode 100644
index 00000000..11a7080e
--- /dev/null
+++ b/addons/website_sale_product_configurator/static/src/scss/website_sale_options.scss
@@ -0,0 +1,15 @@
+.css_not_available.js_product {
+ > *:nth-child(5) > * {
+ display: none;
+ }
+}
+
+div#modal_optional_products table tr td {
+ border: 0;
+}
+
+@include media-breakpoint-down(sm) {
+ div#modal_optional_products .td-qty {
+ display: none;
+ }
+} \ No newline at end of file
diff --git a/addons/website_sale_product_configurator/static/tests/tours/website_sale_buy.js b/addons/website_sale_product_configurator/static/tests/tours/website_sale_buy.js
new file mode 100644
index 00000000..96915b14
--- /dev/null
+++ b/addons/website_sale_product_configurator/static/tests/tours/website_sale_buy.js
@@ -0,0 +1,19 @@
+odoo.define("website_sale_product_configurator.website_sale_tour", function (require) {
+"use strict";
+/**
+ * Add custom steps to handle the optional products modal introduced
+ * by the product configurator module.
+ */
+var tour = require('web_tour.tour');
+require('website_sale.tour');
+
+var addCartStepIndex = _.findIndex(tour.tours.shop_buy_product.steps, function (step) {
+ return (step.id === 'add_cart_step');
+});
+
+tour.tours.shop_buy_product.steps.splice(addCartStepIndex + 1, 0, {
+ content: "click in modal on 'Proceed to checkout' button",
+ trigger: 'button:contains("Proceed to Checkout")',
+});
+
+});
diff --git a/addons/website_sale_product_configurator/static/tests/tours/website_sale_shop_custom_attributes_value.js b/addons/website_sale_product_configurator/static/tests/tours/website_sale_shop_custom_attributes_value.js
new file mode 100644
index 00000000..9872017e
--- /dev/null
+++ b/addons/website_sale_product_configurator/static/tests/tours/website_sale_shop_custom_attributes_value.js
@@ -0,0 +1,67 @@
+odoo.define("website_sale_product_TESTurator.tour_shop_custom_attribute_value", function (require) {
+"use strict";
+
+var tour = require('web_tour.tour');
+var optionVariantImage;
+
+tour.register("a_shop_custom_attribute_value", {
+ url: "/shop?search=Customizable Desk",
+ test: true,
+}, [{
+ content: "click on Customizable Desk",
+ trigger: '.oe_product_cart a:contains("Customizable Desk (TEST)")',
+}, {
+ trigger: 'a.js_add_cart_json:has(i.fa-plus)',
+ run: 'click',
+}, {
+ trigger: 'span.text-danger span:contains(750)',
+ run: function (){}, // check
+}, {
+ trigger: 'b.oe_price span:contains(600)',
+ run: function (){}, // check
+}, {
+ id: 'add_cart_step',
+ trigger: 'a:contains(Add to Cart)',
+ run: 'click',
+}, {
+ trigger: '.oe_optional_products_modal .js_product:eq(1) div:contains("Conference Chair (TEST) (Steel)")',
+ run: function () {
+ optionVariantImage = $('.oe_optional_products_modal .js_product:eq(1) img.variant_image').attr('src');
+ }
+}, {
+ trigger: '.oe_optional_products_modal .js_product:eq(1) input[data-value_name="Aluminium"]',
+}, {
+ trigger: '.oe_optional_products_modal .js_product:eq(1) div:contains("Conference Chair (TEST) (Aluminium)")',
+ run: function () {
+ var newVariantImage = $('.oe_optional_products_modal .js_product:eq(1) img.variant_image').attr('src');
+ if (newVariantImage !== optionVariantImage) {
+ $('<p>').text('image variant option src changed').insertAfter('.oe_optional_products_modal .js_product:eq(1) .product-name');
+ }
+ }
+}, {
+ extra_trigger: '.oe_optional_products_modal .js_product:eq(1) div:contains("image variant option src changed")',
+ trigger: '.oe_optional_products_modal .js_product:eq(1) input[data-value_name="Steel"]',
+}, {
+ trigger: 'li.js_attribute_value span:contains(Aluminium)',
+ extra_trigger: '.oe_optional_products_modal',
+ run: 'click'
+}, {
+ trigger: '.oe_price span:contains(22.90)',
+ run: function (){}, // check
+}, {
+ trigger: '.oe_optional_products_modal .js_product:has(strong:contains(Conference Chair)) .js_add',
+ extra_trigger: '.oe_optional_products_modal .js_product:has(strong:contains(Conference Chair))',
+ run: 'click'
+}, {
+ trigger: '.oe_optional_products_modal .js_product:has(strong:contains(Chair floor protection)) .js_add',
+ extra_trigger: '.oe_optional_products_modal .js_product:has(strong:contains(Chair floor protection))',
+ run: 'click'
+}, {
+ trigger: 'span:contains(1,269.80)',
+ run: function (){}, // check
+}, {
+ trigger: 'button:has(span:contains(Proceed to Checkout))',
+ run: 'click',
+}]);
+
+});