From 3c004ad79880f023917017ec715da9b0e07b0b7b Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Thu, 2 Jul 2020 21:18:29 +0530 Subject: [PATCH 1/3] fix(GST): Do not add tax amount in grand total for reverse charge invoices --- .../purchase_invoice/purchase_invoice.py | 6 ++ .../purchase_invoice/regional/india.js | 30 ++++++++++ erpnext/accounts/general_ledger.py | 1 + erpnext/hooks.py | 5 +- erpnext/regional/india/utils.py | 59 +++++++++++++------ 5 files changed, 80 insertions(+), 21 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index 3cd57d403a..c701a7c9dd 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -438,6 +438,8 @@ class PurchaseInvoice(BuyingController): self.make_tax_gl_entries(gl_entries) + gl_entries = make_regional_gl_entries(gl_entries, self) + gl_entries = merge_similar_entries(gl_entries) self.make_payment_gl_entries(gl_entries) @@ -1097,6 +1099,10 @@ def get_list_context(context=None): }) return list_context +@erpnext.allow_regional +def make_regional_gl_entries(gl_entries, doc): + return gl_entries + @frappe.whitelist() def make_debit_note(source_name, target_doc=None): from erpnext.controllers.sales_and_purchase_return import make_return_doc diff --git a/erpnext/accounts/doctype/purchase_invoice/regional/india.js b/erpnext/accounts/doctype/purchase_invoice/regional/india.js index 81488a2c52..83cb03a77c 100644 --- a/erpnext/accounts/doctype/purchase_invoice/regional/india.js +++ b/erpnext/accounts/doctype/purchase_invoice/regional/india.js @@ -1,3 +1,33 @@ {% include "erpnext/regional/india/taxes.js" %} erpnext.setup_auto_gst_taxation('Purchase Invoice'); + + +frappe.ui.form.on('Purchase Taxes and Charges', { + taxes_add: function(frm) { + if (frm.doc.reverse_charge === 'Y') { + frappe.call({ + 'method': 'erpnext.regional.india.utils.get_gst_accounts', + 'args': { + company: frm.doc.company + }, + 'callback': function(r) { + let accounts = r.message; + let account_list = accounts['cgst_account'] + accounts['sgst_account'] + + accounts['igst_account'] + + let gst_tax = 0; + + $.each(frm.doc.taxes || [], function(i, row) { + if (account_list.includes(row.account_head)) { + gst_tax += row.base_tax_amount_after_discount_amount; + } + }); + + frm.doc.taxes_and_charges_added -= flt(gst_tax); + frm.refresh_field('taxes_and_charges_added'); + } + }) + } + } +}); diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py index bfe35ab006..a1f8c037b3 100644 --- a/erpnext/accounts/general_ledger.py +++ b/erpnext/accounts/general_ledger.py @@ -20,6 +20,7 @@ def make_gl_entries(gl_map, cancel=False, adv_adj=False, merge_entries=True, upd if not cancel: validate_accounting_period(gl_map) gl_map = process_gl_map(gl_map, merge_entries) + print(gl_map, "$$$$$$$$$") if gl_map and len(gl_map) > 1: save_entries(gl_map, adv_adj, update_outstanding) else: diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 835d92ef5c..89c5b7409d 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -246,7 +246,7 @@ doc_events = { "on_trash": "erpnext.regional.check_deletion_permission" }, "Purchase Invoice": { - "on_submit": "erpnext.regional.india.utils.make_reverse_charge_entries" + "validate": "erpnext.regional.india.utils.update_grand_total_for_rcm" }, "Payment Entry": { "on_submit": ["erpnext.regional.create_transaction_log", "erpnext.accounts.doctype.payment_request.payment_request.update_payment_req_status"], @@ -374,7 +374,8 @@ regional_overrides = { 'erpnext.controllers.taxes_and_totals.get_itemised_tax_breakup_data': 'erpnext.regional.india.utils.get_itemised_tax_breakup_data', 'erpnext.accounts.party.get_regional_address_details': 'erpnext.regional.india.utils.get_regional_address_details', '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.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' }, 'United Arab Emirates': { 'erpnext.controllers.taxes_and_totals.update_itemised_tax_data': 'erpnext.regional.united_arab_emirates.utils.update_itemised_tax_data' diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py index 05ffa87f14..c6df1366d1 100644 --- a/erpnext/regional/india/utils.py +++ b/erpnext/regional/india/utils.py @@ -1,7 +1,7 @@ from __future__ import unicode_literals import frappe, re, json from frappe import _ -from frappe.utils import cstr, flt, date_diff, nowdate +from frappe.utils import cstr, flt, date_diff, nowdate, round_based_on_smallest_currency_fraction, money_in_words from erpnext.regional.india import states, state_numbers from erpnext.controllers.taxes_and_totals import get_itemised_tax, get_itemised_taxable_amount from erpnext.controllers.accounts_controller import get_taxes_and_charges @@ -644,6 +644,7 @@ def validate_state_code(state_code, address): else: return int(state_code) +@frappe.whitelist() def get_gst_accounts(company, account_wise=False): gst_accounts = frappe._dict() gst_settings_accounts = frappe.get_all("GST Account", @@ -662,14 +663,49 @@ def get_gst_accounts(company, account_wise=False): return gst_accounts -def make_reverse_charge_entries(doc, method): +def update_grand_total_for_rcm(doc, method): + 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('igst_account') + + 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: + gst_tax += tax.base_tax_amount_after_discount_amount + + doc.taxes_and_charges_added -= gst_tax + doc.total_taxes_and_charges -= gst_tax + + update_totals(gst_tax, doc) + +def update_totals(gst_tax, doc): + 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.base_rounded_total + + doc.in_words = money_in_words(doc.grand_total, doc.currency) + +def make_regional_gl_entries(gl_entries, doc): country = frappe.get_cached_value('Company', doc.company, 'country') if country != 'India': return if doc.reverse_charge == 'Y': - gl_entries = [] 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') @@ -694,19 +730,4 @@ def make_reverse_charge_entries(doc, method): }, account_currency, item=tax) ) - gl_entries.append(doc.get_gl_dict( - { - "account": doc.credit_to if doc.doctype == 'Purchase Invoice' else doc.debit_to, - "cost_center": doc.cost_center, - "posting_date": doc.posting_date, - "party_type": 'Supplier', - "party": doc.supplier, - "against": tax.account_head, - "debit": tax.base_tax_amount_after_discount_amount, - "debit_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=doc) - ) - - make_gl_entries(gl_entries) \ No newline at end of file + return gl_entries \ No newline at end of file From 9ed0384bea9d34b2eded39c336965281c4d127ea Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Fri, 3 Jul 2020 14:54:41 +0530 Subject: [PATCH 2/3] fix: Code cleanup --- .../purchase_invoice/regional/india.js | 30 ------------------- 1 file changed, 30 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/regional/india.js b/erpnext/accounts/doctype/purchase_invoice/regional/india.js index 83cb03a77c..81488a2c52 100644 --- a/erpnext/accounts/doctype/purchase_invoice/regional/india.js +++ b/erpnext/accounts/doctype/purchase_invoice/regional/india.js @@ -1,33 +1,3 @@ {% include "erpnext/regional/india/taxes.js" %} erpnext.setup_auto_gst_taxation('Purchase Invoice'); - - -frappe.ui.form.on('Purchase Taxes and Charges', { - taxes_add: function(frm) { - if (frm.doc.reverse_charge === 'Y') { - frappe.call({ - 'method': 'erpnext.regional.india.utils.get_gst_accounts', - 'args': { - company: frm.doc.company - }, - 'callback': function(r) { - let accounts = r.message; - let account_list = accounts['cgst_account'] + accounts['sgst_account'] - + accounts['igst_account'] - - let gst_tax = 0; - - $.each(frm.doc.taxes || [], function(i, row) { - if (account_list.includes(row.account_head)) { - gst_tax += row.base_tax_amount_after_discount_amount; - } - }); - - frm.doc.taxes_and_charges_added -= flt(gst_tax); - frm.refresh_field('taxes_and_charges_added'); - } - }) - } - } -}); From 05738bd29aa7b46f86a3f3b7da5d06d3fb571bc4 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 6 Jul 2020 13:40:48 +0530 Subject: [PATCH 3/3] fix: Remove print statements --- erpnext/accounts/general_ledger.py | 1 - 1 file changed, 1 deletion(-) diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py index a1f8c037b3..bfe35ab006 100644 --- a/erpnext/accounts/general_ledger.py +++ b/erpnext/accounts/general_ledger.py @@ -20,7 +20,6 @@ def make_gl_entries(gl_map, cancel=False, adv_adj=False, merge_entries=True, upd if not cancel: validate_accounting_period(gl_map) gl_map = process_gl_map(gl_map, merge_entries) - print(gl_map, "$$$$$$$$$") if gl_map and len(gl_map) > 1: save_entries(gl_map, adv_adj, update_outstanding) else: