diff --git a/pos_loyalty/README.rst b/pos_loyalty/README.rst index ed9c1c7c..f3441df6 100644 --- a/pos_loyalty/README.rst +++ b/pos_loyalty/README.rst @@ -1,11 +1,30 @@ -.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg - :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html - :alt: License: AGPL-3 - =============== Loyalty Program =============== +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fpos-lightgray.png?logo=github + :target: https://github.com/OCA/pos/tree/11.0/pos_loyalty + :alt: OCA/pos +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/pos-11-0/pos-11-0-pos_loyalty + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/184/11.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + This module allows you to define a loyalty program in the point of sale, where the customers earn loyalty points and get rewards. @@ -13,46 +32,74 @@ This module is a forward-port to v10 of the pos_loyalty module from Odoo's saas-6 branch. The functionality was moved to the Enterprise edition in later versions. -Usage -===== +**Table of contents** + +.. contents:: + :local: + +Configuration +============= To use this module, you need to: -* Go to *Point of Sale > Configuration > Loyalty Programs* and define a new loyalty program with specific rules and gifts. +* Go to *Point of Sale > Configuration > Loyalty Programs* and define a new loyalty program with specific rules and rewards. * Assign the loyalty program to the desired Point of Sale. -.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas - :alt: Try me on Runbot - :target: https://runbot.odoo-community.org/runbot/{repo_id}/{branch} +Usage +===== + +The Loyalty Program defines rules for acquiring points and rewards on which they can be spent. + +Rules can be defined globally for all products (fields on loyalty.program) and / or rules that are applied only on specific product or PoS category (loyalty.rule records) on a *points per product sold* or *points per currency spent* basis. The specific rules (loyalty.rule) can be defined as cumulative, which means that they will be aggregated with other matching rules (loyalty.rule records and loyalty.program fields). In the case of non-cumulative rules only the points from that one matching rule are used. Additionally, *fixed points per order* can be added which are applied regardless of whether or not cumulative or non-cumulative rules were applied also. + +Rewards can be of three types: + +* *Gift* - give a single unit of product for free +* *Discount* - give a discount to the whole order. It should be added at the end of the order so that the correct total price is used. +* *Resale* - allow for customer to sell back his earned points. These are calculated by setting the price on the Resale product (*resale_product.list_price* * *customer.loyalty_points*) + +All rewards can define how many points they cost (point_cost) and how many are needed so that the customer can become eligable for the reward (minimum_points). for Gift and Discount rewards minimum_points are considered only if they are greater then the point_cost for that reward (minimum_points > point_cost). For Resale products only minimum_points can be used. Bug Tracker =========== -Bugs are tracked on `GitHub Issues -`_. In case of trouble, please -check there if your issue has already been reported. If you spotted it first, -help us smash it by providing detailed and welcomed feedback. +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. Credits ======= +Authors +~~~~~~~ + +* OpenERP SA +* RGB Consulting SL +* Lambda IS + Contributors ------------- +~~~~~~~~~~~~ * RGB Consulting SL (http://www.rgbconsulting.com) * Forward-port from Odoo SA saas-6 branch +* Kiril Vangelovski -Maintainer ----------- +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. .. image:: https://odoo-community.org/logo.png :alt: Odoo Community Association :target: https://odoo-community.org -This module is maintained by the OCA. - OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -To contribute to this module, please visit https://odoo-community.org. \ No newline at end of file +This module is part of the `OCA/pos `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/pos_loyalty/__init__.py b/pos_loyalty/__init__.py index ec50cfc0..69f7babd 100644 --- a/pos_loyalty/__init__.py +++ b/pos_loyalty/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from . import models diff --git a/pos_loyalty/__manifest__.py b/pos_loyalty/__manifest__.py index ee631c48..8bd95be8 100644 --- a/pos_loyalty/__manifest__.py +++ b/pos_loyalty/__manifest__.py @@ -1,19 +1,22 @@ -# -*- coding: utf-8 -*- # Copyright 2004-2010 OpenERP SA # Copyright 2017 RGB Consulting S.L. (https://www.rgbconsulting.com) +# Copyright 2018 Lambda IS DOOEL # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). { 'name': 'Loyalty Program', - 'version': '10.0.1.0.0', + 'version': '11.0.1.0.0', 'category': 'Point of Sale', 'license': 'AGPL-3', 'author': "OpenERP SA, " "RGB Consulting SL, " + "Lambda IS, " "Odoo Community Association (OCA)", 'website': "https://odoo-community.org/", 'depends': ['point_of_sale'], - + 'demo': [ + 'demo/templates.xml', + ], 'data': [ 'security/ir.model.access.csv', 'views/templates.xml', diff --git a/pos_loyalty/demo/templates.xml b/pos_loyalty/demo/templates.xml new file mode 100644 index 00000000..81f834eb --- /dev/null +++ b/pos_loyalty/demo/templates.xml @@ -0,0 +1,8 @@ + + + + diff --git a/pos_loyalty/models/__init__.py b/pos_loyalty/models/__init__.py index 849d26de..d6885ec8 100644 --- a/pos_loyalty/models/__init__.py +++ b/pos_loyalty/models/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from . import loyalty_program @@ -6,4 +5,5 @@ from . import loyalty_reward from . import loyalty_rule from . import pos_config from . import pos_order +from . import pos_order_line from . import res_partner diff --git a/pos_loyalty/models/loyalty_program.py b/pos_loyalty/models/loyalty_program.py index 5817f6d3..a3493beb 100644 --- a/pos_loyalty/models/loyalty_program.py +++ b/pos_loyalty/models/loyalty_program.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2004-2010 OpenERP SA # Copyright 2017 RGB Consulting S.L. (https://www.rgbconsulting.com) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). diff --git a/pos_loyalty/models/loyalty_reward.py b/pos_loyalty/models/loyalty_reward.py index d0897171..ac3d97eb 100644 --- a/pos_loyalty/models/loyalty_reward.py +++ b/pos_loyalty/models/loyalty_reward.py @@ -1,6 +1,6 @@ -# -*- coding: utf-8 -*- # Copyright 2004-2010 OpenERP SA # Copyright 2017 RGB Consulting S.L. (https://www.rgbconsulting.com) +# Copyright 2018 Lambda IS DOOEL # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from odoo import fields, models, api, _ @@ -32,13 +32,18 @@ class LoyaltyReward(models.Model): help='The Loyalty Program this reward' ' belongs to') gift_product_id = fields.Many2one(comodel_name='product.product', + domain=[('available_in_pos', '=', True)], string='Gift Product', help='The product given as a reward') discount_product_id = fields.Many2one(comodel_name='product.product', + domain=[ + ('available_in_pos', '=', True)], string='Discount Product', help='The product used to apply ' 'discounts') point_product_id = fields.Many2one(comodel_name='product.product', + domain=[ + ('available_in_pos', '=', True)], string='Point Product', help='Product that represents a point ' 'that is sold by the customer') diff --git a/pos_loyalty/models/loyalty_rule.py b/pos_loyalty/models/loyalty_rule.py index 9f3b43bb..85caafe6 100644 --- a/pos_loyalty/models/loyalty_rule.py +++ b/pos_loyalty/models/loyalty_rule.py @@ -1,6 +1,6 @@ -# -*- coding: utf-8 -*- # Copyright 2004-2010 OpenERP SA # Copyright 2017 RGB Consulting S.L. (https://www.rgbconsulting.com) +# Copyright 2018 Lambda IS DOOEL # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from odoo import fields, models @@ -26,6 +26,7 @@ class LoyaltyRule(models.Model): help='The Loyalty Program this rule ' 'belongs to') product_id = fields.Many2one(comodel_name='product.product', + domain=[('available_in_pos', '=', True)], string='Target Product', help='The product affected by this rule') category_id = fields.Many2one(comodel_name='pos.category', diff --git a/pos_loyalty/models/pos_config.py b/pos_loyalty/models/pos_config.py index bf91f5e5..b39e549d 100644 --- a/pos_loyalty/models/pos_config.py +++ b/pos_loyalty/models/pos_config.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2004-2010 OpenERP SA # Copyright 2017 RGB Consulting S.L. (https://www.rgbconsulting.com) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). diff --git a/pos_loyalty/models/pos_order.py b/pos_loyalty/models/pos_order.py index 9645c789..bc644065 100644 --- a/pos_loyalty/models/pos_order.py +++ b/pos_loyalty/models/pos_order.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2004-2010 OpenERP SA # Copyright 2017 RGB Consulting S.L. (https://www.rgbconsulting.com) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). diff --git a/pos_loyalty/models/pos_order_line.py b/pos_loyalty/models/pos_order_line.py new file mode 100644 index 00000000..fe9182f5 --- /dev/null +++ b/pos_loyalty/models/pos_order_line.py @@ -0,0 +1,20 @@ +# Copyright 2018 Lambda IS DOOEL +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, models + + +class PosOrderLine(models.Model): + _inherit = 'pos.order.line' + + @api.model + def _order_line_fields(self, line, session_id=None): + line = super(PosOrderLine, self)._order_line_fields( + line, session_id=session_id) + if line and 'reward_id' in line[2]: + # Delete the key since field doesn't exist + # and raises a warning in the logs. + # TODO: add field and remove this if data will be + # used on server, example in report / widget. + del line[2]['reward_id'] + return line diff --git a/pos_loyalty/models/res_partner.py b/pos_loyalty/models/res_partner.py index d678db55..60350f04 100644 --- a/pos_loyalty/models/res_partner.py +++ b/pos_loyalty/models/res_partner.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2004-2010 OpenERP SA # Copyright 2017 RGB Consulting S.L. (https://www.rgbconsulting.com) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). diff --git a/pos_loyalty/readme/CONFIGURE.rst b/pos_loyalty/readme/CONFIGURE.rst new file mode 100644 index 00000000..7c7dac48 --- /dev/null +++ b/pos_loyalty/readme/CONFIGURE.rst @@ -0,0 +1,4 @@ +To use this module, you need to: + +* Go to *Point of Sale > Configuration > Loyalty Programs* and define a new loyalty program with specific rules and rewards. +* Assign the loyalty program to the desired Point of Sale. diff --git a/pos_loyalty/readme/CONTRIBUTORS.rst b/pos_loyalty/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000..4ec3dbcc --- /dev/null +++ b/pos_loyalty/readme/CONTRIBUTORS.rst @@ -0,0 +1,3 @@ +* RGB Consulting SL (http://www.rgbconsulting.com) +* Forward-port from Odoo SA saas-6 branch +* Kiril Vangelovski diff --git a/pos_loyalty/readme/DESCRIPTION.rst b/pos_loyalty/readme/DESCRIPTION.rst new file mode 100644 index 00000000..8bb9f2af --- /dev/null +++ b/pos_loyalty/readme/DESCRIPTION.rst @@ -0,0 +1,6 @@ +This module allows you to define a loyalty program in the point of sale, +where the customers earn loyalty points and get rewards. + +This module is a forward-port to v10 of the pos_loyalty module from Odoo's +saas-6 branch. +The functionality was moved to the Enterprise edition in later versions. diff --git a/pos_loyalty/readme/USAGE.rst b/pos_loyalty/readme/USAGE.rst new file mode 100644 index 00000000..741eecfc --- /dev/null +++ b/pos_loyalty/readme/USAGE.rst @@ -0,0 +1,11 @@ +The Loyalty Program defines rules for acquiring points and rewards on which they can be spent. + +Rules can be defined globally for all products (fields on loyalty.program) and / or rules that are applied only on specific product or PoS category (loyalty.rule records) on a *points per product sold* or *points per currency spent* basis. The specific rules (loyalty.rule) can be defined as cumulative, which means that they will be aggregated with other matching rules (loyalty.rule records and loyalty.program fields). In the case of non-cumulative rules only the points from that one matching rule are used. Additionally, *fixed points per order* can be added which are applied regardless of whether or not cumulative or non-cumulative rules were applied also. + +Rewards can be of three types: + +* *Gift* - give a single unit of product for free +* *Discount* - give a discount to the whole order. It should be added at the end of the order so that the correct total price is used. +* *Resale* - allow for customer to sell back his earned points. These are calculated by setting the price on the Resale product (*resale_product.list_price* * *customer.loyalty_points*) + +All rewards can define how many points they cost (point_cost) and how many are needed so that the customer can become eligable for the reward (minimum_points). for Gift and Discount rewards minimum_points are considered only if they are greater then the point_cost for that reward (minimum_points > point_cost). For Resale products only minimum_points can be used. diff --git a/pos_loyalty/static/description/index.html b/pos_loyalty/static/description/index.html new file mode 100644 index 00000000..55bd7ebb --- /dev/null +++ b/pos_loyalty/static/description/index.html @@ -0,0 +1,449 @@ + + + + + + +Loyalty Program + + + +
+

