feat: Validity dates in Tax Withholding Rates
This commit is contained in:
		
							parent
							
								
									9cb642238f
								
							
						
					
					
						commit
						5e10e10329
					
				| @ -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'] | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
| @ -1,202 +1,72 @@ | |||||||
| { | { | ||||||
|  "allow_copy": 0,  |  "actions": [], | ||||||
|  "allow_guest_to_view": 0,  |  | ||||||
|  "allow_import": 0,  |  | ||||||
|  "allow_rename": 0,  |  | ||||||
|  "beta": 0,  |  | ||||||
|  "creation": "2018-07-17 16:53:13.716665", |  "creation": "2018-07-17 16:53:13.716665", | ||||||
|  "custom": 0,  |  | ||||||
|  "docstatus": 0,  |  | ||||||
|  "doctype": "DocType", |  "doctype": "DocType", | ||||||
|  "document_type": "",  |  | ||||||
|  "editable_grid": 1, |  "editable_grid": 1, | ||||||
|  "engine": "InnoDB", |  "engine": "InnoDB", | ||||||
|  |  "field_order": [ | ||||||
|  |   "from_date", | ||||||
|  |   "to_date", | ||||||
|  |   "tax_withholding_rate", | ||||||
|  |   "column_break_3", | ||||||
|  |   "single_threshold", | ||||||
|  |   "cumulative_threshold" | ||||||
|  |  ], | ||||||
|  "fields": [ |  "fields": [ | ||||||
|   { |   { | ||||||
|    "allow_bulk_edit": 0,  |    "columns": 1, | ||||||
|    "allow_in_quick_entry": 0,  |  | ||||||
|    "allow_on_submit": 0,  |  | ||||||
|    "bold": 0,  |  | ||||||
|    "collapsible": 0,  |  | ||||||
|    "columns": 2,  |  | ||||||
|    "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,  |  | ||||||
|    "allow_in_quick_entry": 0,  |  | ||||||
|    "allow_on_submit": 0,  |  | ||||||
|    "bold": 0,  |  | ||||||
|    "collapsible": 0,  |  | ||||||
|    "columns": 2,  |  | ||||||
|    "fieldname": "tax_withholding_rate", |    "fieldname": "tax_withholding_rate", | ||||||
|    "fieldtype": "Float", |    "fieldtype": "Float", | ||||||
|    "hidden": 0,  |  | ||||||
|    "ignore_user_permissions": 0,  |  | ||||||
|    "ignore_xss_filter": 0,  |  | ||||||
|    "in_filter": 0,  |  | ||||||
|    "in_global_search": 0,  |  | ||||||
|    "in_list_view": 1, |    "in_list_view": 1, | ||||||
|    "in_standard_filter": 0,  |  | ||||||
|    "label": "Tax Withholding Rate", |    "label": "Tax Withholding Rate", | ||||||
|    "length": 0,  |    "reqd": 1 | ||||||
|    "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,  |  | ||||||
|    "allow_in_quick_entry": 0,  |  | ||||||
|    "allow_on_submit": 0,  |  | ||||||
|    "bold": 0,  |  | ||||||
|    "collapsible": 0,  |  | ||||||
|    "columns": 0,  |  | ||||||
|    "fieldname": "column_break_3", |    "fieldname": "column_break_3", | ||||||
|    "fieldtype": "Column Break",  |    "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": 2, | ||||||
|    "allow_in_quick_entry": 0,  |  | ||||||
|    "allow_on_submit": 0,  |  | ||||||
|    "bold": 0,  |  | ||||||
|    "collapsible": 0,  |  | ||||||
|    "columns": 3,  |  | ||||||
|    "fieldname": "single_threshold", |    "fieldname": "single_threshold", | ||||||
|    "fieldtype": "Currency", |    "fieldtype": "Currency", | ||||||
|    "hidden": 0,  |  | ||||||
|    "ignore_user_permissions": 0,  |  | ||||||
|    "ignore_xss_filter": 0,  |  | ||||||
|    "in_filter": 0,  |  | ||||||
|    "in_global_search": 0,  |  | ||||||
|    "in_list_view": 1, |    "in_list_view": 1, | ||||||
|    "in_standard_filter": 0,  |    "label": "Single Transaction Threshold" | ||||||
|    "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,  |  | ||||||
|    "allow_in_quick_entry": 0,  |  | ||||||
|    "allow_on_submit": 0,  |  | ||||||
|    "bold": 0,  |  | ||||||
|    "collapsible": 0,  |  | ||||||
|    "columns": 3, |    "columns": 3, | ||||||
|    "fieldname": "cumulative_threshold", |    "fieldname": "cumulative_threshold", | ||||||
|    "fieldtype": "Currency", |    "fieldtype": "Currency", | ||||||
|    "hidden": 0,  |  | ||||||
|    "ignore_user_permissions": 0,  |  | ||||||
|    "ignore_xss_filter": 0,  |  | ||||||
|    "in_filter": 0,  |  | ||||||
|    "in_global_search": 0,  |  | ||||||
|    "in_list_view": 1, |    "in_list_view": 1, | ||||||
|    "in_standard_filter": 0,  |    "label": "Cumulative Transaction Threshold" | ||||||
|    "label": "Cumulative Transaction Threshold",  |   }, | ||||||
|    "length": 0,  |   { | ||||||
|    "no_copy": 0,  |    "columns": 2, | ||||||
|    "permlevel": 0,  |    "fieldname": "from_date", | ||||||
|    "precision": "",  |    "fieldtype": "Date", | ||||||
|    "print_hide": 0,  |    "in_list_view": 1, | ||||||
|    "print_hide_if_no_value": 0,  |    "label": "From Date", | ||||||
|    "read_only": 0,  |    "reqd": 1 | ||||||
|    "remember_last_selected_value": 0,  |   }, | ||||||
|    "report_hide": 0,  |   { | ||||||
|    "reqd": 0,  |    "columns": 2, | ||||||
|    "search_index": 0,  |    "fieldname": "to_date", | ||||||
|    "set_only_once": 0,  |    "fieldtype": "Date", | ||||||
|    "translatable": 0,  |    "in_list_view": 1, | ||||||
|    "unique": 0 |    "label": "To Date", | ||||||
|  |    "reqd": 1 | ||||||
|   } |   } | ||||||
|  ], |  ], | ||||||
|  "has_web_view": 0,  |  "index_web_pages_for_search": 1, | ||||||
|  "hide_heading": 0,  |  | ||||||
|  "hide_toolbar": 0,  |  | ||||||
|  "idx": 0,  |  | ||||||
|  "image_view": 0,  |  | ||||||
|  "in_create": 0,  |  | ||||||
|  "is_submittable": 0,  |  | ||||||
|  "issingle": 0,  |  | ||||||
|  "istable": 1, |  "istable": 1, | ||||||
|  "max_attachments": 0,  |  "links": [], | ||||||
|  "modified": "2018-07-17 17:13:09.819580",  |  "modified": "2021-08-31 11:42:12.213977", | ||||||
|  "modified_by": "Administrator", |  "modified_by": "Administrator", | ||||||
|  "module": "Accounts", |  "module": "Accounts", | ||||||
|  "name": "Tax Withholding Rate", |  "name": "Tax Withholding Rate", | ||||||
|  "name_case": "",  |  | ||||||
|  "owner": "Administrator", |  "owner": "Administrator", | ||||||
|  "permissions": [], |  "permissions": [], | ||||||
|  "quick_entry": 1, |  "quick_entry": 1, | ||||||
|  "read_only": 0,  |  | ||||||
|  "read_only_onload": 0,  |  | ||||||
|  "show_name_in_global_search": 0,  |  | ||||||
|  "sort_field": "modified", |  "sort_field": "modified", | ||||||
|  "sort_order": "DESC", |  "sort_order": "DESC", | ||||||
|  "track_changes": 1,  |  "track_changes": 1 | ||||||
|  "track_seen": 0,  |  | ||||||
|  "track_views": 0 |  | ||||||
| } | } | ||||||
| @ -301,3 +301,4 @@ 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 | ||||||
| @ -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 | ||||||
|  | 		}) | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user