blob: 4b7017341afa327ae5e4ca4f5af77032c20d2b0f [file] [log] [blame]
Anand Doshi885e0742015-03-03 14:55:30 +05301// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
Rushabh Mehta3daa49a2014-10-21 16:16:30 +05302// License: GNU General Public License v3. See license.txt
3
4// js inside blog page
5
6// shopping cart
7frappe.provide("shopping_cart");
8
9$.extend(shopping_cart, {
10 show_error: function(title, text) {
Rushabh Mehtaa5b149c2014-12-25 17:17:32 +053011 $("#cart-container").html('<div class="msg-box"><h4>' + title + '</h4> ' + text + '</div>');
Rushabh Mehta3daa49a2014-10-21 16:16:30 +053012 },
13
14 bind_events: function() {
15 // bind update button
16 $(document).on("click", ".item-update-cart button", function() {
17 var item_code = $(this).attr("data-item-code");
18 shopping_cart.update_cart({
19 item_code: item_code,
20 qty: $('input[data-item-code="'+item_code+'"]').val(),
21 with_doc: 1,
22 btn: this,
23 callback: function(r) {
24 if(!r.exc) {
25 shopping_cart.render(r.message);
26 var $button = $('button[data-item-code="'+item_code+'"]').addClass("btn-success");
27 setTimeout(function() { $button.removeClass("btn-success"); }, 1000);
28 }
29 },
30 });
31 });
32
33 $("#cart-add-shipping-address").on("click", function() {
34 window.location.href = "address?address_fieldname=shipping_address_name";
35 });
36
37 $("#cart-add-billing-address").on("click", function() {
38 window.location.href = "address?address_fieldname=customer_address";
39 });
40
41 $(".btn-place-order").on("click", function() {
42 shopping_cart.place_order(this);
43 });
44 },
45
46 render: function(out) {
47 var doc = out.doc;
48 var addresses = out.addresses;
49
50 var $cart_items = $("#cart-items").empty();
51 var $cart_taxes = $("#cart-taxes").empty();
52 var $cart_totals = $("#cart-totals").empty();
53 var $cart_billing_address = $("#cart-billing-address").empty();
54 var $cart_shipping_address = $("#cart-shipping-address").empty();
55
Nabin Haite7d15362014-12-25 16:01:55 +053056 var no_items = $.map(doc.items || [],
Rushabh Mehta3daa49a2014-10-21 16:16:30 +053057 function(d) { return d.item_code || null;}).length===0;
58 if(no_items) {
59 shopping_cart.show_error("Empty :-(", frappe._("Go ahead and add something to your cart."));
60 $("#cart-addresses").toggle(false);
61 return;
62 }
63
64 var shipping_rule_added = false;
65 var taxes_exist = false;
66 var shipping_rule_labels = $.map(out.shipping_rules || [], function(rule) { return rule[1]; });
67
Nabin Haite7d15362014-12-25 16:01:55 +053068 $.each(doc.items || [], function(i, d) {
Rushabh Mehta3daa49a2014-10-21 16:16:30 +053069 shopping_cart.render_item_row($cart_items, d);
70 });
71
Nabin Haite7d15362014-12-25 16:01:55 +053072 $.each(doc.taxes || [], function(i, d) {
Rushabh Mehta3daa49a2014-10-21 16:16:30 +053073 if(out.shipping_rules && out.shipping_rules.length &&
74 shipping_rule_labels.indexOf(d.description)!==-1) {
75 shipping_rule_added = true;
76 shopping_cart.render_tax_row($cart_taxes, d, out.shipping_rules);
77 } else {
78 shopping_cart.render_tax_row($cart_taxes, d);
79 }
80
81 taxes_exist = true;
82 });
83
84 if(out.shipping_rules && out.shipping_rules.length && !shipping_rule_added) {
85 shopping_cart.render_tax_row($cart_taxes, {description: "", formatted_tax_amount: ""},
86 out.shipping_rules);
87 taxes_exist = true;
88 }
89
90 if(taxes_exist)
91 $('<hr>').appendTo($cart_taxes);
92
93 shopping_cart.render_tax_row($cart_totals, {
94 description: "<strong>Total</strong>",
95 formatted_tax_amount: "<strong>" + doc.formatted_grand_total_export + "</strong>"
96 });
97
98 if(!(addresses && addresses.length)) {
Rushabh Mehtaa5b149c2014-12-25 17:17:32 +053099 $cart_shipping_address.html('<div class="msg-box">'+frappe._("Hey! Go ahead and add an address")+'</div>');
Rushabh Mehta3daa49a2014-10-21 16:16:30 +0530100 } else {
101 shopping_cart.render_address($cart_shipping_address, addresses, doc.shipping_address_name);
102 shopping_cart.render_address($cart_billing_address, addresses, doc.customer_address);
103 }
104 },
105
106 render_item_row: function($cart_items, doc) {
107 doc.image_html = doc.website_image ?
Anand Doshida858cc2015-02-24 17:50:44 +0530108 '<div style="height: 120px; overflow: hidden;"><img src="' + doc.website_image + '" /></div>': "";
Rushabh Mehta3daa49a2014-10-21 16:16:30 +0530109
110 if(doc.description === doc.item_name) doc.description = "";
111
112 $(repl('<div class="row">\
113 <div class="col-md-9 col-sm-9">\
114 <div class="row">\
115 <div class="col-md-3">%(image_html)s</div>\
116 <div class="col-md-9">\
117 <h4><a href="%(page_name)s">%(item_name)s</a></h4>\
118 <p>%(description)s</p>\
119 </div>\
120 </div>\
121 </div>\
122 <div class="col-md-3 col-sm-3 text-right">\
123 <div class="input-group item-update-cart">\
124 <input type="text" placeholder="Qty" value="%(qty)s" \
125 data-item-code="%(item_code)s" class="text-right form-control">\
126 <div class="input-group-btn">\
127 <button class="btn btn-primary" data-item-code="%(item_code)s">\
128 <i class="icon-ok"></i></button>\
129 </div>\
130 </div>\
131 <p style="margin-top: 10px;">at %(formatted_rate)s</p>\
132 <small class="text-muted" style="margin-top: 10px;">= %(formatted_amount)s</small>\
133 </div>\
134 </div><hr>', doc)).appendTo($cart_items);
135 },
136
137 render_tax_row: function($cart_taxes, doc, shipping_rules) {
138 var shipping_selector;
139 if(shipping_rules) {
140 shipping_selector = '<select class="form-control">' + $.map(shipping_rules, function(rule) {
141 return '<option value="' + rule[0] + '">' + rule[1] + '</option>' }).join("\n") +
142 '</select>';
143 }
144
145 var $tax_row = $(repl('<div class="row">\
146 <div class="col-md-9 col-sm-9">\
147 <div class="row">\
148 <div class="col-md-9 col-md-offset-3">' +
149 (shipping_selector || '<p>%(description)s</p>') +
150 '</div>\
151 </div>\
152 </div>\
153 <div class="col-md-3 col-sm-3 text-right">\
154 <p' + (shipping_selector ? ' style="margin-top: 5px;"' : "") + '>%(formatted_tax_amount)s</p>\
155 </div>\
156 </div>', doc)).appendTo($cart_taxes);
157
158 if(shipping_selector) {
159 $tax_row.find('select option').each(function(i, opt) {
160 if($(opt).html() == doc.description) {
161 $(opt).attr("selected", "selected");
162 }
163 });
164 $tax_row.find('select').on("change", function() {
165 shopping_cart.apply_shipping_rule($(this).val(), this);
166 });
167 }
168 },
169
170 apply_shipping_rule: function(rule, btn) {
171 return frappe.call({
172 btn: btn,
173 type: "POST",
174 method: "erpnext.shopping_cart.cart.apply_shipping_rule",
175 args: { shipping_rule: rule },
176 callback: function(r) {
177 if(!r.exc) {
178 shopping_cart.render(r.message);
179 }
180 }
181 });
182 },
183
184 render_address: function($address_wrapper, addresses, address_name) {
185 $.each(addresses, function(i, address) {
186 $(repl('<div class="panel panel-default"> \
187 <div class="panel-heading"> \
188 <div class="row"> \
189 <div class="col-md-10 address-title" \
190 data-address-name="%(name)s"><strong>%(name)s</strong></div> \
191 <div class="col-md-2"><input type="checkbox" \
192 data-address-name="%(name)s"></div> \
193 </div> \
194 </div> \
195 <div class="panel-collapse collapse" data-address-name="%(name)s"> \
196 <div class="panel-body">%(display)s</div> \
197 </div> \
198 </div>', address))
199 .css({"margin": "10px auto"})
200 .appendTo($address_wrapper);
201 });
202
203 $address_wrapper.find(".panel-heading")
204 .find(".address-title")
205 .css({"cursor": "pointer"})
206 .on("click", function() {
207 $address_wrapper.find('.panel-collapse[data-address-name="'
208 +$(this).attr("data-address-name")+'"]').collapse("toggle");
209 });
210
211 $address_wrapper.find('input[type="checkbox"]').on("click", function() {
212 if($(this).prop("checked")) {
213 var me = this;
214 $address_wrapper.find('input[type="checkbox"]').each(function(i, chk) {
215 if($(chk).attr("data-address-name")!=$(me).attr("data-address-name")) {
216 $(chk).prop("checked", false);
217 }
218 });
219
220 return frappe.call({
221 type: "POST",
222 method: "erpnext.shopping_cart.cart.update_cart_address",
223 args: {
224 address_fieldname: $address_wrapper.attr("data-fieldname"),
225 address_name: $(this).attr("data-address-name")
226 },
227 callback: function(r) {
228 if(!r.exc) {
229 shopping_cart.render(r.message);
230 }
231 }
232 });
233 } else {
234 return false;
235 }
236 });
237
238 $address_wrapper.find('input[type="checkbox"][data-address-name="'+ address_name +'"]')
239 .prop("checked", true);
240
241 $address_wrapper.find(".panel-collapse").collapse({
242 parent: $address_wrapper,
243 toggle: false
244 });
245
246 $address_wrapper.find('.panel-collapse[data-address-name="'+ address_name +'"]')
247 .collapse("show");
248 },
249
250 place_order: function(btn) {
251 return frappe.call({
252 type: "POST",
253 method: "erpnext.shopping_cart.cart.place_order",
254 btn: btn,
255 callback: function(r) {
256 if(r.exc) {
257 var msg = "";
258 if(r._server_messages) {
259 msg = JSON.parse(r._server_messages || []).join("<br>");
260 }
261
262 $("#cart-error")
263 .empty()
264 .html(msg || frappe._("Something went wrong!"))
265 .toggle(true);
266 } else {
Anand Doshida858cc2015-02-24 17:50:44 +0530267 window.location.href = "/orders/" + encodeURIComponent(r.message);
Rushabh Mehta3daa49a2014-10-21 16:16:30 +0530268 }
269 }
270 });
271 }
272});
273
274$(document).ready(function() {
275 shopping_cart.bind_events();
276 return frappe.call({
277 type: "POST",
278 method: "erpnext.shopping_cart.cart.get_cart_quotation",
279 callback: function(r) {
280 $("#cart-container").removeClass("hide");
281 $(".progress").remove();
282 if(r.exc) {
283 if(r.exc.indexOf("WebsitePriceListMissingError")!==-1) {
284 shopping_cart.show_error("Oops!", frappe._("Price List not configured."));
285 } else if(r["403"]) {
286 shopping_cart.show_error("Hey!", frappe._("You need to be logged in to view your cart."));
287 } else {
288 shopping_cart.show_error("Oops!", frappe._("Something went wrong."));
289 }
290 } else {
291 shopping_cart.set_cart_count();
292 shopping_cart.render(r.message);
293 }
294 }
295 });
296});