Revert "Advance against expense claim (#10632)" (#10877)

This reverts commit cdd6ded790cb31a44acb70c219cde0d30da09bde.
This commit is contained in:
Nabin Hait 2017-09-25 11:27:39 +05:30 committed by GitHub
parent 4ebac3380d
commit 3b61552836
14 changed files with 1676 additions and 1986 deletions

View File

@ -8,7 +8,7 @@ from frappe import msgprint, _, scrub
from erpnext.controllers.accounts_controller import AccountsController
from erpnext.accounts.utils import get_balance_on, get_account_currency
from erpnext.accounts.party import get_party_account
from erpnext.hr.doctype.expense_claim.expense_claim import update_paid_amount
from erpnext.hr.doctype.expense_claim.expense_claim import update_reimbursed_amount
from erpnext.hr.doctype.employee_loan.employee_loan import update_disbursement_status
class JournalEntry(AccountsController):
@ -215,8 +215,8 @@ class JournalEntry(AccountsController):
if d.reference_type in ("Sales Invoice", "Purchase Invoice"):
if (against_voucher[0] != d.party or against_voucher[1] != d.account):
frappe.throw(_("Row {0}: Party / Account does not match with {1} / {2} in {3} {4}")
.format(d.idx, field_dict.get(d.reference_type)[0],
field_dict.get(d.reference_type)[1], d.reference_type, d.reference_name))
.format(d.idx, field_dict.get(d.reference_type)[0], field_dict.get(d.reference_type)[1],
d.reference_type, d.reference_name))
# check if party matches for Sales / Purchase Order
if d.reference_type in ("Sales Order", "Purchase Order"):
@ -225,17 +225,6 @@ class JournalEntry(AccountsController):
frappe.throw(_("Row {0}: {1} {2} does not match with {3}") \
.format(d.idx, d.party_type, d.party, d.reference_type))
if d.reference_type == "Expense Claim":
ref_doc = frappe.get_doc("Expense Claim", d.reference_name)
if ref_doc.employee != d.party:
frappe.throw(_("Row {0}# Party must be {1}, same as Expense Claim {2}")
.format(d.idx, ref_doc.employee, d.reference_name))
account_field = "advance_account" if ref_doc.docstatus==0 else "payable_account"
if ref_doc.get(account_field) != d.account:
frappe.throw(_("Row {0}# Account must be {1}, same as Expense Claim {2}")
.format(d.idx, ref_doc.get(account_field), d.reference_name))
self.validate_orders()
self.validate_invoices()
@ -527,7 +516,7 @@ class JournalEntry(AccountsController):
for d in self.accounts:
if d.reference_type=="Expense Claim" and d.reference_name:
doc = frappe.get_doc("Expense Claim", d.reference_name)
update_paid_amount(doc, d.account)
update_reimbursed_amount(doc)
def update_employee_loan(self):
for d in self.accounts:

View File

