17 changed files with 559 additions and 0 deletions
@ -0,0 +1,39 @@ |
|||||
|
======================== |
||||
|
POS Product Multiple UOM |
||||
|
======================== |
||||
|
|
||||
|
Added option to update the uom of products in pos. |
||||
|
|
||||
|
Installation |
||||
|
============ |
||||
|
|
||||
|
Just select it from available modules to install it, there is no need to extra installations. |
||||
|
|
||||
|
Usage |
||||
|
===== |
||||
|
|
||||
|
After installation, go to Inventory -> Settings |
||||
|
and enable the multiple uom option under the 'Products' section. |
||||
|
|
||||
|
Known issues / Roadmap |
||||
|
====================== |
||||
|
|
||||
|
* ... |
||||
|
|
||||
|
Bug Tracker |
||||
|
=========== |
||||
|
|
||||
|
Contact odoo@cybrosys.com |
||||
|
|
||||
|
Contributors |
||||
|
------------ |
||||
|
|
||||
|
* Linto CT <linto@cybrosys.in> |
||||
|
* Shereef PT <shereef@cybrosys.in> |
||||
|
|
||||
|
Maintainer |
||||
|
---------- |
||||
|
|
||||
|
This module is maintained by Cybrosys Technologies. |
||||
|
|
||||
|
For support and more information, please visit https://www.cybrosys.com. |
@ -0,0 +1,25 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
|
||||
|
############################################################################## |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# Copyright (C) 2017-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). |
||||
|
# Author: LINTO C T(<https://www.cybrosys.com>) |
||||
|
# you can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# It is forbidden to publish, distribute, sublicense, or sell copies |
||||
|
# of the Software or modified copies of the Software. |
||||
|
# |
||||
|
# 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3) along with this program. |
||||
|
# If not, see <https://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
|
||||
|
import models |
@ -0,0 +1,45 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
|
||||
|
############################################################################## |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# Copyright (C) 2018-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). |
||||
|
# Author: LINTO C T(<https://www.cybrosys.com>) |
||||
|
# you can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# It is forbidden to publish, distribute, sublicense, or sell copies |
||||
|
# of the Software or modified copies of the Software. |
||||
|
# |
||||
|
# 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3) along with this program. |
||||
|
# If not, see <https://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
{ |
||||
|
'name': 'POS Product Multiple UOM', |
||||
|
'version': '10.0.1.0.0', |
||||
|
'category': 'Point of Sale', |
||||
|
'summary': 'Multiple UOM for Products', |
||||
|
'author': 'Cybrosys Techno Solutions', |
||||
|
'company': 'Cybrosys Techno Solutions', |
||||
|
'maintainer': 'Cybrosys Techno Solutions', |
||||
|
'website': 'https://www.cybrosys.com', |
||||
|
'depends': ['point_of_sale', 'stock'], |
||||
|
'data': [ |
||||
|
'views/pos_template.xml', |
||||
|
'views/pos_view_extended.xml', |
||||
|
], |
||||
|
'demo': [], |
||||
|
'qweb': ['static/src/xml/pos.xml'], |
||||
|
'images': ['static/description/banner.jpg'], |
||||
|
'license': 'LGPL-3', |
||||
|
'installable': True, |
||||
|
'application': False, |
||||
|
'auto_install': False, |
||||
|
} |
@ -0,0 +1,3 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
|
||||
|
import pos_orderline |
@ -0,0 +1,112 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
|
||||
|
from odoo import _ |
||||
|
from odoo.tools import float_is_zero |
||||
|
from odoo import models, fields, api |
||||
|
|
||||
|
|
||||
|
class PosOrderLinesExtended(models.Model): |
||||
|
_inherit = 'pos.order.line' |
||||
|
|
||||
|
uom_id = fields.Many2one('product.uom', string="UOM") |
||||
|
|
||||
|
@api.model |
||||
|
def create(self, values): |
||||
|
"""updating uom to orderlines""" |
||||
|
try: |
||||
|
if values.get('uom_id'): |
||||
|
values['uom_id'] = values['uom_id'][0] |
||||
|
except Exception: |
||||
|
values['uom_id'] = None |
||||
|
pass |
||||
|
res = super(PosOrderLinesExtended, self).create(values) |
||||
|
return res |
||||
|
|
||||
|
|
||||
|
class PosOrderExtended(models.Model): |
||||
|
_inherit = 'pos.order' |
||||
|
|
||||
|
# overwriting this function because, we need to set the uom id based on the unit |
||||
|
# in the orderline instead of product uom, at the time of creating the stock moves |
||||
|
def create_picking(self): |
||||
|
"""Create a picking for each order and validate it.""" |
||||
|
Picking = self.env['stock.picking'] |
||||
|
Move = self.env['stock.move'] |
||||
|
StockWarehouse = self.env['stock.warehouse'] |
||||
|
for order in self: |
||||
|
if not order.lines.filtered(lambda l: l.product_id.type in ['product', 'consu']): |
||||
|
continue |
||||
|
address = order.partner_id.address_get(['delivery']) or {} |
||||
|
picking_type = order.picking_type_id |
||||
|
return_pick_type = order.picking_type_id.return_picking_type_id or order.picking_type_id |
||||
|
order_picking = Picking |
||||
|
return_picking = Picking |
||||
|
moves = Move |
||||
|
location_id = order.location_id.id |
||||
|
if order.partner_id: |
||||
|
destination_id = order.partner_id.property_stock_customer.id |
||||
|
else: |
||||
|
if (not picking_type) or (not picking_type.default_location_dest_id): |
||||
|
customerloc, supplierloc = StockWarehouse._get_partner_locations() |
||||
|
destination_id = customerloc.id |
||||
|
else: |
||||
|
destination_id = picking_type.default_location_dest_id.id |
||||
|
|
||||
|
if picking_type: |
||||
|
message = _("This transfer has been created from the point of sale session: <a href=# data-oe-model=pos.order data-oe-id=%d>%s</a>") % (order.id, order.name) |
||||
|
picking_vals = { |
||||
|
'origin': order.name, |
||||
|
'partner_id': address.get('delivery', False), |
||||
|
'date_done': order.date_order, |
||||
|
'picking_type_id': picking_type.id, |
||||
|
'company_id': order.company_id.id, |
||||
|
'move_type': 'direct', |
||||
|
'note': order.note or "", |
||||
|
'location_id': location_id, |
||||
|
'location_dest_id': destination_id, |
||||
|
} |
||||
|
pos_qty = any([x.qty > 0 for x in order.lines if x.product_id.type in ['product', 'consu']]) |
||||
|
if pos_qty: |
||||
|
order_picking = Picking.create(picking_vals.copy()) |
||||
|
order_picking.message_post(body=message) |
||||
|
neg_qty = any([x.qty < 0 for x in order.lines if x.product_id.type in ['product', 'consu']]) |
||||
|
if neg_qty: |
||||
|
return_vals = picking_vals.copy() |
||||
|
return_vals.update({ |
||||
|
'location_id': destination_id, |
||||
|
'location_dest_id': return_pick_type != picking_type and return_pick_type.default_location_dest_id.id or location_id, |
||||
|
'picking_type_id': return_pick_type.id |
||||
|
}) |
||||
|
return_picking = Picking.create(return_vals) |
||||
|
return_picking.message_post(body=message) |
||||
|
|
||||
|
for line in order.lines.filtered(lambda l: l.product_id.type in ['product', 'consu'] and not float_is_zero(l.qty, precision_rounding=l.product_id.uom_id.rounding)): |
||||
|
moves |= Move.create({ |
||||
|
'name': line.name, |
||||
|
'product_uom': line.uom_id.id, |
||||
|
'picking_id': order_picking.id if line.qty >= 0 else return_picking.id, |
||||
|
'picking_type_id': picking_type.id if line.qty >= 0 else return_pick_type.id, |
||||
|
'product_id': line.product_id.id, |
||||
|
'product_uom_qty': abs(line.qty), |
||||
|
'state': 'draft', |
||||
|
'location_id': location_id if line.qty >= 0 else destination_id, |
||||
|
'location_dest_id': destination_id if line.qty >= 0 else return_pick_type != picking_type and return_pick_type.default_location_dest_id.id or location_id, |
||||
|
}) |
||||
|
# prefer associating the regular order picking, not the return |
||||
|
order.write({'picking_id': order_picking.id or return_picking.id}) |
||||
|
|
||||
|
if return_picking: |
||||
|
order._force_picking_done(return_picking) |
||||
|
if order_picking: |
||||
|
order._force_picking_done(order_picking) |
||||
|
|
||||
|
# when the pos.config has no picking_type_id set only the moves will be created |
||||
|
if moves and not return_picking and not order_picking: |
||||
|
tracked_moves = moves.filtered(lambda move: move.product_id.tracking != 'none') |
||||
|
untracked_moves = moves - tracked_moves |
||||
|
tracked_moves.action_confirm() |
||||
|
untracked_moves.action_assign() |
||||
|
moves.filtered(lambda m: m.state in ['confirmed', 'waiting']).force_assign() |
||||
|
moves.filtered(lambda m: m.product_id.tracking == 'none').action_done() |
||||
|
|
||||
|
return True |
After Width: | Height: | Size: 124 KiB |
After Width: | Height: | Size: 50 KiB |
@ -0,0 +1,92 @@ |
|||||
|
<section class="oe_container"> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<h2 class="oe_slogan">POS Product Multiple UOM</h2> |
||||
|
<h3 class="oe_slogan"></h3> |
||||
|
<h4 class="oe_slogan"><a href="https://www.cybrosys.com">Cybrosys Technologies</a> </h4> |
||||
|
</div> |
||||
|
<div class="oe_row oe_spaced" style="padding-left:65px;"> |
||||
|
<h3><p style="margin-left: 42px;"><b>Features:</b></p></h3> |
||||
|
<div> |
||||
|
<span style="color:green;"> ☑ </span> Multiple UOM for products in POS.<br/> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
|
||||
|
<section class="oe_container oe_dark"> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<div class="oe_picture"> |
||||
|
<h3 class="oe_slogan">Overview</h3> |
||||
|
<p class="oe_mt32 text-justify" style="text-align: center;"> |
||||
|
By default, Odoo does not provide the option to update the unit of measure |
||||
|
of the products we select in the point of sale. We can sell products only in its |
||||
|
default unit. This module provides an option to update the UOM of the products |
||||
|
in point of sale. The stock will also be updated in the new UOM. |
||||
|
</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
|
||||
|
<section class="oe_container"> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<h5 class="oe_slogan"><b>New button added for opening the wizard.</b></h5> |
||||
|
<div style="text-align:center;"> |
||||
|
<div class="oe_demo oe_picture oe_screenshot"> |
||||
|
<img src="modify_uom_button.png"> |
||||
|
</div> |
||||
|
</div> |
||||
|
<br /> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<h5 class="oe_slogan"><b>This button will open a wizard which will show all the UOMs |
||||
|
associated with the selected product. |
||||
|
</b></h5> |
||||
|
</div> |
||||
|
<div class="col-md-12"> |
||||
|
<div class="oe_row_img oe_demo oe_picture oe_screenshot"> |
||||
|
<img src="multi_uom_wiz.png"> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<p class="oe_slogan"> |
||||
|
We can select the UOMs available for this product and update it. |
||||
|
</p> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
</section> |
||||
|
|
||||
|
<section class="oe_container oe_dark"> |
||||
|
<div class="col-md-12"> |
||||
|
<div class=" oe_demo oe_picture oe_screenshot"> |
||||
|
<img src="orderlines.png" /> |
||||
|
<div class="oe_demo_footer oe_centeralign" style="background-color:rgba(162, 70, 137, 0.7);"> |
||||
|
Updated orderline |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
|
||||
|
<section class="oe_container"> |
||||
|
<h2 class="oe_slogan" style="margin-top:20px;" >Need Any Help?</h2> |
||||
|
<div class="oe_slogan" style="margin-top:10px !important;"> |
||||
|
<div> |
||||
|
<a class="btn btn-primary btn-lg mt8" |
||||
|
style="color: #FFFFFF !important;border-radius: 0;" href="https://www.cybrosys.com"><i |
||||
|
class="fa fa-envelope"></i> Email </a> <a |
||||
|
class="btn btn-primary btn-lg mt8" style="color: #FFFFFF !important;border-radius: 0;" |
||||
|
href="https://www.cybrosys.com/contact/"><i |
||||
|
class="fa fa-phone"></i> Contact Us </a> <a |
||||
|
class="btn btn-primary btn-lg mt8" style="color: #FFFFFF !important;border-radius: 0;" |
||||
|
href="https://www.cybrosys.com/odoo-customization-and-installation/"><i |
||||
|
class="fa fa-check-square"></i> Request Customization </a> |
||||
|
</div> |
||||
|
<br> |
||||
|
<img src="cybro_logo.png" style="width: 190px; margin-bottom: 20px;" class="center-block"> |
||||
|
<div> |
||||
|
<a href="https://twitter.com/cybrosys" target="_blank"><i class="fa fa-2x fa-twitter" style="color:white;background: #00a0d1;width:35px;"></i></a></td> |
||||
|
<a href="https://www.linkedin.com/company/cybrosys-technologies-pvt-ltd" target="_blank"><i class="fa fa-2x fa-linkedin" style="color:white;background: #31a3d6;width:35px;padding-left: 3px;"></i></a></td> |
||||
|
<a href="https://www.facebook.com/cybrosystechnologies" target="_blank"><i class="fa fa-2x fa-facebook" style="color:white;background: #3b5998;width:35px;padding-left: 8px;"></i></a></td> |
||||
|
<a href="https://plus.google.com/106641282743045431892/about" target="_blank"><i class="fa fa-2x fa-google-plus" style="color:white;background: #c53c2c;width:35px;padding-left: 3px;"></i></a></td> |
||||
|
<a href="https://in.pinterest.com/cybrosys" target="_blank"><i class="fa fa-2x fa-pinterest" style="color:white;background: #ac0f18;width:35px;padding-left: 3px;"></i></a></td> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
After Width: | Height: | Size: 136 KiB |
After Width: | Height: | Size: 108 KiB |
After Width: | Height: | Size: 130 KiB |
@ -0,0 +1,22 @@ |
|||||
|
.button-multi-uom{ |
||||
|
width: 100%; |
||||
|
height: 32px; |
||||
|
font-size: 16px; |
||||
|
text-align: center; |
||||
|
border-radius: 5px; |
||||
|
} |
||||
|
.multi-uom-span { |
||||
|
width: 50%; |
||||
|
border: 1px solid; |
||||
|
/* vertical-align: middle; */ |
||||
|
align-self: center; |
||||
|
padding: 5px 10px; |
||||
|
background-color: #6EC89B; |
||||
|
color: #fff; |
||||
|
LINE-HEIGHT: 2.5; |
||||
|
transition: all 150ms linear; |
||||
|
} |
||||
|
|
||||
|
.popup-product-creation{ |
||||
|
height: 50% !important; |
||||
|
} |
After Width: | Height: | Size: 36 KiB |
@ -0,0 +1,152 @@ |
|||||
|
odoo.define('product_multi_uom_pos.multi_uom',function(require) { |
||||
|
"use strict"; |
||||
|
|
||||
|
var gui = require('point_of_sale.gui'); |
||||
|
var PosBaseWidget = require('point_of_sale.BaseWidget'); |
||||
|
var core = require('web.core'); |
||||
|
var models = require('point_of_sale.models'); |
||||
|
var OrderlineSuper = models.Orderline; |
||||
|
var pos_screens = require('point_of_sale.screens'); |
||||
|
|
||||
|
var MultiUomWidget = PosBaseWidget.extend({ |
||||
|
template: 'MultiUomWidget', |
||||
|
init: function(parent, args) { |
||||
|
this._super(parent, args); |
||||
|
this.options = {}; |
||||
|
this.uom_list = []; |
||||
|
}, |
||||
|
events: { |
||||
|
'click .button.cancel': 'click_cancel', |
||||
|
'click .button.confirm': 'click_confirm', |
||||
|
}, |
||||
|
/*function returns all the uom s in the specified category*/ |
||||
|
get_units_by_category: function(uom_list, categ_id){ |
||||
|
var uom_by_categ = [] |
||||
|
for (var uom in uom_list){ |
||||
|
if(uom_list[uom].category_id[0] == categ_id[0]){ |
||||
|
uom_by_categ.push(uom_list[uom]); |
||||
|
} |
||||
|
} |
||||
|
return uom_by_categ; |
||||
|
}, |
||||
|
/*Find the base price(price of the product for reference unit)*/ |
||||
|
find_reference_unit_price: function(product, product_uom){ |
||||
|
if(product_uom.uom_type == 'reference'){ |
||||
|
return product.price; |
||||
|
} |
||||
|
else if(product_uom.uom_type == 'smaller'){ |
||||
|
return (product.price * product_uom.factor); |
||||
|
} |
||||
|
else if(product_uom.uom_type == 'bigger'){ |
||||
|
return (product.price / product_uom.factor_inv); |
||||
|
} |
||||
|
}, |
||||
|
/*finds the latest price for the product based on the new uom selected*/ |
||||
|
get_latest_price: function(uom, product){ |
||||
|
var uom_by_category = this.get_units_by_category(this.pos.units_by_id, uom.category_id); |
||||
|
var product_uom = this.pos.units_by_id[product.uom_id[0]]; |
||||
|
var ref_price = this.find_reference_unit_price(product, product_uom); |
||||
|
var ref_unit = null; |
||||
|
for (var i in uom_by_category){ |
||||
|
if(uom_by_category[i].uom_type == 'reference'){ |
||||
|
ref_unit = uom_by_category[i]; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
if(ref_unit){ |
||||
|
if(uom.uom_type == 'bigger'){ |
||||
|
return (ref_price * uom.factor_inv); |
||||
|
} |
||||
|
else if(uom.uom_type == 'smaller'){ |
||||
|
return (ref_price / uom.factor); |
||||
|
} |
||||
|
else if(uom.uom_type == 'reference'){ |
||||
|
return ref_price; |
||||
|
} |
||||
|
} |
||||
|
return product.price; |
||||
|
}, |
||||
|
/*Rendering the wizard*/ |
||||
|
show: function(options){ |
||||
|
options = options || {}; |
||||
|
var current_uom = this.pos.units_by_id[options.uom_list[0]]; |
||||
|
var uom_list = this.pos.units_by_id; |
||||
|
var uom_by_category = this.get_units_by_category(uom_list, current_uom.category_id); |
||||
|
this.uom_list = uom_by_category; |
||||
|
this.current_uom = options.uom_list[0]; |
||||
|
this.renderElement(); |
||||
|
}, |
||||
|
close: function(){ |
||||
|
if (this.pos.barcode_reader) { |
||||
|
this.pos.barcode_reader.restore_callbacks(); |
||||
|
} |
||||
|
}, |
||||
|
click_confirm: function(){ |
||||
|
var self = this; |
||||
|
var uom = parseInt(this.$('.uom').val()); |
||||
|
var order = self.pos.get_order(); |
||||
|
var orderline = order.get_selected_orderline(); |
||||
|
var selected_uom = this.pos.units_by_id[uom]; |
||||
|
orderline.uom_id = []; |
||||
|
orderline.uom_id[0] = uom; |
||||
|
orderline.uom_id[1] = selected_uom.display_name; |
||||
|
|
||||
|
/*Updating the orderlines*/ |
||||
|
order.remove_orderline(orderline); |
||||
|
order.add_orderline(orderline); |
||||
|
var latest_price = this.get_latest_price(selected_uom, orderline.product); |
||||
|
order.get_selected_orderline().set_unit_price(latest_price); |
||||
|
this.gui.close_popup(); |
||||
|
return; |
||||
|
|
||||
|
}, |
||||
|
click_cancel: function(){ |
||||
|
this.gui.close_popup(); |
||||
|
}, |
||||
|
}); |
||||
|
gui.define_popup({name:'multi_uom_screen', widget: MultiUomWidget}); |
||||
|
|
||||
|
models.Orderline = models.Orderline.extend({ |
||||
|
/*Adding uom_id to orderline*/ |
||||
|
initialize: function(attr,options){ |
||||
|
OrderlineSuper.prototype.initialize.call(this, attr, options); |
||||
|
this.uom_id = this ? this.product.uom_id: []; |
||||
|
}, |
||||
|
export_as_JSON: function() { |
||||
|
var result = OrderlineSuper.prototype.export_as_JSON.call(this); |
||||
|
result.uom_id = this.uom_id; |
||||
|
return result; |
||||
|
}, |
||||
|
/*this function now will return the uom_id of the orderline , |
||||
|
instead of the default uom_id of the product*/ |
||||
|
get_unit: function(){ |
||||
|
var res = OrderlineSuper.prototype.get_unit.call(this); |
||||
|
|
||||
|
var unit_id = this.uom_id; |
||||
|
if(!unit_id){ |
||||
|
return res; |
||||
|
} |
||||
|
unit_id = unit_id[0]; |
||||
|
if(!this.pos){ |
||||
|
return undefined; |
||||
|
} |
||||
|
return this.pos.units_by_id[unit_id]; |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
pos_screens.ActionpadWidget.include({ |
||||
|
/*opening the wizard on button click*/ |
||||
|
renderElement: function() { |
||||
|
this._super(); |
||||
|
var self = this; |
||||
|
this.$('.multi-uom-span').click(function(){ |
||||
|
var orderline = self.pos.get_order().get_selected_orderline(); |
||||
|
var options = { |
||||
|
'uom_list': orderline.product.uom_id |
||||
|
}; |
||||
|
self.gui.show_popup('multi_uom_screen', options); |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
}); |
@ -0,0 +1,39 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<templates id="template" xml:space="preserve"> |
||||
|
<t t-extend="ActionpadWidget"> |
||||
|
<t t-jquery="div.actionpad" t-operation="before"> |
||||
|
<div class="button-multi-uom"> |
||||
|
<span class="multi-uom-span"> |
||||
|
Modify Unit of Measure |
||||
|
</span> |
||||
|
</div> |
||||
|
</t> |
||||
|
</t> |
||||
|
|
||||
|
<t t-name="MultiUomWidget"> |
||||
|
<div class="modal-dialog multi-uom"> |
||||
|
<div class="popup popup-product-creation"> |
||||
|
<p class="title">Select Unit of Measure</p> |
||||
|
<div> |
||||
|
<select class="uom" style="width:35%;height:30px;border-radius:5px;"> |
||||
|
<t t-foreach='widget.uom_list' t-as='uom'> |
||||
|
<option t-att-value='uom.id' |
||||
|
t-att-selected="((uom.id == widget.current_uom) ? true:undefined)" > |
||||
|
<t t-esc='uom.display_name'/> |
||||
|
</option> |
||||
|
</t> |
||||
|
</select> |
||||
|
</div> |
||||
|
<div class="footer"> |
||||
|
<div class="button confirm"> |
||||
|
Ok |
||||
|
</div> |
||||
|
<div class="button cancel"> |
||||
|
Cancel |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</t> |
||||
|
|
||||
|
</templates> |
@ -0,0 +1,14 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
<data> |
||||
|
<template id="assets" inherit_id="point_of_sale.assets"> |
||||
|
<xpath expr="." position="inside"> |
||||
|
<script type="text/javascript" src="/product_multi_uom_pos/static/src/js/multi_uom.js"></script> |
||||
|
</xpath> |
||||
|
<xpath expr="//link[@id='pos-stylesheet']" position="after"> |
||||
|
<link rel="stylesheet" href="/product_multi_uom_pos/static/src/css/style.css"/> |
||||
|
</xpath> |
||||
|
</template> |
||||
|
|
||||
|
</data> |
||||
|
</odoo> |
@ -0,0 +1,16 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<odoo> |
||||
|
<data> |
||||
|
<!--Adding uom id to lines--> |
||||
|
<record id="pos_order_line_uom" model="ir.ui.view"> |
||||
|
<field name="name">UOM for Order-line</field> |
||||
|
<field name="model">pos.order</field> |
||||
|
<field name="inherit_id" ref="point_of_sale.view_pos_pos_form" /> |
||||
|
<field name="arch" type="xml"> |
||||
|
<xpath expr="//field[@name='lines']/tree/field[@name='qty']" position="after"> |
||||
|
<field name="uom_id"/> |
||||
|
</xpath> |
||||
|
</field> |
||||
|
</record> |
||||
|
</data> |
||||
|
</odoo> |
Loading…
Reference in new issue