Browse Source

[ADD]Initail Commit

pull/30/merge
SHEREEF PT 8 years ago
parent
commit
74437d1928
  1. 2
      project_subtask/__manifest__.py
  2. 1
      project_subtask/__manifest__.py~
  3. 4
      project_subtask/views/sub_task_type_view.xml
  4. 84
      project_subtask/views/sub_task_type_view.xml~
  5. 3
      vouchers_pos/__init__.py
  6. 46
      vouchers_pos/__manifest__.py
  7. 11
      vouchers_pos/data/product_data.xml
  8. 24
      vouchers_pos/models/__init__.py
  9. 110
      vouchers_pos/models/gift_voucher.py
  10. 7
      vouchers_pos/security/ir.model.access.csv
  11. BIN
      vouchers_pos/static/description/banner.jpg
  12. BIN
      vouchers_pos/static/description/coupon-button-pos.png
  13. BIN
      vouchers_pos/static/description/coupon-form.png
  14. BIN
      vouchers_pos/static/description/coupon-menu-pos.png
  15. BIN
      vouchers_pos/static/description/coupon-verified.png
  16. BIN
      vouchers_pos/static/description/cybro_logo.png
  17. BIN
      vouchers_pos/static/description/history.png
  18. BIN
      vouchers_pos/static/description/icon.png
  19. 154
      vouchers_pos/static/description/index.html
  20. BIN
      vouchers_pos/static/description/verify-coupon.png
  21. BIN
      vouchers_pos/static/description/voucher-form.png
  22. 23
      vouchers_pos/static/src/css/pos.css
  23. 390
      vouchers_pos/static/src/js/coupons.js
  24. 95
      vouchers_pos/static/src/xml/coupons.xml
  25. 47
      vouchers_pos/views/applied_coupons.xml
  26. 128
      vouchers_pos/views/gift_voucher.xml
  27. 11
      vouchers_pos/views/pos_template.xml

2
project_subtask/__manifest__.py