@ -12,7 +12,7 @@ from erpnext.accounts.doctype.journal_entry.journal_entry \
import get_average_exchange_rate, get_default_bank_cash_account
from erpnext.setup.utils import get_exchange_rate
from erpnext.accounts.general_ledger import make_gl_entries
from erpnext.hr.doctype.expense_claim.expense_claim import update_paid_amount
from erpnext.hr.doctype.expense_claim.expense_claim import update_reimbursed_amount
from erpnext.controllers.accounts_controller import AccountsController
class InvalidPaymentEntry(ValidationError): pass
@ -219,20 +219,15 @@ class PaymentEntry(AccountsController):
elif self.party_type=="Supplier":
ref_party_account = ref_doc.credit_to
elif self.party_type=="Employee":
ref_party_account = ref_doc.payable_account \
if ref_doc.docstatus==1 else ref_doc.advance_account
ref_party_account = ref_doc.payable_account
if ref_party_account != self.party_account:
frappe.throw(_("{0} {1} is associated with {2}, but Party Account is {3}")
.format(d.reference_doctype, d.reference_name, ref_party_account, self.party_account))
if ref_doc.docstatus != 1:
if d.reference_doctype!="Expense Claim":
frappe.throw(_("{0} {1} must be submitted")
.format(d.reference_doctype, d.reference_name))
elif not ref_doc.advance_required:
frappe.throw(_("Advance Payment Required should be checked in Expense Claim {0}")
.format(d.reference_name))
frappe.throw(_("{0} {1} must be submitted")
.format(d.reference_doctype, d.reference_name))
def validate_journal_entry(self):
for d in self.get("references"):
@ -486,11 +481,11 @@ class PaymentEntry(AccountsController):
frappe.get_doc(d.reference_doctype, d.reference_name).set_total_advance_paid()
def update_expense_claim(self):
if self.payment_type =="Pay" and self.party:
if self.payment_type in ("Pay") and self.party:
for d in self.get("references"):
if d.reference_doctype=="Expense Claim" and d.reference_name:
doc = frappe.get_doc("Expense Claim", d.reference_name)
update_paid_amount(doc, self.paid_to)
update_reimbursed_amount(doc)
def on_recurring(self, reference_doc, subscription_doc):
self.reference_no = reference_doc.name
@ -702,8 +697,6 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
party_account = doc.debit_to
elif dt == "Purchase Invoice":
party_account = doc.credit_to
elif dt == "Expense Claim":
party_account = doc.payable_account if doc.docstatus==1 else doc.advance_account
elif dt == "Fees":
party_account = doc.receivable_account
else:
@ -723,13 +716,11 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
if party_amount:
grand_total = outstanding_amount = party_amount
elif dt in ("Sales Invoice", "Purchase Invoice"):
grand_total = doc.base_grand_total \
if party_account_currency == doc.company_currency else doc.grand_total
grand_total = doc.base_grand_total if party_account_currency == doc.company_currency else doc.grand_total
outstanding_amount = doc.outstanding_amount
elif dt in ("Expense Claim"):
grand_total = doc.total_sanctioned_amount
outstanding_amount = flt(doc.total_sanctioned_amount) - flt(doc.total_amount_reimbursed) \
- flt(doc.total_advance_paid)
outstanding_amount = doc.total_sanctioned_amount - doc.total_amount_reimbursed
elif dt == "Fees":
grand_total = doc.grand_total
outstanding_amount = doc.outstanding_amount

View File

@ -86,8 +86,9 @@ class TestPaymentEntry(unittest.TestCase):
self.assertEqual(outstanding_amount, 0)
def test_payment_entry_against_ec(self):
payable = frappe.db.get_value('Company', "_Test Company", 'default_payable_account')
ec = make_expense_claim(300, 300, "Travel Expenses - _TC", "_Test Company", payable)
ec = make_expense_claim(payable, 300, 300, "_Test Company","Travel Expenses - _TC")
pe = get_payment_entry("Expense Claim", ec.name, bank_account="_Test Bank USD - _TC", bank_amount=300)
pe.reference_no = "1"
pe.reference_date = "2016-01-01"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

View File

@ -51,30 +51,6 @@ Set the Payment Type to "Pay", the Party Type to Employee, the Party to the empl
from. All outstanding expense claims will be pulled in and payments amounts can be allocated to each expense.
<img class="screenshot" alt="Expense Claim" src="{{docs_base_url}}/assets/img/human-resources/expense_claim_payment_entry.png">
### Managing Advance Payments
Sometimes an employee requires some advance payment before making expenses on behalf of the organisation. This can be managed from the Expense Claim
First make sure that the Default Advance Account has been set in the Company Master:
> Erpnext > Setup > Company
<img class="screenshot" alt="Expense Claim" src="{{docs_base_url}}/assets/img/human-resources/company_advance_account.png">
When creating the Expense Claim, check the 'Advance Payment Required' option
<img class="screenshot" alt="Expense Claim" src="{{docs_base_url}}/assets/img/human-resources/advance_payment_required.png">
After the Expense Claim is Saved and Approved by the Expense Approver, Journal Entry for Advance Payment can be raised by the accountant or user with appropriate permissions. To do that, just click on:
> Make > Advance Payment
<img class="screenshot" alt="Expense Claim" src="{{docs_base_url}}/assets/img/human-resources/make_advance_payment.png">
Note: Once the Expense Claim is Submitted, the button for making Advance Payment is no longer available. This is because expenses get booked on Submission of the Expense Claim and as such, the next logical step is settlement/reimbursement
Advance Payments are expected to be made 'before' the actual expenditure gets booked and settlement/reimbursement should be done against the Employee's Advance Account after submission of the Expense Claim
### Linking with Task & Project
* To Link Expense Claim with Task or Project specify the Task or the Project while making an Expense Claim

