# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
# License: GNU General Public License v3. See license.txt

from __future__ import unicode_literals
import webnotes
from webnotes import msgprint, _
import webnotes.defaults
from webnotes.utils import flt, get_fullname, fmt_money, cstr

class WebsitePriceListMissingError(webnotes.ValidationError): pass

def set_cart_count(quotation=None):
	if not quotation:
		quotation = _get_cart_quotation()
	webnotes.add_cookies["cart_count"] = cstr(len(quotation.doclist.get(
		{"parentfield": "quotation_details"})) or "")

@webnotes.whitelist()
def get_cart_quotation(doclist=None):
	party = get_lead_or_customer()
	
	if not doclist:
		quotation = _get_cart_quotation(party)
		doclist = quotation.doclist
		set_cart_count(quotation)
	
	return {
		"doclist": decorate_quotation_doclist(doclist),
		"addresses": [{"name": address.name, "display": address.display} 
			for address in get_address_docs(party)],
		"shipping_rules": get_applicable_shipping_rules(party)
	}
	
@webnotes.whitelist()
def place_order():
	quotation = _get_cart_quotation()
	controller = quotation.make_controller()
	for fieldname in ["customer_address", "shipping_address_name"]:
		if not quotation.doc.fields.get(fieldname):
			msgprint(_("Please select a") + " " + _(controller.meta.get_label(fieldname)), raise_exception=True)
	
	quotation.ignore_permissions = True
	quotation.submit()
	
	from selling.doctype.quotation.quotation import _make_sales_order
	sales_order = webnotes.bean(_make_sales_order(quotation.doc.name, ignore_permissions=True))
	sales_order.ignore_permissions = True
	sales_order.insert()
	sales_order.submit()
	webnotes.add_cookies["cart_count"] = ""
	
	return sales_order.doc.name

@webnotes.whitelist()
def update_cart(item_code, qty, with_doclist=0):
	quotation = _get_cart_quotation()
	
	qty = flt(qty)
	if qty == 0:
		quotation.set_doclist(quotation.doclist.get({"item_code": ["!=", item_code]}))
		if not quotation.doclist.get({"parentfield": "quotation_details"}) and \
			not quotation.doc.fields.get("__islocal"):
				quotation.__delete = True
			
	else:
		quotation_items = quotation.doclist.get({"item_code": item_code})
		if not quotation_items:
			quotation.doclist.append({
				"doctype": "Quotation Item",
				"parentfield": "quotation_details",
				"item_code": item_code,
				"qty": qty
			})
		else:
			quotation_items[0].qty = qty
	
	apply_cart_settings(quotation=quotation)

	if hasattr(quotation, "__delete"):
		webnotes.delete_doc("Quotation", quotation.doc.name, ignore_permissions=True)
		quotation = _get_cart_quotation()
	else:
		quotation.ignore_permissions = True
		quotation.save()
	
	set_cart_count(quotation)
	
	if with_doclist:
		return get_cart_quotation(quotation.doclist)
	else:
		return quotation.doc.name
		
@webnotes.whitelist()
def update_cart_address(address_fieldname, address_name):
	from utilities.transaction_base import get_address_display
	
	quotation = _get_cart_quotation()
	address_display = get_address_display(webnotes.doc("Address", address_name).fields)
	
	if address_fieldname == "shipping_address_name":
		quotation.doc.shipping_address_name = address_name
		quotation.doc.shipping_address = address_display
		
		if not quotation.doc.customer_address:
			address_fieldname == "customer_address"
	
	if address_fieldname == "customer_address":
		quotation.doc.customer_address = address_name
		quotation.doc.address_display = address_display
		
	
	apply_cart_settings(quotation=quotation)
	
	quotation.ignore_permissions = True
	quotation.save()
		
	return get_cart_quotation(quotation.doclist)

@webnotes.whitelist()
def get_addresses():
	return [d.fields for d in get_address_docs()]
	
