calculate TDS on Sales Invoice Amount
This commit is contained in:
parent
3b4a6be4d0
commit
b9d3385fec
@ -139,9 +139,6 @@
|
|||||||
"Creditors": {
|
"Creditors": {
|
||||||
"account_type": "Payable"
|
"account_type": "Payable"
|
||||||
},
|
},
|
||||||
"TDS": {
|
|
||||||
"account_type": "Payable"
|
|
||||||
},
|
|
||||||
"Payroll Payable": {}
|
"Payroll Payable": {}
|
||||||
},
|
},
|
||||||
"Stock Liabilities": {
|
"Stock Liabilities": {
|
||||||
@ -150,8 +147,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Duties and Taxes": {
|
"Duties and Taxes": {
|
||||||
"account_type": "Tax",
|
"TDS": {
|
||||||
"is_group": 1
|
"account_type": "Tax"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Loans (Liabilities)": {
|
"Loans (Liabilities)": {
|
||||||
"Secured Loans": {},
|
"Secured Loans": {},
|
||||||
|
@ -8,7 +8,7 @@ from frappe import _, throw
|
|||||||
import frappe.defaults
|
import frappe.defaults
|
||||||
|
|
||||||
from erpnext.controllers.buying_controller import BuyingController
|
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.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.doctype.purchase_receipt.purchase_receipt import update_billed_amount_based_on_po
|
||||||
from erpnext.stock import get_warehouse_account_map
|
from erpnext.stock import get_warehouse_account_map
|
||||||
@ -46,6 +46,7 @@ class PurchaseInvoice(BuyingController):
|
|||||||
self.is_opening = 'No'
|
self.is_opening = 'No'
|
||||||
|
|
||||||
self.validate_posting_time()
|
self.validate_posting_time()
|
||||||
|
self.set_tax_withholding()
|
||||||
super(PurchaseInvoice, self).validate()
|
super(PurchaseInvoice, self).validate()
|
||||||
|
|
||||||
if not self.is_return:
|
if not self.is_return:
|
||||||
@ -53,7 +54,6 @@ class PurchaseInvoice(BuyingController):
|
|||||||
self.pr_required()
|
self.pr_required()
|
||||||
self.validate_supplier_invoice()
|
self.validate_supplier_invoice()
|
||||||
|
|
||||||
|
|
||||||
# validate cash purchase
|
# validate cash purchase
|
||||||
if (self.is_paid == 1):
|
if (self.is_paid == 1):
|
||||||
self.validate_cash()
|
self.validate_cash()
|
||||||
@ -168,7 +168,6 @@ class PurchaseInvoice(BuyingController):
|
|||||||
|
|
||||||
super(PurchaseInvoice, self).validate_warehouse()
|
super(PurchaseInvoice, self).validate_warehouse()
|
||||||
|
|
||||||
|
|
||||||
def validate_item_code(self):
|
def validate_item_code(self):
|
||||||
for d in self.get('items'):
|
for d in self.get('items'):
|
||||||
if not d.item_code:
|
if not d.item_code:
|
||||||
@ -731,6 +730,22 @@ class PurchaseInvoice(BuyingController):
|
|||||||
def on_recurring(self, reference_doc, subscription_doc):
|
def on_recurring(self, reference_doc, subscription_doc):
|
||||||
self.due_date = None
|
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()
|
@frappe.whitelist()
|
||||||
def make_debit_note(source_name, target_doc=None):
|
def make_debit_note(source_name, target_doc=None):
|
||||||
from erpnext.controllers.sales_and_purchase_return import make_return_doc
|
from erpnext.controllers.sales_and_purchase_return import make_return_doc
|
||||||
|
@ -13,6 +13,68 @@
|
|||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"fields": [
|
"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_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
@ -271,7 +333,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2018-04-13 19:17:12.494050",
|
"modified": "2018-05-11 14:25:07.474461",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Tax Withholding Category",
|
"name": "Tax Withholding Category",
|
||||||
|
@ -7,4 +7,7 @@ import frappe
|
|||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
|
||||||
class TaxWithholdingCategory(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
|
@ -448,7 +448,6 @@ def get_dashboard_info(party_type, party):
|
|||||||
|
|
||||||
return info
|
return info
|
||||||
|
|
||||||
|
|
||||||
def get_party_shipping_address(doctype, name):
|
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.
|
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]
|
return out[0][0]
|
||||||
else:
|
else:
|
||||||
return ''
|
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
|
||||||
|
}
|
@ -233,7 +233,7 @@
|
|||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 1,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"translatable": 0,
|
"translatable": 0,
|
||||||
@ -997,7 +997,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"fieldname": "tax_withholding_account",
|
"fieldname": "tax_withholding_config",
|
||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
@ -1180,38 +1180,6 @@
|
|||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"translatable": 0,
|
"translatable": 0,
|
||||||
"unique": 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,
|
"has_web_view": 0,
|
||||||
@ -1226,7 +1194,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2018-05-11 14:00:36.204532",
|
"modified": "2018-05-11 15:15:19.912308",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Supplier",
|
"name": "Supplier",
|
||||||
|
@ -240,7 +240,7 @@ def set_tax_withholding_category(docs, company):
|
|||||||
def set_tds_account(docs, company):
|
def set_tds_account(docs, company):
|
||||||
docs.extend([
|
docs.extend([
|
||||||
{
|
{
|
||||||
'doctype': 'Account', 'account_name': 'TDS', 'account_type': 'Payable',
|
'doctype': 'Account', 'account_name': 'TDS', 'account_type': 'Tax',
|
||||||
'parent_account': 'Accounts Payable', 'company': company
|
'parent_account': 'Duties and Taxes', 'company': company
|
||||||
}
|
}
|
||||||
])
|
])
|
Loading…
x
Reference in New Issue
Block a user