Loan Management for the Members (Non Profit Module) (#13149)
* Renamed - Employee Loan Application to Loan Application, Employee Loan to Loan and field Employee Loan Account to Loan Account * Patch added * Dynamic link fields 'applicant' and 'applicant_type' * Member link visible only if domain non profit is active * Modified loan_dashboard * Make Repayment Entry button * Common file loan_common.js for loan and loan_application * repayment schedule rows selection in dialog * validation if repayment amount > total paid amount * repayment only if disbursement is done, make repayment by selecting the installment which falls in the current month * fetch nowdate if disbursement date not found * Rebased with develop * updated non-profit module page * updated patch for renamed fields * dialog to select repayment entries * hidden field to store reschedule paid status * update paid check in loan on journal entry updation * calculate total paid * updated docs * codacy fix
This commit is contained in:
parent
1c3830c53f
commit
4dc453d131
@ -810,6 +810,37 @@
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "paid_loan",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Paid Loan",
|
||||
"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,
|
||||
|
@ -9,7 +9,7 @@ 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_reimbursed_amount
|
||||
from erpnext.hr.doctype.employee_loan.employee_loan import update_disbursement_status
|
||||
from erpnext.hr.doctype.loan.loan import update_disbursement_status, update_total_amount_paid
|
||||
|
||||
from six import string_types, iteritems
|
||||
|
||||
@ -46,9 +46,9 @@ class JournalEntry(AccountsController):
|
||||
def on_submit(self):
|
||||
self.check_credit_limit()
|
||||
self.make_gl_entries()
|
||||
self.update_loan()
|
||||
self.update_advance_paid()
|
||||
self.update_expense_claim()
|
||||
self.update_employee_loan()
|
||||
|
||||
def get_title(self):
|
||||
return self.pay_to_recd_from or self.accounts[0].account
|
||||
@ -72,7 +72,7 @@ class JournalEntry(AccountsController):
|
||||
self.make_gl_entries(1)
|
||||
self.update_advance_paid()
|
||||
self.update_expense_claim()
|
||||
self.update_employee_loan()
|
||||
self.update_loan()
|
||||
self.unlink_advance_entry_reference()
|
||||
self.unlink_asset_reference()
|
||||
|
||||
@ -518,11 +518,17 @@ class JournalEntry(AccountsController):
|
||||
doc = frappe.get_doc("Expense Claim", d.reference_name)
|
||||
update_reimbursed_amount(doc)
|
||||
|
||||
def update_employee_loan(self):
|
||||
def update_loan(self):
|
||||
if self.paid_loan:
|
||||
paid_loan = json.loads(self.paid_loan)
|
||||
value = 1 if self.docstatus < 2 else 0
|
||||
for name in paid_loan:
|
||||
frappe.db.set_value("Repayment Schedule", name, "paid", value)
|
||||
for d in self.accounts:
|
||||
if d.reference_type=="Employee Loan" and flt(d.debit) > 0:
|
||||
doc = frappe.get_doc("Employee Loan", d.reference_name)
|
||||
if d.reference_type=="Loan" and flt(d.debit) > 0:
|
||||
doc = frappe.get_doc("Loan", d.reference_name)
|
||||
update_disbursement_status(doc)
|
||||
update_total_amount_paid(doc)
|
||||
|
||||
def validate_expense_claim(self):
|
||||
for d in self.accounts:
|
||||
|
@ -618,7 +618,7 @@
|
||||
"label": "Reference Type",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "\nSales Invoice\nPurchase Invoice\nJournal Entry\nSales Order\nPurchase Order\nExpense Claim\nAsset\nEmployee Loan\nPayroll Entry\nEmployee Advance",
|
||||
"options": "\nSales Invoice\nPurchase Invoice\nJournal Entry\nSales Order\nPurchase Order\nExpense Claim\nAsset\nLoan\nPayroll Entry\nEmployee Advance",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
|
@ -159,7 +159,7 @@ def get_data():
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": _("Employee Loan Management"),
|
||||
"label": _("Loan Management"),
|
||||
"icon": "icon-list",
|
||||
"items": [
|
||||
{
|
||||
@ -169,12 +169,12 @@ def get_data():
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Employee Loan Application",
|
||||
"description": _("Employee Loan Application")
|
||||
"name": "Loan Application",
|
||||
"description": _("Loan Application")
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Employee Loan"
|
||||
"name": "Loan"
|
||||
},
|
||||
]
|
||||
},
|
||||
|
@ -64,6 +64,26 @@ def get_data():
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": _("Loan Management"),
|
||||
"icon": "icon-list",
|
||||
"items": [
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Loan Type",
|
||||
"description": _("Define various loan types")
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Loan Application",
|
||||
"description": _("Loan Application")
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Loan"
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": _("Grant Application"),
|
||||
"items": [
|
||||
|
BIN
erpnext/docs/assets/img/human-resources/loan-repayment.gif
Normal file
BIN
erpnext/docs/assets/img/human-resources/loan-repayment.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.1 MiB |
@ -1,3 +1,3 @@
|
||||
employees-loan-management
|
||||
loan-management
|
||||
leave-calculation-in-salary-slip
|
||||
working-days-in-salary-slip
|
@ -1,16 +1,16 @@
|
||||
<h1>Employees Loan Management</h1>
|
||||
<h1>Loan Management</h1>
|
||||
|
||||
Employee Loan is an sum of money paid by Employer to Employee based on certain terms and condition. There are multiple ways accounting for the Employee loan can be managed. Company could collect loan from an employee separately. Or they can choose to deduct loan installment from the employee's salary.
|
||||
Loan is an sum of money paid by Employer to Employee based on certain terms and condition. There are multiple ways accounting for the loan can be managed. Company could collect loan from an employee separately. Or they can choose to deduct loan installment from the employee's salary.
|
||||
|
||||
Let's check below how accounting can be managed for Employee Loan in ERPNext.
|
||||
Let's check below how accounting can be managed for Loan in ERPNext.
|
||||
|
||||
### 1. Setup Masters
|
||||
|
||||
Create following Groups and Ledgers in Chart of Accounts if not there.
|
||||
|
||||
#### 1.1 Employee Loan Account
|
||||
#### 1.1 Loan Account
|
||||
|
||||
Create Group as 'Employees Loans' under Current Assets and create employee loan A/C (Ledger) under it. [Check this link for new account creation](/docs/user/manual/en/setting-up/articles/managing-tree-structure-masters)
|
||||
Create Group as 'Loans' under Current Assets and create loan A/C (Ledger) under it. [Check this link for new account creation](/docs/user/manual/en/setting-up/articles/managing-tree-structure-masters)
|
||||
|
||||
![CoA]({{docs_base_url}}/assets/img/articles/Selection_433.png)
|
||||
|
||||
@ -26,7 +26,7 @@ Create Ledger as 'Interest on Loan' under Indirect Income.
|
||||
|
||||
### 2. Book Loan Amount
|
||||
|
||||
Once loan amount is finalized, make journal voucher to book loan payment entry. You should Credit Loan amount to Bank/Cash account and Debit Loan amount employee loan account.
|
||||
Once loan amount is finalized, make journal voucher to book loan payment entry. You should Credit Loan amount to Bank/Cash account and Debit Loan amount loan account.
|
||||
|
||||
![Loan Entry]({{docs_base_url}}/assets/img/articles/Selection_435.png)
|
||||
|
@ -1,60 +0,0 @@
|
||||
# Employee Loan Management
|
||||
This module enables companies which provides employee loans to define and manage employee loans.
|
||||
Employees can request loans, which are then reviewed and approved. For the approved loans,
|
||||
repayment schedule for the entire loan cycle can be generated and automatic deduction from salary can also be set up.
|
||||
|
||||
### Loan Type
|
||||
To create a new Loan Type go to:
|
||||
|
||||
> Human Resources > Employee Loan Management > Loan Type > New Loan Type
|
||||
|
||||
Configure Loan limit and Rate of interest.
|
||||
|
||||
<img class="screenshot" alt="Loan Type" src="{{docs_base_url}}/assets/img/human-resources/loan-type.png">
|
||||
|
||||
### Employee Loan Application
|
||||
|
||||
Employee can apply for loan by going to:
|
||||
|
||||
> Human Resources > Employee Loan Management > Employee Loan Application > New Employee Loan Application
|
||||
|
||||
<img class="screenshot" alt="Employee Loan Application" src="{{docs_base_url}}/assets/img/human-resources/employee-loan-application.png">
|
||||
|
||||
#### In the Employee Loan Application,
|
||||
|
||||
* Enter Employee details and Loan details
|
||||
* Select the repayment method, and based on your selection enter Repayment Period in Months or repayment Amount
|
||||
|
||||
On save, Employee can see Repayment Information and make changes if required before submitting.
|
||||
|
||||
<img class="screenshot" alt="Employee Loan Application" src="{{docs_base_url}}/assets/img/human-resources/repayment-info.png">
|
||||
|
||||
### Employee Loan
|
||||
|
||||
Once the Loan is approved, Manager can create Employee Loan record for the Employee.
|
||||
|
||||
> Human Resources > Employee Loan Management > Employee Loan > New Employee Loan
|
||||
|
||||
<img class="screenshot" alt="Employee Loan Application" src="{{docs_base_url}}/assets/img/human-resources/employee-loan.png">
|
||||
|
||||
#### In the Employee Loan,
|
||||
|
||||
* Enter Employee and Loan Application
|
||||
* Check "Repay from Salary" if the loan repayment will be deducted from the salary
|
||||
* Enter Disbursement Date and Account Info
|
||||
* As soon as you hit save, the repayment schedule is generated.
|
||||
|
||||
<img class="screenshot" alt="repayment Schedule" src="{{docs_base_url}}/assets/img/human-resources/repayment-schedule.png">
|
||||
|
||||
#### Loan repayment deduction from Salary
|
||||
|
||||
To auto deduct the Loan repayment from Salary, check "Repay from Salary" in Employee Loan. It will appear as Loan repayment in Salary Slip.
|
||||
|
||||
<img class="screenshot" alt="Salary Slip" src="{{docs_base_url}}/assets/img/human-resources/loan-repayment-salary-slip.png">
|
||||
|
||||
<div class="embed-container">
|
||||
<iframe src="https://www.youtube.com/embed/IUM0t7t4zFU?rel=0" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen>
|
||||
</iframe>
|
||||
</div>
|
||||
|
||||
{nex}
|
@ -17,5 +17,5 @@ holiday-list
|
||||
human-resource-setup
|
||||
daily-work-summary
|
||||
fleet-management
|
||||
employee-loan-management
|
||||
loan-management
|
||||
articles
|
||||
|
@ -0,0 +1,69 @@
|
||||
# Loan Management
|
||||
This module enables companies which provides loans to define and manage loans.
|
||||
Employees can request loans, which are then reviewed and approved. For the approved loans,
|
||||
repayment schedule for the entire loan cycle can be generated and automatic deduction from salary can also be set up.
|
||||
|
||||
### Loan Type
|
||||
To create a new Loan Type go to:
|
||||
|
||||
> Human Resources > Loan Management > Loan Type > New Loan Type
|
||||
|
||||
Configure Loan limit and Rate of interest.
|
||||
|
||||
<img class="screenshot" alt="Loan Type" src="{{docs_base_url}}/assets/img/human-resources/loan-type.png">
|
||||
|
||||
### Loan Application
|
||||
|
||||
Employee can apply for loan by going to:
|
||||
|
||||
> Human Resources > Loan Management > Loan Application > New Loan Application
|
||||
|
||||
<img class="screenshot" alt="Loan Application" src="{{docs_base_url}}/assets/img/human-resources/employee-loan-application.png">
|
||||
|
||||
#### In the Loan Application,
|
||||
|
||||
* Enter Employee details and Loan details
|
||||
* Select the repayment method, and based on your selection enter Repayment Period in Months or repayment Amount
|
||||
|
||||
On save, Employee can see Repayment Information and make changes if required before submitting.
|
||||
|
||||
<img class="screenshot" alt="Loan Application" src="{{docs_base_url}}/assets/img/human-resources/repayment-info.png">
|
||||
|
||||
### Loan
|
||||
|
||||
Once the Loan is approved, Manager can create Loan record for the Employee.
|
||||
|
||||
> Human Resources > Loan Management > Loan > New Loan
|
||||
|
||||
<img class="screenshot" alt="Loan Application" src="{{docs_base_url}}/assets/img/human-resources/employee-loan.png">
|
||||
|
||||
#### In the Loan,
|
||||
|
||||
* Enter Employee and Loan Application
|
||||
* Check "Repay from Salary" if the loan repayment will be deducted from the salary
|
||||
* Enter Disbursement Date, Repayment Start Date, and Account Info
|
||||
* If the amount has been disbursed and status is set to "Disbursed", as soon as you hit save, the repayment schedule is generated.
|
||||
* The first repayment payment date would be set as per the "Repayment Start Date".
|
||||
|
||||
<img class="screenshot" alt="repayment Schedule" src="{{docs_base_url}}/assets/img/human-resources/repayment-schedule.png">
|
||||
|
||||
#### Loan Repayment for Members
|
||||
|
||||
* After submitting the document, if the status is "Disbursed" and "Repay from Salary" is unchecked, you can click on "Make Repayment Entry" and select the payments which haven't been paid till date.
|
||||
* After selecting the rows, you will be routed to Journal Entry where the selected payments will be added and placed in their respective Debit/ Credit accounts.
|
||||
* On submitting the Journal Entry, "Paid" will be checked in the payment rows of the Repayment Schedule, for which the Journal entry has been created.
|
||||
|
||||
<img class="screenshot" alt="Make Repayment" src="{{docs_base_url}}/assets/img/human-resources/loan-repayment.gif">
|
||||
|
||||
#### Loan repayment deduction from Salary
|
||||
|
||||
To auto deduct the Loan repayment from Salary, check "Repay from Salary" in Loan. It will appear as Loan repayment in Salary Slip.
|
||||
|
||||
<img class="screenshot" alt="Salary Slip" src="{{docs_base_url}}/assets/img/human-resources/loan-repayment-salary-slip.png">
|
||||
|
||||
<div class="embed-container">
|
||||
<iframe src="https://www.youtube.com/embed/IUM0t7t4zFU?rel=0" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen>
|
||||
</iframe>
|
||||
</div>
|
||||
|
||||
{next}
|
@ -1,118 +0,0 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Employee Loan', {
|
||||
onload: function (frm) {
|
||||
frm.set_query("employee_loan_application", function () {
|
||||
return {
|
||||
"filters": {
|
||||
"employee": frm.doc.employee,
|
||||
"docstatus": 1,
|
||||
"status": "Approved"
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
frm.set_query("interest_income_account", function () {
|
||||
return {
|
||||
"filters": {
|
||||
"company": frm.doc.company,
|
||||
"root_type": "Income",
|
||||
"is_group": 0
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
frm.set_query("employee", function() {
|
||||
return {
|
||||
"filters": {
|
||||
"company": frm.doc.company,
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
$.each(["payment_account", "employee_loan_account"], function (i, field) {
|
||||
frm.set_query(field, function () {
|
||||
return {
|
||||
"filters": {
|
||||
"company": frm.doc.company,
|
||||
"root_type": "Asset",
|
||||
"is_group": 0
|
||||
}
|
||||
};
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
refresh: function (frm) {
|
||||
if (frm.doc.docstatus == 1 && (frm.doc.status == "Sanctioned" || frm.doc.status == "Partially Disbursed")) {
|
||||
frm.add_custom_button(__('Make Disbursement Entry'), function () {
|
||||
frm.trigger("make_jv");
|
||||
})
|
||||
}
|
||||
frm.trigger("toggle_fields");
|
||||
},
|
||||
|
||||
make_jv: function (frm) {
|
||||
frappe.call({
|
||||
args: {
|
||||
"employee_loan": frm.doc.name,
|
||||
"company": frm.doc.company,
|
||||
"employee_loan_account": frm.doc.employee_loan_account,
|
||||
"employee": frm.doc.employee,
|
||||
"loan_amount": frm.doc.loan_amount,
|
||||
"payment_account": frm.doc.payment_account
|
||||
},
|
||||
method: "erpnext.hr.doctype.employee_loan.employee_loan.make_jv_entry",
|
||||
callback: function (r) {
|
||||
if (r.message)
|
||||
var doc = frappe.model.sync(r.message)[0];
|
||||
frappe.set_route("Form", doc.doctype, doc.name);
|
||||
}
|
||||
})
|
||||
},
|
||||
mode_of_payment: function (frm) {
|
||||
frappe.call({
|
||||
method: "erpnext.accounts.doctype.sales_invoice.sales_invoice.get_bank_cash_account",
|
||||
args: {
|
||||
"mode_of_payment": frm.doc.mode_of_payment,
|
||||
"company": frm.doc.company
|
||||
},
|
||||
callback: function (r, rt) {
|
||||
if (r.message) {
|
||||
frm.set_value("payment_account", r.message.account);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
employee_loan_application: function (frm) {
|
||||
if(frm.doc.employee_loan_application){
|
||||
return frappe.call({
|
||||
method: "erpnext.hr.doctype.employee_loan.employee_loan.get_employee_loan_application",
|
||||
args: {
|
||||
"employee_loan_application": frm.doc.employee_loan_application
|
||||
},
|
||||
callback: function (r) {
|
||||
if (!r.exc && r.message) {
|
||||
frm.set_value("loan_type", r.message.loan_type);
|
||||
frm.set_value("loan_amount", r.message.loan_amount);
|
||||
frm.set_value("repayment_method", r.message.repayment_method);
|
||||
frm.set_value("monthly_repayment_amount", r.message.repayment_amount);
|
||||
frm.set_value("repayment_periods", r.message.repayment_periods);
|
||||
frm.set_value("rate_of_interest", r.message.rate_of_interest);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
repayment_method: function (frm) {
|
||||
frm.trigger("toggle_fields")
|
||||
},
|
||||
|
||||
toggle_fields: function (frm) {
|
||||
frm.toggle_enable("monthly_repayment_amount", frm.doc.repayment_method == "Repay Fixed Amount per Period")
|
||||
frm.toggle_enable("repayment_periods", frm.doc.repayment_method == "Repay Over Number of Periods")
|
||||
}
|
||||
});
|
239
erpnext/hr/doctype/loan/loan.js
Normal file
239
erpnext/hr/doctype/loan/loan.js
Normal file
@ -0,0 +1,239 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
{% include 'erpnext/hr/loan_common.js' %};
|
||||
|
||||
frappe.ui.form.on('Loan', {
|
||||
onload: function (frm) {
|
||||
frm.set_query("loan_application", function () {
|
||||
return {
|
||||
"filters": {
|
||||
"applicant": frm.doc.applicant,
|
||||
"docstatus": 1,
|
||||
"status": "Approved"
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
frm.set_query("interest_income_account", function () {
|
||||
return {
|
||||
"filters": {
|
||||
"company": frm.doc.company,
|
||||
"root_type": "Income",
|
||||
"is_group": 0
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
$.each(["payment_account", "loan_account"], function (i, field) {
|
||||
frm.set_query(field, function () {
|
||||
return {
|
||||
"filters": {
|
||||
"company": frm.doc.company,
|
||||
"root_type": "Asset",
|
||||
"is_group": 0
|
||||
}
|
||||
};
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
refresh: function (frm) {
|
||||
if (frm.doc.docstatus == 1 && frm.doc.status == "Sanctioned") {
|
||||
frm.add_custom_button(__('Make Disbursement Entry'), function() {
|
||||
frm.trigger("make_jv");
|
||||
})
|
||||
}
|
||||
if (frm.doc.repayment_schedule) {
|
||||
let total_amount_paid = 0;
|
||||
$.each(frm.doc.repayment_schedule || [], function(i, row) {
|
||||
if (row.paid) {
|
||||
total_amount_paid += row.total_payment;
|
||||
}
|
||||
});
|
||||
frm.set_value("total_amount_paid", total_amount_paid);
|
||||
; }
|
||||
if (frm.doc.docstatus == 1 && frm.doc.repayment_start_date && (frm.doc.applicant_type == 'Member' || frm.doc.repay_from_salary == 0)) {
|
||||
frm.add_custom_button(__('Make Repayment Entry'), function() {
|
||||
frm.trigger("make_repayment_entry");
|
||||
})
|
||||
}
|
||||
frm.trigger("toggle_fields");
|
||||
},
|
||||
status: function (frm) {
|
||||
frm.toggle_reqd("disbursement_date", frm.doc.status == 'Disbursed')
|
||||
frm.toggle_reqd("repayment_start_date", frm.doc.status == 'Disbursed')
|
||||
},
|
||||
|
||||
make_jv: function (frm) {
|
||||
frappe.call({
|
||||
args: {
|
||||
"loan": frm.doc.name,
|
||||
"company": frm.doc.company,
|
||||
"loan_account": frm.doc.loan_account,
|
||||
"applicant_type": frm.doc.applicant_type,
|
||||
"applicant": frm.doc.applicant,
|
||||
"loan_amount": frm.doc.loan_amount,
|
||||
"payment_account": frm.doc.payment_account
|
||||
},
|
||||
method: "erpnext.hr.doctype.loan.loan.make_jv_entry",
|
||||
callback: function (r) {
|
||||
if (r.message)
|
||||
var doc = frappe.model.sync(r.message)[0];
|
||||
frappe.set_route("Form", doc.doctype, doc.name);
|
||||
}
|
||||
})
|
||||
},
|
||||
make_repayment_entry: function(frm) {
|
||||
var repayment_schedule = $.map(frm.doc.repayment_schedule, function(d) { return d.paid ? d.payment_date : false; });
|
||||
if(repayment_schedule.length >= 1){
|
||||
frm.repayment_data = [];
|
||||
frm.show_dialog = 1;
|
||||
let title = "";
|
||||
let fields = [
|
||||
{fieldtype:'Section Break', label: __('Repayment Schedule')},
|
||||
{fieldname: 'payments', fieldtype: 'Table',
|
||||
fields: [
|
||||
{
|
||||
fieldtype:'Data',
|
||||
fieldname:'payment_date',
|
||||
label: __('Date'),
|
||||
read_only:1,
|
||||
in_list_view: 1,
|
||||
columns: 2
|
||||
},
|
||||
{
|
||||
fieldtype:'Currency',
|
||||
fieldname:'principal_amount',
|
||||
label: __('Principal Amount'),
|
||||
read_only:1,
|
||||
in_list_view: 1,
|
||||
columns: 3
|
||||
},
|
||||
{
|
||||
fieldtype:'Currency',
|
||||
fieldname:'interest_amount',
|
||||
label: __('Interest'),
|
||||
read_only:1,
|
||||
in_list_view: 1,
|
||||
columns: 2
|
||||
},
|
||||
{
|
||||
fieldtype:'Currency',
|
||||
read_only:1,
|
||||
fieldname:'total_payment',
|
||||
label: __('Total Payment'),
|
||||
in_list_view: 1,
|
||||
columns: 3
|
||||
},
|
||||
],
|
||||
data: frm.repayment_data,
|
||||
get_data: function() {
|
||||
return frm.repayment_data;
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
var dialog = new frappe.ui.Dialog({
|
||||
title: title, fields: fields,
|
||||
});
|
||||
if (frm.doc['repayment_schedule']) {
|
||||
frm.doc['repayment_schedule'].forEach((payment, index) => {
|
||||
if (payment.paid == 0 && payment.payment_date <= frappe.datetime.now_date()) {
|
||||
frm.repayment_data.push ({
|
||||
'id': index,
|
||||
'name': payment.name,
|
||||
'payment_date': payment.payment_date,
|
||||
'principal_amount': payment.principal_amount,
|
||||
'interest_amount': payment.interest_amount,
|
||||
'total_payment': payment.total_payment
|
||||
});
|
||||
dialog.fields_dict.payments.grid.refresh();
|
||||
$(dialog.wrapper.find(".grid-buttons")).hide();
|
||||
$(`.octicon.octicon-triangle-down`).hide();
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
dialog.show()
|
||||
dialog.set_primary_action(__('Make Repayment Entry'), function() {
|
||||
frm.values = dialog.get_values();
|
||||
if(frm.values) {
|
||||
_make_repayment_entry(frm, dialog.fields_dict.payments.grid.get_selected_children());
|
||||
dialog.hide()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
dialog.get_close_btn().on('click', () => {
|
||||
dialog.hide();
|
||||
});
|
||||
},
|
||||
|
||||
mode_of_payment: function (frm) {
|
||||
frappe.call({
|
||||
method: "erpnext.accounts.doctype.sales_invoice.sales_invoice.get_bank_cash_account",
|
||||
args: {
|
||||
"mode_of_payment": frm.doc.mode_of_payment,
|
||||
"company": frm.doc.company
|
||||
},
|
||||
callback: function (r, rt) {
|
||||
if (r.message) {
|
||||
frm.set_value("payment_account", r.message.account);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
loan_application: function (frm) {
|
||||
if(frm.doc.loan_application){
|
||||
return frappe.call({
|
||||
method: "erpnext.hr.doctype.loan.loan.get_loan_application",
|
||||
args: {
|
||||
"loan_application": frm.doc.loan_application
|
||||
},
|
||||
callback: function (r) {
|
||||
if (!r.exc && r.message) {
|
||||
frm.set_value("loan_type", r.message.loan_type);
|
||||
frm.set_value("loan_amount", r.message.loan_amount);
|
||||
frm.set_value("repayment_method", r.message.repayment_method);
|
||||
frm.set_value("monthly_repayment_amount", r.message.repayment_amount);
|
||||
frm.set_value("repayment_periods", r.message.repayment_periods);
|
||||
frm.set_value("rate_of_interest", r.message.rate_of_interest);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
repayment_method: function (frm) {
|
||||
frm.trigger("toggle_fields")
|
||||
},
|
||||
|
||||
toggle_fields: function (frm) {
|
||||
frm.toggle_enable("monthly_repayment_amount", frm.doc.repayment_method == "Repay Fixed Amount per Period")
|
||||
frm.toggle_enable("repayment_periods", frm.doc.repayment_method == "Repay Over Number of Periods")
|
||||
}
|
||||
});
|
||||
|
||||
var _make_repayment_entry = function(frm, payment_rows) {
|
||||
frappe.call({
|
||||
method:"erpnext.hr.doctype.loan.loan.make_repayment_entry",
|
||||
args: {
|
||||
payment_rows: payment_rows,
|
||||
"loan": frm.doc.name,
|
||||
"company": frm.doc.company,
|
||||
"loan_account": frm.doc.loan_account,
|
||||
"applicant_type": frm.doc.applicant_type,
|
||||
"applicant": frm.doc.applicant,
|
||||
"payment_account": frm.doc.payment_account,
|
||||
"interest_income_account": frm.doc.interest_income_account
|
||||
},
|
||||
callback: function(r) {
|
||||
if (r.message)
|
||||
var doc = frappe.model.sync(r.message)[0];
|
||||
frappe.set_route("Form", doc.doctype, doc.name, {'payment_rows': payment_rows});
|
||||
}
|
||||
});
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 0,
|
||||
"autoname": "ELN.####",
|
||||
"autoname": "LN.####",
|
||||
"beta": 0,
|
||||
"creation": "2016-12-02 10:11:49.673604",
|
||||
"custom": 0,
|
||||
@ -19,19 +19,19 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "employee",
|
||||
"fieldtype": "Link",
|
||||
"fieldname": "applicant_type",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 1,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Employee",
|
||||
"label": "Applicant Type",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Employee",
|
||||
"options": "Employee\nMember",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
@ -42,6 +42,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -50,19 +51,19 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "employee_name",
|
||||
"fieldtype": "Read Only",
|
||||
"fieldname": "applicant",
|
||||
"fieldtype": "Dynamic Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 1,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Employee Name",
|
||||
"in_standard_filter": 1,
|
||||
"label": "Applicant",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "employee.employee_name",
|
||||
"options": "applicant_type",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
@ -70,9 +71,10 @@
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -81,7 +83,38 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "employee_loan_application",
|
||||
"fieldname": "applicant_name",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 1,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Applicant Name",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "loan_application",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
@ -90,10 +123,10 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Employee Loan Application",
|
||||
"label": "Loan Application",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Employee Loan Application",
|
||||
"options": "Loan Application",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
@ -104,6 +137,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -135,6 +169,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -164,6 +199,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -195,6 +231,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -226,6 +263,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -247,7 +285,7 @@
|
||||
"label": "Status",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Sanctioned\nPartially Disbursed\nFully Disbursed\nRepaid/Closed",
|
||||
"options": "Sanctioned\nDisbursed\nRepaid/Closed",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
@ -258,6 +296,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -266,6 +305,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.applicant_type==\"Employee\"",
|
||||
"fieldname": "repay_from_salary",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
@ -288,6 +328,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -318,6 +359,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -349,6 +391,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -381,6 +424,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -411,6 +455,38 @@
|
||||
"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": "repayment_start_date",
|
||||
"fieldtype": "Date",
|
||||
"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": "Repayment Start Date",
|
||||
"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
|
||||
},
|
||||
{
|
||||
@ -440,6 +516,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -472,6 +549,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -504,6 +582,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -537,6 +616,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -567,6 +647,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -598,6 +679,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -629,6 +711,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -658,6 +741,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -666,7 +750,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "employee_loan_account",
|
||||
"fieldname": "loan_account",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
@ -675,7 +759,7 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Employee Loan Account",
|
||||
"label": "Loan Account",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Account",
|
||||
@ -689,6 +773,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -720,6 +805,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -750,6 +836,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -781,6 +868,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -811,6 +899,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -843,6 +932,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -872,6 +962,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -904,6 +995,39 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "total_amount_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 Amount Paid",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -924,7 +1048,7 @@
|
||||
"label": "Amended From",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Employee Loan",
|
||||
"options": "Loan",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
@ -934,6 +1058,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
@ -947,16 +1072,15 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-05-02 13:52:30.884154",
|
||||
"modified": "2018-04-08 15:32:58.948412",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Employee Loan",
|
||||
"name": "Loan",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
@ -976,7 +1100,6 @@
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 1,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"delete": 0,
|
@ -3,13 +3,13 @@
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe, math
|
||||
import frappe, math, json
|
||||
import erpnext
|
||||
from frappe import _
|
||||
from frappe.utils import flt, rounded, add_months, nowdate
|
||||
from erpnext.controllers.accounts_controller import AccountsController
|
||||
|
||||
class EmployeeLoan(AccountsController):
|
||||
class Loan(AccountsController):
|
||||
def validate(self):
|
||||
check_repayment_method(self.repayment_method, self.loan_amount, self.monthly_repayment_amount, self.repayment_periods)
|
||||
if not self.company:
|
||||
@ -20,33 +20,38 @@ class EmployeeLoan(AccountsController):
|
||||
self.rate_of_interest = frappe.db.get_value("Loan Type", self.loan_type, "rate_of_interest")
|
||||
if self.repayment_method == "Repay Over Number of Periods":
|
||||
self.monthly_repayment_amount = get_monthly_repayment_amount(self.repayment_method, self.loan_amount, self.rate_of_interest, self.repayment_periods)
|
||||
if self.status == "Repaid/Closed":
|
||||
self.total_amount_paid = self.total_payment
|
||||
if self.status == 'Disbursed' and self.repayment_start_date < self.disbursement_date:
|
||||
frappe.throw(_("Repayment Start Date cannot be before Disbursement Date."))
|
||||
|
||||
self.make_repayment_schedule()
|
||||
self.set_repayment_period()
|
||||
self.calculate_totals()
|
||||
if self.status == "Disbursed":
|
||||
self.make_repayment_schedule()
|
||||
self.set_repayment_period()
|
||||
self.calculate_totals()
|
||||
|
||||
def make_jv_entry(self):
|
||||
self.check_permission('write')
|
||||
journal_entry = frappe.new_doc('Journal Entry')
|
||||
journal_entry.voucher_type = 'Bank Entry'
|
||||
journal_entry.user_remark = _('Against Employee Loan: {0}').format(self.name)
|
||||
journal_entry.user_remark = _('Against Loan: {0}').format(self.name)
|
||||
journal_entry.company = self.company
|
||||
journal_entry.posting_date = nowdate()
|
||||
|
||||
account_amt_list = []
|
||||
|
||||
account_amt_list.append({
|
||||
"account": self.employee_loan_account,
|
||||
"party_type": "Employee",
|
||||
"party": self.employee,
|
||||
"account": self.loan_account,
|
||||
"party_type": self.applicant_type,
|
||||
"party": self.applicant,
|
||||
"debit_in_account_currency": self.loan_amount,
|
||||
"reference_type": "Employee Loan",
|
||||
"reference_type": "Loan",
|
||||
"reference_name": self.name,
|
||||
})
|
||||
account_amt_list.append({
|
||||
"account": self.payment_account,
|
||||
"credit_in_account_currency": self.loan_amount,
|
||||
"reference_type": "Employee Loan",
|
||||
"reference_type": "Loan",
|
||||
"reference_name": self.name,
|
||||
})
|
||||
journal_entry.set("accounts", account_amt_list)
|
||||
@ -54,9 +59,8 @@ class EmployeeLoan(AccountsController):
|
||||
|
||||
def make_repayment_schedule(self):
|
||||
self.repayment_schedule = []
|
||||
payment_date = self.disbursement_date
|
||||
payment_date = self.repayment_start_date
|
||||
balance_amount = self.loan_amount
|
||||
|
||||
while(balance_amount > 0):
|
||||
interest_amount = rounded(balance_amount * flt(self.rate_of_interest) / (12*100))
|
||||
principal_amount = self.monthly_repayment_amount - interest_amount
|
||||
@ -67,7 +71,6 @@ class EmployeeLoan(AccountsController):
|
||||
balance_amount = 0.0
|
||||
|
||||
total_payment = principal_amount + interest_amount
|
||||
|
||||
self.append("repayment_schedule", {
|
||||
"payment_date": payment_date,
|
||||
"principal_amount": principal_amount,
|
||||
@ -75,7 +78,6 @@ class EmployeeLoan(AccountsController):
|
||||
"total_payment": total_payment,
|
||||
"balance_loan_amount": balance_amount
|
||||
})
|
||||
|
||||
next_payment_date = add_months(payment_date, 1)
|
||||
payment_date = next_payment_date
|
||||
|
||||
@ -88,25 +90,33 @@ class EmployeeLoan(AccountsController):
|
||||
def calculate_totals(self):
|
||||
self.total_payment = 0
|
||||
self.total_interest_payable = 0
|
||||
self.total_amount_paid = 0
|
||||
for data in self.repayment_schedule:
|
||||
self.total_payment += data.total_payment
|
||||
self.total_interest_payable +=data.interest_amount
|
||||
if data.paid:
|
||||
self.total_amount_paid += data.total_payment
|
||||
|
||||
def update_total_amount_paid(doc):
|
||||
total_amount_paid = 0
|
||||
for data in doc.repayment_schedule:
|
||||
if data.paid:
|
||||
total_amount_paid += data.total_payment
|
||||
frappe.db.set_value("Loan", doc.name, "total_amount_paid", total_amount_paid)
|
||||
|
||||
def update_disbursement_status(doc):
|
||||
disbursement = frappe.db.sql("""select posting_date, ifnull(sum(debit_in_account_currency), 0) as disbursed_amount
|
||||
from `tabGL Entry` where against_voucher_type = 'Employee Loan' and against_voucher = %s""",
|
||||
(doc.name), as_dict=1)[0]
|
||||
disbursement = frappe.db.sql("""select posting_date, ifnull(sum(credit_in_account_currency), 0) as disbursed_amount
|
||||
from `tabGL Entry` where account = %s and against_voucher_type = 'Loan' and against_voucher = %s""",
|
||||
(doc.payment_account, doc.name), as_dict=1)[0]
|
||||
if disbursement.disbursed_amount == doc.loan_amount:
|
||||
frappe.db.set_value("Employee Loan", doc.name , "status", "Fully Disbursed")
|
||||
if disbursement.disbursed_amount < doc.loan_amount and disbursement.disbursed_amount != 0:
|
||||
frappe.db.set_value("Employee Loan", doc.name , "status", "Partially Disbursed")
|
||||
frappe.db.set_value("Loan", doc.name , "status", "Disbursed")
|
||||
if disbursement.disbursed_amount == 0:
|
||||
frappe.db.set_value("Employee Loan", doc.name , "status", "Sanctioned")
|
||||
frappe.db.set_value("Loan", doc.name , "status", "Sanctioned")
|
||||
if disbursement.disbursed_amount > doc.loan_amount:
|
||||
frappe.throw(_("Disbursed Amount cannot be greater than Loan Amount {0}").format(doc.loan_amount))
|
||||
if disbursement.disbursed_amount > 0:
|
||||
frappe.db.set_value("Employee Loan", doc.name , "disbursement_date", disbursement.posting_date)
|
||||
frappe.db.set_value("Loan", doc.name , "disbursement_date", disbursement.posting_date)
|
||||
frappe.db.set_value("Loan", doc.name , "repayment_start_date", disbursement.posting_date)
|
||||
|
||||
def check_repayment_method(repayment_method, loan_amount, monthly_repayment_amount, repayment_periods):
|
||||
if repayment_method == "Repay Over Number of Periods" and not repayment_periods:
|
||||
@ -129,32 +139,87 @@ def get_monthly_repayment_amount(repayment_method, loan_amount, rate_of_interest
|
||||
return monthly_repayment_amount
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_employee_loan_application(employee_loan_application):
|
||||
employee_loan = frappe.get_doc("Employee Loan Application", employee_loan_application)
|
||||
if employee_loan:
|
||||
return employee_loan.as_dict()
|
||||
def get_loan_application(loan_application):
|
||||
loan = frappe.get_doc("Loan Application", loan_application)
|
||||
if loan:
|
||||
return loan.as_dict()
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_jv_entry(employee_loan, company, employee_loan_account, employee, loan_amount, payment_account=None):
|
||||
def make_repayment_entry(payment_rows, loan, company, loan_account, applicant_type, applicant, \
|
||||
payment_account=None, interest_income_account=None):
|
||||
|
||||
if isinstance(payment_rows, basestring):
|
||||
payment_rows_list = json.loads(payment_rows)
|
||||
else:
|
||||
frappe.throw(_("No repayments available for Journal Entry"))
|
||||
|
||||
if payment_rows_list:
|
||||
row_name = list(set(d["name"] for d in payment_rows_list))
|
||||
else:
|
||||
frappe.throw(_("No repayments selected for Journal Entry"))
|
||||
total_payment = 0
|
||||
principal_amount = 0
|
||||
interest_amount = 0
|
||||
for d in payment_rows_list:
|
||||
total_payment += d["total_payment"]
|
||||
principal_amount += d["principal_amount"]
|
||||
interest_amount += d["interest_amount"]
|
||||
|
||||
journal_entry = frappe.new_doc('Journal Entry')
|
||||
journal_entry.voucher_type = 'Bank Entry'
|
||||
journal_entry.user_remark = _('Against Employee Loan: {0}').format(employee_loan)
|
||||
journal_entry.user_remark = _('Against Loan: {0}').format(loan)
|
||||
journal_entry.company = company
|
||||
journal_entry.posting_date = nowdate()
|
||||
|
||||
journal_entry.paid_loan = json.dumps(row_name)
|
||||
account_amt_list = []
|
||||
|
||||
account_amt_list.append({
|
||||
"account": employee_loan_account,
|
||||
"account": payment_account,
|
||||
"debit_in_account_currency": total_payment,
|
||||
"reference_type": "Loan",
|
||||
"reference_name": loan,
|
||||
})
|
||||
account_amt_list.append({
|
||||
"account": loan_account,
|
||||
"credit_in_account_currency": principal_amount,
|
||||
"party_type": applicant_type,
|
||||
"party": applicant,
|
||||
"reference_type": "Loan",
|
||||
"reference_name": loan,
|
||||
})
|
||||
account_amt_list.append({
|
||||
"account": interest_income_account,
|
||||
"credit_in_account_currency": interest_amount,
|
||||
"reference_type": "Loan",
|
||||
"reference_name": loan,
|
||||
})
|
||||
journal_entry.set("accounts", account_amt_list)
|
||||
|
||||
return journal_entry.as_dict()
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_jv_entry(loan, company, loan_account, applicant_type, applicant, loan_amount,payment_account=None):
|
||||
|
||||
journal_entry = frappe.new_doc('Journal Entry')
|
||||
journal_entry.voucher_type = 'Bank Entry'
|
||||
journal_entry.user_remark = _('Against Loan: {0}').format(loan)
|
||||
journal_entry.company = company
|
||||
journal_entry.posting_date = nowdate()
|
||||
account_amt_list = []
|
||||
|
||||
account_amt_list.append({
|
||||
"account": loan_account,
|
||||
"debit_in_account_currency": loan_amount,
|
||||
"reference_type": "Employee Loan",
|
||||
"reference_name": employee_loan,
|
||||
"party_type": applicant_type,
|
||||
"party": applicant,
|
||||
"reference_type": "Loan",
|
||||
"reference_name": loan,
|
||||
})
|
||||
account_amt_list.append({
|
||||
"account": payment_account,
|
||||
"credit_in_account_currency": loan_amount,
|
||||
"reference_type": "Employee Loan",
|
||||
"reference_name": employee_loan,
|
||||
"reference_type": "Loan",
|
||||
"reference_name": loan,
|
||||
})
|
||||
journal_entry.set("accounts", account_amt_list)
|
||||
return journal_entry.as_dict()
|
@ -2,18 +2,24 @@ from frappe import _
|
||||
|
||||
def get_data():
|
||||
return {
|
||||
'fieldname': 'employee',
|
||||
'fieldname': 'applicant',
|
||||
'non_standard_fieldnames': {
|
||||
'Journal Entry': 'reference_name',
|
||||
'Salary Slip': 'employee'
|
||||
},
|
||||
'transactions': [
|
||||
{
|
||||
'label': _('Employee'),
|
||||
'items': ['Employee Loan Application', 'Salary Slip']
|
||||
'label': _('Applicant'),
|
||||
'items': ['Loan Application']
|
||||
},
|
||||
|
||||
{
|
||||
'label': _('Account'),
|
||||
'items': ['Journal Entry']
|
||||
},
|
||||
{
|
||||
'label': _('Employee'),
|
||||
'items': ['Salary Slip']
|
||||
}
|
||||
]
|
||||
}
|
@ -11,17 +11,17 @@ QUnit.test("Test Loan [HR]", function(assert) {
|
||||
(r) => {
|
||||
employee_name = r.message.name;
|
||||
},
|
||||
() => frappe.db.get_value('Employee Loan Application', {'loan_type': lname}, 'name'),
|
||||
() => frappe.db.get_value('Loan Application', {'loan_type': lname}, 'name'),
|
||||
(r) => {
|
||||
// Creating loan for an employee
|
||||
return frappe.tests.make('Employee Loan', [
|
||||
return frappe.tests.make('Loan', [
|
||||
{ company: 'For Testing'},
|
||||
{ posting_date: '2017-08-26'},
|
||||
{ employee: employee_name},
|
||||
{ employee_loan_application: r.message.name},
|
||||
{ applicant: employee_name},
|
||||
{ loan_application: r.message.name},
|
||||
{ disbursement_date: '2018-08-26'},
|
||||
{ mode_of_payment: 'Cash'},
|
||||
{ employee_loan_account: 'Temporary Opening - FT'},
|
||||
{ loan_account: 'Temporary Opening - FT'},
|
||||
{ interest_income_account: 'Service - FT'}
|
||||
]);
|
||||
},
|
||||
@ -33,7 +33,7 @@ QUnit.test("Test Loan [HR]", function(assert) {
|
||||
|
||||
// Checking if all the amounts are correctly calculated
|
||||
() => {
|
||||
assert.ok(cur_frm.get_field('employee_name').value=='Test Employee 1'&&
|
||||
assert.ok(cur_frm.get_field('applicant_name').value=='Test Employee 1'&&
|
||||
(cur_frm.get_field('status').value=='Sanctioned'),
|
||||
'Loan Sanctioned for correct employee');
|
||||
|
||||
@ -62,7 +62,7 @@ QUnit.test("Test Loan [HR]", function(assert) {
|
||||
'Balance amount after last instalment is correctly calculated');
|
||||
|
||||
},
|
||||
() => frappe.set_route('List','Employee Loan','List'),
|
||||
() => frappe.set_route('List','Loan','List'),
|
||||
() => frappe.timeout(2),
|
||||
|
||||
// Checking the submission of Loan
|
@ -9,19 +9,19 @@ import unittest
|
||||
from frappe.utils import nowdate
|
||||
from erpnext.hr.doctype.salary_structure.test_salary_structure import make_employee
|
||||
|
||||
class TestEmployeeLoan(unittest.TestCase):
|
||||
class TestLoan(unittest.TestCase):
|
||||
def setUp(self):
|
||||
create_loan_type("Personal Loan", 500000, 8.4)
|
||||
self.employee = make_employee("robert_loan@loan.com")
|
||||
create_employee_loan(self.employee, "Personal Loan", 280000, "Repay Over Number of Periods", 20)
|
||||
self.applicant = make_employee("robert_loan@loan.com")
|
||||
create_loan(self.applicant, "Personal Loan", 280000, "Repay Over Number of Periods", 20)
|
||||
|
||||
def test_employee_loan(self):
|
||||
employee_loan = frappe.get_doc("Employee Loan", {"employee":self.employee})
|
||||
self.assertEqual(employee_loan.monthly_repayment_amount, 15052)
|
||||
self.assertEqual(employee_loan.total_interest_payable, 21034)
|
||||
self.assertEqual(employee_loan.total_payment, 301034)
|
||||
def test_loan(self):
|
||||
loan = frappe.get_doc("Loan", {"applicant":self.applicant})
|
||||
self.assertEquals(loan.monthly_repayment_amount, 15052)
|
||||
self.assertEquals(loan.total_interest_payable, 21034)
|
||||
self.assertEquals(loan.total_payment, 301034)
|
||||
|
||||
schedule = employee_loan.repayment_schedule
|
||||
schedule = loan.repayment_schedule
|
||||
|
||||
self.assertEqual(len(schedule), 20)
|
||||
|
||||
@ -30,13 +30,13 @@ class TestEmployeeLoan(unittest.TestCase):
|
||||
self.assertEqual(schedule[idx].interest_amount, interest_amount)
|
||||
self.assertEqual(schedule[idx].balance_loan_amount, balance_loan_amount)
|
||||
|
||||
employee_loan.repayment_method = "Repay Fixed Amount per Period"
|
||||
employee_loan.monthly_repayment_amount = 14000
|
||||
employee_loan.save()
|
||||
loan.repayment_method = "Repay Fixed Amount per Period"
|
||||
loan.monthly_repayment_amount = 14000
|
||||
loan.save()
|
||||
|
||||
self.assertEqual(len(employee_loan.repayment_schedule), 22)
|
||||
self.assertEqual(employee_loan.total_interest_payable, 22712)
|
||||
self.assertEqual(employee_loan.total_payment, 302712)
|
||||
self.assertEquals(len(loan.repayment_schedule), 22)
|
||||
self.assertEquals(loan.total_interest_payable, 22712)
|
||||
self.assertEquals(loan.total_payment, 302712)
|
||||
|
||||
def create_loan_type(loan_name, maximum_loan_amount, rate_of_interest):
|
||||
if not frappe.db.exists("Loan Type", loan_name):
|
||||
@ -47,12 +47,12 @@ def create_loan_type(loan_name, maximum_loan_amount, rate_of_interest):
|
||||
"rate_of_interest": rate_of_interest
|
||||
}).insert()
|
||||
|
||||
def create_employee_loan(employee, loan_type, loan_amount, repayment_method, repayment_periods):
|
||||
def create_loan(applicant, loan_type, loan_amount, repayment_method, repayment_periods):
|
||||
create_loan_type(loan_type, 500000, 8.4)
|
||||
if not frappe.db.get_value("Employee Loan", {"employee":employee}):
|
||||
employee_loan = frappe.new_doc("Employee Loan")
|
||||
employee_loan.update({
|
||||
"employee": employee,
|
||||
if not frappe.db.get_value("Loan", {"applicant":applicant}):
|
||||
loan = frappe.new_doc("Loan")
|
||||
loan.update({
|
||||
"applicant": applicant,
|
||||
"loan_type": loan_type,
|
||||
"loan_amount": loan_amount,
|
||||
"repayment_method": repayment_method,
|
||||
@ -60,10 +60,10 @@ def create_employee_loan(employee, loan_type, loan_amount, repayment_method, rep
|
||||
"disbursement_date": nowdate(),
|
||||
"mode_of_payment": frappe.db.get_value('Mode of Payment', {'type': 'Cash'}, 'name'),
|
||||
"payment_account": frappe.db.get_value('Account', {'account_type': 'Cash', 'company': erpnext.get_default_company(),'is_group':0}, "name"),
|
||||
"employee_loan_account": frappe.db.get_value('Account', {'account_type': 'Cash', 'company': erpnext.get_default_company(),'is_group':0}, "name"),
|
||||
"loan_account": frappe.db.get_value('Account', {'account_type': 'Cash', 'company': erpnext.get_default_company(),'is_group':0}, "name"),
|
||||
"interest_income_account": frappe.db.get_value('Account', {'account_type': 'Cash', 'company': erpnext.get_default_company(),'is_group':0}, "name")
|
||||
})
|
||||
employee_loan.insert()
|
||||
return employee_loan
|
||||
loan.insert()
|
||||
return loan
|
||||
else:
|
||||
return frappe.get_doc("Employee Loan", {"employee":employee})
|
||||
return frappe.get_doc("Loan", {"applicant":applicant})
|
@ -1,7 +1,9 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Employee Loan Application', {
|
||||
{% include 'erpnext/hr/loan_common.js' %};
|
||||
|
||||
frappe.ui.form.on('Loan Application', {
|
||||
refresh: function(frm) {
|
||||
frm.trigger("toggle_fields")
|
||||
frm.trigger("add_toolbar_buttons")
|
||||
@ -16,10 +18,10 @@ frappe.ui.form.on('Employee Loan Application', {
|
||||
},
|
||||
add_toolbar_buttons: function(frm) {
|
||||
if (frm.doc.status == "Approved") {
|
||||
frm.add_custom_button(__('Employee Loan'), function() {
|
||||
frm.add_custom_button(__('Loan'), function() {
|
||||
frappe.call({
|
||||
type: "GET",
|
||||
method: "erpnext.hr.doctype.employee_loan_application.employee_loan_application.make_employee_loan",
|
||||
method: "erpnext.hr.doctype.loan_application.loan_application.make_loan",
|
||||
args: {
|
||||
"source_name": frm.doc.name
|
||||
},
|
@ -1,8 +1,9 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "ELA/.#####",
|
||||
"autoname": "LA/.#####",
|
||||
"beta": 0,
|
||||
"creation": "2016-12-02 12:35:56.046811",
|
||||
"custom": 0,
|
||||
@ -13,6 +14,133 @@
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "applicant_type",
|
||||
"fieldtype": "Select",
|
||||
"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": "Applicant Type",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Employee\nMember",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"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": "applicant",
|
||||
"fieldtype": "Dynamic Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 1,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Applicant",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "applicant_type",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"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,
|
||||
"depends_on": "applicant",
|
||||
"fieldname": "applicant_name",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 1,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Applicant Name",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_2",
|
||||
"fieldtype": "Column 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,
|
||||
"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,
|
||||
@ -40,97 +168,11 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "employee",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 1,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Employee",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Employee",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "employee_name",
|
||||
"fieldtype": "Read Only",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 1,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Employee Name",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "employee.employee_name",
|
||||
"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_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_2",
|
||||
"fieldtype": "Column 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,
|
||||
"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": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -158,9 +200,11 @@
|
||||
"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,
|
||||
@ -172,7 +216,7 @@
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Company",
|
||||
"length": 0,
|
||||
@ -188,9 +232,11 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -217,9 +263,11 @@
|
||||
"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,
|
||||
@ -231,7 +279,7 @@
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Loan Type",
|
||||
"length": 0,
|
||||
@ -247,9 +295,11 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -261,7 +311,7 @@
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Loan Amount",
|
||||
"length": 0,
|
||||
@ -277,9 +327,11 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -306,9 +358,11 @@
|
||||
"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,
|
||||
@ -334,9 +388,11 @@
|
||||
"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,
|
||||
@ -363,9 +419,11 @@
|
||||
"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,
|
||||
@ -392,9 +450,11 @@
|
||||
"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,
|
||||
@ -422,9 +482,11 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@ -452,9 +514,11 @@
|
||||
"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,
|
||||
@ -482,9 +546,11 @@
|
||||
"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,
|
||||
@ -510,9 +576,11 @@
|
||||
"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,
|
||||
@ -541,9 +609,11 @@
|
||||
"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,
|
||||
@ -571,9 +641,11 @@
|
||||
"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,
|
||||
@ -601,9 +673,11 @@
|
||||
"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,
|
||||
@ -620,7 +694,7 @@
|
||||
"label": "Amended From",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Employee Loan Application",
|
||||
"options": "Loan Application",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
@ -630,23 +704,24 @@
|
||||
"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,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 1,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-03-02 04:25:43.397934",
|
||||
"modified": "2018-02-26 08:35:57.606555",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Employee Loan Application",
|
||||
"name": "Loan Application",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
@ -734,12 +809,12 @@
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"search_fields": "employee, employee_name, loan_type, loan_amount",
|
||||
"search_fields": "applicant_type, applicant, loan_type, loan_amount",
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"timeline_field": "employee",
|
||||
"title_field": "employee_name",
|
||||
"timeline_field": "applicant",
|
||||
"title_field": "applicant",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
@ -9,9 +9,9 @@ from frappe.utils import flt, rounded
|
||||
from frappe.model.mapper import get_mapped_doc
|
||||
from frappe.model.document import Document
|
||||
|
||||
from erpnext.hr.doctype.employee_loan.employee_loan import get_monthly_repayment_amount, check_repayment_method
|
||||
from erpnext.hr.doctype.loan.loan import get_monthly_repayment_amount, check_repayment_method
|
||||
|
||||
class EmployeeLoanApplication(Document):
|
||||
class LoanApplication(Document):
|
||||
def validate(self):
|
||||
check_repayment_method(self.repayment_method, self.loan_amount, self.repayment_amount, self.repayment_periods)
|
||||
self.validate_loan_amount()
|
||||
@ -51,10 +51,10 @@ class EmployeeLoanApplication(Document):
|
||||
self.total_payable_amount = self.loan_amount + self.total_payable_interest
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_employee_loan(source_name, target_doc = None):
|
||||
doclist = get_mapped_doc("Employee Loan Application", source_name, {
|
||||
"Employee Loan Application": {
|
||||
"doctype": "Employee Loan",
|
||||
def make_loan(source_name, target_doc = None):
|
||||
doclist = get_mapped_doc("Loan Application", source_name, {
|
||||
"Loan Application": {
|
||||
"doctype": "Loan",
|
||||
"validation": {
|
||||
"docstatus": ["=", 1]
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
QUnit.module('hr');
|
||||
|
||||
QUnit.test("Test: Employee Loan Application [HR]", function (assert) {
|
||||
QUnit.test("Test: Loan Application [HR]", function (assert) {
|
||||
assert.expect(8);
|
||||
let done = assert.async();
|
||||
let employee_name;
|
||||
@ -12,10 +12,10 @@ QUnit.test("Test: Employee Loan Application [HR]", function (assert) {
|
||||
employee_name = r.message.name;
|
||||
},
|
||||
() => {
|
||||
return frappe.tests.make('Employee Loan Application', [
|
||||
return frappe.tests.make('Loan Application', [
|
||||
{ company: 'For Testing'},
|
||||
{ employee: employee_name},
|
||||
{ employee_name: 'Test Employee 1'},
|
||||
{ applicant: employee_name},
|
||||
{ applicant_name: 'Test Employee 1'},
|
||||
{ status: 'Approved'},
|
||||
{ loan_type: 'Test Loan '},
|
||||
{ loan_amount: 200000},
|
||||
@ -33,7 +33,7 @@ QUnit.test("Test: Employee Loan Application [HR]", function (assert) {
|
||||
() => {
|
||||
// To check if all the amounts are correctly calculated
|
||||
|
||||
assert.ok(cur_frm.get_field('employee_name').value == 'Test Employee 1',
|
||||
assert.ok(cur_frm.get_field('applicant_name').value == 'Test Employee 1',
|
||||
'Application created successfully');
|
||||
|
||||
assert.ok(cur_frm.get_field('status').value=='Approved',
|
||||
@ -55,7 +55,7 @@ QUnit.test("Test: Employee Loan Application [HR]", function (assert) {
|
||||
'Total payable amount is correctly calculated');
|
||||
},
|
||||
|
||||
() => frappe.set_route('List','Employee Loan Application','List'),
|
||||
() => frappe.set_route('List','Loan Application','List'),
|
||||
() => frappe.timeout(2),
|
||||
|
||||
// Checking the submission of Loan Application
|
@ -7,10 +7,10 @@ import frappe
|
||||
import unittest
|
||||
from erpnext.hr.doctype.salary_structure.test_salary_structure import make_employee
|
||||
|
||||
class TestEmployeeLoanApplication(unittest.TestCase):
|
||||
class TestLoanApplication(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.create_loan_type()
|
||||
self.employee = make_employee("kate_loan@loan.com")
|
||||
self.applicant = make_employee("kate_loan@loan.com")
|
||||
self.create_loan_application()
|
||||
|
||||
def create_loan_type(self):
|
||||
@ -23,10 +23,10 @@ class TestEmployeeLoanApplication(unittest.TestCase):
|
||||
}).insert()
|
||||
|
||||
def create_loan_application(self):
|
||||
if not frappe.db.get_value("Employee Loan Application", {"employee":self.employee}, "name"):
|
||||
loan_application = frappe.new_doc("Employee Loan Application")
|
||||
if not frappe.db.get_value("Loan Application", {"applicant":self.applicant}, "name"):
|
||||
loan_application = frappe.new_doc("Loan Application")
|
||||
loan_application.update({
|
||||
"employee": self.employee,
|
||||
"applicant": self.applicant,
|
||||
"loan_type": "Home Loan",
|
||||
"rate_of_interest": 9.2,
|
||||
"loan_amount": 250000,
|
||||
@ -37,10 +37,10 @@ class TestEmployeeLoanApplication(unittest.TestCase):
|
||||
|
||||
|
||||
def test_loan_totals(self):
|
||||
loan_application = frappe.get_doc("Employee Loan Application", {"employee":self.employee})
|
||||
self.assertEqual(loan_application.repayment_amount, 11445)
|
||||
self.assertEqual(loan_application.total_payable_interest, 24657)
|
||||
self.assertEqual(loan_application.total_payable_amount, 274657)
|
||||
loan_application = frappe.get_doc("Loan Application", {"applicant":self.applicant})
|
||||
self.assertEquals(loan_application.repayment_amount, 11445)
|
||||
self.assertEquals(loan_application.total_payable_interest, 24657)
|
||||
self.assertEquals(loan_application.total_payable_amount, 274657)
|
||||
|
||||
loan_application.repayment_method = "Repay Fixed Amount per Period"
|
||||
loan_application.repayment_amount = 15000
|
@ -183,7 +183,7 @@ class PayrollEntry(Document):
|
||||
Get loan details from submitted salary slip based on selected criteria
|
||||
"""
|
||||
cond = self.get_filter_condition()
|
||||
return frappe.db.sql(""" select eld.employee_loan_account, eld.employee_loan,
|
||||
return frappe.db.sql(""" select eld.loan_account,
|
||||
eld.interest_income_account, eld.principal_amount, eld.interest_amount, eld.total_payment
|
||||
from
|
||||
`tabSalary Slip` t1, `tabSalary Slip Loan` eld
|
||||
@ -285,10 +285,10 @@ class PayrollEntry(Document):
|
||||
"project": self.project
|
||||
})
|
||||
|
||||
# Employee loan
|
||||
# Loan
|
||||
for data in loan_details:
|
||||
accounts.append({
|
||||
"account": data.employee_loan_account,
|
||||
"account": data.loan_account,
|
||||
"credit_in_account_currency": data.principal_amount
|
||||
})
|
||||
|
||||
|
@ -29,13 +29,13 @@ class TestPayrollEntry(unittest.TestCase):
|
||||
self.assertEqual(get_end_date('2017-02-15', 'monthly'), {'end_date': '2017-03-14'})
|
||||
self.assertEqual(get_end_date('2017-02-15', 'daily'), {'end_date': '2017-02-15'})
|
||||
|
||||
def test_employee_loan(self):
|
||||
def test_loan(self):
|
||||
from erpnext.hr.doctype.salary_structure.test_salary_structure import (make_employee,
|
||||
make_salary_structure)
|
||||
from erpnext.hr.doctype.employee_loan.test_employee_loan import create_employee_loan
|
||||
from erpnext.hr.doctype.loan.test_loan import create_loan
|
||||
|
||||
branch = "Test Employee Branch"
|
||||
employee = make_employee("test_employee@loan.com")
|
||||
applicant = make_employee("test_employee@loan.com")
|
||||
company = erpnext.get_default_company()
|
||||
holiday_list = make_holiday("test holiday for loan")
|
||||
|
||||
@ -72,20 +72,20 @@ class TestPayrollEntry(unittest.TestCase):
|
||||
'branch': branch
|
||||
}).insert()
|
||||
|
||||
employee_doc = frappe.get_doc('Employee', employee)
|
||||
employee_doc = frappe.get_doc('Employee', applicant)
|
||||
employee_doc.branch = branch
|
||||
employee_doc.holiday_list = holiday_list
|
||||
employee_doc.save()
|
||||
|
||||
employee_loan = create_employee_loan(employee,
|
||||
loan = create_loan(applicant,
|
||||
"Personal Loan", 280000, "Repay Over Number of Periods", 20)
|
||||
employee_loan.repay_from_salary = 1
|
||||
employee_loan.submit()
|
||||
loan.repay_from_salary = 1
|
||||
loan.submit()
|
||||
|
||||
salary_strcture = "Test Salary Structure for Loan"
|
||||
if not frappe.db.exists('Salary Structure', salary_strcture):
|
||||
salary_strcture = make_salary_structure(salary_strcture, [{
|
||||
'employee': employee,
|
||||
'employee': applicant,
|
||||
'from_date': '2017-01-01',
|
||||
'base': 30000
|
||||
}])
|
||||
@ -104,13 +104,13 @@ class TestPayrollEntry(unittest.TestCase):
|
||||
end_date=dates.end_date, branch=branch)
|
||||
|
||||
name = frappe.db.get_value('Salary Slip',
|
||||
{'posting_date': nowdate(), 'employee': employee}, 'name')
|
||||
{'posting_date': nowdate(), 'employee': applicant}, 'name')
|
||||
|
||||
salary_slip = frappe.get_doc('Salary Slip', name)
|
||||
for row in salary_slip.loans:
|
||||
if row.employee_loan == employee_loan.name:
|
||||
if row.loan == loan.name:
|
||||
interest_amount = (280000 * 8.4)/(12*100)
|
||||
principal_amount = employee_loan.monthly_repayment_amount - interest_amount
|
||||
principal_amount = loan.monthly_repayment_amount - interest_amount
|
||||
self.assertEqual(row.interest_amount, interest_amount)
|
||||
self.assertEqual(row.principal_amount, principal_amount)
|
||||
self.assertEqual(row.total_payment,
|
||||
@ -119,8 +119,8 @@ class TestPayrollEntry(unittest.TestCase):
|
||||
if salary_slip.docstatus == 0:
|
||||
frappe.delete_doc('Salary Slip', name)
|
||||
|
||||
employee_loan.cancel()
|
||||
frappe.delete_doc('Employee Loan', employee_loan.name)
|
||||
loan.cancel()
|
||||
frappe.delete_doc('Loan', loan.name)
|
||||
|
||||
def get_salary_component_account(sal_comp):
|
||||
company = erpnext.get_default_company()
|
||||
|
@ -40,6 +40,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -71,6 +72,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -102,6 +104,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -133,6 +136,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -164,6 +168,38 @@
|
||||
"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": "paid",
|
||||
"fieldtype": "Check",
|
||||
"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": "Paid",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
@ -177,7 +213,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-07-26 14:47:29.862084",
|
||||
"modified": "2018-03-30 17:37:31.834792",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Repayment Schedule",
|
||||
|
@ -41,6 +41,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -73,6 +74,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -105,6 +107,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -137,6 +140,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -170,6 +174,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -202,6 +207,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -231,6 +237,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
@ -263,6 +270,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -294,6 +302,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -324,6 +333,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -354,6 +364,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -383,6 +394,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -415,6 +427,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -446,6 +459,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -478,6 +492,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -507,6 +522,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -539,6 +555,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -572,6 +589,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -604,6 +622,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -636,6 +655,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -668,6 +688,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -699,6 +720,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -731,6 +753,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -760,6 +783,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -790,6 +814,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -821,6 +846,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -852,6 +878,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -883,6 +910,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -914,6 +942,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -943,6 +972,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -975,6 +1005,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1005,6 +1036,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1035,6 +1067,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
@ -1069,6 +1102,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1099,6 +1133,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
@ -1132,6 +1167,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1162,6 +1198,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1194,6 +1231,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1222,6 +1260,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1254,6 +1293,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1285,6 +1325,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1302,7 +1343,7 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Employee Loan",
|
||||
"label": "Loan",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Salary Slip Loan",
|
||||
@ -1316,6 +1357,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1345,6 +1387,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1377,6 +1420,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1409,6 +1453,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1438,6 +1483,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1470,6 +1516,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1500,6 +1547,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1533,6 +1581,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1562,6 +1611,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1592,6 +1642,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1621,6 +1672,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1653,6 +1705,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
@ -1667,7 +1720,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-11-13 23:55:37.504856",
|
||||
"modified": "2018-02-26 05:16:47.169743",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Salary Slip",
|
||||
|
@ -380,13 +380,13 @@ class SalarySlip(TransactionBase):
|
||||
self.total_interest_amount = 0
|
||||
self.total_principal_amount = 0
|
||||
|
||||
for loan in self.get_employee_loan_details():
|
||||
for loan in self.get_loan_details():
|
||||
self.append('loans', {
|
||||
'employee_loan': loan.name,
|
||||
'loan': loan.name,
|
||||
'total_payment': loan.total_payment,
|
||||
'interest_amount': loan.interest_amount,
|
||||
'principal_amount': loan.principal_amount,
|
||||
'employee_loan_account': loan.employee_loan_account,
|
||||
'loan_account': loan.loan_account,
|
||||
'interest_income_account': loan.interest_income_account
|
||||
})
|
||||
|
||||
@ -394,14 +394,14 @@ class SalarySlip(TransactionBase):
|
||||
self.total_interest_amount += loan.interest_amount
|
||||
self.total_principal_amount += loan.principal_amount
|
||||
|
||||
def get_employee_loan_details(self):
|
||||
return frappe.db.sql("""select rps.principal_amount, rps.interest_amount, el.name,
|
||||
rps.total_payment, el.employee_loan_account, el.interest_income_account
|
||||
def get_loan_details(self):
|
||||
return frappe.db.sql("""select rps.principal_amount, rps.interest_amount, l.name,
|
||||
rps.total_payment, l.loan_account, l.interest_income_account
|
||||
from
|
||||
`tabRepayment Schedule` as rps, `tabEmployee Loan` as el
|
||||
`tabRepayment Schedule` as rps, `tabLoan` as l
|
||||
where
|
||||
el.name = rps.parent and rps.payment_date between %s and %s and
|
||||
el.repay_from_salary = 1 and el.docstatus = 1 and el.employee = %s""",
|
||||
l.name = rps.parent and rps.payment_date between %s and %s and
|
||||
l.repay_from_salary = 1 and l.docstatus = 1 and l.applicant = %s""",
|
||||
(self.start_date, self.end_date, self.employee), as_dict=True) or []
|
||||
|
||||
def on_submit(self):
|
||||
|
@ -134,12 +134,12 @@ class TestSalarySlip(unittest.TestCase):
|
||||
self.assertTrue(email_queue)
|
||||
|
||||
def test_loan_repayment_salary_slip(self):
|
||||
from erpnext.hr.doctype.employee_loan.test_employee_loan import create_loan_type, create_employee_loan
|
||||
employee = self.make_employee("test_employee@salary.com")
|
||||
from erpnext.hr.doctype.loan.test_loan import create_loan_type, create_loan
|
||||
applicant = self.make_employee("test_employee@salary.com")
|
||||
create_loan_type("Car Loan", 500000, 6.4)
|
||||
employee_loan = create_employee_loan(employee, "Car Loan", 11000, "Repay Over Number of Periods", 20)
|
||||
employee_loan.repay_from_salary = 1
|
||||
employee_loan.submit()
|
||||
loan = create_loan(applicant, "Car Loan", 11000, "Repay Over Number of Periods", 20)
|
||||
loan.repay_from_salary = 1
|
||||
loan.submit()
|
||||
ss = frappe.get_doc("Salary Slip",
|
||||
self.make_employee_salary_slip("test_employee@salary.com", "Monthly"))
|
||||
ss.submit()
|
||||
|
@ -18,7 +18,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "employee_loan",
|
||||
"fieldname": "loan",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
@ -27,10 +27,10 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Employee Loan",
|
||||
"label": "Loan",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Employee Loan",
|
||||
"options": "Loan",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
@ -41,6 +41,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -49,7 +50,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "employee_loan_account",
|
||||
"fieldname": "loan_account",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
@ -58,7 +59,7 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Employee Loan Account",
|
||||
"label": "Loan Account",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Account",
|
||||
@ -72,6 +73,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -103,6 +105,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -132,6 +135,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -163,6 +167,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -194,6 +199,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -225,6 +231,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
@ -238,7 +245,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-11-13 23:59:47.237689",
|
||||
"modified": "2018-02-26 05:24:31.369630",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Salary Slip Loan",
|
||||
|
27
erpnext/hr/loan_common.js
Normal file
27
erpnext/hr/loan_common.js
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on(cur_frm.doctype, {
|
||||
refresh: function(frm) {
|
||||
if (!frappe.boot.active_domains.includes("Non Profit")) {
|
||||
frm.set_df_property('applicant_type', 'options', ['Employee']);
|
||||
frm.refresh_field('applicant_type');
|
||||
}
|
||||
},
|
||||
applicant_type: function(frm) {
|
||||
frm.set_value("applicant", null);
|
||||
frm.set_value("applicant_name", null);
|
||||
},
|
||||
applicant: function(frm) {
|
||||
if (frm.doc.applicant) {
|
||||
frappe.model.with_doc(frm.doc.applicant_type, frm.doc.applicant, function() {
|
||||
var applicant = frappe.model.get_doc(frm.doc.applicant_type, frm.doc.applicant);
|
||||
frm.set_value("applicant_name",
|
||||
applicant.employee_name || applicant.member_name);
|
||||
});
|
||||
}
|
||||
else {
|
||||
frm.set_value("applicant_name", null);
|
||||
}
|
||||
}
|
||||
});
|
@ -517,6 +517,7 @@ erpnext.patches.v10_0.update_project_in_sle
|
||||
erpnext.patches.v10_0.fix_reserved_qty_for_sub_contract
|
||||
erpnext.patches.v11_0.add_index_on_nestedset_doctypes
|
||||
erpnext.patches.v11_0.remove_modules_setup_page
|
||||
erpnext.patches.v11_0.rename_employee_loan_to_loan
|
||||
erpnext.patches.v11_0.move_leave_approvers_from_employee
|
||||
erpnext.patches.v11_0.update_department_lft_rgt
|
||||
erpnext.patches.v11_0.add_default_email_template_for_leave
|
||||
|
27
erpnext/patches/v11_0/rename_employee_loan_to_loan.py
Normal file
27
erpnext/patches/v11_0/rename_employee_loan_to_loan.py
Normal file
@ -0,0 +1,27 @@
|
||||
import frappe
|
||||
from frappe.model.utils.rename_field import rename_field
|
||||
|
||||
def execute():
|
||||
if frappe.db.table_exists("Employee Loan Application") and not frappe.db.table_exists("Loan Application"):
|
||||
frappe.rename_doc("DocType", "Employee Loan Application", "Loan Application", force=True)
|
||||
|
||||
if frappe.db.table_exists("Employee Loan") and not frappe.db.table_exists("Loan"):
|
||||
frappe.rename_doc("DocType", "Employee Loan", "Loan", force=True)
|
||||
|
||||
frappe.reload_doc("hr", "doctype", "loan_application")
|
||||
frappe.reload_doc("hr", "doctype", "loan")
|
||||
frappe.reload_doc("hr", "doctype", "salary_slip_loan")
|
||||
|
||||
for doctype in ['Loan', 'Salary Slip Loan']:
|
||||
if frappe.db.has_column(doctype, 'employee_loan_account'):
|
||||
rename_field(doctype, "employee_loan_account", "loan_account")
|
||||
|
||||
columns = {'employee': 'applicant', 'employee_name': 'applicant_name'}
|
||||
for doctype in ['Loan Application', 'Loan']:
|
||||
frappe.db.sql(""" update `tab{doctype}` set applicant_type = 'Employee' """
|
||||
.format(doctype=doctype))
|
||||
for column, new_column in columns.items():
|
||||
if frappe.db.has_column(doctype, column):
|
||||
rename_field(doctype, column, new_column)
|
||||
|
||||
frappe.delete_doc('DocType', doctype)
|
@ -65,8 +65,8 @@ erpnext/hr/doctype/training_event/tests/test_training_event.js
|
||||
erpnext/hr/doctype/training_result_employee/test_training_result.js
|
||||
erpnext/hr/doctype/training_feedback/test_training_feedback.js
|
||||
erpnext/hr/doctype/loan_type/test_loan_type.js
|
||||
erpnext/hr/doctype/employee_loan_application/test_employee_loan_application.js
|
||||
erpnext/hr/doctype/employee_loan/test_employee_loan.js
|
||||
erpnext/hr/doctype/loan_application/test_loan_application.js
|
||||
erpnext/hr/doctype/loan/test_loan.js
|
||||
erpnext/buying/doctype/supplier/test_supplier.js
|
||||
erpnext/buying/doctype/request_for_quotation/tests/test_request_for_quotation.js
|
||||
erpnext/buying/doctype/supplier_quotation/tests/test_supplier_quotation.js
|
||||
|
Loading…
Reference in New Issue
Block a user