@webnotes.whitelist()
def save_address(fields, address_fieldname=None):
	party = get_lead_or_customer()
	fields = webnotes.load_json(fields)
	
	if fields.get("name"):
		bean = webnotes.bean("Address", fields.get("name"))
	else:
		bean = webnotes.bean({"doctype": "Address", "__islocal": 1})
	
	bean.doc.fields.update(fields)
	
	party_fieldname = party.doctype.lower()
	bean.doc.fields.update({
		party_fieldname: party.name,
		(party_fieldname + "_name"): party.fields[party_fieldname + "_name"]
	})
	bean.ignore_permissions = True
	bean.save()
	
	if address_fieldname:
		update_cart_address(address_fieldname, bean.doc.name)
	
	return bean.doc.name
	
def get_address_docs(party=None):
	from webnotes.model.doclist import objectify
	from utilities.transaction_base import get_address_display
	
	if not party:
		party = get_lead_or_customer()
		
	address_docs = objectify(webnotes.conn.sql("""select * from `tabAddress`
		where `%s`=%s order by name""" % (party.doctype.lower(), "%s"), party.name, 
		as_dict=True, update={"doctype": "Address"}))
	
	for address in address_docs:
		address.display = get_address_display(address.fields)
		address.display = (address.display).replace("\n", "<br>\n")
		
	return address_docs
	
def get_lead_or_customer():
	customer = webnotes.conn.get_value("Contact", {"email_id": webnotes.session.user}, "customer")
	if customer:
		return webnotes.doc("Customer", customer)
	
	lead = webnotes.conn.get_value("Lead", {"email_id": webnotes.session.user})
	if lead:
		return webnotes.doc("Lead", lead)
	else:
		lead_bean = webnotes.bean({
			"doctype": "Lead",
			"email_id": webnotes.session.user,
			"lead_name": get_fullname(webnotes.session.user),
			"territory": guess_territory(),
			"status": "Open" # TODO: set something better???
		})
		
		if webnotes.session.user != "Guest":
			lead_bean.ignore_permissions = True
			lead_bean.insert()
			
		return lead_bean.doc
		
def guess_territory():
	territory = None
	geoip_country = webnotes.session.get("session_country")
	if geoip_country:
		territory = webnotes.conn.get_value("Territory", geoip_country)
	
	return territory or \
		webnotes.conn.get_value("Shopping Cart Settings", None, "territory") or \
		"All Territories"

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", "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)
		elif d.charge_type:
			d.formatted_tax_amount = fmt_money(d.tax_amount / doclist[0].conversion_rate,
				currency=doclist[0].currency)

	doclist[0].formatted_grand_total_export = fmt_money(doclist[0].grand_total_export,
		currency=doclist[0].currency)
	
	return [d.fields for d in doclist]

def _get_cart_quotation(party=None):
	if not party:
		party = get_lead_or_customer()
		
	quotation = webnotes.conn.get_value("Quotation", 
		{party.doctype.lower(): party.name, "order_type": "Shopping Cart", "docstatus": 0})
	
	if quotation:
		qbean = webnotes.bean("Quotation", quotation)
	else:
		qbean = webnotes.bean({
			"doctype": "Quotation",
			"naming_series": webnotes.defaults.get_user_default("shopping_cart_quotation_series") or "QTN-CART-",
			"quotation_to": party.doctype,
			"company": webnotes.defaults.get_user_default("company"),
			"order_type": "Shopping Cart",
			"status": "Draft",
			"docstatus": 0,
			"__islocal": 1,
			(party.doctype.lower()): party.name
		})
		
		if party.doctype == "Customer":
			qbean.doc.contact_person = webnotes.conn.get_value("Contact", {"email_id": webnotes.session.user,
				"customer": party.name})
			qbean.run_method("set_contact_fields")
		
		qbean.run_method("onload_post_render")
		apply_cart_settings(party, qbean)
	
	return qbean

