Merge pull request #14027 from saurabh6790/TDS_sprint

Tds sprint
This commit is contained in:
rohitwaghchaure 2018-05-14 20:43:33 +05:30 committed by GitHub
commit 2b8fc49205
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 456 additions and 54 deletions

View File

@ -147,8 +147,9 @@
}
},
"Duties and Taxes": {
"account_type": "Tax",
"is_group": 1
"TDS": {
"account_type": "Tax"
}
},
"Loans (Liabilities)": {
"Secured Loans": {},

View File

@ -7,7 +7,7 @@ import frappe, erpnext, json
from frappe import _, scrub, ValidationError
from frappe.utils import flt, comma_or, nowdate
from erpnext.accounts.utils import get_outstanding_invoices, get_account_currency, get_balance_on
from erpnext.accounts.party import get_party_account
from erpnext.accounts.party import get_party_account, get_patry_tax_withholding_details
from erpnext.accounts.doctype.journal_entry.journal_entry import get_default_bank_cash_account
from erpnext.setup.utils import get_exchange_rate
from erpnext.accounts.general_ledger import make_gl_entries
@ -43,6 +43,7 @@ class PaymentEntry(AccountsController):
def validate(self):
self.setup_party_account_field()
self.set_tax_withholding()
self.set_missing_values()
self.validate_payment_type()
self.validate_party_details()
@ -511,6 +512,27 @@ class PaymentEntry(AccountsController):
self.reference_no = reference_doc.name
self.reference_date = nowdate()
def set_tax_withholding(self):
if self.party_type != 'Supplier':
return
self.supplier = self.party
tax_withholding_details = get_patry_tax_withholding_details(self)
for tax_details in tax_withholding_details:
if self.deductions:
if tax_details['tax']['account_head'] not in [deduction.account for deduction in self.deductions]:
self.append('deductions', self.calculate_deductions(tax_details))
else:
self.append('deductions', self.calculate_deductions(tax_details))
def calculate_deductions(self, tax_details):
return {
"account": tax_details['tax']['account_head'],
"cost_center": frappe.db.get_value("Company", self.company, "cost_center"),
"amount": self.total_allocated_amount * (tax_details['tax']['rate'] / 100)
}
@frappe.whitelist()
def get_outstanding_reference_documents(args):
if isinstance(args, string_types):

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,20 @@ 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
"""
tax_withholding_details = get_patry_tax_withholding_details(self)
for tax_details in tax_withholding_details:
if flt(self.get("rounded_total") or self.grand_total) >= flt(tax_details['threshold']):
if self.taxes:
if tax_details['tax']['description'] not in [tax.description for tax in self.taxes]:
self.append('taxes', tax_details['tax'])
else:
self.append('taxes', tax_details['tax'])
@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,60 @@ 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 = []
print(supplier)
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)
return tax_withholding_details
def prepare_tax_withholding_details(tax_mapper, tax_withholding_details):
if tax_mapper.get('account_head'):
tax_withholding_details.append({
"threshold": tax_mapper['threshold'],
"tax": 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

@ -0,0 +1,166 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"creation": "2018-05-11 13:32:33.825307",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"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": 1,
"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
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "valid_till",
"fieldtype": "Date",
"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": "Valid Till",
"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": "applicable_percent",
"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": "Applicable Percent",
"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": "certificate_received",
"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": "Certificate Received",
"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,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2018-05-11 13:35:44.424855",
"modified_by": "Administrator",
"module": "Buying",
"name": "Party Tax Withholding Config",
"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
}

View File

@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
class PartyTaxWithholdingConfig(Document):
pass

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,
@ -960,6 +960,69 @@
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
"columns": 0,
"fieldname": "default_tax_withholding_config",
"fieldtype": "Section 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,
"label": "Default Tax Withholding Config",
"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": "tax_withholding_config",
"fieldtype": "Table",
"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 Account",
"length": 0,
"no_copy": 0,
"options": "Party Tax Withholding Config",
"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,
@ -1117,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,
@ -1163,7 +1194,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-05-11 12:19:52.519026",
"modified": "2018-05-11 15:15:19.912308",
"modified_by": "Administrator",
"module": "Buying",
"name": "Supplier",

View File

@ -2766,7 +2766,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-05-10 07:52:24.326361",
"modified": "2018-05-11 12:48:46.435484",
"modified_by": "Administrator",
"module": "HR",
"name": "Employee",

View File

@ -16,7 +16,7 @@ def setup(company=None, patch=True):
add_print_formats()
if not patch:
update_address_template()
make_fixtures()
make_fixtures(company)
def update_address_template():
with open(os.path.join(os.path.dirname(__file__), 'address_template.html'), 'r') as f:
@ -189,15 +189,13 @@ def make_custom_fields():
create_custom_fields(custom_fields, ignore_validate = frappe.flags.in_patch)
def make_fixtures():
docs = [
{'doctype': 'Salary Component', 'salary_component': 'Professional Tax', 'description': 'Professional Tax', 'type': 'Deduction'},
{'doctype': 'Salary Component', 'salary_component': 'Provident Fund', 'description': 'Provident fund', 'type': 'Deduction'},
{'doctype': 'Salary Component', 'salary_component': 'House Rent Allowance', 'description': 'House Rent Allowance', 'type': 'Earning'},
{'doctype': 'Salary Component', 'salary_component': 'Basic', 'description': 'Basic', 'type': 'Earning'},
{'doctype': 'Salary Component', 'salary_component': 'Arrear', 'description': 'Arrear', 'type': 'Earning'},
{'doctype': 'Salary Component', 'salary_component': 'Leave Encashment', 'description': 'Leave Encashment', 'type': 'Earning'}
]
def make_fixtures(company=None):
docs = []
company = company.name if company else frappe.db.get_value("Global Defaults", None, "default_company")
set_salary_components(docs)
set_tds_account(docs, company)
set_tax_withholding_category(docs, company)
for d in docs:
try:
@ -206,3 +204,43 @@ def make_fixtures():
doc.insert()
except frappe.NameError:
pass
def set_salary_components(docs):
docs.extend([
{'doctype': 'Salary Component', 'salary_component': 'Professional Tax', 'description': 'Professional Tax', 'type': 'Deduction'},
{'doctype': 'Salary Component', 'salary_component': 'Provident Fund', 'description': 'Provident fund', 'type': 'Deduction'},
{'doctype': 'Salary Component', 'salary_component': 'House Rent Allowance', 'description': 'House Rent Allowance', 'type': 'Earning'},
{'doctype': 'Salary Component', 'salary_component': 'Basic', 'description': 'Basic', 'type': 'Earning'},
{'doctype': 'Salary Component', 'salary_component': 'Arrear', 'description': 'Arrear', 'type': 'Earning'},
{'doctype': 'Salary Component', 'salary_component': 'Leave Encashment', 'description': 'Leave Encashment', 'type': 'Earning'}
])
def set_tax_withholding_category(docs, company):
accounts = []
tds_account = frappe.db.get_value("Account", filter={"account_type": "Payable",
"account_name": "TDS", "company": company})
if company and tds_account:
accounts = [
{
'company': company,
'account': tds_account
}
]
docs.extend([
{
'doctype': 'Tax Withholding Category', '__newname': 'TDS',
'percent_of_tax_withheld': 10,'threshold': 150000, 'book_on_invoice': 1,
'book_on_advance': 0, "withhold_cumulative_tax_amount": 0,
'accounts': accounts
}
])
def set_tds_account(docs, company):
docs.extend([
{
'doctype': 'Account', 'account_name': 'TDS', 'account_type': 'Tax',
'parent_account': 'Duties and Taxes', 'company': company
}
])