Skip to content

Commit

Permalink
Merge pull request #27348 from deepeshgarg007/advance_tds_allocation_gl
Browse files Browse the repository at this point in the history
fix (refactor): Tax Withholding for Advances using Payment Entry against suppliers
  • Loading branch information
deepeshgarg007 authored Nov 26, 2021
2 parents ca8dec0 + 7f06c8c commit 38dfb60
Show file tree
Hide file tree
Showing 13 changed files with 201 additions and 151 deletions.
Empty file.
56 changes: 56 additions & 0 deletions erpnext/accounts/doctype/advance_tax/advance_tax.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"actions": [],
"allow_rename": 1,
"creation": "2021-11-25 10:24:39.836195",
"doctype": "DocType",
"engine": "InnoDB",
"field_order": [
"reference_type",
"reference_name",
"reference_detail",
"account_head",
"allocated_amount"
],
"fields": [
{
"fieldname": "reference_type",
"fieldtype": "Link",
"label": "Reference Type",
"options": "DocType"
},
{
"fieldname": "reference_name",
"fieldtype": "Dynamic Link",
"label": "Reference Name",
"options": "reference_type"
},
{
"fieldname": "reference_detail",
"fieldtype": "Data",
"label": "Reference Detail"
},
{
"fieldname": "account_head",
"fieldtype": "Link",
"label": "Account Head",
"options": "Account"
},
{
"fieldname": "allocated_amount",
"fieldtype": "Currency",
"label": "Allocated Amount",
"options": "party_account_currency"
}
],
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2021-11-25 10:27:51.712286",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Advance Tax",
"owner": "Administrator",
"permissions": [],
"sort_field": "modified",
"sort_order": "DESC"
}
9 changes: 9 additions & 0 deletions erpnext/accounts/doctype/advance_tax/advance_tax.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt

# import frappe
from frappe.model.document import Document


