Browse Source

Dec 26: [ADD] Initial Commit 'advanced_loyalty_management'

pull/254/merge
Cybrosys Technologies 4 months ago
parent
commit
0ea076bfe0
  1. 50
      advanced_loyalty_management/README.rst
  2. 22
      advanced_loyalty_management/__init__.py
  3. 64
      advanced_loyalty_management/__manifest__.py
  4. 6
      advanced_loyalty_management/doc/RELEASE_NOTES.md
  5. 25
      advanced_loyalty_management/models/__init__.py
  6. 37
      advanced_loyalty_management/models/loyalty_program.py
  7. 77
      advanced_loyalty_management/models/loyalty_reward.py
  8. 30
      advanced_loyalty_management/models/pos_order_line.py
  9. 54
      advanced_loyalty_management/models/res_partner.py
  10. BIN
      advanced_loyalty_management/static/description/assets/icons/check.png
  11. BIN
      advanced_loyalty_management/static/description/assets/icons/chevron.png
  12. BIN
      advanced_loyalty_management/static/description/assets/icons/cogs.png
  13. BIN
      advanced_loyalty_management/static/description/assets/icons/consultation.png
  14. BIN
      advanced_loyalty_management/static/description/assets/icons/ecom-black.png
  15. BIN
      advanced_loyalty_management/static/description/assets/icons/education-black.png
  16. BIN
      advanced_loyalty_management/static/description/assets/icons/hotel-black.png
  17. BIN
      advanced_loyalty_management/static/description/assets/icons/license.png
  18. BIN
      advanced_loyalty_management/static/description/assets/icons/lifebuoy.png
  19. BIN
      advanced_loyalty_management/static/description/assets/icons/manufacturing-black.png
  20. BIN
      advanced_loyalty_management/static/description/assets/icons/pos-black.png
  21. BIN
      advanced_loyalty_management/static/description/assets/icons/puzzle.png
  22. BIN
      advanced_loyalty_management/static/description/assets/icons/restaurant-black.png
  23. BIN
      advanced_loyalty_management/static/description/assets/icons/service-black.png
  24. BIN
      advanced_loyalty_management/static/description/assets/icons/trading-black.png
  25. BIN
      advanced_loyalty_management/static/description/assets/icons/training.png
  26. BIN
      advanced_loyalty_management/static/description/assets/icons/update.png
  27. BIN
      advanced_loyalty_management/static/description/assets/icons/user.png
  28. BIN
      advanced_loyalty_management/static/description/assets/icons/wrench.png
  29. BIN
      advanced_loyalty_management/static/description/assets/misc/categories.png
  30. BIN
      advanced_loyalty_management/static/description/assets/misc/check-box.png
  31. BIN
      advanced_loyalty_management/static/description/assets/misc/compass.png
  32. BIN
      advanced_loyalty_management/static/description/assets/misc/corporate.png
  33. BIN
      advanced_loyalty_management/static/description/assets/misc/customer-support.png
  34. BIN
      advanced_loyalty_management/static/description/assets/misc/cybrosys-logo.png
  35. BIN
      advanced_loyalty_management/static/description/assets/misc/features.png
  36. BIN
      advanced_loyalty_management/static/description/assets/misc/logo.png
  37. BIN
      advanced_loyalty_management/static/description/assets/misc/pictures.png
  38. BIN
      advanced_loyalty_management/static/description/assets/misc/pie-chart.png
  39. BIN
      advanced_loyalty_management/static/description/assets/misc/right-arrow.png
  40. BIN
      advanced_loyalty_management/static/description/assets/misc/star.png
  41. BIN
      advanced_loyalty_management/static/description/assets/misc/support.png
  42. BIN
      advanced_loyalty_management/static/description/assets/misc/whatsapp.png
  43. BIN
      advanced_loyalty_management/static/description/assets/modules/1.jpg
  44. BIN
      advanced_loyalty_management/static/description/assets/modules/2.jpg
  45. BIN
      advanced_loyalty_management/static/description/assets/modules/3.jpg
  46. BIN
      advanced_loyalty_management/static/description/assets/modules/4.png
  47. BIN
      advanced_loyalty_management/static/description/assets/modules/5.png
  48. BIN
      advanced_loyalty_management/static/description/assets/modules/6.png
  49. BIN
      advanced_loyalty_management/static/description/assets/screenshots/1.png
  50. BIN
      advanced_loyalty_management/static/description/assets/screenshots/10.png
  51. BIN
      advanced_loyalty_management/static/description/assets/screenshots/11.png
  52. BIN
      advanced_loyalty_management/static/description/assets/screenshots/12.png
  53. BIN
      advanced_loyalty_management/static/description/assets/screenshots/13.png
  54. BIN
      advanced_loyalty_management/static/description/assets/screenshots/14.png
  55. BIN
      advanced_loyalty_management/static/description/assets/screenshots/15.png
  56. BIN
      advanced_loyalty_management/static/description/assets/screenshots/16.png
  57. BIN
      advanced_loyalty_management/static/description/assets/screenshots/17.png
  58. BIN
      advanced_loyalty_management/static/description/assets/screenshots/18.png
  59. BIN
      advanced_loyalty_management/static/description/assets/screenshots/19.png
  60. BIN
      advanced_loyalty_management/static/description/assets/screenshots/2.png
  61. BIN
      advanced_loyalty_management/static/description/assets/screenshots/20.png
  62. BIN
      advanced_loyalty_management/static/description/assets/screenshots/21.png
  63. BIN
      advanced_loyalty_management/static/description/assets/screenshots/22.png
  64. BIN
      advanced_loyalty_management/static/description/assets/screenshots/23.png
  65. BIN
      advanced_loyalty_management/static/description/assets/screenshots/3.png
  66. BIN
      advanced_loyalty_management/static/description/assets/screenshots/4.png
  67. BIN
      advanced_loyalty_management/static/description/assets/screenshots/5.png
  68. BIN
      advanced_loyalty_management/static/description/assets/screenshots/6.png
  69. BIN
      advanced_loyalty_management/static/description/assets/screenshots/7.png
  70. BIN
      advanced_loyalty_management/static/description/assets/screenshots/8.png
  71. BIN
      advanced_loyalty_management/static/description/assets/screenshots/9.png
  72. BIN
      advanced_loyalty_management/static/description/assets/screenshots/v15-hero.gif
  73. BIN
      advanced_loyalty_management/static/description/banner.png
  74. BIN
      advanced_loyalty_management/static/description/icon.png
  75. 715
      advanced_loyalty_management/static/description/index.html
  76. 42
      advanced_loyalty_management/static/src/js/pos_change_popup.js
  77. 82
      advanced_loyalty_management/static/src/js/pos_order.js
  78. 20
      advanced_loyalty_management/static/src/js/pos_order_line.js
  79. 38
      advanced_loyalty_management/static/src/js/pos_payment_screen.js
  80. 62
      advanced_loyalty_management/static/src/js/reward_popup.js
  81. 287
      advanced_loyalty_management/static/src/js/rewardbutton.js
  82. 31
      advanced_loyalty_management/static/src/xml/pos_change_popup.xml
  83. 17
      advanced_loyalty_management/static/src/xml/pos_loyalty_change.xml
  84. 43
      advanced_loyalty_management/static/src/xml/reward_popup.xml
  85. 24
      advanced_loyalty_management/views/loyalty_program_views.xml
  86. 56
      advanced_loyalty_management/views/loyalty_rewards_views.xml
  87. 20
      advanced_loyalty_management/views/res_partner_views.xml

