mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-31 10:49:09 +00:00
Merge pull request #25059 from ruchamahabal/non-profit-fixes
fix: Non Profit fixes
This commit is contained in:
@@ -42,7 +42,7 @@ class Donation(Document):
|
|||||||
self.load_from_db()
|
self.load_from_db()
|
||||||
self.create_payment_entry()
|
self.create_payment_entry()
|
||||||
|
|
||||||
def create_payment_entry(self):
|
def create_payment_entry(self, date=None):
|
||||||
settings = frappe.get_doc('Non Profit Settings')
|
settings = frappe.get_doc('Non Profit Settings')
|
||||||
if not settings.automate_donation_payment_entries:
|
if not settings.automate_donation_payment_entries:
|
||||||
return
|
return
|
||||||
@@ -58,8 +58,9 @@ class Donation(Document):
|
|||||||
frappe.flags.ignore_account_permission = False
|
frappe.flags.ignore_account_permission = False
|
||||||
pe.paid_from = settings.donation_debit_account
|
pe.paid_from = settings.donation_debit_account
|
||||||
pe.paid_to = settings.donation_payment_account
|
pe.paid_to = settings.donation_payment_account
|
||||||
|
pe.posting_date = date or getdate()
|
||||||
pe.reference_no = self.name
|
pe.reference_no = self.name
|
||||||
pe.reference_date = getdate()
|
pe.reference_date = date or getdate()
|
||||||
pe.flags.ignore_mandatory = True
|
pe.flags.ignore_mandatory = True
|
||||||
pe.insert()
|
pe.insert()
|
||||||
pe.submit()
|
pe.submit()
|
||||||
@@ -91,6 +92,10 @@ def capture_razorpay_donations(*args, **kwargs):
|
|||||||
if not data.event == 'payment.captured':
|
if not data.event == 'payment.captured':
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# to avoid capturing subscription payments as donations
|
||||||
|
if payment.description and 'subscription' in str(payment.description).lower():
|
||||||
|
return
|
||||||
|
|
||||||
donor = get_donor(payment.email)
|
donor = get_donor(payment.email)
|
||||||
if not donor:
|
if not donor:
|
||||||
donor = create_donor(payment)
|
donor = create_donor(payment)
|
||||||
@@ -119,7 +124,7 @@ def create_donation(donor, payment):
|
|||||||
'donor_name': donor.donor_name,
|
'donor_name': donor.donor_name,
|
||||||
'email': donor.email,
|
'email': donor.email,
|
||||||
'date': getdate(),
|
'date': getdate(),
|
||||||
'amount': flt(payment.amount),
|
'amount': flt(payment.amount) / 100, # Convert to rupees from paise
|
||||||
'mode_of_payment': payment.method,
|
'mode_of_payment': payment.method,
|
||||||
'razorpay_payment_id': payment.id
|
'razorpay_payment_id': payment.id
|
||||||
}).insert(ignore_mandatory=True)
|
}).insert(ignore_mandatory=True)
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ class Membership(Document):
|
|||||||
last_membership = erpnext.get_last_membership(self.member)
|
last_membership = erpnext.get_last_membership(self.member)
|
||||||
|
|
||||||
# if person applied for offline membership
|
# 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 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()) :
|
if getdate(add_days(last_membership.to_date, -30)) > getdate(nowdate()) :
|
||||||
frappe.throw(_("You can only renew if your membership expires within 30 days"))
|
frappe.throw(_("You can only renew if your membership expires within 30 days"))
|
||||||
@@ -90,6 +90,7 @@ class Membership(Document):
|
|||||||
self.validate_membership_type_and_settings(plan, settings)
|
self.validate_membership_type_and_settings(plan, settings)
|
||||||
|
|
||||||
invoice = make_invoice(self, member, plan, settings)
|
invoice = make_invoice(self, member, plan, settings)
|
||||||
|
self.reload()
|
||||||
self.invoice = invoice.name
|
self.invoice = invoice.name
|
||||||
|
|
||||||
if with_payment_entry:
|
if with_payment_entry:
|
||||||
@@ -284,10 +285,11 @@ def trigger_razorpay_subscription(*args, **kwargs):
|
|||||||
|
|
||||||
settings = frappe.get_doc("Non Profit Settings")
|
settings = frappe.get_doc("Non Profit Settings")
|
||||||
if settings.allow_invoicing and settings.automate_membership_invoicing:
|
if settings.allow_invoicing and settings.automate_membership_invoicing:
|
||||||
|
membership.reload()
|
||||||
membership.generate_invoice(with_payment_entry=settings.automate_membership_payment_entries, save=True)
|
membership.generate_invoice(with_payment_entry=settings.automate_membership_payment_entries, save=True)
|
||||||
|
|
||||||
except Exception as e:
|
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))
|
log = frappe.log_error(message, _("Error creating membership entry for {0}").format(member.name))
|
||||||
notify_failure(log)
|
notify_failure(log)
|
||||||
return { "status": "Failed", "reason": e}
|
return { "status": "Failed", "reason": e}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ frappe.ui.form.on("Non Profit Settings", {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
frm.set_query("debit_account", function() {
|
frm.set_query("membership_debit_account", function() {
|
||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
"account_type": "Receivable",
|
"account_type": "Receivable",
|
||||||
@@ -29,6 +29,16 @@ frappe.ui.form.on("Non Profit Settings", {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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 () {
|
frm.set_query("membership_payment_account", function () {
|
||||||
var account_types = ["Bank", "Cash"];
|
var account_types = ["Bank", "Cash"];
|
||||||
return {
|
return {
|
||||||
@@ -40,6 +50,17 @@ frappe.ui.form.on("Non Profit Settings", {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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";
|
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);
|
frm.set_intro(__("You can learn more about memberships in the manual. ") + `<a href='${docs_url}'>${__('ERPNext Docs')}</a>`, true);
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ class TaxExemption80GCertificate(Document):
|
|||||||
self.validate_duplicates()
|
self.validate_duplicates()
|
||||||
self.validate_company_details()
|
self.validate_company_details()
|
||||||
self.set_company_address()
|
self.set_company_address()
|
||||||
|
self.calculate_total()
|
||||||
self.set_title()
|
self.set_title()
|
||||||
|
|
||||||
def validate_date(self):
|
def validate_date(self):
|
||||||
@@ -29,7 +30,10 @@ class TaxExemption80GCertificate(Document):
|
|||||||
|
|
||||||
def validate_duplicates(self):
|
def validate_duplicates(self):
|
||||||
if self.recipient == 'Donor':
|
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:
|
if certificate:
|
||||||
frappe.throw(_('An 80G Certificate {0} already exists for the donation {1}').format(
|
frappe.throw(_('An 80G Certificate {0} already exists for the donation {1}').format(
|
||||||
get_link_to_form(self.doctype, certificate), frappe.bold(self.donation)
|
get_link_to_form(self.doctype, certificate), frappe.bold(self.donation)
|
||||||
@@ -51,8 +55,17 @@ class TaxExemption80GCertificate(Document):
|
|||||||
self.company_address = address.company_address
|
self.company_address = address.company_address
|
||||||
self.company_address_display = address.company_address_display
|
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):
|
def set_title(self):
|
||||||
if self.recipient == "Member":
|
if self.recipient == 'Member':
|
||||||
self.title = self.member_name
|
self.title = self.member_name
|
||||||
else:
|
else:
|
||||||
self.title = self.donor_name
|
self.title = self.donor_name
|
||||||
@@ -68,7 +81,7 @@ class TaxExemption80GCertificate(Document):
|
|||||||
'from_date': ['between', (fiscal_year.year_start_date, fiscal_year.year_end_date)],
|
'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)],
|
'to_date': ['between', (fiscal_year.year_start_date, fiscal_year.year_end_date)],
|
||||||
'membership_status': ('!=', 'Cancelled')
|
'membership_status': ('!=', 'Cancelled')
|
||||||
}, ['from_date', 'amount', 'name', 'invoice', 'payment_id'])
|
}, ['from_date', 'amount', 'name', 'invoice', 'payment_id'], order_by='from_date')
|
||||||
|
|
||||||
if not memberships:
|
if not memberships:
|
||||||
frappe.msgprint(_('No Membership Payments found against the Member {0}').format(self.member))
|
frappe.msgprint(_('No Membership Payments found against the Member {0}').format(self.member))
|
||||||
|
|||||||
Reference in New Issue
Block a user