diff --git a/vouchers_pos/README.rst b/vouchers_pos/README.rst new file mode 100644 index 000000000..962fc88f4 --- /dev/null +++ b/vouchers_pos/README.rst @@ -0,0 +1,36 @@ + +Coupons & Vouchers in Point of Sale V13 +======================================= + +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/12.0/setup/install.html +- Install our custom addon + +Credits +======= +* Cybrosys Techno Solutions + +Author +------ + +Developers: v10.0 LINTO CT + v11.0 LINTO CT + v12.0 Kavya Raveendran + v13.0 Varsha Vivek + +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..10eb053b0 --- /dev/null +++ b/vouchers_pos/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author:Cybrosys Technologies() + +# 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..50763e4a6 --- /dev/null +++ b/vouchers_pos/__manifest__.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2019-TODAY Cybrosys Technologies(). +# Author:Cybrosys Technologies() + +# 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': '13.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..186abecc4 --- /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..33b1041e7 --- /dev/null +++ b/vouchers_pos/doc/RELEASE_NOTES.md @@ -0,0 +1,7 @@ +## Module + +#### 28.11.2019 +#### Version 13.0.1.0.0 +##### ADD +- Initial commit + 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..c2159602f --- /dev/null +++ b/vouchers_pos/models/gift_voucher.py @@ -0,0 +1,108 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2019-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, help='The expiry date of Voucher.') + + +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", help='Limit to a Single Partner') + limit = fields.Integer(string="Total Available For Each User", default=1, help='Total Available For Each User') + total_avail = fields.Integer(string="Total Available", default=1) + + voucher_val = fields.Float(string="Voucher Value", help='The amount for the voucher.') + 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.png b/vouchers_pos/static/description/banner.png new file mode 100644 index 000000000..cf274c0bb Binary files /dev/null and b/vouchers_pos/static/description/banner.png differ diff --git a/vouchers_pos/static/description/icon.png b/vouchers_pos/static/description/icon.png new file mode 100644 index 000000000..5bd2f0412 Binary files /dev/null and b/vouchers_pos/static/description/icon.png differ diff --git a/vouchers_pos/static/description/images/checked.png b/vouchers_pos/static/description/images/checked.png new file mode 100644 index 000000000..578cedb80 Binary files /dev/null and b/vouchers_pos/static/description/images/checked.png differ diff --git a/vouchers_pos/static/description/images/cybrosys.png b/vouchers_pos/static/description/images/cybrosys.png new file mode 100644 index 000000000..d76b5bafb Binary files /dev/null and b/vouchers_pos/static/description/images/cybrosys.png differ diff --git a/vouchers_pos/static/description/images/voucher_pos.png b/vouchers_pos/static/description/images/voucher_pos.png new file mode 100644 index 000000000..68544e760 Binary files /dev/null and b/vouchers_pos/static/description/images/voucher_pos.png differ diff --git a/vouchers_pos/static/description/images/vouchers-pos-1.png b/vouchers_pos/static/description/images/vouchers-pos-1.png new file mode 100644 index 000000000..cc523e2c8 Binary files /dev/null and b/vouchers_pos/static/description/images/vouchers-pos-1.png differ diff --git a/vouchers_pos/static/description/images/vouchers-pos-2.png b/vouchers_pos/static/description/images/vouchers-pos-2.png new file mode 100644 index 000000000..4d740a115 Binary files /dev/null and b/vouchers_pos/static/description/images/vouchers-pos-2.png differ diff --git a/vouchers_pos/static/description/images/vouchers-pos-3.png b/vouchers_pos/static/description/images/vouchers-pos-3.png new file mode 100644 index 000000000..04960b75b Binary files /dev/null and b/vouchers_pos/static/description/images/vouchers-pos-3.png differ diff --git a/vouchers_pos/static/description/images/vouchers-pos-4.png b/vouchers_pos/static/description/images/vouchers-pos-4.png new file mode 100644 index 000000000..472f6e902 Binary files /dev/null and b/vouchers_pos/static/description/images/vouchers-pos-4.png differ diff --git a/vouchers_pos/static/description/images/vouchers-pos-5.png b/vouchers_pos/static/description/images/vouchers-pos-5.png new file mode 100644 index 000000000..1ab626ee9 Binary files /dev/null and b/vouchers_pos/static/description/images/vouchers-pos-5.png differ diff --git a/vouchers_pos/static/description/images/vouchers-pos-6.png b/vouchers_pos/static/description/images/vouchers-pos-6.png new file mode 100644 index 000000000..a2eca23bf Binary files /dev/null and b/vouchers_pos/static/description/images/vouchers-pos-6.png differ diff --git a/vouchers_pos/static/description/index.html b/vouchers_pos/static/description/index.html new file mode 100644 index 000000000..26564a05f --- /dev/null +++ b/vouchers_pos/static/description/index.html @@ -0,0 +1,343 @@ +
cybrosys-logo
+
+
+
+

