diff --git a/addons/website_sale_advance_pricelist/__init__.py b/addons/website_sale_advance_pricelist/__init__.py new file mode 100644 index 00000000..3f80cbe0 --- /dev/null +++ b/addons/website_sale_advance_pricelist/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# Part of flectra. See LICENSE file for full copyright and licensing details. + +from . import controllers +from . import models diff --git a/addons/website_sale_advance_pricelist/__manifest__.py b/addons/website_sale_advance_pricelist/__manifest__.py new file mode 100644 index 00000000..1e89a003 --- /dev/null +++ b/addons/website_sale_advance_pricelist/__manifest__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# Part of flectra. See LICENSE file for full copyright and licensing details. + +{ + 'name': 'Website Sale Advance Pricelist', + 'version': '1.0.0', + 'category': 'Sale', + 'author': 'FlectraHQ', + 'website': 'https://flectrahq.com', + 'sequence': 25, + 'summary': 'Add Price Rules, Cart Rules and Coupon Rules', + 'depends': ['sale_advance_pricelist', 'website_sale'], + 'data': [ + 'views/sale_order_view.xml', + 'views/asset.xml', + 'data/pricelist_view.xml', + ], + 'demo': [ + 'demo/sale_order_demo.xml', + ], + 'qweb': [ + ], + 'auto_install': False +} diff --git a/addons/website_sale_advance_pricelist/controllers/__init__.py b/addons/website_sale_advance_pricelist/controllers/__init__.py new file mode 100644 index 00000000..99566a84 --- /dev/null +++ b/addons/website_sale_advance_pricelist/controllers/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# Part of flectra. See LICENSE file for full copyright and licensing details. + +from . import main diff --git a/addons/website_sale_advance_pricelist/controllers/main.py b/addons/website_sale_advance_pricelist/controllers/main.py new file mode 100644 index 00000000..7b939ea3 --- /dev/null +++ b/addons/website_sale_advance_pricelist/controllers/main.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- +# Part of flectra. See LICENSE file for full copyright and licensing details. + +from flectra import http +from flectra.http import request +from flectra.addons.website_sale.controllers.main import WebsiteSale +from flectra.addons.portal.controllers.portal import _build_url_w_params +from flectra.tools.misc import formatLang + + +class WebsiteSale(WebsiteSale): + + @http.route(['/shop/pricelist'], type='http', auth="public", website=True) + def pricelist(self, promo, **post): + redirect = post.get('r', '/shop/cart') + if request.website.pricelist_id.pricelist_type == 'basic': + return super(WebsiteSale, self).pricelist(promo) + else: + sale_order_id = request.session.get('sale_order_id') + sale_order = request.env['sale.order'].sudo().browse( + sale_order_id).exists() if sale_order_id else None + pricelist_id = request.website.pricelist_id + if pricelist_id and not pricelist_id.apply_coupon_code: + return request.redirect("%s?apply_coupon_code=1" % redirect) + coupon_obj = request.env['coupon.code'] + coupon_code_id = coupon_obj.sudo().get_coupon_records( + promo, request.website.pricelist_id) + params = {} + if not coupon_code_id: + return request.redirect("%s?coupon_code_id=1" % redirect) + if coupon_code_id.usage_limit > 0 \ + and coupon_code_id.remaining_limit <= 0: + return request.redirect("%s?coupon_exceeds_limit=1" % redirect) + min_order_amount = coupon_code_id.min_order_amount + if not sale_order.coupon_code_id and min_order_amount \ + and sale_order.amount_untaxed < min_order_amount: + params['min_order_amount'] = \ + formatLang(request.env, min_order_amount, + currency_obj=pricelist_id.currency_id) + params['subtotal'] = \ + formatLang(request.env, sale_order.amount_untaxed, + currency_obj=pricelist_id.currency_id) + return request.redirect(_build_url_w_params( + "%s?coupon_min_order=1" % redirect, params)) + if coupon_code_id.model_id: + partner_id = request.website.user_id.sudo().partner_id + check_coupon = coupon_obj.check_condition( + coupon_code_id, partner_id) + if check_coupon: + return request.redirect("%s?coupon_condition=1" % redirect) + check_coupon = True + for line in sale_order.order_line: + if line.product_uom_qty < \ + coupon_code_id.number_of_x_product and not \ + line.coupon_code_id and check_coupon: + check_coupon = True + else: + check_coupon = False + break + if check_coupon: + return request.redirect("%s?coupon_condition=1" % redirect) + sale_order.have_coupon_code = promo + sale_order.apply_coupon_code() + return request.redirect(redirect) + + @http.route(['/website/discount'], type='http', + auth="public", website=True) + def website_discount(self, access_token=None, revive='', **post): + values = {} + order = request.website.sale_get_order() + data = order._get_discount_vals() + values.update({ + 'website_sale_order': order, + 'data': data[0], + }) + return request.render( + "website_sale_advance_pricelist.discount_popover", values, + headers={'Cache-Control': 'no-cache'}) diff --git a/addons/website_sale_advance_pricelist/data/pricelist_view.xml b/addons/website_sale_advance_pricelist/data/pricelist_view.xml new file mode 100644 index 00000000..f6b41c7c --- /dev/null +++ b/addons/website_sale_advance_pricelist/data/pricelist_view.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/addons/website_sale_advance_pricelist/demo/sale_order_demo.xml b/addons/website_sale_advance_pricelist/demo/sale_order_demo.xml new file mode 100644 index 00000000..ace6982a --- /dev/null +++ b/addons/website_sale_advance_pricelist/demo/sale_order_demo.xml @@ -0,0 +1,387 @@ + + + + + + + + + + + + + + + + Graphics Card + + 5 + + 885.0 + + + + + Laptop E5023 + + 3 + + 2950.00 + + + + + + + + + + + + + + + + + + + + + Graphics Card + + 5 + + 885.0 + + + + + Laptop E5023 + + 3 + + 2950.00 + + + + + Computer Case + + 3 + + 25 + + + + + + + + + + + + + + + + + + Graphics Card + + 5 + + 885.0 + + + + + Laptop E5023 + + 3 + + 2950.00 + + + + + + Get10Peroff + + + + + + + + + + + + + + + + + + Graphics Card + + 5 + + 885.0 + + + + + Laptop E5023 + + 3 + + 2950.00 + + + + + + Get20off + + + + + + + + + + + + + + + + + + Graphics Card + + 5 + + 885.0 + + + + + Laptop E5023 + + 3 + + 2950.00 + + + + + + BXGYFree + + + + + + + + + + + + + + + + + + Graphics Card + + 5 + + 885.0 + + + + + Laptop E5023 + + 3 + + 2950.00 + + + + + + BXGYOtherFree + + + + + + + + + + + + + + + + + + Graphics Card + + 5 + + 885.0 + + + + + Laptop E5023 + + 2 + + 2950.00 + + + + + + BXGPercentFree + + + + + + + + + + + + + + + + + + Graphics Card + + 5 + + 885.0 + + + + + Laptop E5023 + + 3 + + 2950.00 + + + + + + CD15Per + + + + + + + + + + + + + + + + + + Graphics Card + + 5 + + 885.0 + + + + + Laptop E5023 + + 3 + + 2950.00 + + + + + + + + + + + + + + sent + + + + + + Graphics Card + + 5 + + 885.0 + + + + + + form + + + pending + 4208.18 + + + + + + + + + + + + \ No newline at end of file diff --git a/addons/website_sale_advance_pricelist/models/__init__.py b/addons/website_sale_advance_pricelist/models/__init__.py new file mode 100644 index 00000000..2fd14881 --- /dev/null +++ b/addons/website_sale_advance_pricelist/models/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# Part of flectra. See LICENSE file for full copyright and licensing details. + +from . import sale diff --git a/addons/website_sale_advance_pricelist/models/sale.py b/addons/website_sale_advance_pricelist/models/sale.py new file mode 100644 index 00000000..efa4dbdf --- /dev/null +++ b/addons/website_sale_advance_pricelist/models/sale.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Part of flectra. See LICENSE file for full copyright and licensing details. + +from flectra import api, models + + +class SaleOrder(models.Model): + _inherit = "sale.order" + + @api.multi + def _cart_update(self, product_id=None, line_id=None, add_qty=0, set_qty=0, + attributes=None, **kwargs): + res = super(SaleOrder, self)._cart_update(product_id, line_id, add_qty, + set_qty, **kwargs) + line = self.env['sale.order.line'].browse(res.get('line_id')) + if res.get('quantity') <= 0 \ + or line.order_id.pricelist_id.pricelist_type == 'basic': + return res + if line.order_id.have_coupon_code and \ + line.coupon_code_id and not line.check_coupon: + return res + if line.order_id.pricelist_id.discount_policy == 'with_discount': + if not line.check_coupon: + line.discount = 0.0 + line.product_id_change() + line.order_id._check_cart_rules() + return res + + +class Website(models.Model): + _inherit = 'website' + + @api.multi + def sale_get_order(self, force_create=False, code=None, + update_pricelist=False, force_pricelist=False): + res = super(Website, self).sale_get_order( + force_create, code, update_pricelist, force_pricelist) + if res.have_coupon_code: + for line in res.order_line: + if line.coupon_code_id and not line.check_coupon: + line.write({'discount': 0.0, 'price_unit': 0.0}) + return res diff --git a/addons/website_sale_advance_pricelist/static/description/icon.png b/addons/website_sale_advance_pricelist/static/description/icon.png new file mode 100644 index 00000000..088d515b Binary files /dev/null and b/addons/website_sale_advance_pricelist/static/description/icon.png differ diff --git a/addons/website_sale_advance_pricelist/static/src/js/discount.js b/addons/website_sale_advance_pricelist/static/src/js/discount.js new file mode 100644 index 00000000..79575acc --- /dev/null +++ b/addons/website_sale_advance_pricelist/static/src/js/discount.js @@ -0,0 +1,57 @@ +flectra.define('website_sale_advance_pricelist.discount', function (require) { + "use strict"; + + require('web.dom_ready'); + var core = require('web.core'); + var _t = core._t; + var discount_counter; + + function popover_discount($discount) { + $discount.popover({ + trigger: 'manual', + html: true, + animation: true, + title: function () { + return _t("Discount Calculation Details"); + }, + container: 'body', + placement: 'auto', + }).on("mouseenter",function () { + var self = this; + clearTimeout(discount_counter); + $discount.not(self).popover('hide'); + discount_counter = setTimeout(function(){ + if($(self).is(':hover')){ + $.get("/website/discount", {'type': 'popover'}) + .then(function (data) { + $(self).data("bs.popover").options.content = data; + $(self).popover("show"); + $(".popover").on("mouseleave", function () { + $(self).trigger('mouseleave'); + }); + }); + } + }, 100); + }).on("mouseleave", function () { + var self = this; + setTimeout(function () { + if (!$(".popover:hover").length) { + if(!$(self).is(':hover')) { + $(self).popover('hide'); + } + } + }, 100); + }); + } + + $(function(e){ + popover_discount($('a[href$="/website/discount"]')); + $(document).on("change", ".oe_cart input.js_quantity[data-product-id]", function () { + setTimeout(function() { + var $discount = $(document).find('a[href="/website/discount"]'); + popover_discount($discount); + },2000); + }); + + }); +}); \ No newline at end of file diff --git a/addons/website_sale_advance_pricelist/views/asset.xml b/addons/website_sale_advance_pricelist/views/asset.xml new file mode 100644 index 00000000..93d4fe35 --- /dev/null +++ b/addons/website_sale_advance_pricelist/views/asset.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/addons/website_sale_advance_pricelist/views/sale_order_view.xml b/addons/website_sale_advance_pricelist/views/sale_order_view.xml new file mode 100644 index 00000000..03c9ddf4 --- /dev/null +++ b/addons/website_sale_advance_pricelist/views/sale_order_view.xml @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file