Multi-currency: Exchange Rate in Journal Entry
This commit is contained in:
		
							parent
							
								
									6c3ff3e2ed
								
							
						
					
					
						commit
						e3ae05aabd
					
				| @ -153,17 +153,18 @@ def update_outstanding_amt(account, party_type, party, against_voucher_type, aga | |||||||
| 		party_condition = "" | 		party_condition = "" | ||||||
| 
 | 
 | ||||||
| 	# get final outstanding amt | 	# get final outstanding amt | ||||||
| 	bal = flt(frappe.db.sql("""select sum(ifnull(debit, 0)) - sum(ifnull(credit, 0)) | 	bal = flt(frappe.db.sql(""" | ||||||
|  | 		select sum(ifnull(debit_in_account_currency, 0)) - sum(ifnull(credit_in_account_currency, 0)) | ||||||
| 		from `tabGL Entry` | 		from `tabGL Entry` | ||||||
| 		where against_voucher_type=%s and against_voucher=%s | 		where against_voucher_type=%s and against_voucher=%s | ||||||
| 		and account = %s {0}""".format(party_condition), | 		and account = %s {0}""".format(party_condition), | ||||||
| 		(against_voucher_type, against_voucher, account))[0][0] or 0.0) | 		(against_voucher_type, against_voucher, account))[0][0] or 0.0) | ||||||
| 
 | 		 | ||||||
| 	if against_voucher_type == 'Purchase Invoice': | 	if against_voucher_type == 'Purchase Invoice': | ||||||
| 		bal = -bal | 		bal = -bal | ||||||
| 	elif against_voucher_type == "Journal Entry": | 	elif against_voucher_type == "Journal Entry": | ||||||
| 		against_voucher_amount = flt(frappe.db.sql(""" | 		against_voucher_amount = flt(frappe.db.sql(""" | ||||||
| 			select sum(ifnull(debit, 0)) - sum(ifnull(credit, 0)) | 			select sum(ifnull(debit_in_account_currency, 0)) - sum(ifnull(credit_in_account_currency, 0)) | ||||||
| 			from `tabGL Entry` where voucher_type = 'Journal Entry' and voucher_no = %s | 			from `tabGL Entry` where voucher_type = 'Journal Entry' and voucher_no = %s | ||||||
| 			and account = %s and ifnull(against_voucher, '') = '' {0}""" | 			and account = %s and ifnull(against_voucher, '') = '' {0}""" | ||||||
| 			.format(party_condition), (against_voucher, account))[0][0]) | 			.format(party_condition), (against_voucher, account))[0][0]) | ||||||
|  | |||||||
| @ -25,16 +25,29 @@ frappe.ui.form.on("Journal Entry", { | |||||||
| 		 | 		 | ||||||
| 		// hide /unhide fields based on currency
 | 		// hide /unhide fields based on currency
 | ||||||
| 		erpnext.journal_entry.toggle_fields_based_on_currency(frm); | 		erpnext.journal_entry.toggle_fields_based_on_currency(frm); | ||||||
|  | 	}, | ||||||
|  | 	 | ||||||
|  | 	multi_currency: function(frm) { | ||||||
|  | 		erpnext.journal_entry.toggle_fields_based_on_currency(frm); | ||||||
| 	} | 	} | ||||||
| }) | }) | ||||||
| 
 | 
 | ||||||
