# 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
import webnotes.model
from webnotes import _, msgprint
from webnotes.utils import cint, flt
from webnotes.model.utils import round_doc
import json

from controllers.transaction_controller import TransactionController

class TaxController(TransactionController):
	def append_taxes(self):
		"""append taxes as per tax master link field"""
		# clear tax table
		self.doclist = self.doclist.get({"parentfield": ["!=",
			self.fmap.taxes_and_charges]})
		
		tax_master_doctype = self.meta.get_options(self.fmap.taxes_and_charges_master)
		master_tax_list = webnotes.get_doclist(tax_master_doctype,
			self.doc.fields.get(self.fmap.taxes_and_charges_master)).get(
			{"parentfield": self.fmap.taxes_and_charges})
			
		for base_tax in master_tax_list:
			tax = DictObj([[field, base_tax.fields.get(field)]
				for field in base_tax.fields
				if field not in webnotes.model.default_fields])
			tax.update({
				"doctype": self.meta.get_options(self.fmap.taxes_and_charges),
				"parentfield": self.fmap.taxes_and_charges,
				"rate": flt(tax.rate, self.precision.tax.rate),
			})
			self.doclist.append(tax)
	
	def calculate_taxes_and_totals(self):
		"""
			Calculates:
				* amount for each item
				* valuation_tax_amount for each item, 
				* tax amount and tax total for each tax
				* net total
				* total taxes
				* grand total
		"""
		self.doc.fields[self.fmap.exchange_rate] = \
			flt(self.doc.fields.get(self.fmap.exchange_rate),
			self.precision.main[self.fmap.exchange_rate])
		
		self.calculate_item_values()
		
		self.initialize_taxes()
		if self.meta.get_field("included_in_print_rate",
				parentfield=self.fmap.taxes_and_charges):
			self.determine_exclusive_rate()
		
		self.calculate_net_total()
		self.calculate_taxes()
		self.calculate_totals()
		self.set_amount_in_words()
		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.fields.get(self.fmap.exchange_rate)),
				self.precision.item[base_field])
		
		for item in self.item_doclist:
			round_doc(item, self.precision.item)
			
			if item.fields.get(self.fmap.discount) == 100:
				if not item.fields.get(self.fmap.print_ref_rate):
					item.fields[self.fmap.print_ref_rate] = \
						item.fields.get(self.fmap.print_rate)
				item.fields[self.fmap.print_rate] = 0
			else:
				if item.fields.get(self.fmap.print_ref_rate):
					item.fields[self.fmap.print_rate] = \
						flt(item.fields.get(self.fmap.print_ref_rate) *
						(1.0 - (item.fields.get(self.fmap.discount) / 100.0)),
						self.precision.item[self.fmap.print_rate])
				else:
					# assume that print rate and discount are specified
					item.fields[self.fmap.print_ref_rate] = \
						flt(item.fields.get(self.fmap.print_rate) / 
						(1.0 - (item.fields.get(self.fmap.discount) / 100.0)),
						self.precision.item[self.fmap.print_ref_rate])
						
			item.fields[self.fmap.print_amount] = \
				flt(item.fields.get(self.fmap.print_rate) * \
				item.fields.get("qty"),
				self.precision.item[self.fmap.print_amount])
				
			_set_base(item, self.fmap.print_ref_rate, self.fmap.ref_rate)
			_set_base(item, self.fmap.print_rate, self.fmap.rate)
			_set_base(item, self.fmap.print_amount, "amount")
			
	def initialize_taxes(self):
		for tax in self.tax_doclist:
			# initialize totals to 0
			tax.tax_amount = tax.total = tax.total_print = 0
			tax.grand_total_for_current_item = tax.tax_amount_for_current_item = 0
			
			# for actual type, user can mention actual tax amount in tax.tax_amount_print
			if tax.charge_type != "Actual" or tax.rate:
				tax.tax_amount_print = 0
			
			self.validate_on_previous_row(tax)
			self.validate_included_tax(tax)
			
			# round relevant values
			round_doc(tax, self.precision.tax)
			
	def calculate_net_total(self):
		self.doc.net_total = 0
		self.doc.fields[self.fmap.net_total_print] = 0
		
		for item in self.item_doclist:
			self.doc.net_total += item.amount
			self.doc.fields[self.fmap.net_total_print] += \
				item.fields.get(self.fmap.print_amount)

		self.doc.net_total = flt(self.doc.net_total, self.precision.main.net_total)
		self.doc.fields[self.fmap.net_total_print] = \
			flt(self.doc.fields.get(self.fmap.net_total_print),
			self.precision.main[self.fmap.net_total_print])
			
	def calculate_taxes(self):
		for item in self.item_doclist:
			item_tax_map = self._load_item_tax_rate(item.item_tax_rate)
			item.fields[self.fmap.valuation_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)
				
				if hasattr(self, "set_valuation_tax_amount"):
					self.set_valuation_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.tax_amount_print * 
						self.doc.fields.get(self.fmap.exchange_rate)) or 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
				
				# accumulate tax_amount_print only if tax is not included
				# and if tax amount of actual type is entered in 'rate' field
				if not cint(tax.included_in_print_rate) and (tax.charge_type != "Actual"
						or tax.rate):
					tax.tax_amount_print += flt((tax.tax_amount_for_current_item /
						self.doc.fields.get(self.fmap.exchange_rate)),
						self.precision.tax.tax_amount_print)
				
				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
				
				# 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)
					
					# if inclusive pricing, current_tax_amount should not be considered
					if cint(tax.included_in_print_rate):
						current_tax_amount = 0
						
					tax.grand_total_print_for_current_item = \
						flt(item.fields.get(self.fmap.print_amount) +
						(current_tax_amount / self.doc.fields.get(
							self.fmap.exchange_rate)),
						self.precision.tax.total_print)
				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)
					
					# if inclusive pricing, current_tax_amount should not be considered
					if cint(tax.included_in_print_rate):
						current_tax_amount = 0
					
					tax.grand_total_print_for_current_item = \
						flt(self.tax_doclist[i-1].grand_total_print_for_current_item +
							(current_tax_amount / self.doc.fields.get(
								self.fmap.exchange_rate)),
							self.precision.tax.total_print)

				# in tax.total, accumulate grand total of each item
				tax.total += tax.grand_total_for_current_item
				tax.total_print += tax.grand_total_print_for_current_item
				
				# TODO store tax_breakup for each item
				
	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 or (tax.tax_amount_print * \
				self.doc.fields.get(self.fmap.exchange_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 calculate_totals(self):
		if self.tax_doclist:
			self.doc.grand_total = flt(self.tax_doclist[-1].total,
				self.precision.main.grand_total)
			self.doc.fields[self.fmap.grand_total_print] = \
				flt(self.tax_doclist[-1].total_print,
				self.precision.main[self.fmap.grand_total_print])
		else:
			self.doc.grand_total = flt(self.doc.net_total,
				self.precision.main.grand_total)
			self.doc.fields[self.fmap.grand_total_print] = \
				flt(self.doc.fields.get(self.fmap.net_total_print),
				self.precision.main[self.fmap.grand_total_print])
		
		self.doc.fields[self.fmap.taxes_and_charges_total] = \
			flt(self.doc.grand_total - self.doc.net_total,
			self.precision.main[self.fmap.taxes_and_charges_total])
			
		self.doc.taxes_and_charges_total_print = \
			flt(self.doc.fields.get(self.fmap.grand_total_print) - \
			self.doc.fields.get(self.fmap.net_total_print),
			self.precision.main.taxes_and_charges_total_print)
		
		self.doc.rounded_total = round(self.doc.grand_total)
		self.doc.fields[self.fmap.rounded_total_print] = \
			round(self.doc.fields.get(self.fmap.grand_total_print))
		
	def set_amount_in_words(self):
		from webnotes.utils import money_in_words
		base_currency = webnotes.conn.get_value("Company", self.doc.currency,
			"default_currency")
		
		self.doc.fields[self.fmap.grand_total_in_words] = \
			money_in_words(self.doc.grand_total, base_currency)
		self.doc.fields[self.fmap.rounded_total_in_words] = \
			money_in_words(self.doc.rounded_total, base_currency)
		
		self.doc.fields[self.fmap.grand_total_in_words_print] = \
			money_in_words(self.doc.fields.get(self.fmap.grand_total_print),
			self.doc.currency)
		self.doc.fields[self.fmap.rounded_total_in_words_print] = \
			money_in_words(self.doc.fields.get(self.fmap.rounded_total_print),
			self.doc.currency)
			
	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=self.fmap.taxes_and_charges)
				}, raise_exception=True)
	
	def validate_included_tax(self, tax):
		"""
			validate conditions related to "Is this Tax Included in Rate?"
		"""
		def _on_previous_row_error(tax, row_range):
			msgprint((_("Row") + " # %(idx)s [%(taxes_doctype)s]: " + \
				_("If") + " '%(inclusive_label)s' " + _("is checked for") + \
				" '%(charge_type_label)s' = '%(charge_type)s', " + _("then") + " " + \
				_("Row") + " # %(row_range)s " + _("should also have") + \
				" '%(inclusive_label)s' = " + _("checked")) % {
					"idx": tax.idx,
					"taxes_doctype": tax.doctype,
					"inclusive_label": self.meta.get_label("included_in_print_rate",
						parentfield=self.fmap.taxes_and_charges),
					"charge_type_label": self.meta.get_label("charge_type",
						parentfield=self.fmap.taxes_and_charges),
					"charge_type": tax.charge_type,
					"row_range": row_range,
				}, raise_exception=True)
		
		if cint(tax.included_in_print_rate):
			if tax.charge_type == "Actual":
				# now inclusive rate for type 'Actual'
				msgprint((_("Row") + " # %(idx)s [%(taxes_doctype)s]: " + \
					"'%(charge_type_label)s' = '%(charge_type)s' " + \
					_("cannot be included in item's rate")) % {
						"idx": tax.idx,
						"taxes_doctype": self.meta.get_options(
							self.fmap.taxes_and_charges),
						"charge_type_label": self.meta.get_label("charge_type",
							parentfield=self.fmap.taxes_and_charges),
						"charge_type": tax.charge_type,
					}, raise_exception=True)
					
			elif tax.charge_type == "On Previous Row Amount" and \
					not cint(self.tax_doclist[cint(tax.row_id) - 1]\
						.included_in_print_rate):
				# for an inclusive tax of type "On Previous Row Amount",
				# dependent row should also be inclusive
				_on_previous_row_error(tax, tax.row_id)
				
			elif tax.charge_type == "On Previous Row Total" and \
					not all([cint(t.included_in_print_rate) \
						for t in self.tax_doclist[:tax.idx - 1]]):
				# for an inclusive tax of type "On Previous Row Total", 
				# all rows above it should also be inclusive
				_on_previous_row_error(tax, "1 - %d" % (tax.idx - 1))
		
	def determine_exclusive_rate(self):
		if not any((cint(tax.included_in_print_rate) for tax in self.tax_doclist)):
			# if no tax is marked as included in print rate, no need to proceed further
			return
		
		for item in self.item_doclist:
			item_tax_map = self._load_item_tax_rate(item.item_tax_rate)
			
			cumulated_tax_fraction = 0
			
			for i, tax in enumerate(self.tax_doclist):
				if cint(tax.included_in_print_rate):
					tax.tax_fraction_for_current_item = \
						self.get_current_tax_fraction(tax, item_tax_map)
				else:
					tax.tax_fraction_for_current_item = 0
				
				if i==0:
					tax.grand_total_fraction_for_current_item = 1 + \
						tax.tax_fraction_for_current_item
				else:
					tax.grand_total_fraction_for_current_item = \
						self.tax_doclist[i-1].grand_total_fraction_for_current_item \
						+ tax.tax_fraction_for_current_item
						
				cumulated_tax_fraction += tax.tax_fraction_for_current_item
			
			if cumulated_tax_fraction:
				item.fields[self.fmap.rate] = \
					flt((item.fields.get(self.fmap.print_rate) * \
					self.doc.fields.get(self.fmap.exchange_rate)) / 
					(1 + cumulated_tax_fraction), self.precision.item[self.fmap.rate])
				
				item.amount = flt(item.fields.get(self.fmap.rate) * item.qty,
					self.precision.item.amount)
				
				item.fields[self.fmap.ref_rate] = \
					flt(item.fields.get(self.fmap.rate) / (1 - \
					(item.fields.get(self.fmap.discount) / 100.0)),
					self.precision.item[self.fmap.ref_rate])
		
				# print item.print_rate, 1+cumulated_tax_fraction, item.rate, item.amount
				# print "-"*10

	def get_current_tax_fraction(self, tax, item_tax_map):
		"""
			Get tax fraction for calculating tax exclusive amount
			from tax inclusive amount
		"""
		current_tax_fraction = 0
		
		if cint(tax.included_in_print_rate):
			tax_rate = self._get_tax_rate(tax, item_tax_map)
			
			if tax.charge_type == "On Net Total":
				current_tax_fraction = tax_rate / 100.0
			
			elif tax.charge_type == "On Previous Row Amount":
				current_tax_fraction = (tax_rate / 100.0) * \
					self.tax_doclist[cint(tax.row_id) - 1]\
						.tax_fraction_for_current_item
			
			elif tax.charge_type == "On Previous Row Total":
				current_tax_fraction = (tax_rate / 100.0) * \
					self.tax_doclist[cint(tax.row_id) - 1]\
						.grand_total_fraction_for_current_item
						
			# print tax.account_head, tax_rate, current_tax_fraction

		return current_tax_fraction
	
	def _load_item_tax_rate(self, item_tax_rate):
		if not item_tax_rate:
			return {}

		return json.loads(item_tax_rate)
		
	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 cleanup(self):
		for f in ["taxes_and_charges_total_print", "rounded_total_in_words_print",
				"rounded_total_print", "rounded_total_in_words"]:
			del self.doc.fields[self.fmap.get(f) or f]
		
		for f in ["grand_total_print_for_current_item", "tax_amount_print",
				"grand_total_for_current_item", "tax_amount_for_current_item",
				"total_print"]:
			for doc in self.doclist.get({"parentfield": self.fmap.taxes_and_charges}):
				del doc.fields[self.fmap.get(f) or f]
