blob: bc99e7bd4b6891f376444be877368595162bb7a5 [file] [log] [blame]
Anand Doshiabc10032013-06-14 17:44:03 +05301# Copyright (c) 2012 Web Notes Technologies Pvt Ltd.
2# License: GNU General Public License (v3). For more information see license.txt
3
4from __future__ import unicode_literals
5import webnotes
Anand Doshiabc10032013-06-14 17:44:03 +05306import webnotes.defaults
Anand Doshic2a35272013-06-19 17:19:20 +05307from webnotes.utils import cint, get_fullname, fmt_money
Anand Doshiabc10032013-06-14 17:44:03 +05308
Anand Doshi3dceb842013-06-19 14:57:14 +05309class WebsitePriceListMissingError(webnotes.ValidationError): pass
Anand Doshie8132122013-06-17 15:42:38 +053010
11@webnotes.whitelist()
Anand Doshiedbf3e12013-07-02 11:40:16 +053012def get_cart_quotation(doclist=None):
13 party = get_lead_or_customer()
14
15 if not doclist:
16 doclist = _get_cart_quotation(party).doclist
17
18 return {
19 "doclist": decorate_quotation_doclist(doclist),
20 "addresses": [{"name": address.name, "display": address.display}
21 for address in get_address_docs(party)]
22 }
23
24@webnotes.whitelist()
Anand Doshic2a35272013-06-19 17:19:20 +053025def update_cart(item_code, qty, with_doclist=0):
Anand Doshi3dceb842013-06-19 14:57:14 +053026 quotation = _get_cart_quotation()
Anand Doshiabc10032013-06-14 17:44:03 +053027
Anand Doshic2a35272013-06-19 17:19:20 +053028 qty = cint(qty)
Anand Doshi3dceb842013-06-19 14:57:14 +053029 if qty == 0:
Anand Doshie8132122013-06-17 15:42:38 +053030 quotation.set_doclist(quotation.doclist.get({"item_code": ["!=", item_code]}))
31 else:
32 quotation_items = quotation.doclist.get({"item_code": item_code})
33 if not quotation_items:
34 quotation.doclist.append({
35 "doctype": "Quotation Item",
36 "parentfield": "quotation_details",
37 "item_code": item_code,
Anand Doshi3dceb842013-06-19 14:57:14 +053038 "qty": qty
Anand Doshie8132122013-06-17 15:42:38 +053039 })
40 else:
Anand Doshi3dceb842013-06-19 14:57:14 +053041 quotation_items[0].qty = qty
Anand Doshiabc10032013-06-14 17:44:03 +053042
43 quotation.ignore_permissions = True
44 quotation.save()
45
Anand Doshic2a35272013-06-19 17:19:20 +053046 if with_doclist:
Anand Doshiedbf3e12013-07-02 11:40:16 +053047 return get_cart_quotation(quotation.doclist)
Anand Doshic2a35272013-06-19 17:19:20 +053048 else:
49 return quotation.doc.name
Anand Doshiedbf3e12013-07-02 11:40:16 +053050
51@webnotes.whitelist()
52def update_cart_address(address_fieldname, address_name):
53 from utilities.transaction_base import get_address_display
54
55 quotation = _get_cart_quotation()
56 address_display = get_address_display(webnotes.doc("Address", address_name).fields)
57
58 if address_fieldname == "shipping_address_name":
59 quotation.doc.shipping_address_name = address_name
60 quotation.doc.shipping_address = address_display
61
62 if not quotation.doc.customer_address:
63 address_fieldname == "customer_address"
64
65 if address_fieldname == "customer_address":
66 quotation.doc.customer_address = address_name
67 quotation.doc.address_display = address_display
68
69
70 quotation.ignore_permissions = True
71 quotation.save()
72
73 return get_cart_quotation(quotation.doclist)
74
75@webnotes.whitelist()
76def get_addresses():
77 return [d.fields for d in get_address_docs()]
78
79@webnotes.whitelist()
80def save_address(fields, address_fieldname=None):
81 party = get_lead_or_customer()
82 fields = webnotes.load_json(fields)
83
84 if fields.get("name"):
85 bean = webnotes.bean("Address", fields.get("name"))
86 else:
87 bean = webnotes.bean({"doctype": "Address", "__islocal": 1})
88
89 bean.doc.fields.update(fields)
90
91 party_fieldname = party.doctype.lower()
92 bean.doc.fields.update({
93 party_fieldname: party.name,
94 (party_fieldname + "_name"): party.fields[party_fieldname + "_name"]
95 })
96 bean.ignore_permissions = True
97 bean.save()
98
99 if address_fieldname:
100 update_cart_address(address_fieldname, bean.doc.name)
101
102 return bean.doc.name
103
104def get_address_docs(party=None):
105 from webnotes.model.doclist import objectify
106 from utilities.transaction_base import get_address_display
107
108 if not party:
109 party = get_lead_or_customer()
110
111 address_docs = objectify(webnotes.conn.sql("""select * from `tabAddress`
112 where `%s`=%s order by name""" % (party.doctype.lower(), "%s"), party.name,
113 as_dict=True, update={"doctype": "Address"}))
114
115 for address in address_docs:
116 address.display = get_address_display(address.fields)
117 address.display = (address.display).replace("\n", "<br>\n")
118
119 return address_docs
Anand Doshie8132122013-06-17 15:42:38 +0530120
Anand Doshiabc10032013-06-14 17:44:03 +0530121def get_lead_or_customer():
122 customer = webnotes.conn.get_value("Contact", {"email_id": webnotes.session.user}, "customer")
123 if customer:
124 return webnotes.doc("Customer", customer)
125
126 lead = webnotes.conn.get_value("Lead", {"email_id": webnotes.session.user})
127 if lead:
128 return webnotes.doc("Lead", lead)
129 else:
130 lead_bean = webnotes.bean({
131 "doctype": "Lead",
132 "email_id": webnotes.session.user,
133 "lead_name": get_fullname(webnotes.session.user),
Anand Doshic2a35272013-06-19 17:19:20 +0530134 "territory": webnotes.conn.get_value("Shopping Cart Settings", None, "territory") or \
135 "All Territories",
Anand Doshiabc10032013-06-14 17:44:03 +0530136 "status": "Open" # TODO: set something better???
137 })
138 lead_bean.ignore_permissions = True
139 lead_bean.insert()
140
141 return lead_bean.doc
Anand Doshi3dceb842013-06-19 14:57:14 +0530142
Anand Doshic2a35272013-06-19 17:19:20 +0530143def decorate_quotation_doclist(doclist):
144 for d in doclist:
145 if d.item_code:
146 d.fields.update(webnotes.conn.get_value("Item", d.item_code,
147 ["website_image", "web_short_description", "page_name"], as_dict=True))
148 d.formatted_rate = fmt_money(d.export_rate, currency=doclist[0].currency)
149 d.formatted_amount = fmt_money(d.export_amount, currency=doclist[0].currency)
150
151 return [d.fields for d in doclist]
Anand Doshi3dceb842013-06-19 14:57:14 +0530152
153def _get_cart_quotation(party=None):
154 if not party:
155 party = get_lead_or_customer()
156
Anand Doshiabc10032013-06-14 17:44:03 +0530157 quotation = webnotes.conn.get_value("Quotation",
158 {party.doctype.lower(): party.name, "order_type": "Shopping Cart", "docstatus": 0})
159
160 if quotation:
161 qbean = webnotes.bean("Quotation", quotation)
162 else:
163 qbean = webnotes.bean({
164 "doctype": "Quotation",
165 "naming_series": "QTN-CART-",
Anand Doshic2a35272013-06-19 17:19:20 +0530166 "quotation_to": party.doctype,
Anand Doshiabc10032013-06-14 17:44:03 +0530167 "company": webnotes.defaults.get_user_default("company"),
168 "order_type": "Shopping Cart",
169 "status": "Draft",
170 "__islocal": 1,
171 "price_list_name": get_price_list(party),
172 (party.doctype.lower()): party.name
173 })
174
175 return qbean
Anand Doshiabc10032013-06-14 17:44:03 +0530176
177def get_price_list(party):
178 if not party.default_price_list:
179 party.default_price_list = get_price_list_using_geoip()
180 party.save()
181
182 return party.default_price_list
183
184def get_price_list_using_geoip():
185 country = webnotes.session.get("session_country")
186 price_list_name = None
187
188 if country:
189 price_list_name = webnotes.conn.sql("""select parent
190 from `tabPrice List Country` plc
191 where country=%s and exists (select name from `tabPrice List` pl
Anand Doshic2a35272013-06-19 17:19:20 +0530192 where use_for_website=1 and ifnull(valid_for_all_countries, 0)=0 and
193 pl.name = plc.parent)""", country)
Anand Doshiabc10032013-06-14 17:44:03 +0530194
195 if price_list_name:
196 price_list_name = price_list_name[0][0]
197 else:
198 price_list_name = webnotes.conn.get_value("Price List",
199 {"use_for_website": 1, "valid_for_all_countries": 1})
200
201 if not price_list_name:
Anand Doshi3dceb842013-06-19 14:57:14 +0530202 raise WebsitePriceListMissingError, "No website Price List specified"
Anand Doshiabc10032013-06-14 17:44:03 +0530203
204 return price_list_name
205
Anand Doshiabc10032013-06-14 17:44:03 +0530206
Anand Doshie8132122013-06-17 15:42:38 +0530207@webnotes.whitelist()
208def checkout():
Anand Doshi3dceb842013-06-19 14:57:14 +0530209 quotation = _get_cart_quotation()
Anand Doshie8132122013-06-17 15:42:38 +0530210
211 quotation.ignore_permissions = True
212 quotation.submit()
213
214 sales_order = webnotes.bean(webnotes.map_doclist([["Quotation", "Sales Order"], ["Quotation Item", "Sales Order Item"],
215 ["Sales Taxes and Charges", "Sales Taxes and Charges"]], quotation.doc.name))
216
217 sales_order.ignore_permissions = True
218 sales_order.insert()
219 sales_order.submit()
220
221 return sales_order
222
223import unittest
224test_dependencies = ["Item", "Price List", "Contact"]
Anand Doshiabc10032013-06-14 17:44:03 +0530225
226class TestCart(unittest.TestCase):
Anand Doshie8132122013-06-17 15:42:38 +0530227 def test_get_lead_or_customer(self):
228 webnotes.session.user = "test@example.com"
229 party1 = get_lead_or_customer()
230 party2 = get_lead_or_customer()
231 self.assertEquals(party1.name, party2.name)
232 self.assertEquals(party1.doctype, "Lead")
233
234 webnotes.session.user = "test_contact_customer@example.com"
235 party = get_lead_or_customer()
236 self.assertEquals(party.name, "_Test Customer")
237
Anand Doshiabc10032013-06-14 17:44:03 +0530238 def test_add_to_cart(self):
239 webnotes.session.user = "test@example.com"
Anand Doshi3dceb842013-06-19 14:57:14 +0530240 update_cart("_Test Item", 1)
Anand Doshiabc10032013-06-14 17:44:03 +0530241
Anand Doshi3dceb842013-06-19 14:57:14 +0530242 quotation = _get_cart_quotation()
Anand Doshie8132122013-06-17 15:42:38 +0530243 quotation_items = quotation.doclist.get({"parentfield": "quotation_details", "item_code": "_Test Item"})
244 self.assertTrue(quotation_items)
245 self.assertEquals(quotation_items[0].qty, 1)
246
247 return quotation
248
Anand Doshi3dceb842013-06-19 14:57:14 +0530249 def test_update_cart(self):
Anand Doshie8132122013-06-17 15:42:38 +0530250 self.test_add_to_cart()
251
Anand Doshi3dceb842013-06-19 14:57:14 +0530252 update_cart("_Test Item", 5)
Anand Doshie8132122013-06-17 15:42:38 +0530253
Anand Doshi3dceb842013-06-19 14:57:14 +0530254 quotation = _get_cart_quotation()
Anand Doshie8132122013-06-17 15:42:38 +0530255 quotation_items = quotation.doclist.get({"parentfield": "quotation_details", "item_code": "_Test Item"})
256 self.assertTrue(quotation_items)
257 self.assertEquals(quotation_items[0].qty, 5)
258
259 return quotation
Anand Doshiabc10032013-06-14 17:44:03 +0530260
261 def test_remove_from_cart(self):
Anand Doshie8132122013-06-17 15:42:38 +0530262 quotation0 = self.test_add_to_cart()
263
Anand Doshi3dceb842013-06-19 14:57:14 +0530264 update_cart("_Test Item", 0)
Anand Doshie8132122013-06-17 15:42:38 +0530265
Anand Doshi3dceb842013-06-19 14:57:14 +0530266 quotation = _get_cart_quotation()
Anand Doshie8132122013-06-17 15:42:38 +0530267 self.assertEquals(quotation0.doc.name, quotation.doc.name)
268
269 quotation_items = quotation.doclist.get({"parentfield": "quotation_details", "item_code": "_Test Item"})
270 self.assertEquals(quotation_items, [])
Anand Doshiabc10032013-06-14 17:44:03 +0530271
272 def test_checkout(self):
Anand Doshi3dceb842013-06-19 14:57:14 +0530273 quotation = self.test_update_cart()
Anand Doshie8132122013-06-17 15:42:38 +0530274 sales_order = checkout()
275 self.assertEquals(sales_order.doclist.getone({"item_code": "_Test Item"}).prevdoc_docname, quotation.doc.name)
Anand Doshiabc10032013-06-14 17:44:03 +0530276