| erpnext.journal_entry.toggle_fields_based_on_currency = function(frm) { | erpnext.journal_entry.toggle_fields_based_on_currency = function(frm) { | ||||||
| 	var fields = ["debit_in_account_currency", "credit_in_account_currency"]; | 	var fields = ["currency_section", "account_currency", "exchange_rate", "debit", "credit"]; | ||||||
| 		 | 	 | ||||||
| 	var company_currency = erpnext.get_currency(frm.doc.company); |  | ||||||
| 		 |  | ||||||
| 	var grid = frm.get_field("accounts").grid; | 	var grid = frm.get_field("accounts").grid; | ||||||
| 	grid.set_column_disp(fields, grid.account_currency!=company_currency); | 	if(grid) grid.set_column_disp(fields, frm.doc.multi_currency); | ||||||
|  | 	 | ||||||
|  | 	// dynamic label
 | ||||||
|  | 	var field_label_map = { | ||||||
|  | 		"debit_in_account_currency": "Debit",  | ||||||
|  | 		"credit_in_account_currency": "Credit" | ||||||
|  | 	}; | ||||||
|  | 	 | ||||||
|  | 	$.each(field_label_map, function (fieldname, label) { | ||||||
|  | 		var df = frappe.meta.get_docfield("Journal Entry Account", fieldname, frm.doc.name); | ||||||
|  | 		df.label = frm.doc.multi_currency ? (label + " in Account Currency") : label; | ||||||
|  | 	}) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({ | erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({ | ||||||
| @ -62,17 +75,26 @@ erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({ | |||||||
| 
 | 
 | ||||||
| 	setup_queries: function() { | 	setup_queries: function() { | ||||||
| 		var me = this; | 		var me = this; | ||||||
| 
 | 		var company_currency = erpnext.get_currency(me.frm.doc.company); | ||||||
| 		$.each(["account", "cost_center"], function(i, fieldname) { | 		 | ||||||
| 			me.frm.set_query(fieldname, "accounts", function() { | 		me.frm.set_query("account", "accounts", function(doc, cdt, cdn) { | ||||||
| 				frappe.model.validate_missing(me.frm.doc, "company"); | 			var filters = { | ||||||
| 				return { | 				company: me.frm.doc.company, | ||||||
| 					filters: { | 				is_group: 0 | ||||||
| 						company: me.frm.doc.company, | 			}; | ||||||
| 						is_group: 0 | 			if(!doc.multi_currency) { | ||||||
| 					} | 				$.extend(filters, {currency: company_currency}); | ||||||
| 				}; | 			} | ||||||
| 			}); | 			return { filters: filters }; | ||||||
|  | 		}); | ||||||
|  | 		 | ||||||
|  | 		me.frm.set_query("cost_center", "accounts", function(doc, cdt, cdn) { | ||||||
|  | 			return {  | ||||||
|  | 				filters: { | ||||||
|  | 					company: me.frm.doc.company, | ||||||
|  | 					is_group: 0 | ||||||
|  | 				} | ||||||
|  | 			}; | ||||||
| 		}); | 		}); | ||||||
| 
 | 
 | ||||||
| 		me.frm.set_query("party_type", "accounts", function(doc, cdt, cdn) { | 		me.frm.set_query("party_type", "accounts", function(doc, cdt, cdn) { | ||||||
| @ -151,32 +173,39 @@ erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({ | |||||||
| 
 | 
 | ||||||
| 	reference_name: function(doc, cdt, cdn) { | 	reference_name: function(doc, cdt, cdn) { | ||||||
| 		var d = frappe.get_doc(cdt, cdn); | 		var d = frappe.get_doc(cdt, cdn); | ||||||
| 		if (d.reference_type==="Purchase Invoice" && !flt(d.debit)) { | 		if(d.reference_name) { | ||||||
| 			this.get_outstanding('Purchase Invoice', d.reference_name, d); | 			if (d.reference_type==="Purchase Invoice" && !flt(d.debit)) { | ||||||
| 		} | 				this.get_outstanding('Purchase Invoice', d.reference_name, doc.company, d); | ||||||
| 		if (d.reference_type==="Sales Invoice" && !flt(d.credit)) { | 			} | ||||||
| 			this.get_outstanding('Sales Invoice', d.reference_name, d); | 			if (d.reference_type==="Sales Invoice" && !flt(d.credit)) { | ||||||
| 		} | 				this.get_outstanding('Sales Invoice', d.reference_name, doc.company, d); | ||||||
| 		if (d.reference_type==="Journal Entry" && !flt(d.credit) && !flt(d.debit)) { | 			} | ||||||
| 			this.get_outstanding('Journal Entry', d.reference_name, d); | 			if (d.reference_type==="Journal Entry" && !flt(d.credit) && !flt(d.debit)) { | ||||||
|  | 				this.get_outstanding('Journal Entry', d.reference_name, doc.company, d); | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	get_outstanding: function(doctype, docname, child) { | 	get_outstanding: function(doctype, docname, company, child) { | ||||||
| 		var me = this; | 		var me = this; | ||||||
| 		var args = { | 		var args = { | ||||||
| 			"doctype": doctype, | 			"doctype": doctype, | ||||||
| 			"docname": docname, | 			"docname": docname, | ||||||
| 			"party": child.party, | 			"party": child.party, | ||||||
| 			"account": child.account | 			"account": child.account, | ||||||
|  | 			"account_currency": child.account_currency, | ||||||
|  | 			"company": company | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		return this.frm.call({ | 		return frappe.call({ | ||||||
| 			child: child, | 			method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_outstanding", | ||||||
| 			method: "get_outstanding", |  | ||||||
| 			args: { args: args}, | 			args: { args: args}, | ||||||
| 			callback: function(r) { | 			callback: function(r) { | ||||||
| 				cur_frm.cscript.update_totals(me.frm.doc); | 				if(r.message) { | ||||||
|  | 					$.each(r.message, function(field, value) { | ||||||
|  | 						frappe.model.set_value(child.doctype, child.name, field, value); | ||||||
|  | 					}) | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
| 		}); | 		}); | ||||||
| 	}, | 	}, | ||||||
| @ -325,42 +354,26 @@ frappe.ui.form.on("Journal Entry Account", { | |||||||
| 					account: d.account,  | 					account: d.account,  | ||||||
| 					date: frm.doc.posting_date, | 					date: frm.doc.posting_date, | ||||||
| 					company: frm.doc.company, | 					company: frm.doc.company, | ||||||
| 					credited: flt(d.credit_in_account_currency) > 0 ? true : false | 					debit: flt(d.debit_in_account_currency), | ||||||
|  | 					credit: flt(d.credit_in_account_currency), | ||||||
|  | 					exchange_rate: d.exchange_rate | ||||||
| 				}, | 				}, | ||||||
| 				callback: function(r) { | 				callback: function(r) { | ||||||
| 					if(r.message) { | 					if(r.message) { | ||||||
| 						$.extend(d, r.message[0]); | 						$.extend(d, r.message); | ||||||
| 						refresh_field('balance', d.name, 'accounts'); | 						refresh_field('accounts'); | ||||||
| 						refresh_field('party_type', d.name, 'accounts'); |  | ||||||
| 						refresh_field('account_currency', d.name, 'accounts'); |  | ||||||
| 						 |  | ||||||
| 						if(r.message[1] && (!frm.doc.exchange_rate || frm.doc.exchange_rate == 1.0)) { |  | ||||||
| 							frm.set_value("exchange_rate", r.message[1]) |  | ||||||
| 						} |  | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 			}); | 			}); | ||||||
| 		} | 		} | ||||||
| 	}, | 	}, | ||||||
| 	 | 	 | ||||||
| 	debit_in_account_currency: function(frm, dt, dn) { | 	debit_in_account_currency: function(frm, cdt, cdn) { | ||||||
| 		var company_currency = erpnext.get_currency(frm.doc.company); | 		erpnext.journal_entry.set_debit_credit_in_company_currency(frm, cdt, cdn); | ||||||
| 		var row = locals[dt][dn]; |  | ||||||
| 		 |  | ||||||
| 		var exchange_rate = (row.account_currency==company_currency) ? 1 : frm.doc.exchange_rate; |  | ||||||
| 		 |  | ||||||
| 		frappe.model.set_value(dt, dn, "debit",  |  | ||||||
| 			flt(flt(row.debit_in_account_currency)*exchange_rate), precision("debit", row)); |  | ||||||
| 	}, | 	}, | ||||||
| 	 | 	 | ||||||
| 	credit_in_account_currency: function(frm, dt, dn) { | 	credit_in_account_currency: function(frm, cdt, cdn) { | ||||||
| 		var company_currency = erpnext.get_currency(frm.doc.company); | 		erpnext.journal_entry.set_debit_credit_in_company_currency(frm, cdt, cdn); | ||||||
| 		var row = locals[dt][dn]; |  | ||||||
| 		 |  | ||||||
| 		var exchange_rate = (row.account_currency==company_currency) ? 1 : frm.doc.exchange_rate; |  | ||||||
| 		 |  | ||||||
| 		frappe.model.set_value(dt, dn, "credit",  |  | ||||||
| 			flt(flt(row.credit_in_account_currency)*exchange_rate), precision("credit", row)); |  | ||||||
| 	}, | 	}, | ||||||
| 	 | 	 | ||||||
| 	debit: function(frm, dt, dn) { | 	debit: function(frm, dt, dn) { | ||||||
| @ -369,9 +382,52 @@ frappe.ui.form.on("Journal Entry Account", { | |||||||
| 	 | 	 | ||||||
| 	credit: function(frm, dt, dn) { | 	credit: function(frm, dt, dn) { | ||||||
| 		cur_frm.cscript.update_totals(frm.doc); | 		cur_frm.cscript.update_totals(frm.doc); | ||||||
|  | 	}, | ||||||
|  | 	 | ||||||
|  | 	exchange_rate: function(frm, cdt, cdn) { | ||||||
|  | 		erpnext.journal_entry.set_debit_credit_in_company_currency(frm, cdt, cdn); | ||||||
| 	} | 	} | ||||||
| }) | }) | ||||||
| 
 | 
 | ||||||
| frappe.ui.form.on("Journal Entry Account", "accounts_remove", function(frm) { | frappe.ui.form.on("Journal Entry Account", "accounts_remove", function(frm) { | ||||||
| 	cur_frm.cscript.update_totals(frm.doc); | 	cur_frm.cscript.update_totals(frm.doc); | ||||||
| }); | }); | ||||||
|  | 
 | ||||||
|  | erpnext.journal_entry.set_debit_credit_in_company_currency = function(frm, cdt, cdn) { | ||||||
|  | 	erpnext.journal_entry.set_exchange_rate(frm, cdt, cdn); | ||||||
|  | 	 | ||||||
|  | 	var row = locals[cdt][cdn]; | ||||||
|  | 	 | ||||||
|  | 	frappe.model.set_value(cdt, cdn, "debit",  | ||||||
|  | 		flt(flt(row.debit_in_account_currency)*row.exchange_rate), precision("debit", row)); | ||||||
|  | 	frappe.model.set_value(cdt, cdn, "credit",  | ||||||
|  | 		flt(flt(row.credit_in_account_currency)*row.exchange_rate), precision("credit", row)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | erpnext.journal_entry.set_exchange_rate = function(frm, cdt, cdn) { | ||||||
|  | 	var company_currency = erpnext.get_currency(frm.doc.company); | ||||||
|  | 	var row = locals[cdt][cdn]; | ||||||
|  | 	 | ||||||
|  | 	if(row.account_currency == company_currency || !frm.doc.multi_currency) { | ||||||
|  | 		frappe.model.set_value(cdt, cdn, "exchange_rate", 1); | ||||||
|  | 	} else if (!row.exchange_rate || row.account_type == "Bank") { | ||||||
|  | 		frappe.call({ | ||||||
|  | 			method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_exchange_rate", | ||||||
|  | 			args: { | ||||||
|  | 				account: row.account,  | ||||||
|  | 				account_currency: row.account_currency, | ||||||
|  | 				company: frm.doc.company, | ||||||
|  | 				reference_type: row.reference_type, | ||||||
|  | 				reference_name: row.reference_name, | ||||||
|  | 				debit: flt(row.debit_in_account_currency), | ||||||
|  | 				credit: flt(row.credit_in_account_currency), | ||||||
|  | 				exchange_rate: row.exchange_rate | ||||||
|  | 			}, | ||||||
|  | 			callback: function(r) { | ||||||
|  | 				if(r.message) { | ||||||
|  | 					frappe.model.set_value(cdt, cdn, "exchange_rate", r.message); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @ -147,28 +147,6 @@ | |||||||
|    "set_only_once": 0,  |    "set_only_once": 0,  | ||||||
|    "unique": 0 |    "unique": 0 | ||||||
|   },  |   },  | ||||||
|   { |  | ||||||
|    "allow_on_submit": 0,  |  | ||||||
|    "bold": 0,  |  | ||||||
|    "collapsible": 0,  |  | ||||||
|    "fieldname": "exchange_rate",  |  | ||||||
|    "fieldtype": "Float",  |  | ||||||
|    "hidden": 0,  |  | ||||||
|    "ignore_user_permissions": 0,  |  | ||||||
|    "in_filter": 0,  |  | ||||||
|    "in_list_view": 0,  |  | ||||||
|    "label": "Exchange Rate",  |  | ||||||
|    "no_copy": 1,  |  | ||||||
|    "permlevel": 0,  |  | ||||||
|    "precision": "",  |  | ||||||
|    "print_hide": 1,  |  | ||||||
|    "read_only": 0,  |  | ||||||
|    "report_hide": 0,  |  | ||||||
|    "reqd": 0,  |  | ||||||
|    "search_index": 0,  |  | ||||||
|    "set_only_once": 0,  |  | ||||||
|    "unique": 0 |  | ||||||
|   },  |  | ||||||
|   { |   { | ||||||
|    "allow_on_submit": 0,  |    "allow_on_submit": 0,  | ||||||
|    "bold": 0,  |    "bold": 0,  | ||||||
| @ -422,6 +400,28 @@ | |||||||
|    "set_only_once": 0,  |    "set_only_once": 0,  | ||||||
|    "unique": 0 |    "unique": 0 | ||||||
|   },  |   },  | ||||||
|  |   { | ||||||
|  |    "allow_on_submit": 0,  | ||||||
|  |    "bold": 0,  | ||||||
|  |    "collapsible": 0,  | ||||||
|  |    "fieldname": "multi_currency",  | ||||||
|  |    "fieldtype": "Check",  | ||||||
|  |    "hidden": 0,  | ||||||
|  |    "ignore_user_permissions": 0,  | ||||||
|  |    "in_filter": 0,  | ||||||
|  |    "in_list_view": 0,  | ||||||
|  |    "label": "Multi Currency",  | ||||||
|  |    "no_copy": 0,  | ||||||
|  |    "permlevel": 0,  | ||||||
|  |    "precision": "",  | ||||||
|  |    "print_hide": 1,  | ||||||
|  |    "read_only": 0,  | ||||||
|  |    "report_hide": 0,  | ||||||
|  |    "reqd": 0,  | ||||||
|  |    "search_index": 0,  | ||||||
|  |    "set_only_once": 0,  | ||||||
|  |    "unique": 0 | ||||||
|  |   },  | ||||||
|   { |   { | ||||||
|    "allow_on_submit": 0,  |    "allow_on_submit": 0,  | ||||||
|    "bold": 0,  |    "bold": 0,  | ||||||
| @ -1024,7 +1024,7 @@ | |||||||
|  "is_submittable": 1,  |  "is_submittable": 1,  | ||||||
|  "issingle": 0,  |  "issingle": 0,  | ||||||
|  "istable": 0,  |  "istable": 0,  | ||||||
|  "modified": "2015-08-27 16:07:33.265318",  |  "modified": "2015-09-09 02:07:40.980884",  | ||||||
|  "modified_by": "Administrator",  |  "modified_by": "Administrator",  | ||||||
|  "module": "Accounts",  |  "module": "Accounts",  | ||||||
|  "name": "Journal Entry",  |  "name": "Journal Entry",  | ||||||
|  | |||||||
| @ -5,9 +5,9 @@ from __future__ import unicode_literals | |||||||
| import frappe | import frappe | ||||||
| from frappe.utils import cstr, flt, fmt_money, formatdate | from frappe.utils import cstr, flt, fmt_money, formatdate | ||||||
| from frappe import msgprint, _, scrub | from frappe import msgprint, _, scrub | ||||||
| from erpnext.setup.utils import get_company_currency, get_exchange_rate |  | ||||||
| from erpnext.controllers.accounts_controller import AccountsController | from erpnext.controllers.accounts_controller import AccountsController | ||||||
| from erpnext.accounts.utils import get_balance_on | from erpnext.accounts.utils import get_balance_on | ||||||
|  | from erpnext.setup.utils import get_company_currency | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class JournalEntry(AccountsController): | class JournalEntry(AccountsController): | ||||||
| @ -267,39 +267,37 @@ class JournalEntry(AccountsController): | |||||||
| 	def validate_multi_currency(self): | 	def validate_multi_currency(self): | ||||||
| 		alternate_currency = [] | 		alternate_currency = [] | ||||||
| 		for d in self.get("accounts"): | 		for d in self.get("accounts"): | ||||||
| 			d.account_currency = frappe.db.get_value("Account", d.account, "account_currency") or self.company_currency | 			account = frappe.db.get_value("Account", d.account, ["account_currency", "account_type"], as_dict=1) | ||||||
|  | 			d.account_currency = account.account_currency or self.company_currency | ||||||
|  | 			d.account_type = account.account_type | ||||||
| 				 | 				 | ||||||
| 			if d.account_currency!=self.company_currency and d.account_currency not in alternate_currency: | 			if d.account_currency!=self.company_currency and d.account_currency not in alternate_currency: | ||||||
| 				alternate_currency.append(d.account_currency) | 				alternate_currency.append(d.account_currency) | ||||||
| 			 | 			 | ||||||
| 		if alternate_currency:				 | 		if alternate_currency: | ||||||
|  | 			if not self.multi_currency: | ||||||
|  | 				frappe.throw(_("Please check Multi Currency option to allow accounts with other currency")) | ||||||
|  | 				 | ||||||
| 			if len(alternate_currency) > 1: | 			if len(alternate_currency) > 1: | ||||||
| 				frappe.throw(_("Only one alternate currency can be used in a single Journal Entry")) | 				frappe.throw(_("Only one alternate currency can be used in a single Journal Entry")) | ||||||
| 			 | 
 | ||||||
| 			self.set_exchange_rate() | 		self.set_exchange_rate() | ||||||
| 			 | 
 | ||||||
| 			if not self.exchange_rate: |  | ||||||
| 				frappe.throw(_("Exchange Rate is mandatory in multi-currency Journal Entry")) |  | ||||||
| 		else: |  | ||||||
| 			self.exchange_rate = 1.0 |  | ||||||
| 			 |  | ||||||
| 		for d in self.get("accounts"): | 		for d in self.get("accounts"): | ||||||
| 			exchange_rate = self.exchange_rate if d.account_currency != self.company_currency else 1 | 			d.debit = flt(flt(d.debit_in_account_currency)*flt(d.exchange_rate), d.precision("debit")) | ||||||
| 			 | 			d.credit = flt(flt(d.credit_in_account_currency)*flt(d.exchange_rate), d.precision("credit")) | ||||||
| 			d.debit = flt(flt(d.debit_in_account_currency)*exchange_rate, d.precision("debit")) | 						 | ||||||
| 			d.credit = flt(flt(d.credit_in_account_currency)*exchange_rate, d.precision("credit")) |  | ||||||
| 			 |  | ||||||
| 	def set_exchange_rate(self): | 	def set_exchange_rate(self): | ||||||
| 		for d in self.get("accounts"): | 		for d in self.get("accounts"): | ||||||
| 			if d.account_currency != self.company_currency: | 			if d.account_currency == self.company_currency: | ||||||
| 				account_type = frappe.db.get_value("Account", d.account, "account_type") | 				d.exchange_rate = 1 | ||||||
| 				if account_type == "Bank" and flt(d.credit_in_account_currency) > 0: | 			elif not d.exchange_rate or d.account_type=="Bank" or \ | ||||||
| 					self.exchange_rate = get_average_exchange_rate(d.account) | 				(d.reference_type in ("Sales Invoice", "Purchase Invoice") and d.reference_name): | ||||||
| 					break | 					d.exchange_rate = get_exchange_rate(d.account, d.account_currency, self.company,  | ||||||
| 				if not self.exchange_rate: | 						d.reference_type, d.reference_name, d.debit, d.credit, d.exchange_rate) | ||||||
| 					self.exchange_rate = get_exchange_rate(d.account_currency, self.company_currency) | 
 | ||||||
| 					 | 			if not d.exchange_rate: | ||||||
| 					 | 				frappe.throw(_("Row {0}: Exchange Rate is mandatory").format(d.idx)) | ||||||
| 
 | 
 | ||||||
| 	def create_remarks(self): | 	def create_remarks(self): | ||||||
| 		r = [] | 		r = [] | ||||||
| @ -387,21 +385,21 @@ class JournalEntry(AccountsController): | |||||||
| 			diff = flt(self.difference, self.precision("difference")) | 			diff = flt(self.difference, self.precision("difference")) | ||||||
| 
 | 
 | ||||||
| 			# If any row without amount, set the diff on that row | 			# If any row without amount, set the diff on that row | ||||||
| 			for d in self.get('accounts'): | 			if diff: | ||||||
| 				if not d.credit and not d.debit and diff != 0: | 				for d in self.get('accounts'): | ||||||
| 					if diff>0: | 					if not d.credit_in_account_currency and not d.debit_in_account_currency and diff != 0: | ||||||
| 						d.credit = diff | 						blank_row = d | ||||||
| 					elif diff<0: | 						 | ||||||
| 						d.debit = diff | 				if not blank_row: | ||||||
| 					flag = 1 | 					blank_row = self.append('accounts', {}) | ||||||
| 
 | 					 | ||||||
| 			# Set the diff in a new row | 				blank_row.exchange_rate = 1 | ||||||
| 			if flag == 0 and diff != 0: |  | ||||||
| 				jd = self.append('accounts', {}) |  | ||||||
| 				if diff>0: | 				if diff>0: | ||||||
| 					jd.credit = abs(diff) | 					blank_row.credit_in_account_currency = diff | ||||||
|  | 					blank_row.credit = diff | ||||||
| 				elif diff<0: | 				elif diff<0: | ||||||
| 					jd.debit = abs(diff) | 					blank_row.debit_in_account_currency = abs(diff) | ||||||
|  | 					blank_row.debit = abs(diff) | ||||||
| 
 | 
 | ||||||
| 			self.validate_debit_and_credit() | 			self.validate_debit_and_credit() | ||||||
| 
 | 
 | ||||||
| @ -500,10 +498,12 @@ def get_default_bank_cash_account(company, voucher_type, mode_of_payment=None): | |||||||
| 			account = frappe.db.get_value("Account", {"company": company, "account_type": "Cash", "is_group": 0}) | 			account = frappe.db.get_value("Account", {"company": company, "account_type": "Cash", "is_group": 0}) | ||||||
| 
 | 
 | ||||||
| 	if account: | 	if account: | ||||||
|  | 		account_details = frappe.db.get_value("Account", account, ["account_currency", "account_type"], as_dict=1) | ||||||
| 		return { | 		return { | ||||||
| 			"account": account, | 			"account": account, | ||||||
| 			"balance": get_balance_on(account), | 			"balance": get_balance_on(account), | ||||||
| 			"account_currency": frappe.db.get_value("Account", account, "account_currency") | 			"account_currency": account_details.account_currency, | ||||||
|  | 			"account_type": account_details.account_type | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| @frappe.whitelist() | @frappe.whitelist() | ||||||
| @ -513,31 +513,36 @@ def get_payment_entry_from_sales_invoice(sales_invoice): | |||||||
| 	si = frappe.get_doc("Sales Invoice", sales_invoice) | 	si = frappe.get_doc("Sales Invoice", sales_invoice) | ||||||
| 	 | 	 | ||||||
| 	# exchange rate | 	# exchange rate | ||||||
| 	if si.company_currency == si.party_account_currency: | 	exchange_rate = get_exchange_rate(si.debit_to, si.party_account_currency, si.company,  | ||||||
| 		exchange_rate = 1 | 		si.doctype, si.name) | ||||||
| 	else: |  | ||||||
| 		exchange_rate = get_exchange_rate(si.party_account_currency, si.company_currency) |  | ||||||
| 	 | 	 | ||||||
| 	jv = get_payment_entry(si) | 	jv = get_payment_entry(si) | ||||||
| 	jv.remark = 'Payment received against Sales Invoice {0}. {1}'.format(si.name, si.remarks) | 	jv.remark = 'Payment received against Sales Invoice {0}. {1}'.format(si.name, si.remarks) | ||||||
| 	jv.exchange_rate = exchange_rate |  | ||||||
| 	 | 	 | ||||||
| 	# credit customer | 	# credit customer | ||||||
| 	jv.get("accounts")[0].account = si.debit_to | 	row1 = jv.get("accounts")[0] | ||||||
| 	jv.get("accounts")[0].account_currency = si.party_account_currency | 	row1.account = si.debit_to | ||||||
| 	jv.get("accounts")[0].party_type = "Customer" | 	row1.account_currency = si.party_account_currency | ||||||
| 	jv.get("accounts")[0].party = si.customer | 	row1.party_type = "Customer" | ||||||
| 	jv.get("accounts")[0].balance = get_balance_on(si.debit_to) | 	row1.party = si.customer | ||||||
| 	jv.get("accounts")[0].party_balance = get_balance_on(party=si.customer, party_type="Customer") | 	row1.balance = get_balance_on(si.debit_to) | ||||||
| 	jv.get("accounts")[0].credit_in_account_currency = si.outstanding_amount | 	row1.party_balance = get_balance_on(party=si.customer, party_type="Customer") | ||||||
| 	jv.get("accounts")[0].reference_type = si.doctype | 	row1.credit_in_account_currency = si.outstanding_amount | ||||||
| 	jv.get("accounts")[0].reference_name = si.name | 	row1.reference_type = si.doctype | ||||||
|  | 	row1.reference_name = si.name | ||||||
|  | 	row1.exchange_rate = exchange_rate | ||||||
|  | 	row1.account_type = "Receivable" if si.customer else "" | ||||||
| 
 | 
 | ||||||
| 	# debit bank | 	# debit bank | ||||||
| 	if jv.get("accounts")[1].account_currency == si.party_account_currency: | 	row2 = jv.get("accounts")[1] | ||||||
| 		jv.get("accounts")[1].debit_in_account_currency = si.outstanding_amount | 	if row2.account_currency == si.party_account_currency: | ||||||
|  | 		row2.debit_in_account_currency = si.outstanding_amount | ||||||
| 	else: | 	else: | ||||||
| 		jv.get("accounts")[1].debit_in_account_currency = si.outstanding_amount * exchange_rate | 		row2.debit_in_account_currency = si.outstanding_amount * exchange_rate | ||||||
|  | 		 | ||||||
|  | 	# set multi currency check | ||||||
|  | 	if row1.account_currency != si.company_currency or row2.account_currency != si.company_currency: | ||||||
|  | 		jv.multi_currency = 1 | ||||||
| 
 | 
 | ||||||
| 	return jv.as_dict() | 	return jv.as_dict() | ||||||
| 
 | 
 | ||||||
| @ -546,31 +551,37 @@ def get_payment_entry_from_purchase_invoice(purchase_invoice): | |||||||
| 	"""Returns new Journal Entry document as dict for given Purchase Invoice""" | 	"""Returns new Journal Entry document as dict for given Purchase Invoice""" | ||||||
| 	pi = frappe.get_doc("Purchase Invoice", purchase_invoice) | 	pi = frappe.get_doc("Purchase Invoice", purchase_invoice) | ||||||
| 	 | 	 | ||||||
| 	if pi.company_currency == pi.party_account_currency: | 	exchange_rate = get_exchange_rate(pi.debit_to, pi.party_account_currency, pi.company,  | ||||||
| 		exchange_rate = 1 | 		pi.doctype, pi.name) | ||||||
| 	else: |  | ||||||
| 		exchange_rate = get_exchange_rate(pi.party_account_currency, pi.company_currency) |  | ||||||
| 	 | 	 | ||||||
| 	jv = get_payment_entry(pi) | 	jv = get_payment_entry(pi) | ||||||
| 	jv.remark = 'Payment against Purchase Invoice {0}. {1}'.format(pi.name, pi.remarks) | 	jv.remark = 'Payment against Purchase Invoice {0}. {1}'.format(pi.name, pi.remarks) | ||||||
| 	jv.exchange_rate = exchange_rate | 	jv.exchange_rate = exchange_rate | ||||||
| 	 | 	 | ||||||
| 	# credit supplier | 	# credit supplier | ||||||
| 	jv.get("accounts")[0].account = pi.credit_to | 	row1 = jv.get("accounts")[0] | ||||||
| 	jv.get("accounts")[0].account_currency = pi.party_account_currency | 	row1.account = pi.credit_to | ||||||
| 	jv.get("accounts")[0].party_type = "Supplier" | 	row1.account_currency = pi.party_account_currency | ||||||
| 	jv.get("accounts")[0].party = pi.supplier | 	row1.party_type = "Supplier" | ||||||
| 	jv.get("accounts")[0].balance = get_balance_on(pi.credit_to) | 	row1.party = pi.supplier | ||||||
| 	jv.get("accounts")[0].party_balance = get_balance_on(party=pi.supplier, party_type="Supplier") | 	row1.balance = get_balance_on(pi.credit_to) | ||||||
| 	jv.get("accounts")[0].debit_in_account_currency = pi.outstanding_amount | 	row1.party_balance = get_balance_on(party=pi.supplier, party_type="Supplier") | ||||||
| 	jv.get("accounts")[0].reference_type = pi.doctype | 	row1.debit_in_account_currency = pi.outstanding_amount | ||||||
| 	jv.get("accounts")[0].reference_name = pi.name | 	row1.reference_type = pi.doctype | ||||||
|  | 	row1.reference_name = pi.name | ||||||
|  | 	row1.exchange_rate = exchange_rate | ||||||
|  | 	row1.account_type = "Payable" if pi.supplier else "" | ||||||
| 
 | 
 | ||||||
| 	# credit bank | 	# credit bank | ||||||
| 	if jv.get("accounts")[1].account_currency == pi.party_account_currency: | 	row2 = jv.get("accounts")[1] | ||||||
| 		jv.get("accounts")[1].credit_in_account_currency = pi.outstanding_amount | 	if row2.account_currency == pi.party_account_currency: | ||||||
|  | 		row2.credit_in_account_currency = pi.outstanding_amount | ||||||
| 	else: | 	else: | ||||||
| 		jv.get("accounts")[1].credit_in_account_currency = pi.outstanding_amount * exchange_rate | 		row2.credit_in_account_currency = pi.outstanding_amount * exchange_rate | ||||||
|  | 		 | ||||||
|  | 	# set multi currency check | ||||||
|  | 	if row1.account_currency != pi.company_currency or row2.account_currency != pi.company_currency: | ||||||
|  | 		jv.multi_currency = 1 | ||||||
| 
 | 
 | ||||||
| 	return jv.as_dict() | 	return jv.as_dict() | ||||||
| 
 | 
 | ||||||
| @ -590,37 +601,39 @@ def get_payment_entry_from_sales_order(sales_order): | |||||||
| 
 | 
 | ||||||
| 	party_account = get_party_account(so.company, so.customer, "Customer") | 	party_account = get_party_account(so.company, so.customer, "Customer") | ||||||
| 	party_account_currency = frappe.db.get_value("Account", party_account, "account_currency") | 	party_account_currency = frappe.db.get_value("Account", party_account, "account_currency") | ||||||
| 	company_currency = get_company_currency(so.company) |  | ||||||
| 	 | 	 | ||||||
| 	if so.company_currency == party_account_currency: | 	exchange_rate = get_exchange_rate(party_account, party_account_currency, so.company) | ||||||
| 		exchange_rate = 1 | 				 | ||||||
| 	else: | 	if party_account_currency == so.company_currency: | ||||||
| 		exchange_rate = get_exchange_rate(party_account_currency, so.company_currency) |  | ||||||
| 		 |  | ||||||
| 	jv.exchange_rate = exchange_rate |  | ||||||
| 		 |  | ||||||
| 	if party_account_currency == company_currency: |  | ||||||
| 		amount = flt(so.base_grand_total) - flt(so.advance_paid) | 		amount = flt(so.base_grand_total) - flt(so.advance_paid) | ||||||
| 	else: | 	else: | ||||||
| 		amount = flt(so.grand_total) - flt(so.advance_paid) | 		amount = flt(so.grand_total) - flt(so.advance_paid) | ||||||
| 
 | 
 | ||||||
| 	# credit customer | 	# credit customer | ||||||
| 	jv.get("accounts")[0].account = party_account | 	row1 = jv.get("accounts")[0] | ||||||
| 	jv.get("accounts")[0].account_currency = party_account_currency | 	row1.account = party_account | ||||||
| 	jv.get("accounts")[0].party_type = "Customer" | 	row1.account_currency = party_account_currency | ||||||
| 	jv.get("accounts")[0].party = so.customer | 	row1.party_type = "Customer" | ||||||
| 	jv.get("accounts")[0].balance = get_balance_on(party_account) | 	row1.party = so.customer | ||||||
| 	jv.get("accounts")[0].party_balance = get_balance_on(party=so.customer, party_type="Customer") | 	row1.balance = get_balance_on(party_account) | ||||||
| 	jv.get("accounts")[0].credit_in_account_currency = amount | 	row1.party_balance = get_balance_on(party=so.customer, party_type="Customer") | ||||||
| 	jv.get("accounts")[0].reference_type = so.doctype | 	row1.credit_in_account_currency = amount | ||||||
| 	jv.get("accounts")[0].reference_name = so.name | 	row1.reference_type = so.doctype | ||||||
| 	jv.get("accounts")[0].is_advance = "Yes" | 	row1.reference_name = so.name | ||||||
|  | 	row1.is_advance = "Yes" | ||||||
|  | 	row1.exchange_rate = exchange_rate | ||||||
|  | 	row1.account_type = "Receivable" | ||||||
| 
 | 
 | ||||||
| 	# debit bank | 	# debit bank | ||||||
| 	if jv.get("accounts")[1].account_currency == party_account_currency: | 	row2 = jv.get("accounts")[1] | ||||||
| 		jv.get("accounts")[1].debit_in_account_currency = amount | 	if row2.account_currency == party_account_currency: | ||||||
|  | 		row2.debit_in_account_currency = amount | ||||||
| 	else: | 	else: | ||||||
| 		jv.get("accounts")[1].debit_in_account_currency = amount * exchange_rate | 		row2.debit_in_account_currency = amount * exchange_rate | ||||||
|  | 		 | ||||||
|  | 	# set multi currency check | ||||||
|  | 	if row1.account_currency != so.company_currency or row2.account_currency != so.company_currency: | ||||||
|  | 		jv.multi_currency = 1 | ||||||
| 
 | 
 | ||||||
| 	return jv.as_dict() | 	return jv.as_dict() | ||||||
| 
 | 
 | ||||||
| @ -639,36 +652,38 @@ def get_payment_entry_from_purchase_order(purchase_order): | |||||||
| 	 | 	 | ||||||
| 	party_account = get_party_account(po.company, po.supplier, "Supplier") | 	party_account = get_party_account(po.company, po.supplier, "Supplier") | ||||||
| 	party_account_currency = frappe.db.get_value("Account", party_account, "account_currency") | 	party_account_currency = frappe.db.get_value("Account", party_account, "account_currency") | ||||||
| 	company_currency = get_company_currency(po.company) |  | ||||||
| 	 | 	 | ||||||
| 	if po.company_currency == party_account_currency: | 	exchange_rate = get_exchange_rate(party_account, party_account_currency, po.company) | ||||||
| 		exchange_rate = 1 |  | ||||||
| 	else: |  | ||||||
| 		exchange_rate = get_exchange_rate(party_account_currency, po.company_currency) |  | ||||||
| 		 | 		 | ||||||
| 	jv.exchange_rate = exchange_rate | 	if party_account_currency == po.company_currency: | ||||||
| 	 |  | ||||||
| 	if party_account_currency == company_currency: |  | ||||||
| 		amount = flt(po.base_grand_total) - flt(po.advance_paid) | 		amount = flt(po.base_grand_total) - flt(po.advance_paid) | ||||||
| 	else: | 	else: | ||||||
| 		amount = flt(po.grand_total) - flt(po.advance_paid) | 		amount = flt(po.grand_total) - flt(po.advance_paid) | ||||||
| 
 | 
 | ||||||
| 	# credit customer | 	# credit customer | ||||||
| 	jv.get("accounts")[0].account = party_account | 	row1 = jv.get("accounts")[0] | ||||||
| 	jv.get("accounts")[0].party_type = "Supplier" | 	row1.account = party_account | ||||||
| 	jv.get("accounts")[0].party = po.supplier | 	row1.party_type = "Supplier" | ||||||
| 	jv.get("accounts")[0].balance = get_balance_on(party_account) | 	row1.party = po.supplier | ||||||
| 	jv.get("accounts")[0].party_balance = get_balance_on(party=po.supplier, party_type="Supplier") | 	row1.balance = get_balance_on(party_account) | ||||||
| 	jv.get("accounts")[0].debit_in_account_currency = amount | 	row1.party_balance = get_balance_on(party=po.supplier, party_type="Supplier") | ||||||
| 	jv.get("accounts")[0].reference_type = po.doctype | 	row1.debit_in_account_currency = amount | ||||||
| 	jv.get("accounts")[0].reference_name = po.name | 	row1.reference_type = po.doctype | ||||||
| 	jv.get("accounts")[0].is_advance = "Yes" | 	row1.reference_name = po.name | ||||||
|  | 	row1.is_advance = "Yes" | ||||||
|  | 	row1.exchange_rate = exchange_rate | ||||||
|  | 	row1.account_type = "Payable" | ||||||
| 
 | 
 | ||||||
| 	# debit bank | 	# debit bank | ||||||
| 	if jv.get("accounts")[1].account_currency == party_account_currency: | 	row2 = jv.get("accounts")[1] | ||||||
| 		jv.get("accounts")[1].credit_in_account_currency = amount | 	if row2.account_currency == party_account_currency: | ||||||
|  | 		row2.credit_in_account_currency = amount | ||||||
| 	else: | 	else: | ||||||
| 		jv.get("accounts")[1].credit_in_account_currency = amount * exchange_rate | 		row2.credit_in_account_currency = amount * exchange_rate | ||||||
|  | 		 | ||||||
|  | 	# set multi currency check | ||||||
|  | 	if row1.account_currency != po.company_currency or row2.account_currency != po.company_currency: | ||||||
|  | 		jv.multi_currency = 1 | ||||||
| 
 | 
 | ||||||
| 	return jv.as_dict() | 	return jv.as_dict() | ||||||
| 
 | 
 | ||||||
| @ -687,6 +702,9 @@ def get_payment_entry(doc): | |||||||
| 		d2.account = bank_account["account"] | 		d2.account = bank_account["account"] | ||||||
| 		d2.balance = bank_account["balance"] | 		d2.balance = bank_account["balance"] | ||||||
| 		d2.account_currency = bank_account["account_currency"] | 		d2.account_currency = bank_account["account_currency"] | ||||||
|  | 		d2.account_type = bank_account["account_type"] | ||||||
|  | 		d2.exchange_rate = get_exchange_rate(bank_account["account"],  | ||||||
|  | 			bank_account["account_currency"], doc.company) | ||||||
| 
 | 
 | ||||||
| 	return jv | 	return jv | ||||||
| 
 | 
 | ||||||
| @ -712,27 +730,37 @@ def get_outstanding(args): | |||||||
| 	if not frappe.has_permission("Account"): | 	if not frappe.has_permission("Account"): | ||||||
| 		frappe.msgprint(_("No Permission"), raise_exception=1) | 		frappe.msgprint(_("No Permission"), raise_exception=1) | ||||||
| 	args = eval(args) | 	args = eval(args) | ||||||
|  | 	company_currency = get_company_currency(args.get("company")) | ||||||
|  | 	 | ||||||
| 	if args.get("doctype") == "Journal Entry": | 	if args.get("doctype") == "Journal Entry": | ||||||
| 		condition = " and party=%(party)s" if args.get("party") else "" | 		condition = " and party=%(party)s" if args.get("party") else "" | ||||||
| 
 | 
 | ||||||
| 		against_jv_amount = frappe.db.sql(""" | 		against_jv_amount = frappe.db.sql(""" | ||||||
| 			select sum(ifnull(debit, 0)) - sum(ifnull(credit, 0)) | 			select sum(ifnull(debit_in_account_currency, 0)) - sum(ifnull(credit_in_account_currency, 0)) | ||||||
| 			from `tabJournal Entry Account` where parent=%(docname)s and account=%(account)s {0} | 			from `tabJournal Entry Account` where parent=%(docname)s and account=%(account)s {0} | ||||||
| 			and ifnull(reference_type, '')=''""".format(condition), args) | 			and ifnull(reference_type, '')=''""".format(condition), args) | ||||||
| 
 | 
 | ||||||
| 		against_jv_amount = flt(against_jv_amount[0][0]) if against_jv_amount else 0 | 		against_jv_amount = flt(against_jv_amount[0][0]) if against_jv_amount else 0 | ||||||
|  | 		amount_field = "credit_in_account_currency" if against_jv_amount > 0 else "debit_in_account_currency" | ||||||
| 		return { | 		return { | ||||||
| 			("credit" if against_jv_amount > 0 else "debit"): abs(against_jv_amount) | 			amount_field: abs(against_jv_amount) | ||||||
| 		} | 		} | ||||||
| 	elif args.get("doctype") == "Sales Invoice": | 	elif args.get("doctype") in ("Sales Invoice", "Purchase Invoice"): | ||||||
| 		outstanding_amount = flt(frappe.db.get_value("Sales Invoice", args["docname"], "outstanding_amount")) | 		invoice = frappe.db.get_value(args["doctype"], args["docname"],  | ||||||
|  | 			["outstanding_amount", "conversion_rate"], as_dict=1) | ||||||
|  | 
 | ||||||
|  | 		exchange_rate = invoice.conversion_rate if (args.get("account_currency") != company_currency) else 1 | ||||||
|  | 		 | ||||||
|  | 		if args["doctype"] == "Sales Invoice": | ||||||
|  | 			amount_field = "credit_in_account_currency" \ | ||||||
|  | 				if flt(invoice.outstanding_amount) > 0 else "debit_in_account_currency" | ||||||
|  | 		else: | ||||||
|  | 			amount_field = "debit_in_account_currency" \ | ||||||
|  | 				if flt(invoice.outstanding_amount) > 0 else "credit_in_account_currency" | ||||||
|  | 				 | ||||||
| 		return { | 		return { | ||||||
| 			("credit" if outstanding_amount > 0 else "debit"): abs(outstanding_amount) | 			amount_field: abs(flt(invoice.outstanding_amount)), | ||||||
| 		} | 			"exchange_rate": exchange_rate | ||||||
| 	elif args.get("doctype") == "Purchase Invoice": |  | ||||||
| 		outstanding_amount = flt(frappe.db.get_value("Purchase Invoice", args["docname"], "outstanding_amount")) |  | ||||||
| 		return { |  | ||||||
| 			("debit" if outstanding_amount > 0 else "credit"): abs(outstanding_amount) |  | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| @frappe.whitelist() | @frappe.whitelist() | ||||||
| @ -753,7 +781,7 @@ def get_party_account_and_balance(company, party_type, party): | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @frappe.whitelist() | @frappe.whitelist() | ||||||
| def get_account_balance_and_party_type(account, date, company, credited=False): | def get_account_balance_and_party_type(account, date, company, debit=None, credit=None, exchange_rate=None): | ||||||
| 	"""Returns dict of account balance and party type to be set in Journal Entry on selection of account.""" | 	"""Returns dict of account balance and party type to be set in Journal Entry on selection of account.""" | ||||||
| 	if not frappe.has_permission("Account"): | 	if not frappe.has_permission("Account"): | ||||||
| 		frappe.msgprint(_("No Permission"), raise_exception=1) | 		frappe.msgprint(_("No Permission"), raise_exception=1) | ||||||
| @ -768,19 +796,37 @@ def get_account_balance_and_party_type(account, date, company, credited=False): | |||||||
| 	else: | 	else: | ||||||
| 		party_type = "" | 		party_type = "" | ||||||
| 		 | 		 | ||||||
| 	exchange_rate = None |  | ||||||
| 	if account_details.account_currency != company_currency: |  | ||||||
| 		if account_details.account_type == "Bank" and credited: |  | ||||||
| 			exchange_rate = get_average_exchange_rate(account) |  | ||||||
| 		else: |  | ||||||
| 			exchange_rate = get_exchange_rate(account_details.account_currency, company_currency) |  | ||||||
| 
 |  | ||||||
| 	grid_values = { | 	grid_values = { | ||||||
| 		"balance": get_balance_on(account, date), | 		"balance": get_balance_on(account, date), | ||||||
| 		"party_type": party_type, | 		"party_type": party_type, | ||||||
|  | 		"account_type": account_details.account_type, | ||||||
| 		"account_currency": account_details.account_currency or company_currency, | 		"account_currency": account_details.account_currency or company_currency, | ||||||
|  | 		"exchange_rate": get_exchange_rate(account, account_details.account_currency,  | ||||||
|  | 			company, debit=debit, credit=credit, exchange_rate=exchange_rate) | ||||||
| 	} | 	} | ||||||
| 	return grid_values, exchange_rate | 	return grid_values | ||||||
|  | 	 | ||||||
|  | @frappe.whitelist() | ||||||
|  | def get_exchange_rate(account, account_currency, company,  | ||||||
|  | 		reference_type=None, reference_name=None, debit=None, credit=None, exchange_rate=None): | ||||||
|  | 	from erpnext.setup.utils import get_exchange_rate | ||||||
|  | 	company_currency = get_company_currency(company) | ||||||
|  | 	account_details = frappe.db.get_value("Account", account, ["account_type", "root_type"], as_dict=1) | ||||||
|  | 		 | ||||||
|  | 	if account_currency != company_currency: | ||||||
|  | 		if reference_type in ("Sales Invoice", "Purchase Invoice") and reference_name: | ||||||
|  | 			exchange_rate = frappe.db.get_value(reference_type, reference_name, "conversion_rate") | ||||||
|  | 		elif account_details.account_type == "Bank" and \ | ||||||
|  | 			((account_details.root_type == "Asset" and flt(credit) > 0) or  | ||||||
|  | 				(account_details.root_type == "Liability" and debit)): | ||||||
|  | 			exchange_rate = get_average_exchange_rate(account) | ||||||
|  | 		 | ||||||
|  | 		if not exchange_rate: | ||||||
|  | 			exchange_rate = get_exchange_rate(account_currency, company_currency) | ||||||
|  | 	else: | ||||||
|  | 		exchange_rate = 1 | ||||||
|  | 	 | ||||||
|  | 	return exchange_rate | ||||||
| 	 | 	 | ||||||
| def get_average_exchange_rate(account): | def get_average_exchange_rate(account): | ||||||
| 	exchange_rate = 0 | 	exchange_rate = 0 | ||||||
|  | |||||||
| @ -218,19 +218,20 @@ def make_journal_entry(account1, account2, amount, cost_center=None, exchange_ra | |||||||
| 	jv.company = "_Test Company" | 	jv.company = "_Test Company" | ||||||
| 	jv.fiscal_year = "_Test Fiscal Year 2013" | 	jv.fiscal_year = "_Test Fiscal Year 2013" | ||||||
| 	jv.user_remark = "test" | 	jv.user_remark = "test" | ||||||
| 	jv.exchange_rate = exchange_rate | 	jv.multi_currency = 1 | ||||||
| 
 |  | ||||||
| 	jv.set("accounts", [ | 	jv.set("accounts", [ | ||||||
| 		{ | 		{ | ||||||
| 			"account": account1, | 			"account": account1, | ||||||
| 			"cost_center": cost_center, | 			"cost_center": cost_center, | ||||||
| 			"debit_in_account_currency": amount if amount > 0 else 0, | 			"debit_in_account_currency": amount if amount > 0 else 0, | ||||||
| 			"credit_in_account_currency": abs(amount) if amount < 0 else 0, | 			"credit_in_account_currency": abs(amount) if amount < 0 else 0, | ||||||
|  | 			"exchange_rate": exchange_rate | ||||||
| 		}, { | 		}, { | ||||||
| 			"account": account2, | 			"account": account2, | ||||||
| 			"cost_center": cost_center, | 			"cost_center": cost_center, | ||||||
| 			"credit_in_account_currency": amount if amount > 0 else 0, | 			"credit_in_account_currency": amount if amount > 0 else 0, | ||||||
| 			"debit_in_account_currency": abs(amount) if amount < 0 else 0, | 			"debit_in_account_currency": abs(amount) if amount < 0 else 0, | ||||||
|  | 			exchange_rate: exchange_rate | ||||||
| 		} | 		} | ||||||
| 	]) | 	]) | ||||||
| 	if save or submit: | 	if save or submit: | ||||||
|  | |||||||
| @ -38,19 +38,18 @@ | |||||||
|    "allow_on_submit": 0,  |    "allow_on_submit": 0,  | ||||||
|    "bold": 0,  |    "bold": 0,  | ||||||
|    "collapsible": 0,  |    "collapsible": 0,  | ||||||
|    "fieldname": "account_currency",  |    "fieldname": "account_type",  | ||||||
|    "fieldtype": "Link",  |    "fieldtype": "Data",  | ||||||
|    "hidden": 1,  |    "hidden": 1,  | ||||||
|    "ignore_user_permissions": 0,  |    "ignore_user_permissions": 0,  | ||||||
|    "in_filter": 0,  |    "in_filter": 0,  | ||||||
|    "in_list_view": 0,  |    "in_list_view": 0,  | ||||||
|    "label": "Account Currency",  |    "label": "Account Type",  | ||||||
|    "no_copy": 1,  |    "no_copy": 0,  | ||||||
|    "options": "Currency",  |  | ||||||
|    "permlevel": 0,  |    "permlevel": 0,  | ||||||
|    "precision": "",  |    "precision": "",  | ||||||
|    "print_hide": 1,  |    "print_hide": 1,  | ||||||
|    "read_only": 1,  |    "read_only": 0,  | ||||||
|    "report_hide": 0,  |    "report_hide": 0,  | ||||||
|    "reqd": 0,  |    "reqd": 0,  | ||||||
|    "search_index": 0,  |    "search_index": 0,  | ||||||
| @ -196,6 +195,96 @@ | |||||||
|    "set_only_once": 0,  |    "set_only_once": 0,  | ||||||
|    "unique": 0 |    "unique": 0 | ||||||
|   },  |   },  | ||||||
|  |   { | ||||||
|  |    "allow_on_submit": 0,  | ||||||
|  |    "bold": 0,  | ||||||
|  |    "collapsible": 0,  | ||||||
|  |    "collapsible_depends_on": "",  | ||||||
|  |    "depends_on": "",  | ||||||
|  |    "fieldname": "currency_section",  | ||||||
|  |    "fieldtype": "Section Break",  | ||||||
|  |    "hidden": 0,  | ||||||
|  |    "ignore_user_permissions": 0,  | ||||||
|  |    "in_filter": 0,  | ||||||
|  |    "in_list_view": 0,  | ||||||
|  |    "label": "Currency",  | ||||||
|  |    "no_copy": 0,  | ||||||
|  |    "permlevel": 0,  | ||||||
|  |    "precision": "",  | ||||||
|  |    "print_hide": 0,  | ||||||
|  |    "read_only": 0,  | ||||||
|  |    "report_hide": 0,  | ||||||
|  |    "reqd": 0,  | ||||||
|  |    "search_index": 0,  | ||||||
|  |    "set_only_once": 0,  | ||||||
|  |    "unique": 0 | ||||||
|  |   },  | ||||||
|  |   { | ||||||
|  |    "allow_on_submit": 0,  | ||||||
|  |    "bold": 0,  | ||||||
|  |    "collapsible": 0,  | ||||||
|  |    "fieldname": "account_currency",  | ||||||
|  |    "fieldtype": "Link",  | ||||||
|  |    "hidden": 0,  | ||||||
|  |    "ignore_user_permissions": 0,  | ||||||
|  |    "in_filter": 0,  | ||||||
|  |    "in_list_view": 0,  | ||||||
|  |    "label": "Account Currency",  | ||||||
|  |    "no_copy": 1,  | ||||||
|  |    "options": "Currency",  | ||||||
|  |    "permlevel": 0,  | ||||||
|  |    "precision": "",  | ||||||
|  |    "print_hide": 1,  | ||||||
|  |    "read_only": 1,  | ||||||
|  |    "report_hide": 0,  | ||||||
|  |    "reqd": 0,  | ||||||
|  |    "search_index": 0,  | ||||||
|  |    "set_only_once": 0,  | ||||||
|  |    "unique": 0 | ||||||
|  |   },  | ||||||
|  |   { | ||||||
|  |    "allow_on_submit": 0,  | ||||||
|  |    "bold": 0,  | ||||||
|  |    "collapsible": 0,  | ||||||
|  |    "fieldname": "column_break_10",  | ||||||
|  |    "fieldtype": "Column Break",  | ||||||
|  |    "hidden": 0,  | ||||||
|  |    "ignore_user_permissions": 0,  | ||||||
|  |    "in_filter": 0,  | ||||||
|  |    "in_list_view": 0,  | ||||||
|  |    "no_copy": 0,  | ||||||
|  |    "permlevel": 0,  | ||||||
|  |    "precision": "",  | ||||||
|  |    "print_hide": 0,  | ||||||
|  |    "read_only": 0,  | ||||||
|  |    "report_hide": 0,  | ||||||
|  |    "reqd": 0,  | ||||||
|  |    "search_index": 0,  | ||||||
|  |    "set_only_once": 0,  | ||||||
|  |    "unique": 0 | ||||||
|  |   },  | ||||||
|  |   { | ||||||
|  |    "allow_on_submit": 0,  | ||||||
|  |    "bold": 0,  | ||||||
|  |    "collapsible": 0,  | ||||||
|  |    "fieldname": "exchange_rate",  | ||||||
|  |    "fieldtype": "Float",  | ||||||
|  |    "hidden": 0,  | ||||||
|  |    "ignore_user_permissions": 0,  | ||||||
|  |    "in_filter": 0,  | ||||||
|  |    "in_list_view": 0,  | ||||||
|  |    "label": "Exchange Rate",  | ||||||
|  |    "no_copy": 0,  | ||||||
|  |    "permlevel": 0,  | ||||||
|  |    "precision": "",  | ||||||
|  |    "print_hide": 1,  | ||||||
|  |    "read_only": 0,  | ||||||
|  |    "report_hide": 0,  | ||||||
|  |    "reqd": 0,  | ||||||
|  |    "search_index": 0,  | ||||||
|  |    "set_only_once": 0,  | ||||||
|  |    "unique": 0 | ||||||
|  |   },  | ||||||
|   { |   { | ||||||
|    "allow_on_submit": 0,  |    "allow_on_submit": 0,  | ||||||
|    "bold": 0,  |    "bold": 0,  | ||||||
| @ -474,7 +563,7 @@ | |||||||
|  "is_submittable": 0,  |  "is_submittable": 0,  | ||||||
|  "issingle": 0,  |  "issingle": 0,  | ||||||
|  "istable": 1,  |  "istable": 1,  | ||||||
|  "modified": "2015-09-04 03:29:37.127968",  |  "modified": "2015-09-09 12:55:59.270539",  | ||||||
|  "modified_by": "Administrator",  |  "modified_by": "Administrator",  | ||||||
|  "module": "Accounts",  |  "module": "Accounts",  | ||||||
|  "name": "Journal Entry Account",  |  "name": "Journal Entry Account",  | ||||||
|  | |||||||
| @ -216,7 +216,7 @@ class PurchaseInvoice(BuyingController): | |||||||
| 					'party_type': 'Supplier', | 					'party_type': 'Supplier', | ||||||
| 					'party': self.supplier, | 					'party': self.supplier, | ||||||
| 					'is_advance' : 'Yes', | 					'is_advance' : 'Yes', | ||||||
| 					'dr_or_cr' : 'debit', | 					'dr_or_cr' : 'debit_in_account_currency', | ||||||
| 					'unadjusted_amt' : flt(d.advance_amount), | 					'unadjusted_amt' : flt(d.advance_amount), | ||||||
| 					'allocated_amt' : flt(d.allocated_amount) | 					'allocated_amt' : flt(d.allocated_amount) | ||||||
| 				} | 				} | ||||||
|  | |||||||
| @ -219,7 +219,8 @@ class TestPurchaseInvoice(unittest.TestCase): | |||||||
| 		pi.load_from_db() | 		pi.load_from_db() | ||||||
| 
 | 
 | ||||||
| 		self.assertTrue(frappe.db.sql("""select name from `tabJournal Entry Account` | 		self.assertTrue(frappe.db.sql("""select name from `tabJournal Entry Account` | ||||||
| 			where reference_type='Purchase Invoice' and reference_name=%s and debit=300""", pi.name)) | 			where reference_type='Purchase Invoice'  | ||||||
|  | 			and reference_name=%s and debit_in_account_currency=300""", pi.name)) | ||||||
| 
 | 
 | ||||||
| 		self.assertEqual(pi.outstanding_amount, 1212.30) | 		self.assertEqual(pi.outstanding_amount, 1212.30) | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -141,6 +141,9 @@ | |||||||
|   "supplier": "_Test Supplier", |   "supplier": "_Test Supplier", | ||||||
|   "supplier_name": "_Test Supplier" |   "supplier_name": "_Test Supplier" | ||||||
|  }, |  }, | ||||||
|  |   | ||||||
|  |   | ||||||
|  |   | ||||||
|  { |  { | ||||||
|   "bill_no": "NA", |   "bill_no": "NA", | ||||||
|   "buying_price_list": "_Test Price List", |   "buying_price_list": "_Test Price List", | ||||||
|  | |||||||
| @ -260,7 +260,7 @@ class SalesInvoice(SellingController): | |||||||
| 					'party_type': 'Customer', | 					'party_type': 'Customer', | ||||||
| 					'party': self.customer, | 					'party': self.customer, | ||||||
| 					'is_advance' : 'Yes', | 					'is_advance' : 'Yes', | ||||||
| 					'dr_or_cr' : 'credit', | 					'dr_or_cr' : 'credit_in_account_currency', | ||||||
| 					'unadjusted_amt' : flt(d.advance_amount), | 					'unadjusted_amt' : flt(d.advance_amount), | ||||||
| 					'allocated_amt' : flt(d.allocated_amount) | 					'allocated_amt' : flt(d.allocated_amount) | ||||||
| 				} | 				} | ||||||
|  | |||||||
| @ -661,7 +661,7 @@ class TestSalesInvoice(unittest.TestCase): | |||||||
| 			where reference_name=%s""", si.name)) | 			where reference_name=%s""", si.name)) | ||||||
| 
 | 
 | ||||||
| 		self.assertTrue(frappe.db.sql("""select name from `tabJournal Entry Account` | 		self.assertTrue(frappe.db.sql("""select name from `tabJournal Entry Account` | ||||||
| 			where reference_name=%s and credit=300""", si.name)) | 			where reference_name=%s and credit_in_account_currency=300""", si.name)) | ||||||
| 
 | 
 | ||||||
| 		self.assertEqual(si.outstanding_amount, 261.8) | 		self.assertEqual(si.outstanding_amount, 261.8) | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -198,21 +198,26 @@ def update_against_doc(d, jv_obj): | |||||||
| 	jv_detail.set("reference_name", d["against_voucher"]) | 	jv_detail.set("reference_name", d["against_voucher"]) | ||||||
| 
 | 
 | ||||||
| 	if d['allocated_amt'] < d['unadjusted_amt']: | 	if d['allocated_amt'] < d['unadjusted_amt']: | ||||||
| 		jvd = frappe.db.sql("""select cost_center, balance, against_account, is_advance | 		jvd = frappe.db.sql(""" | ||||||
| 			from `tabJournal Entry Account` where name = %s""", d['voucher_detail_no']) | 			select cost_center, balance, against_account, is_advance, account_type, exchange_rate | ||||||
|  | 			from `tabJournal Entry Account` where name = %s | ||||||
|  | 		""", d['voucher_detail_no'], as_dict=True) | ||||||
|  | 		 | ||||||
| 		# new entry with balance amount | 		# new entry with balance amount | ||||||
| 		ch = jv_obj.append("accounts") | 		ch = jv_obj.append("accounts") | ||||||
| 		ch.account = d['account'] | 		ch.account = d['account'] | ||||||
|  | 		ch.account_type = jvd[0]['account_type'] | ||||||
|  | 		ch.exchange_rate = jvd[0]['exchange_rate'] | ||||||
| 		ch.party_type = d["party_type"] | 		ch.party_type = d["party_type"] | ||||||
| 		ch.party = d["party"] | 		ch.party = d["party"] | ||||||
| 		ch.cost_center = cstr(jvd[0][0]) | 		ch.cost_center = cstr(jvd[0]["cost_center"]) | ||||||
| 		ch.balance = flt(jvd[0][1]) | 		ch.balance = flt(jvd[0]["balance"]) | ||||||
| 		ch.set(d['dr_or_cr'], flt(d['unadjusted_amt']) - flt(d['allocated_amt'])) | 		ch.set(d['dr_or_cr'], flt(d['unadjusted_amt']) - flt(d['allocated_amt'])) | ||||||
| 		ch.set(d['dr_or_cr']== 'debit' and 'credit' or 'debit', 0) | 		ch.set(d['dr_or_cr']== 'debit' and 'credit' or 'debit', 0) | ||||||
| 		ch.against_account = cstr(jvd[0][2]) | 		ch.against_account = cstr(jvd[0]["against_account"]) | ||||||
| 		ch.reference_type = original_reference_type | 		ch.reference_type = original_reference_type | ||||||
| 		ch.reference_name = original_reference_name | 		ch.reference_name = original_reference_name | ||||||
| 		ch.is_advance = cstr(jvd[0][3]) | 		ch.is_advance = cstr(jvd[0]["is_advance"]) | ||||||
| 		ch.docstatus = 1 | 		ch.docstatus = 1 | ||||||
| 
 | 
 | ||||||
| 	# will work as update after submit | 	# will work as update after submit | ||||||
|  | |||||||
| @ -236,8 +236,8 @@ class AccountsController(TransactionBase): | |||||||
| 				.format(account, " or ".join(valid_currency))) | 				.format(account, " or ".join(valid_currency))) | ||||||
| 		 | 		 | ||||||
| 	def set_balance_in_account_currency(self, gl_dict, account_currency=None):			 | 	def set_balance_in_account_currency(self, gl_dict, account_currency=None):			 | ||||||
| 		if not (self.get("conversion_rate") or self.get("exchange_rate")) \ | 		if (not self.get("conversion_rate") and self.doctype!="Journal Entry"  | ||||||
| 			and account_currency!=self.company_currency: | 			and account_currency!=self.company_currency): | ||||||
| 				frappe.throw(_("Account: {0} with currency: {1} can not be selected") | 				frappe.throw(_("Account: {0} with currency: {1} can not be selected") | ||||||
| 					.format(gl_dict.account, account_currency)) | 					.format(gl_dict.account, account_currency)) | ||||||
| 			 | 			 | ||||||
|  | |||||||
| @ -37,18 +37,18 @@ def execute(): | |||||||
| 		""", (company.default_currency, company.name)) | 		""", (company.default_currency, company.name)) | ||||||
| 		 | 		 | ||||||
| 		# update exchange rate, debit/credit in account currency in Journal Entry | 		# update exchange rate, debit/credit in account currency in Journal Entry | ||||||
| 		frappe.db.sql("""update `tabJournal Entry` set exchange_rate=1""") |  | ||||||
| 	 |  | ||||||
| 		frappe.db.sql(""" | 		frappe.db.sql(""" | ||||||
| 			update | 			update `tabJournal Entry Account` jea | ||||||
| 				`tabJournal Entry Account` jea, `tabJournal Entry` je | 			set exchange_rate=1,  | ||||||
| 			set  |  | ||||||
| 				debit_in_account_currency=debit, | 				debit_in_account_currency=debit, | ||||||
| 				credit_in_account_currency=credit, | 				credit_in_account_currency=credit, | ||||||
| 				account_currency=%s | 				account_type=(select account_type from `tabAccount` where name=jea.account) | ||||||
| 			where | 		""") | ||||||
| 				jea.parent = je.name | 	 | ||||||
| 				and je.company=%s | 		frappe.db.sql(""" | ||||||
|  | 			update `tabJournal Entry Account` jea, `tabJournal Entry` je | ||||||
|  | 			set account_currency=%s | ||||||
|  | 			where jea.parent = je.name and je.company=%s | ||||||
| 		""", (company.default_currency, company.name)) | 		""", (company.default_currency, company.name)) | ||||||
| 	 | 	 | ||||||
| 		# update debit/credit in account currency in GL Entry | 		# update debit/credit in account currency in GL Entry | ||||||
| @ -87,7 +87,15 @@ def execute(): | |||||||
| 							break | 							break | ||||||
| 					 | 					 | ||||||
| 					if not party_account_exists: | 					if not party_account_exists: | ||||||
| 						party_account = party_gle.account if party_gle else company.default_receivable_account | 						party_account = None | ||||||
|  | 						if party_gle: | ||||||
|  | 							party_account = party_gle.account | ||||||
|  | 						else: | ||||||
|  | 							default_receivable_account_currency = frappe.db.get_value("Account",  | ||||||
|  | 								company.default_receivable_account, "account_currency") | ||||||
|  | 							if default_receivable_account_currency != company.default_currency: | ||||||
|  | 								party_account = company.default_receivable_account | ||||||
|  | 							 | ||||||
| 						if party_account: | 						if party_account: | ||||||
| 							party.append("accounts", { | 							party.append("accounts", { | ||||||
| 								"company": company.name, | 								"company": company.name, | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user