Loyalty Program

+ + +

Beta License: AGPL-3 OCA/pos Translate me on Weblate Try me on Runbot

+

This module allows you to define a loyalty program in the point of sale, +where the customers earn loyalty points and get rewards.

+

This module is a forward-port to v10 of the pos_loyalty module from Odoo’s +saas-6 branch. +The functionality was moved to the Enterprise edition in later versions.

+

Table of contents

+ +
+

Configuration

+

To use this module, you need to:

+
    +
  • Go to Point of Sale > Configuration > Loyalty Programs and define a new loyalty program with specific rules and rewards.
  • +
  • Assign the loyalty program to the desired Point of Sale.
  • +
+
+
+

Usage

+

The Loyalty Program defines rules for acquiring points and rewards on which they can be spent.

+

Rules can be defined globally for all products (fields on loyalty.program) and / or rules that are applied only on specific product or PoS category (loyalty.rule records) on a points per product sold or points per currency spent basis. The specific rules (loyalty.rule) can be defined as cumulative, which means that they will be aggregated with other matching rules (loyalty.rule records and loyalty.program fields). In the case of non-cumulative rules only the points from that one matching rule are used. Additionally, fixed points per order can be added which are applied regardless of whether or not cumulative or non-cumulative rules were applied also.

+

Rewards can be of three types:

