Payment Entry submission and more
This commit is contained in:
		
							parent
							
								
									12e2a51519
								
							
						
					
					
						commit
						e3a10170f7
					
				| @ -3,8 +3,10 @@ | ||||
| 
 | ||||
| frappe.ui.form.on('Payment Entry', { | ||||
| 	onload: function(frm) { | ||||
| 		frm.set_value("paid_from_account_currency", null); | ||||
| 		frm.set_value("paid_from_account_currency", null); | ||||
| 		if(frm.doc.__islocal) { | ||||
| 			frm.set_value("paid_from_account_currency", null); | ||||
| 			frm.set_value("paid_to_account_currency", null); | ||||
| 		} | ||||
| 	}, | ||||
| 	 | ||||
| 	setup: function(frm) { | ||||
| @ -14,7 +16,7 @@ frappe.ui.form.on('Payment Entry', { | ||||
| 			{fieldname: 'outstanding_amount', columns: 3}, | ||||
| 			{fieldname: 'allocated_amount', columns: 3} | ||||
| 		]; | ||||
| 				 | ||||
| 		 | ||||
| 		var party_account_type = frm.doc.party_type=="Customer" ? "Receivable" : "Payable"; | ||||
| 				 | ||||
| 		frm.set_query("paid_from", function() { | ||||
| @ -79,23 +81,44 @@ frappe.ui.form.on('Payment Entry', { | ||||
| 	refresh: function(frm) { | ||||
| 		frm.events.hide_unhide_fields(frm); | ||||
| 		frm.events.set_dynamic_labels(frm); | ||||
| 		frm.events.show_general_ledger(frm); | ||||
| 	}, | ||||
| 	 | ||||
| 	hide_unhide_fields: function(frm) { | ||||
| 		var company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency; | ||||
| 		 | ||||
| 		frm.toggle_display(["source_exchange_rate", "base_paid_amount"],  | ||||
| 			(frm.doc.paid_from && frm.doc.paid_from_account_currency != company_currency)); | ||||
| 		 | ||||
| 		frm.toggle_display(["target_exchange_rate", "base_received_amount"],  | ||||
| 			(frm.doc.paid_to && frm.doc.paid_to_account_currency != company_currency)); | ||||
| 		 | ||||
| 		frm.toggle_display(["base_total_allocated_amount"],  | ||||
| 			((frm.doc.payment_type=="Receive" && frm.doc.paid_from_account_currency != company_currency) ||  | ||||
| 				(frm.doc.payment_type=="Pay" && frm.doc.paid_to_account_currency != company_currency))); | ||||
| 		frm.toggle_display("source_exchange_rate",  | ||||
| 			(frm.doc.paid_amount && frm.doc.paid_from_account_currency != company_currency)); | ||||
| 			 | ||||
| 		frm.toggle_display("target_exchange_rate",  | ||||
| 			(frm.doc.received_amount && frm.doc.paid_to_account_currency != company_currency)); | ||||
| 			 | ||||
| 		frm.toggle_display("base_paid_amount",  | ||||
| 			(!frm.doc.party && frm.doc.paid_from_account_currency != company_currency)); | ||||
| 			 | ||||
| 		frm.toggle_display("base_received_amount",  | ||||
| 			(!frm.doc.party && frm.doc.paid_to_account_currency != company_currency)); | ||||
| 				 | ||||
| 		frm.toggle_display(["received_amount"],  | ||||
| 		frm.toggle_display("received_amount",  | ||||
| 			frm.doc.paid_from_account_currency != frm.doc.paid_to_account_currency) | ||||
| 				 | ||||
| 		frm.toggle_display(["base_total_allocated_amount"],  | ||||
| 			(frm.doc.paid_amount && frm.doc.received_amount && frm.doc.base_total_allocated_amount && | ||||
| 			((frm.doc.payment_type=="Receive" && frm.doc.paid_from_account_currency != company_currency) ||  | ||||
| 			(frm.doc.payment_type=="Pay" && frm.doc.paid_to_account_currency != company_currency)))); | ||||
| 			 | ||||
| 		var party_amount = frm.doc.payment_type=="Receive" ?  | ||||
| 			frm.doc.paid_amount : frm.doc.received_amount; | ||||
| 					 | ||||
| 		frm.toggle_display("write_off_difference_amount", (frm.doc.difference_amount && frm.doc.party && | ||||
| 			(frm.doc.paid_from_account_currency == frm.doc.paid_to_account_currency) &&  | ||||
| 			(frm.doc.total_allocated_amount > party_amount))); | ||||
| 		 | ||||
| 		frm.toggle_display("set_exchange_gain_loss",  | ||||
| 			(frm.doc.paid_amount && frm.doc.received_amount && frm.doc.difference_amount &&  | ||||
| 				(frm.doc.paid_from_account_currency != frm.doc.paid_to_account_currency))); | ||||
| 			 | ||||
| 		frm.refresh_fields(); | ||||
| 	}, | ||||
| 	 | ||||
| 	set_dynamic_labels: function(frm) { | ||||
| @ -128,16 +151,17 @@ frappe.ui.form.on('Payment Entry', { | ||||
| 		 | ||||
| 		var party_account_currency = frm.doc.payment_type=="Receive" ?  | ||||
| 			frm.doc.paid_from_account_currency : frm.doc.paid_to_account_currency; | ||||
| 			 | ||||
| 		setup_field_label_map(["total_allocated_amount"], party_account_currency); | ||||
| 
 | ||||
| 		setup_field_label_map(["total_allocated_amount", "unallocated_amount"], party_account_currency); | ||||
| 		 | ||||
| 		$.each(field_label_map, function(fname, label) { | ||||
| 			me.frm.fields_dict[fname].set_label(label); | ||||
| 		}); | ||||
| 		 | ||||
| 		setup_field_label_map(["total_amount"], company_currency, "references"); | ||||
| 		setup_field_label_map(["outstanding_amount", "allocated_amount"],  | ||||
| 		setup_field_label_map(["total_amount", "outstanding_amount", "allocated_amount"],  | ||||
| 			party_account_currency, "references"); | ||||
| 			 | ||||
| 		setup_field_label_map(["amount"], company_currency, "deductions"); | ||||
| 		 | ||||
| 		$.each(grid_field_label_map, function(fname, label) { | ||||
| 			fname = fname.split("-"); | ||||
| @ -149,7 +173,24 @@ frappe.ui.form.on('Payment Entry', { | ||||
| 			("1 " + frm.doc.paid_from_account_currency + " = [?] " + company_currency)); | ||||
| 		 | ||||
| 		cur_frm.set_df_property("target_exchange_rate", "description",  | ||||
| 			("1 " + frm.doc.paid_to_account_currency + " = [?] " + company_currency));		 | ||||
| 			("1 " + frm.doc.paid_to_account_currency + " = [?] " + company_currency)); | ||||
| 			 | ||||
| 		frm.refresh_fields(); | ||||
| 	}, | ||||
| 	 | ||||
| 	show_general_ledger: function(frm) { | ||||
| 		if(frm.doc.docstatus==1) { | ||||
| 			frm.add_custom_button(__('Ledger'), function() { | ||||
| 				frappe.route_options = { | ||||
| 					"voucher_no": frm.doc.name, | ||||
| 					"from_date": frm.doc.posting_date, | ||||
| 					"to_date": frm.doc.posting_date, | ||||
| 					"company": frm.doc.company, | ||||
| 					group_by_voucher: 0 | ||||
| 				}; | ||||
| 				frappe.set_route("query-report", "General Ledger"); | ||||
| 			}, "icon-table"); | ||||
| 		} | ||||
| 	}, | ||||
| 		 | ||||
| 	"party": function(frm) { | ||||
| @ -190,7 +231,7 @@ frappe.ui.form.on('Payment Entry', { | ||||
| 		if(frm.doc.payment_type == "Internal Transfer") { | ||||
| 			$.each(["party", "party_balance", "paid_from", "paid_to",  | ||||
| 				"references", "total_allocated_amount"], function(i, field) { | ||||
| 					frm.set_value(field, ""); | ||||
| 					frm.set_value(field, null); | ||||
| 			}) | ||||
| 		} else { | ||||
| 			frm.events.party(frm); | ||||
| @ -256,6 +297,7 @@ frappe.ui.form.on('Payment Entry', { | ||||
| 	}, | ||||
| 	 | ||||
| 	paid_from_account_currency: function(frm) { | ||||
| 		if(!frm.doc.paid_from_account_currency) return; | ||||
| 		var company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency; | ||||
| 		 | ||||
| 		if (frm.doc.paid_from_account_currency == company_currency) { | ||||
| @ -279,6 +321,7 @@ frappe.ui.form.on('Payment Entry', { | ||||
| 	}, | ||||
| 	 | ||||
| 	paid_to_account_currency: function(frm) { | ||||
| 		if(!frm.doc.paid_to_account_currency) return; | ||||
| 		var company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency; | ||||
| 		 | ||||
| 		frm.events.set_current_exchange_rate(frm, "target_exchange_rate",  | ||||
| @ -319,14 +362,20 @@ frappe.ui.form.on('Payment Entry', { | ||||
| 			frm.set_value("target_exchange_rate", frm.doc.source_exchange_rate); | ||||
| 			frm.set_value("base_received_amount", frm.doc.base_paid_amount); | ||||
| 		} | ||||
| 		 | ||||
| 		frm.events.set_difference_amount(frm); | ||||
| 		if(frm.doc.payment_type == "Receive") | ||||
| 			frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.paid_amount); | ||||
| 		else | ||||
| 			frm.events.set_difference_amount(frm); | ||||
| 	}, | ||||
| 	 | ||||
| 	received_amount: function(frm) { | ||||
| 		frm.set_value("base_received_amount",  | ||||
| 			flt(frm.doc.received_amount) * flt(frm.doc.target_exchange_rate)); | ||||
| 		frm.events.set_difference_amount(frm); | ||||
| 			 | ||||
| 		if(frm.doc.payment_type == "Pay") | ||||
| 			frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.received_amount); | ||||
| 		else | ||||
| 			frm.events.set_difference_amount(frm); | ||||
| 	}, | ||||
| 	 | ||||
| 	get_outstanding_documents: function(frm) { | ||||
| @ -354,24 +403,40 @@ frappe.ui.form.on('Payment Entry', { | ||||
| 						c.reference_name = d.voucher_no; | ||||
| 						c.total_amount = d.invoice_amount; | ||||
| 						c.outstanding_amount = d.outstanding_amount; | ||||
| 						 | ||||
| 						var party_account_currency = frm.doc.payment_type=="Receive" ?  | ||||
| 							frm.doc.paid_from_account_currency : frm.doc.paid_to_account_currency; | ||||
| 
 | ||||
| 						if(frm.doc.party_account_currency != company_currency) { | ||||
| 						if(party_account_currency != company_currency) { | ||||
| 							c.exchange_rate = d.exchange_rate; | ||||
| 						} else { | ||||
| 							c.exchange_rate = 1; | ||||
| 						} | ||||
| 						 | ||||
| 						if (in_list(['Sales Invoice', 'Purchase Invoice'], d.reference_doctype)){ | ||||
| 							c.due_date = d.due_date | ||||
| 						} | ||||
| 					}); | ||||
| 				} | ||||
| 				frm.events.set_total_allocated_amount(frm); | ||||
| 				frm.refresh_fields() | ||||
| 				 | ||||
| 				frm.events.allocate_party_amount_against_ref_docs(frm,  | ||||
| 					(frm.doc.payment_type=="Receive" ? frm.doc.paid_amount : frm.doc.received_amount)); | ||||
| 			} | ||||
| 		}); | ||||
| 	}, | ||||
| 	 | ||||
| 	allocate_party_amount_against_ref_docs: function(frm, amount) { | ||||
| 		$.each(frm.doc.references || [], function(i, row) { | ||||
| 			if (!amount) return false; | ||||
| 			 | ||||
| 			if(row.outstanding_amount >= amount) row.allocated_amount = amount; | ||||
| 			else row.allocated_amount = row.outstanding_amount; | ||||
| 			 | ||||
| 			amount -= flt(row.allocated_amount); | ||||
| 		}) | ||||
| 		frm.refresh_fields() | ||||
| 		frm.events.set_total_allocated_amount(frm); | ||||
| 	}, | ||||
| 	 | ||||
| 	set_total_allocated_amount: function(frm) { | ||||
| 		var total_allocated_amount = base_total_allocated_amount = 0.0; | ||||
| 		$.each(frm.doc.references || [], function(i, row) { | ||||
| @ -399,12 +464,15 @@ frappe.ui.form.on('Payment Entry', { | ||||
| 	 | ||||
| 	set_difference_amount: function(frm) { | ||||
| 		var unallocated_amount = 0; | ||||
| 		var party_amount = frm.doc.payment_type=="Receive" ? frm.doc.paid_amount : frm.doc.received_amount; | ||||
| 		if(frm.doc.party) { | ||||
| 			var party_amount = frm.doc.payment_type=="Receive" ?  | ||||
| 				frm.doc.paid_amount : frm.doc.received_amount; | ||||
| 		 | ||||
| 		if(frm.doc.total_allocated_amount < party_amount) | ||||
| 			unallocated_amount = party_amount - frm.doc.total_allocated_amount; | ||||
| 			if(frm.doc.total_allocated_amount < party_amount) | ||||
| 				unallocated_amount = party_amount - frm.doc.total_allocated_amount; | ||||
| 		}	 | ||||
| 		 | ||||
| 		frm.set_value("unallocated_amount", unallocated_amount) | ||||
| 		frm.set_value("unallocated_amount", unallocated_amount); | ||||
| 		 | ||||
| 		var difference_amount = 0; | ||||
| 		var base_unallocated_amount = flt(frm.doc.unallocated_amount) *	 | ||||
| @ -426,8 +494,7 @@ frappe.ui.form.on('Payment Entry', { | ||||
| 		 | ||||
| 		frm.set_value("difference_amount", difference_amount); | ||||
| 		 | ||||
| 		frm.toggle_display("write_off_difference_amount",  | ||||
| 			(frm.doc.difference_amount && frm.doc.total_allocated_amount > party_amount)); | ||||
| 		frm.events.hide_unhide_fields(frm); | ||||
| 	}, | ||||
| 	 | ||||
| 	check_mandatory_to_fetch: function(frm) { | ||||
| @ -455,7 +522,6 @@ frappe.ui.form.on('Payment Entry', { | ||||
| 					frappe.msgprint(__("Row #{0}: Reference Document Type must be one of Purchase Order, Purchase Invoice or Journal Entry", [row.idx])); | ||||
| 					return false; | ||||
| 				} | ||||
| 
 | ||||
| 		} | ||||
| 
 | ||||
| 		if (row) { | ||||
| @ -466,20 +532,28 @@ frappe.ui.form.on('Payment Entry', { | ||||
| 	}, | ||||
| 	 | ||||
| 	write_off_difference_amount: function(frm) { | ||||
| 		frm.events.set_deductions_entry(frm, "write_off_account");	 | ||||
| 	}, | ||||
| 
 | ||||
| 	set_exchange_gain_loss: function(frm) { | ||||
| 		frm.events.set_deductions_entry(frm, "exchange_gain_loss_account"); | ||||
| 	}, | ||||
| 	 | ||||
| 	set_deductions_entry: function(frm, account) { | ||||
| 		if(frm.doc.difference_amount) { | ||||
| 			frappe.call({ | ||||
| 				method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_write_off_account_and_cost_center", | ||||
| 				method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_company_defaults", | ||||
| 				args: { | ||||
| 					company: frm.doc.company | ||||
| 				}, | ||||
| 				callback: function(r, rt) { | ||||
| 					if(r.message) { | ||||
| 						var write_off_row = $.map(frm.doc["deductions"] || [], function(t) {  | ||||
| 							return t.account==r.message["write_off_account"] ? t : null; }); | ||||
| 							return t.account==r.message[account] ? t : null; }); | ||||
| 						 | ||||
| 						if (!write_off_row.length) { | ||||
| 							var row = frm.add_child("deductions"); | ||||
| 							row.account = r.message["write_off_account"]; | ||||
| 							row.account = r.message[account]; | ||||
| 							row.cost_center = r.message["cost_center"]; | ||||
| 						} else { | ||||
| 							var row = write_off_row[0]; | ||||
|  | ||||
| @ -353,7 +353,7 @@ | ||||
|    "depends_on": "paid_from",  | ||||
|    "fieldname": "paid_from_account_currency",  | ||||
|    "fieldtype": "Link",  | ||||
|    "hidden": 1,  | ||||
|    "hidden": 0,  | ||||
|    "ignore_user_permissions": 0,  | ||||
|    "ignore_xss_filter": 0,  | ||||
|    "in_filter": 0,  | ||||
| @ -368,7 +368,7 @@ | ||||
|    "print_hide_if_no_value": 0,  | ||||
|    "read_only": 1,  | ||||
|    "report_hide": 0,  | ||||
|    "reqd": 0,  | ||||
|    "reqd": 1,  | ||||
|    "search_index": 0,  | ||||
|    "set_only_once": 0,  | ||||
|    "unique": 0 | ||||
| @ -473,7 +473,7 @@ | ||||
|    "print_hide_if_no_value": 0,  | ||||
|    "read_only": 1,  | ||||
|    "report_hide": 0,  | ||||
|    "reqd": 0,  | ||||
|    "reqd": 1,  | ||||
|    "search_index": 0,  | ||||
|    "set_only_once": 0,  | ||||
|    "unique": 0 | ||||
| @ -547,6 +547,7 @@ | ||||
|    "label": "Paid Amount",  | ||||
|    "length": 0,  | ||||
|    "no_copy": 0,  | ||||
|    "options": "paid_from_account_currency",  | ||||
|    "permlevel": 0,  | ||||
|    "precision": "",  | ||||
|    "print_hide": 0,  | ||||
| @ -579,7 +580,7 @@ | ||||
|    "print_hide_if_no_value": 0,  | ||||
|    "read_only": 0,  | ||||
|    "report_hide": 0,  | ||||
|    "reqd": 0,  | ||||
|    "reqd": 1,  | ||||
|    "search_index": 0,  | ||||
|    "set_only_once": 0,  | ||||
|    "unique": 0 | ||||
| @ -599,13 +600,14 @@ | ||||
|    "label": "Paid Amount (Company Currency)",  | ||||
|    "length": 0,  | ||||
|    "no_copy": 0,  | ||||
|    "options": "Company:company:default_currency",  | ||||
|    "permlevel": 0,  | ||||
|    "precision": "",  | ||||
|    "print_hide": 0,  | ||||
|    "print_hide_if_no_value": 0,  | ||||
|    "read_only": 1,  | ||||
|    "report_hide": 0,  | ||||
|    "reqd": 0,  | ||||
|    "reqd": 1,  | ||||
|    "search_index": 0,  | ||||
|    "set_only_once": 0,  | ||||
|    "unique": 0 | ||||
| @ -649,6 +651,7 @@ | ||||
|    "label": "Received Amount",  | ||||
|    "length": 0,  | ||||
|    "no_copy": 0,  | ||||
|    "options": "paid_to_account_currency",  | ||||
|    "permlevel": 0,  | ||||
|    "precision": "",  | ||||
|    "print_hide": 0,  | ||||
| @ -681,7 +684,7 @@ | ||||
|    "print_hide_if_no_value": 0,  | ||||
|    "read_only": 0,  | ||||
|    "report_hide": 0,  | ||||
|    "reqd": 0,  | ||||
|    "reqd": 1,  | ||||
|    "search_index": 0,  | ||||
|    "set_only_once": 0,  | ||||
|    "unique": 0 | ||||
| @ -701,13 +704,14 @@ | ||||
|    "label": "Received Amount (Company Currency)",  | ||||
|    "length": 0,  | ||||
|    "no_copy": 0,  | ||||
|    "options": "Company:company:default_currency",  | ||||
|    "permlevel": 0,  | ||||
|    "precision": "",  | ||||
|    "print_hide": 0,  | ||||
|    "print_hide_if_no_value": 0,  | ||||
|    "read_only": 1,  | ||||
|    "report_hide": 0,  | ||||
|    "reqd": 0,  | ||||
|    "reqd": 1,  | ||||
|    "search_index": 0,  | ||||
|    "set_only_once": 0,  | ||||
|    "unique": 0 | ||||
| @ -758,7 +762,7 @@ | ||||
|    "print_hide_if_no_value": 0,  | ||||
|    "read_only": 0,  | ||||
|    "report_hide": 0,  | ||||
|    "reqd": 0,  | ||||
|    "reqd": 1,  | ||||
|    "search_index": 0,  | ||||
|    "set_only_once": 0,  | ||||
|    "unique": 0 | ||||
| @ -808,6 +812,32 @@ | ||||
|    "print_hide_if_no_value": 0,  | ||||
|    "read_only": 0,  | ||||
|    "report_hide": 0,  | ||||
|    "reqd": 1,  | ||||
|    "search_index": 0,  | ||||
|    "set_only_once": 0,  | ||||
|    "unique": 0 | ||||
|   },  | ||||
|   { | ||||
|    "allow_on_submit": 0,  | ||||
|    "bold": 0,  | ||||
|    "collapsible": 0,  | ||||
|    "depends_on": "eval:doc.docstatus==1",  | ||||
|    "fieldname": "clearance_date",  | ||||
|    "fieldtype": "Date",  | ||||
|    "hidden": 0,  | ||||
|    "ignore_user_permissions": 0,  | ||||
|    "ignore_xss_filter": 0,  | ||||
|    "in_filter": 0,  | ||||
|    "in_list_view": 0,  | ||||
|    "label": "Clearance Date",  | ||||
|    "length": 0,  | ||||
|    "no_copy": 0,  | ||||
|    "permlevel": 0,  | ||||
|    "precision": "",  | ||||
|    "print_hide": 0,  | ||||
|    "print_hide_if_no_value": 0,  | ||||
|    "read_only": 1,  | ||||
|    "report_hide": 0,  | ||||
|    "reqd": 0,  | ||||
|    "search_index": 0,  | ||||
|    "set_only_once": 0,  | ||||
| @ -896,7 +926,7 @@ | ||||
|    "allow_on_submit": 0,  | ||||
|    "bold": 1,  | ||||
|    "collapsible": 0,  | ||||
|    "depends_on": "",  | ||||
|    "depends_on": "eval:(doc.paid_amount && doc.received_amount && doc.references)",  | ||||
|    "fieldname": "total_allocated_amount",  | ||||
|    "fieldtype": "Currency",  | ||||
|    "hidden": 0,  | ||||
| @ -933,32 +963,7 @@ | ||||
|    "label": "Total Allocated Amount (Company Currency)",  | ||||
|    "length": 0,  | ||||
|    "no_copy": 0,  | ||||
|    "permlevel": 0,  | ||||
|    "precision": "",  | ||||
|    "print_hide": 0,  | ||||
|    "print_hide_if_no_value": 0,  | ||||
|    "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,  | ||||
|    "depends_on": "",  | ||||
|    "fieldname": "difference_amount",  | ||||
|    "fieldtype": "Currency",  | ||||
|    "hidden": 0,  | ||||
|    "ignore_user_permissions": 0,  | ||||
|    "ignore_xss_filter": 0,  | ||||
|    "in_filter": 0,  | ||||
|    "in_list_view": 0,  | ||||
|    "label": "Difference Amount (Company Currency)",  | ||||
|    "length": 0,  | ||||
|    "no_copy": 0,  | ||||
|    "options": "Company:company:default_currency",  | ||||
|    "permlevel": 0,  | ||||
|    "precision": "",  | ||||
|    "print_hide": 0,  | ||||
| @ -996,6 +1001,31 @@ | ||||
|    "set_only_once": 0,  | ||||
|    "unique": 0 | ||||
|   },  | ||||
|   { | ||||
|    "allow_on_submit": 0,  | ||||
|    "bold": 0,  | ||||
|    "collapsible": 0,  | ||||
|    "fieldname": "set_exchange_gain_loss",  | ||||
|    "fieldtype": "Button",  | ||||
|    "hidden": 0,  | ||||
|    "ignore_user_permissions": 0,  | ||||
|    "ignore_xss_filter": 0,  | ||||
|    "in_filter": 0,  | ||||
|    "in_list_view": 0,  | ||||
|    "label": "Set Exchange Gain / Loss",  | ||||
|    "length": 0,  | ||||
|    "no_copy": 0,  | ||||
|    "permlevel": 0,  | ||||
|    "precision": "",  | ||||
|    "print_hide": 0,  | ||||
|    "print_hide_if_no_value": 0,  | ||||
|    "read_only": 0,  | ||||
|    "report_hide": 0,  | ||||
|    "reqd": 0,  | ||||
|    "search_index": 0,  | ||||
|    "set_only_once": 0,  | ||||
|    "unique": 0 | ||||
|   },  | ||||
|   { | ||||
|    "allow_on_submit": 0,  | ||||
|    "bold": 0,  | ||||
| @ -1024,7 +1054,7 @@ | ||||
|    "allow_on_submit": 0,  | ||||
|    "bold": 0,  | ||||
|    "collapsible": 0,  | ||||
|    "depends_on": "",  | ||||
|    "depends_on": "eval:(doc.paid_amount && doc.received_amount && doc.references)",  | ||||
|    "fieldname": "unallocated_amount",  | ||||
|    "fieldtype": "Currency",  | ||||
|    "hidden": 0,  | ||||
| @ -1046,6 +1076,33 @@ | ||||
|    "set_only_once": 0,  | ||||
|    "unique": 0 | ||||
|   },  | ||||
|   { | ||||
|    "allow_on_submit": 0,  | ||||
|    "bold": 1,  | ||||
|    "collapsible": 0,  | ||||
|    "depends_on": "eval:(doc.paid_amount && doc.received_amount)",  | ||||
|    "fieldname": "difference_amount",  | ||||
|    "fieldtype": "Currency",  | ||||
|    "hidden": 0,  | ||||
|    "ignore_user_permissions": 0,  | ||||
|    "ignore_xss_filter": 0,  | ||||
|    "in_filter": 0,  | ||||
|    "in_list_view": 0,  | ||||
|    "label": "Difference Amount (Company Currency)",  | ||||
|    "length": 0,  | ||||
|    "no_copy": 0,  | ||||
|    "options": "Company:company:default_currency",  | ||||
|    "permlevel": 0,  | ||||
|    "precision": "",  | ||||
|    "print_hide": 0,  | ||||
|    "print_hide_if_no_value": 0,  | ||||
|    "read_only": 1,  | ||||
|    "report_hide": 0,  | ||||
|    "reqd": 0,  | ||||
|    "search_index": 0,  | ||||
|    "set_only_once": 0,  | ||||
|    "unique": 0 | ||||
|   },  | ||||
|   { | ||||
|    "allow_on_submit": 0,  | ||||
|    "bold": 0,  | ||||
| @ -1099,134 +1156,6 @@ | ||||
|    "set_only_once": 0,  | ||||
|    "unique": 0 | ||||
|   },  | ||||
|   { | ||||
|    "allow_on_submit": 0,  | ||||
|    "bold": 0,  | ||||
|    "collapsible": 1,  | ||||
|    "collapsible_depends_on": "write_off_amount",  | ||||
|    "depends_on": "difference_amount",  | ||||
|    "fieldname": "write_off_section",  | ||||
|    "fieldtype": "Section Break",  | ||||
|    "hidden": 1,  | ||||
|    "ignore_user_permissions": 0,  | ||||
|    "ignore_xss_filter": 0,  | ||||
|    "in_filter": 0,  | ||||
|    "in_list_view": 0,  | ||||
|    "label": "Write Off",  | ||||
|    "length": 0,  | ||||
|    "no_copy": 0,  | ||||
|    "permlevel": 0,  | ||||
|    "precision": "",  | ||||
|    "print_hide": 0,  | ||||
|    "print_hide_if_no_value": 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": "write_off_account",  | ||||
|    "fieldtype": "Link",  | ||||
|    "hidden": 0,  | ||||
|    "ignore_user_permissions": 0,  | ||||
|    "ignore_xss_filter": 0,  | ||||
|    "in_filter": 0,  | ||||
|    "in_list_view": 0,  | ||||
|    "label": "Write Off Account",  | ||||
|    "length": 0,  | ||||
|    "no_copy": 0,  | ||||
|    "options": "Account",  | ||||
|    "permlevel": 0,  | ||||
|    "precision": "",  | ||||
|    "print_hide": 0,  | ||||
|    "print_hide_if_no_value": 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": "write_off_amount",  | ||||
|    "fieldtype": "Currency",  | ||||
|    "hidden": 0,  | ||||
|    "ignore_user_permissions": 0,  | ||||
|    "ignore_xss_filter": 0,  | ||||
|    "in_filter": 0,  | ||||
|    "in_list_view": 0,  | ||||
|    "label": "Write Off Amount",  | ||||
|    "length": 0,  | ||||
|    "no_copy": 0,  | ||||
|    "permlevel": 0,  | ||||
|    "precision": "",  | ||||
|    "print_hide": 0,  | ||||
|    "print_hide_if_no_value": 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": "column_break_39",  | ||||
|    "fieldtype": "Column Break",  | ||||
|    "hidden": 0,  | ||||
|    "ignore_user_permissions": 0,  | ||||
|    "ignore_xss_filter": 0,  | ||||
|    "in_filter": 0,  | ||||
|    "in_list_view": 0,  | ||||
|    "length": 0,  | ||||
|    "no_copy": 0,  | ||||
|    "permlevel": 0,  | ||||
|    "precision": "",  | ||||
|    "print_hide": 0,  | ||||
|    "print_hide_if_no_value": 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": "write_off_cost_center",  | ||||
|    "fieldtype": "Link",  | ||||
|    "hidden": 0,  | ||||
|    "ignore_user_permissions": 0,  | ||||
|    "ignore_xss_filter": 0,  | ||||
|    "in_filter": 0,  | ||||
|    "in_list_view": 0,  | ||||
|    "label": "Write Off Cost Center",  | ||||
|    "length": 0,  | ||||
|    "no_copy": 0,  | ||||
|    "options": "Cost Center",  | ||||
|    "permlevel": 0,  | ||||
|    "precision": "",  | ||||
|    "print_hide": 0,  | ||||
|    "print_hide_if_no_value": 0,  | ||||
|    "read_only": 0,  | ||||
|    "report_hide": 0,  | ||||
|    "reqd": 0,  | ||||
|    "search_index": 0,  | ||||
|    "set_only_once": 0,  | ||||
|    "unique": 0 | ||||
|   },  | ||||
|   { | ||||
|    "allow_on_submit": 0,  | ||||
|    "bold": 0,  | ||||
| @ -1406,6 +1335,31 @@ | ||||
|    "search_index": 0,  | ||||
|    "set_only_once": 0,  | ||||
|    "unique": 0 | ||||
|   },  | ||||
|   { | ||||
|    "allow_on_submit": 0,  | ||||
|    "bold": 0,  | ||||
|    "collapsible": 0,  | ||||
|    "fieldname": "title",  | ||||
|    "fieldtype": "Data",  | ||||
|    "hidden": 1,  | ||||
|    "ignore_user_permissions": 0,  | ||||
|    "ignore_xss_filter": 0,  | ||||
|    "in_filter": 0,  | ||||
|    "in_list_view": 0,  | ||||
|    "label": "Title",  | ||||
|    "length": 0,  | ||||
|    "no_copy": 0,  | ||||
|    "permlevel": 0,  | ||||
|    "precision": "",  | ||||
|    "print_hide": 0,  | ||||
|    "print_hide_if_no_value": 0,  | ||||
|    "read_only": 0,  | ||||
|    "report_hide": 0,  | ||||
|    "reqd": 0,  | ||||
|    "search_index": 0,  | ||||
|    "set_only_once": 0,  | ||||
|    "unique": 0 | ||||
|   } | ||||
|  ],  | ||||
|  "hide_heading": 0,  | ||||
| @ -1418,7 +1372,7 @@ | ||||
|  "issingle": 0,  | ||||
|  "istable": 0,  | ||||
|  "max_attachments": 0,  | ||||
|  "modified": "2016-06-26 01:00:56.344341",  | ||||
|  "modified": "2016-06-26 17:36:58.416685",  | ||||
|  "modified_by": "Administrator",  | ||||
|  "module": "Accounts",  | ||||
|  "name": "Payment Entry",  | ||||
| @ -1471,5 +1425,6 @@ | ||||
|  "read_only_onload": 0,  | ||||
|  "sort_field": "modified",  | ||||
|  "sort_order": "DESC",  | ||||
|  "title_field": "title",  | ||||
|  "track_seen": 0 | ||||
| } | ||||
| @ -5,7 +5,7 @@ | ||||
| from __future__ import unicode_literals | ||||
| import frappe, json | ||||
| from frappe import _, scrub | ||||
| from frappe.utils import flt | ||||
| from frappe.utils import flt, comma_or | ||||
| from erpnext.accounts.utils import get_outstanding_invoices, get_account_currency, get_balance_on | ||||
| from erpnext.accounts.party import get_party_account | ||||
| from erpnext.accounts.doctype.journal_entry.journal_entry import get_average_exchange_rate | ||||
| @ -17,13 +17,18 @@ from erpnext.controllers.accounts_controller import AccountsController | ||||
| 
 | ||||
| class PaymentEntry(AccountsController): | ||||
| 	def validate(self): | ||||
| 		self.define_party_account_field() | ||||
| 		self.set_missing_values() | ||||
| 		self.validate_party_details() | ||||
| 		self.validate_allocated_amounts() | ||||
| 		self.validate_bank_accounts() | ||||
| 		self.set_exchange_rate() | ||||
| 		self.set_amounts() | ||||
| 		self.validate_mandatory() | ||||
| 		self.set_write_off_amount() | ||||
| 		self.set_amounts_in_company_currency() | ||||
| 		self.validate_reference_documents() | ||||
| 		self.set_total_allocated_amount() | ||||
| 		self.set_unallocated_amount() | ||||
| 		self.set_difference_amount() | ||||
| 		self.clear_unallocated_reference_document_rows() | ||||
| 		self.set_title() | ||||
| 		 | ||||
| 	def on_submit(self): | ||||
| 		self.make_gl_entries() | ||||
| @ -32,32 +37,45 @@ class PaymentEntry(AccountsController): | ||||
| 	def on_cancel(self): | ||||
| 		self.make_gl_entries() | ||||
| 		self.update_advance_paid() | ||||
| 				 | ||||
| 	def set_missing_values(self): | ||||
| 		 | ||||
| 	def define_party_account_field(self): | ||||
| 		self.party_account_field = None | ||||
| 		 | ||||
| 		if self.payment_type == "Receive": | ||||
| 			self.paid_from = self.paid_from_account_currency = self.paid_from_account_balance = None | ||||
| 			self.party_account_field = "paid_from" | ||||
| 		elif self.payment_type == "Pay": | ||||
| 			self.paid_to = self.paid_to_account_currency = self.paid_to_account_balance = None | ||||
| 		elif self.payment_type == "Internal Transfer": | ||||
| 			self.party = self.party_account = self.party_account_currency = self.party_balance = None | ||||
| 			self.party_account_field = "paid_to" | ||||
| 					 | ||||
| 	def set_missing_values(self): | ||||
| 		if self.payment_type == "Internal Transfer": | ||||
| 			for field in ("party", "party_balance", "total_allocated_amount",  | ||||
| 				"base_total_allocated_amount", "unallocated_amount"): | ||||
| 					self.set(field, None) | ||||
| 			self.references = [] | ||||
| 		else: | ||||
| 			if not self.party_type: | ||||
| 				frappe.throw(_("Party Type is mandatory")) | ||||
| 				 | ||||
| 			if not self.party: | ||||
| 				frappe.throw(_("Party is mandatory")) | ||||
| 		 | ||||
| 		if self.party: | ||||
| 			if self.party_account:				 | ||||
| 				if not self.party_account_currency: | ||||
| 					self.party_account_currency = get_account_currency(self.party_account) | ||||
| 			if not self.party_balance: | ||||
| 				self.party_balance = get_balance_on(party_type=self.party_type, | ||||
| 					party=self.party, date=self.posting_date) | ||||
| 			 | ||||
| 			if not self.get(self.party_account_field): | ||||
| 				party_account = get_party_account(self.party_type, self.party, self.company) | ||||
| 				self.set(self.party_account_field, party_account) | ||||
| 				 | ||||
| 				if not self.party_balance: | ||||
| 					self.party_balance = get_balance_on(party_type=self.party_type, | ||||
| 						party=self.party, date=self.posting_date) | ||||
| 			else: | ||||
| 				self.party_account = get_party_account(self.party_type, self.party, self.company) | ||||
| 			self.party_account = self.get(self.party_account_field) | ||||
| 				 | ||||
| 		if self.paid_from: | ||||
| 		if self.paid_from and not (self.paid_from_account_currency or self.paid_from_account_balance): | ||||
| 			acc = get_account_currency_and_balance(self.paid_from, self.posting_date) | ||||
| 			self.paid_from_account_currency = acc.account_currency | ||||
| 			self.paid_from_account_balance = acc.account_balance | ||||
| 				 | ||||
| 		if self.paid_to: | ||||
| 		if self.paid_to and not (self.paid_to_account_currency or self.paid_to_account_balance): | ||||
| 			acc = get_account_currency_and_balance(self.paid_to, self.posting_date) | ||||
| 			self.paid_to_account_currency = acc.account_currency | ||||
| 			self.paid_to_account_balance = acc.account_balance | ||||
| @ -66,178 +84,233 @@ class PaymentEntry(AccountsController): | ||||
| 		if self.party: | ||||
| 			if not frappe.db.exists(self.party_type, self.party): | ||||
| 				frappe.throw(_("Invalid {0}: {1}").format(self.party_type, self.party)) | ||||
| 				 | ||||
| 			 | ||||
| 			if self.party_account: | ||||
| 				account_type = frappe.db.get_value("Account", self.party_account, "account_type") | ||||
| 				 | ||||
| 				if self.party_type == "Customer" and account_type != "Receivable": | ||||
| 					frappe.throw(_("Account Type must be Receivable for {0}").format(self.party_account)) | ||||
| 				party_account_type = "Receivable" if self.party_type=="Customer" else "Payable" | ||||
| 				self.validate_account_type(self.party_account, [party_account_type]) | ||||
| 					 | ||||
| 				if self.party_type == "Supplier" and account_type != "Payable": | ||||
| 					frappe.throw(_("Account Type must be Payable for {0}").format(self.party_account)) | ||||
| 	def validate_bank_accounts(self): | ||||
| 		if self.payment_type in ("Pay", "Internal Transfer"): | ||||
| 			self.validate_account_type(self.paid_from, ["Bank", "Cash"]) | ||||
| 			 | ||||
| 		if self.payment_type in ("Receive", "Internal Transfer"): | ||||
| 			self.validate_account_type(self.paid_to, ["Bank", "Cash"]) | ||||
| 			 | ||||
| 	def validate_account_type(self, account, account_types): | ||||
| 		account_type = frappe.db.get_value("Account", account, "account_type") | ||||
| 		if account_type not in account_types: | ||||
| 			frappe.throw(_("Account Type for {0} must be {1}").format(comma_or(account_types))) | ||||
| 				 | ||||
| 	def validate_allocated_amounts(self): | ||||
| 	def set_exchange_rate(self): | ||||
| 		if self.paid_from: | ||||
| 			if self.paid_from_account_currency == self.company_currency: | ||||
| 				self.source_exchange_rate = 1 | ||||
| 			elif self.payment_type in ("Pay", "Internal Transfer"): | ||||
| 				self.source_exchange_rate = get_average_exchange_rate(self.paid_from) | ||||
| 			else: | ||||
| 				self.source_exchange_rate = get_exchange_rate(self.paid_from_account_currency,  | ||||
| 					self.company_currency) | ||||
| 		 | ||||
| 		if self.paid_to: | ||||
| 			self.target_exchange_rate = get_exchange_rate(self.paid_to_account_currency,  | ||||
| 				self.company_currency) | ||||
| 		 | ||||
| 	def set_amounts_in_company_currency(self): | ||||
| 		self.base_paid_amount, self.base_received_amount, self.difference_amount = 0, 0, 0 | ||||
| 		if self.paid_amount: | ||||
| 			self.base_paid_amount = flt(flt(self.paid_amount) * flt(self.source_exchange_rate),  | ||||
| 				self.precision("base_paid_amount")) | ||||
| 				 | ||||
| 		if self.received_amount: | ||||
| 			self.base_received_amount = flt(flt(self.received_amount) * flt(self.target_exchange_rate),  | ||||
| 				self.precision("base_received_amount")) | ||||
| 				 | ||||
| 	def validate_reference_documents(self): | ||||
| 		if self.party_type == "Customer": | ||||
| 			valid_reference_doctypes = ("Sales Order", "Sales Invoice", "Journal Entry") | ||||
| 		else: | ||||
| 			valid_reference_doctypes = ("Purchase Order", "Purchase Invoice", "Journal Entry") | ||||
| 			 | ||||
| 		for d in self.get("references"): | ||||
| 			if d.reference_doctype not in valid_reference_doctypes: | ||||
| 				frappe.throw(_("Reference Doctype must be one of {0}") | ||||
| 					.format(comma_or(valid_reference_doctypes))) | ||||
| 				 | ||||
| 			elif d.reference_name: | ||||
| 				if not frappe.db.exists(d.reference_doctype, d.reference_name): | ||||
| 					frappe.throw(_("{0} {1} does not exist").format(d.reference_doctype, d.reference_name)) | ||||
| 				else: | ||||
| 					ref_doc = frappe.get_doc(d.reference_doctype, d.reference_name) | ||||
| 
 | ||||
| 					if d.reference_doctype != "Journal Entry" \ | ||||
| 							and self.party != ref_doc.get(scrub(self.party_type)): | ||||
| 						frappe.throw(_("{0} {1} does not associated with {2} {3}") | ||||
| 							.format(d.reference_doctype, d.reference_name, self.party_type, self.party)) | ||||
| 					 | ||||
| 					if ref_doc.docstatus != 1: | ||||
| 						frappe.throw(_("{0} {1} must be submitted") | ||||
| 							.format(d.reference_doctype, d.reference_name)) | ||||
| 				 | ||||
| 	def set_total_allocated_amount(self): | ||||
| 		if self.payment_type == "Internal Transfer": | ||||
| 			self.references = [] | ||||
| 			self.total_allocated_amount = 0 | ||||
| 			return | ||||
| 			 | ||||
| 		self.total_allocated_amount, self.base_total_allocated_amount = 0, 0 | ||||
| 		for d in self.get("references"): | ||||
| 			if d.allocated_amount: | ||||
| 				if d.allocated_amount > d.outstanding_amount: | ||||
| 					frappe.throw(_("Row #{0}: Allocated amount cannot be greater than outstanding amount") | ||||
| 						.format(d.idx)) | ||||
| 				 | ||||
| 				self.total_allocated_amount += flt(d.allocated_amount) | ||||
| 				self.base_total_allocated_amount += flt(flt(d.allocated_amount) * flt(d.exchange_rate),  | ||||
| 					self.precision("base_paid_amount")) | ||||
| 
 | ||||
| 		party_amount_field = "received_amount" if self.payment_type == "Pay" else "paid_amount" | ||||
| 	 | ||||
| 	def set_unallocated_amount(self): | ||||
| 		self.unallocated_amount = 0; | ||||
| 		if self.party: | ||||
| 			party_amount = self.paid_amount if self.payment_type=="Receive" else self.received_amount | ||||
| 			 | ||||
| 		if self.total_allocated_amount != self.get(party_amount_field): | ||||
| 			frappe.throw(_("Total Allocated Amount must be equal to {0} ({1})") | ||||
| 				.format(self.get(party_amount_field), self.meta.get_label(party_amount_field))) | ||||
| 			if self.total_allocated_amount < party_amount: | ||||
| 				self.unallocated_amount = party_amount - self.total_allocated_amount | ||||
| 				 | ||||
| 	def set_exchange_rate(self): | ||||
| 		if self.paid_from: | ||||
| 			if self.paid_from_account_currency != self.company_currency: | ||||
| 				self.source_exchange_rate = get_average_exchange_rate(self.paid_from) | ||||
| 			else: | ||||
| 				self.source_exchange_rate = 1 | ||||
| 				 | ||||
| 		if self.paid_to: | ||||
| 			self.target_exchange_rate = get_exchange_rate(self.paid_to_account_currency,  | ||||
| 				self.company_currency) | ||||
| 	def set_difference_amount(self): | ||||
| 		base_unallocated_amount = self.unallocated_amount * \ | ||||
| 			(self.source_exchange_rate if self.payment_type=="Receive" else self.target_exchange_rate) | ||||
| 			 | ||||
| 		base_party_amount = self.base_total_allocated_amount + base_unallocated_amount | ||||
| 		 | ||||
| 	def set_amounts(self): | ||||
| 		self.base_paid_amount, self.base_received_amount, self.difference_amount = 0, 0, 0 | ||||
| 		if self.paid_amount: | ||||
| 			if self.paid_from: | ||||
| 				self.base_paid_amount = flt(flt(self.paid_amount) * flt(self.source_exchange_rate),  | ||||
| 					self.precision("base_paid_amount")) | ||||
| 			else: | ||||
| 				self.base_paid_amount = self.base_total_allocated_amount | ||||
| 				 | ||||
| 		if self.received_amount: | ||||
| 			if self.paid_to: | ||||
| 				self.base_received_amount = flt(flt(self.received_amount) * flt(self.target_exchange_rate),  | ||||
| 					self.precision("base_received_amount")) | ||||
| 			else: | ||||
| 				self.base_received_amount = self.base_total_allocated_amount | ||||
| 		 | ||||
| 		self.difference_amount = self.base_paid_amount - self.base_received_amount | ||||
| 		 | ||||
| 	def validate_mandatory(self): | ||||
| 		mandatory_fields = ["paid_amount", "received_amount", "base_paid_amount", "base_received_amount",  | ||||
| 			"reference_no", "reference_date"] | ||||
| 		if self.payment_type == "Receive": | ||||
| 			mandatory_fields += ["party_type", "party", "party_account", "party_account_currency",  | ||||
| 				"paid_to", "paid_to_account_currency", "references", "total_allocated_amount"] | ||||
| 			self.difference_amount = base_party_amount - self.base_received_amount | ||||
| 		elif self.payment_type == "Pay": | ||||
| 			mandatory_fields += ["party_type", "party", "party_account", "party_account_currency",  | ||||
| 				"paid_from", "paid_from_account_currency", "references", "total_allocated_amount"] | ||||
| 			self.difference_amount = self.base_paid_amount - base_party_amount | ||||
| 		else: | ||||
| 			mandatory_fields += ["paid_from", "paid_from_account_currency", | ||||
| 				"paid_to", "paid_to_account_currency"] | ||||
| 			self.difference_amount = self.base_paid_amount - flt(self.base_received_amount) | ||||
| 			 | ||||
| 		for d in self.get("deductions"): | ||||
| 			if d.amount: | ||||
| 				self.difference_amount -= flt(d.amount) | ||||
| 				 | ||||
| 		if self.paid_from: | ||||
| 			mandatory_fields.append("source_exchange_rate") | ||||
| 		if self.paid_to: | ||||
| 			mandatory_fields.append("target_exchange_rate") | ||||
| 	def clear_unallocated_reference_document_rows(self): | ||||
| 		self.set("references", self.get("references", {"allocated_amount": ["not in", [0, None, ""]]})) | ||||
| 
 | ||||
| 		for field in mandatory_fields: | ||||
| 			if not self.get(field): | ||||
| 				frappe.throw(_("{0} is mandatory").format(self.meta.get_label(field))) | ||||
| 
 | ||||
| 	def set_write_off_amount(self): | ||||
| 		frappe.db.sql("""delete from `tabPayment Entry Reference`  | ||||
| 			where parent = %s and allocated_amount = 0""", self.name) | ||||
| 			 | ||||
| 	def set_title(self): | ||||
| 		if self.payment_type in ("Receive", "Pay"): | ||||
| 			bank_account_currency = self.paid_from_account_currency \ | ||||
| 				if self.paid_from else self.paid_to_account_currency | ||||
| 				 | ||||
| 			if self.party_account_currency == bank_account_currency and self.difference_amount: | ||||
| 				self.write_off_amount = self.difference_amount | ||||
| 			self.title = self.party | ||||
| 		else: | ||||
| 			self.title = self.paid_from + " - " + self.paid_to | ||||
| 				 | ||||
| 	def make_gl_entries(self): | ||||
| 		gl_entries = [] | ||||
| 		self.add_party_gl_entries(gl_entries) | ||||
| 		self.add_bank_gl_entries(gl_entries) | ||||
| 		self.add_write_off_gl_entries(gl_entries) | ||||
| 		self.add_deductions_gl_entries(gl_entries) | ||||
| 		 | ||||
| 		make_gl_entries(gl_entries, cancel = (self.docstatus==2)) | ||||
| 		 | ||||
| 		 | ||||
| 	def add_party_gl_entries(self, gl_entries): | ||||
| 		if self.party_account: | ||||
| 			if self.payment_type=="Receive": | ||||
| 				party_account_currency = self.paid_from_account_currency | ||||
| 				against_account = self.paid_to | ||||
| 			else: | ||||
| 				 party_account_currency = self.paid_to_account_currency | ||||
| 				 against_account = self.paid_from | ||||
| 			 | ||||
| 				 | ||||
| 			party_gl_dict = self.get_gl_dict({ | ||||
| 				"account": self.party_account, | ||||
| 				"party_type": self.party_type, | ||||
| 				"party": self.party, | ||||
| 				"against": self.paid_from or self.paid_to, | ||||
| 				"account_currency": self.party_account_currency | ||||
| 				"against": against_account, | ||||
| 				"account_currency": party_account_currency | ||||
| 			}) | ||||
| 			 | ||||
| 			for d in self.get("references"): | ||||
| 				party_gl_dict.update({ | ||||
| 				gle = party_gl_dict.copy() | ||||
| 				gle.update({ | ||||
| 					"against_voucher_type": d.reference_doctype, | ||||
| 					"against_voucher": d.reference_name | ||||
| 				}) | ||||
| 				 | ||||
| 				allocated_amount_in_company_currency = flt(flt(d.allocated_amount) * flt(d.exchange_rate),  | ||||
| 					self.precision("paid_amount")) | ||||
| 					 | ||||
| 					self.precision("paid_amount"))	 | ||||
| 				 | ||||
| 				if self.payment_type == "Receive": | ||||
| 					party_gl_dict.update({ | ||||
| 					gle.update({ | ||||
| 						"credit_in_account_currency": d.allocated_amount, | ||||
| 						"credit": allocated_amount_in_company_currency | ||||
| 					}) | ||||
| 				elif self.payment_type == "Pay": | ||||
| 					party_gl_dict.update({ | ||||
| 					gle.update({ | ||||
| 						"debit_in_account_currency": d.allocated_amount, | ||||
| 						"debit": allocated_amount_in_company_currency | ||||
| 					}) | ||||
| 				 | ||||
| 				gl_entries.append(party_gl_dict) | ||||
| 				gl_entries.append(gle) | ||||
| 				 | ||||
| 			if self.unallocated_amount: | ||||
| 				base_unallocated_amount = base_unallocated_amount = self.unallocated_amount * \ | ||||
| 					(self.source_exchange_rate if self.payment_type=="Receive" else self.target_exchange_rate) | ||||
| 					 | ||||
| 				gle = party_gl_dict.copy() | ||||
| 				if self.payment_type == "Receive": | ||||
| 					gle.update({ | ||||
| 						"credit_in_account_currency": self.unallocated_amount, | ||||
| 						"credit": base_unallocated_amount | ||||
| 					}) | ||||
| 				elif self.payment_type == "Pay": | ||||
| 					gle.update({ | ||||
| 						"debit_in_account_currency": self.unallocated_amount, | ||||
| 						"debit": base_unallocated_amount | ||||
| 					}) | ||||
| 				 | ||||
| 				gl_entries.append(gle) | ||||
| 				 | ||||
| 				 | ||||
| 	def add_bank_gl_entries(self, gl_entries): | ||||
| 		if self.paid_from and self.paid_amount: | ||||
| 		if self.payment_type in ("Pay", "Internal Transfer"): | ||||
| 			gl_entries.append( | ||||
| 				self.get_gl_dict({ | ||||
| 					"account": self.paid_from, | ||||
| 					"account_currency": self.paid_from_account_currency, | ||||
| 					"against": self.party_account, | ||||
| 					"against": self.party if self.payment_type=="Pay" else self.paid_to, | ||||
| 					"credit_in_account_currency": self.paid_amount, | ||||
| 					"credit": self.base_paid_amount | ||||
| 				}) | ||||
| 			) | ||||
| 		if self.paid_to and self.received_amount: | ||||
| 		if self.payment_type in ("Receive", "Internal Transfer"): | ||||
| 			gl_entries.append( | ||||
| 				self.get_gl_dict({ | ||||
| 					"account": self.paid_to, | ||||
| 					"account_currency": self.paid_to_account_currency, | ||||
| 					"against": self.party, | ||||
| 					"against": self.party if self.payment_type=="Receive" else self.paid_from, | ||||
| 					"debit_in_account_currency": self.received_amount, | ||||
| 					"debit": self.base_received_amount | ||||
| 				}) | ||||
| 			) | ||||
| 			 | ||||
| 	def add_write_off_gl_entries(self, gl_entries): | ||||
| 		if self.write_off_account and self.write_off_amount: | ||||
| 			write_off_account_currency = get_account_currency(self.write_off_account) | ||||
| 			if self.write_off_account_currency != self.company_currency: | ||||
| 				frappe.throw(_("Write Off Account currency must be same as {0}") | ||||
| 					.format(self.company_currency)) | ||||
| 
 | ||||
| 			gl_entries.append( | ||||
| 				self.get_gl_dict({ | ||||
| 					"account": self.write_off_account, | ||||
| 					"against": self.party, | ||||
| 					"debit_in_account_currency": self.write_off_amount, | ||||
| 					"debit": self.write_off_amount, | ||||
| 					"cost_center": self.write_off_cost_center | ||||
| 				}, write_off_account_currency) | ||||
| 			) | ||||
| 		 | ||||
| 	def add_deductions_gl_entries(self, gl_entries): | ||||
| 		pass | ||||
| 
 | ||||
| 		for d in self.get("deductions"): | ||||
| 			if d.amount: | ||||
| 				account_currency = get_account_currency(d.account) | ||||
| 				if account_currency != self.company_currency: | ||||
| 					frappe.throw(_("Currency for {0} must be {1}").format(d.account, self.company_currency)) | ||||
| 					 | ||||
| 				gl_entries.append( | ||||
| 					self.get_gl_dict({ | ||||
| 						"account": d.account, | ||||
| 						"account_currency": account_currency, | ||||
| 						"against": self.party or self.paid_from, | ||||
| 						"debit_in_account_currency": d.amount, | ||||
| 						"debit": d.amount, | ||||
| 						"cost_center": d.cost_center | ||||
| 					}) | ||||
| 				) | ||||
| 				 | ||||
| 	def update_advance_paid(self): | ||||
| 		if self.payment_type in ("Receive", "Pay") and self.party: | ||||
| 			for d in self.get("references"): | ||||
| @ -324,6 +397,13 @@ def get_account_currency_and_balance(account, date): | ||||
| 	}) | ||||
| 	 | ||||
| @frappe.whitelist() | ||||
| def get_write_off_account_and_cost_center(company): | ||||
| 	return frappe.db.get_value("Company", company, ["write_off_account", "cost_center"], as_dict=1) | ||||
| 	 | ||||
| def get_company_defaults(company): | ||||
| 	fields = ["write_off_account", "exchange_gain_loss_account", "cost_center"] | ||||
| 	ret = frappe.db.get_value("Company", company, fields, as_dict=1) | ||||
| 	 | ||||
| 	for fieldname in fields: | ||||
| 		if not ret[fieldname]: | ||||
| 			frappe.throw(_("Please set default {0} in Company {1}") | ||||
| 				.format(frappe.get_meta("Company").get_label(fieldname), company)) | ||||
| 	 | ||||
| 	return ret | ||||
| @ -30,7 +30,7 @@ | ||||
|    "print_hide_if_no_value": 0,  | ||||
|    "read_only": 0,  | ||||
|    "report_hide": 0,  | ||||
|    "reqd": 0,  | ||||
|    "reqd": 1,  | ||||
|    "search_index": 0,  | ||||
|    "set_only_once": 0,  | ||||
|    "unique": 0 | ||||
| @ -221,7 +221,7 @@ | ||||
|  "issingle": 0,  | ||||
|  "istable": 1,  | ||||
|  "max_attachments": 0,  | ||||
|  "modified": "2016-06-22 16:15:10.404692",  | ||||
|  "modified": "2016-06-26 15:01:17.161402",  | ||||
|  "modified_by": "Administrator",  | ||||
|  "module": "Accounts",  | ||||
|  "name": "Payment Entry Reference",  | ||||
|  | ||||
| @ -290,7 +290,7 @@ def get_company_default(company, fieldname): | ||||
| 	value = frappe.db.get_value("Company", company, fieldname) | ||||
| 
 | ||||
| 	if not value: | ||||
| 		throw(_("Please set default value {0} in Company {1}").format(frappe.get_meta("Company").get_label(fieldname), company)) | ||||
| 		throw(_("Please set default {0} in Company {1}").format(frappe.get_meta("Company").get_label(fieldname), company)) | ||||
| 
 | ||||
| 	return value | ||||
| 
 | ||||
| @ -427,7 +427,9 @@ def get_outstanding_invoices(party_type, party, account, condition=None): | ||||
| 			'due_date': frappe.db.get_value(d.voucher_type, d.voucher_no, "due_date"), | ||||
| 			'exchange_rate': frappe.db.get_value(d.voucher_type, d.voucher_no, "conversion_rate") | ||||
| 		}) | ||||
| 
 | ||||
| 		 | ||||
| 	outstanding_invoices = sorted(outstanding_invoices, key=lambda k: k['due_date']) | ||||
| 	 | ||||
| 	return outstanding_invoices | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -255,7 +255,7 @@ class AccountsController(TransactionBase): | ||||
| 		if not account_currency: | ||||
| 			account_currency = get_account_currency(gl_dict.account) | ||||
| 
 | ||||
| 		if self.doctype not in ["Journal Entry", "Period Closing Voucher"]: | ||||
| 		if self.doctype not in ["Journal Entry", "Period Closing Voucher", "Payment Entry"]: | ||||
| 			self.validate_account_currency(gl_dict.account, account_currency) | ||||
| 			set_balance_in_account_currency(gl_dict, account_currency, self.get("conversion_rate"), self.company_currency) | ||||
| 
 | ||||
|  | ||||
| @ -137,6 +137,7 @@ erpnext.company.setup_queries = function(frm) { | ||||
| 		["default_income_account", {"root_type": "Income"}], | ||||
| 		["round_off_account", {"root_type": "Expense"}], | ||||
| 		["write_off_account", {"root_type": "Expense"}], | ||||
| 		["exchange_gain_loss_account", {"root_type": "Expense"}], | ||||
| 		["accumulated_depreciation_account", {"root_type": "Asset"}], | ||||
| 		["depreciation_expense_account", {"root_type": "Expense"}], | ||||
| 		["disposal_account", {"report_type": "Profit and Loss"}], | ||||
|  | ||||
| @ -521,6 +521,32 @@ | ||||
|    "set_only_once": 0,  | ||||
|    "unique": 0 | ||||
|   },  | ||||
|   { | ||||
|    "allow_on_submit": 0,  | ||||
|    "bold": 0,  | ||||
|    "collapsible": 0,  | ||||
|    "fieldname": "exchange_gain_loss_account",  | ||||
|    "fieldtype": "Link",  | ||||
|    "hidden": 0,  | ||||
|    "ignore_user_permissions": 0,  | ||||
|    "ignore_xss_filter": 0,  | ||||
|    "in_filter": 0,  | ||||
|    "in_list_view": 0,  | ||||
|    "label": "Exchange Gain / Loss Account",  | ||||
|    "length": 0,  | ||||
|    "no_copy": 0,  | ||||
|    "options": "Account",  | ||||
|    "permlevel": 0,  | ||||
|    "precision": "",  | ||||
|    "print_hide": 0,  | ||||
|    "print_hide_if_no_value": 0,  | ||||
|    "read_only": 0,  | ||||
|    "report_hide": 0,  | ||||
|    "reqd": 0,  | ||||
|    "search_index": 0,  | ||||
|    "set_only_once": 0,  | ||||
|    "unique": 0 | ||||
|   },  | ||||
|   { | ||||
|    "allow_on_submit": 0,  | ||||
|    "bold": 0,  | ||||
| @ -1359,7 +1385,7 @@ | ||||
|  "istable": 0,  | ||||
|  "max_attachments": 0,  | ||||
|  "menu_index": 0,  | ||||
|  "modified": "2016-06-26 00:44:30.299891",  | ||||
|  "modified": "2016-06-26 09:08:50.476200",  | ||||
|  "modified_by": "Administrator",  | ||||
|  "module": "Setup",  | ||||
|  "name": "Company",  | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user