def update_party(fullname, company_name=None, mobile_no=None, phone=None):
	party = get_lead_or_customer()

	if party.doctype == "Lead":
		party.company_name = company_name
		party.lead_name = fullname
		party.mobile_no = mobile_no
		party.phone = phone
	else:
		party.customer_name = company_name or fullname
		party.customer_type == "Company" if company_name else "Individual"
		
		contact_name = webnotes.conn.get_value("Contact", {"email_id": webnotes.session.user,
			"customer": party.name})
		contact = webnotes.bean("Contact", contact_name)
		contact.doc.first_name = fullname
		contact.doc.last_name = None
		contact.doc.customer_name = party.customer_name
		contact.doc.mobile_no = mobile_no
		contact.doc.phone = phone
		contact.ignore_permissions = True
		contact.save()
	
	party_bean = webnotes.bean(party.fields)
	party_bean.ignore_permissions = True
	party_bean.save()
	
	qbean = _get_cart_quotation(party)
	if not qbean.doc.fields.get("__islocal"):
		qbean.doc.customer_name = company_name or fullname
		qbean.run_method("set_contact_fields")
		qbean.ignore_permissions = True
		qbean.save()

def apply_cart_settings(party=None, quotation=None):
	if not party:
		party = get_lead_or_customer()
	if not quotation:
		quotation = _get_cart_quotation(party)
	
	cart_settings = webnotes.get_obj("Shopping Cart Settings")
	
	billing_territory = get_address_territory(quotation.doc.customer_address) or \
		party.territory or "All Territories"
		
	set_price_list_and_rate(quotation, cart_settings, billing_territory)
	
	quotation.run_method("calculate_taxes_and_totals")
	
	set_taxes(quotation, cart_settings, billing_territory)
	
	_apply_shipping_rule(party, quotation, cart_settings)
	
def set_price_list_and_rate(quotation, cart_settings, billing_territory):
	"""set price list based on billing territory"""
	quotation.doc.selling_price_list = cart_settings.get_price_list(billing_territory)
	
	# reset values
	quotation.doc.price_list_currency = quotation.doc.currency = \
		quotation.doc.plc_conversion_rate = quotation.doc.conversion_rate = None
	for item in quotation.doclist.get({"parentfield": "quotation_details"}):
		item.ref_rate = item.adj_rate = item.export_rate = item.export_amount = None
	
	# refetch values
	quotation.run_method("set_price_list_and_item_details")
	
	# set it in cookies for using in product page
	webnotes.cookies[b"selling_price_list"] = quotation.doc.selling_price_list
	
def set_taxes(quotation, cart_settings, billing_territory):
	"""set taxes based on billing territory"""
	quotation.doc.charge = cart_settings.get_tax_master(billing_territory)

	# clear table
	quotation.set_doclist(quotation.doclist.get({"parentfield": ["!=", "other_charges"]}))
	
	# append taxes
	controller = quotation.make_controller()
	controller.append_taxes_from_master("other_charges", "charge")
	quotation.set_doclist(controller.doclist)

@webnotes.whitelist()
def apply_shipping_rule(shipping_rule):
	quotation = _get_cart_quotation()
	
	quotation.doc.shipping_rule = shipping_rule
	
	apply_cart_settings(quotation=quotation)
	
	quotation.ignore_permissions = True
	quotation.save()
	
	return get_cart_quotation(quotation.doclist)
	
def _apply_shipping_rule(party=None, quotation=None, cart_settings=None):
	shipping_rules = get_shipping_rules(party, quotation, cart_settings)
	
	if not shipping_rules:
		return
		
	elif quotation.doc.shipping_rule not in shipping_rules:
		quotation.doc.shipping_rule = shipping_rules[0]
	
	quotation.run_method("apply_shipping_rule")
	quotation.run_method("calculate_taxes_and_totals")
	
