Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: accounting automations for ineligible ITC #1168

Merged
merged 8 commits into from
Oct 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 53 additions & 9 deletions india_compliance/gst_india/constants/custom_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@
"options": "Account",
"insert_after": "default_finance_book",
},
{
"fieldname": "default_gst_expense_account",
"label": "Default GST Expense Account",
"fieldtype": "Link",
"options": "Account",
"insert_after": "default_customs_expense_account",
},
],
("Customer", "Supplier"): party_fields,
# Purchase Fields
Expand Down Expand Up @@ -308,6 +315,7 @@
"Sales Invoice Item",
"POS Invoice Item",
"Purchase Invoice Item",
"Purchase Receipt Item",
): [
{
"fieldname": "taxable_value",
Expand All @@ -320,6 +328,22 @@
"no_copy": 1,
},
],
(
"Supplier Quotation Item",
"Purchase Order Item",
"Purchase Receipt Item",
"Purchase Invoice Item",
): [
{
"fieldname": "is_ineligible_for_itc",
"label": "Is Ineligible for Input Tax Credit",
"fieldtype": "Check",
"fetch_from": "item_code.is_ineligible_for_itc",
"insert_after": "is_nil_exempt",
"fetch_if_empty": 1,
"print_hide": 1,
},
],
"Sales Invoice": [
{
"fieldname": "port_address",
Expand Down Expand Up @@ -377,24 +401,34 @@
"collapsible": 1,
},
{
"fieldname": "eligibility_for_itc",
"label": "Eligibility For ITC",
"fieldname": "itc_classification",
"label": "ITC Classification",
"fieldtype": "Select",
"insert_after": "gst_section",
"print_hide": 1,
"options": (
"Input Service Distributor\nImport Of Service\nImport Of"
" Goods\nITC on Reverse Charge\nIneligible As Per Section"
" 17(5)\nIneligible Others\nAll Other ITC"
" Goods\nITC on Reverse Charge\nAll Other ITC"
),
"default": "All Other ITC",
"translatable": 0,
},
{
"fieldname": "ineligibility_reason",
"label": "Reason for Ineligibility",
"fieldtype": "Select",
"insert_after": "itc_classification",
"options": (
"\nIneligible As Per Section 17(5)\nITC restricted due to PoS rules"
),
"read_only": 1,
"print_hide": 1,
},
{
"fieldname": "reconciliation_status",
"label": "Reconciliation Status",
"fieldtype": "Select",
"insert_after": "eligibility_for_itc",
"insert_after": "ineligibility_reason",
"print_hide": 1,
"options": ("\nNot Applicable\nReconciled\nUnreconciled\nIgnored"),
"no_copy": 1,
Expand All @@ -407,26 +441,29 @@
},
{
"fieldname": "itc_integrated_tax",
"label": "Availed ITC Integrated Tax",
"label": "Integrated Tax",
"fieldtype": "Currency",
"insert_after": "gst_col_break",
"options": "Company:company:default_currency",
"read_only": 1,
"print_hide": 1,
},
{
"fieldname": "itc_central_tax",
"label": "Availed ITC Central Tax",
"label": "Central Tax",
"fieldtype": "Currency",
"insert_after": "itc_integrated_tax",
"options": "Company:company:default_currency",
"read_only": 1,
"print_hide": 1,
},
{
"fieldname": "itc_state_tax",
"label": "Availed ITC State/UT Tax",
"label": "State/UT Tax",
"fieldtype": "Currency",
"insert_after": "itc_central_tax",
"options": "Company:company:default_currency",
"read_only": 1,
"print_hide": 1,
},
{
Expand All @@ -435,6 +472,7 @@
"fieldtype": "Currency",
"insert_after": "itc_state_tax",
"options": "Company:company:default_currency",
"read_only": 1,
"print_hide": 1,
},
],
Expand Down Expand Up @@ -584,7 +622,7 @@
],
"Journal Entry": [
{
"fieldname": "reversal_type",
"fieldname": "ineligibility_reason",
"label": "Reversal Type",
"fieldtype": "Select",
"insert_after": "voucher_type",
Expand Down Expand Up @@ -647,6 +685,12 @@
"fieldtype": "Check",
"insert_after": "is_nil_exempt",
},
{
"fieldname": "is_ineligible_for_itc",
"label": "Is Ineligible for Input Tax Credit",
"fieldtype": "Check",
"insert_after": "item_tax_section_break",
},
],
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,14 @@ frappe.ui.form.on("Bill of Entry", {
);
}

