Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions setup/website_sale_free_qty_virtual_available/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import setuptools

setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)
68 changes: 68 additions & 0 deletions website_sale_free_qty_virtual_available/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
.. image:: https://img.shields.io/badge/license-LGPL--3-blue.svg
:target: https://opensource.org/licenses/LGPL-3.0
:alt: License: LGPL-3

=======================================================
Website Sale Free Qty Virtual Available
=======================================================

Overview
========

The **Website Sale Free Qty Virtual Available** module replaces the usage of `free_qty` with `virtual_available` to determine if stock is available or not in the context of online sales. This adjustment ensures that only the available quantity (considering reserved stock) is used to check stock availability.

Features
========

- **Stock Availability Based on Virtual Available**:
- The module uses the `virtual_available` field instead of `free_qty` to determine if a product is available for sale, ensuring a more accurate representation of stock levels.

- **Customization**:
- Modifies the product availability template to check stock availability using `virtual_available` when determining if the product is out of stock.

- **Updated Variant Controller**:
- The module extends the variant controller to include the `virtual_available` value for a product, ensuring accurate stock information is provided when querying product combinations.

Usage
=====

1. **Install the Module**:
- Install the **Website Sale Free Qty Virtual Available** module from the Apps menu.

2. **Product Availability Check**:
- After installation, the stock availability check on the website will be based on the `virtual_available` field, which accounts for both real stock and reserved quantities.

3. **Combination Info**:
- When querying product combinations, the updated `virtual_available` value will be included in the response, providing accurate stock information for each variant.

Configuration
=============

No additional configuration is required. The module will automatically replace the use of `free_qty` with `virtual_available` for stock availability checks.

Testing
=======

1. Test by adding a product to the website and verifying that the stock status is based on `virtual_available`.
2. Confirm that when querying product combinations, the `virtual_available` field is correctly included in the response.

Bug Tracker
===========

If you encounter any issues, please report them on the GitHub repository at `GitHub Issues <https://github.com/avanzosc/odoo-addons/issues>`_.

Credits
=======

Contributors
------------

* Ana Juaristi <[email protected]>
* Unai Beristain <[email protected]>

For specific questions or support, please contact the contributors.

License
=======

This project is licensed under the LGPL-3 License. For more details, refer to the LICENSE file or visit <https://opensource.org/licenses/LGPL-3.0>.
1 change: 1 addition & 0 deletions website_sale_free_qty_virtual_available/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import controllers
17 changes: 17 additions & 0 deletions website_sale_free_qty_virtual_available/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "Website Sale Free Qty Virtual Available",
"version": "16.0.1.0.0",
"category": "Website",
"author": "Avanzosc",
"license": "LGPL-3",
"depends": ["website_sale_stock"],
"assets": {
"web.assets_frontend": [
"website_sale_free_qty_virtual_available/static/src/xml/**/*",
"website_sale_free_qty_virtual_available/static/src/js/**/*",
],
},
"installable": True,
"application": False,
"website": "https://github.com/avanzosc/sale-addons",
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import variant
25 changes: 25 additions & 0 deletions website_sale_free_qty_virtual_available/controllers/variant.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from odoo import http
from odoo.http import request

from odoo.addons.sale.controllers.variant import VariantController


class VariantControllerInherit(VariantController):

@http.route(
["/sale/get_combination_info"], type="json", auth="user", methods=["POST"]
)
def get_combination_info(
self, product_template_id, product_id, combination, add_qty, pricelist_id, **kw
):
combination = super().get_combination_info(
product_template_id, product_id, combination, add_qty, pricelist_id, **kw
)

# Retrieve the product.template and add the virtual_available field to combination
product_template = request.env["product.template"].browse(
int(product_template_id)
)
combination.update({"virtual_available": product_template.virtual_available})

return combination
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
odoo.define("website_sale_free_qty_virtual_available.VariantMixin", function (require) {
"use strict";

var VariantMixin = require("website_sale_stock.VariantMixin");

var originalFunction = VariantMixin._onChangeCombinationStock;

VariantMixin._onChangeCombinationStock = function (ev, $parent, combination) {
// originalFunction.apply(this, arguments);

if (combination && combination.product_id) {
var virtualAvailable = combination.virtual_available || 0;

var $input = $parent.find('input[name="add_qty"]');
if ($input.length && parseFloat($input.val()) > virtualAvailable) {
$input.val(virtualAvailable);
}

var $stockWarning = $parent.find(".availability_message");
if ($stockWarning.length) {
var message =
virtualAvailable > 0
? _.str.sprintf("Only %s units available in stock.", virtualAvailable)
: "Out of stock";
$stockWarning.html(message);
}
}
if (
combination.product_type === "product" &&
!combination.allow_out_of_stock_order
) {
combination.virtual_available -= parseInt(combination.cart_qty);
const $addQtyInput = $parent.find('input[name="add_qty"]');
let qty = $addQtyInput.val();
const ctaWrapper = $parent[0].querySelector("#o_wsale_cta_wrapper");
ctaWrapper.classList.replace("d-none", "d-flex");
ctaWrapper.classList.remove("out_of_stock");

$addQtyInput.data("max", combination.virtual_available || 1);
if (combination.virtual_available < 0) {
combination.virtual_available = 0;
}
if (qty > combination.virtual_available) {
qty = combination.virtual_available || 1;
$addQtyInput.val(qty);
}
if (combination.virtual_available < 1) {
ctaWrapper.classList.replace("d-flex", "d-none");
ctaWrapper.classList.add("out_of_stock");
}
}
};
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates id="template" xml:space="preserve">
<t
t-name="website_sale_free_qty_virtual_available.product_availability"
inherit_id="website_sale_stock.product_availability"
>
<xpath expr="//t[@t-if='has_out_of_stock_message']/../.." position="attributes">
<attribute name="t-if">virtual_available lte 0 and !cart_qty</attribute>
</xpath>
</t>
</templates>
Loading