@ -22,7 +22,7 @@
##############################################################################
{
'name': 'Sub Tasks in Project',
'version': '10.0.2.0.0',
'version': '10.0.3.0.0',
'summary': """Implementation & Reports of Sub-Task in Project Module""",
'description': 'This module helps you to create sub task under a task',
'category': 'Project',

1
project_subtask/__manifest__.py~

@ -31,6 +31,7 @@
'website': "http://www.cybrosys.com",
'depends': ['base', 'project'],
'data': [
'security/ir.model.access.csv',
'views/project_view.xml',
'views/task_view.xml',
'views/sub_task.xml',

4
project_subtask/views/sub_task_type_view.xml

@ -78,7 +78,7 @@
</p>
</field>
</record>
<menuitem action="project.open_task_type_form" id="base.menu_project_config_project" name="Task Stages" parent="project.menu_project_config" sequence="3" groups="project.group_project_manager"/>
<menuitem action="project.open_task_type_form" id="project.menu_project_config_project" name="Task Stages" parent="project.menu_project_config" sequence="3" groups="project.group_project_manager"/>
<menuitem action="open_sub_task_type_form" id="menu_project_config_project_sub_task_stage" name="Sub Task Stages" parent="project.menu_project_config" sequence="4" groups="project.group_project_manager"/>
</data>
</odoo>
</odoo>

84
project_subtask/views/sub_task_type_view.xml~

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="sub_task_type_edit" model="ir.ui.view">
<field name="name">project.sub_task.type.form</field>
<field name="model">project.sub_task.type</field>
<field name="arch" type="xml">
<form string="Sub Task Stage">
<group>
<group>
<field name="name"/>
<field name="sequence" groups="base.group_no_one"/>
</group>
<group>
<field name="fold"/>
<field name="done_state"/>
<field name="cancel_state"/>
</group>
</group>
<group string="Projects &amp;Tasks using this stage">
<field name="task_ids" widget="many2many_tags"/>
</group>
<group string="Stage Description and Tooltips">
<p class="text-muted" colspan="2">
At each stage employees can block or make task/issue ready for next stage.
You can define here labels that will be displayed for the state instead
of the default labels.
</p>
<label for="legend_normal" string=" " class="oe_kanban_status oe_project_kanban_legend"/>
<field name="legend_normal" nolabel="1"/>
<label for="legend_blocked" string=" " class="oe_kanban_status oe_kanban_status_red oe_project_kanban_legend"/>
<field name="legend_blocked" nolabel="1"/>
<label for="legend_done" string=" " class="oe_kanban_status oe_kanban_status_green oe_project_kanban_legend"/>
<field name="legend_done" nolabel="1"/>
<p class="text-muted" colspan="2">
You can also give a tooltip about the use of the stars available in the kanban and form views.
</p>
<label for="legend_priority" string=" " class="fa fa-star fa-lg o_star_on oe_project_kanban_legend"/>
<field name="legend_priority" nolabel="1"/>
<p class="text-muted" colspan="2">
You can also add a description to help your coworkers understand the meaning and purpose of the stage.
</p>
<field name="description" placeholder="Add a description..." nolabel="1" colspan="2"/>
</group>
</form>
</field>
</record>
<record id="sub_task_type_tree" model="ir.ui.view">
<field name="name">project.sub_task.type.tree</field>
<field name="model">project.sub_task.type</field>
<field name="arch" type="xml">
<tree string="Task Stage">
<field name="sequence" widget="handle" groups="base.group_no_one"/>
<field name="name"/>
<field name="fold"/>
<field name="description"/>
</tree>
</field>
</record>
<record id="open_sub_task_type_form" model="ir.actions.act_window">
<field name="name">Stages</field>
<field name="res_model">project.sub_task.type</field>
<field name="view_type">form</field>
<field name="view_id" ref="sub_task_type_tree"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to add a stage in the task pipeline.
</p><p>
Define the steps that will be used in the project from the
creation of the task, up to the closing of the task or issue.
You will use these stages in order to track the progress in
solving a task or an issue.
</p>
</field>
</record>
<menuitem action="project.open_task_type_form" id="base.menu_project_config_project" name="Task Stages" parent="project.menu_project_config" sequence="3" groups="project.group_project_manager"/>
<menuitem action="open_sub_task_type_form" id="menu_project_config_project_sub_task_stage" name="Sub Task Stages" parent="project.menu_project_config" sequence="4" groups="project.group_project_manager"/>
</data>
</odoo>

3
vouchers_pos/__init__.py

@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
import models

46
vouchers_pos/__manifest__.py

@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
# Copyright (C) 2017-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
# Author: Linto C T(<https://www.cybrosys.com>)
# you can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# It is forbidden to publish, distribute, sublicense, or sell copies
# of the Software or modified copies of the Software.
#
# 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
# GENERAL PUBLIC LICENSE (LGPL v3) along with this program.
# If not, see <https://www.gnu.org/licenses/>.
#
##############################################################################
{
'name': 'Coupons & Vouchers in Point of Sale',
'version': '10.0.1.0',
'category': 'Point of Sale',
'summary': 'Manage Point of Sale Coupon Codes & Its Redeem Operations',
'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/*.xml'],
'images': ['static/description/banner.jpg'],
'license': 'AGPL-3',
'installable': True,
'application': False,
'auto_install': False,
}

11
vouchers_pos/data/product_data.xml

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo noupdate="1">
<record model="product.product" id="gift_product_pos">
<field name="name">Gift-Coupon</field>
<field name="display_name">Gift-Coupon</field>
<field name="avilable_in_pos">True</field>
<field name="type">service</field>
<field name="taxes_id"></field>
<field name="supplier_taxes_id"></field>
</record>
</odoo>

24
vouchers_pos/models/__init__.py

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
# Copyright (C) 2017-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
# Author: LINTO C T(<https://www.cybrosys.com>)
# you can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# It is forbidden to publish, distribute, sublicense, or sell copies
# of the Software or modified copies of the Software.
#
# 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
# GENERAL PUBLIC LICENSE (LGPL v3) along with this program.
# If not, see <https://www.gnu.org/licenses/>.
#
##############################################################################
import gift_voucher

110
vouchers_pos/models/gift_voucher.py

@ -0,0 +1,110 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
# Copyright (C) 2017-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
# Author: LINTO C T(<https://www.cybrosys.com>)
# you can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# It is forbidden to publish, distribute, sublicense, or sell copies
# of the Software or modified copies of the Software.
#
# 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
# GENERAL PUBLIC LICENSE (LGPL v3) along with this program.
# If not, see <https://www.gnu.org/licenses/>.
#
##############################################################################
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")

7
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
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 voucher_mgr access_voucher_mgr vouchers_pos.model_gift_voucher_pos point_of_sale.group_pos_manager 1 1 1 1
3 coupon_mgr access_coupon_mgr vouchers_pos.model_gift_coupon_pos point_of_sale.group_pos_manager 1 1 1 1
4 partner_coupon_mgr access_partner_coupon_mgr vouchers_pos.model_partner_coupon_pos point_of_sale.group_pos_manager 1 1 1 1
5 voucher_usr access_voucher_usr vouchers_pos.model_gift_voucher_pos point_of_sale.group_pos_user 1 0 0 0
6 coupon_usr access_coupon_usr vouchers_pos.model_gift_coupon_pos point_of_sale.group_pos_user 1 0 0 0
7 partner_coupon_usr access_partner_coupon_usr vouchers_pos.model_partner_coupon_pos point_of_sale.group_pos_user 1 0 0 0

BIN
vouchers_pos/static/description/banner.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

BIN
vouchers_pos/static/description/coupon-button-pos.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

BIN
vouchers_pos/static/description/coupon-form.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
vouchers_pos/static/description/coupon-menu-pos.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

BIN
vouchers_pos/static/description/coupon-verified.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
vouchers_pos/static/description/cybro_logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
vouchers_pos/static/description/history.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
vouchers_pos/static/description/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

154
vouchers_pos/static/description/index.html

@ -0,0 +1,154 @@
<section class="oe_container">
<div class="oe_row oe_spaced">
<h2 class="oe_slogan">Vouchers and Coupons</h2>
<h3 class="oe_slogan">..Manage Gift Vouchers and Coupon Codes in Point of Sale..</h3>
<h4 class="oe_slogan"><a href="https://www.cybrosys.com">Cybrosys Technologies</a> </h4>
</div>
<div class="oe_row oe_spaced" style="padding-left:65px;">
<h4>Features:</h4>
<div>
<span style="color:green;"> &#9745; </span> Create gift vouchers for products.<br/>
<span style="color:green;"> &#9745; </span> Create gift vouchers for point of sale category.<br/>
<span style="color:green;"> &#9745; </span> Create global gift vouchers.<br/>
<span style="color:green;"> &#9745; </span> Create and configure coupon codes.<br/>
<span style="color:green;"> &#9745; </span> Apply coupon codes from point of sale.<br/>
<span style="color:green;"> &#9745; </span> Coupon usage tracking.<br/>
</div>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<div class="oe_picture">
<h3 class="oe_slogan">Overview</h3>
<p class="oe_mt32">
Gift vouchers and coupon codes can be used to provide a certain amount of discount to our customers
using a secret code.
</p>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<div>
<div class="oe_span6">
<div class="oe_demo oe_picture oe_screenshot">
<img style="border:10px solid white;width: 260px;" src="coupon-menu-pos.png">
</div>
</div>
<br><br><br>
<p>After installing this module, three menus will be created under
point of sale. We can use these menus to create, configure and track vouchers, coupons and their usage.</p>
</div>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<h3 class="oe_slogan">Vouchers</h3>
<div class="" style="text-align: center;">
<div class="oe_span12">
<div class="oe_demo oe_picture oe_screenshot">
<img style="border:10px solid white;" src="voucher-form.png">
</div>
</div>
<p> This is the form for creating vouchers. We can create vouchers for a single product, pos category and
for all the products.</p>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<h3 class="oe_slogan">Coupons</h3>
<div class="oe_span12" style="text-align: center;">
<div class="oe_demo oe_picture oe_screenshot">
<img style="border:10px solid white;" src="coupon-form.png">
</div>
</div>
<br>
<div class="" style="text-align: center;">
<div class="" style="text-align: center;">
<p>
After creating the voucher, we need to create the coupons related to each voucher. From
the coupons menu, we can create new coupons and link it to the corresponding vouchers. The fixed type coupon will
include a fixed amount discount to the order and percentage type coupon will set the coupon amount based on
the total order amount and the percentage provided in the back end.
<p>
</div>
</div>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<h3 class="oe_slogan">Apply Coupons</h3>
<br />
<p> The 'Coupons' button in point of sale can be used to enter the coupon code.
</p>
<div class="oe_span6">
<div class="oe_demo oe_picture oe_screenshot">
<img style="border:10px solid white;" src="coupon-button-pos.png">
</div>
</div>
<div class="oe_span6">
<div class="oe_demo oe_picture oe_screenshot">
<img style="border:10px solid white;" src="verify-coupon.png">
</div>
</div>
<div class="oe_span6">
<div class="oe_demo oe_picture oe_screenshot">
<img style="border:10px solid white;" src="coupon-verified.png">
</div>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<h3 class="oe_slogan">Coupon Tracking</h3>
<div class="oe_span12">
<div class="oe_demo oe_picture oe_screenshot">
<img style="border:10px solid white;width:100%;height:100%;" src="history.png">
</div>
</div>
<p style="text-align:center;">Go to the 'Coupon History' menu under 'Vouchers and Coupons' for coupon tracking.</p>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<div style="text-align: center;">
<a href="https://www.cybrosys.com/blog/odoo-pos-coupons-and-vouchers">
<h1 style="color:lightseagreen;font-family: initial;"><i>
Click here for more detailed description.
</i></h1>
</a>
</div>
</div>
</section>
<section class="oe_container">
<h2 class="oe_slogan" style="margin-top:20px;" >Need Any Help?</h2>
<div class="oe_slogan" style="margin-top:10px !important;">
<div>
<a class="btn btn-primary btn-lg mt8"
style="color: #FFFFFF !important;border-radius: 0;" href="https://www.cybrosys.com"><i
class="fa fa-envelope"></i> Email </a> <a
class="btn btn-primary btn-lg mt8" style="color: #FFFFFF !important;border-radius: 0;"
href="https://www.cybrosys.com/contact/"><i
class="fa fa-phone"></i> Contact Us </a> <a
class="btn btn-primary btn-lg mt8" style="color: #FFFFFF !important;border-radius: 0;"
href="https://www.cybrosys.com/odoo-customization-and-installation/"><i
class="fa fa-check-square"></i> Request Customization </a>
</div>
<br>
<img src="cybro_logo.png" style="width: 190px; margin-bottom: 20px;" class="center-block">
<div>
<a href="https://twitter.com/cybrosys" target="_blank"><i class="fa fa-2x fa-twitter" style="color:white;background: #00a0d1;width:35px;"></i></a></td>
<a href="https://www.linkedin.com/company/cybrosys-technologies-pvt-ltd" target="_blank"><i class="fa fa-2x fa-linkedin" style="color:white;background: #31a3d6;width:35px;padding-left: 3px;"></i></a></td>
<a href="https://www.facebook.com/cybrosystechnologies" target="_blank"><i class="fa fa-2x fa-facebook" style="color:white;background: #3b5998;width:35px;padding-left: 8px;"></i></a></td>
<a href="https://plus.google.com/106641282743045431892/about" target="_blank"><i class="fa fa-2x fa-google-plus" style="color:white;background: #c53c2c;width:35px;padding-left: 3px;"></i></a></td>
<a href="https://in.pinterest.com/cybrosys" target="_blank"><i class="fa fa-2x fa-pinterest" style="color:white;background: #ac0f18;width:35px;padding-left: 3px;"></i></a></td>
</div>
</div>
</section>

BIN
vouchers_pos/static/description/verify-coupon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
vouchers_pos/static/description/voucher-form.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

23
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;*/
/*}*/

390
vouchers_pos/static/src/js/coupons.js

@ -0,0 +1,390 @@
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.DataModel');
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 = PosBaseWidget.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,'<br/>'));
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,'<br/>'));
}
}
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());
}), 0), this.pos.currency.rounding);
return final_res;
},
});
});

