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

wn.provide("erpnext");
wn.require("app/js/controllers/stock_controller.js");

erpnext.TransactionController = erpnext.stock.StockController.extend({
	onload: function() {
		var me = this;
		if(this.frm.doc.__islocal) {
			var today = get_today(),
				currency = wn.defaults.get_default("currency");
			
			$.each({
				posting_date: today,
				due_date: today,
				transaction_date: today,
				currency: currency,
				price_list_currency: currency,
				status: "Draft",
				company: wn.defaults.get_default("company"),
				fiscal_year: wn.defaults.get_default("fiscal_year"),
				is_subcontracted: "No",
			}, function(fieldname, value) {
				if(me.frm.fields_dict[fieldname] && !me.frm.doc[fieldname])
					me.frm.set_value(fieldname, value);
			});			
		}

		if(this.other_fname) {
			this[this.other_fname + "_remove"] = this.calculate_taxes_and_totals;
		}
		
		if(this.fname) {
			this[this.fname + "_remove"] = this.calculate_taxes_and_totals;
		}
	},
	
	onload_post_render: function() {
		var me = this;
		if(this.frm.doc.__islocal && this.frm.doc.company && !this.frm.doc.is_pos) {
			if(!this.frm.doc.customer || !this.frm.doc.supplier) {
				return this.frm.call({
					doc: this.frm.doc,
					method: "onload_post_render",
					freeze: true,
					callback: function(r) {
						// remove this call when using client side mapper
						me.set_default_values();
						me.set_dynamic_labels();
						me.calculate_taxes_and_totals();
					}
				});
			} else {
				this.calculate_taxes_and_totals();
			}
		}
	},
	
	refresh: function() {
		this.frm.clear_custom_buttons();
		erpnext.hide_naming_series();
		erpnext.hide_company();
		this.show_item_wise_taxes();
		this.set_dynamic_labels();

		// Show POS button only if it is enabled from features setup
		if(cint(sys_defaults.fs_pos_view)===1 && this.frm.doctype!="Material Request")
			this.pos_btn();
	},

	pos_btn: function() {
		if(this.$pos_btn) 
			this.$pos_btn.remove();

		if(!this.pos_active) {
			var btn_label = wn._("POS View"),
				icon = "icon-desktop";
		} else {
			var btn_label = wn._(this.frm.doctype) + wn._(" View"),
				icon = "icon-file-text";
		}
		var me = this;

		this.$pos_btn = this.frm.add_custom_button(btn_label, function() {
			me.toggle_pos();
			me.pos_btn();
		}, icon);
	},

	toggle_pos: function(show) {
		// Check whether it is Selling or Buying cycle
		var price_list = wn.meta.has_field(cur_frm.doc.doctype, "selling_price_list") ?
			this.frm.doc.selling_price_list : this.frm.doc.buying_price_list;
		
		if (!price_list)
			msgprint(wn._("Please select Price List"))
		else {
			if((show===true && this.pos_active) || (show===false && !this.pos_active)) return;

			// make pos
			if(!this.frm.pos) {
				this.frm.layout.add_view("pos");
				this.frm.pos = new erpnext.POS(this.frm.layout.views.pos, this.frm);
			}

			// toggle view
			this.frm.layout.set_view(this.pos_active ? "" : "pos");
			this.pos_active = !this.pos_active;

			// refresh
			if(this.pos_active)
				this.frm.pos.refresh();
			this.frm.refresh();
		}
	},

	serial_no: function(doc, cdt, cdn) {
		var me = this;
		var item = wn.model.get_doc(cdt, cdn);

		if (item.serial_no) {
			if (!item.item_code) {
				this.frm.script_manager.trigger("item_code", cdt, cdn);
			}
			else {
				var sr_no = [];

				// Replacing all occurences of comma with carriage return
				var serial_nos = item.serial_no.trim().replace(/,/g, '\n');

				serial_nos = serial_nos.trim().split('\n');
				
				// Trim each string and push unique string to new list
				for (var x=0; x<=serial_nos.length - 1; x++) {
					if (serial_nos[x].trim() != "" && sr_no.indexOf(serial_nos[x].trim()) == -1) {
						sr_no.push(serial_nos[x].trim());
					}
				}

				// Add the new list to the serial no. field in grid with each in new line
				item.serial_no = "";
				for (var x=0; x<=sr_no.length - 1; x++)
					item.serial_no += sr_no[x] + '\n';

				refresh_field("serial_no", item.name, item.parentfield);
				wn.model.set_value(item.doctype, item.name, "qty", sr_no.length);
			}
		}
	},
	
	validate: function() {
		this.calculate_taxes_and_totals();
	},
	
	set_default_values: function() {
		$.each(wn.model.get_doclist(this.frm.doctype, this.frm.docname), function(i, doc) {
			var updated = wn.model.set_default_values(doc);
			if(doc.parentfield) {
				refresh_field(doc.parentfield);
			} else {
				refresh_field(updated);
			}
		});
	},
	
	company: function() {
		if(this.frm.doc.company && this.frm.fields_dict.currency) {
			var company_currency = this.get_company_currency();
			if (!this.frm.doc.currency) {
				this.frm.set_value("currency", company_currency);
			}
			
			if (this.frm.doc.currency == company_currency) {
				this.frm.set_value("conversion_rate", 1.0);
			}
			if (this.frm.doc.price_list_currency == company_currency) {
				this.frm.set_value('plc_conversion_rate', 1.0);
			}

			this.frm.script_manager.trigger("currency");
		}
	},
	
	get_company_currency: function() {
		return erpnext.get_currency(this.frm.doc.company);
	},
	
	currency: function() {
		var me = this;
		this.set_dynamic_labels();

		var company_currency = this.get_company_currency();
		if(this.frm.doc.currency !== company_currency) {
			this.get_exchange_rate(this.frm.doc.currency, company_currency, 
				function(exchange_rate) {
					me.frm.set_value("conversion_rate", exchange_rate);
					me.conversion_rate();
				});
		} else {
			this.conversion_rate();		
		}
	},
	
	conversion_rate: function() {
		if(this.frm.doc.currency === this.get_company_currency()) {
			this.frm.set_value("conversion_rate", 1.0);
		}
		if(this.frm.doc.currency === this.frm.doc.price_list_currency &&
			this.frm.doc.plc_conversion_rate !== this.frm.doc.conversion_rate) {
				this.frm.set_value("plc_conversion_rate", this.frm.doc.conversion_rate);
		}
		if(flt(this.frm.doc.conversion_rate)>0.0) this.calculate_taxes_and_totals();
	},
	
	get_price_list_currency: function(buying_or_selling) {
		var me = this;
		var fieldname = buying_or_selling.toLowerCase() + "_price_list";
		if(this.frm.doc[fieldname]) {
			return this.frm.call({
				method: "setup.utils.get_price_list_currency",
				args: { 
					price_list: this.frm.doc[fieldname],
				},
				callback: function(r) {
					if(!r.exc) {
						me.price_list_currency();
					}
				}
			});
		}
	},
	
	get_exchange_rate: function(from_currency, to_currency, callback) {
		var exchange_name = from_currency + "-" + to_currency;
		wn.model.with_doc("Currency Exchange", exchange_name, function(name) {
			var exchange_doc = wn.model.get_doc("Currency Exchange", exchange_name);
			callback(exchange_doc ? flt(exchange_doc.exchange_rate) : 0);
		});
	},
	
	price_list_currency: function() {
		var me=this;
		this.set_dynamic_labels();
		
		var company_currency = this.get_company_currency();
		if(this.frm.doc.price_list_currency !== company_currency) {
			this.get_exchange_rate(this.frm.doc.price_list_currency, company_currency, 
				function(exchange_rate) {
					if(exchange_rate) {
						me.frm.set_value("plc_conversion_rate", exchange_rate);
						me.plc_conversion_rate();
					}
				});
		} else {
			this.plc_conversion_rate();
		}
	},
	
	plc_conversion_rate: function() {
		if(this.frm.doc.price_list_currency === this.get_company_currency()) {
			this.frm.set_value("plc_conversion_rate", 1.0);
		}
		if(this.frm.doc.price_list_currency === this.frm.doc.currency) {
			this.frm.set_value("conversion_rate", this.frm.doc.plc_conversion_rate);
			this.calculate_taxes_and_totals();
		}
	},
	
	qty: function(doc, cdt, cdn) {
		this.calculate_taxes_and_totals();
	},
	
	tax_rate: function(doc, cdt, cdn) {
		this.calculate_taxes_and_totals();
	},

	row_id: function(doc, cdt, cdn) {
		var tax = wn.model.get_doc(cdt, cdn);
		try {
			this.validate_on_previous_row(tax);
			this.calculate_taxes_and_totals();
		} catch(e) {
			tax.row_id = null;
			refresh_field("row_id", tax.name, tax.parentfield);
			throw e;
		}
	},
	
	set_dynamic_labels: function() {
		// What TODO? should we make price list system non-mandatory?
		this.frm.toggle_reqd("plc_conversion_rate",
			!!(this.frm.doc.price_list_name && this.frm.doc.price_list_currency));
			
		var company_currency = this.get_company_currency();
		this.change_form_labels(company_currency);
		this.change_grid_labels(company_currency);
		this.frm.refresh_fields();
	},
	
	recalculate: function() {
		this.calculate_taxes_and_totals();
	},
	
	recalculate_values: function() {
		this.calculate_taxes_and_totals();
	},
	
	calculate_charges: function() {
		this.calculate_taxes_and_totals();
	},
	
	included_in_print_rate: function(doc, cdt, cdn) {
		var tax = wn.model.get_doc(cdt, cdn);
		try {
			this.validate_on_previous_row(tax);
			this.validate_inclusive_tax(tax);
			this.calculate_taxes_and_totals();
		} catch(e) {
			tax.included_in_print_rate = 0;
			refresh_field("included_in_print_rate", tax.name, tax.parentfield);
			throw e;
		}
	},
	
	validate_on_previous_row: function(tax) {
		// validate if a valid row id is mentioned in case of
		// On Previous Row Amount and On Previous Row Total
		if(([wn._("On Previous Row Amount"), wn._("On Previous Row Total")].indexOf(tax.charge_type) != -1) &&
			(!tax.row_id || cint(tax.row_id) >= tax.idx)) {
				var msg = repl(wn._("Row") + " # %(idx)s [%(doctype)s]: " +
					wn._("Please specify a valid") + " %(row_id_label)s", {
						idx: tax.idx,
						doctype: tax.doctype,
						row_id_label: wn.meta.get_label(tax.doctype, "row_id", tax.name)
					});
				msgprint(msg);
				throw msg;
			}
	},
	
	validate_inclusive_tax: function(tax) {
		if(!this.frm.tax_doclist) this.frm.tax_doclist = this.get_tax_doclist();
		
		var actual_type_error = function() {
			var msg = repl(wn._("For row") + " # %(idx)s [%(doctype)s]: " + 
				"%(charge_type_label)s = \"%(charge_type)s\" " +
				wn._("cannot be included in Item's rate"), {
					idx: tax.idx,
					doctype: tax.doctype,
					charge_type_label: wn.meta.get_label(tax.doctype, "charge_type", tax.name),
					charge_type: tax.charge_type
				});
			msgprint(msg);
			throw msg;
		};
		
		var on_previous_row_error = function(row_range) {
			var msg = repl(wn._("For row") + " # %(idx)s [%(doctype)s]: " + 
				wn._("to be included in Item's rate, it is required that: ") + 
				" [" + wn._("Row") + " # %(row_range)s] " + wn._("also be included in Item's rate"), {
					idx: tax.idx,
					doctype: tax.doctype,
					charge_type_label: wn.meta.get_label(tax.doctype, "charge_type", tax.name),
					charge_type: tax.charge_type,
					inclusive_label: wn.meta.get_label(tax.doctype, "included_in_print_rate", tax.name),
					row_range: row_range,
				});
			
			msgprint(msg);
			throw msg;
		};
		
		if(cint(tax.included_in_print_rate)) {
			if(tax.charge_type == "Actual") {
				// inclusive tax cannot be of type Actual
				actual_type_error();
			} else if(tax.charge_type == "On Previous Row Amount" &&
				!cint(this.frm.tax_doclist[tax.row_id - 1].included_in_print_rate)) {
					// referred row should also be an inclusive tax
					on_previous_row_error(tax.row_id);
			} else if(tax.charge_type == "On Previous Row Total") {
				var taxes_not_included = $.map(this.frm.tax_doclist.slice(0, tax.row_id), 
					function(t) { return cint(t.included_in_print_rate) ? null : t; });
				if(taxes_not_included.length > 0) {
					// all rows above this tax should be inclusive
					on_previous_row_error(tax.row_id == 1 ? "1" : "1 - " + tax.row_id);
				}
			}
		}
	},
	
	_load_item_tax_rate: function(item_tax_rate) {
		return item_tax_rate ? JSON.parse(item_tax_rate) : {};
	},
	
	_get_tax_rate: function(tax, item_tax_map) {
		return (keys(item_tax_map).indexOf(tax.account_head) != -1) ?
			flt(item_tax_map[tax.account_head], precision("rate", tax)) :
			tax.rate;
	},
	
	get_item_wise_taxes_html: function() {
		var item_tax = {};
		var tax_accounts = [];
		var company_currency = this.get_company_currency();
		
		$.each(this.get_tax_doclist(), function(i, tax) {
			var tax_amount_precision = precision("tax_amount", tax);
			var tax_rate_precision = precision("rate", tax);
			$.each(JSON.parse(tax.item_wise_tax_detail || '{}'), 
				function(item_code, tax_data) {
					if(!item_tax[item_code]) item_tax[item_code] = {};
					if($.isArray(tax_data)) {
						var tax_rate = "";
						if(tax_data[0] != null) {
							tax_rate = (tax.charge_type === "Actual") ?
								format_currency(flt(tax_data[0], tax_amount_precision), company_currency, tax_amount_precision) :
								(flt(tax_data[0], tax_rate_precision) + "%");
						}
						var tax_amount = format_currency(flt(tax_data[1], tax_amount_precision), company_currency,
							tax_amount_precision);
						
						item_tax[item_code][tax.name] = [tax_rate, tax_amount];
					} else {
						item_tax[item_code][tax.name] = [flt(tax_data, tax_rate_precision) + "%", ""];
					}
				});
			tax_accounts.push([tax.name, tax.account_head]);
		});
		
		var headings = $.map([wn._("Item Name")].concat($.map(tax_accounts, function(head) { return head[1]; })), 
			function(head) { return '<th style="min-width: 100px;">' + (head || "") + "</th>" }).join("\n");
			
		var distinct_item_names = [];
		var distinct_items = [];
		$.each(this.get_item_doclist(), function(i, item) {
			if(distinct_item_names.indexOf(item.item_code || item.item_name)===-1) {
				distinct_item_names.push(item.item_code || item.item_name);
				distinct_items.push(item);
			}
		});
		
		var rows = $.map(distinct_items, function(item) {
			var item_tax_record = item_tax[item.item_code || item.item_name];
			if(!item_tax_record) { return null; }
			return repl("<tr><td>%(item_name)s</td>%(taxes)s</tr>", {
				item_name: item.item_name,
				taxes: $.map(tax_accounts, function(head) {
					return item_tax_record[head[0]] ?
						"<td>(" + item_tax_record[head[0]][0] + ") " + item_tax_record[head[0]][1] + "</td>" :
						"<td></td>";
				}).join("\n")
			});
		}).join("\n");
		
		if(!rows) return "";
		return '<div style="overflow-x: scroll;"><table class="table table-bordered table-hover">\
			<thead><tr>' + headings + '</tr></thead> \
			<tbody>' + rows + '</tbody> \
		</table></div>';
	},
	
	_validate_before_fetch: function(fieldname) {
		var me = this;
		if(!me.frm.doc[fieldname]) {
			return (wn._("Please specify") + ": " + 
				wn.meta.get_label(me.frm.doc.doctype, fieldname, me.frm.doc.name) + 
				". " + wn._("It is needed to fetch Item Details."));
		}
		return null;
	},
	
	validate_company_and_party: function(party_field) {
		var me = this;
		var valid = true;
		var msg = "";
		$.each(["company", party_field], function(i, fieldname) {
			var msg_for_fieldname = me._validate_before_fetch(fieldname);
			if(msg_for_fieldname) {
				msgprint(msg_for_fieldname);
				valid = false;
			}
		});
		return valid;
	},
	
	get_item_doclist: function() {
		return wn.model.get_doclist(this.frm.doc.doctype, this.frm.doc.name,
			{parentfield: this.fname});
	},
	
	get_tax_doclist: function() {
		return wn.model.get_doclist(this.frm.doc.doctype, this.frm.doc.name,
			{parentfield: this.other_fname});
	},
	
	validate_conversion_rate: function() {
		this.frm.doc.conversion_rate = flt(this.frm.doc.conversion_rate, precision("conversion_rate"));
		var conversion_rate_label = wn.meta.get_label(this.frm.doc.doctype, "conversion_rate", 
			this.frm.doc.name);
		
		if(this.frm.doc.conversion_rate == 0) {
			wn.throw(wn._(conversion_rate_label) + " " + wn._("cannot be 0"));
		}
		
		var company_currency = this.get_company_currency();
		
		if(!this.frm.doc.conversion_rate) {
			wn.throw(wn._("Please enter valid") + " " + wn._(conversion_rate_label) + 
				" 1 " + this.frm.doc.currency + " = [?] " + company_currency);
		}
	},
	
	calculate_taxes_and_totals: function() {
		this.validate_conversion_rate();
		this.frm.item_doclist = this.get_item_doclist();
		this.frm.tax_doclist = this.get_tax_doclist();
		
		this.calculate_item_values();
		this.initialize_taxes();
		this.determine_exclusive_rate && this.determine_exclusive_rate();
		this.calculate_net_total();
		this.calculate_taxes();
		this.calculate_totals();
		this._cleanup();
		
		this.show_item_wise_taxes();
	},
	
	initialize_taxes: function() {
		var me = this;
		$.each(this.frm.tax_doclist, function(i, tax) {
			tax.item_wise_tax_detail = {};
			$.each(["tax_amount", "total",
				"tax_amount_for_current_item", "grand_total_for_current_item",
				"tax_fraction_for_current_item", "grand_total_fraction_for_current_item"],
				function(i, fieldname) { tax[fieldname] = 0.0 });
			
			me.validate_on_previous_row(tax);
			me.validate_inclusive_tax(tax);
			wn.model.round_floats_in(tax);
		});
	},
	
	calculate_taxes: function() {
		var me = this;
		
		$.each(this.frm.item_doclist, function(n, item) {
			var item_tax_map = me._load_item_tax_rate(item.item_tax_rate);
			
			$.each(me.frm.tax_doclist, function(i, tax) {
				// tax_amount represents the amount of tax for the current step
				var current_tax_amount = me.get_current_tax_amount(item, tax, item_tax_map);

				me.set_item_tax_amount && me.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(tax.charge_type == "Actual" && 
					!(current_tax_amount || me.frm.doc.net_total || tax.tax_amount)) {
						var zero_net_total_adjustment = flt(tax.rate, precision("tax_amount", tax));
						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 += current_tax_amount;
				
				// for buying
				if(tax.category) {
					// if just for valuation, do not add the tax amount in total
					// hence, setting it as 0 for further steps
					current_tax_amount = (tax.category == "Valuation") ? 0.0 : current_tax_amount;
					
					current_tax_amount *= (tax.add_deduct_tax == "Deduct") ? -1.0 : 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,
						precision("total", tax));
				} else {
					tax.grand_total_for_current_item = 
						flt(me.frm.tax_doclist[i-1].grand_total_for_current_item + current_tax_amount,
							precision("total", tax));
				}
				
				// in tax.total, accumulate grand total for each item
				tax.total += tax.grand_total_for_current_item;
			});
		});
	},
	
	get_current_tax_amount: function(item, tax, item_tax_map) {
		var tax_rate = this._get_tax_rate(tax, item_tax_map);
		var current_tax_amount = 0.0;
		
		if(tax.charge_type == "Actual") {
			// distribute the tax amount proportionally to each item row
			var actual = flt(tax.rate, precision("tax_amount", tax));
			current_tax_amount = this.frm.doc.net_total ?
				((item.amount / this.frm.doc.net_total) * actual) :
				0.0;
			
		} else if(tax.charge_type == "On Net Total") {
			current_tax_amount = (tax_rate / 100.0) * item.amount;
			
		} else if(tax.charge_type == "On Previous Row Amount") {
			current_tax_amount = (tax_rate / 100.0) *
				this.frm.tax_doclist[cint(tax.row_id) - 1].tax_amount_for_current_item;
			
		} else if(tax.charge_type == "On Previous Row Total") {
			current_tax_amount = (tax_rate / 100.0) *
				this.frm.tax_doclist[cint(tax.row_id) - 1].grand_total_for_current_item;
			
		}
		
		current_tax_amount = flt(current_tax_amount, precision("tax_amount", tax));
		
		// store tax breakup for each item
		tax.item_wise_tax_detail[item.item_code || item.item_name] = [tax_rate, current_tax_amount];
		
		return current_tax_amount;
	},
	
	_cleanup: function() {
		$.each(this.frm.tax_doclist, function(i, tax) {
			$.each(["tax_amount_for_current_item", "grand_total_for_current_item",
				"tax_fraction_for_current_item", "grand_total_fraction_for_current_item"], 
				function(i, fieldname) { delete tax[fieldname]; });
			
			tax.item_wise_tax_detail = JSON.stringify(tax.item_wise_tax_detail);
		});
	},

	calculate_total_advance: function(parenttype, advance_parentfield) {
		if(this.frm.doc.doctype == parenttype && this.frm.doc.docstatus < 2) {
			var advance_doclist = wn.model.get_doclist(this.frm.doc.doctype, this.frm.doc.name, 
				{parentfield: advance_parentfield});
			this.frm.doc.total_advance = flt(wn.utils.sum(
				$.map(advance_doclist, function(adv) { return adv.allocated_amount })
			), precision("total_advance"));
			
			this.calculate_outstanding_amount();
		}
	},
	
	_set_in_company_currency: function(item, print_field, base_field) {
		// set values in base currency
		item[base_field] = flt(item[print_field] * this.frm.doc.conversion_rate,
			precision(base_field, item));
	},
	
	get_terms: function() {
		var me = this;
		if(this.frm.doc.tc_name) {
			return this.frm.call({
				method: "webnotes.client.get_value",
				args: {
					doctype: "Terms and Conditions",
					fieldname: "terms",
					filters: { name: this.frm.doc.tc_name },
				},
			});
		}
	},
});