diff --git a/addons/website_sale_stock/__manifest__.py b/addons/website_sale_stock/__manifest__.py index 00ecc1ac8a5..778f05a18e3 100644 --- a/addons/website_sale_stock/__manifest__.py +++ b/addons/website_sale_stock/__manifest__.py @@ -19,7 +19,9 @@ Then it can be made specific at the product level. 'views/product_template_views.xml', 'views/res_config_settings_views.xml', 'views/website_sale_stock_templates.xml', - 'views/stock_picking_views.xml' + 'views/stock_picking_views.xml', + 'data/template_email.xml', + 'data/ir_cron_data.xml', ], 'demo': [ 'data/website_sale_stock_demo.xml', @@ -29,6 +31,9 @@ Then it can be made specific at the product level. 'web.assets_frontend': [ 'website_sale_stock/static/src/js/**/*', ], + 'web.assets_tests': [ + 'website_sale_stock/static/tests/tours/website_sale_stock_stock_notification.js', + ], }, 'license': 'LGPL-3', } diff --git a/addons/website_sale_stock/controllers/main.py b/addons/website_sale_stock/controllers/main.py index 8a430fbc0a9..3e42aef9cd4 100644 --- a/addons/website_sale_stock/controllers/main.py +++ b/addons/website_sale_stock/controllers/main.py @@ -2,10 +2,11 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo.addons.website_sale.controllers import main as website_sale_controller - -from odoo import http +from odoo.tools import email_re +from odoo import http, _ from odoo.http import request from odoo.exceptions import ValidationError +from werkzeug.exceptions import BadRequest class PaymentPortal(website_sale_controller.PaymentPortal): @@ -26,3 +27,30 @@ class PaymentPortal(website_sale_controller.PaymentPortal): if values: raise ValidationError(' '.join(values)) return super().shop_payment_transaction(*args, **kwargs) + + +class WebsiteSale(website_sale_controller.WebsiteSale): + @http.route(['/shop/add/stock_notification'], type="json", auth="public", website=True) + def add_stock_email_notification(self, email, product_id): + if not email_re.match(email): + raise BadRequest(_("Invalid Email")) + + product = request.env['product.product'].browse(int(product_id)) + partners = request.env['res.partner'].sudo()._mail_find_partner_from_emails([email], force_create=True) + partner = partners[0] + + if not product._has_stock_notification(partner): + product.sudo().stock_notification_partner_ids += partner + + if request.website.is_public_user(): + request.session['product_with_stock_notification_enabled'] = request.session.get( + 'product_with_stock_notification_enabled', + set() + ) | {product_id} + request.session['stock_notification_email'] = email + + def _prepare_product_values(self, product, category='', search='', **kwargs): + values = super()._prepare_product_values(product, category, search, **kwargs) + # We need the user mail to prefill the back of stock notification, so we put it in the value that will be sent + values['user_email'] = request.env.user.email or request.session.get('stock_notification_email', '') + return values diff --git a/addons/website_sale_stock_wishlist/data/ir_cron_data.xml b/addons/website_sale_stock/data/ir_cron_data.xml similarity index 74% rename from addons/website_sale_stock_wishlist/data/ir_cron_data.xml rename to addons/website_sale_stock/data/ir_cron_data.xml index dfb61dd7473..747a852f988 100644 --- a/addons/website_sale_stock_wishlist/data/ir_cron_data.xml +++ b/addons/website_sale_stock/data/ir_cron_data.xml @@ -1,12 +1,12 @@ - Wishlist: send email regarding products availability + Product: send email regarding products availability 1 hours -1 - + model._send_availability_email() code diff --git a/addons/website_sale_stock_wishlist/data/template_email.xml b/addons/website_sale_stock/data/template_email.xml similarity index 50% rename from addons/website_sale_stock_wishlist/data/template_email.xml rename to addons/website_sale_stock/data/template_email.xml index 7dfc2bc3c28..f6e7cfa832c 100644 --- a/addons/website_sale_stock_wishlist/data/template_email.xml +++ b/addons/website_sale_stock/data/template_email.xml @@ -5,18 +5,24 @@

Dear Customer,

The following product is now available.

- - + +
-

+

+

+ () +

