From c2a352711f0c422565c25bca65cb57fc3fbbe4cd Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Wed, 19 Jun 2013 17:19:20 +0530 Subject: [PATCH] [shopping cart] show items, editable qty and show amount for that item --- public/js/website_utils.js | 3 +- selling/doctype/quotation/quotation.txt | 4 +- selling/utils.py | 2 +- setup/doctype/price_list/price_list.py | 19 +++ setup/doctype/price_list/price_list.txt | 4 +- website/css/website.css | 10 ++ .../shopping_cart_settings/__init__.py | 0 .../shopping_cart_settings.py | 8 + .../shopping_cart_settings.txt | 51 +++++++ website/helpers/cart.py | 30 +++- website/page/website_home/website_home.js | 6 + website/templates/html/product_page.html | 6 +- website/templates/js/cart.js | 139 ++++++++++++------ website/templates/pages/cart.html | 11 +- 14 files changed, 232 insertions(+), 61 deletions(-) create mode 100644 website/doctype/shopping_cart_settings/__init__.py create mode 100644 website/doctype/shopping_cart_settings/shopping_cart_settings.py create mode 100644 website/doctype/shopping_cart_settings/shopping_cart_settings.txt diff --git a/public/js/website_utils.js b/public/js/website_utils.js index 83becc6b0e..098f8da188 100644 --- a/public/js/website_utils.js +++ b/public/js/website_utils.js @@ -193,7 +193,8 @@ $.extend(wn.cart, { method: "website.helpers.cart.update_cart", args: { item_code: opts.item_code, - qty: opts.qty + qty: opts.qty, + with_doclist: opts.with_doclist }, btn: opts.btn, callback: function(r) { diff --git a/selling/doctype/quotation/quotation.txt b/selling/doctype/quotation/quotation.txt index 1017221bf6..74a4396aef 100644 --- a/selling/doctype/quotation/quotation.txt +++ b/selling/doctype/quotation/quotation.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-24 19:29:08", "docstatus": 0, - "modified": "2013-06-05 19:07:51", + "modified": "2013-06-19 15:55:15", "modified_by": "Administrator", "owner": "Administrator" }, @@ -223,7 +223,7 @@ "label": "Order Type", "oldfieldname": "order_type", "oldfieldtype": "Select", - "options": "\nSales\nMaintenance", + "options": "\nSales\nMaintenance\nShopping Cart", "print_hide": 1, "read_only": 0, "reqd": 1, diff --git a/selling/utils.py b/selling/utils.py index 61eab59dfc..bd04db570e 100644 --- a/selling/utils.py +++ b/selling/utils.py @@ -134,7 +134,7 @@ def _get_price_list_rate(args, item_bean, meta): base_ref_rate = item_bean.doclist.get({ "parentfield": "ref_rate_details", "price_list_name": args.price_list_name, - "price_list_currency": args.price_list_currency, + "ref_currency": args.price_list_currency, "buying_or_selling": "Selling"}) if not base_ref_rate: diff --git a/setup/doctype/price_list/price_list.py b/setup/doctype/price_list/price_list.py index c4feb60a2e..e6e7b7f61c 100644 --- a/setup/doctype/price_list/price_list.py +++ b/setup/doctype/price_list/price_list.py @@ -33,6 +33,25 @@ class DocType(DocListController): if self.doc.buying_or_selling not in ["Buying", "Selling"]: msgprint(_(self.meta.get_label("buying_or_selling")) + " " + _("must be one of") + " " + comma_or(["Buying", "Selling"]), raise_exception=True) + + self.validate_use_for_website() + + def validate_use_for_website(self): + if self.doc.use_for_website: + if self.doc.valid_for_all_countries: + if webnotes.conn.sql("""select name from `tabPrice List` where use_for_website=1 + and valid_for_all_countries=1 and name!=%s""", self.doc.name): + webnotes.msgprint(_("Error: Another Price List already exists that is used for website and is valid for all countries."), + raise_exception=True) + + elif self.doclist.get({"parentfield": "valid_for_countries"}): + for d in self.doclist.get({"parentfield": "valid_for_countries"}): + if webnotes.conn.sql("""select country from `tabPrice List Country` plc, `tabPrice List` pl + where plc.parent=pl.name and pl.use_for_website=1 and + ifnull(valid_for_all_countries, 0)=0 and country=%s and pl.name!=%s""", + (d.country, self.doc.name)): + webnotes.msgprint(_("Error: Another Price List already exists that is used for website and is valid for country") + + ": " + d.country, raise_exception=True) def on_trash(self): webnotes.conn.sql("""delete from `tabItem Price` where price_list_name = %s""", diff --git a/setup/doctype/price_list/price_list.txt b/setup/doctype/price_list/price_list.txt index daffecedc3..8115f3d32b 100644 --- a/setup/doctype/price_list/price_list.txt +++ b/setup/doctype/price_list/price_list.txt @@ -2,13 +2,13 @@ { "creation": "2013-01-25 11:35:09", "docstatus": 0, - "modified": "2013-06-14 16:07:25", + "modified": "2013-06-19 15:24:23", "modified_by": "Administrator", "owner": "Administrator" }, { "allow_attach": 0, - "allow_copy": 1, + "allow_copy": 0, "allow_email": 1, "allow_print": 1, "autoname": "field:price_list_name", diff --git a/website/css/website.css b/website/css/website.css index 7efceb2e63..737d3d0f4e 100644 --- a/website/css/website.css +++ b/website/css/website.css @@ -117,3 +117,13 @@ a { margin-top: -10px; margin-left: -10px; } + +.hidden-sm-inline { + display: none; +} + +@media (min-width: 768px) { + .hidden-sm-inline { + display: inline; + } +} \ No newline at end of file diff --git a/website/doctype/shopping_cart_settings/__init__.py b/website/doctype/shopping_cart_settings/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/website/doctype/shopping_cart_settings/shopping_cart_settings.py b/website/doctype/shopping_cart_settings/shopping_cart_settings.py new file mode 100644 index 0000000000..928aa9ff9f --- /dev/null +++ b/website/doctype/shopping_cart_settings/shopping_cart_settings.py @@ -0,0 +1,8 @@ +# For license information, please see license.txt + +from __future__ import unicode_literals +import webnotes + +class DocType: + def __init__(self, d, dl): + self.doc, self.doclist = d, dl \ No newline at end of file diff --git a/website/doctype/shopping_cart_settings/shopping_cart_settings.txt b/website/doctype/shopping_cart_settings/shopping_cart_settings.txt new file mode 100644 index 0000000000..627c1274c6 --- /dev/null +++ b/website/doctype/shopping_cart_settings/shopping_cart_settings.txt @@ -0,0 +1,51 @@ +[ + { + "creation": "2013-06-19 15:57:32", + "docstatus": 0, + "modified": "2013-06-19 16:01:25", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "description": "Default settings for Shopping Cart", + "doctype": "DocType", + "issingle": 1, + "module": "Website", + "name": "__common__" + }, + { + "doctype": "DocField", + "fieldname": "territory", + "fieldtype": "Link", + "label": "Default Territory", + "name": "__common__", + "options": "Territory", + "parent": "Shopping Cart Settings", + "parentfield": "fields", + "parenttype": "DocType", + "permlevel": 0, + "reqd": 1 + }, + { + "create": 1, + "doctype": "DocPerm", + "name": "__common__", + "parent": "Shopping Cart Settings", + "parentfield": "permissions", + "parenttype": "DocType", + "permlevel": 0, + "read": 1, + "role": "Website Manager", + "write": 1 + }, + { + "doctype": "DocType", + "name": "Shopping Cart Settings" + }, + { + "doctype": "DocField" + }, + { + "doctype": "DocPerm" + } +] \ No newline at end of file diff --git a/website/helpers/cart.py b/website/helpers/cart.py index b62e0bb7cf..a24afb57a9 100644 --- a/website/helpers/cart.py +++ b/website/helpers/cart.py @@ -3,16 +3,16 @@ from __future__ import unicode_literals import webnotes -from webnotes import _, msgprint import webnotes.defaults -from webnotes.utils import today, get_fullname +from webnotes.utils import cint, get_fullname, fmt_money class WebsitePriceListMissingError(webnotes.ValidationError): pass @webnotes.whitelist() -def update_cart(item_code, qty): +def update_cart(item_code, qty, with_doclist=0): quotation = _get_cart_quotation() + qty = cint(qty) if qty == 0: quotation.set_doclist(quotation.doclist.get({"item_code": ["!=", item_code]})) else: @@ -30,7 +30,10 @@ def update_cart(item_code, qty): quotation.ignore_permissions = True quotation.save() - return quotation.doc.name + if with_doclist: + return decorate_quotation_doclist(quotation.doclist) + else: + return quotation.doc.name def get_lead_or_customer(): customer = webnotes.conn.get_value("Contact", {"email_id": webnotes.session.user}, "customer") @@ -45,6 +48,8 @@ def get_lead_or_customer(): "doctype": "Lead", "email_id": webnotes.session.user, "lead_name": get_fullname(webnotes.session.user), + "territory": webnotes.conn.get_value("Shopping Cart Settings", None, "territory") or \ + "All Territories", "status": "Open" # TODO: set something better??? }) lead_bean.ignore_permissions = True @@ -55,8 +60,18 @@ def get_lead_or_customer(): @webnotes.whitelist() def get_cart_quotation(): - return [d.fields for d in _get_cart_quotation(get_lead_or_customer()).doclist] + doclist = _get_cart_quotation(get_lead_or_customer()).doclist + return decorate_quotation_doclist(doclist) +def decorate_quotation_doclist(doclist): + for d in doclist: + if d.item_code: + d.fields.update(webnotes.conn.get_value("Item", d.item_code, + ["website_image", "web_short_description", "page_name"], as_dict=True)) + d.formatted_rate = fmt_money(d.export_rate, currency=doclist[0].currency) + d.formatted_amount = fmt_money(d.export_amount, currency=doclist[0].currency) + + return [d.fields for d in doclist] def _get_cart_quotation(party=None): if not party: @@ -71,7 +86,7 @@ def _get_cart_quotation(party=None): qbean = webnotes.bean({ "doctype": "Quotation", "naming_series": "QTN-CART-", - "quotation_to": "Customer", + "quotation_to": party.doctype, "company": webnotes.defaults.get_user_default("company"), "order_type": "Shopping Cart", "status": "Draft", @@ -97,7 +112,8 @@ def get_price_list_using_geoip(): price_list_name = webnotes.conn.sql("""select parent from `tabPrice List Country` plc where country=%s and exists (select name from `tabPrice List` pl - where use_for_website=1 and pl.name = plc.parent)""", country) + where use_for_website=1 and ifnull(valid_for_all_countries, 0)=0 and + pl.name = plc.parent)""", country) if price_list_name: price_list_name = price_list_name[0][0] diff --git a/website/page/website_home/website_home.js b/website/page/website_home/website_home.js index 71f2f4d2cd..fb612df11d 100644 --- a/website/page/website_home/website_home.js +++ b/website/page/website_home/website_home.js @@ -63,6 +63,12 @@ wn.module_page["Website"] = [ "description":wn._("Setup of fonts and background."), doctype:"Style Settings" }, + { + "route":"Form/Shopping Cart Settings", + "label":wn._("Shopping Cart Settings"), + "description":wn._("Setup of Shopping Cart."), + doctype:"Shopping Cart Settings" + }, ] }, { diff --git a/website/templates/html/product_page.html b/website/templates/html/product_page.html index 837b105702..bf1ecc066b 100644 --- a/website/templates/html/product_page.html +++ b/website/templates/html/product_page.html @@ -40,12 +40,14 @@

- +
diff --git a/website/templates/js/cart.js b/website/templates/js/cart.js index 121ca6ab81..e4bd6b2917 100644 --- a/website/templates/js/cart.js +++ b/website/templates/js/cart.js @@ -19,12 +19,10 @@ $(document).ready(function() { // make list of items in the cart // wn.cart.render(); - // wn.cart.bind_events(); + wn.cart.bind_events(); wn.call({ + type: "POST", method: "website.helpers.cart.get_cart_quotation", - args: { - _type: "POST" - }, callback: function(r) { console.log(r); $("#cart-container").removeClass("hide"); @@ -36,11 +34,7 @@ $(document).ready(function() { wn.cart.show_error("Oops!", "Something went wrong."); } } else { - if(r.message[0].__islocal) { - wn.cart.show_error("Empty :-(", "Go ahead and add something to your cart."); - } else { - wn.cart.render(r.message); - } + wn.cart.render(r.message); } } @@ -54,19 +48,74 @@ $.extend(wn.cart, { $("#cart-container").html('

' + title + '

' + text + '
'); }, + bind_events: function() { + // bind update button + $(document).on("click", ".item-update-cart button", function() { + console.log("click!"); + var item_code = $(this).attr("data-item-code"); + wn.cart.update_cart({ + item_code: item_code, + qty: $('input[data-item-code="'+item_code+'"]').val(), + with_doclist: 1, + btn: this, + callback: function(r) { + if(!r.exc) { + wn.cart.render(r.message); + var $button = $('button[data-item-code="'+item_code+'"]').addClass("btn-success"); + setTimeout(function() { $button.removeClass("btn-success"); }, 1000); + } + }, + }); + }); + }, + render: function(doclist) { - return; var $cart_wrapper = $("#cart-items").empty(); - if(Object.keys(wn.cart.get_cart()).length) { - $('
\ -
\ -
\ -
\ -
Item Details
\ + + if($.map(doclist, function(d) { return d.item_code || null;}).length===0) { + wn.cart.show_error("Empty :-(", "Go ahead and add something to your cart."); + return; + } + + $.each(doclist, function(i, doc) { + if(doc.doctype === "Quotation Item") { + doc.image_html = doc.image ? + '
' : + '{% include "app/website/templates/html/product_missing_image.html" %}'; + + if(!doc.web_short_description) doc.web_short_description = doc.description; + + $(repl('
\ +
\ +
\ +
%(image_html)s
\ +
\ +

%(item_name)s

\ +

%(web_short_description)s

\ +
\ +
\
\ -
\ -
Qty
\ -

').appendTo($cart_wrapper); +
\ +
\ + \ +
\ + \ +
\ +
\ +

at %(formatted_rate)s

\ + = %(formatted_amount)s\ +
\ +

', doc)).appendTo($cart_wrapper); + + } + }); + + return; + + if(Object.keys(wn.cart.get_cart()).length) { $.each(wn.cart.get_cart(), function(item_code, item) { item.image_html = item.image ? @@ -101,30 +150,30 @@ $.extend(wn.cart, { } }, - bind_events: function() { - // on change of qty - $(".cart-input-qty").on("change", function on_change_of_qty() { - wn.cart.set_value_in_cart($(this).attr("item_code"), "qty", $(this).val()); - }); - - // shopping cart button - $(".checkout-btn").on("click", function() { - console.log("checkout!"); - console.log(wn.cart.get_cart()); - - var user_is_logged_in = getCookie("full_name"); - if(user_is_logged_in) { - wn.call({ - method: "website.helpers.cart.checkout", - args: {cart: wn.cart.get_cart()}, - btn: this, - callback: function(r) { - console.log(r); - } - }); - } else { - window.location.href = "login?from=cart"; - } - }); - } + // bind_events: function() { + // // on change of qty + // $(".cart-input-qty").on("change", function on_change_of_qty() { + // wn.cart.set_value_in_cart($(this).attr("item_code"), "qty", $(this).val()); + // }); + // + // // shopping cart button + // $(".checkout-btn").on("click", function() { + // console.log("checkout!"); + // console.log(wn.cart.get_cart()); + // + // var user_is_logged_in = getCookie("full_name"); + // if(user_is_logged_in) { + // wn.call({ + // method: "website.helpers.cart.checkout", + // args: {cart: wn.cart.get_cart()}, + // btn: this, + // callback: function(r) { + // console.log(r); + // } + // }); + // } else { + // window.location.href = "login?from=cart"; + // } + // }); + // } }); \ No newline at end of file diff --git a/website/templates/pages/cart.html b/website/templates/pages/cart.html index ada15770f8..2619dec08c 100644 --- a/website/templates/pages/cart.html +++ b/website/templates/pages/cart.html @@ -8,7 +8,7 @@ {% block content %}
-

Shopping Cart

+

Shopping Cart

@@ -16,6 +16,15 @@

+
+
+
+
+
Item Details
+
+
+
Qty
+