diff --git a/vouchers_pos/README.rst b/vouchers_pos/README.rst new file mode 100644 index 000000000..824b0e684 --- /dev/null +++ b/vouchers_pos/README.rst @@ -0,0 +1,35 @@ +==================== +Coupons & Vouchers in Point of Sale V11 +==================== + +This module allow special discounts to your customers using Gift Vouchers and Coupon codes. + +Depends +======= +[point_of_sale] addon Odoo + + +Installation +============ + +- www.odoo.com/documentation/11.0/setup/install.html +- Install our custom addon + + +Credits +======= +* Cybrosys Techno Solutions + +Author +------ + +Developers: LINTO CT + + +Maintainer +---------- + +This module is maintained by Cybrosys Technologies. + +For support and more information, please visit https://www.cybrosys.com. + diff --git a/vouchers_pos/__init__.py b/vouchers_pos/__init__.py new file mode 100644 index 000000000..6cbc024eb --- /dev/null +++ b/vouchers_pos/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author:LINTO CT() + +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +################################################################################### + +from. import models diff --git a/vouchers_pos/__manifest__.py b/vouchers_pos/__manifest__.py new file mode 100644 index 000000000..42e136541 --- /dev/null +++ b/vouchers_pos/__manifest__.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author:LINTO CT() + +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +################################################################################### +{ + 'name': 'Coupons & Vouchers in Point of Sale', + 'version': '11.0.1.0.0', + 'category': 'Point of Sale', + 'summary': 'Manage Point of Sale Vouchers & Coupon Codes', + 'author': 'Cybrosys Techno Solutions', + 'website': "https://www.cybrosys.com", + 'company': 'Cybrosys Techno Solutions', + 'depends': ['point_of_sale'], + 'data': [ + 'data/product_data.xml', + 'views/gift_voucher.xml', + 'views/applied_coupons.xml', + 'views/pos_template.xml', + 'security/ir.model.access.csv' + ], + 'qweb': ['static/src/xml/coupons.xml'], + 'images': ['static/description/banner.jpg'], + 'license': 'AGPL-3', + 'installable': True, + 'application': False, + 'auto_install': False, +} diff --git a/vouchers_pos/data/product_data.xml b/vouchers_pos/data/product_data.xml new file mode 100644 index 000000000..660a0685c --- /dev/null +++ b/vouchers_pos/data/product_data.xml @@ -0,0 +1,11 @@ + + + + Gift-Coupon + Gift-Coupon + True + service + + + + diff --git a/vouchers_pos/doc/RELEASE_NOTES.md b/vouchers_pos/doc/RELEASE_NOTES.md new file mode 100644 index 000000000..06961ecfa --- /dev/null +++ b/vouchers_pos/doc/RELEASE_NOTES.md @@ -0,0 +1,4 @@ +## Module + +#### 11.01.2019 +#### Version 11.0.1.0.0 diff --git a/vouchers_pos/models/__init__.py b/vouchers_pos/models/__init__.py new file mode 100644 index 000000000..84646df3e --- /dev/null +++ b/vouchers_pos/models/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author:LINTO CT() + +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +################################################################################### + +from . import gift_voucher diff --git a/vouchers_pos/models/gift_voucher.py b/vouchers_pos/models/gift_voucher.py new file mode 100644 index 000000000..3b3eb6c0c --- /dev/null +++ b/vouchers_pos/models/gift_voucher.py @@ -0,0 +1,109 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author:LINTO CT() + +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +################################################################################### +import string +import random +from odoo import models, fields, api, _ +from odoo.exceptions import UserError + + +class GiftVoucherPos(models.Model): + _name = 'gift.voucher.pos' + + name = fields.Char(string="Name", required=True) + voucher_type = fields.Selection( + selection=[ + ('product', 'Product'), + ('category', 'POS Category'), + ('all', 'All Products'), + ], string="Applicable on ", default='product' + ) + product_id = fields.Many2one('product.product', string="Product") + product_categ = fields.Many2one('pos.category', string="Product Category") + min_value = fields.Integer(string="Minimum Voucher Value", required=True) + max_value = fields.Integer(string="Maximum Voucher Value", required=True) + expiry_date = fields.Date(string="Expiry Date", required=True) + + +class GiftCouponPos(models.Model): + _name = 'gift.coupon.pos' + + def get_code(self): + size = 7 + chars = string.ascii_uppercase + string.digits + return ''.join(random.choice(chars) for _ in range(size)) + + _sql_constraints = [ + ('name_uniq', 'unique (code)', "Code already exists !"), + ] + + name = fields.Char(string="Name", required=True) + code = fields.Char(string="Code", default=get_code) + voucher = fields.Many2one('gift.voucher.pos', string="Voucher", required=True) + start_date = fields.Date(string="Start Date") + end_date = fields.Date(string="End Date") + partner_id = fields.Many2one('res.partner', string="Limit to a Single Partner") + limit = fields.Integer(string="Total Available For Each User", default=1) + total_avail = fields.Integer(string="Total Available", default=1) + + voucher_val = fields.Float(string="Voucher Value") + type = fields.Selection([ + ('fixed', 'Fixed Amount'), + ('percentage', 'Percentage'), + ], store=True, default='fixed') + + @api.onchange('voucher_val') + def check_val(self): + if self.voucher_val > self.voucher.max_value or self.voucher_val < self.voucher.min_value: + raise UserError(_("Please check the voucher value")) + + +class CouponPartnerPos(models.Model): + _name = 'partner.coupon.pos' + + partner_id = fields.Many2one('res.partner', string="Partner") + coupon_pos = fields.Char(string="Coupon Applied") + number_pos = fields.Integer(string="Number of Times Used") + + def update_history(self, vals): + if vals: + h_obj = self.env['partner.coupon.pos'] + history = h_obj.search([('coupon_pos', '=', vals['coupon_pos']), + ('partner_id', '=', vals['partner_id'])], limit=1) + coupon = self.env['gift.coupon.pos'].search([('code', '=', vals['coupon_pos'])], limit=1) + if history: + history.number_pos += 1 + coupon.total_avail -= 1 + else: + coupon.total_avail -= 1 + rec = { + 'partner_id': vals['partner_id'], + 'number_pos': 1, + 'coupon_pos': vals['coupon_pos'] + } + h_obj.create(rec) + return True + + +class PartnerExtendedPos(models.Model): + _inherit = 'res.partner' + + applied_coupon_pos = fields.One2many('partner.coupon.pos', 'partner_id', string="Coupons Applied From POS") diff --git a/vouchers_pos/security/ir.model.access.csv b/vouchers_pos/security/ir.model.access.csv new file mode 100644 index 000000000..be5525444 --- /dev/null +++ b/vouchers_pos/security/ir.model.access.csv @@ -0,0 +1,7 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +voucher_mgr,access_voucher_mgr,vouchers_pos.model_gift_voucher_pos,point_of_sale.group_pos_manager,1,1,1,1 +coupon_mgr,access_coupon_mgr,vouchers_pos.model_gift_coupon_pos,point_of_sale.group_pos_manager,1,1,1,1 +partner_coupon_mgr,access_partner_coupon_mgr,vouchers_pos.model_partner_coupon_pos,point_of_sale.group_pos_manager,1,1,1,1 +voucher_usr,access_voucher_usr,vouchers_pos.model_gift_voucher_pos,point_of_sale.group_pos_user,1,0,0,0 +coupon_usr,access_coupon_usr,vouchers_pos.model_gift_coupon_pos,point_of_sale.group_pos_user,1,0,0,0 +partner_coupon_usr,access_partner_coupon_usr,vouchers_pos.model_partner_coupon_pos,point_of_sale.group_pos_user,1,0,0,0 diff --git a/vouchers_pos/static/description/banner.jpg b/vouchers_pos/static/description/banner.jpg new file mode 100644 index 000000000..384d5d6c6 Binary files /dev/null and b/vouchers_pos/static/description/banner.jpg differ diff --git a/vouchers_pos/static/description/coupon-button-pos.png b/vouchers_pos/static/description/coupon-button-pos.png new file mode 100644 index 000000000..be74d9bc4 Binary files /dev/null and b/vouchers_pos/static/description/coupon-button-pos.png differ diff --git a/vouchers_pos/static/description/coupon-form.png b/vouchers_pos/static/description/coupon-form.png new file mode 100644 index 000000000..ee42e3541 Binary files /dev/null and b/vouchers_pos/static/description/coupon-form.png differ diff --git a/vouchers_pos/static/description/coupon-menu-pos.png b/vouchers_pos/static/description/coupon-menu-pos.png new file mode 100644 index 000000000..4764a9d5c Binary files /dev/null and b/vouchers_pos/static/description/coupon-menu-pos.png differ diff --git a/vouchers_pos/static/description/coupon-verified.png b/vouchers_pos/static/description/coupon-verified.png new file mode 100644 index 000000000..e07ea4d94 Binary files /dev/null and b/vouchers_pos/static/description/coupon-verified.png differ diff --git a/vouchers_pos/static/description/cybro_logo.png b/vouchers_pos/static/description/cybro_logo.png new file mode 100644 index 000000000..bb309114c Binary files /dev/null and b/vouchers_pos/static/description/cybro_logo.png differ diff --git a/vouchers_pos/static/description/history.png b/vouchers_pos/static/description/history.png new file mode 100644 index 000000000..c52008589 Binary files /dev/null and b/vouchers_pos/static/description/history.png differ diff --git a/vouchers_pos/static/description/icon.png b/vouchers_pos/static/description/icon.png new file mode 100644 index 000000000..df9234a31 Binary files /dev/null and b/vouchers_pos/static/description/icon.png differ diff --git a/vouchers_pos/static/description/index.html b/vouchers_pos/static/description/index.html new file mode 100644 index 000000000..55d1557a4 --- /dev/null +++ b/vouchers_pos/static/description/index.html @@ -0,0 +1,393 @@ +
+
+