Vouchers and Coupons

+

Manage Gift Vouchers and Coupon Codes in Point of Sale

+
+

Key Highlights

+
    +
  • checkCreate gift vouchers for products.
  • +
  • check Create gift vouchers for point of sale category.
  • +
  • check Create global gift vouchers.
  • +
  • check Create and configure coupon codes.
  • +
  • check Apply coupon codes from point of sale.
  • +
  • check Coupon usage tracking.
  • +
+
+
+
+
+
+
+
+ +
+
+ +

Overview

+
+

+ Using the module, one can allow special discounts to their customers via using Gift Vouchers and Coupon codes in their point of sale. +

+
+
+ +

Vouchers and Coupons

+
+
    +
  • + checkCreate gift vouchers for products. +
  • +
  • + checkCreate gift vouchers for point of sale category. +
  • +
  • + checkCreate global gift vouchers. +
  • +
  • + checkCreate and configure coupon codes. +
  • +
  • + checkApply coupon codes from point of sale. +
  • +
  • + checkCoupon usage tracking. +
  • + +
+
+ +
+
+

Screenshots

+
+
+
+ +
+
+
+
+
+ +

Video

+
+
+

Vouchers and Coupons Demo

+ +
+ Cybrosys Cover Video +
+
+
+ +
+
    +
+
+
+
+
+
+
+

Suggested Products

+
+ +
+
+

Our Service

+
+ +
+
+
+

Our Industries

+
+ +
+
+
+ +
+
+

Trading

+

Easily procure and sell your products.

+
+
+
+
+ +
+
+

Manufacturing

+

Plan, track and schedule your operations.

+
+
+
+
+ +
+
+

Restaurant

+

Run your bar or restaurant methodical.

+
+
+
+
+ +
+
+

POS

+

Easy configuring and convivial selling.

+
+
+
+
+ +
+
+

E-commerce & Website

+

Mobile friendly, awe-inspiring product pages.

+
+
+
+
+ +
+
+

Hotel Management

+

An all-inclusive hotel management application.

+
+
+
+
+ +
+
+

Education

+

A Collaborative platform for educational management.

+
+
+
+
+ +
+
+

Service Management

+

Keep track of services and invoice accordingly.

+
+
+
+
+
+ +
+
+
+

Need Any Help?

+
+

If you have anything to share with us based on your use of this module, please let us know. We are ready to offer our support.

+
+

Email us

+

odoo@cybrosys.com / info@cybrosys.com

+
+
+

Contact Us

+ www.cybrosys.com +
+
+
+
+
+
+
+
+
+ +
+ + + + + + + +
+
+
+ \ No newline at end of file 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..ceaf7098f --- /dev/null +++ b/vouchers_pos/static/src/js/coupons.js @@ -0,0 +1,395 @@ +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 rpc = require('web.rpc'); + 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'], + }; + rpc.query({ + model: 'partner.coupon.pos', + method: 'update_history', + args: ['', temp] + }).then(function (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) { + console.log("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..b278d0996 --- /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 + + + 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..23b6d1778 --- /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 + + + tree,form + + + + Generate Gift Coupons + gift.coupon.pos + ir.actions.act_window + + + 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 @@ + + + + + +