feat: Validity dates in Tax Withholding Rates

This commit is contained in:
Deepesh Garg 2021-08-31 18:23:28 +05:30
parent 9cb642238f
commit 5e10e10329
5 changed files with 159 additions and 250 deletions

View File

@ -10,7 +10,24 @@ from frappe.utils import flt, getdate, cint
from erpnext.accounts.utils import get_fiscal_year from erpnext.accounts.utils import get_fiscal_year
class TaxWithholdingCategory(Document): class TaxWithholdingCategory(Document):
pass def validate(self):
self.validate_dates()
self.validate_thresholds()
def validate_dates(self):
last_date = None
for d in self.get('rates'):
if getdate(d.from_date) >= getdate(d.to_date):
frappe.throw(_("Row #{0}: From Date cannot be before To Date").format(d.idx))
# validate overlapping of dates
if last_date and getdate(r.to_date) < getdate(last_date):
frappe.throw(_("Row #{0}: Dates overlapping with other row").format(d.idx))
def validate_thresholds(self):
for d in self.get('rates'):
if d.cumulative_threshold and d.cumulative_threshold < d.single_threshold:
frappe.throw(_("Row #{0}: Cumulative threshold cannot be less than Single Transaction threshold").format(d.idx))
def get_party_details(inv): def get_party_details(inv):
party_type, party = '', '' party_type, party = '', ''
@ -49,8 +66,8 @@ def get_party_tax_withholding_details(inv, tax_withholding_category=None):
if not parties: if not parties:
parties.append(party) parties.append(party)
fiscal_year = get_fiscal_year(inv.get('posting_date') or inv.get('transaction_date'), company=inv.company) posting_date = inv.get('posting_date') or inv.get('transaction_date')
tax_details = get_tax_withholding_details(tax_withholding_category, fiscal_year[0], inv.company) tax_details = get_tax_withholding_details(tax_withholding_category, posting_date, inv.company)
if not tax_details: if not tax_details:
frappe.throw(_('Please set associated account in Tax Withholding Category {0} against Company {1}') frappe.throw(_('Please set associated account in Tax Withholding Category {0} against Company {1}')
@ -64,7 +81,7 @@ def get_party_tax_withholding_details(inv, tax_withholding_category=None):
tax_amount, tax_deducted = get_tax_amount( tax_amount, tax_deducted = get_tax_amount(
party_type, parties, party_type, parties,
inv, tax_details, inv, tax_details,
fiscal_year, pan_no posting_date, pan_no
) )
if party_type == 'Supplier': if party_type == 'Supplier':
@ -74,16 +91,18 @@ def get_party_tax_withholding_details(inv, tax_withholding_category=None):
return tax_row return tax_row
def get_tax_withholding_details(tax_withholding_category, fiscal_year, company): def get_tax_withholding_details(tax_withholding_category, posting_date, company):
tax_withholding = frappe.get_doc("Tax Withholding Category", tax_withholding_category) tax_withholding = frappe.get_doc("Tax Withholding Category", tax_withholding_category)
tax_rate_detail = get_tax_withholding_rates(tax_withholding, fiscal_year) tax_rate_detail = get_tax_withholding_rates(tax_withholding, posting_date)
for account_detail in tax_withholding.accounts: for account_detail in tax_withholding.accounts:
if company == account_detail.company: if company == account_detail.company:
return frappe._dict({ return frappe._dict({
"account_head": account_detail.account, "account_head": account_detail.account,
"rate": tax_rate_detail.tax_withholding_rate, "rate": tax_rate_detail.tax_withholding_rate,
"from_date": tax_rate_detail.from_date,
"to_date": tax_rate_detail.to_date,
"threshold": tax_rate_detail.single_threshold, "threshold": tax_rate_detail.single_threshold,
"cumulative_threshold": tax_rate_detail.cumulative_threshold, "cumulative_threshold": tax_rate_detail.cumulative_threshold,
"description": tax_withholding.category_name if tax_withholding.category_name else tax_withholding_category, "description": tax_withholding.category_name if tax_withholding.category_name else tax_withholding_category,
@ -92,13 +111,13 @@ def get_tax_withholding_details(tax_withholding_category, fiscal_year, company):
"round_off_tax_amount": tax_withholding.round_off_tax_amount "round_off_tax_amount": tax_withholding.round_off_tax_amount
}) })
def get_tax_withholding_rates(tax_withholding, fiscal_year): def get_tax_withholding_rates(tax_withholding, posting_date):
# returns the row that matches with the fiscal year from posting date # returns the row that matches with the fiscal year from posting date
for rate in tax_withholding.rates: for rate in tax_withholding.rates:
if rate.fiscal_year == fiscal_year: if getdate(rate.from_date) <= getdate(posting_date) <= getdate(rate.to_date):
return rate return rate
frappe.throw(_("No Tax Withholding data found for the current Fiscal Year.")) frappe.throw(_("No Tax Withholding data found for the current posting date."))
def get_tax_row_for_tcs(inv, tax_details, tax_amount, tax_deducted): def get_tax_row_for_tcs(inv, tax_details, tax_amount, tax_deducted):
row = { row = {
@ -140,38 +159,38 @@ def get_tax_row_for_tds(tax_details, tax_amount):
"account_head": tax_details.account_head "account_head": tax_details.account_head
} }
def get_lower_deduction_certificate(fiscal_year, pan_no): def get_lower_deduction_certificate(tax_details, pan_no):
ldc_name = frappe.db.get_value('Lower Deduction Certificate', { 'pan_no': pan_no, 'fiscal_year': fiscal_year }, 'name') ldc_name = frappe.db.get_value('Lower Deduction Certificate',
{
'pan_no': pan_no,
'valid_from': ('>=', tax_details.from_date),
'valid_upto': ('<=', tax_details.to_date)
}, 'name')
if ldc_name: if ldc_name:
return frappe.get_doc('Lower Deduction Certificate', ldc_name) return frappe.get_doc('Lower Deduction Certificate', ldc_name)
def get_tax_amount(party_type, parties, inv, tax_details, fiscal_year_details, pan_no=None): def get_tax_amount(party_type, parties, inv, tax_details, posting_date, pan_no=None):
fiscal_year = fiscal_year_details[0] vouchers = get_invoice_vouchers(parties, tax_details, inv.company, party_type=party_type)
advance_vouchers = get_advance_vouchers(parties, company=inv.company, from_date=tax_details.from_date,
to_date=tax_details.to_date, party_type=party_type)
vouchers = get_invoice_vouchers(parties, fiscal_year, inv.company, party_type=party_type)
advance_vouchers = get_advance_vouchers(parties, fiscal_year, inv.company, party_type=party_type)
taxable_vouchers = vouchers + advance_vouchers taxable_vouchers = vouchers + advance_vouchers
tax_deducted = 0 tax_deducted = 0
if taxable_vouchers: if taxable_vouchers:
tax_deducted = get_deducted_tax(taxable_vouchers, fiscal_year, tax_details) tax_deducted = get_deducted_tax(taxable_vouchers, tax_details)
tax_amount = 0 tax_amount = 0
posting_date = inv.get('posting_date') or inv.get('transaction_date')
if party_type == 'Supplier': if party_type == 'Supplier':
ldc = get_lower_deduction_certificate(fiscal_year, pan_no) ldc = get_lower_deduction_certificate(tax_details, pan_no)
if tax_deducted: if tax_deducted:
net_total = inv.net_total net_total = inv.net_total
if ldc: if ldc:
tax_amount = get_tds_amount_from_ldc(ldc, parties, fiscal_year, pan_no, tax_details, posting_date, net_total) tax_amount = get_tds_amount_from_ldc(ldc, parties, pan_no, tax_details, posting_date, net_total)
else: else:
tax_amount = net_total * tax_details.rate / 100 if net_total > 0 else 0 tax_amount = net_total * tax_details.rate / 100 if net_total > 0 else 0
else: else:
tax_amount = get_tds_amount( tax_amount = get_tds_amount(ldc, parties, inv, tax_details, tax_deducted, vouchers)
ldc, parties, inv, tax_details,
fiscal_year_details, tax_deducted, vouchers
)
elif party_type == 'Customer': elif party_type == 'Customer':
if tax_deducted: if tax_deducted:
@ -180,14 +199,11 @@ def get_tax_amount(party_type, parties, inv, tax_details, fiscal_year_details, p
else: else:
# if no TCS has been charged in FY, # if no TCS has been charged in FY,
# then chargeable value is "prev invoices + advances" value which cross the threshold # then chargeable value is "prev invoices + advances" value which cross the threshold
tax_amount = get_tcs_amount( tax_amount = get_tcs_amount(parties, inv, tax_details, vouchers, advance_vouchers)
parties, inv, tax_details,
fiscal_year_details, vouchers, advance_vouchers
)
return tax_amount, tax_deducted return tax_amount, tax_deducted
def get_invoice_vouchers(parties, fiscal_year, company, party_type='Supplier'): def get_invoice_vouchers(parties, tax_details, company, party_type='Supplier'):
dr_or_cr = 'credit' if party_type == 'Supplier' else 'debit' dr_or_cr = 'credit' if party_type == 'Supplier' else 'debit'
filters = { filters = {
@ -195,14 +211,14 @@ def get_invoice_vouchers(parties, fiscal_year, company, party_type='Supplier'):
'company': company, 'company': company,
'party_type': party_type, 'party_type': party_type,
'party': ['in', parties], 'party': ['in', parties],
'fiscal_year': fiscal_year, 'posting_date': ['between', (tax_details.from_date, tax_details.to_date)],
'is_opening': 'No', 'is_opening': 'No',
'is_cancelled': 0 'is_cancelled': 0
} }
return frappe.get_all('GL Entry', filters=filters, distinct=1, pluck="voucher_no") or [""] return frappe.get_all('GL Entry', filters=filters, distinct=1, pluck="voucher_no") or [""]
def get_advance_vouchers(parties, fiscal_year=None, company=None, from_date=None, to_date=None, party_type='Supplier'): def get_advance_vouchers(parties, company=None, from_date=None, to_date=None, party_type='Supplier'):
# for advance vouchers, debit and credit is reversed # for advance vouchers, debit and credit is reversed
dr_or_cr = 'debit' if party_type == 'Supplier' else 'credit' dr_or_cr = 'debit' if party_type == 'Supplier' else 'credit'
@ -215,8 +231,6 @@ def get_advance_vouchers(parties, fiscal_year=None, company=None, from_date=None
'against_voucher': ['is', 'not set'] 'against_voucher': ['is', 'not set']
} }
if fiscal_year:
filters['fiscal_year'] = fiscal_year
if company: if company:
filters['company'] = company filters['company'] = company
if from_date and to_date: if from_date and to_date:
@ -224,20 +238,21 @@ def get_advance_vouchers(parties, fiscal_year=None, company=None, from_date=None
return frappe.get_all('GL Entry', filters=filters, distinct=1, pluck='voucher_no') or [""] return frappe.get_all('GL Entry', filters=filters, distinct=1, pluck='voucher_no') or [""]
def get_deducted_tax(taxable_vouchers, fiscal_year, tax_details): def get_deducted_tax(taxable_vouchers, tax_details):
# check if TDS / TCS account is already charged on taxable vouchers # check if TDS / TCS account is already charged on taxable vouchers
filters = { filters = {
'is_cancelled': 0, 'is_cancelled': 0,
'credit': ['>', 0], 'credit': ['>', 0],
'fiscal_year': fiscal_year, 'posting_date': ['between', (tax_details.from_date, tax_details.to_date)],
'account': tax_details.account_head, 'account': tax_details.account_head,
'voucher_no': ['in', taxable_vouchers], 'voucher_no': ['in', taxable_vouchers],
} }
field = "sum(credit)" field = "credit"
return frappe.db.get_value('GL Entry', filters, field) or 0.0 entries = frappe.db.get_all('GL Entry', filters, pluck=field)
return sum(entries)
def get_tds_amount(ldc, parties, inv, tax_details, fiscal_year_details, tax_deducted, vouchers): def get_tds_amount(ldc, parties, inv, tax_details, tax_deducted, vouchers):
tds_amount = 0 tds_amount = 0
invoice_filters = { invoice_filters = {
'name': ('in', vouchers), 'name': ('in', vouchers),
@ -261,7 +276,7 @@ def get_tds_amount(ldc, parties, inv, tax_details, fiscal_year_details, tax_dedu
supp_credit_amt += supp_jv_credit_amt supp_credit_amt += supp_jv_credit_amt
supp_credit_amt += inv.net_total supp_credit_amt += inv.net_total
debit_note_amount = get_debit_note_amount(parties, fiscal_year_details, inv.company) debit_note_amount = get_debit_note_amount(parties, tax_details.from_date, tax_details.to_date, inv.company)
supp_credit_amt -= debit_note_amount supp_credit_amt -= debit_note_amount
threshold = tax_details.get('threshold', 0) threshold = tax_details.get('threshold', 0)
@ -289,9 +304,8 @@ def get_tds_amount(ldc, parties, inv, tax_details, fiscal_year_details, tax_dedu
return tds_amount return tds_amount
def get_tcs_amount(parties, inv, tax_details, fiscal_year_details, vouchers, adv_vouchers): def get_tcs_amount(parties, inv, tax_details, vouchers, adv_vouchers):
tcs_amount = 0 tcs_amount = 0
fiscal_year, _, _ = fiscal_year_details
# sum of debit entries made from sales invoices # sum of debit entries made from sales invoices
invoiced_amt = frappe.db.get_value('GL Entry', { invoiced_amt = frappe.db.get_value('GL Entry', {
@ -310,14 +324,14 @@ def get_tcs_amount(parties, inv, tax_details, fiscal_year_details, vouchers, adv
}, 'sum(credit)') or 0.0 }, 'sum(credit)') or 0.0
# sum of credit entries made from sales invoice # sum of credit entries made from sales invoice
credit_note_amt = frappe.db.get_value('GL Entry', { credit_note_amt = sum(frappe.db.get_all('GL Entry', {
'is_cancelled': 0, 'is_cancelled': 0,
'credit': ['>', 0], 'credit': ['>', 0],
'party': ['in', parties], 'party': ['in', parties],
'fiscal_year': fiscal_year, 'posting_date': ['between', (tax_details.from_date, tax_details.to_date)],
'company': inv.company, 'company': inv.company,
'voucher_type': 'Sales Invoice', 'voucher_type': 'Sales Invoice',
}, 'sum(credit)') or 0.0 }, pluck='credit'))
cumulative_threshold = tax_details.get('cumulative_threshold', 0) cumulative_threshold = tax_details.get('cumulative_threshold', 0)
@ -336,7 +350,7 @@ def get_invoice_total_without_tcs(inv, tax_details):
return inv.grand_total - tcs_tax_row_amount return inv.grand_total - tcs_tax_row_amount
def get_tds_amount_from_ldc(ldc, parties, fiscal_year, pan_no, tax_details, posting_date, net_total): def get_tds_amount_from_ldc(ldc, parties, pan_no, tax_details, posting_date, net_total):
tds_amount = 0 tds_amount = 0
limit_consumed = frappe.db.get_value('Purchase Invoice', { limit_consumed = frappe.db.get_value('Purchase Invoice', {
'supplier': ('in', parties), 'supplier': ('in', parties),
@ -353,14 +367,13 @@ def get_tds_amount_from_ldc(ldc, parties, fiscal_year, pan_no, tax_details, post
return tds_amount return tds_amount
def get_debit_note_amount(suppliers, fiscal_year_details, company=None): def get_debit_note_amount(suppliers, from_date, to_date, company=None):
_, year_start_date, year_end_date = fiscal_year_details
filters = { filters = {
'supplier': ['in', suppliers], 'supplier': ['in', suppliers],
'is_return': 1, 'is_return': 1,
'docstatus': 1, 'docstatus': 1,
'posting_date': ['between', (year_start_date, year_end_date)] 'posting_date': ['between', (from_date, to_date)]
} }
fields = ['abs(sum(net_total)) as net_total'] fields = ['abs(sum(net_total)) as net_total']

View File

@ -312,16 +312,16 @@ def create_records():
}).insert() }).insert()
def create_tax_with_holding_category(): def create_tax_with_holding_category():
fiscal_year = get_fiscal_year(today(), company="_Test Company")[0] fiscal_year = get_fiscal_year(today(), company="_Test Company")
# Cumulative threshold
# Cummulative thresold
if not frappe.db.exists("Tax Withholding Category", "Cumulative Threshold TDS"): if not frappe.db.exists("Tax Withholding Category", "Cumulative Threshold TDS"):
frappe.get_doc({ frappe.get_doc({
"doctype": "Tax Withholding Category", "doctype": "Tax Withholding Category",
"name": "Cumulative Threshold TDS", "name": "Cumulative Threshold TDS",
"category_name": "10% TDS", "category_name": "10% TDS",
"rates": [{ "rates": [{
'fiscal_year': fiscal_year, 'from_date': fiscal_year[1],
'to_date': fiscal_year[2],
'tax_withholding_rate': 10, 'tax_withholding_rate': 10,
'single_threshold': 0, 'single_threshold': 0,
'cumulative_threshold': 30000.00 'cumulative_threshold': 30000.00
@ -338,7 +338,8 @@ def create_tax_with_holding_category():
"name": "Cumulative Threshold TCS", "name": "Cumulative Threshold TCS",
"category_name": "10% TCS", "category_name": "10% TCS",
"rates": [{ "rates": [{
'fiscal_year': fiscal_year, 'from_date': fiscal_year[1],
'to_date': fiscal_year[2],
'tax_withholding_rate': 10, 'tax_withholding_rate': 10,
'single_threshold': 0, 'single_threshold': 0,
'cumulative_threshold': 30000.00 'cumulative_threshold': 30000.00
@ -356,7 +357,8 @@ def create_tax_with_holding_category():
"name": "Single Threshold TDS", "name": "Single Threshold TDS",
"category_name": "10% TDS", "category_name": "10% TDS",
"rates": [{ "rates": [{
'fiscal_year': fiscal_year, 'from_date': fiscal_year[1],
'to_date': fiscal_year[2],
'tax_withholding_rate': 10, 'tax_withholding_rate': 10,
'single_threshold': 20000.00, 'single_threshold': 20000.00,
'cumulative_threshold': 0 'cumulative_threshold': 0
@ -376,7 +378,8 @@ def create_tax_with_holding_category():
"consider_party_ledger_amount": 1, "consider_party_ledger_amount": 1,
"tax_on_excess_amount": 1, "tax_on_excess_amount": 1,
"rates": [{ "rates": [{
'fiscal_year': fiscal_year, 'from_date': fiscal_year[1],
'to_date': fiscal_year[2],
'tax_withholding_rate': 10, 'tax_withholding_rate': 10,
'single_threshold': 0, 'single_threshold': 0,
'cumulative_threshold': 30000 'cumulative_threshold': 30000

View File

@ -1,202 +1,72 @@
{ {
"allow_copy": 0, "actions": [],
"allow_guest_to_view": 0, "creation": "2018-07-17 16:53:13.716665",
"allow_import": 0, "doctype": "DocType",
"allow_rename": 0, "editable_grid": 1,
"beta": 0, "engine": "InnoDB",
"creation": "2018-07-17 16:53:13.716665", "field_order": [
"custom": 0, "from_date",
"docstatus": 0, "to_date",
"doctype": "DocType", "tax_withholding_rate",
"document_type": "", "column_break_3",
"editable_grid": 1, "single_threshold",
"engine": "InnoDB", "cumulative_threshold"
],
"fields": [ "fields": [
{ {
"allow_bulk_edit": 0, "columns": 1,
"allow_in_quick_entry": 0, "fieldname": "tax_withholding_rate",
"allow_on_submit": 0, "fieldtype": "Float",
"bold": 0, "in_list_view": 1,
"collapsible": 0, "label": "Tax Withholding Rate",
"columns": 2, "reqd": 1
"fieldname": "fiscal_year", },
"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": "Fiscal Year",
"length": 0,
"no_copy": 0,
"options": "Fiscal Year",
"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,
"translatable": 0,
"unique": 0
},
{ {
"allow_bulk_edit": 0, "fieldname": "column_break_3",
"allow_in_quick_entry": 0, "fieldtype": "Column Break"
"allow_on_submit": 0, },
"bold": 0,
"collapsible": 0,
"columns": 2,
"fieldname": "tax_withholding_rate",
"fieldtype": "Float",
"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": "Tax Withholding Rate",
"length": 0,
"no_copy": 0,
"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,
"translatable": 0,
"unique": 0
},
{ {
"allow_bulk_edit": 0, "columns": 2,
"allow_in_quick_entry": 0, "fieldname": "single_threshold",
"allow_on_submit": 0, "fieldtype": "Currency",
"bold": 0, "in_list_view": 1,
"collapsible": 0, "label": "Single Transaction Threshold"
"columns": 0, },
"fieldname": "column_break_3",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"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,
"translatable": 0,
"unique": 0
},
{ {
"allow_bulk_edit": 0, "columns": 3,
"allow_in_quick_entry": 0, "fieldname": "cumulative_threshold",
"allow_on_submit": 0, "fieldtype": "Currency",
"bold": 0, "in_list_view": 1,
"collapsible": 0, "label": "Cumulative Transaction Threshold"
"columns": 3, },
"fieldname": "single_threshold",
"fieldtype": "Currency",
"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": "Single Transaction Threshold",
"length": 0,
"no_copy": 0,
"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,
"translatable": 0,
"unique": 0
},
{ {
"allow_bulk_edit": 0, "columns": 2,
"allow_in_quick_entry": 0, "fieldname": "from_date",
"allow_on_submit": 0, "fieldtype": "Date",
"bold": 0, "in_list_view": 1,
"collapsible": 0, "label": "From Date",
"columns": 3, "reqd": 1
"fieldname": "cumulative_threshold", },
"fieldtype": "Currency", {
"hidden": 0, "columns": 2,
"ignore_user_permissions": 0, "fieldname": "to_date",
"ignore_xss_filter": 0, "fieldtype": "Date",
"in_filter": 0, "in_list_view": 1,
"in_global_search": 0, "label": "To Date",
"in_list_view": 1, "reqd": 1
"in_standard_filter": 0,
"label": "Cumulative Transaction Threshold",
"length": 0,
"no_copy": 0,
"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,
"translatable": 0,
"unique": 0
} }
], ],
"has_web_view": 0, "index_web_pages_for_search": 1,
"hide_heading": 0, "istable": 1,
"hide_toolbar": 0, "links": [],
"idx": 0, "modified": "2021-08-31 11:42:12.213977",
"image_view": 0, "modified_by": "Administrator",
"in_create": 0, "module": "Accounts",
"is_submittable": 0, "name": "Tax Withholding Rate",
"issingle": 0, "owner": "Administrator",
"istable": 1, "permissions": [],
"max_attachments": 0, "quick_entry": 1,
"modified": "2018-07-17 17:13:09.819580", "sort_field": "modified",
"modified_by": "Administrator", "sort_order": "DESC",
"module": "Accounts", "track_changes": 1
"name": "Tax Withholding Rate",
"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,
"track_views": 0
} }

View File

@ -300,4 +300,5 @@ erpnext.patches.v13_0.reset_clearance_date_for_intracompany_payment_entries
erpnext.patches.v13_0.einvoicing_deprecation_warning erpnext.patches.v13_0.einvoicing_deprecation_warning
erpnext.patches.v14_0.delete_einvoicing_doctypes erpnext.patches.v14_0.delete_einvoicing_doctypes
erpnext.patches.v13_0.set_operation_time_based_on_operating_cost erpnext.patches.v13_0.set_operation_time_based_on_operating_cost
erpnext.patches.v13_0.validate_options_for_data_field erpnext.patches.v13_0.validate_options_for_data_field
erpnext.patches.v13_0.update_dates_in_tax_withholding_category

View File

@ -0,0 +1,22 @@
# Copyright (c) 2021, Frappe and Contributors
# License: GNU General Public License v3. See license.txt
import frappe
from erpnext.accounts.utils import get_fiscal_year
def execute():
frappe.reload_doc('accounts', 'doctype', 'Tax Withholding Rate')
tds_category_rates = frappe.get_all('Tax Withholding Rate', fields=['name', 'fiscal_year'])
fiscal_year_map = {}
for rate in tds_category_rates:
if not fiscal_year_map.get(rate.fiscal_year):
fiscal_year_map[rate.fiscal_year] = get_fiscal_year(fiscal_year=rate.fiscal_year)
from_date = fiscal_year_map.get(rate.fiscal_year)[1]
to_date = fiscal_year_map.get(rate.fiscal_year)[2]
frappe.db.set_value('Tax Withholding Rate', rate.name, {
'from_date': from_date,
'to_date': to_date
})