Browse Source

Oct 16: [FIX] Bug fixed 'product_multi_uom_pos'

pull/347/head
Cybrosys Technologies 6 months ago
parent
commit
a3b17f6c7b
  1. 2
      product_multi_uom_pos/__init__.py
  2. 7
      product_multi_uom_pos/__manifest__.py
  3. 8
      product_multi_uom_pos/data/uom_data.xml
  4. 9
      product_multi_uom_pos/doc/RELEASE_NOTES.md
  5. 1
      product_multi_uom_pos/models/__init__.py
  6. 46
      product_multi_uom_pos/models/pos_multi_uom.py
  7. 17
      product_multi_uom_pos/models/pos_session.py
  8. 21
      product_multi_uom_pos/models/product_template.py
  9. 3
      product_multi_uom_pos/models/res_config_settings.py
  10. 17
      product_multi_uom_pos/models/stock_picking.py
  11. 2
      product_multi_uom_pos/security/ir.model.access.csv
  12. BIN
      product_multi_uom_pos/static/description/assets/screenshots/10.png
  13. BIN
      product_multi_uom_pos/static/description/assets/screenshots/2.png
  14. BIN
      product_multi_uom_pos/static/description/assets/screenshots/9.png
  15. 36
      product_multi_uom_pos/static/description/index.html
  16. 24
      product_multi_uom_pos/static/src/overrides/generic_components/orderline/orderline.js
  17. 50
      product_multi_uom_pos/static/src/overrides/generic_components/orderline/orderline.xml
  18. 23
      product_multi_uom_pos/static/src/overrides/models/orderline.js
  19. 12
      product_multi_uom_pos/static/src/overrides/models/store.js
  20. 24
      product_multi_uom_pos/views/pos_order_views.xml
  21. 11
      product_multi_uom_pos/views/product_template_views.xml

2
product_multi_uom_pos/__init__.py

@ -19,4 +19,4 @@
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from . import models
from . import models

7
product_multi_uom_pos/__manifest__.py

