Merge branch 'develop' into fix-minor-custom-cash-flow
This commit is contained in:
commit
8e7c214e9e
@ -42,10 +42,18 @@ class ExpenseClaim(AccountsController):
|
||||
"2": "Cancelled"
|
||||
}[cstr(self.docstatus or 0)]
|
||||
|
||||
paid_amount = flt(self.total_amount_reimbursed) + flt(self.total_advance_amount)
|
||||
precision = self.precision("grand_total")
|
||||
if (self.is_paid or (flt(self.total_sanctioned_amount) > 0 and self.docstatus == 1
|
||||
and flt(self.grand_total, precision) == flt(paid_amount, precision))) and self.approval_status == 'Approved':
|
||||
|
||||
if (
|
||||
# set as paid
|
||||
self.is_paid
|
||||
or (flt(self.total_sanctioned_amount > 0) and (
|
||||
# grand total is reimbursed
|
||||
(self.docstatus == 1 and flt(self.grand_total, precision) == flt(self.total_amount_reimbursed, precision))
|
||||
# grand total (to be paid) is 0 since linked advances already cover the claimed amount
|
||||
or (flt(self.grand_total, precision) == 0)
|
||||
))
|
||||
) and self.approval_status == "Approved":
|
||||
status = "Paid"
|
||||
elif flt(self.total_sanctioned_amount) > 0 and self.docstatus == 1 and self.approval_status == 'Approved':
|
||||
status = "Unpaid"
|
||||
|
@ -72,6 +72,72 @@ class TestExpenseClaim(unittest.TestCase):
|
||||
expense_claim = frappe.get_doc("Expense Claim", expense_claim.name)
|
||||
self.assertEqual(expense_claim.status, "Unpaid")
|
||||
|
||||
# expense claim without any sanctioned amount should not have status as Paid
|
||||
claim = make_expense_claim(payable_account, 1000, 0, "_Test Company", "Travel Expenses - _TC")
|
||||
self.assertEqual(claim.total_sanctioned_amount, 0)
|
||||
self.assertEqual(claim.status, "Submitted")
|
||||
|
||||
# no gl entries created
|
||||
gl_entry = frappe.get_all('GL Entry', {'voucher_type': 'Expense Claim', 'voucher_no': claim.name})
|
||||
self.assertEqual(len(gl_entry), 0)
|
||||
|
||||
def test_expense_claim_against_fully_paid_advances(self):
|
||||
from erpnext.hr.doctype.employee_advance.test_employee_advance import (
|
||||
get_advances_for_claim,
|
||||
make_employee_advance,
|
||||
make_payment_entry,
|
||||
)
|
||||
|
||||
frappe.db.delete("Employee Advance")
|
||||
|
||||
payable_account = get_payable_account("_Test Company")
|
||||
claim = make_expense_claim(payable_account, 1000, 1000, "_Test Company", "Travel Expenses - _TC", do_not_submit=True)
|
||||
|
||||
advance = make_employee_advance(claim.employee)
|
||||
pe = make_payment_entry(advance)
|
||||
pe.submit()
|
||||
|
||||
# claim for already paid out advances
|
||||
claim = get_advances_for_claim(claim, advance.name)
|
||||
claim.save()
|
||||
claim.submit()
|
||||
|
||||
self.assertEqual(claim.grand_total, 0)
|
||||
self.assertEqual(claim.status, "Paid")
|
||||
|
||||
def test_expense_claim_partially_paid_via_advance(self):
|
||||
from erpnext.hr.doctype.employee_advance.test_employee_advance import (
|
||||
get_advances_for_claim,
|
||||
make_employee_advance,
|
||||
)
|
||||
from erpnext.hr.doctype.employee_advance.test_employee_advance import (
|
||||
make_payment_entry as make_advance_payment,
|
||||
)
|
||||
|
||||
frappe.db.delete("Employee Advance")
|
||||
|
||||
payable_account = get_payable_account("_Test Company")
|
||||
claim = make_expense_claim(payable_account, 1000, 1000, "_Test Company", "Travel Expenses - _TC", do_not_submit=True)
|
||||
|
||||
# link advance for partial amount
|
||||
advance = make_employee_advance(claim.employee, {'advance_amount': 500})
|
||||
pe = make_advance_payment(advance)
|
||||
pe.submit()
|
||||
|
||||
claim = get_advances_for_claim(claim, advance.name)
|
||||
claim.save()
|
||||
claim.submit()
|
||||
|
||||
self.assertEqual(claim.grand_total, 500)
|
||||
self.assertEqual(claim.status, "Unpaid")
|
||||
|
||||
# reimburse remaning amount
|
||||
make_payment_entry(claim, payable_account, 500)
|
||||
claim.reload()
|
||||
|
||||
self.assertEqual(claim.total_amount_reimbursed, 500)
|
||||
self.assertEqual(claim.status, "Paid")
|
||||
|
||||
def test_expense_claim_gl_entry(self):
|
||||
payable_account = get_payable_account(company_name)
|
||||
taxes = generate_taxes()
|
||||
|
@ -351,7 +351,6 @@
|
||||
"hide_border": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "get_items_from",
|
||||
"fieldname": "sub_assembly_items",
|
||||
"fieldtype": "Table",
|
||||
"label": "Sub Assembly Items",
|
||||
@ -385,7 +384,7 @@
|
||||
"index_web_pages_for_search": 1,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2022-03-14 03:56:23.209247",
|
||||
"modified": "2022-03-25 09:15:25.017664",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "Production Plan",
|
||||
|
@ -362,3 +362,4 @@ erpnext.patches.v14_0.update_employee_advance_status
|
||||
erpnext.patches.v13_0.add_cost_center_in_loans
|
||||
erpnext.patches.v13_0.set_return_against_in_pos_invoice_references
|
||||
erpnext.patches.v13_0.remove_unknown_links_to_prod_plan_items # 24-03-2022
|
||||
erpnext.patches.v13_0.update_expense_claim_status_for_paid_advances
|
||||
|
@ -0,0 +1,22 @@
|
||||
import frappe
|
||||
|
||||
|
||||
def execute():
|
||||
"""
|
||||
Update Expense Claim status to Paid if:
|
||||
- the entire required amount is already covered via linked advances
|
||||
- the claim is partially paid via advances and the rest is reimbursed
|
||||
"""
|
||||
|
||||
ExpenseClaim = frappe.qb.DocType('Expense Claim')
|
||||
|
||||
(frappe.qb
|
||||
.update(ExpenseClaim)
|
||||
.set(ExpenseClaim.status, 'Paid')
|
||||
.where(
|
||||
((ExpenseClaim.grand_total == 0) | (ExpenseClaim.grand_total == ExpenseClaim.total_amount_reimbursed))
|
||||
& (ExpenseClaim.approval_status == 'Approved')
|
||||
& (ExpenseClaim.docstatus == 1)
|
||||
& (ExpenseClaim.total_sanctioned_amount > 0)
|
||||
)
|
||||
).run()
|
@ -1044,7 +1044,7 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
|
||||
var company_currency = this.get_company_currency();
|
||||
// Added `ignore_price_list` to determine if document is loading after mapping from another doc
|
||||
if(this.frm.doc.currency && this.frm.doc.currency !== company_currency
|
||||
&& !this.frm.doc.__onload.ignore_price_list) {
|
||||
&& !(this.frm.doc.__onload && this.frm.doc.__onload.ignore_price_list)) {
|
||||
|
||||
this.get_exchange_rate(transaction_date, this.frm.doc.currency, company_currency,
|
||||
function(exchange_rate) {
|
||||
@ -1145,7 +1145,8 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
|
||||
|
||||
var company_currency = this.get_company_currency();
|
||||
// Added `ignore_price_list` to determine if document is loading after mapping from another doc
|
||||
if(this.frm.doc.price_list_currency !== company_currency && !this.frm.doc.__onload.ignore_price_list) {
|
||||
if(this.frm.doc.price_list_currency !== company_currency &&
|
||||
!(this.frm.doc.__onload && this.frm.doc.__onload.ignore_price_list)) {
|
||||
this.get_exchange_rate(this.frm.doc.posting_date, this.frm.doc.price_list_currency, company_currency,
|
||||
function(exchange_rate) {
|
||||
me.frm.set_value("plc_conversion_rate", exchange_rate);
|
||||
|
Loading…
x
Reference in New Issue
Block a user