diff --git a/erpnext/accounts/doctype/gst_account/gst_account.json b/erpnext/accounts/doctype/gst_account/gst_account.json
index 70673387fe8..b6ec8844e18 100644
--- a/erpnext/accounts/doctype/gst_account/gst_account.json
+++ b/erpnext/accounts/doctype/gst_account/gst_account.json
@@ -1,196 +1,82 @@
{
- "allow_copy": 0,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "beta": 0,
- "creation": "2018-01-02 15:48:58.768352",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "",
- "editable_grid": 1,
- "engine": "InnoDB",
+ "actions": [],
+ "creation": "2018-01-02 15:48:58.768352",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "company",
+ "cgst_account",
+ "sgst_account",
+ "igst_account",
+ "cess_account",
+ "is_reverse_charge_account"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "company",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Company",
- "length": 0,
- "no_copy": 0,
- "options": "Company",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
+ "columns": 1,
+ "fieldname": "company",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Company",
+ "options": "Company",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "cgst_account",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "CGST Account",
- "length": 0,
- "no_copy": 0,
- "options": "Account",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
+ "columns": 2,
+ "fieldname": "cgst_account",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "CGST Account",
+ "options": "Account",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "sgst_account",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "SGST Account",
- "length": 0,
- "no_copy": 0,
- "options": "Account",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
+ "columns": 2,
+ "fieldname": "sgst_account",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "SGST Account",
+ "options": "Account",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "igst_account",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "IGST Account",
- "length": 0,
- "no_copy": 0,
- "options": "Account",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
+ "columns": 2,
+ "fieldname": "igst_account",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "IGST Account",
+ "options": "Account",
+ "reqd": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "cess_account",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "CESS Account",
- "length": 0,
- "no_copy": 0,
- "options": "Account",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
+ "columns": 2,
+ "fieldname": "cess_account",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "CESS Account",
+ "options": "Account"
+ },
+ {
+ "columns": 1,
+ "default": "0",
+ "fieldname": "is_reverse_charge_account",
+ "fieldtype": "Check",
+ "in_list_view": 1,
+ "label": "Is Reverse Charge Account"
}
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 0,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 1,
- "max_attachments": 0,
- "modified": "2018-01-02 15:52:22.335988",
- "modified_by": "Administrator",
- "module": "Accounts",
- "name": "GST Account",
- "name_case": "",
- "owner": "Administrator",
- "permissions": [],
- "quick_entry": 1,
- "read_only": 0,
- "read_only_onload": 0,
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1,
- "track_seen": 0
+ ],
+ "index_web_pages_for_search": 1,
+ "istable": 1,
+ "links": [],
+ "modified": "2021-04-09 12:30:25.889993",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "GST Account",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
}
\ No newline at end of file
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 7496e3a6000..dae9a00b383 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -260,7 +260,7 @@ doc_events = {
},
"Purchase Invoice": {
"validate": [
- "erpnext.regional.india.utils.update_grand_total_for_rcm",
+ "erpnext.regional.india.utils.validate_reverse_charge_transaction",
"erpnext.regional.united_arab_emirates.utils.update_grand_total_for_rcm",
"erpnext.regional.united_arab_emirates.utils.validate_returns"
]
@@ -406,7 +406,6 @@ regional_overrides = {
'erpnext.controllers.taxes_and_totals.get_regional_round_off_accounts': 'erpnext.regional.india.utils.get_regional_round_off_accounts',
'erpnext.hr.utils.calculate_annual_eligible_hra_exemption': 'erpnext.regional.india.utils.calculate_annual_eligible_hra_exemption',
'erpnext.hr.utils.calculate_hra_exemption_for_period': 'erpnext.regional.india.utils.calculate_hra_exemption_for_period',
- 'erpnext.accounts.doctype.purchase_invoice.purchase_invoice.make_regional_gl_entries': 'erpnext.regional.india.utils.make_regional_gl_entries',
'erpnext.controllers.accounts_controller.validate_einvoice_fields': 'erpnext.regional.india.e_invoice.utils.validate_einvoice_fields'
},
'United Arab Emirates': {
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index c97bb3c59c1..eab8c76cb65 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -758,4 +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
+erpnext.patches.v12_0.create_itc_reversal_custom_fields #1
diff --git a/erpnext/patches/v12_0/create_itc_reversal_custom_fields.py b/erpnext/patches/v12_0/create_itc_reversal_custom_fields.py
index 80c47c236f0..0d06a5ceb3c 100644
--- a/erpnext/patches/v12_0/create_itc_reversal_custom_fields.py
+++ b/erpnext/patches/v12_0/create_itc_reversal_custom_fields.py
@@ -27,6 +27,11 @@ def execute():
fetch_from='company_address.gstin',
depends_on="eval:doc.voucher_type=='Reversal Of ITC'",
mandatory_depends_on="eval:doc.voucher_type=='Reversal Of ITC'")
+ ],
+ 'Purchase Invoice': [
+ dict(fieldname='eligibility_for_itc', label='Eligibility For ITC',
+ fieldtype='Select', insert_after='reason_for_issuing_document', print_hide=1,
+ options='Input Service Distributor\nImport Of Service\nImport Of Capital Goods\nITC on Reverse Charge\nIneligible\nAll Other ITC', default="All Other ITC")
]
}
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 f4e8ae085a2..d27ab20aab0 100644
--- a/erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.py
+++ b/erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.py
@@ -183,6 +183,7 @@ class GSTR3BReport(Document):
itc_type_map = {
'IMPG': 'Import Of Capital Goods',
'IMPS': 'Import Of Service',
+ 'ISRC': 'ITC on Reverse Charge',
'ISD': 'Input Service Distributor',
'OTH': 'All Other ITC'
}
@@ -198,7 +199,7 @@ class GSTR3BReport(Document):
itc_type = 'All Other ITC'
gst_category = ['Unregistered', 'Overseas']
else:
- gst_category = ['Unregistered', 'Overseas', 'Registered Regular']
+ gst_category = ['Overseas', 'Registered Regular']
reverse_charge = ["N", "Y"]
for account_head in self.account_heads:
diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py
index 1839bbe1222..8bcc36b05a4 100644
--- a/erpnext/regional/india/setup.py
+++ b/erpnext/regional/india/setup.py
@@ -190,7 +190,7 @@ def make_custom_fields(update=True):
purchase_invoice_itc_fields = [
dict(fieldname='eligibility_for_itc', label='Eligibility For ITC',
fieldtype='Select', insert_after='reason_for_issuing_document', print_hide=1,
- options='Input Service Distributor\nImport Of Service\nImport Of Capital Goods\nIneligible\nAll Other ITC', default="All Other ITC"),
+ options='Input Service Distributor\nImport Of Service\nImport Of Capital Goods\nITC on Reverse Charge\nIneligible\nAll Other ITC', default="All Other ITC"),
dict(fieldname='itc_integrated_tax', label='Availed ITC Integrated Tax',
fieldtype='Data', insert_after='eligibility_for_itc', print_hide=1),
dict(fieldname='itc_central_tax', label='Availed ITC Central Tax',
diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py
index 4a93cfd1ed6..b2687473420 100644
--- a/erpnext/regional/india/utils.py
+++ b/erpnext/regional/india/utils.py
@@ -674,10 +674,17 @@ def validate_state_code(state_code, address):
return int(state_code)
@frappe.whitelist()
-def get_gst_accounts(company, account_wise=False):
+def get_gst_accounts(company, account_wise=False, only_reverse_charge=0, only_non_reverse_charge=0):
+ filters={"parent": "GST Settings", "company": company}
+
+ if only_reverse_charge:
+ filters.update({'is_reverse_charge_account': 1})
+ elif only_non_reverse_charge:
+ filters.update({'is_reverse_charge_account': 0})
+
gst_accounts = frappe._dict()
gst_settings_accounts = frappe.get_all("GST Account",
- filters={"parent": "GST Settings", "company": company},
+ filters=filters,
fields=["cgst_account", "sgst_account", "igst_account", "cess_account"])
if not gst_settings_accounts and not frappe.flags.in_test:
@@ -692,105 +699,37 @@ def get_gst_accounts(company, account_wise=False):
return gst_accounts
-def update_grand_total_for_rcm(doc, method):
+def validate_reverse_charge_transaction(doc, method):
country = frappe.get_cached_value('Company', doc.company, 'country')
if country != 'India':
return
- gst_tax, base_gst_tax = get_gst_tax_amount(doc)
-
- if not base_gst_tax:
- return
+ base_gst_tax = 0
+ base_reverse_charge_booked = 0
if doc.reverse_charge == 'Y':
- doc.taxes_and_charges_added -= gst_tax
- doc.total_taxes_and_charges -= gst_tax
- doc.base_taxes_and_charges_added -= base_gst_tax
- doc.base_total_taxes_and_charges -= base_gst_tax
+ gst_accounts = get_gst_accounts(doc.company, only_reverse_charge=1)
+ reverse_charge_accounts = gst_accounts.get('cgst_account') + gst_accounts.get('sgst_account') \
+ + gst_accounts.get('igst_account')
- update_totals(gst_tax, base_gst_tax, doc)
-
-def update_totals(gst_tax, base_gst_tax, doc):
- doc.base_grand_total -= base_gst_tax
- doc.grand_total -= gst_tax
-
- if doc.meta.get_field("rounded_total"):
- if doc.is_rounded_total_disabled():
- doc.outstanding_amount = doc.grand_total
- else:
- doc.rounded_total = round_based_on_smallest_currency_fraction(doc.grand_total,
- doc.currency, doc.precision("rounded_total"))
-
- doc.rounding_adjustment += flt(doc.rounded_total - doc.grand_total,
- doc.precision("rounding_adjustment"))
-
- doc.outstanding_amount = doc.rounded_total or doc.grand_total
-
- doc.in_words = money_in_words(doc.grand_total, doc.currency)
- doc.base_in_words = money_in_words(doc.base_grand_total, erpnext.get_company_currency(doc.company))
- doc.set_payment_schedule()
-
-def make_regional_gl_entries(gl_entries, doc):
- country = frappe.get_cached_value('Company', doc.company, 'country')
-
- if country != 'India':
- return gl_entries
-
- gst_tax, base_gst_tax = get_gst_tax_amount(doc)
-
- if not base_gst_tax:
- return gl_entries
-
- if doc.reverse_charge == 'Y':
- gst_accounts = get_gst_accounts(doc.company)
- gst_account_list = gst_accounts.get('cgst_account') + gst_accounts.get('sgst_account') \
+ gst_accounts = get_gst_accounts(doc.company, only_non_reverse_charge=1)
+ non_reverse_charge_accounts = gst_accounts.get('cgst_account') + gst_accounts.get('sgst_account') \
+ gst_accounts.get('igst_account')
for tax in doc.get('taxes'):
- if tax.category not in ("Total", "Valuation and Total"):
- continue
-
- dr_or_cr = "credit" if tax.add_deduct_tax == "Add" else "debit"
- if flt(tax.base_tax_amount_after_discount_amount) and tax.account_head in gst_account_list:
- account_currency = get_account_currency(tax.account_head)
-
- gl_entries.append(doc.get_gl_dict(
- {
- "account": tax.account_head,
- "cost_center": tax.cost_center,
- "posting_date": doc.posting_date,
- "against": doc.supplier,
- dr_or_cr: tax.base_tax_amount_after_discount_amount,
- dr_or_cr + "_in_account_currency": tax.base_tax_amount_after_discount_amount \
- if account_currency==doc.company_currency \
- else tax.tax_amount_after_discount_amount
- }, account_currency, item=tax)
- )
-
- return gl_entries
-
-def get_gst_tax_amount(doc):
- gst_accounts = get_gst_accounts(doc.company)
- gst_account_list = gst_accounts.get('cgst_account', []) + gst_accounts.get('sgst_account', []) \
- + gst_accounts.get('igst_account', [])
-
- base_gst_tax = 0
- gst_tax = 0
-
- for tax in doc.get('taxes'):
- if tax.category not in ("Total", "Valuation and Total"):
- continue
-
- if flt(tax.base_tax_amount_after_discount_amount) and tax.account_head in gst_account_list:
- if tax.add_deduct_tax == "Add":
+ if tax.account_head in non_reverse_charge_accounts and tax.add_deduct_tax == 'Add':
base_gst_tax += tax.base_tax_amount_after_discount_amount
- gst_tax += tax.tax_amount_after_discount_amount
- else:
- base_gst_tax -= tax.base_tax_amount_after_discount_amount
- gst_tax -= tax.tax_amount_after_discount_amount
+ elif tax.account_head in reverse_charge_accounts and tax.add_deduct_tax == 'Deduct':
+ base_reverse_charge_booked += tax.base_tax_amount_after_discount_amount
- return gst_tax, base_gst_tax
+ if base_gst_tax != base_reverse_charge_booked:
+ msg = _("Booked reverse charge is not equal to applied tax amount")
+ msg += "
"
+ msg += _("Please refer {gst_document_link} to learn more about how to setup and create reverse charge invoice").format(
+ gst_document_link='GST Documentation')
+
+ frappe.throw(msg)
@frappe.whitelist()
def get_regional_round_off_accounts(company, account_list):