def get_applicable_shipping_rules(party=None, quotation=None):
	shipping_rules = get_shipping_rules(party, quotation)
	
	if shipping_rules:
		rule_label_map = webnotes.conn.get_values("Shipping Rule", shipping_rules, "label")
		# we need this in sorted order as per the position of the rule in the settings page
		return [[rule, rule_label_map.get(rule)] for rule in shipping_rules]
		
def get_shipping_rules(party=None, quotation=None, cart_settings=None):
	if not party:
		party = get_lead_or_customer()
	if not quotation:
		quotation = _get_cart_quotation()
	if not cart_settings:
		cart_settings = webnotes.get_obj("Shopping Cart Settings")
		
	# set shipping rule based on shipping territory	
	shipping_territory = get_address_territory(quotation.doc.shipping_address_name) or \
		party.territory
	
	shipping_rules = cart_settings.get_shipping_rules(shipping_territory)
	
	return shipping_rules
	
def get_address_territory(address_name):
	"""Tries to match city, state and country of address to existing territory"""
	territory = None

	if address_name:
		address_fields = webnotes.conn.get_value("Address", address_name, 
			["city", "state", "country"])
		for value in address_fields:
			territory = webnotes.conn.get_value("Territory", value)
			if territory:
				break
	
	return territory
	
import unittest
test_dependencies = ["Item", "Price List", "Contact", "Shopping Cart Settings"]

class TestCart(unittest.TestCase):
	def tearDown(self):
		return
		
		cart_settings = webnotes.bean("Shopping Cart Settings")
		cart_settings.ignore_permissions = True
		cart_settings.doc.enabled = 0
		cart_settings.save()
	
	def enable_shopping_cart(self):
		return
		if not webnotes.conn.get_value("Shopping Cart Settings", None, "enabled"):
			cart_settings = webnotes.bean("Shopping Cart Settings")
			cart_settings.ignore_permissions = True
			cart_settings.doc.enabled = 1
			cart_settings.save()
			
	def test_get_lead_or_customer(self):
		webnotes.session.user = "test@example.com"
		party1 = get_lead_or_customer()
		party2 = get_lead_or_customer()
		self.assertEquals(party1.name, party2.name)
		self.assertEquals(party1.doctype, "Lead")
		
		webnotes.session.user = "test_contact_customer@example.com"
		party = get_lead_or_customer()
		self.assertEquals(party.name, "_Test Customer")
		
	def test_add_to_cart(self):
		self.enable_shopping_cart()
		webnotes.session.user = "test@example.com"
		
		update_cart("_Test Item", 1)
		
		quotation = _get_cart_quotation()
		quotation_items = quotation.doclist.get({"parentfield": "quotation_details", "item_code": "_Test Item"})
		self.assertTrue(quotation_items)
		self.assertEquals(quotation_items[0].qty, 1)
		
		return quotation
		
	def test_update_cart(self):
		self.test_add_to_cart()

		update_cart("_Test Item", 5)
		
		quotation = _get_cart_quotation()
		quotation_items = quotation.doclist.get({"parentfield": "quotation_details", "item_code": "_Test Item"})
		self.assertTrue(quotation_items)
		self.assertEquals(quotation_items[0].qty, 5)
		
		return quotation
		
	def test_remove_from_cart(self):
		quotation0 = self.test_add_to_cart()
		
		update_cart("_Test Item", 0)
		
		quotation = _get_cart_quotation()
		self.assertEquals(quotation0.doc.name, quotation.doc.name)
		
		quotation_items = quotation.doclist.get({"parentfield": "quotation_details", "item_code": "_Test Item"})
		self.assertEquals(quotation_items, [])
		
	def test_place_order(self):
		quotation = self.test_update_cart()
		sales_order_name = place_order()
		sales_order = webnotes.bean("Sales Order", sales_order_name)
		self.assertEquals(sales_order.doclist.getone({"item_code": "_Test Item"}).prevdoc_docname, quotation.doc.name)
		