@ -21,7 +21,7 @@
#############################################################################
{
'name': "POS Product Multiple UOM",
'version': '17.0.1.0.1',
'version': '17.0.1.0.2',
'category': 'Point of Sale',
'summary': """A module to manage multiple UoM in POS""",
'description': """Using this app, you can change unit of measure of
@ -30,10 +30,9 @@
'company': 'Cybrosys Techno Solutions',
'maintainer': 'Cybrosys Techno Solutions',
'website': "https://www.cybrosys.com",
'depends': ['base', 'point_of_sale'],
'depends': ['point_of_sale', 'uom'],
'data':
[
'security/ir.model.access.csv',
[ 'data/uom_data.xml',
'views/res_config_settings_views.xml',
'views/product_template_views.xml',
'views/pos_order_views.xml',

8
product_multi_uom_pos/data/uom_data.xml

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record model="res.groups" id="base.group_user">
<field name="implied_ids" eval="[(4, ref('uom.group_uom'))]"/>
</record>
</data>
</odoo>

9
product_multi_uom_pos/doc/RELEASE_NOTES.md

@ -18,4 +18,11 @@
#### 20.08.2024
#### Version 17.0.1.0.1
##### UPDT
- Bug Fix - Resolved the issue of UOM shown in sales details report
- Bug Fix - Resolved the issue of UOM shown in sales details report
#### 16.10.2024
#### Version 17.0.1.0.2
##### UPDT
- Bug Fix - 1) Changed the workflow, Unit and price will be automatically calculated on the basis of selected UOM ratio.
2) Resolved issue with the multiple order lines in the POS.
3) Resolved the issue in the delivery.

1
product_multi_uom_pos/models/__init__.py

@ -26,4 +26,3 @@ from . import stock_picking
from . import pos_config
from . import report_sale_details
from . import res_config_settings
from . import pos_multi_uom

46
product_multi_uom_pos/models/pos_multi_uom.py

@ -1,46 +0,0 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Gayathri V (Contact : odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import fields, models
class PosMultiUom(models.Model):
"""
Model for managing Point of Sale (POS) Multi Unit of Measure (UoM).
This model represents the association between a product template and its
multiple unit of measure options for the Point of Sale module.
"""
_name = 'pos.multi.uom'
_description = 'POS Multi UoM'
product_template_id = fields.Many2one('product.template',
string='Product Template',
help='Inverse field of one2many'
'field POS Multiple UoM in'
'product.template')
category_id = fields.Many2one(
related='product_template_id.uom_id.category_id',
string='UoM Category', help='Category of unit of measure')
uom_id = fields.Many2one('uom.uom', string='Unit Of Measure',
domain="[('category_id', '=', category_id)]",
help="Choose a UoM")
price = fields.Float(string='Sale Price', help="Set a price for selected "
"UoM")

17
product_multi_uom_pos/models/pos_session.py

@ -31,20 +31,3 @@ class PosSession(models.Model):
result = super()._loader_params_product_product()
result['search_params']['fields'].append('pos_multi_uom_ids')
return result
def _pos_ui_models_to_load(self):
"""Loading model 'pos.multi.uom' to POS"""
result = super()._pos_ui_models_to_load()
result.append('pos.multi.uom')
return result
def _loader_params_pos_multi_uom(self):
"""Loading fields of model 'pos.multi.uom' to POS"""
return {
'search_params': {
'fields': ['uom_id', 'price', 'product_template_id']}
}
def _get_pos_ui_pos_multi_uom(self, params):
"""Loading new model to POS"""
return self.env['pos.multi.uom'].search_read(**params['search_params'])

21
product_multi_uom_pos/models/product_template.py

@ -27,22 +27,9 @@ class ProductTemplate(models.Model):
of measure"""
_inherit = 'product.template'
multi_uom = fields.Boolean(compute='_compute_multi_uom', string='Multi UoM',
help='A boolean field to show the one2many field'
'POS Multiple UoM if the Multi UoM option'
' is enabled in Configuration settings')
pos_multi_uom_ids = fields.One2many('pos.multi.uom', 'product_template_id',
product_uom_category_id = fields.Many2one(related='uom_id.category_id')
pos_multi_uom_ids = fields.Many2many('uom.uom', 'product_template_id',
string="POS Multiple UoM",
domain="[('category_id', '=', product_uom_category_id)]",
help='These UoM can be selected from '
'PoS')
def _compute_multi_uom(self):
"""
Updates the 'multi_uom' field based on the configuration parameter
'product_multi_uom_pos.pos_multi_uom'.
"""
status = self.env['ir.config_parameter'].sudo().get_param(
'product_multi_uom_pos.pos_multi_uom')
self.write({
'multi_uom': status
})
'PoS')

3
product_multi_uom_pos/models/res_config_settings.py

@ -19,7 +19,8 @@
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import fields, models
from odoo import api, fields, models
from odoo.tools import decode_message_header
class ResConfigSettings(models.TransientModel):

17
product_multi_uom_pos/models/stock_picking.py

@ -20,6 +20,8 @@
#
#############################################################################
from odoo import models
from itertools import groupby
class StockPicking(models.Model):
@ -45,3 +47,18 @@ class StockPicking(models.Model):
'location_dest_id': self.location_dest_id.id,
'company_id': self.company_id.id,
}
def _create_move_from_pos_order_lines(self, lines):
self.ensure_one()
lines_by_product = groupby(
sorted(lines, key=lambda l: (l.product_id.id, l.product_uom_id)),
key=lambda l: (l.product_id.id, l.product_uom_id)
)
move_vals = []
for dummy, olines in lines_by_product:
order_lines = self.env['pos.order.line'].concat(*olines)
move_vals.append(self._prepare_stock_move_vals(order_lines[0], order_lines))
moves = self.env['stock.move'].create(move_vals)
confirmed_moves = moves._action_confirm()
confirmed_moves._add_mls_related_to_order(lines, are_qties_done=True)
confirmed_moves.picked = True
self._link_owner_on_return_picking(lines)

2
product_multi_uom_pos/security/ir.model.access.csv

@ -1,2 +0,0 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_pos_multi_uom,access.pos.multi.uom,model_pos_multi_uom,base.group_user,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_pos_multi_uom access.pos.multi.uom model_pos_multi_uom base.group_user 1 1 1 1

BIN
product_multi_uom_pos/static/description/assets/screenshots/10.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

BIN
product_multi_uom_pos/static/description/assets/screenshots/2.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

After

Width:  |  Height:  |  Size: 118 KiB

BIN
product_multi_uom_pos/static/description/assets/screenshots/9.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

36
product_multi_uom_pos/static/description/index.html