+ Vouchers and Coupons +

+

+ Manage Gift Vouchers and Coupon Codes in Point of Sale +

+
+ Cybrosys Technologies +
+ +
+ cybrosys technologies
+
+ +
+
+
+
+

+ Overview +

+

+ With this module, you can allow special discounts to your customers using Gift Vouchers and Coupon codes + in point of sale. +

+
+
+
+
+

+ Features +

+

+ + Create gift vouchers for products. +

+

+ + Create gift vouchers for point of sale category. +

+

+ + Create global gift vouchers. +

+

+ + Create and configure coupon codes. +

+

+ + Apply coupon codes from point of sale. +

+

+ + Coupon usage tracking. +

+
+
+
+
+

+ Screenshots +

+

+ + Coupon menu +

+
    +
  • + After installing this module, three menus will be created under + point of sale. +
  • +
  • + You can use these menus to create, configure and track vouchers, coupons and their usage. +
  • +
+
+ +
+

+ + Create vouchers +

+
    +
  • + This is the form for creating vouchers. +
  • +
  • + You can create vouchers for a single product, pos category and + for all the products. +
  • +
+
+ +
+

+ + Apply Coupons +

+
    +
  • + The 'Coupons' button in point of sale can be used to enter the coupon code. +
  • +
+
+ +
+
+ +
+
+ +
+

