This question has been flagged
3 Replies
6564 Views

Hello there,

I'm on Odoo 8.

I'm searching the way to override the function price_to_str(price) in the file website_sale.js.

I think this file is written with jQuery. So, my usual way to extend Javascript doesn't work.

My custom module is ready. My new .js file is well loaded. So, I just need the javascript code. Not the way to include a new .js file with a custom module.

Could you help?


Code in website_sale.js :

$(document).ready(function () {
    ...
    $('.oe_website_sale').each(function () {
        ...
        function price_to_str(price) {
            price = Math.round(price * 100) / 100;
    var dec = Math.round((price % 1) * 100);
    return price + (dec ? '' : '.0') + (dec%10 ? '' : '0');
    }
        ...
    });
});


EDIT #1

Just a precision. If you use the second way proposed by ALex, You should include your custom .js file with :

<template id="assets_frontend" inherit_id="website.assets_frontend" name="Shop">
            <xpath expr="." position="inside">
                  <script type="text/javascript" src="/my_custom_module_name/static/src/js/website_sale.js"></script>
            </xpath>
</template>



Avatar
Discard
Best Answer

Hi Pascal

Due to that is a nested local function there is no way that you could extend that function using any kind of JS inheritance technique, you could only have at least 2 choices here.

1- You could disconnect that js file using Odoo xml extension like: 

<template id="assets_frontend" inherit_id="website.assets_frontend" name="Shop">
    <xpath expr="//script[@src='/website_sale/static/src/js/website_sale.js']" position="remove"/>
    <xpath expr="." position="inside">
        <script type="text/javascript" src="/your_website_sale_module/static/src/js/website_sale.js"></script>
    </xpath>
</template>

And provide yours with the proper changes, that is a valid way to change JS in extreme scenarios in Odoo 

2- Disconnect the events binding functions that use the price_to_str function in order to rebind it with a new version of the event binding using a new local nested version of the price_to_str function, using jquery.off

http://api.jquery.com/off/

Like:s

$(document).ready(function () {
    function update_product_image(event_source, product_id) {
        var $img = $(event_source).closest('tr.js_product, .oe_website_sale').find('span[data-oe-model^="product."][data-oe-type="image"] img:first, img.product_detail_img');
        $img.attr("src", "/website/image/product.product/" + product_id + "/image");
        $img.parent().attr('data-oe-model', 'product.product').attr('data-oe-id', product_id)
            .data('oe-model', 'product.product').data('oe-id', product_id);
    }

    $('.oe_website_sale').each(function () {
        var oe_website_sale = this;
        
        //your new function
        function price_to_str(price) {
            price = Math.round(price * 100) / 100;
            var dec = Math.round((price % 1) * 100);
            return price + (dec ? '' : '.0') + (dec%10 ? '' : '0');
        }

        $(oe_website_sale).off('change', 'input.js_product_change');
        
        $(oe_website_sale).on('change', 'input.js_product_change', function (ev) {
            var $parent = $(this).closest('.js_product');
            $parent.find(".oe_default_price:first .oe_currency_value").html( price_to_str(+$(this).data('lst_price')) );
            $parent.find(".oe_price:first .oe_currency_value").html(price_to_str(+$(this).data('price')) );
            update_product_image(this, +$(this).val());
        });
        
        $(oe_website_sale).off('change', 'input.js_variant_change, select.js_variant_change, ul[data-attribute_value_ids]');
        
        $(oe_website_sale).on('change', 'input.js_variant_change, select.js_variant_change, ul[data-attribute_value_ids]', function (ev) {
            var $ul = $(ev.target).closest('.js_add_cart_variants');
            var $parent = $ul.closest('.js_product');
            var $product_id = $parent.find('input.product_id').first();
            var $price = $parent.find(".oe_price:first .oe_currency_value");
            var $default_price = $parent.find(".oe_default_price:first .oe_currency_value");
            var $optional_price = $parent.find(".oe_optional:first .oe_currency_value");
            var variant_ids = $ul.data("attribute_value_ids");
            var values = [];
            $parent.find('input.js_variant_change:checked, select.js_variant_change').each(function () {
                values.push(+$(this).val());
            });

            $parent.find("label").removeClass("text-muted css_not_available");

            var product_id = false;
            for (var k in variant_ids) {
                if (_.isEmpty(_.difference(variant_ids[k][1], values))) {
                    $price.html(price_to_str(variant_ids[k][2]));
                    $default_price.html(price_to_str(variant_ids[k][3]));
                    if (variant_ids[k][3]-variant_ids[k][2]>0.2) {
                        $default_price.closest('.oe_website_sale').addClass("discount");
                        $optional_price.closest('.oe_optional').show().css('text-decoration', 'line-through');
                    } else {
                        $default_price.closest('.oe_website_sale').removeClass("discount");
                        $optional_price.closest('.oe_optional').hide();
                    }
                    product_id = variant_ids[k][0];
                    break;
                }
            }

            if (product_id) {
                update_product_image(this, product_id);
            }

            $parent.find("input.js_variant_change:radio, select.js_variant_change").each(function () {
                var $input = $(this);
                var id = +$input.val();
                var values = [id];

                $parent.find("ul:not(:has(input.js_variant_change[value='" + id + "'])) input.js_variant_change:checked, select").each(function () {
                    values.push(+$(this).val());
                });

                for (var k in variant_ids) {
                    if (!_.difference(values, variant_ids[k][1]).length) {
                        return;
                    }
                }
                $input.closest("label").addClass("css_not_available");
                $input.find("option[value='" + id + "']").addClass("css_not_available");
            });

            if (product_id) {
                $parent.removeClass("css_not_available");
                $product_id.val(product_id);
                $parent.find(".js_check_product").removeAttr("disabled");
            } else {
                $parent.addClass("css_not_available");
                $product_id.val(0);
                $parent.find(".js_check_product").attr("disabled", "disabled");
            }
        });
    });
});

That I think that is the one choice you could do if you don't want to use the first choice to provide a new version of the whole file recommended in this case

Hope this help you

Avatar
Discard
Author

Absolutely great! Thanks a lot my friend.

Best Answer

Hello Pascal,


If you want the default behavior...  You can also update the code, this function has been fixed to respect the Odoo configuration (rounding, decimal separator, ...) meanwhile.


https://github.com/odoo/odoo/commit/fee60159640206558e98d5103c8a883412419f5a


Best regards


JKE

Avatar
Discard
Author

Thanks for this answer.

I have downloaded new sources. All these changes are applied in the new code : https://github.com/odoo-dev/odoo/commit/52d73263f10df715fe481d0d815c004935a001a4

I have updated my views.

I have disabled my custom website_sale.js.

Decimal separator (comma) is well displayed in the cart in all case.

Decimal separator (comma) is well displayed in the product page without variants.

One problem still persists on product pages with variants. On load, the price is still displayed with a dot instead of a comma. But as soon as I select another variant, the price come back with a comma...

Author

I've just tried with a fresh installation of the last nightly build of Odoo 8. The problem persists. If I load a product page and the product has some variants, the first price displayed on load doesn't respect the decimal separator. A dot is displayed instead of a comma. If I select another variant, the price is well displayed with the comma.

Thanks, i have just checked now and I reproduce your problem.

I will check it asap.

There are also another bug where the group is done with value < 1000... Eg: 340,00€ => .340,00

Strange ... maybe a typo during the cleaning...

Author

Yeah! Happy to see that I'm not crazy! Always nervous to find error in Odoo code.