feat(Non Profit): 80G Certificates and Donations (#24848)

* feat(Non Profit): 80G Certificates and Donations

* fix(Membership): Generate Invoice for membership webhook only if automation is enabled (#24849)
This commit is contained in:
Rucha Mahabal
2021-03-11 16:02:23 +05:30
committed by GitHub
parent 0623a34210
commit 0b29f87fa2
42 changed files with 2021 additions and 330 deletions

View File

@@ -0,0 +1,67 @@
// Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.ui.form.on('Tax Exemption 80G Certificate', {
refresh: function(frm) {
if (frm.doc.donor) {
frm.set_query('donation', function() {
return {
filters: {
docstatus: 1,
donor: frm.doc.donor
}
};
});
}
},
recipient: function(frm) {
if (frm.doc.recipient === 'Donor') {
frm.set_value({
'member': '',
'member_name': '',
'member_email': '',
'member_pan_number': '',
'fiscal_year': '',
'total': 0,
'payments': []
});
} else {
frm.set_value({
'donor': '',
'donor_name': '',
'donor_email': '',
'donor_pan_number': '',
'donation': '',
'date_of_donation': '',
'amount': 0,
'mode_of_payment': '',
'razorpay_payment_id': ''
});
}
},
get_payments: function(frm) {
frm.call({
doc: frm.doc,
method: 'get_payments',
freeze: true
});
},
company: function(frm) {
if ((frm.doc.member || frm.doc.donor) && frm.doc.company) {
frm.call({
doc: frm.doc,
method: 'set_company_address',
freeze: true
});
}
},
donation: function(frm) {
if (frm.doc.recipient === 'Donor' && !frm.doc.donor) {
frappe.msgprint(__('Please select donor first'));
}
}
});

View File

