@ -0,0 +1,49 @@ |
|||||
|
.. image:: https://img.shields.io/badge/license-AGPL--3-blue.svg |
||||
|
:target: https://www.gnu.org/licenses/agpl-3.0-standalone.html |
||||
|
:alt: License: AGPL-3 |
||||
|
|
||||
|
Service Charges POS |
||||
|
======================= |
||||
|
This module allows you to set service charges for an order by globally and session wise. |
||||
|
|
||||
|
Configuration |
||||
|
============= |
||||
|
- www.odoo.com/documentation/18.0/setup/install.html |
||||
|
- Install our custom addon |
||||
|
|
||||
|
Company |
||||
|
------- |
||||
|
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__ |
||||
|
|
||||
|
License |
||||
|
------- |
||||
|
General Public License, Version 3 (AGPL v3). |
||||
|
(https://www.gnu.org/licenses/agpl-3.0-standalone.html) |
||||
|
|
||||
|
Credits |
||||
|
------- |
||||
|
Developers: (V18) Nivedhya T |
||||
|
|
||||
|
Contact: odoo@cybrosys.com |
||||
|
|
||||
|
Contacts |
||||
|
-------- |
||||
|
* Mail Contact : odoo@cybrosys.com |
||||
|
* Website : https://cybrosys.com |
||||
|
|
||||
|
Bug Tracker |
||||
|
----------- |
||||
|
Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. |
||||
|
|
||||
|
Maintainer |
||||
|
========== |
||||
|
This module is maintained by Cybrosys Technologies. |
||||
|
|
||||
|
For support and more information, please visit https://www.cybrosys.com |
||||
|
|
||||
|
.. image:: https://cybrosys.com/images/logo.png |
||||
|
:target: https://www.cybrosys.com" |
||||
|
|
||||
|
Further information |
||||
|
=================== |
||||
|
HTML Description: `<static/description/index.html>`__ |
@ -0,0 +1,22 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
################################################################################ |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). |
||||
|
# Author: Cybrosys Techno Solutions(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 . import models |
@ -0,0 +1,49 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
################################################################################ |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). |
||||
|
# Author: Cybrosys Techno Solutions(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/>. |
||||
|
# |
||||
|
################################################################################ |
||||
|
{ |
||||
|
'name': 'Service Charges POS', |
||||
|
'version': '18.0.1.0.0', |
||||
|
'category': 'Point Of Sale', |
||||
|
'summary': 'Allows you to set service charges.', |
||||
|
'description': 'Allows you to set service charges for an order by globally' |
||||
|
' and session wise.', |
||||
|
'author': 'Cybrosys Techno Solutions', |
||||
|
'company': 'Cybrosys Techno Solutions', |
||||
|
'maintainer': 'Cybrosys Techno Solutions', |
||||
|
'website': 'https://www.cybrosys.com', |
||||
|
'depends': ['point_of_sale'], |
||||
|
'data': [ |
||||
|
'views/res_config_settings_views.xml', |
||||
|
'views/pos_config_views.xml', |
||||
|
], |
||||
|
'assets': { |
||||
|
'point_of_sale._assets_pos': [ |
||||
|
'service_charges_pos/static/src/js/service_charge_button.js', |
||||
|
'service_charges_pos/static/src/xml/service_charge_button.xml', |
||||
|
], |
||||
|
}, |
||||
|
'images': ['static/description/banner.jpg'], |
||||
|
'license': 'AGPL-3', |
||||
|
'installable': True, |
||||
|
'auto_install': False, |
||||
|
'application': False, |
||||
|
} |
@ -0,0 +1,6 @@ |
|||||
|
## Module <service_charges_pos> |
||||
|
#### 17.07.2025 |
||||
|
#### Version 18.0.1.0.0 |
||||
|
#### FIX |
||||
|
#### ADD |
||||
|
- Initial commit for Service Charges POS |
@ -0,0 +1,24 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
################################################################################ |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). |
||||
|
# Author: Cybrosys Techno Solutions(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 . import pos_config |
||||
|
from . import pos_session |
||||
|
from . import res_config_settings |
@ -0,0 +1,94 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
################################################################################ |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). |
||||
|
# Author: Cybrosys Techno Solutions(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 api, fields, models, _ |
||||
|
from odoo.exceptions import UserError |
||||
|
from odoo.osv.expression import OR |
||||
|
|
||||
|
|
||||
|
class PosConfig(models.Model): |
||||
|
""" |
||||
|
To inherit model pos.config |
||||
|
""" |
||||
|
_inherit = 'pos.config' |
||||
|
|
||||
|
is_service_charges = fields.Boolean("Service Charges", help="Enable Service Charges") |
||||
|
visibility_type = fields.Selection([ |
||||
|
('global', 'Global'), |
||||
|
('session', 'Session')], |
||||
|
string='Visibility', default='global', |
||||
|
help="Can choose visibility of service charges.") |
||||
|
service_charge = fields.Float(string='Service Charge', |
||||
|
help="Charge need to apply", |
||||
|
default=10.0) |
||||
|
service_product_id = fields.Many2one('product.product', |
||||
|
string='Service Product', |
||||
|
domain="[('sale_ok', '=', True)]", |
||||
|
help="Service Product") |
||||
|
service_charge_type = fields.Selection([ |
||||
|
('amount', 'Amount'), |
||||
|
('percentage', 'Percentage')], |
||||
|
string='Type', default='amount', |
||||
|
help="Can choose charge percentage or amount") |
||||
|
|
||||
|
@api.model |
||||
|
def _default_service_charge_on_module_install(self): |
||||
|
""" |
||||
|
Set default service product on module installation""" |
||||
|
configs = self.env['pos.config'].search([]) |
||||
|
open_configs = ( |
||||
|
self.env['pos.session'] |
||||
|
.search(['|', ('state', '!=', 'closed'), ('rescue', '=', True)]) |
||||
|
.mapped('config_id') |
||||
|
) |
||||
|
# Do not modify configs where an opened session exists. |
||||
|
product = self.env.ref("point_of_sale.product_product_consumable", |
||||
|
raise_if_not_found=False) |
||||
|
for conf in (configs - open_configs): |
||||
|
conf.service_product_id = product if ( |
||||
|
conf.is_service_charges |
||||
|
) and product and ( |
||||
|
not product.company_id or product.company_id == conf.company_id |
||||
|
) else False |
||||
|
|
||||
|
def open_ui(self): |
||||
|
""" |
||||
|
Overridden to check if service product is set when service charge is enabled""" |
||||
|
for config in self: |
||||
|
if not self.current_session_id and ( |
||||
|
config.is_service_charges |
||||
|
) and not config.service_product_id: |
||||
|
raise UserError(_( |
||||
|
'A discount product is needed to use the Service Charge ' |
||||
|
'feature. Go to Point of Sale > Configuration > Settings ' |
||||
|
'to set it.')) |
||||
|
return super().open_ui() |
||||
|
|
||||
|
def _get_special_products(self): |
||||
|
""" Overridden to add service product to the list of special products""" |
||||
|
res = super()._get_special_products() |
||||
|
return res | self.env['pos.config'].search( |
||||
|
[]).mapped('service_product_id') |
||||
|
|
||||
|
def _get_available_product_domain(self): |
||||
|
""" Overridden to include service product in the available products""" |
||||
|
domain = super()._get_available_product_domain() |
||||
|
return OR([domain, [('id', '=', self.service_product_id.id)]]) |
@ -0,0 +1,44 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
################################################################################ |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). |
||||
|
# Author: Cybrosys Techno Solutions(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 models |
||||
|
|
||||
|
|
||||
|
class PosSession(models.Model): |
||||
|
''' Inherit pos.session to add service product to the product list''' |
||||
|
_inherit = 'pos.session' |
||||
|
|
||||
|
def _get_pos_ui_product_product(self, params): |
||||
|
"""Add service product to the product list if service charges is""" |
||||
|
result = super()._get_pos_ui_product_product(params) |
||||
|
service_product_id = self.config_id.service_product_id.id |
||||
|
product_ids_set = {product['id'] for product in result} |
||||
|
|
||||
|
if self.config_id.is_service_charges and ( |
||||
|
service_product_id) not in product_ids_set: |
||||
|
product_model = self.env['product.product'].with_context( |
||||
|
**params['context']) |
||||
|
product = product_model.search_read([( |
||||
|
'id', '=', service_product_id |
||||
|
)], fields=params['search_params']['fields']) |
||||
|
self._process_pos_ui_product_product(product) |
||||
|
result.extend(product) |
||||
|
return result |
@ -0,0 +1,64 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
################################################################################ |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). |
||||
|
# Author: Cybrosys Techno Solutions(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 api, fields, models |
||||
|
|
||||
|
|
||||
|
class ResConfigSettings(models.TransientModel): |
||||
|
''' Inherit res.config.settings to add service charges fields ''' |
||||
|
_inherit = 'res.config.settings' |
||||
|
|
||||
|
# pos.config fields |
||||
|
pos_is_service_charges = fields.Boolean( |
||||
|
related='pos_config_id.is_service_charges', readonly=False, |
||||
|
string="Service Charges", help="Enable Service Charges") |
||||
|
pos_visibility_type = fields.Selection([ |
||||
|
('global', 'Global'), |
||||
|
('session', 'Session')], |
||||
|
related='pos_config_id.visibility_type', |
||||
|
readonly=False, help="Can choose visibility of service charges.") |
||||
|
pos_service_charge = fields.Float(related='pos_config_id.service_charge', |
||||
|
readonly=False, help="Charge need to apply") |
||||
|
pos_service_product_id = fields.Many2one( |
||||
|
'product.product', |
||||
|
compute='_compute_pos_service_product_id', store=True, readonly=False, |
||||
|
domain="[('type', '=', 'service')]") |
||||
|
pos_service_charge_type = fields.Selection([ |
||||
|
('amount', 'Amount'), |
||||
|
('percentage', 'Percentage')], |
||||
|
related='pos_config_id.service_charge_type', |
||||
|
readonly=False) |
||||
|
|
||||
|
@api.depends('company_id', 'pos_is_service_charges', 'pos_config_id') |
||||
|
def _compute_pos_service_product_id(self): |
||||
|
"""Compute service product based on the company and other fields""" |
||||
|
default_product = self.env.ref( |
||||
|
"point_of_sale.product_product_consumable", |
||||
|
raise_if_not_found=False) or self.env['product.product'] |
||||
|
for res_config in self: |
||||
|
service_product = res_config.pos_config_id.service_product_id or ( |
||||
|
default_product) |
||||
|
if (res_config.pos_is_service_charges) and ( |
||||
|
not service_product.company_id or ( |
||||
|
service_product.company_id) == res_config.company_id): |
||||
|
res_config.pos_service_product_id = service_product |
||||
|
else: |
||||
|
res_config.pos_service_product_id = False |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 210 KiB |
After Width: | Height: | Size: 209 KiB |
After Width: | Height: | Size: 109 KiB |
After Width: | Height: | Size: 495 B |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 624 B |
After Width: | Height: | Size: 136 KiB |
After Width: | Height: | Size: 214 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 310 B |
After Width: | Height: | Size: 929 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 542 B |
After Width: | Height: | Size: 576 B |
After Width: | Height: | Size: 733 B |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 699 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 911 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 600 B |
After Width: | Height: | Size: 673 B |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 462 B |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 926 B |
After Width: | Height: | Size: 9.0 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 7.0 KiB |
After Width: | Height: | Size: 878 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 653 B |
After Width: | Height: | Size: 800 B |
After Width: | Height: | Size: 905 B |
After Width: | Height: | Size: 189 KiB |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 839 B |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 5.9 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 427 B |
After Width: | Height: | Size: 627 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 988 B |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 875 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 540 KiB |
After Width: | Height: | Size: 90 KiB |
After Width: | Height: | Size: 86 KiB |
After Width: | Height: | Size: 86 KiB |
After Width: | Height: | Size: 1.0 MiB |
After Width: | Height: | Size: 196 KiB |
After Width: | Height: | Size: 147 KiB |
After Width: | Height: | Size: 100 KiB |
After Width: | Height: | Size: 369 KiB |
After Width: | Height: | Size: 463 KiB |
After Width: | Height: | Size: 364 KiB |
After Width: | Height: | Size: 455 KiB |
After Width: | Height: | Size: 142 KiB |
After Width: | Height: | Size: 364 KiB |
After Width: | Height: | Size: 457 KiB |
After Width: | Height: | Size: 144 KiB |
After Width: | Height: | Size: 762 KiB |
After Width: | Height: | Size: 43 KiB |
After Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 50 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 2.4 KiB |