@ -169,8 +169,7 @@
style=" font-weight:600 !important; color:#282F33 !important; font-size:1.3rem !important">
Form View of Product </h4>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
If 'Multiple Unit of Measure' option is
enabled, you can add
You can add
multiple units of measures and its price
under 'Sales' tab of
Products as shown.</p>
@ -178,6 +177,39 @@
</div>
</div>
</div>
<div class="col-lg-12 py-2"
style="padding: 1rem 4rem !important;">
<div
style="border: 1px solid #d8d6d6; border-radius: 4px; background: #fff; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);">
<div class="row justify-content-center p-3 w-100 m-0">
<img src="assets/screenshots/9.png"
class="img-responsive" width="100%"
height="auto">
</div>
<div class="px-3">
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
You can UOM in UOM categories in the Inventory module</p>
</div>
</div>
</div>
<div class="col-lg-12 py-2"
style="padding: 1rem 4rem !important;">
<div
style="border: 1px solid #d8d6d6; border-radius: 4px; background: #fff; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);">
<div class="row justify-content-center p-3 w-100 m-0">
<img src="assets/screenshots/10.png"
class="img-responsive" width="100%"
height="auto">
</div>
<div class="px-3">
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">
Price and unit will be calculated based on the ratio in the UOM
</p>
</div>
</div>
</div>
<div class="col-lg-12 py-2"
style="padding: 1rem 4rem !important;">
<div

24
product_multi_uom_pos/static/src/overrides/generic_components/orderline/orderline.js

@ -5,18 +5,22 @@ import { useRef } from "@odoo/owl";
import { patch } from "@web/core/utils/patch";
patch(Orderline.prototype, {
props: {
...Orderline.props,
line: {
shape: {
multiUom: { type: Array, optional: true },
resetUom: { type: Function, optional: true },
getUom: { type: Function, optional: true },
onSelectionChangedUom: { type: Function, optional: true },
},
},
},
setup(_defaultObj, options) {
super.setup(...arguments);
this.select_uom = useRef("uom_value");
},
});
Orderline.props = {
...Orderline.props,
line: {
shape: {
resetUom: { type: Function, optional: true },
getUom: { type: Function, optional: true },
onSelectionChangedUom: { type: Function, optional: true },
},
},
};

50
product_multi_uom_pos/static/src/overrides/generic_components/orderline/orderline.xml

@ -5,31 +5,31 @@
t-inherit="point_of_sale.Orderline"
t-inherit-mode="extension" owl="1">
<xpath expr="//ul[hasclass('info-list')]" position="after">
<t t-if="line.onSelectionChangedUom and line.getUom(this).length != 0">
<button id="reset_uom" style="margin-top: 15px; background:transparent;border:transparent;
margin-bottom: 5px;margin-left: 180px;"
t-on-click="line.resetUom">
<i class="fa fa-rotate-left"/>
</button>
<select style="width:32%;height:25px;border-radius:5px;border:1px solid transparent;margin-top: -22px;
margin-bottom: 5px;margin-left: 10px; background: rgb(95 115 116 / 20%);"
id="select_uom" class="select_uom"
t-on-change="line.onSelectionChangedUom"
t-ref="uom_value">
<option value="change_uom" id="change_uom"
selected="selected"
disabled="disabled">Change UoM</option>
<t t-foreach="line.getUom(this)" t-as="item"
t-key="item.id">
<option id="select_uom"
class="select_uom"
t-att-value="[item.price,item.uom_id[0],item.uom_id[1]]">
<div><span>$ <t
t-esc="item.price"/> per
<t t-esc="item.uom_id[1]"/></span></div>
</option>
</t>
</select>
<t t-if="line.onSelectionChangedUom">
<t t-if="this.env.services.pos.config.pos_multi_uom and line.multiUom and line.multiUom.length > 0">
<button id="reset_uom" style="margin-top: 25px; background:transparent;border:transparent;
margin-bottom: 5px;margin-left: 180px;"
t-on-click="line.resetUom">
<i class="fa fa-rotate-left"/>
</button>
<select style="width:32%;height:25px;border-radius:5px;border:1px solid transparent;margin-top: -22px;
margin-bottom: 5px;margin-left: 10px; background: rgb(95 115 116 / 20%);"
id="select_uom" class="select_uom"
t-on-change="line.onSelectionChangedUom"
t-ref="uom_value">
<option value="change_uom" id="change_uom"
selected="selected"
disabled="disabled">Change UoM</option>
<t t-foreach="line.multiUom" t-as="item"
t-key="item">
<option id="select_uom"
class="select_uom"
t-att-value="item">
<div><span t-esc="this.env.services.pos.units_by_id[item].name"/></div>
</option>
</t>
</select>
</t>
</t>
</xpath>
</t>

