Merge pull request #25020 from prssanna/help-links-fix-v13

diff --git a/erpnext/non_profit/doctype/donation/donation.py b/erpnext/non_profit/doctype/donation/donation.py
index e947588..4fd1a30 100644
--- a/erpnext/non_profit/doctype/donation/donation.py
+++ b/erpnext/non_profit/doctype/donation/donation.py
@@ -42,7 +42,7 @@
 		self.load_from_db()
 		self.create_payment_entry()
 
-	def create_payment_entry(self):
+	def create_payment_entry(self, date=None):
 		settings = frappe.get_doc('Non Profit Settings')
 		if not settings.automate_donation_payment_entries:
 			return
@@ -58,8 +58,9 @@
 		frappe.flags.ignore_account_permission = False
 		pe.paid_from = settings.donation_debit_account
 		pe.paid_to = settings.donation_payment_account
+		pe.posting_date = date or getdate()
 		pe.reference_no = self.name
-		pe.reference_date = getdate()
+		pe.reference_date = date or getdate()
 		pe.flags.ignore_mandatory = True
 		pe.insert()
 		pe.submit()
@@ -91,6 +92,10 @@
 		if not data.event == 'payment.captured':
 			return
 
+		# to avoid capturing subscription payments as donations
+		if payment.description and 'subscription' in str(payment.description).lower():
+			return
+
 		donor = get_donor(payment.email)
 		if not donor:
 			donor = create_donor(payment)
@@ -119,7 +124,7 @@
 		'donor_name': donor.donor_name,
 		'email': donor.email,
 		'date': getdate(),
-		'amount': flt(payment.amount),
+		'amount': flt(payment.amount) / 100, # Convert to rupees from paise
 		'mode_of_payment': payment.method,
 		'razorpay_payment_id': payment.id
 	}).insert(ignore_mandatory=True)
diff --git a/erpnext/non_profit/doctype/membership/membership.py b/erpnext/non_profit/doctype/membership/membership.py
index 191281f..52447e4 100644
--- a/erpnext/non_profit/doctype/membership/membership.py
+++ b/erpnext/non_profit/doctype/membership/membership.py
@@ -48,7 +48,7 @@
 		last_membership = erpnext.get_last_membership(self.member)
 
 		# if person applied for offline membership
-		if last_membership and not frappe.session.user == "Administrator":
+		if last_membership and last_membership.name != self.name and not frappe.session.user == "Administrator":
 			# if last membership does not expire in 30 days, then do not allow to renew
 			if getdate(add_days(last_membership.to_date, -30)) > getdate(nowdate()) :
 				frappe.throw(_("You can only renew if your membership expires within 30 days"))
@@ -90,6 +90,7 @@
 		self.validate_membership_type_and_settings(plan, settings)
 
 		invoice = make_invoice(self, member, plan, settings)
+		self.reload()
 		self.invoice = invoice.name
 
 		if with_payment_entry:
@@ -284,10 +285,11 @@
 
 		settings = frappe.get_doc("Non Profit Settings")
 		if settings.allow_invoicing and settings.automate_membership_invoicing:
+			membership.reload()
 			membership.generate_invoice(with_payment_entry=settings.automate_membership_payment_entries, save=True)
 
 	except Exception as e:
-		message = "{0}\n\n{1}\n\n{2}: {3}".format(e, frappe.get_traceback(), __("Payment ID"), payment.id)
+		message = "{0}\n\n{1}\n\n{2}: {3}".format(e, frappe.get_traceback(), _("Payment ID"), payment.id)
 		log = frappe.log_error(message, _("Error creating membership entry for {0}").format(member.name))
 		notify_failure(log)
 		return { "status": "Failed", "reason": e}
diff --git a/erpnext/non_profit/doctype/non_profit_settings/non_profit_settings.js b/erpnext/non_profit/doctype/non_profit_settings/non_profit_settings.js
index cff92b4..4c4ca98 100644
--- a/erpnext/non_profit/doctype/non_profit_settings/non_profit_settings.js
+++ b/erpnext/non_profit/doctype/non_profit_settings/non_profit_settings.js
@@ -19,7 +19,7 @@
 			};
 		});
 
