From 98238d7c3456248611a1a5d62abaae7412f735e3 Mon Sep 17 00:00:00 2001 From: Sanket322 <113279972+Sanket322@users.noreply.github.com> Date: Mon, 3 Jun 2024 09:47:25 +0530 Subject: [PATCH] fix: ineligible ITC due to Pos value in GSTR3b (#2197) * fix: itc calculated for pos rule * fix: changes as per review * fix: make separate function for pos rule * fix: changes as per review * fix: None error handling * fix: changes as per review * fix: remove unrequired condition for ineligible transactions --------- Co-authored-by: ljain112 --- .../doctype/gstr_3b_report/gstr_3b_report.py | 8 +- .../report/gstr_3b_details/gstr_3b_details.py | 79 ++++++++++++++++--- 2 files changed, 75 insertions(+), 12 deletions(-) diff --git a/india_compliance/gst_india/doctype/gstr_3b_report/gstr_3b_report.py b/india_compliance/gst_india/doctype/gstr_3b_report/gstr_3b_report.py index b7c0c7cad5..db9c4e5916 100644 --- a/india_compliance/gst_india/doctype/gstr_3b_report/gstr_3b_report.py +++ b/india_compliance/gst_india/doctype/gstr_3b_report/gstr_3b_report.py @@ -123,7 +123,13 @@ def get_itc_reversal_entries(self): def update_itc_reversal_from_purchase_invoice(self): ineligible_credit = IneligibleITC( self.company, self.gst_details.get("gstin"), self.month_no, self.year - ).get_for_purchase_invoice(group_by="ineligibility_reason") + ).get_ineligible_itc_us_17_5_for_purchase(group_by="ineligibility_reason") + + ineligible_credit_due_to_pos = IneligibleITC( + self.company, self.gst_details.get("gstin"), self.month_no, self.year + ).get_ineligible_itc_due_to_pos_for_purchase(group_by="ineligibility_reason") + + ineligible_credit.extend(ineligible_credit_due_to_pos) return self.process_ineligible_credit(ineligible_credit) diff --git a/india_compliance/gst_india/report/gstr_3b_details/gstr_3b_details.py b/india_compliance/gst_india/report/gstr_3b_details/gstr_3b_details.py index 22827f6f4f..35a808298d 100644 --- a/india_compliance/gst_india/report/gstr_3b_details/gstr_3b_details.py +++ b/india_compliance/gst_india/report/gstr_3b_details/gstr_3b_details.py @@ -270,7 +270,7 @@ def get_itc_from_journal_entry(self): def get_ineligible_itc_from_purchase(self): ineligible_itc = IneligibleITC( self.company, self.company_gstin, self.filters.month, self.filters.year - ).get_for_purchase_invoice() + ).get_ineligible_itc_us_17_5_for_purchase() return self.process_ineligible_itc(ineligible_itc) @@ -286,10 +286,6 @@ def process_ineligible_itc(self, ineligible_itc): return [] for row in ineligible_itc.copy(): - if row.itc_classification == "ITC restricted due to PoS rules": - ineligible_itc.remove(row) - continue - for key in ["iamt", "camt", "samt", "csamt"]: row[key] = row[key] * -1 @@ -429,11 +425,15 @@ def __init__(self, company, gstin, month, year) -> None: self.year = year self.gst_accounts = get_escaped_gst_accounts(company, "Input") - def get_for_purchase_invoice(self, group_by="name"): + def get_ineligible_itc_us_17_5_for_purchase(self, group_by="name"): + """ + - Ineligible As Per Section 17(5) + - ITC restricted due to ineligible items in purchase invoice + """ ineligible_transactions = self.get_vouchers_with_gst_expense("Purchase Invoice") if not ineligible_transactions: - return + return [] pi = frappe.qb.DocType("Purchase Invoice") @@ -446,9 +446,10 @@ def get_for_purchase_invoice(self, group_by="name"): pi.name.as_("voucher_no"), pi.ineligibility_reason.as_("itc_classification"), ) - .where(IfNull(pi.ineligibility_reason, "") != "") + .where( + IfNull(pi.ineligibility_reason, "") == "Ineligible As Per Section 17(5)" + ) .where(pi.name.isin(ineligible_transactions)) - .where(pi.company_gstin != IfNull(pi.supplier_gstin, "")) .groupby(pi[group_by]) .run(as_dict=1) ) @@ -465,15 +466,71 @@ def get_for_purchase_invoice(self, group_by="name"): Sum(pi.itc_state_tax).as_("samt"), Sum(pi.itc_cess_amount).as_("csamt"), ) - .where(IfNull(pi.ineligibility_reason, "") != "") + .where( + IfNull(pi.ineligibility_reason, "") == "Ineligible As Per Section 17(5)" + ) .where(pi.name.isin(ineligible_transactions)) - .where(pi.company_gstin != IfNull(pi.supplier_gstin, "")) .groupby(pi[group_by]) .run(as_dict=1) ) return self.get_ineligible_credit(credit_availed, credit_available, group_by) + def get_ineligible_itc_due_to_pos_for_purchase(self, group_by="name"): + """ + - ITC restricted due to PoS rules + """ + ineligible_transactions = self.get_vouchers_with_gst_expense("Purchase Invoice") + + if not ineligible_transactions: + return [] + + pi = frappe.qb.DocType("Purchase Invoice") + taxes = frappe.qb.DocType("Purchase Taxes and Charges") + + # utility function + def get_tax_case_statement(account, alias): + return Sum( + Case() + .when( + taxes.account_head.isin(account), + taxes.base_tax_amount_after_discount_amount, + ) + .else_(0) + ).as_(alias) + + # Credit availed is not required as it will be always 0 for pos + + ineligible_credit = ( + frappe.qb.from_(pi) + .inner_join(taxes) + .on(pi.name == taxes.parent) + .select( + pi.name.as_("voucher_no"), + pi.posting_date, + pi.ineligibility_reason.as_("itc_classification"), + get_tax_case_statement([self.gst_accounts.igst_account], "iamt"), + get_tax_case_statement([self.gst_accounts.cgst_account], "camt"), + get_tax_case_statement([self.gst_accounts.sgst_account], "camt"), + get_tax_case_statement( + [ + self.gst_accounts.cess_account, + self.gst_accounts.cess_non_advol_account, + ], + "csamt", + ), + ) + .where(taxes.account_head.isin(list(self.gst_accounts.values()))) + .where( + IfNull(pi.ineligibility_reason, "") == "ITC restricted due to PoS rules" + ) + .where(pi.name.isin(ineligible_transactions)) + .groupby(pi[group_by]) + .run(as_dict=True) + ) + + return ineligible_credit + def get_for_bill_of_entry(self, group_by="name"): ineligible_transactions = self.get_vouchers_with_gst_expense("Bill of Entry")