Well, the current behavior when we go to the shop, is according to how much item is left of a product, shows you the amount of Item that remains this logic does not take into account whether you are a registered user of the online store, or not. what I want is to expand the behavior and that if it is user without registering, do not show you the amount of stock I have of this item.
Current code of the module to be modified
website_sale_stock>static>src>xml>website_sale_stock_product_available.xml I can't show xml view
website_sale_stock>static>src>js>variant_mixin.js
odoo.define('website_sale_stock.VariantMixin', function (require) {
'use strict';
const {Markup} = require('web.utils');
var VariantMixin = require('sale.VariantMixin');
var publicWidget = require('web.public.widget');
var ajax = require('web.ajax');
var core = require('web.core');
var QWeb = core.qweb;
const loadXml = async () => {
return ajax.loadXML('/website_sale_stock/static/src/xml/website_sale_stock_product_availability.xml', QWeb);
};
require('website_sale.website_sale');
/**
* Addition to the variant_mixin._onChangeCombination
*
* This will prevent the user from selecting a quantity that is not available in the
* stock for that product.
*
* It will also display various info/warning messages regarding the select product's stock.
*
* This behavior is only applied for the web shop (and not on the SO form)
* and only for the main product.
*
* @param {MouseEvent} ev
* @param {$.Element} $parent
* @param {Array} combination
*/
VariantMixin._onChangeCombinationStock = function (ev, $parent, combination) {
let product_id = 0;
// needed for list view of variants
if ($parent.find('input.product_id:checked').length) {
product_id = $parent.find('input.product_id:checked').val();
} else {
product_id = $parent.find('.product_id').val();
}
const isMainProduct = combination.product_id &&
($parent.is('.js_main_product') || $parent.is('.main_product')) &&
combination.product_id === parseInt(product_id);
if (!this.isWebsite || !isMainProduct) {
return;
}
const $addQtyInput = $parent.find('input[name="add_qty"]');
let qty = $addQtyInput.val();
$parent.find('#add_to_cart').removeClass('out_of_stock');
$parent.find('.o_we_buy_now').removeClass('out_of_stock');
if (combination.product_type === 'product' && !combination.allow_out_of_stock_order) {
combination.free_qty -= parseInt(combination.cart_qty);
$addQtyInput.data('max', combination.free_qty || 1);
if (combination.free_qty combination.free_qty = 0;
}
if (qty > combination.free_qty) {
qty = combination.free_qty || 1;
$addQtyInput.val(qty);
}
if (combination.free_qty $parent.find('#add_to_cart').addClass('disabled out_of_stock');
$parent.find('.o_we_buy_now').addClass('disabled out_of_stock');
}
}
loadXml().then(function (result) {
$('.oe_website_sale')
.find('.availability_message_' + combination.product_template)
.remove();
combination.has_out_of_stock_message = $(combination.out_of_stock_message).text() !== '';
combination.out_of_stock_message = Markup(combination.out_of_stock_message);
const $message = $(QWeb.render(
'website_sale_stock.product_availability',
combination
));
$('div.availability_messages').html($message);
});
};
publicWidget.registry.WebsiteSale.include({
/**
* Adds the stock checking to the regular _onChangeCombination method
* @override
*/
_onChangeCombination: function () {
this._super.apply(this, arguments);
VariantMixin._onChangeCombinationStock.apply(this, arguments);
},
/**
* Recomputes the combination after adding a product to the cart
* @override
*/
_onClickAdd(ev) {
return this._super.apply(this, arguments).then(() => {
if ($('div.availability_messages').length) {
this._getCombinationInfo(ev);
}
});
}
});
return VariantMixin;
});
website_sale_stock>controller>main.py
class PaymentPortal(website_sale_controller.PaymentPortal):
@http.route()
def shop_payment_transaction(self, *args, **kwargs):
""" Payment transaction override to double check cart quantities before
placing the order
"""
order = request.website.sale_get_order()
values = []
for line in order.order_line:
if line.product_id.type == 'product' and not line.product_id.allow_out_of_stock_order:
cart_qty = sum(order.order_line.filtered(lambda p: p.product_id.id == line.product_id.id).mapped('product_uom_qty'))
avl_qty = line.product_id.with_context(warehouse=order.warehouse_id.id).free_qty
if cart_qty > avl_qty:
values.append(_(
'You ask for %(quantity)s products but only %(available_qty)s is available',
quantity=cart_qty,
available_qty=avl_qty if avl_qty > 0 else 0
))
if values:
raise ValidationError('. '.join(values) + '.')
return super().shop_payment_transaction(*args, **kwargs)
Then the first thins that I do, is add necesary code for extend the behavior from website_sale_stock
website_sale_stock>static>src>xml>website_sale_stock_product_available.xml
Add t-if="user_id != public_user_id"
website_sale_stock>static>src>js>variant_mixin.js
The same origin
website_sale_stock>controller>main.py
class PaymentPortal(website_sale_controller.PaymentPortal):
@http.route()
def shop_payment_transaction(self, *args, **kwargs):
""" Payment transaction override to double check cart quantities before
placing the order
"""
order = request.website.sale_get_order()
values = []
for line in order.order_line:
if line.product_id.type == 'product' and not line.product_id.allow_out_of_stock_order:
cart_qty = sum(order.order_line.filtered(lambda p: p.product_id.id == line.product_id.id).mapped('product_uom_qty'))
avl_qty = line.product_id.with_context(warehouse=order.warehouse_id.id).free_qty
if cart_qty > avl_qty:
values.append(_(
'You ask for %(quantity)s products but only %(available_qty)s is available',
quantity=cart_qty,
available_qty=avl_qty if avl_qty > 0 else 0
))
if values:
raise ValidationError('. '.join(values) + '.')
return super().shop_payment_transaction(*args, **kwargs)
@http.route('/restingir_visibilidad_stock/product_availability', type='http',auth='public',website=True)
def custom_route(self, **kwargs):
return request.render('restringir_visibilidad_stock.restriccion_view', {
'user_id': request.env.user.id,
'public_user_id': request.env.ref('base.public_user').id,
})
And this code is sucessfully.
The last part is I want to extract the code to create a new module and have generated the following code.
restringir_visibilidad_stock>static>src>xml>restriccion_view.xml
restringir_visibilidad_stock>static>src>js>variant.js
I copy origin code, and I change only, call to xml view
restringir_visibilidad_stock>controller>main.py
# -*- coding: utf-8 -*-
# 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.http import request
from odoo.exceptions import ValidationError
# código hecho por David Ymant
class PaymentPortal(http.HTTP):
@http.route('/restingir_visibilidad_stock/product_availability', type='http',auth='public',website=True)
def custom_route(self, **kwargs):
return request.render('restringir_visibilidad_stock.restriccion_view', {
'user_id': request.env.user.id,
'public_user_id': request.env.ref('base.public_user').id,
})
is functional, but this way I disable the option that in the search engine of the online store, show me the list of components that match the search, for example, if I put key, it don't display all items that begin with key...
Any thelp is welcome.