95
vouchers_pos/static/src/xml/coupons.xml

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="coupon_template" xml:space="preserve">
<!--template for coupons-->
<t t-name="VoucherWidget">
<div class='control-button' style="width: 70%;margin-top: 5px;margin-bottom: -5px;">
<div class="coupons">
<i class='fa fa-star' /> Coupons
</div>
</div>
</t>
<t t-name="CouponPopupWidget">
<div class="modal-dialog">
<div class="popup popup-textinput">
<p class="title"><t t-esc=" widget.options.title || '' " /></p>
<input class="coupon_code" type='text' t-att-value="widget.options.value || ''"></input>
<button class="validate_coupon">Verify</button>
<div class="coupon_status">
<p class="coupon_status_p"></p>
</div>
<div class="footer">
<div class="button confirm-coupon" style="display:none;">
Apply
</div>
<div class="button cancel">
Cancel
</div>
</div>
</div>
</div>
</t>
<!--
<t t-name="ClientLine">
<tr class='client-line' t-att-data-id='partner.id'>
<td><t t-esc='partner.name' /></td>
<td><t t-esc='partner.address' /></td>
<td><t t-esc='partner.phone or partner.mobile or ""' /></td>
<td><t t-esc='partner.pos_pricelist_id[1] or ""' /></td>
</tr>
</t>
-->
<t t-extend="ProductScreenWidget">
<t t-jquery='div.placeholder-ActionpadWidget' t-operation='before'>
<div class="placeholder-VoucherWidget"></div>
</t>
</t>
<!--
<t t-extend="ClientListScreenWidget">
<t t-jquery='.client-list' t-operation='replace'>
<table class='client-list'>
<thead>
<tr>
<th>Name</th>
<th>Address</th>
<th>Phone</th>
<th>POS Pricelist</th>
</tr>
</thead>
<tbody class='client-list-contents'>
</tbody>
</table>
</t>
</t>
-->
<!--
<t t-extend="OrderSelectorWidget">
<t t-jquery="div.order-selector" t-operation="append">
<div>
<span class="order-pricelist-label">
<b> Pricelist: </b>
</span>
<select id ="pos_pricelist" class="order-pricelist" >
<t t-if="widget.pos_pricelist">
<option>
<t t-esc='widget.pos_pricelist'/>
</option>
</t>
<option></option>
<t t-foreach="widget.pos.pricelists || []" t-as="item">
<t t-if="widget.pos_pricelist != item.name">
<option>
<t t-esc='item.name'/>
</option>
</t>
</t>
</select>
</div>
</t>
</t>
-->
</templates>