-

-

+

-

+

- + Order Now
diff --git a/addons/website_sale_stock/models/product_product.py b/addons/website_sale_stock/models/product_product.py index 399c21c5145..f08b2d7c378 100644 --- a/addons/website_sale_stock/models/product_product.py +++ b/addons/website_sale_stock/models/product_product.py @@ -1,17 +1,25 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo import models +from odoo import models, fields, _ from odoo.http import request class ProductProduct(models.Model): _inherit = 'product.product' + stock_notification_partner_ids = fields.Many2many('res.partner', relation='stock_notification_product_partner_rel', string='Back in stock Notifications') + + def _has_stock_notification(self, partner): + self.ensure_one() + return partner in self.stock_notification_partner_ids + def _get_cart_qty(self, website=None): if not self.allow_out_of_stock_order: website = website or self.env['website'].get_current_website() - cart = website and request and website.sale_get_order() or None + # When the cron is run manually, request has no attribute website, and that would cause a crash + # so we check for it + cart = website and request and hasattr(request, 'website') and website.sale_get_order() or None if cart: return sum( cart._get_common_product_lines(product=self).mapped('product_uom_qty') @@ -21,3 +29,26 @@ class ProductProduct(models.Model): def _is_sold_out(self): combination_info = self.with_context(website_sale_stock_get_quantity=True).product_tmpl_id._get_combination_info(product_id=self.id) return combination_info['product_type'] == 'product' and combination_info['free_qty'] <= 0 + + def _send_availability_email(self): + for product in self.search([('stock_notification_partner_ids', '!=', False)]): + if product._is_sold_out(): + continue + for partner in product.stock_notification_partner_ids: + body_html = self.env['ir.qweb']._render('website_sale_stock.availability_email_body', {"product": product}) + msg = self.env["mail.message"].sudo().new(dict(body=body_html, record_name=product.name)) + full_mail = self.env["mail.render.mixin"]._render_encapsulate( + "mail.mail_notification_light", + body_html, + add_context=dict(message=msg, model_description=_("Product")), + ) + mail_values = { + "subject": _("The product '%(product_name)s' is now available") % {'product_name': product.name}, + "email_from": (product.company_id.partner_id or self.env.user).email_formatted, + "email_to": partner.email_formatted, + "body_html": full_mail, + } + + mail = self.env["mail.mail"].sudo().create(mail_values) + mail.send(raise_exception=False) + product.stock_notification_partner_ids -= partner diff --git a/addons/website_sale_stock/models/product_template.py b/addons/website_sale_stock/models/product_template.py index ac2fafca299..7346bcec16e 100644 --- a/addons/website_sale_stock/models/product_template.py +++ b/addons/website_sale_stock/models/product_template.py @@ -2,6 +2,7 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo import fields, models from odoo.tools.translate import html_translate +from odoo.http import request class ProductTemplate(models.Model): @@ -25,6 +26,11 @@ class ProductTemplate(models.Model): product = self.env['product.product'].sudo().browse(combination_info['product_id']) website = self.env['website'].get_current_website() free_qty = product.with_context(warehouse=website._get_warehouse_available()).free_qty + has_stock_notification = product._has_stock_notification(self.env.user.partner_id) \ + or request \ + and product.id in request.session.get('product_with_stock_notification_enabled', + set()) + stock_notification_email = request and request.session.get('stock_notification_email', '') combination_info.update({ 'free_qty': free_qty, 'product_type': product.type, @@ -35,6 +41,8 @@ class ProductTemplate(models.Model): 'allow_out_of_stock_order': self.allow_out_of_stock_order, 'show_availability': self.show_availability, 'out_of_stock_message': self.out_of_stock_message, + 'has_stock_notification': has_stock_notification, + 'stock_notification_email': stock_notification_email, }) else: product_template = self.sudo() diff --git a/addons/website_sale_stock/static/src/js/website_sale.js b/addons/website_sale_stock/static/src/js/website_sale.js new file mode 100644 index 00000000000..7a85f4bd4b3 --- /dev/null +++ b/addons/website_sale_stock/static/src/js/website_sale.js @@ -0,0 +1,63 @@ +/** @odoo-module alias=website_sale_stock.website_sale**/ + +import { WebsiteSale } from 'website_sale.website_sale'; +import { is_email } from 'web.utils'; + +WebsiteSale.include({ + events: Object.assign({}, WebsiteSale.prototype.events, { + 'click #product_stock_notification_message': '_onClickProductStockNotificationMessage', + 'click #product_stock_notification_form_submit_button': '_onClickSubmitProductStockNotificationForm', + }), + + _onClickProductStockNotificationMessage: function (ev) { + const partnerEmail = document.querySelector('#wsale_user_email').value; + const emailInputEl = document.querySelector('#stock_notification_input'); + + emailInputEl.value = partnerEmail; + this._handleClickStockNotificationMessage(ev); + }, + + _onClickSubmitProductStockNotificationForm: function (ev) { + const formEl = ev.currentTarget.closest('#stock_notification_form'); + const productId = parseInt(formEl.querySelector('input[name="product_id"]').value); + this._handleClickSubmitStockNotificationForm(ev, productId); + }, + + + _handleClickStockNotificationMessage(ev) { + ev.currentTarget.classList.add('d-none'); + ev.currentTarget.parentElement.querySelector('#stock_notification_form').classList.remove('d-none'); + }, + + _handleClickSubmitStockNotificationForm(ev, productId) { + const stockNotificationEl = ev.currentTarget.closest('#stock_notification_div'); + const formEl = stockNotificationEl.querySelector('#stock_notification_form'); + const email = stockNotificationEl.querySelector('#stock_notification_input').value.trim(); + + if (!is_email(email)) { + return this._displayEmailIncorrectMessage(stockNotificationEl); + } + + this._rpc({ + route: "/shop/add/stock_notification", + params: { + product_id: productId, + email, + }, + }).then((data) => { + const message = stockNotificationEl.querySelector('#stock_notification_success_message'); + + message.classList.remove('d-none'); + formEl.classList.add('d-none'); + }).catch((error) => { + this._displayEmailIncorrectMessage(stockNotificationEl); + }); + }, + + _displayEmailIncorrectMessage(stockNotificationEl) { + const incorrectIconEl = stockNotificationEl.querySelector('#stock_notification_input_incorrect'); + incorrectIconEl.classList.remove('d-none'); + } +}); + +export default WebsiteSale; diff --git a/addons/website_sale_stock/static/src/xml/website_sale_stock_product_availability.xml b/addons/website_sale_stock/static/src/xml/website_sale_stock_product_availability.xml index 89fb1911994..c43b0aaf672 100644 --- a/addons/website_sale_stock/static/src/xml/website_sale_stock_product_availability.xml +++ b/addons/website_sale_stock/static/src/xml/website_sale_stock_product_availability.xml @@ -3,10 +3,47 @@ - -
- - Out of Stock +
+
+ + +
+ + Out of Stock +
+
+
+
+ +
+
+ + + +
+ +
+
+ + Invalid email +
+
+ +
+
+
+ + We'll notify you once the product is back in stock. +
+
+
Only left in stock. diff --git a/addons/website_sale_stock/static/tests/tours/website_sale_stock_stock_notification.js b/addons/website_sale_stock/static/tests/tours/website_sale_stock_stock_notification.js new file mode 100644 index 00000000000..a4ac06ac11d --- /dev/null +++ b/addons/website_sale_stock/static/tests/tours/website_sale_stock_stock_notification.js @@ -0,0 +1,32 @@ +/** @odoo-module **/ + +import tour from 'web_tour.tour'; + +tour.register('back_in_stock_notification_product', { + test: true, + url: '/shop?search=Macbook%20Pro', + }, + [ + { + content: "Open product page", + trigger: 'a:contains("Macbook Pro")', + }, + { + content: "Click on 'Be notified when back in stock'", + trigger: '#product_stock_notification_message', + }, + { + content: "Fill email form", + trigger: 'div[id="stock_notification_form"] input[name="email"]', + run: 'text test@test.test', + }, + { + content: "Click on the button", + trigger: '#product_stock_notification_form_submit_button', + }, + { + content: "Success Message", + trigger: '#stock_notification_success_message', + }, + ], +); diff --git a/addons/website_sale_stock/tests/__init__.py b/addons/website_sale_stock/tests/__init__.py index 778ed8c0ec7..923b3940b8b 100644 --- a/addons/website_sale_stock/tests/__init__.py +++ b/addons/website_sale_stock/tests/__init__.py @@ -2,3 +2,4 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from . import test_website_sale_stock_product_warehouse +from . import test_website_sale_stock_stock_notification diff --git a/addons/website_sale_stock/tests/test_website_sale_stock_stock_notification.py b/addons/website_sale_stock/tests/test_website_sale_stock_stock_notification.py new file mode 100644 index 00000000000..e86c0790a09 --- /dev/null +++ b/addons/website_sale_stock/tests/test_website_sale_stock_stock_notification.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo.tests import tagged +from odoo.tests.common import HttpCase + + +@tagged('post_install', '-at_install') +class TestStockNotificationProduct(HttpCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + warehouse = cls.env['stock.warehouse'].create({ + 'name': 'Wishlist Warehouse', + 'code': 'W_WH' + }) + current_website = cls.env['website'].get_current_website() + current_website.warehouse_id = warehouse + + cls.warehouse = warehouse + cls.current_website = current_website + + cls.product = cls.env['product.product'].create({ + 'name': 'Macbook Pro', + 'website_published': True, + 'type': 'product', + 'allow_out_of_stock_order': False, + + }) + cls.pricelist = cls.env['product.pricelist'].create({ + 'name': 'Public Pricelist', + }) + cls.currency = cls.env.ref("base.USD") + + def test_back_in_stock_notification_product(self): + self.start_tour("/", 'back_in_stock_notification_product') + + partner_ids = self.env['res.partner']._mail_find_partner_from_emails(['test@test.test']) + partner = partner_ids[0] + ProductProduct = self.env['product.product'] + product = ProductProduct.browse(self.product.id) + self.assertTrue(product._has_stock_notification(partner)) + + # No email should be sent + ProductProduct._send_availability_email() + emails = self.env['mail.mail'].search([('email_to', '=', partner.email_formatted)]) + self.assertEqual(len(emails), 0) + + # Replenish Product + quants = self.env['stock.quant'].with_context(inventory_mode=True).create({ + 'product_id': self.product.id, + 'inventory_quantity': 10.0, + 'location_id': self.warehouse.lot_stock_id.id, + }) + quants.action_apply_inventory() + + ProductProduct._send_availability_email() + emails = self.env['mail.mail'].search([('email_to', '=', partner.email_formatted)]) + self.assertEqual(emails[0].subject, "The product 'Macbook Pro' is now available") + self.assertFalse(product._has_stock_notification(partner)) diff --git a/addons/website_sale_stock/views/website_sale_stock_templates.xml b/addons/website_sale_stock/views/website_sale_stock_templates.xml index 5e1b7abb8a1..d3d962fca5b 100644 --- a/addons/website_sale_stock/views/website_sale_stock_templates.xml +++ b/addons/website_sale_stock/views/website_sale_stock_templates.xml @@ -14,6 +14,9 @@
+ + + diff --git a/addons/website_sale_stock_wishlist/__manifest__.py b/addons/website_sale_stock_wishlist/__manifest__.py index 9d8affb006a..68a2ff445cf 100644 --- a/addons/website_sale_stock_wishlist/__manifest__.py +++ b/addons/website_sale_stock_wishlist/__manifest__.py @@ -14,13 +14,14 @@ Allow the user to select if he wants to receive email notifications when a produ ], 'data': [ 'views/website_sale_stock_wishlist_templates.xml', - 'data/template_email.xml', - 'data/ir_cron_data.xml', ], 'assets': { 'web.assets_frontend': [ 'website_sale_stock_wishlist/static/src/**/*', ], + 'web.assets_tests': [ + 'website_sale_stock_wishlist/static/tests/tours/website_sale_stock_wishlist_stock_notification.js', + ], }, 'auto_install': True, 'license': 'LGPL-3', diff --git a/addons/website_sale_stock_wishlist/controllers/__init__.py b/addons/website_sale_stock_wishlist/controllers/__init__.py index 6628b140058..b6ee6a5108f 100644 --- a/addons/website_sale_stock_wishlist/controllers/__init__.py +++ b/addons/website_sale_stock_wishlist/controllers/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from . import main from . import variant diff --git a/addons/website_sale_stock_wishlist/controllers/main.py b/addons/website_sale_stock_wishlist/controllers/main.py deleted file mode 100644 index 0dab1295cfb..00000000000 --- a/addons/website_sale_stock_wishlist/controllers/main.py +++ /dev/null @@ -1,13 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo import http -from odoo.http import request -from odoo.addons.website_sale.controllers.main import WebsiteSale - - -class WebsiteSaleStockWishlist(WebsiteSale): - @http.route(['/shop/wishlist/notify/'], type='json', auth="public", website=True) - def notify_stock(self, wish, notify=True, **kw): - if not request.website.is_public_user(): - wish['stock_notification'] = notify - return wish['stock_notification'] diff --git a/addons/website_sale_stock_wishlist/models/__init__.py b/addons/website_sale_stock_wishlist/models/__init__.py index c0f071d53f8..f0ff14e93cc 100644 --- a/addons/website_sale_stock_wishlist/models/__init__.py +++ b/addons/website_sale_stock_wishlist/models/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from . import product_wishlist from . import product_template +from . import product_wishlist diff --git a/addons/website_sale_stock_wishlist/models/product_template.py b/addons/website_sale_stock_wishlist/models/product_template.py index 2f9b4a5f487..5c5012fad8f 100644 --- a/addons/website_sale_stock_wishlist/models/product_template.py +++ b/addons/website_sale_stock_wishlist/models/product_template.py @@ -20,6 +20,6 @@ class ProductTemplate(models.Model): if combination_info['product_id']: product = self.env['product.product'].sudo().browse(combination_info["product_id"]) - combination_info['wish'] = product._is_in_wishlist() + combination_info['is_in_wishlist'] = product._is_in_wishlist() return combination_info diff --git a/addons/website_sale_stock_wishlist/models/product_wishlist.py b/addons/website_sale_stock_wishlist/models/product_wishlist.py index 9b516db6e8f..77f93d43ec4 100644 --- a/addons/website_sale_stock_wishlist/models/product_wishlist.py +++ b/addons/website_sale_stock_wishlist/models/product_wishlist.py @@ -1,53 +1,19 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo import fields, models, _ +from odoo import fields, models, api class ProductWishlist(models.Model): _inherit = "product.wishlist" - stock_notification = fields.Boolean(default=False, required=True) + stock_notification = fields.Boolean(compute='_compute_stock_notification', default=False, required=True) - def _add_to_wishlist(self, pricelist_id, currency_id, website_id, price, product_id, partner_id=False): - wish = super()._add_to_wishlist( - pricelist_id=pricelist_id, - currency_id=currency_id, - website_id=website_id, - price=price, - product_id=product_id, - partner_id=partner_id, - ) - wish['stock_notification'] = wish.product_id._is_sold_out() + @api.depends("product_id", "partner_id") + def _compute_stock_notification(self): + for record in self: + record.stock_notification = record.product_id._has_stock_notification(record.partner_id) - return wish - - def _send_availability_email(self): - to_notify = self.env['product.wishlist'].search([('stock_notification', '=', True)]) - - if not to_notify: - return - - notified = self.env['product.wishlist'] - - # cannot group by product_id because it depend of website_id -> warehouse_id - for wishlist in to_notify: - product = wishlist.with_context(website_id=wishlist.website_id.id).product_id - if not product._is_sold_out(): - body_html = self.env['ir.qweb']._render('website_sale_stock_wishlist.availability_email_body', {"wishlist": wishlist}) - msg = self.env["mail.message"].sudo().new(dict(body=body_html, record_name=product.name)) - full_mail = self.env["mail.render.mixin"]._render_encapsulate( - "mail.mail_notification_light", - body_html, - add_context=dict(message=msg, model_description=_("Wishlist")), - ) - mail_values = { - "subject": _("The product '%(product_name)s' is now available") % {'product_name': product.name}, - "email_from": (product.company_id.partner_id or self.env.user).email_formatted, - "email_to": wishlist.partner_id.email_formatted, - "body_html": full_mail, - } - - mail = self.env["mail.mail"].sudo().create(mail_values) - mail.send(raise_exception=False) - notified += wishlist - notified.stock_notification = False + def _inverse_stock_notification(self): + for record in self: + if record.stock_notification: + record.product_id.stock_notification_partner_ids += record.partner_id diff --git a/addons/website_sale_stock_wishlist/static/src/js/website_sale.js b/addons/website_sale_stock_wishlist/static/src/js/website_sale.js new file mode 100644 index 00000000000..92ea427f023 --- /dev/null +++ b/addons/website_sale_stock_wishlist/static/src/js/website_sale.js @@ -0,0 +1,20 @@ +/** @odoo-module **/ + +import WebsiteSale from 'website_sale_stock.website_sale'; + +WebsiteSale.include({ + + events: Object.assign({}, WebsiteSale.prototype.events, { + 'click #wishlist_stock_notification_message': '_onClickWishlistStockNotificationMessage', + 'click #wishlist_stock_notification_form_submit_button': '_onClickSubmitWishlistStockNotificationForm', + }), + + _onClickWishlistStockNotificationMessage(ev) { + this._handleClickStockNotificationMessage(ev); + }, + + _onClickSubmitWishlistStockNotificationForm(ev) { + const productId = JSON.parse(ev.currentTarget.closest('tr').dataset.productTrackingInfo).item_id; + this._handleClickSubmitStockNotificationForm(ev, productId); + }, +}); diff --git a/addons/website_sale_stock_wishlist/static/src/js/wishlist.js b/addons/website_sale_stock_wishlist/static/src/js/wishlist.js index 2622be385a7..67c713659e1 100644 --- a/addons/website_sale_stock_wishlist/static/src/js/wishlist.js +++ b/addons/website_sale_stock_wishlist/static/src/js/wishlist.js @@ -4,13 +4,6 @@ import publicWidget from 'web.public.widget'; import 'website_sale_wishlist.wishlist'; publicWidget.registry.ProductWishlist.include({ - events: _.extend({}, publicWidget.registry.ProductWishlist.prototype.events, { - 'click .wishlist-section .o_notify_stock': '_onClickNotifyStock', - }), - - //-------------------------------------------------------------------------- - // Private - //-------------------------------------------------------------------------- /** * Removes wishlist indication when adding a product to the wishlist. @@ -19,29 +12,11 @@ publicWidget.registry.ProductWishlist.include({ */ _addNewProducts: function () { this._super(...arguments); - const wishlistMessageEl = this.el.querySelector('#stock_wishlist_message'); - if (wishlistMessageEl) { - wishlistMessageEl.classList.add('d-none'); + const saveForLaterButtonEl = document.querySelector('#wsale_save_for_later_button'); + const addedToYourWishListAlertEl = document.querySelector('#wsale_added_to_your_wishlist_alert'); + if (saveForLaterButtonEl) { + saveForLaterButtonEl.classList.add('d-none'); + addedToYourWishListAlertEl.classList.remove('d-none'); } }, - /** - * @private - * @param {Event} ev - */ - _onClickNotifyStock: function (ev) { - const targetEl = ev.currentTarget; - const wishID = targetEl.closest('tr').dataset.wishId; - const iconEl = targetEl.querySelector('i'); - const currentNotify = targetEl.dataset.notify === 'True'; - this._rpc({ - route: `/shop/wishlist/notify/${wishID}`, - params: { - notify: !currentNotify, - } - }).then((notify) => { - targetEl.dataset.notify = notify ? 'True' : 'False'; - iconEl.classList.toggle('fa-check-square-o', notify); - iconEl.classList.toggle('fa-square-o', !notify); - }); - }, }); diff --git a/addons/website_sale_stock_wishlist/static/src/xml/product_availability.xml b/addons/website_sale_stock_wishlist/static/src/xml/product_availability.xml index 4f01c7b03a9..0f12e8605f2 100644 --- a/addons/website_sale_stock_wishlist/static/src/xml/product_availability.xml +++ b/addons/website_sale_stock_wishlist/static/src/xml/product_availability.xml @@ -4,27 +4,22 @@
- - Add to your wishlist to be notified when it's back in stock. - -