class AdvanceTax(Document):
pass
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@
"allocated_amount",
"column_break_13",
"base_tax_amount",
"base_total",
"base_allocated_amount"
"base_total"
],
"fields": [
{
Expand Down Expand Up @@ -168,12 +167,6 @@
"label": "Allocated Amount",
"options": "currency"
},
{
"fieldname": "base_allocated_amount",
"fieldtype": "Currency",
"label": "Allocated Amount (Company Currency)",
"options": "Company:company:default_currency"
},
{
"fetch_from": "account_head.account_currency",
"fieldname": "currency",
Expand All @@ -186,7 +179,7 @@
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2021-06-09 11:46:58.373170",
"modified": "2021-11-25 11:10:10.945027",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Advance Taxes and Charges",
Expand Down
12 changes: 1 addition & 11 deletions erpnext/accounts/doctype/payment_entry/payment_entry.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@
"taxes_and_charges_section",
"purchase_taxes_and_charges_template",
"sales_taxes_and_charges_template",
"advance_tax_account",
"column_break_55",
"apply_tax_withholding_amount",
"tax_withholding_category",
Expand Down Expand Up @@ -685,15 +684,6 @@
"fieldtype": "Section Break",
"hide_border": 1
},
{
"depends_on": "eval:doc.apply_tax_withholding_amount",
"description": "Provisional tax account for advance tax. Taxes are parked in this account until payments are allocated to invoices",
"fieldname": "advance_tax_account",
"fieldtype": "Link",
"label": "Advance Tax Account",
"mandatory_depends_on": "eval:doc.apply_tax_withholding_amount",
"options": "Account"
},
{
"depends_on": "eval:doc.received_amount && doc.payment_type != 'Internal Transfer'",
"fieldname": "received_amount_after_tax",
Expand Down Expand Up @@ -730,7 +720,7 @@
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2021-10-22 17:50:24.632806",
"modified": "2021-11-24 18:58:24.919764",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Entry",
Expand Down
45 changes: 12 additions & 33 deletions erpnext/accounts/doctype/payment_entry/payment_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category import (
get_party_tax_withholding_details,
)
from erpnext.accounts.general_ledger import make_gl_entries
from erpnext.accounts.general_ledger import make_gl_entries, process_gl_map
from erpnext.accounts.party import get_party_account
from erpnext.accounts.utils import get_account_currency, get_balance_on, get_outstanding_invoices
from erpnext.controllers.accounts_controller import (
Expand Down Expand Up @@ -433,23 +433,12 @@ def set_tax_withholding(self):
if not self.apply_tax_withholding_amount:
return

if not self.advance_tax_account:
frappe.throw(_("Advance TDS account is mandatory for advance TDS deduction"))

net_total = self.paid_amount

for reference in self.get("references"):
net_total_for_tds = 0
if reference.reference_doctype == 'Purchase Order':
net_total_for_tds += flt(frappe.db.get_value('Purchase Order', reference.reference_name, 'net_total'))

if net_total_for_tds:
net_total = net_total_for_tds

# Adding args as purchase invoice to get TDS amount
args = frappe._dict({
'company': self.company,
'doctype': 'Purchase Invoice',
'doctype': 'Payment Entry',
'supplier': self.party,
'posting_date': self.posting_date,
'net_total': net_total
Expand All @@ -461,7 +450,6 @@ def set_tax_withholding(self):
return

tax_withholding_details.update({
'add_deduct_tax': 'Add',
'cost_center': self.cost_center or erpnext.get_default_cost_center(self.company)
})

Expand Down Expand Up @@ -689,6 +677,7 @@ def make_gl_entries(self, cancel=0, adv_adj=0):
self.add_deductions_gl_entries(gl_entries)
self.add_tax_gl_entries(gl_entries)

gl_entries = process_gl_map(gl_entries)
make_gl_entries(gl_entries, cancel=cancel, adv_adj=adv_adj)

def add_party_gl_entries(self, gl_entries):
Expand Down Expand Up @@ -752,7 +741,8 @@ def add_bank_gl_entries(self, gl_entries):
"against": self.party if self.payment_type=="Pay" else self.paid_to,
"credit_in_account_currency": self.paid_amount,
"credit": self.base_paid_amount,
"cost_center": self.cost_center
"cost_center": self.cost_center,
"post_net_value": True
}, item=self)
)
if self.payment_type in ("Receive", "Internal Transfer"):
Expand Down Expand Up @@ -782,14 +772,10 @@ def add_tax_gl_entries(self, gl_entries):
rev_dr_or_cr = "credit" if dr_or_cr == "debit" else "debit"
against = self.party or self.paid_to

payment_or_advance_account = self.get_party_account_for_taxes()
payment_account = self.get_party_account_for_taxes()
tax_amount = d.tax_amount
base_tax_amount = d.base_tax_amount

if self.advance_tax_account:
tax_amount = -1 * tax_amount
base_tax_amount = -1 * base_tax_amount

gl_entries.append(
self.get_gl_dict({
"account": d.account_head,
Expand All @@ -798,19 +784,21 @@ def add_tax_gl_entries(self, gl_entries):
dr_or_cr + "_in_account_currency": base_tax_amount
if account_currency==self.company_currency
else d.tax_amount,
"cost_center": d.cost_center
"cost_center": d.cost_center,
"post_net_value": True,
}, account_currency, item=d))

if not d.included_in_paid_amount or self.advance_tax_account:
if not d.included_in_paid_amount:
gl_entries.append(
self.get_gl_dict({
"account": payment_or_advance_account,
"account": payment_account,
"against": against,
rev_dr_or_cr: tax_amount,
rev_dr_or_cr + "_in_account_currency": base_tax_amount
if account_currency==self.company_currency
else d.tax_amount,
"cost_center": self.cost_center,
"post_net_value": True,
}, account_currency, item=d))

def add_deductions_gl_entries(self, gl_entries):
Expand All @@ -832,9 +820,7 @@ def add_deductions_gl_entries(self, gl_entries):
)

def get_party_account_for_taxes(self):
if self.advance_tax_account:
return self.advance_tax_account
elif self.payment_type == 'Receive':
if self.payment_type == 'Receive':
return self.paid_to
elif self.payment_type in ('Pay', 'Internal Transfer'):
return self.paid_from
Expand Down Expand Up @@ -1599,13 +1585,6 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
})
pe.set_difference_amount()

if doc.doctype == 'Purchase Order' and doc.apply_tds:
pe.apply_tax_withholding_amount = 1
pe.tax_withholding_category = doc.tax_withholding_category

