@ -0,0 +1,42 @@ |
|||||
|
======================== |
||||
|
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 |
||||
|
------------ |
||||
|
|
||||
|
* Version 10: Linto CT <linto@cybrosys.in> |
||||
|
* Version 10: Shereef PT <shereef@cybrosys.in> |
||||
|
* Version 12: Mehjabin Farsana <mehjabin@cybrosys.in> |
||||
|
* Version 13: Mehjabin Farsana <mehjabin@cybrosys.in> |
||||
|
* Version 14: Jibin James <jibin@cybrosys.in> |
||||
|
|
||||
|
Maintainer |
||||
|
---------- |
||||
|
|
||||
|
This module is maintained by Cybrosys Technologies. |
||||
|
|
||||
|
For support and more information, please visit https://www.cybrosys.com. |
@ -0,0 +1,23 @@ |
|||||
|
# -*- 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. |
||||
|
# |
||||
|
# 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/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
|
||||
|
from . import models |
@ -0,0 +1,52 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
|
||||
|
############################################################################## |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2020-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. |
||||
|
# |
||||
|
# 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': '15.0.1.0.0', |
||||
|
'category': 'Point of Sale', |
||||
|
'sequence': -100, |
||||
|
'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_view_extended.xml', |
||||
|
], |
||||
|
# 'qweb': ['static/src/xml/pos.xml'], |
||||
|
'images': ['static/description/banner.png', |
||||
|
'static/description/icon.png'], |
||||
|
'assets': { |
||||
|
'point_of_sale.assets': [ |
||||
|
'product_multi_uom_pos/static/src/css/style.css', |
||||
|
'product_multi_uom_pos/static/src/js/models.js', |
||||
|
'product_multi_uom_pos/static/src/js/multi_uom_widget.js', |
||||
|
'product_multi_uom_pos/static/src/js/uom_button.js', |
||||
|
], |
||||
|
'web.assets_qweb': ['product_multi_uom_pos/static/src/xml/pos.xml'], |
||||
|
}, |
||||
|
'license': 'LGPL-3', |
||||
|
'installable': True, |
||||
|
'application': False, |
||||
|
'auto_install': False, |
||||
|
} |
@ -0,0 +1,10 @@ |
|||||
|
## Module <product_multi_uom_pos> |
||||
|
|
||||
|
#### 26.11.2020 |
||||
|
#### Version 14.0.1.0.0 |
||||
|
#### Migration |
||||
|
Migration Of POS Product Multiple UOM |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
@ -0,0 +1,23 @@ |
|||||
|
# -*- 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. |
||||
|
# |
||||
|
# 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/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
|
||||
|
from . import pos_orderline |
@ -0,0 +1,133 @@ |
|||||
|
# -*- 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. |
||||
|
# |
||||
|
# 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/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
|
||||
|
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('uom.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 |
||||
|
source_loc = picking_type.default_location_src_id |
||||
|
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': source_loc.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': source_loc.id, |
||||
|
'location_dest_id': return_pick_type != picking_type and return_pick_type.default_location_dest_id.id or source_loc.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 if line.uom_id.id else line.product_id.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': source_loc.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 source_loc.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: 310 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 576 B |
After Width: | Height: | Size: 733 B |
After Width: | Height: | Size: 911 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 673 B |
After Width: | Height: | Size: 878 B |
After Width: | Height: | Size: 653 B |
After Width: | Height: | Size: 905 B |
After Width: | Height: | Size: 839 B |
After Width: | Height: | Size: 427 B |
After Width: | Height: | Size: 627 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 988 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 59 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 93 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 57 KiB |
After Width: | Height: | Size: 63 KiB |
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 56 KiB |
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 52 KiB |
After Width: | Height: | Size: 69 KiB |
After Width: | Height: | Size: 68 KiB |
After Width: | Height: | Size: 72 KiB |
@ -0,0 +1,582 @@ |
|||||
|
<div class="container" style="padding: 1rem !important; margin-bottom: 1.5rem !important;"> |
||||
|
<div class="row"> |
||||
|
<div class="col-sm-12 col-md-12 col-lg-12 d-flex justify-content-between" |
||||
|
style="border-bottom: 1px solid #d5d5d5;"> |
||||
|
<div class="my-3"> |
||||
|
<img src="./images/logo.png" style="width: auto !important; height: 40px !important;"> |
||||
|
</div> |
||||
|
<div class="my-3 d-flex align-items-center"> |
||||
|
<div |
||||
|
style="background-color: #7C7BAD !important; color: #fff !important; font-weight: 600 !important; padding: 5px 15px 8px !important; margin: 0 5px !important;"> |
||||
|
<i class="fa fa-check mr-1"></i>Community |
||||
|
</div> |
||||
|
<div |
||||
|
style="background-color: #875A7B !important; color: #fff !important; font-weight: 600 !important; padding: 5px 15px 8px !important; margin: 0 5px !important;"> |
||||
|
<i class="fa fa-check mr-1"></i>Enterprise |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div style="padding: 3.5rem 1.5rem !important; background-color: #ffffff !important;"> |
||||
|
<div class="container"> |
||||
|
<!-- HERO --> |
||||
|
<div class="row"> |
||||
|
<div class="col-lg-12 d-flex flex-column justify-content-center" |
||||
|
style="text-align: center; padding: 1rem !important;"> |
||||
|
<h1 class="text-center" style="color: #212121 !important; font-size: 3.5rem !important;"><span |
||||
|
style="font-weight: 700 !important;">POS Product Multiple UOM</span></h1> |
||||
|
<p class="text-center" |
||||
|
style="color: #212529 !important; font-size: 1.5rem !important; letter-spacing: 5px !important;"> |
||||
|
Update Product Unit Of Measure |
||||
|
</p> |
||||
|
<img src="./images/hero.png" class="img-responsive"> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- END OF HERO --> |
||||
|
|
||||
|
<!-- OVERVIEW --> |
||||
|
<div class="row"> |
||||
|
<div class="col-lg-12 d-flex flex-column justify-content-center" |
||||
|
style="text-align: center; padding: 2.5rem 1rem !important;"> |
||||
|
<h2 style="color: #212529 !important;">Overview</h2> |
||||
|
<hr |
||||
|
style="border: 3px solid #AC1015 !important; background-color: #AC1015 !important; width: 80px !important; margin-bottom: 2rem !important;" /> |
||||
|
<p class="text-center" style="color: #212529 !important; font-size: 1.5rem !important;"> |
||||
|
By default, Odoo does not provide the option to update the unit of measure of the products we |
||||
|
selected in the Point of Sale. The Products can only be sold in its default unit. This module |
||||
|
provides an option to update the UOM of the products in the Point of Sale. The stock will also |
||||
|
be updated in the new UOM. |
||||
|
</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- END OF OVERVIEW --> |
||||
|
|
||||
|
|
||||
|
<!-- KEY FEATURES --> |
||||
|
<div class="row"> |
||||
|
<div class="col-lg-12 d-flex flex-column justify-content-center" style="padding: 2.5rem 1rem !important;"> |
||||
|
<h2 class="text-center" style="color: #212529 !important;">Key Features</h2> |
||||
|
<hr |
||||
|
style="border: 3px solid #AC1015 !important; background-color: #AC1015 !important; width: 80px !important; margin-bottom: 2rem !important;" /> |
||||
|
<div class="row"> |
||||
|
|
||||
|
|
||||
|
<div class="col-lg-12"> |
||||
|
|
||||
|
<div class="d-flex deep-2" |
||||
|
style="height: 60px !important; padding: 1rem 1.5rem !important; border-radius: 0 !important; margin: 1.5rem 0"> |
||||
|
<img src="./images/checked.png" style="height: 24px !important; width: 24px !important;" |
||||
|
class="mt-1 mr-2" height="24px" width="24px"> |
||||
|
<p style="color: #212529 !important; font-size: 1.3rem !important;"> |
||||
|
Multiple UOM for products in POS. |
||||
|
</p> |
||||
|
</div> |
||||
|
|
||||
|
<div class="d-flex deep-2" |
||||
|
style="height: 60px !important; padding: 1rem 1.5rem !important; border-radius: 0 !important; margin: 1.5rem 0"> |
||||
|
<img src="./images/checked.png" style="height: 24px !important; width: 24px !important;" |
||||
|
class="mt-1 mr-2" height="24px" width="24px"> |
||||
|
<p style="color: #212529 !important; font-size: 1.3rem !important;"> |
||||
|
Select Unit of measure popup. |
||||
|
</p> |
||||
|
</div> |
||||
|
<div class="d-flex deep-2" |
||||
|
style="height: 60px !important; padding: 1rem 1.5rem !important; border-radius: 0 !important; margin: 1.5rem 0"> |
||||
|
<img src="./images/checked.png" style="height: 24px !important; width: 24px !important;" |
||||
|
class="mt-1 mr-2" height="24px" width="24px"> |
||||
|
<p style="color: #212529 !important; font-size: 1.3rem !important;"> |
||||
|
Updated uom to orderlines. |
||||
|
</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<!-- END OF KEY FEATURES --> |
||||
|
|
||||
|
<!-- SCREENSHOTS --> |
||||
|
<div class="row"> |
||||
|
<div class="col-lg-12 d-flex flex-column justify-content-center" style="padding: 2.5rem 1rem !important;"> |
||||
|
<h2 style="text-align: center; color: #212529 !important;">Screenshots</h2> |
||||
|
<hr |
||||
|
style="border: 3px solid #AC1015 !important; background-color: #AC1015 !important; width: 80px !important; margin-bottom: 2rem !important;" /> |
||||
|
|
||||
|
<!-- img --> |
||||
|
<div class="d-flex m-0" style="border-bottom: 1px solid #e5e5e5 !important;"> |
||||
|
<div class="mr-3"> |
||||
|
<h3 |
||||
|
style="font-size: 2rem !important; font-weight: 800 !important; color: #ffffff !important; background-color: #AC1015 !important; padding: 1rem !important; width: 70px !important; height: 75px !important;"> |
||||
|
01</h3> |
||||
|
</div> |
||||
|
<div> |
||||
|
<h3 style="font-size: 1.7rem !important; font-weight: 600 !important;"> |
||||
|
Modify UOM Button |
||||
|
</h3> |
||||
|
<p |
||||
|
style="color: #212529 !important; font-size: 1.3rem !important; font-weight: 300 !important;"> |
||||
|
Modify Unit of Measure Button in POS. |
||||
|
</p> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
<img src="./images/screenshot-01.png" class="img-responsive border" |
||||
|
style="margin-top: -15px !important; margin-top: 1rem !important; margin-bottom: 4rem !important;"> |
||||
|
<!-- endo of img --> |
||||
|
|
||||
|
<!-- img --> |
||||
|
<div class="d-flex m-0" style="border-bottom: 1px solid #e5e5e5 !important;"> |
||||
|
<div class="mr-3"> |
||||
|
<h3 |
||||
|
style="font-size: 2rem !important; font-weight: 800 !important; color: #ffffff !important; background-color: #AC1015 !important; padding: 1rem !important; width: 70px !important; height: 75px !important;"> |
||||
|
02</h3> |
||||
|
</div> |
||||
|
<div> |
||||
|
<h3 style="font-size: 1.7rem !important; font-weight: 600 !important;"> |
||||
|
Available UOM Wizards |
||||
|
</h3> |
||||
|
<p |
||||
|
style="color: #212529 !important; font-size: 1.3rem !important; font-weight: 300 !important;"> |
||||
|
This button will open a wizard which will show all the UOMs associated with the selected |
||||
|
product. |
||||
|
</p> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
<img src="./images/screenshot-02.png" class="img-responsive border" |
||||
|
style="margin-top: -15px !important; margin-top: 1rem !important; margin-bottom: 4rem !important;"> |
||||
|
<!-- endo of img --> |
||||
|
|
||||
|
<!-- img --> |
||||
|
<div class="d-flex m-0" style="border-bottom: 1px solid #e5e5e5 !important;"> |
||||
|
<div class="mr-3"> |
||||
|
<h3 |
||||
|
style="font-size: 2rem !important; font-weight: 800 !important; color: #ffffff !important; background-color: #AC1015 !important; padding: 1rem !important; width: 70px !important; height: 75px !important;"> |
||||
|
03</h3> |
||||
|
</div> |
||||
|
<div> |
||||
|
<h3 style="font-size: 1.7rem !important; font-weight: 600 !important;"> |
||||
|
Select UOM Available for Products |
||||
|
</h3> |
||||
|
<p |
||||
|
style="color: #212529 !important; font-size: 1.3rem !important; font-weight: 300 !important;"> |
||||
|
UOMs available for this product can be selected and updated. |
||||
|
</p> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
<img src="./images/screenshot-03.png" class="img-responsive border" |
||||
|
style="margin-top: -15px !important; margin-top: 1rem !important; margin-bottom: 4rem !important;"> |
||||
|
<!-- endo of img --> |
||||
|
|
||||
|
<!-- img --> |
||||
|
<div class="d-flex m-0" style="border-bottom: 1px solid #e5e5e5 !important;"> |
||||
|
<div class="mr-3"> |
||||
|
<h3 |
||||
|
style="font-size: 2rem !important; font-weight: 800 !important; color: #ffffff !important; background-color: #AC1015 !important; padding: 1rem !important; width: 70px !important; height: 75px !important;"> |
||||
|
04</h3> |
||||
|
</div> |
||||
|
<div> |
||||
|
<h3 style="font-size: 1.7rem !important; font-weight: 600 !important;"> |
||||
|
Updated UOM in POS Orderlines |
||||
|
</h3> |
||||
|
<p |
||||
|
style="color: #212529 !important; font-size: 1.3rem !important; font-weight: 300 !important;"> |
||||
|
Updated Unit of Measure in POS Orderlines. |
||||
|
</p> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
<img src="./images/screenshot-04.png" class="img-responsive border" |
||||
|
style="margin-top: -15px !important; margin-top: 1rem !important; margin-bottom: 4rem !important;"> |
||||
|
<!-- endo of img --> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- END OF SCREENSHOTS --> |
||||
|
|
||||
|
<!-- SUGGESTED PRODUCTS --> |
||||
|
<div class="row"> |
||||
|
<div class="col-lg-12 d-flex flex-column justify-content-center" |
||||
|
style="text-align: center; padding: 2.5rem 1rem !important;"> |
||||
|
<h2 style="color: #212529 !important;">Suggested Products</h2> |
||||
|
<hr |
||||
|
style="border: 3px solid #AC1015 !important; background-color: #AC1015 !important; width: 80px !important; margin-bottom: 2rem !important;" /> |
||||
|
|
||||
|
<div id="demo1" class="row carousel slide" data-ride="carousel"> |
||||
|
<!-- The slideshow --> |
||||
|
<div class="carousel-inner"> |
||||
|
<div class="carousel-item active" style="min-height:0px"> |
||||
|
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left"> |
||||
|
<a href="https://apps.odoo.com/apps/modules/14.0/product_return_pos/" target="_blank"> |
||||
|
<div style="border-radius:10px"> |
||||
|
<img class="img img-responsive center-block" |
||||
|
style="border-top-left-radius:10px; border-top-right-radius:10px" |
||||
|
src="./images/modules/pos_return_image.png"> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left"> |
||||
|
<a href="https://apps.odoo.com/apps/modules/14.0/product_barcode/" target="_blank"> |
||||
|
<div style="border-radius:10px"> |
||||
|
<img class="img img-responsive center-block" |
||||
|
style="border-top-left-radius:10px; border-top-right-radius:10px" |
||||
|
src="./images/modules/barcode_image.png"> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left"> |
||||
|
<a href="https://apps.odoo.com/apps/modules/14.0/barcode_scanning_sale_purchase/" |
||||
|
target="_blank"> |
||||
|
<div style="border-radius:10px"> |
||||
|
<img class="img img-responsive center-block" |
||||
|
style="border-top-left-radius:10px; border-top-right-radius:10px" |
||||
|
src="./images/modules/barcode_scan_image.png"> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="carousel-item" style="min-height:0px"> |
||||
|
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left"> |
||||
|
<a href="https://apps.odoo.com/apps/modules/14.0/pos_order_types/" target="_blank"> |
||||
|
<div style="border-radius:10px"> |
||||
|
<img class="img img-responsive center-block" |
||||
|
style="border-top-left-radius:10px; border-top-right-radius:10px" |
||||
|
src="./images/modules/pos_order_image.png"> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left"> |
||||
|
<a href="https://apps.odoo.com/apps/modules/14.0/account_payment_approval/" |
||||
|
target="_blank"> |
||||
|
<div style="border-radius:10px"> |
||||
|
<img class="img img-responsive center-block" |
||||
|
style="border-top-left-radius:10px; border-top-right-radius:10px" |
||||
|
src="./images/modules/payment_image.png"> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left"> |
||||
|
<a href="https://apps.odoo.com/apps/modules/14.0/point_of_sale_logo/" target="_blank"> |
||||
|
<div style="border-radius:10px"> |
||||
|
<img class="img img-responsive center-block" |
||||
|
style="border-top-left-radius:10px; border-top-right-radius:10px" |
||||
|
src="./images/modules/pos_logo_image.png"> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- Left and right controls --> |
||||
|
<a class="carousel-control-prev" href="#demo1" data-slide="prev" |
||||
|
style="left:-25px;width: 35px;color: #000;"> <span class="carousel-control-prev-icon"><i |
||||
|
class="fa fa-chevron-left" style="font-size:24px"></i></span> </a> <a |
||||
|
class="carousel-control-next" href="#demo1" data-slide="next" |
||||
|
style="right:-25px;width: 35px;color: #000;"> |
||||
|
<span class="carousel-control-next-icon"><i class="fa fa-chevron-right" |
||||
|
style="font-size:24px"></i></span> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- END OF SUGGESTED PRODUCTS --> |
||||
|
|
||||
|
<!-- OUR SERVICES --> |
||||
|
<section class="container" style="margin-top: 6rem !important;"> |
||||
|
<div class="row"> |
||||
|
<div class="col-lg-12 d-flex flex-column justify-content-center align-items-center"> |
||||
|
<h2 style="color: #212529 !important;">Our Services</h2> |
||||
|
<hr |
||||
|
style="border: 3px solid #AC1015 !important; background-color: #AC1015 !important; width: 80px !important; margin-bottom: 2rem !important;" /> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
||||
|
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
||||
|
style="background-color: #1dd1a1 !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
||||
|
<img src="assets/icons/cogs.png" class="img-responsive" height="48px" width="48px"> |
||||
|
</div> |
||||
|
<h6 class="text-center" |
||||
|
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">Odoo |
||||
|
Customization</h6> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
||||
|
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
||||
|
style="background-color: #ff6b6b !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
||||
|
<img src="assets/icons/wrench.png" class="img-responsive" height="48px" width="48px"> |
||||
|
</div> |
||||
|
<h6 class="text-center" |
||||
|
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">Odoo |
||||
|
Implementation</h6> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
||||
|
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
||||
|
style="background-color: #6462CD !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
||||
|
<img src="assets/icons/lifebuoy.png" class="img-responsive" height="48px" width="48px"> |
||||
|
</div> |
||||
|
<h6 class="text-center" |
||||
|
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">Odoo |
||||
|
Support</h6> |
||||
|
</div> |
||||
|
|
||||
|
|
||||
|
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
||||
|
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
||||
|
style="background-color: #ffa801 !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
||||
|
<img src="assets/icons/user.png" class="img-responsive" height="48px" width="48px"> |
||||
|
</div> |
||||
|
<h6 class="text-center" |
||||
|
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">Hire |
||||
|
Odoo |
||||
|
Developer</h6> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
||||
|
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
||||
|
style="background-color: #54a0ff !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
||||
|
<img src="assets/icons/puzzle.png" class="img-responsive" height="48px" width="48px"> |
||||
|
</div> |
||||
|
<h6 class="text-center" |
||||
|
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">Odoo |
||||
|
Integration</h6> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
||||
|
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
||||
|
style="background-color: #6d7680 !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
||||
|
<img src="assets/icons/update.png" class="img-responsive" height="48px" width="48px"> |
||||
|
</div> |
||||
|
<h6 class="text-center" |
||||
|
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">Odoo |
||||
|
Migration</h6> |
||||
|
</div> |
||||
|
|
||||
|
|
||||
|
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
||||
|
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
||||
|
style="background-color: #786fa6 !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
||||
|
<img src="assets/icons/consultation.png" class="img-responsive" height="48px" width="48px"> |
||||
|
</div> |
||||
|
<h6 class="text-center" |
||||
|
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">Odoo |
||||
|
Consultancy</h6> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
||||
|
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
||||
|
style="background-color: #f8a5c2 !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
||||
|
<img src="assets/icons/training.png" class="img-responsive" height="48px" width="48px"> |
||||
|
</div> |
||||
|
<h6 class="text-center" |
||||
|
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">Odoo |
||||
|
Implementation</h6> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4"> |
||||
|
<div class="d-flex justify-content-center align-items-center mx-3 my-3" |
||||
|
style="background-color: #e6be26 !important; border-radius: 15px !important; height: 80px; width: 80px;"> |
||||
|
<img src="assets/icons/license.png" class="img-responsive" height="48px" width="48px"> |
||||
|
</div> |
||||
|
<h6 class="text-center" |
||||
|
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">Odoo |
||||
|
Licensing Consultancy</h6> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
<!-- END OF END OF OUR SERVICES --> |
||||
|
|
||||
|
<!-- OUR INDUSTRIES --> |
||||
|
<section class="container" style="margin-top: 6rem !important;"> |
||||
|
<div class="row"> |
||||
|
<div class="col-lg-12 d-flex flex-column justify-content-center align-items-center"> |
||||
|
<h2 style="color: #212529 !important;">Our Industries</h2> |
||||
|
<hr |
||||
|
style="border: 3px solid #AC1015 !important; background-color: #AC1015 !important; width: 80px !important; margin-bottom: 2rem !important;" /> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-3"> |
||||
|
<div class="my-4 d-flex flex-column justify-content-center" |
||||
|
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;"> |
||||
|
<img src="./assets/icons/trading-black.png" class="img-responsive mb-3" height="48px" |
||||
|
width="48px"> |
||||
|
<h5 |
||||
|
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;"> |
||||
|
Trading |
||||
|
</h5> |
||||
|
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;"> |
||||
|
Easily procure |
||||
|
and |
||||
|
sell your products</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-3"> |
||||
|
<div class="my-4 d-flex flex-column justify-content-center" |
||||
|
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;"> |
||||
|
<img src="./assets/icons/pos-black.png" class="img-responsive mb-3" height="48px" width="48px"> |
||||
|
<h5 |
||||
|
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;"> |
||||
|
POS |
||||
|
</h5> |
||||
|
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;"> |
||||
|
Easy |
||||
|
configuration |
||||
|
and convivial experience</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-3"> |
||||
|
<div class="my-4 d-flex flex-column justify-content-center" |
||||
|
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;"> |
||||
|
<img src="./assets/icons/education-black.png" class="img-responsive mb-3" height="48px" |
||||
|
width="48px"> |
||||
|
<h5 |
||||
|
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;"> |
||||
|
Education |
||||
|
</h5> |
||||
|
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;"> |
||||
|
A platform for |
||||
|
educational management</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-3"> |
||||
|
<div class="my-4 d-flex flex-column justify-content-center" |
||||
|
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;"> |
||||
|
<img src="./assets/icons/manufacturing-black.png" class="img-responsive mb-3" height="48px" |
||||
|
width="48px"> |
||||
|
<h5 |
||||
|
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;"> |
||||
|
Manufacturing |
||||
|
</h5> |
||||
|
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;"> |
||||
|
Plan, track and |
||||
|
schedule your operations</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-3"> |
||||
|
<div class="my-4 d-flex flex-column justify-content-center" |
||||
|
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;"> |
||||
|
<img src="./assets/icons/ecom-black.png" class="img-responsive mb-3" height="48px" width="48px"> |
||||
|
<h5 |
||||
|
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;"> |
||||
|
E-commerce & Website |
||||
|
</h5> |
||||
|
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;"> |
||||
|
Mobile |
||||
|
friendly, |
||||
|
awe-inspiring product pages</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-3"> |
||||
|
<div class="my-4 d-flex flex-column justify-content-center" |
||||
|
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;"> |
||||
|
<img src="./assets/icons/service-black.png" class="img-responsive mb-3" height="48px" |
||||
|
width="48px"> |
||||
|
<h5 |
||||
|
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;"> |
||||
|
Service Management |
||||
|
</h5> |
||||
|
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;"> |
||||
|
Keep track of |
||||
|
services and invoice</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-3"> |
||||
|
<div class="my-4 d-flex flex-column justify-content-center" |
||||
|
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;"> |
||||
|
<img src="./assets/icons/restaurant-black.png" class="img-responsive mb-3" height="48px" |
||||
|
width="48px"> |
||||
|
<h5 |
||||
|
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;"> |
||||
|
Restaurant |
||||
|
</h5> |
||||
|
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;"> |
||||
|
Run your bar or |
||||
|
restaurant methodically</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="col-lg-3"> |
||||
|
<div class="my-4 d-flex flex-column justify-content-center" |
||||
|
style="background-color: #f6f8f9 !important; border-radius: 10px; padding: 2rem !important; height: 250px !important;"> |
||||
|
<img src="./assets/icons/hotel-black.png" class="img-responsive mb-3" height="48px" |
||||
|
width="48px"> |
||||
|
<h5 |
||||
|
style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;"> |
||||
|
Hotel Management |
||||
|
</h5> |
||||
|
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;"> |
||||
|
An |
||||
|
all-inclusive |
||||
|
hotel management application</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
</section> |
||||
|
|
||||
|
<!-- END OF END OF OUR INDUSTRIES --> |
||||
|
|
||||
|
<!-- FOOTER --> |
||||
|
<!-- Footer Section --> |
||||
|
<section class="container" style="margin: 5rem auto 2rem;"> |
||||
|
<div class="row" style="max-width:1540px;"> |
||||
|
<div class="col-lg-12 d-flex flex-column justify-content-center align-items-center"> |
||||
|
<h2 style="color: #212529 !important;">Need Help?</h2> |
||||
|
<hr |
||||
|
style="border: 3px solid #AC1015 !important; background-color: #AC1015 !important; width: 80px !important; margin-bottom: 2rem !important;" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<!-- Contact Cards --> |
||||
|
<div class="row d-flex justify-content-center align-items-center" |
||||
|
style="max-width:1540px; margin: 0 auto 2rem auto;"> |
||||
|
|
||||
|
<div class="col-lg-12" style="padding: 0rem 3rem 2rem; border-radius: 10px; margin-right: 3rem; "> |
||||
|
|
||||
|
<div class="row mt-4"> |
||||
|
<div class="col-lg-6"> |
||||
|
<a href="mailto:odoo@cybrosys.com" target="_blank" class="btn btn-block mb-2 deep_hover" |
||||
|
style="text-decoration: none; background-color: #4d4d4d; color: #FFF; border-radius: 4px;"><i |
||||
|
class="fa fa-envelope mr-2"></i>odoo@cybrosys.com</a> |
||||
|
</div> |
||||
|
<div class="col-lg-6"> |
||||
|
<a href="https://api.whatsapp.com/send?phone=918606827707" target="_blank" |
||||
|
class="btn btn-block mb-2 deep_hover" |
||||
|
style="text-decoration: none; background-color: #25D366; color: #FFF; border-radius: 4px;"><i |
||||
|
class="fa fa-whatsapp mr-2"></i>WhatsApp</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
<!-- End of Contact Cards --> |
||||
|
</section> |
||||
|
<!-- Footer --> |
||||
|
<section class="oe_container" style="padding: 2rem 3rem 1rem;"> |
||||
|
<div class="row" style="max-width:1540px; margin: 0 auto; margin-right: 3rem; "> |
||||
|
<!-- Logo --> |
||||
|
<div class="col-lg-12 d-flex justify-content-center align-items-center" style="margin-top: 3rem;"> |
||||
|
<img src="https://www.cybrosys.com/images/logo.png" width="200px" height="auto" /> |
||||
|
</div> |
||||
|
<!-- End of Logo --> |
||||
|
<div class="col-lg-12"> |
||||
|
<hr |
||||
|
style="margin-top: 3rem;background: linear-gradient(90deg, rgba(2,0,36,0) 0%, rgba(229,229,229,1) 33%, rgba(229,229,229,1) 58%, rgba(0,212,255,0) 100%); height: 2px; border-style: none;"> |
||||
|
<!-- End of Footer Section --> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
<!-- END OF FOOTER --> |
||||
|
|
||||
|
|
||||
|
</div> |
||||
|
</div> |
@ -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; |
||||
|
} |
@ -0,0 +1,138 @@ |
|||||
|
odoo.define('product_multi_uom_pos.models',function(require) { |
||||
|
"use strict"; |
||||
|
|
||||
|
var core = require('web.core'); |
||||
|
var models = require('point_of_sale.models'); |
||||
|
var OrderlineSuper = models.Orderline; |
||||
|
var field_utils = require('web.field_utils'); |
||||
|
var QWeb = core.qweb; |
||||
|
var _t = core._t; |
||||
|
var utils = require('web.utils'); |
||||
|
var round_pr = utils.round_precision; |
||||
|
var _super_orderline = models.Orderline.prototype; |
||||
|
|
||||
|
|
||||
|
|
||||
|
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); |
||||
|
console.log("result",result); |
||||
|
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]; |
||||
|
}, |
||||
|
|
||||
|
set_quantity: function(quantity, keep_price) { |
||||
|
OrderlineSuper.prototype.set_quantity.call(this, quantity, keep_price); |
||||
|
this.order.assert_editable(); |
||||
|
if(quantity === 'remove'){ |
||||
|
this.order.remove_orderline(this); |
||||
|
return; |
||||
|
}else{ |
||||
|
var quant = parseFloat(quantity) || 0; |
||||
|
var unit = this.get_unit(); |
||||
|
if(unit){ |
||||
|
if (unit.rounding) { |
||||
|
var decimals = this.pos.dp['Product Unit of Measure']; |
||||
|
var rounding = Math.max(unit.rounding, Math.pow(10, -decimals)); |
||||
|
this.quantity = round_pr(quant, rounding); |
||||
|
this.quantityStr = field_utils.format.float(this.quantity, {digits: [69, decimals]}); |
||||
|
} else { |
||||
|
this.quantity = round_pr(quant, 1); |
||||
|
this.quantityStr = this.quantity.toFixed(0); |
||||
|
} |
||||
|
}else{ |
||||
|
this.quantity = quant; |
||||
|
this.quantityStr = '' + this.quantity; |
||||
|
} |
||||
|
} |
||||
|
// just like in sale.order changing the quantity will recompute the unit price
|
||||
|
if(! keep_price && ! this.price_manually_set){ |
||||
|
var self = this; |
||||
|
var order = self.pos.get_order(); |
||||
|
var orderline = order.get_selected_orderline(); |
||||
|
if (orderline){ |
||||
|
var uom = orderline.uom_id[0]; |
||||
|
var lst_uom = this.pos.units_by_id[uom]; |
||||
|
var ref_qty = orderline.quantity; |
||||
|
var ref_price = orderline.product.lst_price; |
||||
|
if (lst_uom.uom_type == 'bigger') { |
||||
|
this.set_unit_price(ref_price * lst_uom.factor_inv); |
||||
|
this.order.fix_tax_included_price(this); |
||||
|
} |
||||
|
else if (lst_uom.uom_type == 'smaller') { |
||||
|
this.set_unit_price(ref_price / lst_uom.factor); |
||||
|
this.order.fix_tax_included_price(this); |
||||
|
} |
||||
|
else { |
||||
|
this.set_unit_price(ref_price); |
||||
|
this.order.fix_tax_included_price(this); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
else{ |
||||
|
this.set_unit_price(this.product.get_price(this.order.pricelist, this.get_quantity())); |
||||
|
this.order.fix_tax_included_price(this); |
||||
|
} |
||||
|
} |
||||
|
this.trigger('change', this); |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
|
||||
|
|
||||
|
models.Order = models.Order.extend({ |
||||
|
|
||||
|
updatePricelist: function(newClient) { |
||||
|
let newClientPricelist, newClientFiscalPosition; |
||||
|
const defaultFiscalPosition = this.pos.fiscal_positions.find( |
||||
|
(position) => position.id === this.pos.config.default_fiscal_position_id[0] |
||||
|
); |
||||
|
if (newClient) { |
||||
|
newClientFiscalPosition = newClient.property_account_position_id |
||||
|
? this.pos.fiscal_positions.find( |
||||
|
(position) => position.id === newClient.property_account_position_id[0] |
||||
|
) |
||||
|
: defaultFiscalPosition; |
||||
|
newClientPricelist = |
||||
|
this.pos.pricelists.find( |
||||
|
(pricelist) => pricelist.id === newClient.property_product_pricelist[0] |
||||
|
) || this.pos.default_pricelist; |
||||
|
} else { |
||||
|
newClientFiscalPosition = defaultFiscalPosition; |
||||
|
newClientPricelist = this.pos.default_pricelist; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
if (this.selected_orderline.uom_id != this.selected_orderline.product.uom_id){ |
||||
|
this.fiscal_position = newClientFiscalPosition; |
||||
|
|
||||
|
}else{ |
||||
|
this.fiscal_position = newClientFiscalPosition; |
||||
|
this.set_pricelist(newClientPricelist); |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}); |
@ -0,0 +1,16 @@ |
|||||
|
odoo.define('product_multi_uom_pos.multi_uom',function(require) { |
||||
|
"use strict"; |
||||
|
|
||||
|
console.log("multi_uom_main") |
||||
|
|
||||
|
var gui = require('point_of_sale.gui'); |
||||
|
var core = require('web.core'); |
||||
|
var models = require('point_of_sale.models'); |
||||
|
var pos_screens = require('point_of_sale.screens'); |
||||
|
var field_utils = require('web.field_utils'); |
||||
|
var rpc = require('web.rpc'); |
||||
|
var QWeb = core.qweb; |
||||
|
var _t = core._t; |
||||
|
var utils = require('web.utils'); |
||||
|
var round_pr = utils.round_precision; |
||||
|
|
@ -0,0 +1,136 @@ |
|||||
|
odoo.define('product_multi_uom_pos.multi_uom_widget',function(require) { |
||||
|
"use strict"; |
||||
|
|
||||
|
var gui = require('point_of_sale.Gui'); |
||||
|
var core = require('web.core'); |
||||
|
var QWeb = core.qweb; |
||||
|
|
||||
|
const NumberBuffer = require('point_of_sale.NumberBuffer'); |
||||
|
const { onChangeOrder, useBarcodeReader } = require('point_of_sale.custom_hooks'); |
||||
|
const PosComponent = require('point_of_sale.PosComponent'); |
||||
|
const Registries = require('point_of_sale.Registries'); |
||||
|
const ProductScreen = require('point_of_sale.ProductScreen'); |
||||
|
const { useListener } = require('web.custom_hooks'); |
||||
|
const { useState, useRef } = owl.hooks; |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
class MultiUomWidget extends PosComponent { |
||||
|
|
||||
|
|
||||
|
constructor() { |
||||
|
super(...arguments); |
||||
|
|
||||
|
this.options = {}; |
||||
|
this.uom_list = []; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
mounted(options){ |
||||
|
|
||||
|
var current_uom = this.env.pos.units_by_id[this.props.options.uom_list[0]]; |
||||
|
var uom_list = this.env.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 = this.props.options.uom_list[0]; |
||||
|
this.render(); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
get_units_by_category(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(product, product_uom){ |
||||
|
if(product_uom.uom_type == 'reference'){ |
||||
|
return product.lst_price; |
||||
|
} |
||||
|
else if(product_uom.uom_type == 'smaller'){ |
||||
|
return (product.lst_price * product_uom.factor); |
||||
|
} |
||||
|
else if(product_uom.uom_type == 'bigger'){ |
||||
|
return (product.lst_price / product_uom.factor_inv); |
||||
|
} |
||||
|
} |
||||
|
/*finds the latest price for the product based on the new uom selected*/ |
||||
|
get_latest_price(uom, product){ |
||||
|
var uom_by_category = this.get_units_by_category(this.env.pos.units_by_id, uom.category_id); |
||||
|
var product_uom = this.env.pos.units_by_id[product.uom_id[0]]; |
||||
|
var ref_price = this.find_reference_unit_price(product, product_uom); |
||||
|
var ref_price = product.lst_price; |
||||
|
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'){ |
||||
|
console.log("bigggg"); |
||||
|
console.log("ref_price * uom.factor_inv",ref_price * uom.factor_inv); |
||||
|
|
||||
|
return (ref_price * uom.factor_inv); |
||||
|
} |
||||
|
else if(uom.uom_type == 'smaller'){ |
||||
|
console.log("smalll"); |
||||
|
console.log("small",(ref_price / uom.factor_inv)); |
||||
|
|
||||
|
return (ref_price / uom.factor); |
||||
|
} |
||||
|
else if(uom.uom_type == 'reference'){ |
||||
|
console.log("refernce"); |
||||
|
console.log("ref_price",ref_price); |
||||
|
return ref_price; |
||||
|
} |
||||
|
} |
||||
|
return product.lst_price; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
click_confirm(){ |
||||
|
var self = this; |
||||
|
var uom = parseInt($('.uom').val()); |
||||
|
var order = this.env.pos.get_order(); |
||||
|
var orderline = order.get_selected_orderline(); |
||||
|
var selected_uom = this.env.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); |
||||
|
orderline.lst_price = latest_price; |
||||
|
|
||||
|
this.trigger('close-popup'); |
||||
|
return; |
||||
|
|
||||
|
} |
||||
|
click_cancel(){ |
||||
|
this.trigger('close-popup'); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
MultiUomWidget.template = 'MultiUomWidget'; |
||||
|
MultiUomWidget.defaultProps = { |
||||
|
confirmText: 'Return', |
||||
|
cancelText: 'Cancel', |
||||
|
title: 'Confirm ?', |
||||
|
body: '', |
||||
|
}; |
||||
|
Registries.Component.add(MultiUomWidget); |
||||
|
return MultiUomWidget; |
||||
|
}); |
||||
|
|
@ -0,0 +1,52 @@ |
|||||
|
odoo.define('product_multi_uom_pos.uom_button',function(require) { |
||||
|
"use strict"; |
||||
|
|
||||
|
var core = require('web.core'); |
||||
|
var QWeb = core.qweb; |
||||
|
|
||||
|
const { onChangeOrder, useBarcodeReader } = require('point_of_sale.custom_hooks'); |
||||
|
const PosComponent = require('point_of_sale.PosComponent'); |
||||
|
const Registries = require('point_of_sale.Registries'); |
||||
|
const ProductScreen = require('point_of_sale.ProductScreen'); |
||||
|
const { useListener } = require('web.custom_hooks'); |
||||
|
const { useState, useRef } = owl.hooks; |
||||
|
const { Gui } = require('point_of_sale.Gui'); |
||||
|
|
||||
|
|
||||
|
|
||||
|
class UOMButton extends PosComponent { |
||||
|
|
||||
|
constructor() { |
||||
|
super(...arguments); |
||||
|
useListener('click', this.button_click); |
||||
|
} |
||||
|
|
||||
|
button_click() { |
||||
|
var orderline = this.env.pos.get_order().get_selected_orderline(); |
||||
|
var options = { |
||||
|
'uom_list': orderline.product.uom_id |
||||
|
}; |
||||
|
|
||||
|
Gui.showPopup('MultiUomWidget',{options:options}); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
UOMButton.template = 'UOMButton'; |
||||
|
ProductScreen.addControlButton({ |
||||
|
|
||||
|
component: UOMButton, |
||||
|
condition: function () { |
||||
|
return true; |
||||
|
}, |
||||
|
position: ['before', 'SetFiscalPositionButton'], |
||||
|
|
||||
|
}); |
||||
|
|
||||
|
Registries.Component.add(UOMButton); |
||||
|
return UOMButton; |
||||
|
|
||||
|
|
||||
|
|
||||
|
}); |
@ -0,0 +1,39 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<templates id="template" xml:space="preserve"> |
||||
|
|
||||
|
|
||||
|
<t t-name="UOMButton" owl="1"> |
||||
|
<div class="control-button"> |
||||
|
<span class="multi-uom-span" aria-label="Info" title="Info"> |
||||
|
Modify Unit of Measure |
||||
|
</span> |
||||
|
</div> |
||||
|
</t> |
||||
|
|
||||
|
<t t-name="MultiUomWidget" owl="1"> |
||||
|
<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='uom_list || []' t-as='uom' t-key="uom.id"> |
||||
|
<option t-att-value='uom.id' |
||||
|
t-att-selected="((uom.id == current_uom) ? true:undefined)" > |
||||
|
<t t-esc='uom.display_name'/> |
||||
|
</option> |
||||
|
</t> |
||||
|
</select> |
||||
|
</div> |
||||
|
<div class="footer"> |
||||
|
<div class="button confirm" t-on-click="click_confirm"> |
||||
|
Ok |
||||
|
</div> |
||||
|
<div class="button cancel" t-on-click="click_cancel"> |
||||
|
Cancel |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</t> |
||||
|
|
||||
|
</templates> |
@ -0,0 +1,16 @@ |
|||||
|
<?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/models.js"></script> |
||||
|
<script type="text/javascript" src="/product_multi_uom_pos/static/src/js/multi_uom_widget.js"></script> |
||||
|
<script type="text/javascript" src="/product_multi_uom_pos/static/src/js/uom_button.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> |