View File

@ -2432,7 +2432,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-07-11 14:30:13.694009",
"modified": "2017-06-13 14:29:13.694009",
"modified_by": "Administrator",
"module": "HR",
"name": "Employee",

View File

@ -34,6 +34,9 @@ erpnext.hr.ExpenseClaimController = frappe.ui.form.Controller.extend({
$.extend(cur_frm.cscript, new erpnext.hr.ExpenseClaimController({frm: cur_frm}));
cur_frm.add_fetch('employee', 'company', 'company');
cur_frm.add_fetch('employee','employee_name','employee_name');
cur_frm.cscript.onload = function(doc) {
if(!doc.approval_status)
cur_frm.set_value("approval_status", "Draft");
@ -68,6 +71,34 @@ cur_frm.cscript.clear_sanctioned = function(doc) {
refresh_many(['sanctioned_amount', 'total_sanctioned_amount']);
};
cur_frm.cscript.refresh = function(doc) {
cur_frm.cscript.set_help(doc);
if(!doc.__islocal) {
cur_frm.toggle_enable("exp_approver", doc.approval_status=="Draft");
cur_frm.toggle_enable("approval_status", (doc.exp_approver==frappe.session.user && doc.docstatus==0));
if (doc.docstatus==0 && doc.exp_approver==frappe.session.user && doc.approval_status=="Approved")
cur_frm.savesubmit();
if (doc.docstatus===1 && doc.approval_status=="Approved") {
/* eslint-disable */
// no idea how `me` works here
if (cint(doc.total_amount_reimbursed) > 0 && frappe.model.can_read("Journal Entry")) {
cur_frm.add_custom_button(__('Bank Entries'), function() {
frappe.route_options = {
"Journal Entry Account.reference_type": me.frm.doc.doctype,
"Journal Entry Account.reference_name": me.frm.doc.name,
company: me.frm.doc.company
};
frappe.set_route("List", "Journal Entry");
}, __("View"));
}
/* eslint-enable */
}
}
};
cur_frm.cscript.set_help = function(doc) {
cur_frm.set_intro("");
if(doc.__islocal && !in_list(frappe.user_roles, "HR User")) {
@ -123,75 +154,30 @@ erpnext.expense_claim = {
frappe.ui.form.on("Expense Claim", {
setup: function(frm) {
frm.trigger("set_query_for_cost_center");
frm.trigger("set_query_for_advance_account");
frm.trigger("set_query_for_payable_account");
frm.add_fetch("company", "cost_center", "cost_center");
frm.add_fetch("company", "default_advance_account", "advance_account");
frm.add_fetch("company", "default_payable_account", "payable_account");
frm.add_fetch('employee', 'company', 'company');
frm.add_fetch('employee','employee_name','employee_name');
},
refresh: function(frm) {
cur_frm.cscript.set_help(frm.doc);
frm.trigger("toggle_fields");
if(!frm.doc.__islocal) {
frm.trigger("toggle_fields");
frm.toggle_enable("exp_approver", frm.doc.approval_status=="Draft");
frm.toggle_enable("approval_status",
(frm.doc.exp_approver==frappe.session.user && frm.doc.docstatus==0));
frm.toggle_enable("employee", !(frm.doc.status=="Approved" || frm.doc.total_advance_paid));
frm.toggle_enable("advance_account", !frm.doc.total_advance_paid);
frm.toggle_enable("company", !(frm.doc.status=="Approved" || frm.doc.total_advance_paid));
if(frm.doc.docstatus == 1 && frm.doc.approval_status == 'Approved') {
frm.add_custom_button(__('Accounting Ledger'), function() {
frappe.route_options = {
voucher_no: frm.doc.name,
company: frm.doc.company,
group_by_voucher: false
};
frappe.set_route("query-report", "General Ledger");
}, __("View"));
}
if (frm.doc.docstatus==0 && frm.doc.exp_approver==frappe.session.user
&& frm.doc.approval_status=="Approved" && frm.doc.advance_required==0) {
frm.savesubmit();
}
if (frm.doc.docstatus==0 && frm.doc.approval_status=="Approved"
&& frm.doc.advance_required
&& cint(frm.doc.total_advance_paid) < cint(frm.doc.total_sanctioned_amount)
&& frappe.model.can_create("Payment Entry")) {
frm.add_custom_button(__('Advance Payment'),
function() { frm.events.make_payment_entry(frm); }, __("Make"));
frm.page.set_inner_btn_group_as_primary(__("Make"));
}
if (frm.doc.docstatus===1 && frm.doc.approval_status=="Approved"
&& (cint(frm.doc.total_amount_reimbursed) < cint(frm.doc.total_sanctioned_amount))
&& frappe.model.can_create("Payment Entry")) {
frm.add_custom_button(__('Payment'),
function() { frm.events.make_payment_entry(frm); }, __("Make"));
}
if(frm.doc.docstatus == 1 && frm.doc.approval_status == 'Approved') {
frm.add_custom_button(__('Accounting Ledger'), function() {
frappe.route_options = {
voucher_no: frm.doc.name,
company: frm.doc.company,
group_by_voucher: false
};
frappe.set_route("query-report", "General Ledger");
}, __("View"));
}
if (frm.doc.docstatus===1 && frm.doc.approval_status=="Approved") {
/* eslint-disable */
// no idea how `me` works here
if (cint(frm.doc.total_amount_reimbursed) > 0 && frappe.model.can_read("Journal Entry")) {
frm.add_custom_button(__('Bank Entries'), function() {
frappe.route_options = {
"Journal Entry Account.reference_type": frm.doc.doctype,
"Journal Entry Account.reference_name": frm.doc.name,
company: frm.doc.company
};
frappe.set_route("List", "Journal Entry");
}, __("View"));
}
/* eslint-enable */
}
if (frm.doc.docstatus===1 && frm.doc.approval_status=="Approved"
&& (cint(frm.doc.total_amount_reimbursed) < cint(frm.doc.total_sanctioned_amount))
&& frappe.model.can_create("Payment Entry")) {
frm.add_custom_button(__('Payment'),
function() { frm.events.make_payment_entry(frm); }, __("Make"));
}
},
@ -213,10 +199,6 @@ frappe.ui.form.on("Expense Claim", {
});
},
advance_required: function(frm) {
frm.refresh();
},
set_query_for_cost_center: function(frm) {
frm.fields_dict["cost_center"].get_query = function() {
return {
@ -227,18 +209,6 @@ frappe.ui.form.on("Expense Claim", {
};
},
set_query_for_advance_account: function(frm) {
frm.fields_dict["advance_account"].get_query = function() {
return {
filters: {
"report_type": "Balance Sheet",
"account_type": "Receivable",
"company": frm.doc.company
}
};
};
},
set_query_for_payable_account: function(frm) {
frm.fields_dict["payable_account"].get_query = function() {
return {

View File

@ -172,36 +172,6 @@
"unique": 0,
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "advance_required",
"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": "Advance Payment Required",
"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,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@ -576,37 +546,6 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "total_advance_paid",
"fieldtype": "Currency",
"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": "Total Advance Paid",
"length": 0,
"no_copy": 1,
"options": "Company:company:default_currency",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@ -854,38 +793,6 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "advance_account",
"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": "Advance Account",
"length": 0,
"no_copy": 0,
"options": "Account",
"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,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@ -1057,7 +964,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
"modified": "2017-07-17 15:48:23.255142",
"modified": "2017-07-17 15:47:23.255142",
"modified_by": "Administrator",
"module": "HR",
"name": "Expense Claim",

View File

@ -33,7 +33,6 @@ class ExpenseClaim(AccountsController):
self.set_payable_account()
self.set_cost_center()
self.set_status()
self.validate_advance_payment()
if self.task and not self.project:
self.project = frappe.db.get_value("Task", self.task, "project")
@ -44,8 +43,7 @@ class ExpenseClaim(AccountsController):
"2": "Cancelled"
}[cstr(self.docstatus or 0)]
total_paid_amount = flt(self.total_amount_reimbursed) + flt(self.total_advance_paid)
if self.total_sanctioned_amount > 0 and self.total_sanctioned_amount == total_paid_amount \
if self.total_sanctioned_amount > 0 and self.total_sanctioned_amount == self.total_amount_reimbursed \
and self.docstatus == 1 and self.approval_status == 'Approved':
self.status = "Paid"
elif self.total_sanctioned_amount > 0 and self.docstatus == 1 and self.approval_status == 'Approved':
@ -69,7 +67,7 @@ class ExpenseClaim(AccountsController):
self.make_gl_entries()
if self.is_paid:
update_paid_amount(self, self.payable_account)
update_reimbursed_amount(self)
self.set_status()
@ -79,7 +77,7 @@ class ExpenseClaim(AccountsController):
self.make_gl_entries(cancel=True)
if self.is_paid:
update_paid_amount(self, self.payable_account)
update_reimbursed_amount(self)
self.set_status()
@ -98,36 +96,19 @@ class ExpenseClaim(AccountsController):
gl_entry = []
self.validate_account_details()
outstanding_amount = flt(self.total_sanctioned_amount) - flt(self.total_advance_paid)
# payable entry
if outstanding_amount:
gl_entry.append(
self.get_gl_dict({
"account": self.payable_account,
"credit": outstanding_amount,
"credit_in_account_currency": outstanding_amount,
"against": ",".join([d.default_account for d in self.expenses]),
"party_type": "Employee",
"party": self.employee,
"against_voucher_type": self.doctype,
"against_voucher": self.name
})
)
if self.total_advance_paid:
gl_entry.append(
self.get_gl_dict({
"account": self.advance_account,
"credit": self.total_advance_paid,
"credit_in_account_currency": self.total_advance_paid,
"against": ",".join([d.default_account for d in self.expenses]),
"party_type": "Employee",
"party": self.employee,
"against_voucher_type": self.doctype,
"against_voucher": self.name
})
)
gl_entry.append(
self.get_gl_dict({
"account": self.payable_account,
"credit": self.total_sanctioned_amount,
"credit_in_account_currency": self.total_sanctioned_amount,
"against": ",".join([d.default_account for d in self.expenses]),
"party_type": "Employee",
"party": self.employee,
"against_voucher_type": self.doctype,
"against_voucher": self.name
})
)
# expense entries
for data in self.expenses:
@ -141,15 +122,14 @@ class ExpenseClaim(AccountsController):
})
)
if self.is_paid and outstanding_amount:
if self.is_paid:
# payment entry
payment_account = get_bank_cash_account(self.mode_of_payment, self.company).get("account")
gl_entry.append(
self.get_gl_dict({
"account": payment_account,
"credit": outstanding_amount,
"credit_in_account_currency": outstanding_amount,
"credit": self.total_sanctioned_amount,
"credit_in_account_currency": self.total_sanctioned_amount,
"against": self.employee
})
)
@ -160,8 +140,8 @@ class ExpenseClaim(AccountsController):
"party_type": "Employee",
"party": self.employee,
"against": payment_account,
"debit": outstanding_amount,
"debit_in_account_currency": outstanding_amount,
"debit": self.total_sanctioned_amount,
"debit_in_account_currency": self.total_sanctioned_amount,
"against_voucher": self.name,
"against_voucher_type": self.doctype,
})
@ -208,37 +188,18 @@ class ExpenseClaim(AccountsController):
def set_expense_account(self):
for expense in self.expenses:
if not expense.default_account:
expense.default_account = get_expense_claim_account(expense.expense_type,
self.company)["account"]
expense.default_account = get_expense_claim_account(expense.expense_type, self.company)["account"]
def validate_advance_payment(self):
if self.advance_required:
if self.docstatus == 1 and not self.total_advance_paid:
frappe.throw(_("Advance payment required before submission of the Expense Claim"))
elif self.total_advance_paid:
frappe.throw(_("As advance payment already done, cannot unset 'Advance Payment Required'"))
def update_reimbursed_amount(doc):
amt = frappe.db.sql("""select ifnull(sum(debit_in_account_currency), 0) as amt
from `tabGL Entry` where against_voucher_type = 'Expense Claim' and against_voucher = %s
and party = %s """, (doc.name, doc.employee) ,as_dict=1)[0].amt
def update_paid_amount(doc, party_account):
paid_amount = frappe.db.sql("""
select ifnull(sum(debit_in_account_currency), 0) as amount
from `tabGL Entry`
where
against_voucher_type = 'Expense Claim' and against_voucher = %s
and party = %s and account = %s
""", (doc.name, doc.employee, party_account) ,as_dict=1)[0].amount
doc.total_amount_reimbursed = amt
frappe.db.set_value("Expense Claim", doc.name , "total_amount_reimbursed", amt)
paid_amount_field = None
if party_account == doc.payable_account:
paid_amount_field = "total_amount_reimbursed"
elif party_account == doc.advance_account:
paid_amount_field = "total_advance_paid"
if paid_amount_field:
doc.set(paid_amount_field, paid_amount)
frappe.db.set_value("Expense Claim", doc.name , paid_amount_field, paid_amount)
doc.set_status()
frappe.db.set_value("Expense Claim", doc.name , "status", doc.status)
doc.set_status()
frappe.db.set_value("Expense Claim", doc.name , "status", doc.status)
@frappe.whitelist()
def get_expense_approver(doctype, txt, searchfield, start, page_len, filters):
@ -258,31 +219,25 @@ def make_bank_entry(dt, dn):
if not default_bank_cash_account:
default_bank_cash_account = get_default_bank_cash_account(expense_claim.company, "Cash")
if expense_claim.docstatus == 0:
party_account = expense_claim.advance_account
else:
party_account = expense_claim.payable_account
payment_amount = flt(expense_claim.total_sanctioned_amount) \
- flt(expense_claim.total_amount_reimbursed) - flt(expense_claim.total_advance_paid)
je = frappe.new_doc("Journal Entry")
je.voucher_type = 'Bank Entry'
je.company = expense_claim.company
je.remark = 'Advance ' if expense_claim.docstatus==0 else '' + 'Payment against Expense Claim: ' + dn;
je.remark = 'Payment against Expense Claim: ' + dn;
je.append("accounts", {
"account": party_account,
"debit_in_account_currency": payment_amount,
"account": expense_claim.payable_account,
"debit_in_account_currency": flt(expense_claim.total_sanctioned_amount - expense_claim.total_amount_reimbursed),
"reference_type": "Expense Claim",
"reference_name": expense_claim.name,
"party_type": "Employee",
"party": expense_claim.employee
"party": expense_claim.employee,
"reference_name": expense_claim.name
})
je.append("accounts", {
"account": default_bank_cash_account.account,
"credit_in_account_currency": payment_amount,
"credit_in_account_currency": flt(expense_claim.total_sanctioned_amount - expense_claim.total_amount_reimbursed),
"reference_type": "Expense Claim",
"reference_name": expense_claim.name,
"balance": default_bank_cash_account.balance,
"account_currency": default_bank_cash_account.account_currency,
"account_type": default_bank_cash_account.account_type

View File

@ -6,7 +6,6 @@ import frappe
import unittest
from frappe.utils import random_string, nowdate
from erpnext.hr.doctype.expense_claim.expense_claim import make_bank_entry
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
test_records = frappe.get_test_records('Expense Claim')
@ -23,35 +22,28 @@ class TestExpenseClaim(unittest.TestCase):
[{ "title": "_Test Project Task 1", "status": "Open" }]
}).save()
existing_claimed_amount = frappe.db.get_value("Project", "_Test Project 1", "total_expense_claim")
task_name = frappe.db.get_value("Task", {"project": "_Test Project 1"})
payable_account = get_payable_account("Wind Power LLC")
make_expense_claim(300, 200,"Travel Expenses - WP", "Wind Power LLC",
payable_account, "_Test Project 1", task_name)
make_expense_claim(payable_account, 300, 200, "Wind Power LLC","Travel Expenses - WP", "_Test Project 1", task_name)
self.assertEqual(frappe.db.get_value("Task", task_name, "total_expense_claim"), 200)
self.assertEqual(frappe.db.get_value("Project", "_Test Project 1", "total_expense_claim"),
existing_claimed_amount + 200)
self.assertEqual(frappe.db.get_value("Project", "_Test Project 1", "total_expense_claim"), 200)
expense_claim2 = make_expense_claim(600, 500, "Travel Expenses - WP", "Wind Power LLC",
payable_account, "_Test Project 1", task_name)
expense_claim2 = make_expense_claim(payable_account, 600, 500, "Wind Power LLC", "Travel Expenses - WP","_Test Project 1", task_name)
self.assertEqual(frappe.db.get_value("Task", task_name, "total_expense_claim"), 700)
self.assertEqual(frappe.db.get_value("Project", "_Test Project 1", "total_expense_claim"),
existing_claimed_amount + 700)
self.assertEqual(frappe.db.get_value("Project", "_Test Project 1", "total_expense_claim"), 700)
expense_claim2.cancel()
frappe.delete_doc("Expense Claim", expense_claim2.name)
self.assertEqual(frappe.db.get_value("Task", task_name, "total_expense_claim"), 200)
self.assertEqual(frappe.db.get_value("Project", "_Test Project 1", "total_expense_claim"),
existing_claimed_amount+200)
self.assertEqual(frappe.db.get_value("Project", "_Test Project 1", "total_expense_claim"), 200)
def test_expense_claim_status(self):
payable_account = get_payable_account("Wind Power LLC")
expense_claim = make_expense_claim(300, 200, "Travel Expenses - WP",
"Wind Power LLC", payable_account)
expense_claim = make_expense_claim(payable_account, 300, 200, "Wind Power LLC", "Travel Expenses - WP")
je_dict = make_bank_entry("Expense Claim", expense_claim.name)
je = frappe.get_doc(je_dict)
@ -69,8 +61,7 @@ class TestExpenseClaim(unittest.TestCase):
def test_expense_claim_gl_entry(self):
payable_account = get_payable_account("Wind Power LLC")
expense_claim = make_expense_claim(300, 200, "Travel Expenses - WP",
"Wind Power LLC", payable_account)
expense_claim = make_expense_claim(payable_account, 300, 200, "Wind Power LLC", "Travel Expenses - WP")
expense_claim.submit()
gl_entries = frappe.db.sql("""select account, debit, credit
@ -107,82 +98,25 @@ class TestExpenseClaim(unittest.TestCase):
gl_entry = frappe.get_all('GL Entry', {'voucher_type': 'Expense Claim', 'voucher_no': expense_claim.name})
self.assertEquals(len(gl_entry), 0)
def test_advance_payment(self):
expense_claim = make_expense_claim(150, 150, "Travel Expenses - _TC",
advance_required=1, submit=False)
payment_entry = get_payment_entry("Expense Claim", expense_claim.name, bank_amount=50)
payment_entry.received_amount = payment_entry.paid_amount = 50
payment_entry.get("references")[0].allocated_amount = 50
payment_entry.reference_no = "1"
payment_entry.reference_date = "2016-01-01"
payment_entry.save()
payment_entry.submit()
expense_claim.load_from_db()
self.assertEqual(expense_claim.total_advance_paid, 50)
expense_claim.submit()
payment_entry = get_payment_entry("Expense Claim", expense_claim.name)
payment_entry.reference_no = "1"
payment_entry.reference_date = "2016-01-01"
payment_entry.save()
payment_entry.submit()
expense_claim.load_from_db()
self.assertEqual(expense_claim.total_advance_paid, 50)
self.assertEqual(expense_claim.total_amount_reimbursed, 100)
gl_entries = frappe.db.sql("""select account, debit, credit
from `tabGL Entry` where voucher_type='Expense Claim' and voucher_no=%s
order by account asc""", expense_claim.name, as_dict=1)
self.assertTrue(gl_entries)
expected_values = dict((d[0], d) for d in [
[get_advance_account("_Test Company"), 0.0, 50.0],
[get_payable_account("_Test Company"), 0.0, 100.0],
["Travel Expenses - _TC", 150.0, 0.0]
])
for gle in gl_entries:
self.assertEquals(expected_values[gle.account][0], gle.account)
self.assertEquals(expected_values[gle.account][1], gle.debit)
self.assertEquals(expected_values[gle.account][2], gle.credit)
def get_payable_account(company):
return frappe.db.get_value('Company', company, 'default_payable_account')
def get_advance_account(company):
return frappe.db.get_value('Company', company, 'default_advance_account') \
or frappe.db.get_value('Company', company, 'default_receivable_account')
def make_expense_claim(claim_amount, sanctioned_amount, expense_account, company="_Test Company",
payable_account=None, project=None, task_name=None,
advance_required=0, advance_account=None, submit=True):
def make_expense_claim(payable_account,claim_amount, sanctioned_amount, company, account, project=None, task_name=None):
expense_claim = frappe.get_doc({
"doctype": "Expense Claim",
"employee": "_T-Employee-0001",
"payable_account": payable_account or get_payable_account(company),
"advance_account": advance_account or get_advance_account(company),
"advance_required": advance_required,
"payable_account": payable_account,
"approval_status": "Approved",
"company": company,
"expenses": [{
"expense_type": "Travel",
"default_account": expense_account,
"claim_amount": claim_amount,
"sanctioned_amount": sanctioned_amount
}]
})
"expenses":
[{ "expense_type": "Travel", "default_account": account, "claim_amount": claim_amount, "sanctioned_amount": sanctioned_amount }]
})
if project:
expense_claim.project = project
if task_name:
expense_claim.task = task_name
expense_claim.save()
if submit:
expense_claim.submit()
expense_claim.submit()
return expense_claim

View File

@ -149,7 +149,6 @@ erpnext.company.setup_queries = function(frm) {
["default_bank_account", {"account_type": "Bank"}],
["default_cash_account", {"account_type": "Cash"}],
["default_receivable_account", {"account_type": "Receivable"}],
["default_advance_account", {"account_type": "Receivable"}],
["default_payable_account", {"account_type": "Payable"}],
["default_expense_account", {"root_type": "Expense"}],
["default_income_account", {"root_type": "Income"}],

View File

@ -901,38 +901,6 @@
"unique": 0,
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:!doc.__islocal",
"fieldname": "default_advance_account",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Default Advance Account",
"length": 0,
"no_copy": 1,
"options": "Account",
"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,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@ -2023,7 +1991,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
"modified": "2017-09-14 18:12:10.008743",
"modified": "2017-08-31 11:48:56.278568",
"modified_by": "Administrator",
"module": "Setup",
"name": "Company",