From 1cc836d92cfd20c8cb8391efafa0717dc03a6f2f Mon Sep 17 00:00:00 2001 From: Haresh Chavda Date: Mon, 21 May 2018 14:03:13 +0530 Subject: [PATCH] [ADD] Website Sale Advance Pricelist --- .../__init__.py | 5 + .../__manifest__.py | 24 ++ .../controllers/__init__.py | 4 + .../controllers/main.py | 78 ++++ .../data/pricelist_view.xml | 22 + .../demo/sale_order_demo.xml | 387 ++++++++++++++++++ .../models/__init__.py | 4 + .../models/sale.py | 42 ++ .../static/description/icon.png | Bin 0 -> 2873 bytes .../static/src/js/discount.js | 57 +++ .../views/asset.xml | 8 + .../views/sale_order_view.xml | 203 +++++++++ 12 files changed, 834 insertions(+) create mode 100644 addons/website_sale_advance_pricelist/__init__.py create mode 100644 addons/website_sale_advance_pricelist/__manifest__.py create mode 100644 addons/website_sale_advance_pricelist/controllers/__init__.py create mode 100644 addons/website_sale_advance_pricelist/controllers/main.py create mode 100644 addons/website_sale_advance_pricelist/data/pricelist_view.xml create mode 100644 addons/website_sale_advance_pricelist/demo/sale_order_demo.xml create mode 100644 addons/website_sale_advance_pricelist/models/__init__.py create mode 100644 addons/website_sale_advance_pricelist/models/sale.py create mode 100644 addons/website_sale_advance_pricelist/static/description/icon.png create mode 100644 addons/website_sale_advance_pricelist/static/src/js/discount.js create mode 100644 addons/website_sale_advance_pricelist/views/asset.xml create mode 100644 addons/website_sale_advance_pricelist/views/sale_order_view.xml 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 0000000000000000000000000000000000000000..088d515b1397cd6afc52f78125ed6bb3ced1052e GIT binary patch literal 2873 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 literal 0 HcmV?d00001 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