# ERPNext - web based ERP (http://erpnext.com)
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
# 
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

from __future__ import unicode_literals
import webnotes
from webnotes import _, msgprint
from webnotes.utils import flt, cint
import json

from buying.utils import get_item_details
from setup.utils import get_company_currency
from webnotes.model.utils import round_floats_in_doc

from controllers.stock_controller import StockController

class BuyingController(StockController):
	def validate(self):
		super(BuyingController, self).validate()
		self.validate_stock_or_nonstock_items()
		if self.meta.get_field("currency"):
			self.company_currency = get_company_currency(self.doc.company)
			self.validate_conversion_rate("currency", "conversion_rate")
			
			if self.doc.price_list_name and self.doc.price_list_currency:
				self.validate_conversion_rate("price_list_currency", "plc_conversion_rate")
			
			# IMPORTANT: enable this only when client side code is similar to this one
			# self.calculate_taxes_and_totals()
						
			# set total in words
			self.set_total_in_words()
			
	def validate_stock_or_nonstock_items(self):
		items = [d.item_code for d in self.doclist.get({"parentfield": self.fname})]
		if self.stock_items:
			nonstock_items = list(set(items) - set(self.stock_items))
			if nonstock_items:
				webnotes.msgprint(_("Stock and non-stock items can not be entered in the same ") + 
					self.doc.doctype + _(""". You should make separate documents for them.
					Stock Items: """) + ", ".join(self.stock_items) + _("""
					Non-stock Items: """) + ", ".join(nonstock_items), raise_exception=1)
				
		elif items and not self.stock_items:
			tax_for_valuation = [d.account_head for d in 
				self.doclist.get({"parentfield": "purchase_tax_details"}) 
				if d.category in ["Valuation", "Valuation and Total"]]
			if tax_for_valuation:
				webnotes.msgprint(_("""Tax Category can not be 'Valuation' or 'Valuation and Total' 
					as all items are non-stock items"""), raise_exception=1)
			
	def update_item_details(self):
		for item in self.doclist.get({"parentfield": self.fname}):
			ret = get_item_details({
				"doctype": self.doc.doctype,
				"docname": self.doc.name,
				"item_code": item.item_code,
				"warehouse": item.warehouse,
				"supplier": self.doc.supplier,
				"transaction_date": self.doc.posting_date,
				"conversion_rate": self.doc.conversion_rate,
				"price_list_name": self.doc.price_list_name,
				"price_list_currency": self.doc.price_list_currency,
				"plc_conversion_rate": self.doc.plc_conversion_rate
			})
			for r in ret:
				if not item.fields.get(r):
					item.fields[r] = ret[r]
	
	def validate_conversion_rate(self, currency_field, conversion_rate_field):
		"""common validation for currency and price list currency"""
		
		currency = self.doc.fields.get(currency_field)
		conversion_rate = flt(self.doc.fields.get(conversion_rate_field))
		conversion_rate_label = self.meta.get_label(conversion_rate_field)
		
		if conversion_rate == 0:
			msgprint(conversion_rate_label + _(' cannot be 0'), raise_exception=True)
		
		# parenthesis for 'OR' are necessary as we want it to evaluate as 
		# mandatory valid condition and (1st optional valid condition 
		# 	or 2nd optional valid condition)
		valid_conversion_rate = (conversion_rate and 
			((currency == self.company_currency and conversion_rate == 1.00)
				or (currency != self.company_currency and conversion_rate != 1.00)))

		if not valid_conversion_rate:
			msgprint(_('Please enter valid ') + conversion_rate_label + (': ') 
				+ ("1 %s = [?] %s" % (currency, self.company_currency)),
				raise_exception=True)

	def set_total_in_words(self):
		from webnotes.utils import money_in_words
		company_currency = get_company_currency(self.doc.company)
		if self.meta.get_field("in_words"):
			self.doc.in_words = money_in_words(self.doc.grand_total, company_currency)
		if self.meta.get_field("in_words_import"):
			self.doc.in_words_import = money_in_words(self.doc.grand_total_import,
		 		self.doc.currency)
		
	def calculate_taxes_and_totals(self):
		self.doc.conversion_rate = flt(self.doc.conversion_rate)
		self.item_doclist = self.doclist.get({"parentfield": self.fname})
		self.tax_doclist = self.doclist.get({"parentfield": "purchase_tax_details"})
		
		self.calculate_item_values()
		self.initialize_taxes()
		self.calculate_net_total()
		self.calculate_taxes()
		self.calculate_totals()
		self.calculate_outstanding_amount()
		
		self._cleanup()
		
	def calculate_item_values(self):
		def _set_base(item, print_field, base_field):
			"""set values in base currency"""
			item.fields[base_field] = flt((flt(item.fields[print_field],
				self.precision.item[print_field]) * self.doc.conversion_rate),
				self.precision.item[base_field])

		for item in self.item_doclist:
			round_floats_in_doc(item, self.precision.item)
			
			# hack! - cleaned up in _cleanup()
			if self.doc.doctype != "Purchase Invoice":
				item.rate = item.purchase_rate
				self.precision.item.rate = self.precision.item.purchase_rate
				
				item.discount = item.discount_rate
				self.precision.item.discount = self.precision.item.discount_rate

			if item.discount == 100:
				if not item.import_ref_rate:
					item.import_ref_rate = item.import_rate
				item.import_rate = 0
			else:
				if item.import_ref_rate:
					item.import_rate = flt(item.import_ref_rate *
						(1.0 - (item.discount_rate / 100.0)),
						self.precision.item.import_rate)
				else:
					# assume that print rate and discount are specified
					item.import_ref_rate = flt(item.import_rate / 
						(1.0 - (item.discount_rate / 100.0)),
						self.precision.item.import_ref_rate)
						
			item.import_amount = flt(item.import_rate * item.qty,
				self.precision.item.import_amount)
				
			_set_base(item, "import_ref_rate", "purchase_ref_rate")
			_set_base(item, "import_rate", "rate")
			_set_base(item, "import_amount", "amount")
		
	def initialize_taxes(self):
		for tax in self.tax_doclist:
			# initialize totals to 0
			tax.tax_amount = tax.total = 0.0
			
			# temporary fields
			tax.tax_amount_for_current_item = tax.grand_total_for_current_item = 0.0
			
			tax.item_wise_tax_detail = {}
			
			self.validate_on_previous_row(tax)
			
			round_floats_in_doc(tax, self.precision.tax)
		
	def calculate_net_total(self):
		self.doc.net_total = 0
		self.doc.net_total_import = 0

		for item in self.item_doclist:
			self.doc.net_total += item.amount
			self.doc.net_total_import += item.import_amount
			
		self.doc.net_total = flt(self.doc.net_total, self.precision.main.net_total)
		self.doc.net_total_import = flt(self.doc.net_total_import,
			self.precision.main.net_total_import)
		
	def calculate_taxes(self):
		for item in self.item_doclist:
			item_tax_map = self._load_item_tax_rate(item.item_tax_rate)
			item.item_tax_amount = 0

			for i, tax in enumerate(self.tax_doclist):
				# tax_amount represents the amount of tax for the current step
				current_tax_amount = self.get_current_tax_amount(item, tax, item_tax_map)

				self.set_item_tax_amount(item, tax, current_tax_amount)

				# case when net total is 0 but there is an actual type charge
				# in this case add the actual amount to tax.tax_amount
				# and tax.grand_total_for_current_item for the first such iteration
				if not (current_tax_amount or self.doc.net_total or tax.tax_amount) and \
						tax.charge_type=="Actual":
					zero_net_total_adjustment = flt(tax.rate, self.precision.tax.tax_amount)
					current_tax_amount += zero_net_total_adjustment

				# store tax_amount for current item as it will be used for
				# charge type = 'On Previous Row Amount'
				tax.tax_amount_for_current_item = current_tax_amount

				# accumulate tax amount into tax.tax_amount
				tax.tax_amount += tax.tax_amount_for_current_item

				if tax.category == "Valuation":
					# if just for valuation, do not add the tax amount in total
					# hence, setting it as 0 for further steps
					current_tax_amount = 0
				else:
					current_tax_amount *= tax.add_deduct_tax == "Deduct" and -1.0 or 1.0

				# Calculate tax.total viz. grand total till that step
				# note: grand_total_for_current_item contains the contribution of 
				# item's amount, previously applied tax and the current tax on that item
				if i==0:
					tax.grand_total_for_current_item = flt(item.amount +
						current_tax_amount, self.precision.tax.total)

				else:
					tax.grand_total_for_current_item = \
						flt(self.tax_doclist[i-1].grand_total_for_current_item +
							current_tax_amount, self.precision.tax.total)

				# in tax.total, accumulate grand total of each item
				tax.total += tax.grand_total_for_current_item

				# store tax_breakup for each item
				# DOUBT: should valuation type amount also be stored?
				tax.item_wise_tax_detail[item.item_code] = current_tax_amount
		
	def calculate_totals(self):
		if self.tax_doclist:
			self.doc.grand_total = flt(self.tax_doclist[-1].total,
				self.precision.main.grand_total)
			self.doc.grand_total_import = flt(
				self.doc.grand_total / self.doc.conversion_rate,
				self.precision.main.grand_total_import)
		else:
			self.doc.grand_total = flt(self.doc.net_total,
				self.precision.main.grand_total)
			self.doc.grand_total_import = flt(
				self.doc.grand_total / self.doc.conversion_rate,
				self.precision.main.grand_total_import)

		self.doc.total_tax = \
			flt(self.doc.grand_total - self.doc.net_total,
			self.precision.main.total_tax)

		if self.meta.get_field("rounded_total"):
			self.doc.rounded_total = round(self.doc.grand_total)
		
		if self.meta.get_field("rounded_total_import"):
			self.doc.rounded_total_import = round(self.doc.grand_total_import)
			
	def calculate_outstanding_amount(self):
		if self.doc.doctype == "Purchase Invoice" and self.doc.docstatus == 0:
			self.doc.total_advance = flt(self.doc.total_advance,
				self.precision.main.total_advance)
			self.doc.total_amount_to_pay = flt(self.doc.grand_total - flt(self.doc.write_off_amount,
				self.precision.main.write_off_amount), self.precision.main.total_amount_to_pay)
			self.doc.outstanding_amount = flt(self.doc.total_amount_to_pay - self.doc.total_advance,
				self.precision.main.outstanding_amount)
			
	def _cleanup(self):
		for tax in self.tax_doclist:
			del tax.fields["grand_total_for_current_item"]
			del tax.fields["tax_amount_for_current_item"]
			tax.item_wise_tax_detail = json.dumps(tax.item_wise_tax_detail)
		
		# except in purchase invoice, rate field is purchase_rate
		if self.doc.doctype != "Purchase Invoice":
			for item in self.item_doclist:
				item.purchase_rate = item.rate
				del item.fields["rate"]
				
				item.discount_rate = item.discount
				del item.fields["discount"]
		
	def validate_on_previous_row(self, tax):
		"""
			validate if a valid row id is mentioned in case of
			On Previous Row Amount and On Previous Row Total
		"""
		if tax.charge_type in ["On Previous Row Amount", "On Previous Row Total"] and \
				(not tax.row_id or cint(tax.row_id) >= tax.idx):
			msgprint((_("Row") + " # %(idx)s [%(taxes_doctype)s]: " + \
				_("Please specify a valid") + " %(row_id_label)s") % {
					"idx": tax.idx,
					"taxes_doctype": tax.parenttype,
					"row_id_label": self.meta.get_label("row_id",
						parentfield="purchase_tax_details")
				}, raise_exception=True)
				
	def _load_item_tax_rate(self, item_tax_rate):
		if not item_tax_rate:
			return {}
		return json.loads(item_tax_rate)
		
	def get_current_tax_amount(self, item, tax, item_tax_map):
		tax_rate = self._get_tax_rate(tax, item_tax_map)

		if tax.charge_type == "Actual":
			# distribute the tax amount proportionally to each item row
			actual = flt(tax.rate, self.precision.tax.tax_amount)
			current_tax_amount = (self.doc.net_total
				and ((item.amount / self.doc.net_total) * actual)
				or 0)
		elif tax.charge_type == "On Net Total":
			current_tax_amount = (tax_rate / 100.0) * item.amount
		elif tax.charge_type == "On Previous Row Amount":
			current_tax_amount = (tax_rate / 100.0) * \
				self.tax_doclist[cint(tax.row_id) - 1].tax_amount_for_current_item
		elif tax.charge_type == "On Previous Row Total":
			current_tax_amount = (tax_rate / 100.0) * \
				self.tax_doclist[cint(tax.row_id) - 1].grand_total_for_current_item

		return flt(current_tax_amount, self.precision.tax.tax_amount)
		
	def _get_tax_rate(self, tax, item_tax_map):
		if item_tax_map.has_key(tax.account_head):
			return flt(item_tax_map.get(tax.account_head), self.precision.tax.rate)
		else:
			return tax.rate
			
	def set_item_tax_amount(self, item, tax, current_tax_amount):
		"""
			item_tax_amount is the total tax amount applied on that item
			stored for valuation 
			
			TODO: rename item_tax_amount to valuation_tax_amount
		"""
		if tax.category in ["Valuation", "Valuation and Total"] and \
				item.item_code in self.stock_items:
			item.item_tax_amount += flt(current_tax_amount,
				self.precision.item.item_tax_amount)
				
	# update valuation rate
	def update_valuation_rate(self, parentfield):
		for d in self.doclist.get({"parentfield": parentfield}):
			d.conversion_factor = d.conversion_factor or flt(webnotes.conn.get_value(
				"UOM Conversion Detail", {"parent": d.item_code, "uom": d.uom}, 
				"conversion_factor")) or 1
			if d.item_code and d.qty:
				# if no item code, which is sometimes the case in purchase invoice, 
				# then it is not possible to track valuation against it
				d.valuation_rate = (flt(d.purchase_rate or d.rate)
					+ (flt(d.item_tax_amount) + flt(d.rm_supp_cost)) / flt(d.qty)
					) / flt(d.conversion_factor)
			else:
				d.valuation_rate = 0.0
				
	def validate_for_subcontracting(self):
		if not self.doc.is_subcontracted and self.sub_contracted_items:
			webnotes.msgprint(_("""Please enter whether %s is made for subcontracting or purchasing,
			 	in 'Is Subcontracted' field""" % self.doc.doctype), raise_exception=1)
			
		if self.doc.doctype == "Purchase Receipt" and self.doc.is_subcontracted=="Yes" \
			and not self.doc.supplier_warehouse:
				webnotes.msgprint(_("Supplier Warehouse mandatory subcontracted purchase receipt"), 
					raise_exception=1)
										
	def update_raw_materials_supplied(self, raw_material_table):
		self.doclist = self.doc.clear_table(self.doclist, raw_material_table)
		if self.doc.is_subcontracted=="Yes":
			for item in self.doclist.get({"parentfield": self.fname}):
				if item.item_code in self.sub_contracted_items:
					self.add_bom_items(item, raw_material_table)

	def add_bom_items(self, d, raw_material_table):
		bom_items = self.get_items_from_default_bom(d.item_code)
		raw_materials_cost = 0
		for item in bom_items:
			required_qty = flt(item.qty_consumed_per_unit) * flt(d.qty) * flt(d.conversion_factor)
			rm_doclist = {
				"parentfield": raw_material_table,
				"doctype": self.doc.doctype + " Item Supplied",
				"reference_name": d.name,
				"bom_detail_no": item.name,
				"main_item_code": d.item_code,
				"rm_item_code": item.item_code,
				"stock_uom": item.stock_uom,
				"required_qty": required_qty,
				"conversion_factor": d.conversion_factor,
				"rate": item.rate,
				"amount": required_qty * flt(item.rate)
			}
			if self.doc.doctype == "Purchase Receipt":
				rm_doclist.update({
					"consumed_qty": required_qty,
					"description": item.description,
				})
				
			self.doclist.append(rm_doclist)
			
			raw_materials_cost += required_qty * flt(item.rate)
			
		if self.doc.doctype == "Purchase Receipt":
			d.rm_supp_cost = raw_materials_cost

	def get_items_from_default_bom(self, item_code):
		# print webnotes.conn.sql("""select name from `tabBOM` where item = '_Test FG Item'""")
		bom_items = webnotes.conn.sql("""select t2.item_code, t2.qty_consumed_per_unit, 
			t2.rate, t2.stock_uom, t2.name, t2.description 
			from `tabBOM` t1, `tabBOM Item` t2 
			where t2.parent = t1.name and t1.item = %s and t1.is_default = 1 
			and t1.docstatus = 1 and t1.is_active = 1""", item_code, as_dict=1)
		if not bom_items:
			msgprint(_("No default BOM exists for item: ") + item_code, raise_exception=1)
		
		return bom_items

	
	@property
	def precision(self):
		if not hasattr(self, "_precision"):
			self._precision = webnotes._dict()
			self._precision.main = self.meta.get_precision_map()
			self._precision.item = self.meta.get_precision_map(parentfield = self.fname)
			if self.meta.get_field("purchase_tax_details"):
				self._precision.tax = self.meta.get_precision_map(parentfield = \
					"purchase_tax_details")
		return self._precision

	@property
	def sub_contracted_items(self):
		if not hasattr(self, "_sub_contracted_items"):
			self._sub_contracted_items = []
			item_codes = list(set(item.item_code for item in 
				self.doclist.get({"parentfield": self.fname})))
			if item_codes:
				self._sub_contracted_items = [r[0] for r in webnotes.conn.sql("""select name
					from `tabItem` where name in (%s) and is_sub_contracted_item='Yes'""" % \
					(", ".join((["%s"]*len(item_codes))),), item_codes)]

		return self._sub_contracted_items
		
	@property
	def purchase_items(self):
		if not hasattr(self, "_purchase_items"):
			self._purchase_items = []
			item_codes = list(set(item.item_code for item in 
				self.doclist.get({"parentfield": self.fname})))
			if item_codes:
				self._purchase_items = [r[0] for r in webnotes.conn.sql("""select name
					from `tabItem` where name in (%s) and is_purchase_item='Yes'""" % \
					(", ".join((["%s"]*len(item_codes))),), item_codes)]

		return self._purchase_items
