diff --git a/erpnext/patches.txt b/erpnext/patches.txt index dcf626995bc..c97bb3c59c1 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -758,3 +758,4 @@ erpnext.patches.v13_0.rename_membership_settings_to_non_profit_settings erpnext.patches.v12_0.create_taxable_value_field erpnext.patches.v12_0.add_company_link_to_einvoice_settings erpnext.patches.v13_0.update_payment_terms_outstanding +erpnext.patches.v12_0.create_itc_reversal_custom_fields #1 \ No newline at end of file diff --git a/erpnext/patches/v12_0/create_itc_reversal_custom_fields.py b/erpnext/patches/v12_0/create_itc_reversal_custom_fields.py new file mode 100644 index 00000000000..80c47c236f0 --- /dev/null +++ b/erpnext/patches/v12_0/create_itc_reversal_custom_fields.py @@ -0,0 +1,33 @@ +from __future__ import unicode_literals +import frappe +from frappe.custom.doctype.custom_field.custom_field import create_custom_fields +from frappe.custom.doctype.property_setter.property_setter import make_property_setter + +def execute(): + company = frappe.get_all('Company', filters = {'country': 'India'}) + if not company: + return + + journal_entry_types = frappe.get_meta("Journal Entry").get_options("voucher_type").split("\n") + ['Reversal Of ITC'] + make_property_setter('Journal Entry', 'voucher_type', 'options', '\n'.join(journal_entry_types), '') + + custom_fields = { + 'Journal Entry': [ + dict(fieldname='reversal_type', label='Reversal Type', + fieldtype='Select', insert_after='voucher_type', print_hide=1, + options="As per rules 42 & 43 of CGST Rules\nOthers", + depends_on="eval:doc.voucher_type=='Reversal Of ITC'", + mandatory_depends_on="eval:doc.voucher_type=='Reversal Of ITC'"), + dict(fieldname='company_address', label='Company Address', + fieldtype='Link', options='Address', insert_after='reversal_type', + print_hide=1, depends_on="eval:doc.voucher_type=='Reversal Of ITC'", + mandatory_depends_on="eval:doc.voucher_type=='Reversal Of ITC'"), + dict(fieldname='company_gstin', label='Company GSTIN', + fieldtype='Data', read_only=1, insert_after='company_address', print_hide=1, + fetch_from='company_address.gstin', + depends_on="eval:doc.voucher_type=='Reversal Of ITC'", + mandatory_depends_on="eval:doc.voucher_type=='Reversal Of ITC'") + ] + } + + create_custom_fields(custom_fields, update=True) \ No newline at end of file diff --git a/erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.py b/erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.py index a49996d107e..f4e8ae085a2 100644 --- a/erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.py +++ b/erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.py @@ -166,7 +166,7 @@ class GSTR3BReport(Document): inward_nil_exempt = self.get_inward_nil_exempt(self.gst_details.get("gst_state")) self.set_inter_state_supply(inter_state_supplies) self.set_inward_nil_exempt(inward_nil_exempt) - + self.get_itc_reversal_entries() self.missing_field_invoices = self.get_missing_field_invoices() self.json_output = frappe.as_json(self.report_dict) @@ -251,6 +251,32 @@ class GSTR3BReport(Document): if key[0] == "UIN Holders": self.report_dict["inter_sup"]["uin_details"].append(value) + def get_itc_reversal_entries(self): + reversal_entries = frappe.db.sql(""" select ja.account, j.reversal_type, sum(credit_in_account_currency) as amount + from `tabJournal Entry` j, `tabJournal Entry Account` ja + where j.docstatus = 1 + and ja.parent = j.name + and j.voucher_type = 'Reversal Of ITC' + and month(j.posting_date) = %s and year(j.posting_date) = %s + and j.company = %s and j.company_gstin = %s + group by ja.account, j.reversal_type""", (self.month_no, self.year, self.company, + self.gst_details.get("gstin")), as_dict=1) + + for entry in reversal_entries: + if entry.reversal_type == 'As per rules 42 & 43 of CGST Rules': + index = 0 + else: + index = 1 + + if entry.account in [a.cgst_account for a in self.account_heads]: + self.report_dict["itc_elg"]["itc_rev"][index]["camt"] += flt(entry.amount) + if entry.account in [a.sgst_account for a in self.account_heads]: + self.report_dict["itc_elg"]["itc_rev"][index]["samt"] += flt(entry.amount) + if entry.account in [a.igst_account for a in self.account_heads]: + self.report_dict["itc_elg"]["itc_rev"][index]["iamt"] += flt(entry.amount) + if entry.account in [a.cess_account for a in self.account_heads]: + self.report_dict["itc_elg"]["itc_rev"][index]["csamt"] += flt(entry.amount) + def get_total_taxable_value(self, doctype, reverse_charge): return frappe._dict(frappe.db.sql(""" diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py index dd883b457f3..1839bbe1222 100644 --- a/erpnext/regional/india/setup.py +++ b/erpnext/regional/india/setup.py @@ -105,8 +105,17 @@ def add_print_formats(): frappe.reload_doc("accounts", "print_format", "gst_pos_invoice") frappe.reload_doc("accounts", "print_format", "GST E-Invoice") - frappe.db.sql(""" update `tabPrint Format` set disabled = 0 where - name in('GST POS Invoice', 'GST Tax Invoice', 'GST E-Invoice') """) + frappe.db.set_value("Print Format", "GST POS Invoice", "disabled", 0) + frappe.db.set_value("Print Format", "GST Tax Invoice", "disabled", 0) + frappe.db.set_value("Print Format", "GST E-Invoice", "disabled", 0) + +def make_property_setters(): + # GST rules do not allow for an invoice no. bigger than 16 characters + journal_entry_types = frappe.get_meta("Journal Entry").get_options("voucher_type").split("\n") + ['Reversal Of ITC'] + + make_property_setter('Sales Invoice', 'naming_series', 'options', 'SINV-.YY.-\nSRET-.YY.-', '') + make_property_setter('Purchase Invoice', 'naming_series', 'options', 'PINV-.YY.-\nPRET-.YY.-', '') + make_property_setter('Journal Entry', 'voucher_type', 'options', '\n'.join(journal_entry_types), '') def make_custom_fields(update=True): hsn_sac_field = dict(fieldname='gst_hsn_code', label='HSN/SAC', @@ -219,6 +228,23 @@ def make_custom_fields(update=True): depends_on="eval:doc.gst_category=='Overseas' "), ] + journal_entry_fields = [ + dict(fieldname='reversal_type', label='Reversal Type', + fieldtype='Select', insert_after='voucher_type', print_hide=1, + options="As per rules 42 & 43 of CGST Rules\nOthers", + depends_on="eval:doc.voucher_type=='Reversal Of ITC'", + mandatory_depends_on="eval:doc.voucher_type=='Reversal Of ITC'"), + dict(fieldname='company_address', label='Company Address', + fieldtype='Link', options='Address', insert_after='reversal_type', + print_hide=1, depends_on="eval:doc.voucher_type=='Reversal Of ITC'", + mandatory_depends_on="eval:doc.voucher_type=='Reversal Of ITC'"), + dict(fieldname='company_gstin', label='Company GSTIN', + fieldtype='Data', read_only=1, insert_after='company_address', print_hide=1, + fetch_from='company_address.gstin', + depends_on="eval:doc.voucher_type=='Reversal Of ITC'", + mandatory_depends_on="eval:doc.voucher_type=='Reversal Of ITC'") + ] + inter_state_gst_field = [ dict(fieldname='is_inter_state', label='Is Inter State', fieldtype='Check', insert_after='disabled', print_hide=1), @@ -433,6 +459,7 @@ def make_custom_fields(update=True): 'Purchase Receipt': purchase_invoice_gst_fields, 'Sales Invoice': sales_invoice_gst_category + invoice_gst_fields + sales_invoice_shipping_fields + sales_invoice_gst_fields + si_ewaybill_fields + si_einvoice_fields, 'Delivery Note': sales_invoice_gst_fields + ewaybill_fields + sales_invoice_shipping_fields, + 'Journal Entry': journal_entry_fields, 'Sales Order': sales_invoice_gst_fields, 'Tax Category': inter_state_gst_field, 'Item': [