@@ -0,0 +1,297 @@
{
"actions": [],
"autoname": "naming_series:",
"creation": "2021-02-15 12:37:21.577042",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"naming_series",
"recipient",
"member",
"member_name",
"member_email",
"member_pan_number",
"donor",
"donor_name",
"donor_email",
"donor_pan_number",
"column_break_4",
"date",
"fiscal_year",
"section_break_11",
"company",
"company_address",
"company_address_display",
"column_break_14",
"company_pan_number",
"company_80g_number",
"company_80g_wef",
"title",
"section_break_6",
"get_payments",
"payments",
"total",
"donation_details_section",
"donation",
"date_of_donation",
"amount",
"column_break_27",
"mode_of_payment",
"razorpay_payment_id"
],
"fields": [
{
"fieldname": "recipient",
"fieldtype": "Select",
"in_list_view": 1,
"label": "Certificate Recipient",
"options": "Member\nDonor",
"reqd": 1
},
{
"depends_on": "eval:doc.recipient === \"Member\";",
"fieldname": "member",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Member",
"mandatory_depends_on": "eval:doc.recipient === \"Member\";",
"options": "Member"
},
{
"depends_on": "eval:doc.recipient === \"Member\";",
"fetch_from": "member.member_name",
"fieldname": "member_name",
"fieldtype": "Data",
"label": "Member Name",
"read_only": 1
},
{
"depends_on": "eval:doc.recipient === \"Donor\";",
"fieldname": "donor",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Donor",
"mandatory_depends_on": "eval:doc.recipient === \"Donor\";",
"options": "Donor"
},
{
"fieldname": "column_break_4",
"fieldtype": "Column Break"
},
{
"fieldname": "date",
"fieldtype": "Date",
"label": "Date",
"reqd": 1
},
{
"depends_on": "eval:doc.recipient === \"Member\";",
"fieldname": "section_break_6",
"fieldtype": "Section Break"
},
{
"fieldname": "payments",
"fieldtype": "Table",
"label": "Payments",
"options": "Tax Exemption 80G Certificate Detail"
},
{
"fieldname": "total",
"fieldtype": "Currency",
"in_list_view": 1,
"label": "Total",
"read_only": 1
},
{
"depends_on": "eval:doc.recipient === \"Member\";",
"fieldname": "fiscal_year",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Fiscal Year",
"options": "Fiscal Year"
},
{
"fieldname": "company",
"fieldtype": "Link",
"label": "Company",
"options": "Company",
"reqd": 1
},
{
"fieldname": "get_payments",
"fieldtype": "Button",
"label": "Get Memberships"
},
{
"fieldname": "naming_series",
"fieldtype": "Select",
"label": "Naming Series",
"options": "NPO-80G-.YYYY.-"
},
{
"fieldname": "section_break_11",
"fieldtype": "Section Break",
"label": "Company Details"
},
{
"fieldname": "company_address",
"fieldtype": "Link",
"label": "Company Address",
"options": "Address"
},
{
"fieldname": "column_break_14",
"fieldtype": "Column Break"
},
{
"fetch_from": "company.pan_details",
"fieldname": "company_pan_number",
"fieldtype": "Data",
"label": "PAN Number",
"read_only": 1
},
{
"fieldname": "company_address_display",
"fieldtype": "Small Text",
"hidden": 1,
"label": "Company Address Display",
"print_hide": 1,
"read_only": 1
},
{
"fetch_from": "company.company_80g_number",
"fieldname": "company_80g_number",
"fieldtype": "Data",
"label": "80G Number",
"read_only": 1
},
{
"fetch_from": "company.with_effect_from",
"fieldname": "company_80g_wef",
"fieldtype": "Date",
"label": "80G With Effect From",
"read_only": 1
},
{
"depends_on": "eval:doc.recipient === \"Donor\";",
"fieldname": "donation_details_section",
"fieldtype": "Section Break",
"label": "Donation Details"
},
{
"fieldname": "donation",
"fieldtype": "Link",
"label": "Donation",
"mandatory_depends_on": "eval:doc.recipient === \"Donor\";",
"options": "Donation"
},
{
"fetch_from": "donation.amount",
"fieldname": "amount",
"fieldtype": "Currency",
"label": "Amount",
"read_only": 1
},
{
"fetch_from": "donation.mode_of_payment",
"fieldname": "mode_of_payment",
"fieldtype": "Link",
"label": "Mode of Payment",
"options": "Mode of Payment",
"read_only": 1
},
{
"fetch_from": "donation.razorpay_payment_id",
"fieldname": "razorpay_payment_id",
"fieldtype": "Data",
"label": "RazorPay Payment ID",
"read_only": 1
},
{
"fetch_from": "donation.date",
"fieldname": "date_of_donation",
"fieldtype": "Date",
"label": "Date of Donation",
"read_only": 1
},
{
"fieldname": "column_break_27",
"fieldtype": "Column Break"
},
{
"depends_on": "eval:doc.recipient === \"Donor\";",
"fetch_from": "donor.donor_name",
"fieldname": "donor_name",
"fieldtype": "Data",
"label": "Donor Name",
"read_only": 1
},
{
"depends_on": "eval:doc.recipient === \"Donor\";",
"fetch_from": "donor.email",
"fieldname": "donor_email",
"fieldtype": "Data",
"label": "Email",
"read_only": 1
},
{
"depends_on": "eval:doc.recipient === \"Member\";",
"fetch_from": "member.email_id",
"fieldname": "member_email",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Email",
"read_only": 1
},
{
"depends_on": "eval:doc.recipient === \"Member\";",
"fetch_from": "member.pan_number",
"fieldname": "member_pan_number",
"fieldtype": "Data",
"label": "PAN Details",
"read_only": 1
},
{
"depends_on": "eval:doc.recipient === \"Donor\";",
"fetch_from": "donor.pan_number",
"fieldname": "donor_pan_number",
"fieldtype": "Data",
"label": "PAN Details",
"read_only": 1
},
{
"fieldname": "title",
"fieldtype": "Data",
"hidden": 1,
"label": "Title",
"print_hide": 1
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2021-02-22 00:03:34.215633",
"modified_by": "Administrator",
"module": "Regional",
"name": "Tax Exemption 80G Certificate",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"search_fields": "member, member_name",
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "title",
"track_changes": 1
}

View File

@@ -0,0 +1,89 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.model.document import Document
from frappe.utils import getdate, flt, get_link_to_form
from erpnext.accounts.utils import get_fiscal_year
from frappe.contacts.doctype.address.address import get_company_address
class TaxExemption80GCertificate(Document):
def validate(self):
self.validate_date()
self.validate_duplicates()
self.validate_company_details()
self.set_company_address()
self.set_title()
def validate_date(self):
if self.recipient == 'Member':
if getdate(self.date):
fiscal_year = get_fiscal_year(fiscal_year=self.fiscal_year, as_dict=True)
if not (fiscal_year.year_start_date <= getdate(self.date) \
<= fiscal_year.year_end_date):
frappe.throw(_('The Certificate Date is not in the Fiscal Year {0}').format(frappe.bold(self.fiscal_year)))
def validate_duplicates(self):
if self.recipient == 'Donor':
certificate = frappe.db.exists(self.doctype, {'donation': self.donation})
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)
), title=_('Duplicate Certificate'))
def validate_company_details(self):
fields = ['company_80g_number', 'with_effect_from', 'pan_details']
company_details = frappe.db.get_value('Company', self.company, fields, as_dict=True)
if not company_details.company_80g_number:
frappe.throw(_('Please set the {0} for company {1}').format(frappe.bold('80G Number'),
get_link_to_form('Company', self.company)))
if not company_details.pan_details:
frappe.throw(_('Please set the {0} for company {1}').format(frappe.bold('PAN Number'),
get_link_to_form('Company', self.company)))
def set_company_address(self):
address = get_company_address(self.company)
self.company_address = address.company_address
self.company_address_display = address.company_address_display
def set_title(self):
if self.recipient == "Member":
self.title = self.member_name
else:
self.title = self.donor_name
def get_payments(self):
if not self.member:
frappe.throw(_('Please select a Member first.'))
fiscal_year = get_fiscal_year(fiscal_year=self.fiscal_year, as_dict=True)
memberships = frappe.db.get_all('Membership', {
'member': self.member,
'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'])
if not memberships:
frappe.msgprint(_('No Membership Payments found against the Member {0}').format(self.member))
total = 0
self.payments = []
for doc in memberships:
self.append('payments', {
'date': doc.from_date,
'amount': doc.amount,
'invoice_id': doc.invoice,
'razorpay_payment_id': doc.payment_id,
'membership': doc.name
})
total += flt(doc.amount)
self.total = total