+ + Coupon Tracking +

+
    +
  • + Go to the 'Coupon History' menu under 'Vouchers and Coupons' for coupon tracking. +
  • +
+
+ +
+
+
+
+
+

+ Our Services +

+
+ + + +
+ +
+ + + +
+

+ + Odoo Support +

+ +
+ +
+
+
+
+
+

+ Our Industries +

+
+
+ +
+
+ + Odoo Industry + +
+
+
+

+ + Trading + +

+

+ Easily procure and sell your products. +

+
+ +
+
+ +
+
+ + Odoo Industry + +
+
+
+

+ + Manufacturing +

+

+ Plan, track and schedule your operations. +

+
+ +
+
+ +
+
+ + Odoo Industry + +
+
+
+

+ + Restaurant +

+

+ Run your bar or restaurant methodical. +

+
+ +
+
+ +
+
+ + Odoo Industry + +
+
+
+

+ + POS +

+

+ Easy configuring and convivial selling. +

+
+ +
+
+ +
+
+ + Odoo Industry + +
+
+
+

+ + E-commerce & Website +

+

+ Mobile friendly, awe-inspiring product pages. +

+
+
+
+ +
+
+ + Odoo Industry + +
+
+
+

+ + Hotel Management +

+

+ An all-inclusive hotel management application. +