23
product_multi_uom_pos/static/src/overrides/models/orderline.js

@ -43,17 +43,17 @@ patch(Orderline.prototype, {
return this.product.get_unit();
},
onSelectionChangedUom(ev) {
var splitTargetValue = ev.target.value.split(',')
var price = splitTargetValue[0]
var uomId = splitTargetValue[1]
var uomName = splitTargetValue[2]
// Set the selected unit of measure on the order line
const currentOrder = this.env.services.pos.get_order();
currentOrder.selected_orderline.set_uom({0:uomId,1:uomName})
// Set the price_manually_set flag to indicate that the price was manually set
currentOrder.selected_orderline.price_type = "manual";
// Set the unit price of selected UoM on the order line
currentOrder.selected_orderline.set_unit_price(price);
var uom_id = ev.target.value
var selected_uom = this.env.services.pos.units_by_id[uom_id]
var selected_product = this.props.slots['product-name'].__ctx.line
selected_product.set_uom({0:selected_uom.id,1:selected_uom.name})
selected_product.price_type = "manual";
if (selected_uom.uom_type == "smaller"){
selected_product.set_unit_price(selected_product.product.lst_price * (1 / selected_uom.ratio));
} else {
selected_product.set_unit_price(selected_product.product.lst_price * selected_uom.ratio);
}
},
getUom(self) {
const currentOrder = self.env.services.pos.get_order();
@ -74,6 +74,7 @@ patch(Orderline.prototype, {
getUom: this.getUom,
resetUom: this.resetUom,
onSelectionChangedUom: this.onSelectionChangedUom,
multiUom: [...this.product.pos_multi_uom_ids],
};
},
});

12
product_multi_uom_pos/static/src/overrides/models/store.js

@ -1,12 +0,0 @@
/** @odoo-module */
import { PosStore } from "@point_of_sale/app/store/pos_store";
import { patch } from "@web/core/utils/patch";
patch(PosStore.prototype, {
// @Override
async _processData(loadedData) {
await super._processData(...arguments);
this.pos_multi_uom = loadedData['pos.multi.uom'];
},
});

24
product_multi_uom_pos/views/pos_order_views.xml

@ -1,16 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<!-- Adding new field 'uom_id' to POS order line-->
<record id="view_pos_pos_form" model="ir.ui.view">
<field name="name">pos.order.view.form.inherit.product.multi.uom.pos
</field>
<field name="inherit_id" ref="point_of_sale.view_pos_pos_form"/>
<field name="model">pos.order</field>
<field name="arch" type="xml">
<xpath expr="//field[@name='lines']/tree/field[@name='qty']"
position="after">
<field name="uom_id" column_invisible="True"/>
</xpath>
</field>
</record>
<!-- <record id="view_pos_pos_form" model="ir.ui.view">-->
<!-- <field name="name">pos.order.view.form.inherit.product.multi.uom.pos-->
<!-- </field>-->
<!-- <field name="inherit_id" ref="point_of_sale.view_pos_pos_form"/>-->
<!-- <field name="model">pos.order</field>-->
<!-- <field name="arch" type="xml">-->
<!-- <xpath expr="//field[@name='lines']/tree/field[@name='qty']"-->
<!-- position="after">-->
<!-- <field name="uom_id" column_invisible="True"/>-->
<!-- </xpath>-->
<!-- </field>-->
<!-- </record>-->
</odoo>

11
product_multi_uom_pos/views/product_template_views.xml

@ -9,15 +9,8 @@
<field name="model">product.template</field>
<field name="arch" type="xml">
<xpath expr="//field[@name='pos_categ_ids']" position="after">
<field name="multi_uom" invisible="1"/>
<field name="pos_multi_uom_ids"
invisible="multi_uom == False">
<tree editable="bottom">
<field name="uom_id"/>
<field name="price"/>
<field name="category_id" invisible="1"/>
</tree>
</field>
<field name="pos_multi_uom_ids" widget="many2many_tags"/>
<field name="product_uom_category_id"/>
</xpath>
</field>
</record>

Loading…
Cancel
Save