View File

@@ -0,0 +1,101 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
from __future__ import unicode_literals
import frappe
import unittest
from frappe.utils import getdate
from erpnext.accounts.utils import get_fiscal_year
from erpnext.non_profit.doctype.donation.test_donation import create_donor, create_mode_of_payment, create_donor_type
from erpnext.non_profit.doctype.donation.donation import create_donation
from erpnext.non_profit.doctype.membership.test_membership import setup_membership, make_membership
from erpnext.non_profit.doctype.member.member import create_member
class TestTaxExemption80GCertificate(unittest.TestCase):
def setUp(self):
frappe.db.sql('delete from `tabTax Exemption 80G Certificate`')
frappe.db.sql('delete from `tabMembership`')
create_donor_type()
settings = frappe.get_doc('Non Profit Settings')
settings.company = '_Test Company'
settings.donation_company = '_Test Company'
settings.default_donor_type = '_Test Donor'
settings.creation_user = 'Administrator'
settings.save()
company = frappe.get_doc('Company', '_Test Company')
company.pan_details = 'BBBTI3374C'
company.company_80g_number = 'NQ.CIT(E)I2018-19/DEL-IE28615-27062018/10087'
company.with_effect_from = getdate()
company.save()
def test_duplicate_donation_certificate(self):
donor = create_donor()
create_mode_of_payment()
payment = frappe._dict({
'amount': 100,
'method': 'Debit Card',
'id': 'pay_MeXAmsgeKOhq7O'
})
donation = create_donation(donor, payment)
args = frappe._dict({
'recipient': 'Donor',
'donor': donor.name,
'donation': donation.name
})
certificate = create_80g_certificate(args)
certificate.insert()
# check company details
self.assertEquals(certificate.company_pan_number, 'BBBTI3374C')
self.assertEquals(certificate.company_80g_number, 'NQ.CIT(E)I2018-19/DEL-IE28615-27062018/10087')
# check donation details
self.assertEquals(certificate.amount, donation.amount)
duplicate_certificate = create_80g_certificate(args)
# duplicate validation
self.assertRaises(frappe.ValidationError, duplicate_certificate.insert)
def test_membership_80g_certificate(self):
plan = setup_membership()
# make test member
member_doc = create_member(frappe._dict({
'fullname': "_Test_Member",
'email': "_test_member_erpnext@example.com",
'plan_id': plan.name
}))
member_doc.make_customer_and_link()
member = member_doc.name
membership = make_membership(member, { "from_date": getdate() })
invoice = membership.generate_invoice(save=True)
args = frappe._dict({
'recipient': 'Member',
'member': member,
'fiscal_year': get_fiscal_year(getdate(), as_dict=True).get('name')
})
certificate = create_80g_certificate(args)
certificate.get_payments()
certificate.insert()
self.assertEquals(len(certificate.payments), 1)
self.assertEquals(certificate.payments[0].amount, membership.amount)
self.assertEquals(certificate.payments[0].invoice_id, invoice.name)
def create_80g_certificate(args):
certificate = frappe.get_doc({
'doctype': 'Tax Exemption 80G Certificate',
'recipient': args.recipient,
'date': getdate(),
'company': '_Test Company'
})
certificate.update(args)
return certificate