if not pe.advance_tax_account:
pe.advance_tax_account = frappe.db.get_value('Company', pe.company, 'unrealized_profit_loss_account')

return pe

def get_bank_cash_account(doc, bank_account):
Expand Down
11 changes: 10 additions & 1 deletion erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@
"allocate_advances_automatically",
"get_advances",
"advances",
"advance_tax",
"payment_schedule_section",
"payment_terms_template",
"ignore_default_payment_terms_template",
Expand Down Expand Up @@ -1408,13 +1409,21 @@
{
"fieldname": "column_break_147",
"fieldtype": "Column Break"
},
{
"fieldname": "advance_tax",
"fieldtype": "Table",
"hidden": 1,
"label": "Advance Tax",
"options": "Advance Tax",
"read_only": 1
}
],
"icon": "fa fa-file-text",
"idx": 204,
"is_submittable": 1,
"links": [],
"modified": "2021-10-12 20:55:16.145651",
"modified": "2021-11-25 13:31:02.716727",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice",
Expand Down
42 changes: 39 additions & 3 deletions erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,7 @@ def on_submit(self):

self.update_project()
update_linked_doc(self.doctype, self.name, self.inter_company_invoice_reference)
self.update_advance_tax_references()

self.process_common_party_accounting()

Expand Down Expand Up @@ -472,8 +473,6 @@ def get_gl_entries(self, warehouse_account=None):
self.make_exchange_gain_loss_gl_entries(gl_entries)
self.make_internal_transfer_gl_entries(gl_entries)

self.allocate_advance_taxes(gl_entries)

gl_entries = make_regional_gl_entries(gl_entries, self)

gl_entries = merge_similar_entries(gl_entries)
Expand Down Expand Up @@ -1074,6 +1073,7 @@ def on_cancel(self):

unlink_inter_company_doc(self.doctype, self.name, self.inter_company_invoice_reference)
self.ignore_linked_doctypes = ('GL Entry', 'Stock Ledger Entry', 'Repost Item Valuation')
self.update_advance_tax_references(cancel=1)

def update_project(self):
project_list = []
Expand Down Expand Up @@ -1150,7 +1150,10 @@ def set_tax_withholding(self):
if not self.tax_withholding_category:
return

tax_withholding_details = get_party_tax_withholding_details(self, self.tax_withholding_category)
tax_withholding_details, advance_taxes = get_party_tax_withholding_details(self, self.tax_withholding_category)

# Adjust TDS paid on advances
self.allocate_advance_tds(tax_withholding_details, advance_taxes)

if not tax_withholding_details:
return
Expand All @@ -1174,6 +1177,39 @@ def set_tax_withholding(self):
# calculate totals again after applying TDS
self.calculate_taxes_and_totals()

def allocate_advance_tds(self, tax_withholding_details, advance_taxes):
self.set('advance_tax', [])
for tax in advance_taxes:
allocated_amount = 0
pending_amount = flt(tax.tax_amount - tax.allocated_amount)
if flt(tax_withholding_details.get('tax_amount')) >= pending_amount:
tax_withholding_details['tax_amount'] -= pending_amount
allocated_amount = pending_amount
elif flt(tax_withholding_details.get('tax_amount')) and flt(tax_withholding_details.get('tax_amount')) < pending_amount:
allocated_amount = tax_withholding_details['tax_amount']
tax_withholding_details['tax_amount'] = 0

self.append('advance_tax', {
'reference_type': 'Payment Entry',
'reference_name': tax.parent,
'reference_detail': tax.name,
'account_head': tax.account_head,
'allocated_amount': allocated_amount
})

def update_advance_tax_references(self, cancel=0):
for tax in self.get('advance_tax'):
at = frappe.qb.DocType("Advance Taxes and Charges").as_("at")

if cancel:
frappe.qb.update(at).set(
at.allocated_amount, at.allocated_amount - tax.allocated_amount
).where(at.name == tax.reference_detail).run()
else:
frappe.qb.update(at).set(
at.allocated_amount, at.allocated_amount + tax.allocated_amount
).where(at.name == tax.reference_detail).run()

def set_status(self, update=False, status=None, update_modified=True):
if self.is_new():
if self.get('amended_from'):
Expand Down
Loading

0 comments on commit 38dfb60

Please sign in to comment.