47
vouchers_pos/views/applied_coupons.xml

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="applied_coupons_pos_view" model="ir.ui.view">
<field name="name">applied_coupons_form</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<xpath expr="//page[@name='sales_purchases']" position="after">
<page name="coupon_applied" string="Applied Coupons">
<field name="applied_coupon_pos" readonly="1">
<tree>
<field name="partner_id" invisible="1"/>
<field name="coupon_pos" />
<field name="number_pos" />
</tree>
</field>
</page>
</xpath>
</field>
</record>
<record id="gift_coupon_history_pos_tree" model="ir.ui.view">
<field name="name">Gift Coupon History</field>
<field name="model">partner.coupon.pos</field>
<field name="arch" type="xml">
<tree>
<field name="partner_id" />
<field name="coupon_pos" />
<field name="number_pos" />
</tree>
</field>
</record>
<record id="action_gift_coupon_history_pos" model="ir.actions.act_window">
<field name="name">Gift Coupons History</field>
<field name="res_model">partner.coupon.pos</field>
<field name="type">ir.actions.act_window</field>
<field name="view_type">form</field>
<field name="view_id" ref="gift_coupon_history_pos_tree"/>
<field name="view_mode">tree</field>
</record>
<menuitem name="Coupon History" id="gift_coupon_history_pos" action="action_gift_coupon_history_pos"
parent="vouchers_pos.gift_coupon_main"/>
</data>
</odoo>

