calculate TDS on Sales Invoice Amount

This commit is contained in:
Saurabh 2018-05-12 17:42:20 +05:30
parent 3b4a6be4d0
commit b9d3385fec
7 changed files with 153 additions and 48 deletions

View File

@ -139,9 +139,6 @@
"Creditors": {
"account_type": "Payable"
},
"TDS": {
"account_type": "Payable"
},
"Payroll Payable": {}
},
"Stock Liabilities": {
@ -150,8 +147,9 @@
}
},
"Duties and Taxes": {
"account_type": "Tax",
"is_group": 1
"TDS": {
"account_type": "Tax"
}
},
"Loans (Liabilities)": {
"Secured Loans": {},

View File

@ -8,7 +8,7 @@ from frappe import _, throw
import frappe.defaults
from erpnext.controllers.buying_controller import BuyingController
from erpnext.accounts.party import get_party_account, get_due_date
from erpnext.accounts.party import get_party_account, get_due_date, get_patry_tax_withholding_details
from erpnext.accounts.utils import get_account_currency, get_fiscal_year
from erpnext.stock.doctype.purchase_receipt.purchase_receipt import update_billed_amount_based_on_po
from erpnext.stock import get_warehouse_account_map
@ -46,6 +46,7 @@ class PurchaseInvoice(BuyingController):
self.is_opening = 'No'
self.validate_posting_time()
self.set_tax_withholding()
super(PurchaseInvoice, self).validate()
if not self.is_return:
@ -53,7 +54,6 @@ class PurchaseInvoice(BuyingController):
self.pr_required()
self.validate_supplier_invoice()
# validate cash purchase
if (self.is_paid == 1):
self.validate_cash()
@ -168,7 +168,6 @@ class PurchaseInvoice(BuyingController):
super(PurchaseInvoice, self).validate_warehouse()
def validate_item_code(self):
for d in self.get('items'):
if not d.item_code:
@ -731,6 +730,22 @@ class PurchaseInvoice(BuyingController):
def on_recurring(self, reference_doc, subscription_doc):
self.due_date = None
def set_tax_withholding(self):
"""
1. Get TDS Configurations against Supplier or Pull Default One.
2. Form Purchase Order, identify partial payments
3. If sum of all invoices grand total is greater than threshold and If TDS not deducted in previos Invoices
then deduct TDS for sum amount else deduct TDS for current Invoice
"""
if not self.get("__islocal"):
return
tax_withholding_details = get_patry_tax_withholding_details(self)
if tax_withholding_details and\
flt(self.get("rounded_total") or self.grand_total) >= flt(tax_withholding_details['threshold']):
self.append('taxes', tax_withholding_details['taxes'])
@frappe.whitelist()
def make_debit_note(source_name, target_doc=None):
from erpnext.controllers.sales_and_purchase_return import make_return_doc

View File

@ -13,6 +13,68 @@
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "is_default",
"fieldtype": "Check",
"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,
"label": "Is Default",
"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_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "enabled",
"fieldtype": "Check",
"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,
"label": "Enabled",
"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_on_submit": 0,
@ -271,7 +333,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-04-13 19:17:12.494050",
"modified": "2018-05-11 14:25:07.474461",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Tax Withholding Category",

View File

@ -7,4 +7,7 @@ import frappe
from frappe.model.document import Document
class TaxWithholdingCategory(Document):
pass
def validate(self):
if not frappe.db.get_value("Tax Withholding Category",
{"is_default": 1, "name": ("!=", self.name)}, "name"):
self.is_default = 1

View File

@ -448,7 +448,6 @@ def get_dashboard_info(party_type, party):
return info
def get_party_shipping_address(doctype, name):
"""
Returns an Address name (best guess) for the given doctype and name for which `address_type == 'Shipping'` is true.
@ -476,3 +475,63 @@ def get_party_shipping_address(doctype, name):
return out[0][0]
else:
return ''
def get_patry_tax_withholding_details(ref_doc):
supplier = frappe.get_doc("Supplier", ref_doc.supplier)
tax_withholding_details = {}
for tax in supplier.tax_withholding_config:
tax_mapper = get_tax_mapper()
set_tax_withholding_details(tax_mapper, ref_doc, tax_withholding_category=tax.tax_withholding_category)
if tax.valid_till and date_diff(tax.valid_till, ref_doc.posting_date) > 0:
tax_mapper.update({
"rate": tax.applicable_percentage
})
prepare_tax_withholding_details(tax_mapper, tax_withholding_details)
if not tax_withholding_details:
tax_mapper = get_tax_mapper()
set_tax_withholding_details(tax_mapper, ref_doc, use_default=1)
prepare_tax_withholding_details(tax_mapper, tax_withholding_details)
return tax_withholding_details
def prepare_tax_withholding_details(tax_mapper, tax_withholding_details):
if tax_mapper.get('account_head'):
tax_withholding_details.update({
"threshold": tax_mapper['threshold'],
"taxes": tax_mapper
})
del tax_mapper['threshold']
def set_tax_withholding_details(tax_mapper, ref_doc, tax_withholding_category=None, use_default=0):
if tax_withholding_category:
tax_withholding = frappe.get_doc("Tax Withholding Category", tax_withholding_category)
else:
tax_withholding = frappe.get_doc("Tax Withholding Category", {'is_default': 1, 'enabled': 1})
if tax_withholding.book_on_invoice and ref_doc.doctype=='Purchase Invoice' \
or tax_withholding.book_on_advance and ref_doc.doctype in ('Payment Entry', 'Journal Entry'):
for account_detail in tax_withholding.accounts:
if ref_doc.company == account_detail.company:
tax_mapper.update({
"account_head": account_detail.account,
"rate": tax_withholding.percent_of_tax_withheld,
"threshold": tax_withholding.threshold,
"description": tax_withholding.name
})
def get_tax_mapper():
return {
"category": "Total",
"add_deduct_tax": "Deduct",
"charge_type": "On Net Total",
"rate": 0,
"description": '',
"account_head": '',
"threshold": 0.0
}

View File

@ -233,7 +233,7 @@
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
@ -997,7 +997,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "tax_withholding_account",
"fieldname": "tax_withholding_config",
"fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 0,
@ -1180,38 +1180,6 @@
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "tax_withholding_category",
"fieldtype": "Link",
"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,
"label": "Tax Withholding Category",
"length": 0,
"no_copy": 0,
"options": "Tax Withholding Category",
"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,
@ -1226,7 +1194,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-05-11 14:00:36.204532",
"modified": "2018-05-11 15:15:19.912308",
"modified_by": "Administrator",
"module": "Buying",
"name": "Supplier",

View File

@ -240,7 +240,7 @@ def set_tax_withholding_category(docs, company):
def set_tds_account(docs, company):
docs.extend([
{
'doctype': 'Account', 'account_name': 'TDS', 'account_type': 'Payable',
'parent_account': 'Accounts Payable', 'company': company
'doctype': 'Account', 'account_name': 'TDS', 'account_type': 'Tax',
'parent_account': 'Duties and Taxes', 'company': company
}
])