if (frm.doc.docstatus === 1 && frm.doc.total_customs_duty > 0) {
const has_ineligible_items = frm.doc.items.some(
item => item.is_ineligible_for_itc
);

if (
(frm.doc.docstatus === 1 && frm.doc.total_customs_duty > 0) ||
has_ineligible_items
) {
frm.add_custom_button(
__("Landed Cost Voucher"),
() => {
Expand Down
47 changes: 44 additions & 3 deletions india_compliance/gst_india/doctype/bill_of_entry/bill_of_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@
from frappe.model.mapper import get_mapped_doc
from frappe.utils import today
import erpnext
from erpnext.accounts.general_ledger import make_gl_entries
from erpnext.accounts.general_ledger import make_gl_entries, make_reverse_gl_entries
from erpnext.controllers.accounts_controller import AccountsController
from erpnext.controllers.taxes_and_totals import get_round_off_applicable_accounts

from india_compliance.gst_india.overrides.ineligible_itc import (
update_landed_cost_voucher_for_gst_expense,
update_regional_gl_entries,
update_valuation_rate,
)
from india_compliance.gst_india.utils import get_gst_accounts_by_type


Expand Down Expand Up @@ -45,13 +50,16 @@ def validate(self):
self.validate_purchase_invoice()
self.validate_taxes()
self.reconciliation_status = "Unreconciled"
update_valuation_rate(self)

def on_submit(self):
make_gl_entries(self.get_gl_entries())
gl_entries = self.get_gl_entries()
update_regional_gl_entries(gl_entries, self)
make_gl_entries(gl_entries)

def on_cancel(self):
self.ignore_linked_doctypes = ("GL Entry",)
make_gl_entries(self.get_gl_entries(), cancel=True)
make_reverse_gl_entries(voucher_type=self.doctype, voucher_no=self.name)

# Code adapted from AccountsController.on_trash
def on_trash(self):
Expand Down Expand Up @@ -305,6 +313,32 @@ def get_rows_to_update(self, item_name=None, tax_name=None):

return items, taxes

def get_stock_items(self):
stock_items = []
item_codes = list(set(item.item_code for item in self.get("items")))
if item_codes:
stock_items = frappe.db.get_values(
"Item",
{"name": ["in", item_codes], "is_stock_item": 1},
pluck="name",
cache=True,
)

return stock_items

def get_asset_items(self):
asset_items = []
item_codes = list(set(item.item_code for item in self.get("items")))
if item_codes:
asset_items = frappe.db.get_values(
"Item",
{"name": ["in", item_codes], "is_fixed_asset": 1},
pluck="name",
cache=True,
)

return asset_items


@frappe.whitelist()
def make_bill_of_entry(source_name, target_doc=None):
Expand Down Expand Up @@ -454,6 +488,7 @@ def set_missing_values(source, target):
for item in target.items:
item.applicable_charges = items[item.purchase_receipt_item].customs_duty
total_customs_duty += item.applicable_charges
item.boe_detail = items[item.purchase_receipt_item].boe_detail

# add taxes
target.append(
Expand All @@ -473,6 +508,8 @@ def set_missing_values(source, target):
)
)

update_landed_cost_voucher_for_gst_expense(source, target)

doc = get_mapped_doc(
"Bill of Entry",
source_name,
Expand Down Expand Up @@ -503,6 +540,7 @@ def get_items_for_landed_cost_voucher(boe):
"""
pi = frappe.get_doc("Purchase Invoice", boe.purchase_invoice)
item_customs_map = {item.pi_detail: item.customs_duty for item in boe.items}
item_name_map = {item.pi_detail: item.name for item in boe.items}

def _item_dict(items):
return frappe._dict({item.name: item for item in items})
Expand All @@ -512,6 +550,7 @@ def _item_dict(items):
pi_items = [pi_item.as_dict() for pi_item in pi.items]
for pi_item in pi_items:
pi_item.customs_duty = item_customs_map.get(pi_item.name)
pi_item.boe_detail = item_name_map.get(pi_item.name)

return _item_dict(pi_items)

Expand All @@ -526,6 +565,7 @@ def _item_dict(items):

for pr_item in pr_items:
pr_item.customs_duty = item_customs_map.get(pr_pi_map.get(pr_item.name))
pr_item.boe_detail = item_name_map.get(pr_pi_map.get(pr_item.name))

return _item_dict(pr_items)

Expand All @@ -542,5 +582,6 @@ def _item_dict(items):
customs_duty_for_item = item_customs_map.get(pr_item.purchase_invoice_item)
total_qty = item_qty_map.get(pr_item.purchase_invoice_item)
pr_item.customs_duty = customs_duty_for_item * pr_item.qty / total_qty
pr_item.boe_detail = item_name_map.get(pr_item.purchase_invoice_item)

return _item_dict(pr_items)
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"column_break_ifxl",
"taxable_value",
"item_tax_template",
"is_ineligible_for_itc",
"accounting_dimensions_section",
"cost_center",
"dimension_col_break",
Expand Down Expand Up @@ -106,12 +107,21 @@
"fieldtype": "Link",
"label": "Project",
"options": "Project"
},
{
"default": "0",
"fetch_from": "item_code.is_ineligible_for_itc",
"fetch_if_empty": 1,
"fieldname": "is_ineligible_for_itc",
"fieldtype": "Check",
"label": "Is Ineligible for Input Tax Credit",
"print_hide": 1
}
],
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2023-03-13 14:26:53.580618",
"modified": "2023-10-20 12:24:27.373448",
"modified_by": "Administrator",
"module": "GST India",
"name": "Bill of Entry Item",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ <h5>4. &nbsp {{__("Eligible ITC")}}</h5>
<td></td>
</tr>
<tr>
<td>&nbsp (1) {{__("As per rules 42 & 43 of CGST Rules")}}</td>
<td>&nbsp (1) {{__("As per rules 42 & 43 of CGST Rules and section 17(5)")}}</td>
<td class="right">{{ flt(data.itc_elg.itc_rev[0].iamt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_rev[0].camt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_rev[0].samt, 2) }}</td>
Expand Down Expand Up @@ -249,14 +249,14 @@ <h5>4. &nbsp {{__("Eligible ITC")}}</h5>
<td></td>
</tr>
<tr>
<td>&nbsp (1) {{__("As per section 17(5)")}}</td>
<td>&nbsp (1) {{__("ITC reclaimed which was reversed under Table 4(B)(2) in earlier tax period")}}</td>
<td class="right">{{ flt(data.itc_elg.itc_inelg[0].iamt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_inelg[0].camt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_inelg[0].samt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_inelg[0].csamt, 2) }}</td>
</tr>
<tr>
<td>&nbsp (2) {{__("Others")}}</td>
<td>&nbsp (2) {{__("Ineligible ITC under section 16(4) & ITC restricted due to PoS rules")}}</td>
<td class="right">{{ flt(data.itc_elg.itc_inelg[1].iamt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_inelg[1].camt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_inelg[1].samt, 2) }}</td>
Expand Down
Loading
Loading