50
advanced_loyalty_management/README.rst

@ -0,0 +1,50 @@
.. image:: https://img.shields.io/badge/license-LGPL--3-green.svg
:target: https://www.gnu.org/licenses/lgpl-3.0-standalone.html
:alt: License: LGPL-3
Advanced Loyalty Management
===========================
* In this module we can deduct the loyalty points when order is refunded, we can convert the change into loyalty points, History of claimed rewards can be seen in customer's page.And introduced new reward type , in which we can redeem our points.
Configuration
============
- www.odoo.com/documentation/15.0/setup/install.html
- Install our custom addon
Company
-------
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__
License
-------
General Public License, Version 3 (LGPL v3).
(https://www.gnu.org/licenses/lgpl-3.0-standalone.html)
Credits
-------
* Developer: (V17) NIHALA KP,
(V16) NIHALA KP,
(V15) Adarsh K,
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://cybrosys.com"
Further Information
-----------
HTML Description: `<static/description/index.html>`__

22
advanced_loyalty_management/__init__.py

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<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
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from . import models

64
advanced_loyalty_management/__manifest__.py

@ -0,0 +1,64 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<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
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
{
'name': 'Advanced Loyalty Management',
'version': '15.0.1.0.0',
'category': 'Point of Sale',
'summary': 'Enhanced Loyalty Program Features',
'description': """In this module, we have incorporated new features such as
converting changes into loyalty points, displaying claimed rewards history, and
introducing a new type of reward. These enhancements aim to provide a more
comprehensive and rewarding experience for customers engaging with the loyalty
program.""",
'author': 'Cybrosys Techno Solutions',
'company': 'Cybrosys Techno Solutions',
'maintainer': 'Cybrosys Techno Solutions',
'website': 'https://www.cybrosys.com',
'depends': ['point_of_sale', 'pos_loyalty', 'base', 'sale_management'],
'data': [
'views/res_partner_views.xml',
'views/loyalty_rewards_views.xml',
'views/loyalty_program_views.xml',
],
'assets': {
'point_of_sale.assets': [
'advanced_loyalty_management/static/src/js/pos_payment_screen.js',
'advanced_loyalty_management/static/src/js/pos_change_popup.js',
'advanced_loyalty_management/static/src/js/pos_order_line.js',
'advanced_loyalty_management/static/src/js/pos_order.js',
'advanced_loyalty_management/static/src/js/rewardbutton.js',
'advanced_loyalty_management/static/src/js/reward_popup.js',
],
'web.assets_qweb': [
'advanced_loyalty_management/static/src/xml/pos_loyalty_change.xml',
'advanced_loyalty_management/static/src/xml/pos_change_popup.xml',
'advanced_loyalty_management/static/src/xml/reward_popup.xml',
],
},
'images': [
'static/description/banner.png',
],
'license': 'LGPL-3',
'installable': True,
'auto_install': False,
'application': False,
}

6
advanced_loyalty_management/doc/RELEASE_NOTES.md

@ -0,0 +1,6 @@
## Module <advanced_loyalty_management>
#### 23.07.2024
#### Version 15.0.1.0.0
#### ADD
- Initial Commit Advanced Loyalty Management

25
advanced_loyalty_management/models/__init__.py

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<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
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from . import loyalty_program
from . import loyalty_reward
from . import res_partner
from . import pos_order_line

37
advanced_loyalty_management/models/loyalty_program.py

@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<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
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import fields, models
class LoyaltyProgram(models.Model):
"""To load more fields in loyalty program and loyalty model"""
_inherit = 'loyalty.program'
point_rate = fields.Integer(string='Point Rate',
help="Points corresponding to each unit",
default=1, required=True)
change_rate = fields.Monetary(string='Change Rate', default=1,
readonly=True,
help="Unit of money per points cost")
currency_id = fields.Many2one('res.currency', string='Currency',
default=lambda self: self.env.user.company_id.currency_id,
help="Symbol of Currency")

77
advanced_loyalty_management/models/loyalty_reward.py

@ -0,0 +1,77 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<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
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import api, fields, models
class LoyaltyReward(models.Model):
"""To add a new reward type in loyalty reward"""
_inherit = 'loyalty.reward'
reward_type = fields.Selection(selection_add=[
('redemption', 'Redemption')
], ondelete={'redemption': 'set default'},
help="A new reward type is added")
redemption_point = fields.Integer(string='Redemption Point', default=1.0,
readonly=True,
help="No of points redeemed according "
"to the redemption amount")
redemption_amount = fields.Float(string='Maximum Redemption per Point',
default=1.00, required=True,
help="Maximum Redemption per redemption "
"point")
max_redemption_type = fields.Selection(
[('amount', 'Amount'), ('percent', 'Percentage'), ('points', 'Points')],
default="amount",
required=True,
help="Redemption type based on Fixed Amount,percentage or Point wise")
max_redemption_amount = fields.Float(string='Max Redemption Amount',
default=10, required=True,
help="Maximum redemption amount "
"given to an order")
redemption_frequency = fields.Integer(string='Redemption Frequency',
default=1, required=True,
help="Number of times this reward "
"can be claimed")
redemption_frequency_unit = fields.Selection([('day', 'Daily'),
('week', 'Weekly'),
('month', 'Monthly'),
('year', 'Yearly')],
default='day', required=True,
string='Redemption Frequency'
'Unit',
help="Choose the frequency "
"for claiming the reward")
redemption_eligibility = fields.Float(string="Redemption Eligibility",
default=200,
help="points required for claiming "
"the reward")
@api.model
def create(self, vals):
"""creation of new reward product"""
product = self.env['product.product'].create({
'name': vals['name'],
'detailed_type': 'service',
'available_in_pos': True,
})
vals['discount_product_id'] = product.id
return super(LoyaltyReward, self).create(vals)

30
advanced_loyalty_management/models/pos_order_line.py

@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<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
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import fields, models
class PosOrderLine(models.Model):
"""New boolean field is added to filter rewards from order line"""
_inherit = 'pos.order.line'
is_reward_line = fields.Boolean(
help="Whether this line is part of a reward or not.")

54
advanced_loyalty_management/models/res_partner.py

@ -0,0 +1,54 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<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
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import api, models
class ResPartner(models.Model):
"""Add loyalty in view_partner_form"""
_inherit = 'res.partner'
def action_view_claimed_rewards(self):
"""a smart button is created to view the claimed the rewards"""
order_id = self.env['pos.order'].search(
[('partner_id', '=', self.id)]).ids
return {
'type': 'ir.actions.act_window',
'name': 'Claimed Rewards',
'view_mode': 'tree,form',
'res_model': 'pos.order.line',
'domain': [('is_reward_line', '=', True),
('order_id', 'in', order_id)],
'context': "{'create': False}"
}
@api.model
def check_redemption(self, partner_id):
"""To check number of times the reward is claimed"""
order = self.env['pos.order'].search([('partner_id', '=', partner_id)])
data = []
date = []
order_line = self.env['pos.order.line'].search(
[('is_reward_line', '=', 'true'), ('order_id', 'in', order.ids)])
for line in order_line:
data.append(line.order_id.id)
date.append(line.create_date.date())
return data, date

BIN
advanced_loyalty_management/static/description/assets/icons/check.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
advanced_loyalty_management/static/description/assets/icons/chevron.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 B

BIN
advanced_loyalty_management/static/description/assets/icons/cogs.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
advanced_loyalty_management/static/description/assets/icons/consultation.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
advanced_loyalty_management/static/description/assets/icons/ecom-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 B

BIN
advanced_loyalty_management/static/description/assets/icons/education-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

BIN
advanced_loyalty_management/static/description/assets/icons/hotel-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 B

BIN
advanced_loyalty_management/static/description/assets/icons/license.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
advanced_loyalty_management/static/description/assets/icons/lifebuoy.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
advanced_loyalty_management/static/description/assets/icons/manufacturing-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

BIN
advanced_loyalty_management/static/description/assets/icons/pos-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 878 B

BIN
advanced_loyalty_management/static/description/assets/icons/puzzle.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

BIN
advanced_loyalty_management/static/description/assets/icons/restaurant-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 B

BIN
advanced_loyalty_management/static/description/assets/icons/service-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 839 B

BIN
advanced_loyalty_management/static/description/assets/icons/trading-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

BIN
advanced_loyalty_management/static/description/assets/icons/training.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

BIN
advanced_loyalty_management/static/description/assets/icons/update.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
advanced_loyalty_management/static/description/assets/icons/user.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 988 B

BIN
advanced_loyalty_management/static/description/assets/icons/wrench.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
advanced_loyalty_management/static/description/assets/misc/categories.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
advanced_loyalty_management/static/description/assets/misc/check-box.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
advanced_loyalty_management/static/description/assets/misc/compass.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
advanced_loyalty_management/static/description/assets/misc/corporate.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
advanced_loyalty_management/static/description/assets/misc/customer-support.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
advanced_loyalty_management/static/description/assets/misc/cybrosys-logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
advanced_loyalty_management/static/description/assets/misc/features.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 589 B

BIN
advanced_loyalty_management/static/description/assets/misc/logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
advanced_loyalty_management/static/description/assets/misc/pictures.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
advanced_loyalty_management/static/description/assets/misc/pie-chart.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
advanced_loyalty_management/static/description/assets/misc/right-arrow.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 967 B

BIN
advanced_loyalty_management/static/description/assets/misc/star.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
advanced_loyalty_management/static/description/assets/misc/support.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

BIN
advanced_loyalty_management/static/description/assets/misc/whatsapp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
advanced_loyalty_management/static/description/assets/modules/1.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

BIN
advanced_loyalty_management/static/description/assets/modules/2.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

BIN
advanced_loyalty_management/static/description/assets/modules/3.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

BIN
advanced_loyalty_management/static/description/assets/modules/4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
advanced_loyalty_management/static/description/assets/modules/5.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

BIN
advanced_loyalty_management/static/description/assets/modules/6.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

BIN
advanced_loyalty_management/static/description/assets/screenshots/1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

BIN
advanced_loyalty_management/static/description/assets/screenshots/11.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

BIN
advanced_loyalty_management/static/description/assets/screenshots/12.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

BIN
advanced_loyalty_management/static/description/assets/screenshots/13.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

BIN
advanced_loyalty_management/static/description/assets/screenshots/14.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

BIN
advanced_loyalty_management/static/description/assets/screenshots/15.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

BIN
advanced_loyalty_management/static/description/assets/screenshots/16.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

BIN
advanced_loyalty_management/static/description/assets/screenshots/17.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

BIN
advanced_loyalty_management/static/description/assets/screenshots/18.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

BIN
advanced_loyalty_management/static/description/assets/screenshots/19.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

BIN
advanced_loyalty_management/static/description/assets/screenshots/20.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

BIN
advanced_loyalty_management/static/description/assets/screenshots/21.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

BIN
advanced_loyalty_management/static/description/assets/screenshots/22.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

BIN
advanced_loyalty_management/static/description/assets/screenshots/23.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
advanced_loyalty_management/static/description/assets/screenshots/3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
advanced_loyalty_management/static/description/assets/screenshots/4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

BIN
advanced_loyalty_management/static/description/assets/screenshots/5.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

BIN
advanced_loyalty_management/static/description/assets/screenshots/6.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
advanced_loyalty_management/static/description/assets/screenshots/7.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

BIN
advanced_loyalty_management/static/description/assets/screenshots/8.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

BIN
advanced_loyalty_management/static/description/assets/screenshots/v15-hero.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 433 KiB

BIN
advanced_loyalty_management/static/description/banner.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
advanced_loyalty_management/static/description/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

715
advanced_loyalty_management/static/description/index.html

@ -0,0 +1,715 @@
<div style="background-color: #714B67; height: 810px; width: 100%; padding: 15px; position: relative;">
<!-- TITLE BAR -->
<div class="d-flex align-items-center justify-content-between"
style="border-bottom: 1px solid #875A7B; padding: 15px; display: flex; justify-content: space-between; align-items: center;">
<img src="assets/misc/cybrosys-logo.png" width="42" height="42"
style="width: 42px; height: 42px; "/>
<div>
<div
style="color: #7C7BAD; font-size: 14px; font-family: 'Montserrat', sans-serif; font-weight: bold; background-color: white; display: inline-block; padding: 3px 10px; border-radius: 50px;"
class="mr-2">
<i class="fa fa-check mr-1"></i>Enterprise
</div>
<div
style="color: #7C7BAD; font-size: 14px; font-family: 'Montserrat', sans-serif; font-weight: bold; background-color: white; display: inline-block; padding: 3px 10px; border-radius: 50px;"
class="mr-2">
<i class="fa fa-check mr-1"></i>Odoo.sh
</div>
</div>
</div>
<!-- END OF TITLE BAR -->
<div class="container">
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-12">
<!-- APP HERO -->
<h1 style="color: #FFFFFF; font-weight: bolder; font-size: 50px; text-align: center; margin-top: 50px;">
Advanced Loyalty Management</h1>
<p style="color:#FFFFFF; padding: 8px 15px; text-align: center; font-size: 24px;">
In This Module, We have Incorporated new Features such as
Converting Changes into Loyalty Points, Displaying Claimed Rewards History, and
Introducing a new Type of Reward
<img src="assets/screenshots/v15-hero.gif"
class="img-responsive"
style="width: 100%; margin-left: auto; margin-right: auto;"/>
</div>
</div>
</div>
</div>
<!-- NAVIGATION SECTION -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px; margin-top: 300px;">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/compass.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Explore This
Module</h2>
</div>
<div class="row my-4" style="font-family: 'Montserrat', sans-serif;">
<div class="col-sm-12 col-md-6 my-3">
<a href="#overview">
<div class="d-flex justify-content-between align-items-center"
style="background-color: #f5f5f5; padding: 30px; width: 100%;">
<div>
<span style="color: #714B67; font-size: 24px; font-weight: 500; display: block;">Overview</span>
<span style="color: #714B67; font-size: 16px; font-weight: 400; color:#282F33; display: block;">Learn
more about this
module</span>
</div>
<img src="assets/misc/right-arrow.png" width="36" height="36"/>
</div>
</a>
</div>
<div class="col-sm-12 col-md-6 my-3">
<a href="#features">
<div class="d-flex justify-content-between align-items-center"
style="background-color: #f5f5f5; padding: 30px; width: 100%;">
<div>
<span style="color: #714B67; font-size: 24px; font-weight: 500; display: block;">Features</span>
<span style="color: #714B67; font-size: 16px; font-weight: 400; color:#282F33; display: block;">View
features of this
module</span>
</div>
<img src="assets/misc/right-arrow.png" width="36" height="36"/>
</div>
</a>
</div>
<div class="col-sm-12 col-md-6 my-3">
<a href="#screenshots">
<div class="d-flex justify-content-between align-items-center"
style="background-color: #f5f5f5; padding: 30px; width: 100%;">
<div>
<span style="color: #714B67; font-size: 24px; font-weight: 500; display: block;">Screenshots</span>
<span style="color: #714B67; font-size: 16px; font-weight: 400; color:#282F33; display: block;">View
screenshots for this
module</span>
</div>
<img src="assets/misc/right-arrow.png" width="36" height="36"/>
</div>
</a>
</div>
</div>
<!-- END OF NAVIGATION SECTION -->
<!-- OVERVIEW SECTION -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px;" id="overview">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/pie-chart.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Overview
</h2>
</div>
<div class="row"
style="font-family: 'Montserrat', sans-serif; font-weight: 400; font-size: 14px; line-height: 200%;">
<div class="col-sm-12 py-4">
In this module, we have implemented the functionality to convert change
into loyalty points. Customers can conveniently view their claimed rewards
history on their respective pages. Furthermore, we've introduced a new reward type,
allowing users to redeem their accumulated points.
</div>
</div>
<!-- END OF OVERVIEW SECTION -->
<!-- FEATURES SECTION -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px;" id="features">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/features.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Features
</h2>
</div>
<div class="row"
style="font-family: 'Montserrat', sans-serif; font-weight: 400; font-size: 14px; line-height: 200%;">
<div class="col-sm-12 col-md-6">
<div class="d-flex align-items-center"
style="margin-top: 30px; margin-bottom: 30px">
<img src="assets/misc/check-box.png" class="mr-2"/>
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">We can convert the change into Loyalty Points.</span>
</div>
<div class="d-flex align-items-center"
style="margin-top: 30px; margin-bottom: 30px">
<img src="assets/misc/check-box.png" class="mr-2"/>
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">History of claimed Rewards can be seen in the customer's page</span>
</div>
<div class="d-flex align-items-center"
style="margin-top: 30px; margin-bottom: 30px">
<img src="assets/misc/check-box.png" class="mr-2"/>
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">A new loyalty reward type is introduced, where we can redeem the points</span>
</div>
</div>
</div>
<!-- END OF FEATURES SECTION -->
<!-- SCREENSHOTS SECTION -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px;"
id="screenshots">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/pictures.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Screenshots
</h2>
</div>
<div class="row">
<div class="col-sm-12">
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
We have the capability to convert the change to loyalty points.To facilitate this, we have introduced
a new field in the loyalty program for the conversion rate per dollar.
</h3>
<img src="assets/screenshots/1.png" class="img-thumbnail">
<img src="assets/screenshots/2.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Initially, we can select a customer, whose loyalty points are set to zero.
</h3>
<img src="assets/screenshots/3.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Then we can create a sales order directly from the POS interface.
</h3>
<img src="assets/screenshots/4.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
We create a button under the change to convert the loyalty.
</h3>
<img src="assets/screenshots/5.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
When the popup is clicked, the loyalty program allocated for the POS session
will become visible here.Clicking the ADD button will convert changes, and the
change amount will reset to zero.
</h3>
<img src="assets/screenshots/6.png" class="img-thumbnail">
<img src="assets/screenshots/7.png" class="img-thumbnail">
<img src="assets/screenshots/8.png" class="img-thumbnail">
<img src="assets/screenshots/9.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Now let's check new reward type and how its works
</h3>
<img src="assets/screenshots/10.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
In this type of reward, customers can only claim the reward if they are making
a second purchase or if they have existing loyalty points.
</h3>
<img src="assets/screenshots/11.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
If the same customer do the purchase for the second time, they are eligible for claiming the reward
</h3>
<img src="assets/screenshots/12.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Upon selecting the reward a popup showing how many points we can redeem
</h3>
<img src="assets/screenshots/13.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Then we can see that it is applied to reward line
</h3>
<img src="assets/screenshots/14.png" class="img-thumbnail">
<img src="assets/screenshots/15.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
If the same customer come again he cannot claim it again, While configuring the rewards ,
we give the condition Daily 1
</h3>
<img src="assets/screenshots/16.png" class="img-thumbnail">
<img src="assets/screenshots/17.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
If maximum redemption amount type is given in percentage, We can redeem the 10% of the order's subtotal
</h3>
<img src="assets/screenshots/18.png" class="img-thumbnail">
<img src="assets/screenshots/19.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
If maximum redemption amount type is given in Points, We can redeem that much points as
maximum redemption points
</h3>
<img src="assets/screenshots/20.png" class="img-thumbnail">
<img src="assets/screenshots/21.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">
Next we can see the history of claimed rewards in the customer's page.
</h3>
<img src="assets/screenshots/22.png" class="img-thumbnail">
<img src="assets/screenshots/23.png" class="img-thumbnail">
</div>
</div>
</div>
<!-- END OF SCREENSHOTS SECTION -->
<!-- RELATED PRODUCTS -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px;">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/categories.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Related
Products
</h2>
</div>
<div class="row">
<div class="col-sm-12">
<div id="demo1" class="row carousel slide" data-ride="carousel">
<!-- The slideshow -->
<div class="carousel-inner" style="padding: 30px;">
<div class="carousel-item" style="min-height: 198.656px;">
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16"
style="float:left">
<a href="https://apps.odoo.com/apps/modules/15.0/advanced_chatter_view/"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-radius: 0px;"
src="assets/modules/1.jpg">
</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/15.0/hide_chatter/#"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-radius: 0px;"
src="assets/modules/2.jpg">
</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/15.0/mail_push_notification/"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-radius: 0px;"
src="assets/modules/3.jpg">
</div>
</a>
</div>
</div>
<div class="carousel-item active"
style="min-height: 198.656px;">
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16"
style="float:left">
<a href="https://apps.odoo.com/apps/modules/15.0/activity_reminder/"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-radius: 0px;"
src="assets/modules/4.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/15.0/product_return_pos/"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-radius: 0px;"
src="assets/modules/5.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/15.0/autosuggestion_in_discuss/"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block"
style="border-radius: 0px;"
src="assets/modules/6.png">
</div>
</a>
</div>
</div>
</div>
<!-- Left and right controls -->
<a class="carousel-control-prev" href="#demo1" data-slide="prev"
style="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="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 RELATED PRODUCTS -->
<!-- OUR SERVICES -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px;">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/star.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Our Services
</h2>
</div>
<div class="container my-5">
<div class="row">
<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>
</div>
<!-- END OF OUR SERVICES -->
<!-- OUR INDUSTRIES -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px;">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/corporate.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Our
Industries
</h2>
</div>
<div class="container my-5">
<div class="row">
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; 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: 0px; 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: 0px; 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: 0px; 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: 0px; 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 &amp; 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: 0px; 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: 0px; 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: 0px; 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>
</div>
<!-- END OF OUR INDUSTRIES -->
<!-- SUPPORT -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px;">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/customer-support.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Support
</h2>
</div>
<div class="container mt-5">
<div class="row">
<div class="col-sm-12 col-md-6">
<div style="background-color: #F6F8F9; padding: 30px; display: flex; align-items: center;">
<div class="mr-4 d-flex justify-content-center align-items-center"
style="background-color: #714B67; display: inline-block; height: 70px; width: 70px; display: flex; align-items: center; justify-content: center;">
<img src="assets/misc/support.png" height="48" width="48"
style="width: 42px; height: 42px;"/>
</div>
<div>
<h4>Need Help?</h4>
<p style="line-height: 100%;">Got questions or need help?
Get in touch.</p>
<a href="mailto:odoo@cybrosys.com">
<p style="font-weight: 400; font-size: 28px; line-height: 80%; color: #714B67;">
odoo@cybrosys.com</p>
</a>
</div>
</div>
</div>
<div class="col-sm-12 col-md-6">
<div style="background-color: #F6F8F9; padding: 30px; display: flex; align-items: center;">
<div class="mr-4 d-flex justify-content-center align-items-center"
style="background-color: #2AC44D; display: inline-block; height: 70px; width: 70px; display: flex; align-items: center; justify-content: center;">
<img src="assets/misc/whatsapp.png" height="52" width="52"
style="width: 52px; height: 52px;"/>
</div>
<div>
<h4>WhatsApp</h4>
<p style="line-height: 100%;">Say hi to us on WhatsApp!</p>
<a href="https://api.whatsapp.com/send?phone=918606827707">
<p style="font-weight: 400; font-size: 28px; line-height: 80%; color: #714B67;">
+91 86068
27707</p>
</a>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12 my-5 d-flex justify-content-center align-items-center">
<img src="assets/misc/logo.png" width="144" height="31"
style="width:144px; height: 31px; margin-top: 40px;"/>
</div>
</div>
</div>
<!-- END OF SUPPORT -->

42
advanced_loyalty_management/static/src/js/pos_change_popup.js

@ -0,0 +1,42 @@
odoo.define('advanced_loyalty_management.LoyaltyPrograms', function (require) {
"use strict";
const AbstractAwaitablePopup = require('point_of_sale.AbstractAwaitablePopup');
const Registries = require('point_of_sale.Registries');
const rpc = require('web.rpc');
const { _t } = require('web.core');
class LoyaltyPrograms extends AbstractAwaitablePopup {
constructor() {
super(...arguments);
}
async convertToLoyalty(props, programId) {
const change = props.change;
const order = props.Order;
const loyalty = props.Loyalty
// Resets the change by adjusting the payment
if (change > 0) {
const lastPaymentLine = props.Order.get_paymentlines().slice(-1)[0];
if (lastPaymentLine) {
lastPaymentLine.set_amount(lastPaymentLine.get_amount() - change);
}
order.change_to_loyalty = change * loyalty.point_rate;
}
this.trigger('confirm');
}
}
LoyaltyPrograms.template = 'LoyaltyPrograms';
LoyaltyPrograms.defaultProps = {
confirmText: _t('Confirm'),
cancelText: _t('Cancel'),
title: _t('Loyalty Programs'),
body: '',
};
Registries.Component.add(LoyaltyPrograms);
return LoyaltyPrograms;
});

82
advanced_loyalty_management/static/src/js/pos_order.js

@ -0,0 +1,82 @@
odoo.define('advanced_loyalty_management.Order', function(require) {
"use strict";
const models = require('point_of_sale.models');
const _super_Order = models.Order.prototype;
const { patch } = require('web.utils');
const ProductScreen = require('point_of_sale.ProductScreen');
models.Order = models.Order.extend({
initialize: function(attributes, options) {
_super_Order.initialize.apply(this, arguments);
if (options?.json?.lines.length === 0) {
this.additional_redeemed_points = 0;
this.pointsWon = 0;
this.selected_reward = null;
}
},
get_won_points: function() {
const wonPoints = _super_Order.get_won_points.apply(this, arguments);
if (this.selected_reward && this.selected_reward.reward_type === 'redemption') {
return Math.max(0, this.pointsWon - this.additional_redeemed_points);
}
return wonPoints;
},
get_spent_points: function() {
const spentPoints = _super_Order.get_spent_points.apply(this, arguments);
return spentPoints + this.additional_redeemed_points;
},
get_new_points: function() {
const newPoints = _super_Order.get_new_points.apply(this, arguments);
if (this.selected_reward && this.selected_reward.reward_type === 'redemption') {
return Math.max(0, this.pointsWon - this.additional_redeemed_points);
}
return newPoints;
},
// Ensure pointsWon, additional_redeemed_points, selected_reward is also persisted
export_as_JSON: function() {
const json = _super_Order.export_as_JSON.apply(this, arguments);
json.additional_redeemed_points = this.additional_redeemed_points;
json.selected_reward = this.selected_reward;
json.pointsWon = this.pointsWon;
return json;
},
// Restore pointsWon, additional_redeemed_points, selected_reward
init_from_JSON: function(json) {
_super_Order.init_from_JSON.apply(this, arguments);
this.additional_redeemed_points = json.additional_redeemed_points || 0;
this.selected_reward = json.selected_reward || null;
this.pointsWon = json.pointsWon || 0;
},
applyRedeemPoints: function(pointsToRedeem, selectedReward, pointsWon) {
this.additional_redeemed_points += pointsToRedeem;
this.selected_reward = selectedReward;
this.pointsWon = pointsWon;
},
resetRedemptionPoints: function() {
this.additional_redeemed_points = 0;
this.pointsWon = 0;
this.selected_reward = null;
}
});
// Resets the loyalty points on clicking backspace
patch(ProductScreen.prototype, 'advanced_loyalty_management.ProductScreen', {
_updateSelectedOrderline: function (event) {
let screen = this._super(...arguments);
const order = this.env.pos.get_order()
const selectedLine = order?.selected_orderline?.get_reward()?.reward_type;
if (selectedLine === 'redemption') {
order.resetRedemptionPoints();
this.render();
}
return screen;
},
});
return models;
});

20
advanced_loyalty_management/static/src/js/pos_order_line.js

@ -0,0 +1,20 @@
odoo.define('advanced_loyalty_management.OrderLine', function (require) {
"use strict";
var models = require('point_of_sale.models');
var _super_orderline = models.Orderline.prototype;
models.Orderline = models.Orderline.extend({
// To include a is_reward_line flag for reward lines, during initialization and JSON export
initialize: function(attr, options) {
_super_orderline.initialize.apply(this, arguments);
if (options.extras && options.extras.is_reward_line) {
this.is_reward_line = options.extras.is_reward_line;
}
},
export_as_JSON: function() {
var json = _super_orderline.export_as_JSON.apply(this, arguments);
json.is_reward_line = this.is_reward_line || false;
return json;
},
});
});

38
advanced_loyalty_management/static/src/js/pos_payment_screen.js

@ -0,0 +1,38 @@
odoo.define('advanced_loyalty_management.ChangeLoyalty', function (require) {
"use strict";
const { patch } = require('web.utils');
const PaymentScreenStatus = require('point_of_sale.PaymentScreenStatus');
const { Gui } = require('point_of_sale.Gui');
patch(PaymentScreenStatus.prototype, 'point_of_sale/static/src/js/Screens/PaymentScreen/PaymentScreenStatus.js', {
async convertLoyalty() {
var order = this.env.pos.get_order();
const result = await Gui.showPopup('LoyaltyPrograms', {
title: this.env._t('Convert Change'),
cancelText: this.env._t("Cancel"),
confirmText: this.env._t("Confirm"),
Order: order,
Loyalty: this.env.pos.loyalty,
LoyaltyPoints: order.get_won_points(),
change: order.get_change(),
});
},
showLoyaltyButton: function() {
var order = this.env.pos.get_order();
const showButton = order.get_change() > 0 && order.get_won_points() > 0
return showButton;
},
});
// Patch the Order prototype to modify get_won_points and adds the change
const Order = require('point_of_sale.models').Order;
patch(Order.prototype, 'advanced_loyalty_management.Order', {
get_won_points: function () {
let points = this._super(...arguments);
if (this.change_to_loyalty) {
points += this.change_to_loyalty;
}
return points;
},
});
});

62
advanced_loyalty_management/static/src/js/reward_popup.js

@ -0,0 +1,62 @@
odoo.define('advanced_loyalty_management.RewardPopup', function (require) {
"use strict";
const AbstractAwaitablePopup = require('point_of_sale.AbstractAwaitablePopup');
const Registries = require('point_of_sale.Registries');
const { _t } = require('web.core');
const { hooks } = owl;
const { useState, useRef } = hooks;
class RewardPopup extends AbstractAwaitablePopup {
setup() {
this.state = useState({
value: '',
redeemPoints: ''
});
this.points = useRef("points");
}
toRedeem(ev) {
this.state.redeemPoints = this.points.el.value;
}
save(props, ev) {
const pointsToRedeem = parseInt(this.state.redeemPoints);
if (isNaN(pointsToRedeem)) {
this.showPopup('ErrorPopup', {
title: _t('Error'),
body: _t('Please enter a valid number'),
});
return;
}
if (props.max_redemption_points < pointsToRedeem) {
this.showPopup('ErrorPopup', {
title: _t('Error'),
body: _t('Points to redeem should be less than Maximum Redemption Point.'),
});
return;
}
const selectedReward = props.selected_reward;
selectedReward.pointsToRedeem = parseInt(this.state.redeemPoints);
const pointsWon = props.order.get_won_points();
props.order.point_cost = pointsToRedeem;
ev.confirm();
props.property.apply_reward(selectedReward);
props.order.applyRedeemPoints(pointsToRedeem, selectedReward, pointsWon);
}
}
RewardPopup.template = 'RewardPopup';
RewardPopup.defaultProps = {
confirmText: _t('Confirm'),
cancelText: _t('Cancel'),
title: _t('Reward'),
body: '',
};
Registries.Component.add(RewardPopup);
return RewardPopup;
});

287
advanced_loyalty_management/static/src/js/rewardbutton.js

@ -0,0 +1,287 @@
odoo.define('advanced_loyalty_management.RewardButton', function (require) {
"use strict";
const { patch } = require('web.utils');
const { useListener } = require('web.custom_hooks');
const RewardButton = require('pos_loyalty.RewardButton');
const { Gui } = require('point_of_sale.Gui');
const { _t } = require('web.core');
const { useState } = owl;
var models = require('point_of_sale.models');
var rpc = require('web.rpc');
var utils = require('web.utils');
var round_pr = utils.round_precision;
models.load_fields("loyalty.reward",
["max_redemption_amount", "redemption_point", "redemption_amount","redemption_frequency","redemption_frequency_unit",
"redemption_eligibility", "max_redemption_type"]);
models.load_fields("loyalty.program",
["point_rate"]);
patch(RewardButton.prototype, "pos_loyalty/static/src/js/RewardButton.js", {
setup() {
useListener('click', this.onClick);
this.state = useState({
frequency : 0,
});
},
async apply_reward(reward) {
const order = this.env.pos.get_order();
var client = order.get_client();
var product, product_price, order_total, spendable;
var crounding;
if (!client) {
return;
} else if (reward.reward_type === 'gift') {
product = order.pos.db.get_product_by_id(reward.gift_product_id[0]);
if (!product) {
return;
}
let options = await order._getAddProductOptions(product);
await order.add_product(product, {
...options,
price: 0,
quantity: 1,
merge: false,
extras: { reward_id: reward.id, price_manually_set: true, is_reward_line: true },
});
} else if (reward.reward_type === 'discount') {
crounding = order.pos.currency.rounding;
spendable = order.get_spendable_points();
order_total = order.get_total_with_tax();
var discount = 0;
product = order.pos.db.get_product_by_id(reward.discount_product_id[0]);
if (!product) {
return;
}
if (reward.discount_type === "percentage") {
if (reward.discount_apply_on === "on_order") {
discount += round_pr(order_total * (reward.discount_percentage / 100), crounding);
}
if (reward.discount_apply_on === "specific_products") {
for (var prod of reward.discount_specific_product_ids) {
var specific_products = order.pos.db.get_product_by_id(prod);
if (!specific_products)
return;
for (var line of order.get_orderlines()) {
if (line.product.id === specific_products.id)
discount += round_pr(line.get_price_with_tax() * (reward.discount_percentage / 100), crounding);
}
}
}
if (reward.discount_apply_on === "cheapest_product") {
var price;
for (var line of order.get_orderlines()) {
if ((!price || price > line.get_unit_price()) && line.product.id !== product.id) {
discount = round_pr(line.get_price_with_tax() * (reward.discount_percentage / 100), crounding);
price = line.get_unit_price();
}
}
}
if (reward.discount_max_amount !== 0 && discount > reward.discount_max_amount)
discount = reward.discount_max_amount;
let options = await order._getAddProductOptions(product);
await order.add_product(product, {
...options,
price: -discount,
quantity: 1,
merge: false,
extras: { reward_id: reward.id, price_manually_set: true, is_reward_line: true },
});
}
if (reward.discount_type == "fixed_amount") {
let discount_fixed_amount = reward.discount_fixed_amount;
let point_cost = reward.point_cost;
let quantity_to_apply = Math.floor(spendable / point_cost);
let amount_discounted = discount_fixed_amount * quantity_to_apply;
if (amount_discounted > order_total) {
quantity_to_apply = Math.floor(order_total / discount_fixed_amount);
}
let options = await order._getAddProductOptions(product);
await order.add_product(product, {
...options,
price: -discount_fixed_amount,
quantity: quantity_to_apply,
merge: false,
extras: { reward_id: reward.id, price_manually_set: true, is_reward_line: true },
});
}
}
// Start of new condition for reward_type 'redemption'
else if (reward.reward_type === 'redemption') {
if (order.get_client() != null) {
await this.check(reward, order.get_client().id);
}
if (reward.redemption_frequency > this.state.frequency) {
product = this.env.pos.db.get_product_by_id(reward.discount_product_id[0]);
if (!product) {
return;
}
let options = await order._getAddProductOptions(product);
await order.add_product(product, {
...options,
price: -reward.pointsToRedeem,
quantity: 1,
merge: false,
extras: { reward_id: reward.id, price_manually_set: true, is_reward_line: true },
});
} else {
this.showPopup('ErrorPopup', {
title: _t("REDEMPTION LIMIT REACHED"),
body: _t("You have reached the redemption limit for this period."),
});
}
}
},
async check(reward, partnerId){
//---To check how many times the reward is claimed
let count = 0;
var checkRedemption = await rpc.query({
model:'res.partner',
method:'check_redemption',
args:[partnerId]
})
.then((result)=>{
const today = new Date()
const year = today.getFullYear();
const month = String(today.getMonth() + 1).padStart(2, '0');
const day = String(today.getDate()).padStart(2, '0');
const formattedDate = `${year}-${month}-${day}`;
const currentWeekStart = new Date(today.getFullYear(), today.getMonth(), today.getDate() - today.getDay());
const currentWeekEnd = new Date(today.getFullYear(), today.getMonth(), today.getDate() + (6 - today.getDay()));
const formattedCurrentWeekStart = currentWeekStart.toISOString().split('T')[0];
const formattedCurrentWeekEnd = currentWeekEnd.toISOString().split('T')[0];
const currentMonthStart = new Date(today.getFullYear(), today.getMonth(), 1);
const currentMonthEnd = new Date(today.getFullYear(), today.getMonth() + 1, 0); // Last day of current month
const formattedCurrentMonthStart = currentMonthStart.toISOString().split('T')[0];
const formattedCurrentMonthEnd = currentMonthEnd.toISOString().split('T')[0];
const currentYearStart = new Date(today.getFullYear(), 0, 1);
const currentYearEnd = new Date(today.getFullYear(), 11, 31);
const formattedCurrentYearStart = currentYearStart.toISOString().split('T')[0];
const formattedCurrentYearEnd = currentYearEnd.toISOString().split('T')[0];
if(reward.redemption_frequency_unit === 'day'){
for (let i = 0; i < result[1].length; i++) {
if (result[1][i] === formattedDate) {
count ++;
}
}
}
else if(reward.redemption_frequency_unit === 'week'){
for (let i = 0; i < result[1].length; i++) {
const date =(result[1][i]);
if (date >= formattedCurrentWeekStart && date <= formattedCurrentWeekEnd) {
count++;
}
}
}
else if(reward.redemption_frequency_unit === 'month'){
for (let i = 0; i < result[1].length; i++) {
const date =(result[1][i]);
if (date >= formattedCurrentMonthStart && date <= formattedCurrentMonthEnd) {
count++;
}
}
}
else if(reward.redemption_frequency_unit === 'year'){
for (let i = 0; i < result[1].length; i++) {
const date =(result[1][i]);
if (date >= formattedCurrentYearStart && date <= formattedCurrentYearEnd) {
count ++
}
}
}
return count
})
this.state.frequency = checkRedemption
},
async onClick() {
const order = this.env.pos.get_order();
const rewards = order.get_available_rewards();
const client = order.get_client();
if (rewards.length === 0) {
await this.showPopup('ErrorPopup', {
title: this.env._t('No rewards available.'),
body: this.env._t('There are no rewards claimable for this customer.')
});
return false;
}
let rewardPoints = 0;
if (client) {
rewardPoints = client.loyalty_points || 0;
}
const filteredRewards = rewards.filter(reward => {
if (reward.reward_type === 'redemption') {
return rewardPoints > 0;
}
return true;
});
if (filteredRewards.length === 0) {
await this.showPopup('ErrorPopup', {
title: this.env._t('No claimable rewards.'),
body: this.env._t('There are no rewards claimable for this customer.')
});
return false;
}
const rewardsList = filteredRewards.map((reward) => ({
id: reward.id,
label: reward.name,
item: reward,
}));
const { confirmed, payload: selectedReward } = await this.showPopup('SelectionPopup', {
title: this.env._t('Please select a reward'),
list: rewardsList,
});
if (confirmed) {
if (selectedReward.reward_type == "redemption") {
var points = [];
if (selectedReward.max_redemption_type == 'points') {
points.push(selectedReward.max_redemption_amount / selectedReward.redemption_amount);
} else if (selectedReward.max_redemption_type == 'amount') {
points.push(selectedReward.max_redemption_amount / selectedReward.redemption_amount);
} else if (selectedReward.max_redemption_type == 'percent') {
var totalAmount = order.get_total_with_tax();
var maxRedemption = totalAmount * selectedReward.max_redemption_amount / 100;
points.push(maxRedemption / selectedReward.redemption_amount);
}
Gui.showPopup('RewardPopup', {
title: this.env._t('Reward'),
cancelText: this.env._t("Cancel"),
confirmText: this.env._t("Confirm"),
rewards: rewards,
selected_reward: selectedReward,
order: order,
max_redemption_points: points[0],
property: this
});
} else {
return this.apply_reward(selectedReward);
}
}
return false;
}
})
})

31
advanced_loyalty_management/static/src/xml/pos_change_popup.xml

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<!-- Popup when convert to loyalty is clicked -->
<t t-name="LoyaltyPrograms" owl="1">
<div role="dialog" class="modal-dialog">
<div class="popup popup-couponproducts" style="background-color: #ffffff; text-align: center;">
<p class="title">
<t t-esc="props.title"/>
</p>
<div class="body">
<div style="margin: 3%; display: inline-block;">
<span style="font-size: 25px; font-weight: bold;">
<t t-esc="props.Loyalty.name"/>
</span>
<button class="button btn btn-lg btn-primary"
style="margin-top: 10px; padding: 10px; width: 100%; text-align: center; font-weight: bold;"
t-on-click="() => { convertToLoyalty(props, this); cancel(); }">
Add
</button>
</div>
</div>
<div class="footer footer-flex modal-footer justify-content-end">
<div class="button cancel btn btn-lg btn-primary"
t-on-click="cancel">
<t t-esc="props.cancelText"/>
</div>
</div>
</div>
</div>
</t>
</templates>

17
advanced_loyalty_management/static/src/xml/pos_loyalty_change.xml

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<templates id="template" xml:space="preserve">
<!--Button is added to convert the change to loyalty points-->
<t t-inherit="point_of_sale.PaymentScreenStatus" t-inherit-mode="extension">
<xpath expr="//div[hasclass('payment-status-change')]" position="after">
<t t-if="showLoyaltyButton()">
<button class="btn btn-light rounded-0 fw-bolder"
t-on-click="convertLoyalty" style="font-size: 17px;">
<i role="img" aria-label="Custom Button"
title="Custom Button"/>
Convert to Loyalty
</button>
</t>
</xpath>
</t>
</templates>

43
advanced_loyalty_management/static/src/xml/reward_popup.xml

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<!-- Popup displayed when convert to loyalty is clicked -->
<t t-name="RewardPopup" owl="1">
<div role="dialog" class="modal-dialog">
<div class="popup popup-couponproducts" style="background-color: #ffffff; text-align: center;">
<p class="title">
<t t-esc="props.title"/>
</p>
<div class="body">
<form>
<table style="width: 100%; border-collapse: collapse; border: 1px solid #ddd;">
<tr style="background-color: #f2f2f2;">
<th style="padding: 8px; text-align: left;">Max Redemption Points</th>
<th style="padding: 8px; text-align: left;">To redeem</th>
</tr>
<tr>
<td style="padding: 8px;text-align: left;">
<t t-esc="props.max_redemption_points"/>
</td>
<td style="padding: 8px;text-align: left;">
<input class="w-75 form-control" name="customer"
t-on-change="() => toRedeem(this)"
t-ref="points"/>
</td>
</tr>
</table>
</form>
</div>
<div class="footer footer-flex modal-footer justify-content-end">
<button
class="button cancel btn btn-lg btn-primary"
t-on-click="(ev) => save(props,this)"
string="add">Add</button>
<div class="button cancel btn btn-lg btn-primary"
t-on-click="cancel">
<t t-esc="props.cancelText"/>
</div>
</div>
</div>
</div>
</t>
</templates>

24
advanced_loyalty_management/views/loyalty_program_views.xml

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!--New fields added to loyalty.program view-->
<record id="view_loyalty_program_form" model="ir.ui.view">
<field name="name">loyalty.program.view.form.inherit.advanced.loyalty.management</field>
<field name="model">loyalty.program</field>
<field name="inherit_id" ref="pos_loyalty.view_loyalty_program_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='points']" position="after">
<div class="o_group">
<div class="o_col">
<label for="point_rate" style="font-weight: bold;"/>
<div id="point_rate" class="o_row">
<field name="point_rate" style="width: 2rem;" class="oe_inline"/>
<span invisible="" style="font-weight: bold;">Point per</span>
<field name="change_rate" widget="monetary" class="oe_inline"/>
<field name="currency_id" invisible="1"/>
</div>
</div>
</div>
</xpath>
</field>
</record>
</odoo>

56
advanced_loyalty_management/views/loyalty_rewards_views.xml

@ -0,0 +1,56 @@
<?xml version="1.0" encoding = "utf-8"?>
<odoo>
<!--New fields added to Reward form-->
<record id="view_loyalty_reward_form" model="ir.ui.view">
<field name="name">
loyalty.reward.view.form.inherit.advanced.loyalty.management
</field>
<field name="model">loyalty.reward</field>
<field name="inherit_id" ref="pos_loyalty.view_loyalty_reward_form"/>
<field name="arch" type="xml">
<xpath expr="//group[2]/group" position="after">
<label for="redemption_point" string="Conditions"
attrs="{'invisible': [('reward_type','!=','redemption')]}" style="font-weight: bold;"/>
<group
attrs="{'invisible': [('reward_type','!=','redemption')]}">
<field name="redemption_point" default="1"/>
<field name="redemption_amount" widget="monetary"/>
<label for="max_redemption_amount"/>
<div id="max_redemption_amount" class="o_row">
<field name="max_redemption_type" class="oe_inline"/>
<field name="max_redemption_amount"
class="oe_inline"/>
</div>
<field name="redemption_frequency"/>
<field name="redemption_frequency_unit"/>
<field name="redemption_eligibility" widget="monetary"/>
</group>
</xpath>
<xpath expr="//label[@for='discount_type']" position="replace">
<label string="Apply Discount" for="discount_type" attrs="{'invisible': [('reward_type', 'in', ('gift','redemption'))]}"/>
</xpath>
<xpath expr="//field[@name='discount_product_id']" position="replace">
<field name="discount_product_id" string="Discount Product"
attrs="{ 'invisible':[('reward_type','not in',['discount','redemption'])],
'required':[('reward_type','==','discount')] }" domain="[('available_in_pos', '=', True)]"
context="{'default_available_in_pos': '1'}"/>
</xpath>
<xpath expr="//field[@name='discount_apply_on']" position="replace">
<field name="discount_apply_on" attrs="{'invisible':
['|', ('reward_type', 'in', ('product', 'gift', 'redemption')),
('discount_type', '!=', 'percentage')]}" widget="radio"/>
</xpath>
<xpath expr="//field[@name='discount_max_amount']" position="replace">
<field name="discount_max_amount" class="oe_inline" attrs="{'invisible':
[('reward_type', '=', 'redemption')]}"/>
</xpath>
<xpath expr="//label[@for='discount_max_amount']" position="replace">
<label for="discount_max_amount" string="Max Discount Amount" attrs="{'invisible': ['|', ('reward_type', 'in', ('product', 'gift', 'redemption')), ('discount_type', '!=', 'percentage')]}"/>
</xpath>
<xpath expr="//span[hasclass('oe_grey')]" position="replace">
<span class="oe_grey" attrs="{'invisible':
[('reward_type', '=', 'redemption')]}">if 0, no limit</span>
</xpath>
</field>
</record>
</odoo>

20
advanced_loyalty_management/views/res_partner_views.xml

@ -0,0 +1,20 @@
<?xml version="1.0" encoding = "utf-8"?>
<odoo>
<!-- Claimed Rewards smart button is shown in customer's form -->
<record id="view_partner_form" model="ir.ui.view">
<field name="name">res.partner.view.form.inherit.advanced.loyalty.management</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<xpath expr="//button[@name='action_view_sale_order']"
position="after" create="false">
<button name="action_view_claimed_rewards"
type="object"
class="oe_stat_button"
string="Claimed Rewards"
icon="fa-book">
</button>
</xpath>
</field>
</record>
</odoo>
Loading…
Cancel
Save