diff --git a/pos_multi_variant/__init__.py b/pos_multi_variant/__init__.py
index 727eb6127..cbad9d814 100644
--- a/pos_multi_variant/__init__.py
+++ b/pos_multi_variant/__init__.py
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
+
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
@@ -19,4 +20,5 @@
# If not, see .
#
#############################################################################
+
from . import models
diff --git a/pos_multi_variant/__manifest__.py b/pos_multi_variant/__manifest__.py
index ac06c2618..8df4284b0 100644
--- a/pos_multi_variant/__manifest__.py
+++ b/pos_multi_variant/__manifest__.py
@@ -21,7 +21,7 @@
#############################################################################
{
'name': "POS Product Multi variant",
- 'version': '16.0.1.0.0',
+ 'version': '16.0.1.0.1',
'category': 'Point of Sale',
'summary': """POS Multi-variant module is an advanced way for managing
product variants from the point of sale application""",
diff --git a/pos_multi_variant/doc/RELEASE_NOTES.md b/pos_multi_variant/doc/RELEASE_NOTES.md
index 943eb5d86..d60724117 100755
--- a/pos_multi_variant/doc/RELEASE_NOTES.md
+++ b/pos_multi_variant/doc/RELEASE_NOTES.md
@@ -6,4 +6,7 @@
- Initial commit for POS Product Multi variant
-
+#### 14.01.2025
+#### Version 16.0.1.0.1
+##### ADD
+- Fixed issue related to the amount total in pos orders.
\ No newline at end of file
diff --git a/pos_multi_variant/models/__init__.py b/pos_multi_variant/models/__init__.py
index 3cb2769c0..3b765088a 100644
--- a/pos_multi_variant/models/__init__.py
+++ b/pos_multi_variant/models/__init__.py
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
+
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
@@ -19,6 +20,7 @@
# If not, see .
#
#############################################################################
+
from . import product_template
from . import pos_session
from . import variants_tree
diff --git a/pos_multi_variant/models/pos_session.py b/pos_multi_variant/models/pos_session.py
index 66ae666b0..fea407b63 100644
--- a/pos_multi_variant/models/pos_session.py
+++ b/pos_multi_variant/models/pos_session.py
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
+
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
@@ -19,6 +20,7 @@
# If not, see .
#
#############################################################################
+
from odoo import models
diff --git a/pos_multi_variant/models/product_template.py b/pos_multi_variant/models/product_template.py
index fe89de6cd..e39083f51 100644
--- a/pos_multi_variant/models/product_template.py
+++ b/pos_multi_variant/models/product_template.py
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
+
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
@@ -19,6 +20,7 @@
# If not, see .
#
#############################################################################
+
from odoo import fields, models
diff --git a/pos_multi_variant/models/variants_tree.py b/pos_multi_variant/models/variants_tree.py
index c90a782f7..5bbad8b98 100644
--- a/pos_multi_variant/models/variants_tree.py
+++ b/pos_multi_variant/models/variants_tree.py
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
+
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
@@ -19,6 +20,7 @@
# If not, see .
#
#############################################################################
+
from odoo import fields, models
diff --git a/pos_multi_variant/static/src/css/label.css b/pos_multi_variant/static/src/css/label.css
index 977f72571..8348e398f 100644
--- a/pos_multi_variant/static/src/css/label.css
+++ b/pos_multi_variant/static/src/css/label.css
@@ -38,6 +38,24 @@ position: absolute;
background-color:#d7d7d7;
font-style: italic;
}
+
+.multi_variant {
+ position: absolute;
+ top: 51px;
+ left: 10px;
+ padding: 5px 10px;
+ background-color: #007bff;
+ color: white;
+ font-size: 12px;
+ font-weight: bold;
+ border-radius: 3px;
+ border: 1px solid #0056b3;
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
+ text-transform: uppercase;
+ cursor: default;
+ white-space: nowrap;
+ }
+
.variant-selected{
position: absolute;
bottom: 23px;
@@ -64,4 +82,140 @@ font-style: italic;
justify-content: center;
align-items: center;
color: #03001C;
+}
+
+.pos_multi_variant .product-category {
+ padding: 0.4rem 0;
+ max-width: 1200px;
+ margin: 0 auto;
+}
+
+.pos_multi_variant .category-title {
+ font-size: 1.8rem;
+ color: #333;
+ margin-bottom: 1.5rem;
+ text-align: center;
+ font-weight: 600;
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+}
+
+.pos_multi_variant .product-grid {
+ display: grid;
+ /* Three items per row by default */
+ grid-template-columns: repeat(3, 1fr);
+ gap: 1rem;
+ padding: 0 1rem;
+ margin: 0 auto;
+ max-width: 1000px;
+}
+
+.pos_multi_variant .product-card {
+ position: relative;
+ background: white;
+ border-radius: 12px;
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
+ transition: transform 0.3s ease, box-shadow 0.3s ease;
+ overflow: hidden;
+ cursor: pointer;
+ width: 100%;
+}
+
+.pos_multi_variant .product-card:hover {
+ transform: translateY(-5px);
+ box-shadow: 0 8px 12px rgba(0, 0, 0, 0.15);
+}
+
+.pos_multi_variant .product-image {
+ position: relative;
+ width: 100%;
+ padding-top: 100%; /* 1:1 Aspect Ratio */
+ overflow: hidden;
+}
+
+.pos_multi_variant .product-image img {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ transition: transform 0.3s ease;
+}
+
+.pos_multi_variant .product-card:hover .product-image img {
+ transform: scale(1.05);
+}
+
+.pos_multi_variant .ribbon {
+ position: absolute;
+ top: 20px;
+ left: -5px;
+ background: #40bb4e;
+ color: white;
+ padding: 8px 20px;
+ font-size: 0.85rem;
+ font-weight: 600;
+ text-transform: uppercase;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
+ z-index: 100;
+ clip-path: polygon(0 0, 100% 0, calc(100% - 10px) 100%, 0 100%, 10px 50%);
+}
+
+.pos_multi_variant .price-tag {
+ position: absolute;
+ bottom: 60px;
+ right: 10px;
+ background: rgba(0, 0, 0, 0.8);
+ color: white;
+ padding: 5px 10px;
+ border-radius: 20px;
+ font-size: 0.9rem;
+ font-weight: 500;
+}
+
+.pos_multi_variant .variant-name {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ background: rgba(0, 0, 0, 0.7);
+ color: white;
+ padding: 12px;
+ text-align: center;
+ font-size: 1rem;
+ font-weight: 500;
+}
+
+.pos_multi_variant .section-divider {
+ border: none;
+ height: 1px;
+ background: linear-gradient(to right, transparent, #ddd, transparent);
+ margin: 2rem 0;
+}
+
+/* Tablet view - 2 items per row */
+@media (max-width: 900px) {
+ .pos_multi_variant .product-grid {
+ grid-template-columns: repeat(2, 1fr);
+ gap: 1.5rem;
+ padding: 0 1rem;
+ }
+
+ .pos_multi_variant .category-title {
+ font-size: 1.5rem;
+ }
+}
+
+/* Mobile view - 1 item per row */
+@media (max-width: 600px) {
+ .pos_multi_variant .product-grid {
+ grid-template-columns: 1fr;
+ gap: 1rem;
+ }
+
+ .pos_multi_variant .product-card {
+ max-width: 350px;
+ margin: 0 auto;
+ }
}
\ No newline at end of file
diff --git a/pos_multi_variant/static/src/js/ProductPopup.js b/pos_multi_variant/static/src/js/ProductPopup.js
index 7db458c1f..b99cedbad 100644
--- a/pos_multi_variant/static/src/js/ProductPopup.js
+++ b/pos_multi_variant/static/src/js/ProductPopup.js
@@ -1,75 +1,57 @@
-odoo.define('pos_multi_variant.ProductsPopup', function(require) {
- 'use strict';
- /* This JavaScript code defines the ProductsPopup component, which extends
- * the ProductItem class from the point_of_sale module. It represents a popup
- * for selecting product variants.
- */
- const Registries = require('point_of_sale.Registries');
- const { useListener } = require("@web/core/utils/hooks");
- const ProductItem = require('point_of_sale.ProductItem');
+/** @odoo-module **/
- class ProductsPopup extends ProductItem {
- setup() {
- super.setup();
- useListener('click','.confirm', this.click_confirm);
- useListener('click','.product', this.select_variant);
- useListener('click','.cancel', this.click_cancel);
- }
- select_variant(e) {
- var order = this.env.pos.get_order()
- var self = e.composedPath ? e.composedPath()[2] : e.path[2];
- var action = $(self).find('.action').text();
- var category = $(self).find('.action').data('category');
- $('.product-img').find('.variant-selected').each(function ()
- { if($(this).data('category') == category)
- { $(this).text("").removeClass('variant-selected');
- $(self).find('.action').text("Selected").addClass('variant-selected');
- }
- });
- $(self).find('.action').text("Selected").addClass('variant-selected');
- var add = $(self).find('.extra-price').text().substr(1).slice(0, -2);
- var type = $(self).find('.variants').text();
- $(self).find('.variant-selected').attr('data-price', add);
- $(self).find('.variant-selected').attr('data-type', type);
- }
- click_confirm(e){
- var price = 0.00
- var order = this.env.pos.get_order()
- var selected_orderline = order.get_selected_orderline()
- var variants = []
- this.env.pos.selectedOrder.selected_orderline.product_variants=variants
- $('.product-img').find('.variant-selected').each(function ()
- {
- var add = this.previousSibling.innerHTML;
- add = add.slice(3)
- price += parseFloat(add)
- if (order.selected_orderline.product.is_pos_variants){
- variants.push({
- 'extra_price': add,
- 'type': $(this).data('type'),
- })
- };
- })
- selected_orderline.price_manually_set = true;
- selected_orderline.price += price
- this.env.posbus.trigger('close-popup', {
- popupId: this.props.id
- });
- }
- click_cancel(){
- this.env.posbus.trigger('close-popup', {
- popupId: this.props.id
- });
- }
- imageUrl() {
- return `/web/image?model=product.product&field=image_1920&id=${this.props.product_tmpl_id}&unique=1`;
+import Registries from 'point_of_sale.Registries';
+import { useListener } from "@web/core/utils/hooks";
+const ProductItem = require('point_of_sale.ProductItem');
+const { useState } = owl;
+
+
+class ProductsPopup extends ProductItem {
+ setup() {
+ super.setup();
+ this.state = useState({
+ variant_details: this.props.variant_details,
+ selected_variants: {},
+ price_total: {},
+ })
+ }
+
+ SelectVariant(product,variant) {
+ if (this.state.selected_variants[product.attribute_id[1]] === variant.id){
+ this.state.selected_variants[product.attribute_id[1]] = false
+ this.state.price_total[product.attribute_id[1]] = 0.0
}
- async _clickProduct(event) {
+ else{
+ this.state.selected_variants[product.attribute_id[1]] = variant.id
+ this.state.price_total[product.attribute_id[1]] = product.extra_price
}
}
- ProductsPopup.template = 'ProductsPopUp';
- ProductsPopup.defaultProps = {};
- Registries.Component.add(ProductsPopup);
- return ProductsPopup;
-});
+ clickConfirm(e){
+ const total = Object.values(this.state.price_total).reduce((sum, value) => sum + value, 0);
+ var order = this.env.pos.get_order()
+ var selected_orderline = order.get_selected_orderline()
+ selected_orderline.price += total
+ this.env.posbus.trigger('close-popup', {
+ popupId: this.props.id
+ });
+ }
+ clickCancel(){
+ this.env.pos.get_order().orderlines.remove(this.env.pos.get_order().selected_orderline)
+ this.env.posbus.trigger('close-popup', {
+ popupId: this.props.id
+ });
+ }
+
+ imageUrl() {
+ return `/web/image?model=product.product&field=image_1920&id=${this.props.product_tmpl_id}&unique=1`;
+ }
+
+ getSelected(attr, variant) {
+ return this.state.selected_variants[attr] === variant.id
+ }
+
+}
+ProductsPopup.template = 'ProductsPopUp';
+ProductsPopup.defaultProps = {};
+Registries.Component.add(ProductsPopup);
diff --git a/pos_multi_variant/static/src/js/ProductScreen.js b/pos_multi_variant/static/src/js/ProductScreen.js
index 660e73323..0087e1a55 100644
--- a/pos_multi_variant/static/src/js/ProductScreen.js
+++ b/pos_multi_variant/static/src/js/ProductScreen.js
@@ -1,62 +1,59 @@
-odoo.define('pos_multi_variant.ProductScreen', function(require) {
- 'use strict';
- /* This JavaScript code extends the ProductScreen class from the point_of_sale module.
- * It adds functionality for handling product clicks and displaying the ProductsPopup
- * for selecting variants.
- */
- var ProductScreen = require('point_of_sale.ProductScreen');
- const Registries = require('point_of_sale.Registries');
- const NumberBuffer = require('point_of_sale.NumberBuffer');
- var rpc = require('web.rpc');
- const ProductScreenExtend = (ProductScreen) =>
- class extends ProductScreen {
- constructor() {
- super(...arguments);
+/** @odoo-module **/
+
+import ProductScreen from 'point_of_sale.ProductScreen';
+import Registries from 'point_of_sale.Registries';
+import NumberBuffer from 'point_of_sale.NumberBuffer';
+import rpc from 'web.rpc';
+
+const ProductScreenExtend = (ProductScreen) =>
+class extends ProductScreen {
+ setup() {
+ super.setup();
+ }
+
+ async _clickProduct(event) {
+ await super._clickProduct(...arguments)
+ if (!this.currentOrder) {
+ this.env.pos.add_new_order();
}
- async _clickProduct(event) {
- await super._clickProduct(...arguments)
- if (!this.currentOrder) {
- this.env.pos.add_new_order();
- }
- const product = event.detail;
- var variant_product = ''
- await rpc.query({
- model: 'variants.tree',
- method: 'search_read',
- fields: ['extra_price','attribute_id','value_ids', 'variants_id'],
- args: [[['variants_id','=',event.detail.product_tmpl_id]]]
- }).then(function (data) {
- variant_product = data
- });
- var li=[]
- for(var i=0; i class VariantsPosGlobalState extends PosGlobalState {
- async _processData(loadedData) {
+/** @odoo-module **/
- await super._processData(...arguments);
+import { PosGlobalState } from 'point_of_sale.models';
+import Registries from 'point_of_sale.Registries';
- this.variants_tree = loadedData['variants.tree'];
- this.product_attribute_value = loadedData['product.attribute.value'];
- }
+const VariantsPosGlobalState = (PosGlobalState) => class VariantsPosGlobalState extends PosGlobalState {
+ async _processData(loadedData) {
+
+ await super._processData(...arguments);
+
+ this.variants_tree = loadedData['variants.tree'];
+ this.product_attribute_value = loadedData['product.attribute.value'];
}
- Registries.Model.extend(PosGlobalState, VariantsPosGlobalState);
-});
+}
+Registries.Model.extend(PosGlobalState, VariantsPosGlobalState);
diff --git a/pos_multi_variant/static/src/js/product_variant_orderline.js b/pos_multi_variant/static/src/js/product_variant_orderline.js
index 4fdf5c644..82600904a 100644
--- a/pos_multi_variant/static/src/js/product_variant_orderline.js
+++ b/pos_multi_variant/static/src/js/product_variant_orderline.js
@@ -1,34 +1,23 @@
-odoo.define('pos_order_question.Orderline', function(require) {
- 'use strict';
- /* This JavaScript code defines the PosMultiVariantOrderline class
- * extending the Orderline class from the point_of_sale.models module.
- * It adds additional functionality related to product variants.
- */
- var {
- Orderline,
- } = require('point_of_sale.models');
- var utils = require('web.utils');
- const Registries = require('point_of_sale.Registries');
+/** @odoo-module **/
- const PosMultiVariantOrderline = (Orderline) => class PosMultiVariantOrderline extends Orderline {
+import { Orderline } from 'point_of_sale.models';
+import Registries from 'point_of_sale.Registries';
- constructor(obj, options) {
- super(...arguments);
- this.product_variants = this.product_variants || [];
- }
- export_as_JSON() {
- const json = super.export_as_JSON(...arguments);
- json.product_variants = this.product_variants || [];
- return json;
- }
- export_for_printing() {
- var line = super.export_for_printing(...arguments);
- line.product_variants = this.product_variants;
- return line;
- }
+export const PosMultiVariantOrderline = (Orderline) => class PosMultiVariantOrderline extends Orderline {
+ constructor(obj, options) {
+ super(...arguments);
+ this.product_variants = this.product_variants || [];
}
- Registries.Model.extend(Orderline, PosMultiVariantOrderline);
-});
-
-
+ export_as_JSON() {
+ const json = super.export_as_JSON(...arguments);
+ json.product_variants = this.product_variants || [];
+ return json;
+ }
+ export_for_printing() {
+ var line = super.export_for_printing(...arguments);
+ line.product_variants = this.product_variants;
+ return line;
+ }
+}
+Registries.Model.extend(Orderline, PosMultiVariantOrderline);
diff --git a/pos_multi_variant/static/src/xml/label.xml b/pos_multi_variant/static/src/xml/label.xml
index b77b82001..91ecd0d69 100644
--- a/pos_multi_variant/static/src/xml/label.xml
+++ b/pos_multi_variant/static/src/xml/label.xml
@@ -2,10 +2,9 @@
-
+
- Multi-variant
-
+ Multi-variant
diff --git a/pos_multi_variant/static/src/xml/popup.xml b/pos_multi_variant/static/src/xml/popup.xml
index 99c12b9b6..8a3cea5d5 100644
--- a/pos_multi_variant/static/src/xml/popup.xml
+++ b/pos_multi_variant/static/src/xml/popup.xml
@@ -1,57 +1,53 @@
-
-
-
-
-
-
+
+
+
+
+
+
\ No newline at end of file