feat: add tax and charges in expense claim
This commit is contained in:
parent
74f502cfa6
commit
ac9a4fe03c
@ -157,6 +157,14 @@ frappe.ui.form.on("Expense Claim", {
|
||||
}
|
||||
};
|
||||
});
|
||||
// frm.set_query("taxes", "account_head", function(doc) {
|
||||
// return {
|
||||
// filters: [
|
||||
// ['docstatus', '=', 1],
|
||||
// ['company', '=', doc.company]
|
||||
// ]
|
||||
// };
|
||||
// });
|
||||
},
|
||||
|
||||
onload: function(frm) {
|
||||
@ -259,6 +267,18 @@ frappe.ui.form.on("Expense Claim", {
|
||||
frm.events.get_advances(frm);
|
||||
},
|
||||
|
||||
get_taxes: function(frm) {
|
||||
if(frm.doc.taxes) {
|
||||
frappe.call({
|
||||
method: "calculate_taxes",
|
||||
doc: frm.doc,
|
||||
callback: (r) => {
|
||||
refresh_field("taxes");
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
get_advances: function(frm) {
|
||||
frappe.model.clear_table(frm.doc, "advances");
|
||||
if (frm.doc.employee) {
|
||||
@ -298,6 +318,7 @@ frappe.ui.form.on("Expense Claim Detail", {
|
||||
sanctioned_amount: function(frm, cdt, cdn) {
|
||||
var doc = frm.doc;
|
||||
cur_frm.cscript.calculate_total(doc,cdt,cdn);
|
||||
frm.trigger("get_taxes");
|
||||
}
|
||||
});
|
||||
|
||||
@ -332,6 +353,47 @@ frappe.ui.form.on("Expense Claim Advance", {
|
||||
}
|
||||
});
|
||||
|
||||
frappe.ui.form.on("Expense Taxes and Charges", {
|
||||
account_head: function(frm, cdt, cdn) {
|
||||
var child = locals[cdt][cdn];
|
||||
if(child.account_head && !child.description && !child.rate) {
|
||||
// set description from account head
|
||||
child.description = child.account_head.split(' - ').slice(0, -1).join(' - ');
|
||||
|
||||
// set the tax rate from account head
|
||||
frappe.db.get_value("Account", child.account_head, "tax_rate").then((r) => {
|
||||
if(r.message) {
|
||||
frappe.model.set_value(cdt, cdn, 'rate', r.message.tax_rate);
|
||||
}
|
||||
});
|
||||
refresh_field("taxes");
|
||||
}
|
||||
},
|
||||
|
||||
calculate_total: function(frm, cdt, cdn) {
|
||||
var child = locals[cdt][cdn];
|
||||
child.total = flt(frm.doc.total_sanctioned_amount) + flt(child.tax_amount);
|
||||
|
||||
refresh_field("taxes");
|
||||
},
|
||||
|
||||
rate: function(frm, cdt, cdn) {
|
||||
var child = locals[cdt][cdn];
|
||||
if(!child.amount) {
|
||||
child.tax_amount = flt(frm.doc.total_sanctioned_amount) * (flt(child.rate)/100);
|
||||
refresh_field("taxes");
|
||||
}
|
||||
frm.trigger("calculate_total", cdt, cdn)
|
||||
},
|
||||
|
||||
tax_amount: function(frm, cdt, cdn) {
|
||||
var child = locals[cdt][cdn];
|
||||
child.rate = flt(child.tax_amount/frm.doc.total_sanctioned_amount) * 100;
|
||||
frm.trigger("calculate_total", cdt, cdn)
|
||||
refresh_field("taxes");
|
||||
}
|
||||
});
|
||||
|
||||
cur_frm.fields_dict['task'].get_query = function(doc) {
|
||||
return {
|
||||
filters:{
|
||||
|
@ -4,6 +4,7 @@
|
||||
"creation": "2013-01-10 16:34:14",
|
||||
"doctype": "DocType",
|
||||
"document_type": "Setup",
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"naming_series",
|
||||
"employee",
|
||||
@ -18,6 +19,9 @@
|
||||
"expense_details",
|
||||
"expenses",
|
||||
"sb1",
|
||||
"taxes",
|
||||
"net_total",
|
||||
"section_break_16",
|
||||
"posting_date",
|
||||
"vehicle_log",
|
||||
"task",
|
||||
@ -315,12 +319,28 @@
|
||||
{
|
||||
"fieldname": "dimension_col_break",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "taxes",
|
||||
"fieldtype": "Table",
|
||||
"label": "Expense Taxes and Charges",
|
||||
"options": "Expense Taxes and Charges"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_16",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "net_total",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Net Total",
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-money",
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"modified": "2019-05-25 22:53:31.682151",
|
||||
"modified": "2019-06-11 13:21:42.386420",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Expense Claim",
|
||||
|
@ -12,6 +12,7 @@ from erpnext.accounts.general_ledger import make_gl_entries
|
||||
from erpnext.accounts.doctype.sales_invoice.sales_invoice import get_bank_cash_account
|
||||
from erpnext.controllers.accounts_controller import AccountsController
|
||||
from frappe.utils.csvutils import getlink
|
||||
from erpnext.accounts.utils import get_account_currency
|
||||
|
||||
class InvalidExpenseApproverError(frappe.ValidationError): pass
|
||||
class ExpenseApproverIdentityError(frappe.ValidationError): pass
|
||||
@ -29,6 +30,7 @@ class ExpenseClaim(AccountsController):
|
||||
self.set_expense_account(validate=True)
|
||||
self.set_payable_account()
|
||||
self.set_cost_center()
|
||||
self.calculate_taxes()
|
||||
self.set_status()
|
||||
if self.task and not self.project:
|
||||
self.project = frappe.db.get_value("Task", self.task, "project")
|
||||
@ -93,7 +95,7 @@ class ExpenseClaim(AccountsController):
|
||||
elif self.project:
|
||||
frappe.get_doc("Project", self.project).update_project()
|
||||
|
||||
def make_gl_entries(self, cancel = False):
|
||||
def make_gl_entries(self, cancel=False):
|
||||
if flt(self.total_sanctioned_amount) > 0:
|
||||
gl_entries = self.get_gl_entries()
|
||||
make_gl_entries(gl_entries, cancel)
|
||||
@ -102,7 +104,7 @@ class ExpenseClaim(AccountsController):
|
||||
gl_entry = []
|
||||
self.validate_account_details()
|
||||
|
||||
payable_amount = flt(self.total_sanctioned_amount) - flt(self.total_advance_amount)
|
||||
payable_amount = flt(self.net_total) - flt(self.total_advance_amount)
|
||||
|
||||
# payable entry
|
||||
if payable_amount:
|
||||
@ -170,8 +172,26 @@ class ExpenseClaim(AccountsController):
|
||||
})
|
||||
)
|
||||
|
||||
gl_entry = self.make_tax_gl_entries(gl_entry)
|
||||
|
||||
return gl_entry
|
||||
|
||||
def make_tax_gl_entries(self, gl_entries):
|
||||
# tax table gl entries
|
||||
for tax in self.get("taxes"):
|
||||
account_currency = get_account_currency(tax.account_head)
|
||||
gl_entries.append(
|
||||
self.get_gl_dict({
|
||||
"account": tax.account_head,
|
||||
"debit": tax.tax_amount,
|
||||
"against": self.employee,
|
||||
"cost_center": self.cost_center,
|
||||
"against_voucher_type": self.doctype,
|
||||
"against_voucher": self.name
|
||||
}, account_currency)
|
||||
)
|
||||
return gl_entries
|
||||
|
||||
def validate_account_details(self):
|
||||
if not self.cost_center:
|
||||
frappe.throw(_("Cost center is required to book an expense claim"))
|
||||
@ -193,6 +213,15 @@ class ExpenseClaim(AccountsController):
|
||||
self.total_claimed_amount += flt(d.claim_amount)
|
||||
self.total_sanctioned_amount += flt(d.sanctioned_amount)
|
||||
|
||||
def calculate_taxes(self):
|
||||
for tax in self.taxes:
|
||||
if tax.rate:
|
||||
tax.tax_amount = flt(self.total_sanctioned_amount) * flt(tax.rate/100)
|
||||
if tax.tax_amount:
|
||||
tax.rate = flt(tax.tax_amount)/flt(self.total_sanctioned_amount) * 100
|
||||
tax.total = flt(tax.tax_amount) + flt(self.total_sanctioned_amount)
|
||||
self.net_total += tax.total
|
||||
|
||||
def update_task(self):
|
||||
task = frappe.get_doc("Task", self.task)
|
||||
task.update_total_expense_claim()
|
||||
|
@ -0,0 +1,103 @@
|
||||
{
|
||||
"autoname": "hash",
|
||||
"creation": "2019-06-03 11:42:33.123976",
|
||||
"doctype": "DocType",
|
||||
"document_type": "Setup",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"account_head",
|
||||
"cost_center",
|
||||
"col_break1",
|
||||
"rate",
|
||||
"description",
|
||||
"section_break_6",
|
||||
"tax_amount",
|
||||
"column_break_8",
|
||||
"total"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "col_break1",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"columns": 2,
|
||||
"fieldname": "account_head",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Account Head",
|
||||
"oldfieldname": "account_head",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Account",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"default": ":Company",
|
||||
"fieldname": "cost_center",
|
||||
"fieldtype": "Link",
|
||||
"label": "Cost Center",
|
||||
"oldfieldname": "cost_center",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Cost Center"
|
||||
},
|
||||
{
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Description",
|
||||
"oldfieldname": "description",
|
||||
"oldfieldtype": "Small Text",
|
||||
"print_width": "300px",
|
||||
"reqd": 1,
|
||||
"width": "300px"
|
||||
},
|
||||
{
|
||||
"columns": 2,
|
||||
"fieldname": "rate",
|
||||
"fieldtype": "Float",
|
||||
"in_list_view": 1,
|
||||
"label": "Rate",
|
||||
"oldfieldname": "rate",
|
||||
"oldfieldtype": "Currency"
|
||||
},
|
||||
{
|
||||
"columns": 2,
|
||||
"fieldname": "tax_amount",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Amount",
|
||||
"oldfieldname": "tax_amount",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "currency"
|
||||
},
|
||||
{
|
||||
"columns": 2,
|
||||
"fieldname": "total",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Total",
|
||||
"oldfieldname": "total",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_6",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_8",
|
||||
"fieldtype": "Column Break"
|
||||
}
|
||||
],
|
||||
"istable": 1,
|
||||
"modified": "2019-06-11 14:19:34.780611",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Expense Taxes and Charges",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "ASC",
|
||||
"track_changes": 1
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2019, 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 ExpenseTaxesandCharges(Document):
|
||||
pass
|
Loading…
x
Reference in New Issue
Block a user