+
+
+
+ +
+
+ + Odoo Industry + +
+
+
+

+ + Education +

+

+ A Collaborative platform for educational management. +

+
+
+
+ +
+
+ + Odoo Industry + +
+
+
+

+ + Service Management +

+

+ Keep track of services and invoice accordingly. +

+
+
+
+
+
+
+ +
+ + + + diff --git a/vouchers_pos/static/description/verify-coupon.png b/vouchers_pos/static/description/verify-coupon.png new file mode 100644 index 000000000..e0fb88be9 Binary files /dev/null and b/vouchers_pos/static/description/verify-coupon.png differ diff --git a/vouchers_pos/static/description/voucher-form.png b/vouchers_pos/static/description/voucher-form.png new file mode 100644 index 000000000..7d7e02cce Binary files /dev/null and b/vouchers_pos/static/description/voucher-form.png differ diff --git a/vouchers_pos/static/src/css/pos.css b/vouchers_pos/static/src/css/pos.css new file mode 100644 index 000000000..552a6910b --- /dev/null +++ b/vouchers_pos/static/src/css/pos.css @@ -0,0 +1,23 @@ +div.coupons{ + color: seagreen; +} +button.validate_coupon{ + height: 38px; + vertical-align: middle; + background-color: aliceblue; + border-radius: 12px; +} +/*.pos .order-pricelist{*/ + /*color: black;*/ + /*margin-top: 2%;*/ + /*width: 200px;*/ +/*}*/ +/*.pos .order-pricelist-label{*/ + /*color: #e9f6e4;*/ + /*box-sizing: border-box;*/ + /*-moz-box-sizing: border-box;*/ + /*height: 85px !important;*/ + /*font-size: initial;*/ + /*vertical-align: middle;*/ + /*text-align: center;*/ +/*}*/ \ No newline at end of file diff --git a/vouchers_pos/static/src/js/coupons.js b/vouchers_pos/static/src/js/coupons.js new file mode 100644 index 000000000..a1ee8ef18 --- /dev/null +++ b/vouchers_pos/static/src/js/coupons.js @@ -0,0 +1,391 @@ +odoo.define("vouchers_pos.coupons", function (require) { + "use strict"; + var core = require('web.core'); + var pos_screen = require('point_of_sale.screens'); + var PosBaseWidget = require('point_of_sale.BaseWidget'); + var pos_model = require('point_of_sale.models'); + var pos_popup = require('point_of_sale.popups'); + var gui = require('point_of_sale.gui'); + var models = pos_model.PosModel.prototype.models; + var PosModelSuper = pos_model.PosModel; + var OrderSuper = pos_model.Order; + var Model = require('web.BasicModel'); + var core = require('web.core'); + var _t = core._t; + var utils = require('web.utils'); + var round_pr = utils.round_precision; + + function find_coupon(code, coupons, vouchers) { + var coupon = []; + for(var i in coupons){ + if (coupons[i]['code'] == code){ + coupon.push(coupons[i]); + } + } + if(coupon.length > 0){ + for(var i in vouchers){ + if (vouchers[i]['id'] == coupon[0]['voucher'][0]){ + coupon.push(vouchers[i]); + return coupon; + } + } + } + return false + } + + function check_validity(coupon, applied_coupons, customer) { + // checking it is already used or not + for (var i in applied_coupons){ + if(applied_coupons[i]['coupon_pos'] == coupon[0]['code'] && applied_coupons[i]['partner_id'][0] == customer['id']){ + return applied_coupons[i]; + } + } + return false; + } + + function check_expiry(start, end) { + var today = moment().format('YYYY-MM-DD'); + if(start && end) { + if (today < start || today > end) + return false; + } + else if(start){ + if (today < start) + return false; + } + else if(end){ + if (today > end) + return false; + } + return true; + } + + function get_coupon_product(products) { + for (var i in products){ + if(products[i]['display_name'] == 'Gift-Coupon') + return products[i]['id']; + } + return false; + } + + // getting vouchers and coupons + models.push( + { + model: 'gift.voucher.pos', + fields: ['id', 'voucher_type', 'name', 'product_id', 'expiry_date', 'product_categ'], + loaded: function (self, vouchers) { + self.vouchers = vouchers; + }, + },{ + model: 'gift.coupon.pos', + fields: ['id', 'name', 'code', 'voucher', 'start_date', + 'end_date', 'partner_id', 'limit', 'total_avail', 'voucher_val', 'type'], + loaded: function (self, coupons) { + self.coupons = coupons; + }, + }, + { + model: 'partner.coupon.pos', + fields: ['partner_id', 'coupon_pos', 'number_pos'], + loaded: function (self, applied_coupon) { + self.applied_coupon = applied_coupon; + }, + } + ); + + var VoucherWidget = pos_screen.ActionButtonWidget.extend({ + template:"VoucherWidget", + init: function(parent) { + return this._super(parent); + }, + renderElement: function () { + var self = this; + this._super(); + this.$(".coupons").click(function () { + self.gui.show_popup('coupon',{ + 'title': _t('Enter your Coupon'), + }); + }); + }, + }); + + + pos_screen.ProductScreenWidget.include({ + start: function(){ + this._super(); + this.coupons = new VoucherWidget(this,{}); + this.coupons.replace(this.$('.placeholder-VoucherWidget')); + }, + }); + + var CouponPopupWidget = pos_popup.extend({ + template: 'CouponPopupWidget', + init: function(parent) { + this.coupon_product = null; + return this._super(parent); + }, + show: function(options){ + options = options || {}; + this._super(options); + if(!this.coupon_product) + this.coupon_product = get_coupon_product(this.pos.db.product_by_id); + this.flag = true; + this.coupon_status = []; + this.renderElement(); + this.$('input').focus(); + }, + click_confirm: function(){ + var value = this.$('input').val(); + this.gui.close_popup(); + if( this.options.confirm ){ + this.options.confirm.call(this,value); + } + }, + renderElement: function () { + this._super(); + var self = this; + + this.$(".validate_coupon").click(function () { + // checking the code entered + var current_order = self.pos.get_order(); + var coupon = $(".coupon_code").val(); + if (current_order.orderlines.models.length == 0){ + self.gui.show_popup('error',{ + 'title': _t('No products !'), + 'body': _t('You cannot apply coupon without products.'), + }); + } + else if(coupon){ + if(self.pos.get_client()){ + var customer = self.pos.get_client(); + var coupon_res = find_coupon(coupon, self.pos.coupons, self.pos.vouchers); + var flag = true; + // is there a coupon with this code which has balance above zero + if(coupon_res && coupon_res[0]['total_avail'] > 0){ + var applied_coupons = self.pos.applied_coupon; + // checking coupon status + var coupon_stat = check_validity(coupon_res, applied_coupons, customer); + // if this coupon was for a particular customer and is not used already + if(coupon_res[0]['partner_id'] && coupon_res[0]['partner_id'][0] != customer['id']){ + flag = false; + } + var today = moment().format('YYYY-MM-DD'); + // checking coupon balance and expiry + if(flag && coupon_stat && coupon_stat.number_pos < coupon_res[0]['limit'] && + today <= coupon_res[1]['expiry_date']){ + // checking coupon validity + flag = check_expiry(coupon_res[0]['start_date'], coupon_res[0]['end_date']); + } + // this customer has not used this coupon yet + else if(flag && !coupon_stat && today <= coupon_res[1]['expiry_date']){ + flag = check_expiry(coupon_res[0]['start_date'], coupon_res[0]['end_date']); + } + else{ + flag = false; + $(".coupon_status_p").text("Unable to apply coupon. Check coupon validity.!"); + } + } + else{ + flag = false; + $(".coupon_status_p").text("Invalid code or no coupons left. Please try again !!"); + } + if(flag){ + var val = coupon_res[0]['type'] == 'fixed' ? + coupon_res[0]['voucher_val'] : coupon_res[0]['voucher_val'] + "%"; + var obj = $(".coupon_status_p").text("voucher value is : "+val+" \n" + + " Do you want to proceed ? \n This operation cannot be reversed."); + obj.html(obj.html().replace(/\n/g,'
')); + var order = self.pos.get_order(); + order.set_coupon_value(coupon_res[0]); + } + self.flag = flag; + if(flag){ + $(".confirm-coupon").css("display", "block"); + } + else{ + var ob = $(".coupon_status_p").text("Invalid code or no coupons left. \nPlease check coupon validity.\n" + + "or check whether the coupon usage is limited to a particular customer."); + ob.html(ob.html().replace(/\n/g,'
')); + } + } + else{ + $(".coupon_status_p").text("Please select a customer !!"); + } + } + }); + this.$(".confirm-coupon").click(function () { + // verifying and applying coupon + if(self.flag){ + var order = self.pos.get_order(); + var lines = order ? order.orderlines : false; + if(order.coupon){ + self.gui.close_popup(); + self.gui.show_popup('error',{ + 'title': _t('Unable to apply coupon !'), + 'body': _t('Either coupon is already applied or you have not selected any products.'), + }); + } + else{ + if(lines.models.length > 0 && order.check_voucher_validy()) { + var product = self.pos.db.get_product_by_id(self.coupon_product); + var price = -1; + if (order.coupon_status['type'] == 'fixed') { + price *= order.coupon_status['voucher_val']; + } + if (order.coupon_status['type'] == 'percentage') { + price *= order.get_total_with_tax() * order.coupon_status['voucher_val'] / 100; + } + if ((order.get_total_with_tax - price) <= 0) { + self.gui.close_popup(); + self.gui.show_popup('error', { + 'title': _t('Unable to apply coupon !'), + 'body': _t('Coupon amount is too large to apply. The total amount cannot be negative'), + }); + } + else{ + order.add_product(product, {quantity: 1, price: price}); + order.coupon_applied(); + // updating coupon balance after applying coupon + var client = self.pos.get_client(); + var temp = { + 'partner_id': client['id'], + 'coupon_pos': order.coupon_status['code'], + }; + new Model('partner.coupon.pos').call('update_history', ['', temp]).done(function (result) { + // alert("result") + var applied = self.pos.applied_coupon; + var already_used = false; + for (var j in applied) { + if (applied[j]['partner_id'][0] == client['id'] && + applied[j]['coupon_pos'] == order.coupon_status['code']) { + applied[j]['number_pos'] += 1; + already_used = true; + break; + } + } + if (!already_used) { + var temp = { + 'partner_id': [client['id'], client['name']], + 'number_pos': 1, + 'coupon_pos': order.coupon_status['code'] + }; + self.pos.applied_coupon.push(temp); + } + }); + self.gui.close_popup(); + } + } + else{ + self.gui.close_popup(); + self.gui.show_popup('error',{ + 'title': _t('Unable to apply coupon !'), + 'body': _t('This coupon is not applicable on the products or category you have selected !'), + }); + } + } + } + else{ + self.gui.close_popup(); + self.gui.show_popup('error',{ + 'title': _t('Unable to apply coupon !'), + 'body': _t('Invalid Code or no Coupons left !'), + }); + } + }); + }, + }); + gui.define_popup({name:'coupon', widget: CouponPopupWidget}); + + // PosModel is extended to store vouchers, & coupon details + pos_model.PosModel = pos_model.PosModel.extend({ + initialize: function(session, attributes) { + PosModelSuper.prototype.initialize.call(this, session, attributes) + this.vouchers = ['']; + this.coupons = []; + this.applied_coupon = []; + }, + }); + + pos_model.Order = pos_model.Order.extend({ + initialize: function(attributes,options){ + this.coupon = false; + this.coupon_status = []; + return OrderSuper.prototype.initialize.call(this, attributes,options);; + }, + set_coupon_value: function (coupon) { + this.coupon_status = coupon; + return; + }, + coupon_applied: function () { + this.coupon = true; + this.export_as_JSON(); + return; + }, + check_voucher_validy: function () { + var self = this; + var order = self.pos.get_order(); + var vouchers = self.pos.vouchers; + var voucher = null; + for (var i in vouchers){ + if(vouchers[i]['id'] == self.coupon_status.voucher[0]){ + voucher = vouchers[i]; + break; + } + } + var flag ; + if(voucher){ + switch(voucher.voucher_type){ + case 'product': { + var lines = order.orderlines.models; + var products = {}; + for (var p in lines){ + products[lines[p].product.id] = null; + } + if(voucher.product_id[0] in products){ + flag = true; + } + else + flag = false; + break; + } + case 'category':{ + var lines = order.orderlines.models; + var category = {}; + for (var p in lines){ + if(lines[p].product.pos_categ_id){ + category[lines[p].product.pos_categ_id[0]] = null; + } + } + if(voucher.product_categ[0] in category){ + flag = true; + } + else + flag = false; + break; + } + case 'all': flag = true; break; + default: break; + } + } + return flag; + }, + export_as_JSON: function () { + var self = OrderSuper.prototype.export_as_JSON.call(this); + self.coupon = this.coupon; + self.coupon_status = this.coupon_status; + return self; + }, + init_from_JSON: function(json) { + this.coupon = json.coupon; + this.coupon_status = json.coupon_status; + OrderSuper.prototype.init_from_JSON.call(this, json); + }, + get_total_without_tax: function() { + var res = OrderSuper.prototype.get_total_without_tax.call(this); + var final_res = round_pr(this.orderlines.reduce((function(sum, orderLine) { + return sum + (orderLine.get_unit_price() * orderLine.get_quantity() * (1.0 - (orderLine.get_discount() / 100.0))); + }), 0), this.pos.currency.rounding); + return final_res; + }, + }); +}); \ No newline at end of file diff --git a/vouchers_pos/static/src/xml/coupons.xml b/vouchers_pos/static/src/xml/coupons.xml new file mode 100644 index 000000000..d0180d485 --- /dev/null +++ b/vouchers_pos/static/src/xml/coupons.xml @@ -0,0 +1,94 @@ + + + + +
+
+ Coupons +
+
+
+ + + + + + + + +
+
+
+ + + + +
\ No newline at end of file diff --git a/vouchers_pos/views/applied_coupons.xml b/vouchers_pos/views/applied_coupons.xml new file mode 100644 index 000000000..2ab56b2d2 --- /dev/null +++ b/vouchers_pos/views/applied_coupons.xml @@ -0,0 +1,47 @@ + + + + + applied_coupons_form + res.partner + + + + + + + + + + + + + + + + + + Gift Coupon History + partner.coupon.pos + + + + + + + + + + + Gift Coupons History + partner.coupon.pos + ir.actions.act_window + form + + tree + + + + + \ No newline at end of file diff --git a/vouchers_pos/views/gift_voucher.xml b/vouchers_pos/views/gift_voucher.xml new file mode 100644 index 000000000..c95b404a2 --- /dev/null +++ b/vouchers_pos/views/gift_voucher.xml @@ -0,0 +1,128 @@ + + + + + Gift Voucher + gift.voucher.pos + +
+ +

+ + + + + + + + + + + + +
+
+
+
+ + + Gift Voucher + gift.voucher.pos + + + + + + + + + + + + + Gift Coupon + gift.coupon.pos + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + + Gift Coupon + gift.coupon.pos + + + + + + + + + + + + + + + + Gift Vouchers + gift.voucher.pos + ir.actions.act_window + form + + tree,form + + + + Generate Gift Coupons + gift.coupon.pos + ir.actions.act_window + form + + tree,form + + + + + +
+
\ No newline at end of file diff --git a/vouchers_pos/views/pos_template.xml b/vouchers_pos/views/pos_template.xml new file mode 100644 index 000000000..e742ff567 --- /dev/null +++ b/vouchers_pos/views/pos_template.xml @@ -0,0 +1,11 @@ + + + + + +