View File

@@ -0,0 +1,66 @@
{
"actions": [],
"creation": "2021-02-15 12:43:52.754124",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"date",
"amount",
"invoice_id",
"column_break_4",
"razorpay_payment_id",
"membership"
],
"fields": [
{
"fieldname": "date",
"fieldtype": "Date",
"in_list_view": 1,
"label": "Date",
"reqd": 1
},
{
"fieldname": "amount",
"fieldtype": "Currency",
"in_list_view": 1,
"label": "Amount",
"reqd": 1
},
{
"fieldname": "invoice_id",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Invoice ID",
"options": "Sales Invoice",
"reqd": 1
},
{
"fieldname": "razorpay_payment_id",
"fieldtype": "Data",
"label": "Razorpay Payment ID"
},
{
"fieldname": "membership",
"fieldtype": "Link",
"label": "Membership",
"options": "Membership"
},
{
"fieldname": "column_break_4",
"fieldtype": "Column Break"
}
],
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2021-02-15 16:35:10.777587",
"modified_by": "Administrator",
"module": "Regional",
"name": "Tax Exemption 80G Certificate Detail",
"owner": "Administrator",
"permissions": [],
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}

View File

@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
# import frappe
from frappe.model.document import Document
class TaxExemption80GCertificateDetail(Document):
pass

View File

