@ -0,0 +1,24 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# Copyright (C) 2017-TODAY Cybrosys Technologies(<http://www.cybrosys.com>). |
||||
|
# Author: Linto C T(<http://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 <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
|
||||
|
import models |
@ -0,0 +1,44 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# Copyright (C) 2017-TODAY Cybrosys Technologies(<http://www.cybrosys.com>). |
||||
|
# Author: Linto C T(<http://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 <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
{ |
||||
|
'name': 'Price Lists in Point of Sale', |
||||
|
'version': '10.0.1.0', |
||||
|
'category': 'Point of Sale', |
||||
|
'summary': """Set Price Lists for Customers. Products/POS Categories Can be Added to Price Lists""", |
||||
|
'author': 'Cybrosys Techno Solutions', |
||||
|
'website': "http://www.cybrosys.com", |
||||
|
'company': 'Cybrosys Techno Solutions', |
||||
|
'depends': ['point_of_sale'], |
||||
|
'data': [ |
||||
|
'views/pricelist.xml', |
||||
|
'views/pricelist_menu.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, |
||||
|
'auto_install': False, |
||||
|
} |
@ -0,0 +1,23 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# Copyright (C) 2017-TODAY Cybrosys Technologies(<http://www.cybrosys.com>). |
||||
|
# Author: Linto C T(<http://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 <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
import pos_pricelist |
@ -0,0 +1,65 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# Copyright (C) 2017-TODAY Cybrosys Technologies(<http://www.cybrosys.com>). |
||||
|
# Author: Linto C T(<http://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 <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
|
||||
|
from odoo import models, fields |
||||
|
|
||||
|
|
||||
|
class PosPriceList(models.Model): |
||||
|
_name = 'pos.pricelist' |
||||
|
|
||||
|
def _get_default_currency_id(self): |
||||
|
return self.env.user.company_id.currency_id.id |
||||
|
|
||||
|
name = fields.Char(string="Name", required=True) |
||||
|
item_ids = fields.One2many('pos.pricelist.items', 'pos_pricelist_id', string="Pricelist Items") |
||||
|
currency_id = fields.Many2one('res.currency', 'Currency', default=_get_default_currency_id, required=True) |
||||
|
company_id = fields.Many2one('res.company', 'Company') |
||||
|
|
||||
|
|
||||
|
class PosPricelistItems(models.Model): |
||||
|
_name = 'pos.pricelist.items' |
||||
|
|
||||
|
name = fields.Char(string="Name", required=True) |
||||
|
pos_pricelist_id = fields.Many2one('pos.pricelist', string="Pricelist") |
||||
|
applied_on = fields.Selection([('global', "Global"), ('product_category', 'Product Category'), |
||||
|
('product', 'Product')], string="Applied On", default='global', required=True) |
||||
|
min_quantity = fields.Integer(string="Minimum Quantity") |
||||
|
date_start = fields.Date(string="Date Start") |
||||
|
date_end = fields.Date(string="Date End") |
||||
|
compute_price = fields.Selection([('fixed', 'Fixed'), ('percentage', 'Percentage')], |
||||
|
string="Compute Price", default='fixed') |
||||
|
fixed_price = fields.Float(string="Fixed Price") |
||||
|
percent_price = fields.Float(string="Percentage") |
||||
|
|
||||
|
categ_id = fields.Many2one('pos.category', string="POS Product Category") |
||||
|
product_tmpl_id = fields.Many2one('product.template', string="Product") |
||||
|
|
||||
|
company_id = fields.Many2one('res.company', 'Company', readonly=True, related='pos_pricelist_id.company_id', store=True) |
||||
|
currency_id = fields.Many2one('res.currency', 'Currency', |
||||
|
readonly=True, related='pos_pricelist_id.currency_id', store=True) |
||||
|
|
||||
|
|
||||
|
class PriceListPartner(models.Model): |
||||
|
_inherit = 'res.partner' |
||||
|
|
||||
|
pos_pricelist_id = fields.Many2one('pos.pricelist', string="POS Pricelist") |
|
After Width: | Height: | Size: 116 KiB |
After Width: | Height: | Size: 118 KiB |
After Width: | Height: | Size: 50 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 36 KiB |
@ -0,0 +1,131 @@ |
|||||
|
<section class="oe_container"> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<h2 class="oe_slogan">Pricelist in Point of Sale</h2> |
||||
|
<h3 class="oe_slogan">..Manage Your Pricing Based on Pricelists in Point of Sale..</h3> |
||||
|
<h4 class="oe_slogan" style="font-size: 23px;">Author : Cybrosys Techno Solutions , www.cybrosys.com</h4> |
||||
|
</div> |
||||
|
<div class="oe_row oe_spaced" style="padding-left:65px;"> |
||||
|
<h4>Features:</h4> |
||||
|
<div> |
||||
|
<span style="color:green;"> ☑ </span> Create price lists for products.<br/> |
||||
|
<span style="color:green;"> ☑ </span> Create price lists for point of sale category.<br/> |
||||
|
<span style="color:green;"> ☑ </span> Create global price lists.<br/> |
||||
|
<span style="color:green;"> ☑ </span> Apply price lists for customers.<br/> |
||||
|
<span style="color:green;"> ☑ </span> Independent from Sale Price List.<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"> |
||||
|
This module adds a feature to odoo's point of sale. With this module, we will be able to create, |
||||
|
configure and apply pricelists in point of sale. |
||||
|
</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
|
||||
|
<section class="oe_container"> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<h3 class="oe_slogan">Menu</h3> |
||||
|
<div style="text-align: center"> |
||||
|
<p> |
||||
|
<h4>Point of Sale -> Configuration -> Pricelists</h4> |
||||
|
<p> |
||||
|
</div> |
||||
|
<div> |
||||
|
<div class="oe_demo oe_picture oe_screenshot"> |
||||
|
<img style="border:10px solid white;height: 400px;" src="pricelist.png"> |
||||
|
</div> |
||||
|
<p>After installing this module, a new menu will be created under |
||||
|
point of sale configuration. This menu will open the form for creating the pricelists. |
||||
|
We can add pricelist items by clicking on the 'Add an item' button, which wil open a new form.</p> |
||||
|
</div> |
||||
|
<br> |
||||
|
<div class="" style="text-align: center"> |
||||
|
<div class="oe_demo oe_picture oe_screenshot"> |
||||
|
<img style="border:10px solid white;height: 400px;" src="global_item.png"> |
||||
|
</div> |
||||
|
<p> This is the form for creating pricelist items. We can create rules for product, point of sale category |
||||
|
and global rules.</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
|
||||
|
<section class="oe_container oe_dark"> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<h3 class="oe_slogan">Pricelist Selection</h3> |
||||
|
<div class="" style="text-align: center"> |
||||
|
<div class="oe_demo oe_picture oe_screenshot"> |
||||
|
<img style="border:10px solid white;height: 400px;" src="pricelist-selection-partner.png"> |
||||
|
</div> |
||||
|
<span>☛ Pricelist selection in customer form.</span> |
||||
|
</div> |
||||
|
<br> |
||||
|
<div class="" style="text-align: center"> |
||||
|
<div class="" style="text-align: center"> |
||||
|
<p> |
||||
|
After creating the pricelist, we can assign that pricelist to a customer from the customer |
||||
|
form. A new field is added for selecting the point of sale price list under the point of sale section. |
||||
|
<p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
|
||||
|
<section class="oe_container"> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<h3 class="oe_slogan">Apply Pricelist</h3> |
||||
|
<div> |
||||
|
<div class="oe_demo oe_picture oe_screenshot"> |
||||
|
<img style="border:10px solid white;height: 400px;" src="customer_selected.png"> |
||||
|
</div> |
||||
|
<p> The pricelist will be automatically selected |
||||
|
after selecting the customer, if there is any pricelist set for this customer. |
||||
|
If there is no pricelist is there for the customer we selected, then there is an option |
||||
|
for us to manually select the pricelist. |
||||
|
</p> |
||||
|
</div> |
||||
|
</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-price-list"> |
||||
|
<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> |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 54 KiB |
@ -0,0 +1,14 @@ |
|||||
|
.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; |
||||
|
} |
@ -0,0 +1,277 @@ |
|||||
|
odoo.define("pos_pricing.pricelist", function (require) { |
||||
|
"use strict"; |
||||
|
var core = require('web.core'); |
||||
|
var pos_model = require('point_of_sale.models'); |
||||
|
var pos_chrome = require('point_of_sale.chrome') |
||||
|
var models = pos_model.PosModel.prototype.models; |
||||
|
var PosModelSuper = pos_model.PosModel; |
||||
|
var OrderSuper = pos_model.Order; |
||||
|
var OrderlineSuper = pos_model.Orderline; |
||||
|
// get pos_pricelist_id of each customer
|
||||
|
for(var i=0; i<models.length; i++){ |
||||
|
var model=models[i]; |
||||
|
if(model.model === 'res.partner'){ |
||||
|
model.fields.push('pos_pricelist_id'); |
||||
|
} |
||||
|
} |
||||
|
// getting pricelists and pricelist items
|
||||
|
models.push( |
||||
|
{ |
||||
|
model: 'pos.pricelist', |
||||
|
fields: ['id', 'name'], |
||||
|
loaded: function (self, pricelists) { |
||||
|
for (var i in pricelists){ |
||||
|
self.pricelists.push(pricelists[i]); |
||||
|
} |
||||
|
}, |
||||
|
},{ |
||||
|
model: 'pos.pricelist.items', |
||||
|
fields: ['id', 'fixed_price', 'date_end', 'applied_on', 'min_quantity', |
||||
|
'percent_price', 'date_start', 'product_tmpl_id', 'pos_pricelist_id', 'compute_price', 'categ_id'], |
||||
|
loaded: function (self, pricelist_items) { |
||||
|
self.pricelist_items = pricelist_items; |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
model: 'product.template', |
||||
|
fields: ['id', 'categ_id'], |
||||
|
loaded: function (self, category) { |
||||
|
self.category = category; |
||||
|
}, |
||||
|
} |
||||
|
); |
||||
|
// this function is used to get the id of selected pricelist using the name of pricelist
|
||||
|
function get_pricelist_id(pricelists, name){ |
||||
|
for(var i in pricelists){ |
||||
|
if(pricelists[i].name == name){ |
||||
|
return pricelists[i].id; |
||||
|
} |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
// PosModel is extended to store category, pricelists and pricelist items on startup
|
||||
|
pos_model.PosModel = pos_model.PosModel.extend({ |
||||
|
initialize: function(session, attributes) { |
||||
|
PosModelSuper.prototype.initialize.call(this, session, attributes) |
||||
|
this.pricelist_items = ['']; |
||||
|
this.pricelists = []; |
||||
|
this.category = []; |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
pos_model.Order = pos_model.Order.extend({ |
||||
|
// case : selecting product after selecting client ----------------------------------
|
||||
|
// here we will get the pricelist selected, if there are any and apply the pricelist after validation
|
||||
|
add_product: function (product, options) { |
||||
|
var self = this; |
||||
|
var pricelist_id = get_pricelist_id(self.pos.pricelists, $("#pos_pricelist").val()); |
||||
|
OrderSuper.prototype.add_product.call(this, product, options); |
||||
|
if (!pricelist_id){ |
||||
|
if (this.pos.get_client()){ |
||||
|
self.apply_pricelist(this.pos.get_client(), pricelist_id); |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
// this function returns the new price after checking the computation method of the pricelist item
|
||||
|
set_price: function (line, item) { |
||||
|
var new_price = 0; |
||||
|
switch (item.compute_price){ |
||||
|
case 'fixed': new_price = item.fixed_price; break; |
||||
|
case 'percentage': new_price = line.product.price -(line.product.price * item.percent_price / 100); break; |
||||
|
} |
||||
|
return new_price; |
||||
|
}, |
||||
|
/*this function is used to check the given id is present in the array or not, |
||||
|
since the 'in' operator was not working properly*/ |
||||
|
find_pricelist_item: function (id, item_ids) { |
||||
|
for (var j in item_ids){ |
||||
|
if(item_ids[j] == id){ |
||||
|
return true; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
return false; |
||||
|
}, |
||||
|
|
||||
|
// apply pricelist for this client----------------------------
|
||||
|
apply_pricelist: function(client, pricelist_id){ |
||||
|
var self = this; |
||||
|
// list of all pricelist items available
|
||||
|
var pricelist_items = self.pos.pricelist_items; |
||||
|
var items = []; |
||||
|
// getting this client's pricelist items from the complete list ---------------------------
|
||||
|
for (var i in pricelist_items){ |
||||
|
if(pricelist_items[i].pos_pricelist_id[0] == pricelist_id){ |
||||
|
items.push(pricelist_items[i]); |
||||
|
} |
||||
|
} |
||||
|
// checking the start date and end date of these items and selecting only the valid items
|
||||
|
pricelist_items = []; |
||||
|
var today = moment().format('YYYY-MM-DD'); |
||||
|
for (var i in items){ |
||||
|
if(((items[i].date_start == false) || (items[i].date_start <= today)) |
||||
|
&& ((items[i].date_end == false) || (items[i].date_end >= today))) |
||||
|
{ |
||||
|
pricelist_items.push(items[i]); |
||||
|
} |
||||
|
} |
||||
|
// grouping the pricelist items based on applicability
|
||||
|
// we are listing those products and categories which has a pricelist item for them
|
||||
|
// for making the checkings easier
|
||||
|
var global_items = []; |
||||
|
var category_items = []; |
||||
|
var category_ids = []; |
||||
|
var product_items = []; |
||||
|
var product_ids = []; |
||||
|
for(var i in pricelist_items){ |
||||
|
switch(pricelist_items[i].applied_on){ |
||||
|
case 'global': global_items.push(pricelist_items[i]); break; |
||||
|
case 'product_category': category_items.push(pricelist_items[i]); |
||||
|
category_ids.push(pricelist_items[i].categ_id[0]) ; break; |
||||
|
case 'product': product_items.push(pricelist_items[i]); |
||||
|
product_ids.push(pricelist_items[i].product_tmpl_id[0]) ;break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// getting current order ====================================================
|
||||
|
var order = self.pos.get_order(); |
||||
|
var lines = order ? order.get_orderlines() : null; |
||||
|
|
||||
|
//looping through each line
|
||||
|
for (var l in lines){ |
||||
|
// checking if this product has a valid pricelist rule set or not
|
||||
|
var product_item = self.find_pricelist_item(lines[l].product.product_tmpl_id, product_ids); |
||||
|
// checking if this product's category has a valid pricelist rule set or not
|
||||
|
var categ_item = self.find_pricelist_item(lines[l].product.pos_categ_id[0], category_ids); |
||||
|
var temp = -1; |
||||
|
var new_price = lines[l].product.price; |
||||
|
// checking if the product has any pricelist item set
|
||||
|
if(product_item){ |
||||
|
for(var j in product_items){ |
||||
|
if(product_items[j].product_tmpl_id[0] == lines[l].product.product_tmpl_id){ |
||||
|
if(lines[l].quantity >= product_items[j].min_quantity){ |
||||
|
if(temp < 0){ |
||||
|
temp = lines[l].quantity - product_items[j].min_quantity; |
||||
|
new_price = self.set_price(lines[l], product_items[j]); |
||||
|
} |
||||
|
else if(temp > (lines[l].quantity - product_items[j].min_quantity) && |
||||
|
(lines[l].quantity - product_items[j].min_quantity) >= 0){ |
||||
|
temp = lines[l].quantity - product_items[j].min_quantity; |
||||
|
new_price = self.set_price(lines[l], product_items[j]); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
lines[l].set_unit_price(new_price); |
||||
|
} |
||||
|
else if(categ_item){ |
||||
|
for(var j in category_items){ |
||||
|
if(category_items[j].categ_id[0] == lines[l].product.pos_categ_id[0]){ |
||||
|
if(lines[l].quantity >= category_items[j].min_quantity) |
||||
|
{ |
||||
|
if(temp < 0){ |
||||
|
temp = lines[l].quantity - category_items[j].min_quantity; |
||||
|
new_price = self.set_price(lines[l], category_items[j]); |
||||
|
} |
||||
|
else if(temp > (lines[l].quantity - category_items[j].min_quantity) && |
||||
|
(lines[l].quantity - category_items[j].min_quantity) >= 0){ |
||||
|
temp = lines[l].quantity - category_items[j].min_quantity; |
||||
|
new_price = self.set_price(lines[l], category_items[j]); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
lines[l].set_unit_price(new_price); |
||||
|
} |
||||
|
// if there are no rules set for product or category, we will check global pricelists
|
||||
|
else if(global_items.length > 0){ |
||||
|
for(var j in global_items){ |
||||
|
if(lines[l].quantity >= global_items[j].min_quantity) |
||||
|
{ |
||||
|
if(temp < 0){ |
||||
|
temp = lines[l].quantity - global_items[j].min_quantity; |
||||
|
new_price = self.set_price(lines[l], global_items[j]); |
||||
|
} |
||||
|
else if(temp > (lines[l].quantity - global_items[j].min_quantity) && |
||||
|
(lines[l].quantity - global_items[j].min_quantity) >= 0){ |
||||
|
temp = lines[l].quantity - global_items[j].min_quantity; |
||||
|
new_price = self.set_price(lines[l], global_items[j]); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
lines[l].set_unit_price(new_price); |
||||
|
} |
||||
|
// else we set the original price
|
||||
|
else{ |
||||
|
lines[l].set_unit_price(lines[l].product.price); |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
// this function will first set a customer for this order and then, it will apply the pricelist of this customer to
|
||||
|
// this order if there are any
|
||||
|
set_client: function(client){ |
||||
|
var self = this; |
||||
|
var current_pricelist = document.getElementById('pos_pricelist'); |
||||
|
if(client){ |
||||
|
if (current_pricelist != null){ |
||||
|
current_pricelist.value = client.pos_pricelist_id[1]; |
||||
|
} |
||||
|
var order = self.pos.get_order(); |
||||
|
if (order) { |
||||
|
if (order.orderlines.length) { |
||||
|
self.apply_pricelist(client, client.pos_pricelist_id[0]); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
else if(current_pricelist){ |
||||
|
current_pricelist.value = ''; |
||||
|
} |
||||
|
OrderSuper.prototype.set_client.call(this, client); |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
pos_model.Orderline = pos_model.Orderline.extend({ |
||||
|
set_quantity: function(quantity){ |
||||
|
OrderlineSuper.prototype.set_quantity.call(this, quantity); |
||||
|
var pricelist_id = get_pricelist_id(this.pos.pricelists, $("#pos_pricelist").val()); |
||||
|
if (this.order.get_client() && pricelist_id) { |
||||
|
this.order.apply_pricelist(this.order.get_client(), pricelist_id); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
}); |
||||
|
|
||||
|
pos_chrome.OrderSelectorWidget.include({ |
||||
|
renderElement: function(){ |
||||
|
var pos_pricelist = $("#pos_pricelist"); |
||||
|
this.pos_pricelist = false; |
||||
|
if (pos_pricelist != null){ |
||||
|
this.pos_pricelist = pos_pricelist.val(); |
||||
|
} |
||||
|
var self = this; |
||||
|
this._super(); |
||||
|
this.$("#pos_pricelist").change(function () { |
||||
|
self.pos.pos_pricelist = false; |
||||
|
var order = self.pos.get_order(); |
||||
|
var client = order.get_client(); |
||||
|
var pricelist_id = get_pricelist_id(self.pos.pricelists, $("#pos_pricelist").val()); |
||||
|
if (client && pricelist_id){ |
||||
|
order.apply_pricelist(client, pricelist_id); |
||||
|
} |
||||
|
else if (!client){ |
||||
|
$("#pos_pricelist").val('') |
||||
|
alert("Unable to set pricelist. Please check customer...!!") |
||||
|
} |
||||
|
}); |
||||
|
this.$('.order-button.select-order').click(function(event){ |
||||
|
self.order_click_handler(event,$(this)); |
||||
|
}); |
||||
|
this.$('.neworder-button').click(function(event){ |
||||
|
self.neworder_click_handler(event,$(this)); |
||||
|
}); |
||||
|
this.$('.deleteorder-button').click(function(event){ |
||||
|
self.deleteorder_click_handler(event,$(this)); |
||||
|
}); |
||||
|
}, |
||||
|
}); |
||||
|
}); |
@ -0,0 +1,67 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<templates id="point_of_sale.template" xml:space="preserve"> |
||||
|
<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="ClientDetails"> |
||||
|
<t t-jquery='.client-details-right' t-operation='append'> |
||||
|
<div class='client-detail'> |
||||
|
<span class='label'>Pricelist</span> |
||||
|
<t t-if='partner.pos_pricelist_id'> |
||||
|
<span class='detail client-id'><t t-esc='partner.pos_pricelist_id[1]'/></span> |
||||
|
</t> |
||||
|
<t t-if='!partner.barcode'> |
||||
|
<span class='detail client-id empty'>N/A</span> |
||||
|
</t> |
||||
|
</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> |
@ -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="/pos_pricing/static/src/js/pricelist.js"></script> |
||||
|
<link rel="stylesheet" href="/pos_pricing/static/src/css/pos.css" id="pos-stylesheet"/> |
||||
|
</xpath> |
||||
|
</template> |
||||
|
</data> |
||||
|
</odoo> |
@ -0,0 +1,16 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<openerp> |
||||
|
<data> |
||||
|
<!--showing pricelist in partner form--> |
||||
|
<record id="pos_pricelist_customer_form" model="ir.ui.view"> |
||||
|
<field name="name">pos.pricelist.customer</field> |
||||
|
<field name="model">res.partner</field> |
||||
|
<field name="inherit_id" ref="point_of_sale.view_partner_property_form" /> |
||||
|
<field name="arch" type="xml"> |
||||
|
<xpath expr="//group[@name='point_of_sale']" position="inside"> |
||||
|
<field name="pos_pricelist_id" /> |
||||
|
</xpath> |
||||
|
</field> |
||||
|
</record> |
||||
|
</data> |
||||
|
</openerp> |
@ -0,0 +1,125 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<odoo> |
||||
|
<data> |
||||
|
<!--pricelist item view--> |
||||
|
<record id="pos_pricelist_item_tree_view" model="ir.ui.view"> |
||||
|
<field name="name">pos.pricelist.item.tree</field> |
||||
|
<field name="model">pos.pricelist.items</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree string="Pricelist Items"> |
||||
|
<field colspan="4" name="name"/> |
||||
|
<field name="product_tmpl_id"/> |
||||
|
<field name="categ_id"/> |
||||
|
<field name="min_quantity"/> |
||||
|
<field name="date_start"/> |
||||
|
<field name="date_end"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="pos_pricelist_item_form_view" model="ir.ui.view"> |
||||
|
<field name="name">pos.pricelist.item.form</field> |
||||
|
<field name="model">pos.pricelist.items</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form string="Pricelist Items"> |
||||
|
<h1><field name="name"/></h1> |
||||
|
<group> |
||||
|
<group> |
||||
|
<field name="applied_on" widget="radio"/> |
||||
|
<field name="categ_id" attrs="{'invisible':[('applied_on', '!=', 'product_category')], 'required':[('applied_on', '=', 'product_category')]}"/> |
||||
|
<field name="product_tmpl_id" domain="[('available_in_pos', '=', True)]" |
||||
|
attrs="{'invisible':[('applied_on', '!=', 'product')],'required':[('applied_on', '=', 'product')]}" string="Product"/> |
||||
|
</group> |
||||
|
<group> |
||||
|
<field name="min_quantity"/> |
||||
|
<field name="date_start"/> |
||||
|
<field name="date_end"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
<separator string="Price Computation"/> |
||||
|
<group> |
||||
|
<group> |
||||
|
<label for="compute_price" string="Compute Price"/> |
||||
|
<div> |
||||
|
<field name="compute_price" widget="radio"/> |
||||
|
<field name="currency_id" invisible="1"/> |
||||
|
<div attrs="{'invisible':[('compute_price', '!=', 'fixed')]}"> |
||||
|
<field name="fixed_price" nolabel= "1" widget='monetary' options="{'currency_field': 'currency_id'}"/></div> |
||||
|
<div attrs="{'invisible':[('compute_price', '!=', 'percentage')]}"> |
||||
|
<field name="percent_price" nolabel="1" class="oe_inline"/>%% |
||||
|
</div> |
||||
|
</div> |
||||
|
</group> |
||||
|
</group> |
||||
|
<div class="oe_grey" groups="product.group_uom"> |
||||
|
<p>The computed price is expressed in the default Unit of Measure of the product.</p> |
||||
|
</div> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<record model="ir.ui.view" id="pos_pricelist_view_search"> |
||||
|
<field name="name">pos.pricelist.search</field> |
||||
|
<field name="model">pos.pricelist</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<search string="POS Price Search"> |
||||
|
<field name="name" string="Products Price"/> |
||||
|
<field name="currency_id" groups="base.group_multi_currency"/> |
||||
|
</search> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
|
||||
|
<record id="pos_pricelist_view_tree" model="ir.ui.view"> |
||||
|
<field name="name">pos.pricelist.tree</field> |
||||
|
<field name="model">pos.pricelist</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree string="POS Price List"> |
||||
|
<field name="name"/> |
||||
|
<field name="currency_id" groups="base.group_multi_currency"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="pos_pricelist_view" model="ir.ui.view"> |
||||
|
<field name="name">pos.pricelist.form</field> |
||||
|
<field name="model">pos.pricelist</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form string="POS Price List"> |
||||
|
<sheet> |
||||
|
<div class="oe_title"> |
||||
|
<h1><field name="name" placeholder="e.g. USD Retailers"/></h1> |
||||
|
</div> |
||||
|
<group> |
||||
|
<field name="currency_id" groups="base.group_multi_currency"/> |
||||
|
<field name="company_id" groups="base.group_multi_company" options="{'no_create': True}"/> |
||||
|
</group> |
||||
|
<div> |
||||
|
<separator string="Pricelist Items"/> |
||||
|
<field name="item_ids" nolabel="1" context="{'default_base':'list_price'}"> |
||||
|
<tree string="Pricelist Items"> |
||||
|
<field name="name" string="Applicable On"/> |
||||
|
<field name="min_quantity"/> |
||||
|
<field name="date_start"/> |
||||
|
<field name="date_end"/> |
||||
|
<field name="applied_on" invisible="1"/> |
||||
|
<field name="compute_price" invisible="1"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</div> |
||||
|
</sheet> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="action_pos_pricelist_menu" model="ir.actions.act_window"> |
||||
|
<field name="name">Pricelists</field> |
||||
|
<field name="res_model">pos.pricelist</field> |
||||
|
<field name="view_type">form</field> |
||||
|
<field name="view_mode">tree,form</field> |
||||
|
</record> |
||||
|
|
||||
|
<menuitem name="Pricelists" id="pos_pricelist_menu" action="action_pos_pricelist_menu" |
||||
|
parent="point_of_sale.menu_point_config_product" sequence="2" /> |
||||
|
</data> |
||||
|
</odoo> |