-		frm.set_query("debit_account", function() {
+		frm.set_query("membership_debit_account", function() {
 			return {
 				filters: {
 					"account_type": "Receivable",
@@ -29,6 +29,16 @@
 			};
 		});
 
+		frm.set_query("donation_debit_account", function() {
+			return {
+				filters: {
+					"account_type": "Receivable",
+					"is_group": 0,
+					"company": frm.doc.donation_company
+				}
+			};
+		});
+
 		frm.set_query("membership_payment_account", function () {
 			var account_types = ["Bank", "Cash"];
 			return {
@@ -40,6 +50,17 @@
 			};
 		});
 
+		frm.set_query("donation_payment_account", function () {
+			var account_types = ["Bank", "Cash"];
+			return {
+				filters: {
+					"account_type": ["in", account_types],
+					"is_group": 0,
+					"company": frm.doc.donation_company
+				}
+			};
+		});
+
 		let docs_url = "https://docs.erpnext.com/docs/user/manual/en/non_profit/membership";
 
 		frm.set_intro(__("You can learn more about memberships in the manual. ") + `<a href='${docs_url}'>${__('ERPNext Docs')}</a>`, true);
diff --git a/erpnext/payroll/doctype/salary_slip/salary_slip.js b/erpnext/payroll/doctype/salary_slip/salary_slip.js
index 7460c75..d527839 100644
--- a/erpnext/payroll/doctype/salary_slip/salary_slip.js
+++ b/erpnext/payroll/doctype/salary_slip/salary_slip.js
@@ -74,43 +74,46 @@
 		if (!frm.doc.letter_head && company.default_letter_head) {
 			frm.set_value('letter_head', company.default_letter_head);
 		}
+	},
+
+	currency: function(frm) {
 		frm.trigger("set_dynamic_labels");
 	},
 
 	set_dynamic_labels: function(frm) {
 		var company_currency = frm.doc.company? erpnext.get_currency(frm.doc.company): frappe.defaults.get_default("currency");
-		frappe.run_serially([
-			() => 	frm.events.set_exchange_rate(frm, company_currency),
-			() => 	frm.events.change_form_labels(frm, company_currency),
-			() => 	frm.events.change_grid_labels(frm),
-			() => 	frm.refresh_fields()
-		]);
+		if (frm.doc.employee && frm.doc.currency) {
+			frappe.run_serially([
+				() => 	frm.events.set_exchange_rate(frm, company_currency),
+				() => 	frm.events.change_form_labels(frm, company_currency),
+				() => 	frm.events.change_grid_labels(frm),
+				() => 	frm.refresh_fields()
+			]);
+		}
 	},
 
 	set_exchange_rate: function(frm, company_currency) {
-		if (frm.doc.docstatus === 0) {
-			if (frm.doc.currency) {
-				var from_currency = frm.doc.currency;
-				if (from_currency != company_currency) {
-					frm.events.hide_loan_section(frm);
-					frappe.call({
-						method: "erpnext.setup.utils.get_exchange_rate",
-						args: {
-							from_currency: from_currency,
-							to_currency: company_currency,
-						},
-						callback: function(r) {
-							frm.set_value("exchange_rate", flt(r.message));
-							frm.set_df_property('exchange_rate', 'hidden', 0);
-							frm.set_df_property("exchange_rate", "description", "1 " + frm.doc.currency
-								+ " = [?] " + company_currency);
-						}
-					});
-				} else {
-					frm.set_value("exchange_rate", 1.0);
-					frm.set_df_property('exchange_rate', 'hidden', 1);
-					frm.set_df_property("exchange_rate", "description", "" );
-				}
+		if (frm.doc.currency) {
+			var from_currency = frm.doc.currency;
+			if (from_currency != company_currency) {
+				frm.events.hide_loan_section(frm);
+				frappe.call({
+					method: "erpnext.setup.utils.get_exchange_rate",
+					args: {
+						from_currency: from_currency,
+						to_currency: company_currency,
+					},
+					callback: function(r) {
+						frm.set_value("exchange_rate", flt(r.message));
+						frm.set_df_property("exchange_rate", "hidden", 0);
+						frm.set_df_property("exchange_rate", "description", "1 " + frm.doc.currency
+							+ " = [?] " + company_currency);
+					}
+				});
+			} else {
+				frm.set_value("exchange_rate", 1.0);
+				frm.set_df_property("exchange_rate", "hidden", 1);
+				frm.set_df_property("exchange_rate", "description", "");
 			}
 		}
 	},
diff --git a/erpnext/regional/doctype/tax_exemption_80g_certificate/tax_exemption_80g_certificate.py b/erpnext/regional/doctype/tax_exemption_80g_certificate/tax_exemption_80g_certificate.py
index d734a18..41c7b23 100644
--- a/erpnext/regional/doctype/tax_exemption_80g_certificate/tax_exemption_80g_certificate.py
+++ b/erpnext/regional/doctype/tax_exemption_80g_certificate/tax_exemption_80g_certificate.py
@@ -16,6 +16,7 @@
 		self.validate_duplicates()
 		self.validate_company_details()
 		self.set_company_address()
+		self.calculate_total()
 		self.set_title()
 
 	def validate_date(self):
@@ -29,7 +30,10 @@
 
 	def validate_duplicates(self):
 		if self.recipient == 'Donor':
-			certificate = frappe.db.exists(self.doctype, {'donation': self.donation})
+			certificate = frappe.db.exists(self.doctype, {
+				'donation': self.donation,
+				'name': ('!=', self.name)
+			})
 			if certificate:
 				frappe.throw(_('An 80G Certificate {0} already exists for the donation {1}').format(
 					get_link_to_form(self.doctype, certificate), frappe.bold(self.donation)
@@ -51,8 +55,17 @@
 		self.company_address = address.company_address
 		self.company_address_display = address.company_address_display
 
+	def calculate_total(self):
+		if self.recipient == 'Donor':
+			return
+
+		total = 0
+		for entry in self.payments:
+			total += flt(entry.amount)
+		self.total = total
+
 	def set_title(self):
-		if self.recipient == "Member":
+		if self.recipient == 'Member':
 			self.title = self.member_name
 		else:
 			self.title = self.donor_name
@@ -68,7 +81,7 @@
 			'from_date': ['between', (fiscal_year.year_start_date, fiscal_year.year_end_date)],
 			'to_date': ['between', (fiscal_year.year_start_date, fiscal_year.year_end_date)],
 			'membership_status': ('!=', 'Cancelled')
-		}, ['from_date', 'amount', 'name', 'invoice', 'payment_id'])
+		}, ['from_date', 'amount', 'name', 'invoice', 'payment_id'], order_by='from_date')
 
 		if not memberships:
 			frappe.msgprint(_('No Membership Payments found against the Member {0}').format(self.member))