@@ -398,9 +398,9 @@ def make_custom_fields(update=True):
si_einvoice_fields = [
dict(fieldname='irn', label='IRN', fieldtype='Data', read_only=1, insert_after='customer', no_copy=1, print_hide=1,
depends_on='eval:in_list(["Registered Regular", "SEZ", "Overseas", "Deemed Export"], doc.gst_category) && doc.irn_cancelled === 0'),
dict(fieldname='ack_no', label='Ack. No.', fieldtype='Data', read_only=1, hidden=1, insert_after='irn', no_copy=1, print_hide=1),
dict(fieldname='ack_date', label='Ack. Date', fieldtype='Data', read_only=1, hidden=1, insert_after='ack_no', no_copy=1, print_hide=1),
dict(fieldname='irn_cancelled', label='IRN Cancelled', fieldtype='Check', no_copy=1, print_hide=1,
@@ -498,6 +498,14 @@ def make_custom_fields(update=True):
fieldtype='Link', options='Salary Component', insert_after='basic_component'),
dict(fieldname='arrear_component', label='Arrear Component',
fieldtype='Link', options='Salary Component', insert_after='hra_component'),
dict(fieldname='non_profit_section', label='Non Profit Settings',
fieldtype='Section Break', insert_after='asset_received_but_not_billed', collapsible=1),
dict(fieldname='company_80g_number', label='80G Number',
fieldtype='Data', insert_after='non_profit_section'),
dict(fieldname='with_effect_from', label='80G With Effect From',
fieldtype='Date', insert_after='company_80g_number'),
dict(fieldname='pan_details', label='PAN Number',
fieldtype='Data', insert_after='with_effect_from')
],
'Employee Tax Exemption Declaration':[
dict(fieldname='hra_section', label='HRA Exemption',
@@ -580,7 +588,15 @@ def make_custom_fields(update=True):
'options': '\nWith Payment of Tax\nWithout Payment of Tax'
}
],
"Member": [
'Member': [
{
'fieldname': 'pan_number',
'label': 'PAN Details',
'fieldtype': 'Data',
'insert_after': 'email_id'
}
],
'Donor': [
{
'fieldname': 'pan_number',
'label': 'PAN Details',
@@ -642,7 +658,7 @@ def set_tax_withholding_category(company):
pass
docs = get_tds_details(accounts, fiscal_year)
for d in docs:
try:
doc = frappe.get_doc(d)
@@ -660,7 +676,7 @@ def set_tax_withholding_category(company):
fy_exist = [k for k in doc.get('rates') if k.get('fiscal_year')==fiscal_year]
if not fy_exist:
doc.append("rates", d.get('rates')[0])
doc.flags.ignore_permissions = True
doc.flags.ignore_mandatory = True
doc.save()

View File

@@ -0,0 +1,26 @@
{
"absolute_value": 0,
"align_labels_right": 0,
"creation": "2021-02-22 00:17:33.878581",
"css": ".details {\n font-size: 15px;\n font-family: Tahoma, sans-serif;;\n line-height: 150%;\n}\n\n.certificate-footer {\n font-size: 15px;\n font-family: Tahoma, sans-serif;\n line-height: 140%;\n margin-top: 120px;\n}\n\n.company-address {\n color: #666666;\n font-size: 15px;\n font-family: Tahoma, sans-serif;;\n}",
"custom_format": 1,
"default_print_language": "en",
"disabled": 0,
"doc_type": "Tax Exemption 80G Certificate",
"docstatus": 0,
"doctype": "Print Format",
"font": "Default",
"html": "{% if letter_head and not no_letterhead -%}\n <div class=\"letter-head\">{{ letter_head }}</div>\n{%- endif %}\n\n<div>\n <h3 class=\"text-center\">{{ doc.company }} 80G Donor Certificate</h3>\n</div>\n<br><br>\n\n<div class=\"details\">\n <p> <b>{{ _(\"Certificate No. : \") }}</b> {{ doc.name }} </p>\n <p>\n \t<b>{{ _(\"Date\") }} :</b> {{ doc.get_formatted(\"date\") }}<br>\n </p>\n <br><br>\n \n <div>\n\n This is to confirm that the {{ doc.company }} received an amount of <b>{{doc.get_formatted(\"amount\")}}</b>\n from <b>{{ doc.donor_name }}</b>\n {% if doc.pan_number -%}\n bearing PAN Number {{ doc.member_pan_number }}\n {%- endif %}\n\n via the Mode of Payment {{doc.mode_of_payment}}\n\n {% if doc.razorpay_payment_id -%}\n bearing RazorPay Payment ID {{ doc.razorpay_payment_id }}\n {%- endif %}\n\n on {{ doc.get_formatted(\"date_of_donation\") }}\n <br><br>\n \n <p>\n We thank you for your contribution towards the corpus of the {{ doc.company }} and helping support our work.\n </p>\n\n </div>\n</div>\n\n<br><br>\n<p class=\"company-address text-left\"> {{doc.company_address_display }}</p>\n\n<div class=\"certificate-footer text-center\">\n <p><i>Computer generated receipt - Does not require signature</i></p><br>\n \n {% if doc.company_pan_number %}\n <p>\n <b>{{ doc.company }}'s PAN Account No :</b> {{ doc.company_pan_number }}\n <p><br>\n {% endif %}\n \n <p>\n <b>80G Number : </b> {{ doc.company_80g_number }}\n {% if doc.company_80g_wef %}\n ( w.e.f. {{ doc.get_formatted('company_80g_wef') }} )\n {% endif %}\n </p><br>\n</div>",
"idx": 0,
"line_breaks": 0,
"modified": "2021-02-22 00:20:08.516600",
"modified_by": "Administrator",
"module": "Regional",
"name": "80G Certificate for Donation",
"owner": "Administrator",
"print_format_builder": 0,
"print_format_type": "Jinja",
"raw_printing": 0,
"show_section_headings": 0,
"standard": "Yes"
}

View File

@@ -0,0 +1,26 @@
{
"absolute_value": 0,
"align_labels_right": 0,
"creation": "2021-02-15 16:53:55.026611",
"css": ".details {\n font-size: 15px;\n font-family: Tahoma, sans-serif;;\n line-height: 150%;\n}\n\n.certificate-footer {\n font-size: 15px;\n font-family: Tahoma, sans-serif;\n line-height: 140%;\n margin-top: 120px;\n}\n\n.company-address {\n color: #666666;\n font-size: 15px;\n font-family: Tahoma, sans-serif;;\n}",
"custom_format": 1,
"default_print_language": "en",
"disabled": 0,
"doc_type": "Tax Exemption 80G Certificate",
"docstatus": 0,
"doctype": "Print Format",
"font": "Default",
"html": "{% if letter_head and not no_letterhead -%}\n <div class=\"letter-head\">{{ letter_head }}</div>\n{%- endif %}\n\n<div>\n <h3 class=\"text-center\">{{ doc.company }} Members 80G Donor Certificate</h3>\n <h3 class=\"text-center\">Financial Cycle {{ doc.fiscal_year }}</h3>\n</div>\n<br><br>\n\n<div class=\"details\">\n <p> <b>{{ _(\"Certificate No. : \") }}</b> {{ doc.name }} </p>\n <p>\n \t<b>{{ _(\"Date\") }} :</b> {{ doc.get_formatted(\"date\") }}<br>\n </p>\n <br><br>\n \n <div>\n This is to confirm that the {{ doc.company }} received a total amount of <b>{{doc.get_formatted(\"total\")}}</b>\n from <b>{{ doc.member_name }}</b>\n {% if doc.pan_number -%}\n bearing PAN Number {{ doc.member_pan_number }}\n {%- endif %}\n as per the payment details given below:\n \n <br><br>\n <table class=\"table table-bordered table-condensed\">\n \t<thead>\n \t\t<tr>\n \t\t\t<th >{{ _(\"Date\") }}</th>\n \t\t\t<th class=\"text-right\">{{ _(\"Amount\") }}</th>\n \t\t\t<th class=\"text-right\">{{ _(\"Invoice ID\") }}</th>\n \t\t</tr>\n \t</thead>\n \t<tbody>\n \t\t{%- for payment in doc.payments -%}\n \t\t<tr>\n \t\t\t<td> {{ payment.date }} </td>\n \t\t\t<td class=\"text-right\">{{ payment.get_formatted(\"amount\") }}</td>\n \t\t\t<td class=\"text-right\">{{ payment.invoice_id }}</td>\n \t\t</tr>\n \t\t{%- endfor -%}\n \t</tbody>\n </table>\n \n <br>\n \n <p>\n We thank you for your contribution towards the corpus of the {{ doc.company }} and helping support our work.\n </p>\n\n </div>\n</div>\n\n<br><br>\n<p class=\"company-address text-left\"> {{doc.company_address_display }}</p>\n\n<div class=\"certificate-footer text-center\">\n <p><i>Computer generated receipt - Does not require signature</i></p><br>\n \n {% if doc.company_pan_number %}\n <p>\n <b>{{ doc.company }}'s PAN Account No :</b> {{ doc.company_pan_number }}\n <p><br>\n {% endif %}\n \n <p>\n <b>80G Number : </b> {{ doc.company_80g_number }}\n {% if doc.company_80g_wef %}\n ( w.e.f. {{ doc.get_formatted('company_80g_wef') }} )\n {% endif %}\n </p><br>\n</div>",
"idx": 0,
"line_breaks": 0,
"modified": "2021-02-21 23:29:00.778973",
"modified_by": "Administrator",
"module": "Regional",
"name": "80G Certificate for Membership",
"owner": "Administrator",
"print_format_builder": 0,
"print_format_type": "Jinja",
"raw_printing": 0,
"show_section_headings": 0,
"standard": "Yes"
}