+
    +
  • Gift - give a single unit of product for free
  • +
  • Discount - give a discount to the whole order. It should be added at the end of the order so that the correct total price is used.
  • +
  • Resale - allow for customer to sell back his earned points. These are calculated by setting the price on the Resale product (resale_product.list_price * customer.loyalty_points)
  • +
+

All rewards can define how many points they cost (point_cost) and how many are needed so that the customer can become eligable for the reward (minimum_points). for Gift and Discount rewards minimum_points are considered only if they are greater then the point_cost for that reward (minimum_points > point_cost). For Resale products only minimum_points can be used.

+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • OpenERP SA
  • +
  • RGB Consulting SL
  • +
  • Lambda IS
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/pos project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/pos_loyalty/static/src/js/tests.js b/pos_loyalty/static/src/js/tests.js new file mode 100644 index 00000000..3e5514a0 --- /dev/null +++ b/pos_loyalty/static/src/js/tests.js @@ -0,0 +1,163 @@ +// Copyright 2004-2018 Odoo SA +// Copyright 2018 Lambda IS DOOEL +// License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +odoo.define('pos_loyalty.tour.test_pos_loyalty', function (require) { + "use strict"; + + // Some of the steps are taken from the pos_basic_order tour in point_of_sale. + // Added additional ones necessary for testing the rewards. + + var Tour = require("web_tour.tour"); + + function add_customer(customer_name) { + return [{ + content: 'open customer screen', + trigger: '.button.set-customer', + }, { + content: 'choose customer ' + customer_name, + trigger: 'table.client-list tbody.client-list-contents tr.client-line td:contains("' + customer_name + '")', + }, { + content: 'select customer ' + customer_name, + trigger: '.button.next:contains("Set Customer")', + }, { + content: 'Check if customer ' + customer_name + ' is added', + trigger: '.button.set-customer:contains("' + customer_name + '")', + run: function () {}, // it's a check + }]; + } + + function add_reward(reward_name) { + return [{ + content: 'open rewards screen', + trigger: '.control-button:contains("Rewards")', + }, { + content: 'choose reward', + trigger: '.selection-item:contains("' + reward_name + '")', + }] + } + + function add_product_to_order(product_name) { + return [{ + content: 'buy ' + product_name, + trigger: '.product-list .product-name:contains("' + product_name + '")', + }, { + content: 'the ' + product_name + ' have been added to the order', + trigger: '.order .product-name:contains("' + product_name + '")', + run: function () {}, // it's a check + }]; + } + + function verify_order_product(product_name) { + return [{ + content: 'check if ' + product_name + ' is in order', + trigger: '.orderline .product-name:contains("' + product_name + '")', + run: function () {}, // it's a check + }] + } + + function generate_keypad_steps(amount_str, keypad_selector) { + var i, steps = [], current_char; + for (i = 0; i < amount_str.length; ++i) { + current_char = amount_str[i]; + steps.push({ + content: 'press ' + current_char + ' on payment keypad', + trigger: keypad_selector + ' .input-button:contains("' + current_char + '"):visible' + }); + } + + return steps; + } + + function generate_payment_screen_keypad_steps(amount_str) { + return generate_keypad_steps(amount_str, '.payment-numpad'); + } + + function generate_product_screen_keypad_steps(amount_str) { + return generate_keypad_steps(amount_str, '.numpad'); + } + + function verify_order_total(total_str) { + return [{ + content: 'order total contains ' + total_str, + trigger: '.order .total .value:contains("' + total_str + '")', + run: function () {}, // it's a check + }]; + } + + function goto_payment_screen_and_select_payment_method() { + return [{ + content: "go to payment screen", + trigger: '.button.pay', + }, { + content: "pay with cash", + trigger: '.paymentmethod:contains("Cash")', + }]; + } + + function finish_order() { + return [{ + content: "validate the order", + trigger: '.button.next:visible', + }, { + content: "verify that the order is being sent to the backend", + trigger: ".js_connecting:visible", + run: function () {}, // it's a check + }, { + content: "verify that the order has been succesfully sent to the backend", + trigger: ".js_connected:visible", + run: function () {}, // it's a check + }, { + content: "next order", + trigger: '.button.next:visible', + }]; + } + + var steps = [{ + content: 'waiting for loading to finish', + trigger: '.o_main_content:has(.loader:hidden)', + run: function () {}, // it's a check + }]; + + steps = steps.concat(add_customer('Agrolait')); + steps = steps.concat(add_product_to_order('Peaches')); + steps = steps.concat(verify_order_total('5.10')); + + steps = steps.concat(add_product_to_order('Peaches')); // buy another kg of peaches + steps = steps.concat(verify_order_total('10.20')); + steps = steps.concat(goto_payment_screen_and_select_payment_method()); + steps = steps.concat(generate_payment_screen_keypad_steps("12.20")); + + steps = steps.concat([{ + content: "verify tendered", + trigger: '.col-tendered:contains("12.20")', + run: function () {}, // it's a check + }, { + content: "verify change", + trigger: '.col-change:contains("2.00")', + run: function () {}, // it's a check + }]); + + steps = steps.concat(finish_order()); + + Tour.register('test_pos_loyalty_acquire_points', { test: true, url: '/pos/web' }, steps); + + steps = [{ + content: 'waiting for loading to finish', + trigger: '.o_main_content:has(.loader:hidden)', + run: function () {}, // it's a check + }]; + steps = steps.concat(add_customer('Agrolait')); + steps = steps.concat(add_reward('Free Peaches')); + steps = steps.concat(verify_order_product('Peaches')); + steps = steps.concat(verify_order_total('0.00')); + steps = steps.concat(goto_payment_screen_and_select_payment_method()); + steps = steps.concat([{ + content: "verify tendered", + trigger: '.col-tendered:contains("0.00")', + run: function () {}, // it's a check + }]); + steps = steps.concat(finish_order()); + + Tour.register('test_pos_loyalty_spend_points', { test: true, url: '/pos/web' }, steps); +}) diff --git a/pos_loyalty/tests/__init__.py b/pos_loyalty/tests/__init__.py new file mode 100644 index 00000000..09e18a01 --- /dev/null +++ b/pos_loyalty/tests/__init__.py @@ -0,0 +1,2 @@ + +from . import test_pos_loyalty diff --git a/pos_loyalty/tests/test_pos_loyalty.py b/pos_loyalty/tests/test_pos_loyalty.py new file mode 100644 index 00000000..1a50dd1b --- /dev/null +++ b/pos_loyalty/tests/test_pos_loyalty.py @@ -0,0 +1,74 @@ +# Copyright 2004-2018 Odoo SA +# Copyright 2018 Lambda IS DOOEL +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo.api import Environment +from odoo.tests import HttpCase + + +class TestPOSLoyalty(HttpCase): + + def test_pos_loyalty(self): + cr = self.registry.cursor() + assert cr == self.registry.test_cr + env = Environment(cr, self.uid, {}) + main_pos_config = env.ref('point_of_sale.pos_config_main') + target_product = env.ref('point_of_sale.peche') + free_product = env.ref('point_of_sale.Onions') + customer = env.ref('base.res_partner_2') + loyalty_program = env['loyalty.program'].create({ + 'name': 'foo', + 'rule_ids': [(0, 0, { + 'name': 'Peaches', + 'type': 'product', + 'product_id': target_product.id, + 'pp_product': 10, + })], + 'reward_ids': [(0, 0, { + 'name': 'Free Peaches', + 'type': 'gift', + 'gift_product_id': target_product.id, + 'point_cost': 20, + 'minimum_points': 20, + }), (0, 0, { + 'name': 'Free Onions', + 'type': 'gift', + 'gift_product_id': free_product.id, + 'point_cost': 20, + 'minimum_points': 20, + })] + }) + main_pos_config.write({'loyalty_id': loyalty_program.id}) + main_pos_config.open_session_cb() + + # needed because tests are run before the module is marked as + # installed. In js web will only load qweb coming from modules + # that are returned by the backend in module_boot. Without + # this you end up with js, css but no qweb. + env['ir.module.module'].search( + [('name', '=', 'pos_loyalty')], limit=1).state = 'installed' + + cr.release() + + # Process an order with 2kg of Peaches which should + # add 20 loyalty points + self.phantom_js("/pos/web", + "odoo.__DEBUG__.services['web_tour.tour'].run(" + "'test_pos_loyalty_acquire_points')", + "odoo.__DEBUG__.services['web_tour.tour'].tours" + ".test_pos_loyalty_acquire_points.ready", + login="admin") + + self.assertEqual(customer.loyalty_points, 20) + + # Spend 20 loyalty points on "Free Peaches" reward + self.phantom_js("/pos/web", + "odoo.__DEBUG__.services['web_tour.tour'].run(" + "'test_pos_loyalty_spend_points')", + "odoo.__DEBUG__.services['web_tour.tour'].tours" + ".test_pos_loyalty_spend_points.ready", + login="admin") + + customer_points = customer.read( + ['loyalty_points'])[0]['loyalty_points'] + self.assertEqual(customer_points, 0) diff --git a/pos_loyalty/views/pos_config_view.xml b/pos_loyalty/views/pos_config_view.xml index 525f19f2..8988a056 100644 --- a/pos_loyalty/views/pos_config_view.xml +++ b/pos_loyalty/views/pos_config_view.xml @@ -1,14 +1,22 @@ - + pos.config.form pos.config - + - - - - + +
+
+
+