128
vouchers_pos/views/gift_voucher.xml

@ -0,0 +1,128 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="gift_voucher_pos_form" model="ir.ui.view">
<field name="name">Gift Voucher</field>
<field name="model">gift.voucher.pos</field>
<field name="arch" type="xml">
<form>
<sheet>
<h1><field name="name"/></h1>
<group>
<group>
<field name="voucher_type" widget="radio"/>
<field name="product_id" attrs="{'invisible': [('voucher_type', 'in', ('category','all'))],
'required':[('voucher_type', '=', 'product')]}"/>
<field name="product_categ" attrs="{'invisible': [('voucher_type', 'in', ('product','all'))],
'required':[('voucher_type', '=', 'category')]}"/>
</group>
<group>
<field name="min_value" />
<field name="max_value" />
<field name="expiry_date" />
</group>
</group>
</sheet>
</form>
</field>
</record>
<record id="gift_voucher_pos_tree" model="ir.ui.view">
<field name="name">Gift Voucher</field>
<field name="model">gift.voucher.pos</field>
<field name="arch" type="xml">
<tree>
<field name="name" />
<field name="product_id" />
<field name="min_value" />
<field name="max_value" />
<field name="expiry_date" />
</tree>
</field>
</record>
<record id="gift_coupon_pos_form" model="ir.ui.view">
<field name="name">Gift Coupon</field>
<field name="model">gift.coupon.pos</field>
<field name="arch" type="xml">
<form>
<sheet>
<div class="oe_title">
<label for="name" string="Name" />
<h1>
<field name="name"/>
</h1>
</div>
<group>
<group>
<field name="code" />
<field name="start_date" />
</group>
<group>
<field name="voucher" />
<field name="end_date" />
</group>
</group>
<group string="Conditions">
<group>
<field name="total_avail" />
</group>
<group>
<field name="partner_id" />
<field name="limit" />
</group>
</group>
<group string="Pricing">
<group>
<field name="voucher_val" />
</group>
<group>
<field name="type" />
</group>
</group>
</sheet>
</form>
</field>
</record>
<record id="gift_coupon_pos_tree" model="ir.ui.view">
<field name="name">Gift Coupon</field>
<field name="model">gift.coupon.pos</field>
<field name="arch" type="xml">
<tree>
<field name="name" />
<field name="code" />
<field name="voucher" />
<field name="start_date" />
<field name="end_date" />
<field name="partner_id" />
<field name="total_avail" />
<field name="type" />
</tree>
</field>
</record>
<record id="action_gift_voucher_pos" model="ir.actions.act_window">
<field name="name">Gift Vouchers</field>
<field name="res_model">gift.voucher.pos</field>
<field name="type">ir.actions.act_window</field>
<field name="view_type">form</field>
<field name="view_id" ref="gift_voucher_pos_tree"/>
<field name="view_mode">tree,form</field>
</record>
<record id="action_gift_coupon_pos" model="ir.actions.act_window">
<field name="name">Generate Gift Coupons</field>
<field name="res_model">gift.coupon.pos</field>
<field name="type">ir.actions.act_window</field>
<field name="view_type">form</field>
<field name="view_id" ref="gift_coupon_pos_tree"/>
<field name="view_mode">tree,form</field>
</record>
<menuitem name="Vouchers and Coupons" id="gift_coupon_main" sequence="99"
parent="point_of_sale.menu_point_root"/>
<menuitem name="Gift Voucher" id="gift_voucher" action="action_gift_voucher_pos" parent="gift_coupon_main"/>
<menuitem name="Gift Coupon" id="gift_coupon" action="action_gift_coupon_pos" parent="gift_coupon_main"/>
</data>
</odoo>

11
vouchers_pos/views/pos_template.xml

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<template id="assets" inherit_id="point_of_sale.assets">
<xpath expr="." position="inside">
<script type="text/javascript" src="/vouchers_pos/static/src/js/coupons.js"></script>
<link rel="stylesheet" href="/vouchers_pos/static/src/css/pos.css" id="pos-stylesheet"/>
</xpath>
</template>
</data>
</odoo>
Loading…
Cancel
Save