Merge branch 'develop' of github.com:frappe/erpnext into develop
This commit is contained in:
commit
d9a265fab1
@ -337,14 +337,19 @@ def set_taxes(party, party_type, posting_date, company, customer_group=None, sup
|
|||||||
|
|
||||||
def validate_party_frozen_disabled(party_type, party_name):
|
def validate_party_frozen_disabled(party_type, party_name):
|
||||||
if party_type and party_name:
|
if party_type and party_name:
|
||||||
|
if party_type in ("Customer", "Supplier"):
|
||||||
party = frappe.db.get_value(party_type, party_name, ["is_frozen", "disabled"], as_dict=True)
|
party = frappe.db.get_value(party_type, party_name, ["is_frozen", "disabled"], as_dict=True)
|
||||||
if party.disabled:
|
if party.disabled:
|
||||||
frappe.throw(_("{0} {1} is disabled").format(party_type, party_name), PartyDisabled)
|
frappe.throw(_("{0} {1} is disabled").format(party_type, party_name), PartyDisabled)
|
||||||
elif party.is_frozen:
|
elif party.get("is_frozen"):
|
||||||
frozen_accounts_modifier = frappe.db.get_value( 'Accounts Settings', None,'frozen_accounts_modifier')
|
frozen_accounts_modifier = frappe.db.get_value( 'Accounts Settings', None,'frozen_accounts_modifier')
|
||||||
if not frozen_accounts_modifier in frappe.get_roles():
|
if not frozen_accounts_modifier in frappe.get_roles():
|
||||||
frappe.throw(_("{0} {1} is frozen").format(party_type, party_name), PartyFrozen)
|
frappe.throw(_("{0} {1} is frozen").format(party_type, party_name), PartyFrozen)
|
||||||
|
|
||||||
|
elif party_type == "Employee":
|
||||||
|
if frappe.db.get_value("Employee", party_name, "status") == "Left":
|
||||||
|
frappe.msgprint(_("{0} {1} is not active").format(party_type, party_name), PartyDisabled, alert=True)
|
||||||
|
|
||||||
def get_timeline_data(doctype, name):
|
def get_timeline_data(doctype, name):
|
||||||
'''returns timeline data for the past one year'''
|
'''returns timeline data for the past one year'''
|
||||||
from frappe.desk.form.load import get_communication_data
|
from frappe.desk.form.load import get_communication_data
|
||||||
|
@ -47,6 +47,12 @@ frappe.query_reports["General Ledger"] = {
|
|||||||
"label": __("Voucher No"),
|
"label": __("Voucher No"),
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"project",
|
||||||
|
"label": __("Project"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Project"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"fieldtype": "Break",
|
"fieldtype": "Break",
|
||||||
},
|
},
|
||||||
|
@ -149,6 +149,9 @@ def get_conditions(filters):
|
|||||||
if not (filters.get("account") or filters.get("party") or filters.get("group_by_account")):
|
if not (filters.get("account") or filters.get("party") or filters.get("group_by_account")):
|
||||||
conditions.append("posting_date >=%(from_date)s")
|
conditions.append("posting_date >=%(from_date)s")
|
||||||
|
|
||||||
|
if filters.get("project"):
|
||||||
|
conditions.append("project=%(project)s")
|
||||||
|
|
||||||
from frappe.desk.reportview import build_match_conditions
|
from frappe.desk.reportview import build_match_conditions
|
||||||
match_conditions = build_match_conditions("GL Entry")
|
match_conditions = build_match_conditions("GL Entry")
|
||||||
if match_conditions: conditions.append(match_conditions)
|
if match_conditions: conditions.append(match_conditions)
|
||||||
|
@ -21,20 +21,12 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({
|
|||||||
if(this.frm.get_field('shipping_address')) {
|
if(this.frm.get_field('shipping_address')) {
|
||||||
this.frm.set_query("shipping_address", function(){
|
this.frm.set_query("shipping_address", function(){
|
||||||
if(me.frm.doc.customer){
|
if(me.frm.doc.customer){
|
||||||
return{
|
return {
|
||||||
filters:{
|
query: 'frappe.geo.doctype.address.address.address_query',
|
||||||
"customer": me.frm.doc.customer
|
filters: { link_doctype: 'Customer', link_name: me.frm.doc.customer }
|
||||||
}
|
};
|
||||||
}
|
} else
|
||||||
}
|
return erpnext.queries.company_address_query(me.frm.doc)
|
||||||
else{
|
|
||||||
return{
|
|
||||||
filters:{
|
|
||||||
"is_your_company_address": 1,
|
|
||||||
"company": me.frm.doc.company
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -26,11 +26,11 @@ frappe.ui.form.on("Supplier", {
|
|||||||
|
|
||||||
if(frm.doc.__islocal){
|
if(frm.doc.__islocal){
|
||||||
hide_field(['address_html','contact_html']);
|
hide_field(['address_html','contact_html']);
|
||||||
erpnext.utils.clear_address_and_contact(frm);
|
frappe.geo.clear_address_and_contact(frm);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
unhide_field(['address_html','contact_html']);
|
unhide_field(['address_html','contact_html']);
|
||||||
erpnext.utils.render_address_and_contact(frm);
|
frappe.geo.render_address_and_contact(frm);
|
||||||
|
|
||||||
// custom buttons
|
// custom buttons
|
||||||
frm.add_custom_button(__('Accounting Ledger'), function() {
|
frm.add_custom_button(__('Accounting Ledger'), function() {
|
||||||
|
@ -6,7 +6,7 @@ import frappe
|
|||||||
import frappe.defaults
|
import frappe.defaults
|
||||||
from frappe import msgprint, _
|
from frappe import msgprint, _
|
||||||
from frappe.model.naming import make_autoname
|
from frappe.model.naming import make_autoname
|
||||||
from erpnext.utilities.address_and_contact import (load_address_and_contact,
|
from frappe.geo.address_and_contact import (load_address_and_contact,
|
||||||
delete_contact_and_address)
|
delete_contact_and_address)
|
||||||
|
|
||||||
from erpnext.utilities.transaction_base import TransactionBase
|
from erpnext.utilities.transaction_base import TransactionBase
|
||||||
@ -61,14 +61,6 @@ class Supplier(TransactionBase):
|
|||||||
validate_party_accounts(self)
|
validate_party_accounts(self)
|
||||||
self.status = get_party_status(self)
|
self.status = get_party_status(self)
|
||||||
|
|
||||||
def get_contacts(self,nm):
|
|
||||||
if nm:
|
|
||||||
contact_details =frappe.db.convert_to_lists(frappe.db.sql("select name, CONCAT(IFNULL(first_name,''),' ',IFNULL(last_name,'')),contact_no,email_id from `tabContact` where supplier = %s", nm))
|
|
||||||
|
|
||||||
return contact_details
|
|
||||||
else:
|
|
||||||
return ''
|
|
||||||
|
|
||||||
def on_trash(self):
|
def on_trash(self):
|
||||||
delete_contact_and_address('Supplier', self.name)
|
delete_contact_and_address('Supplier', self.name)
|
||||||
|
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
"apply_user_permissions": 1,
|
|
||||||
"creation": "2013-10-09 10:38:40",
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "Report",
|
|
||||||
"idx": 1,
|
|
||||||
"is_standard": "Yes",
|
|
||||||
"modified": "2014-09-11 08:53:17.358554",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "Buying",
|
|
||||||
"name": "Supplier Addresses and Contacts",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"query": "SELECT\n `tabSupplier`.name as \"Supplier:Link/Supplier:120\",\n\t`tabSupplier`.supplier_name as \"Supplier Name::120\",\n\t`tabSupplier`.supplier_type as \"Supplier Type:Link/Supplier Type:120\",\n\tconcat_ws(', ', \n\t\ttrim(',' from `tabAddress`.address_line1), \n\t\ttrim(',' from tabAddress.address_line2), \n\t\ttabAddress.state, tabAddress.pincode, tabAddress.country\n\t) as 'Address::180',\n concat_ws(', ', `tabContact`.first_name, `tabContact`.last_name) as \"Contact Name::180\",\n\t`tabContact`.phone as \"Phone\",\n\t`tabContact`.mobile_no as \"Mobile No\",\n\t`tabContact`.email_id as \"Email Address::120\",\n\t`tabContact`.is_primary_contact as \"Is Primary Contact::120\"\nFROM\n\t`tabSupplier`\n\tleft join `tabAddress` on (\n\t\t`tabAddress`.supplier=`tabSupplier`.name\n\t)\n\tleft join `tabContact` on (\n\t\t`tabContact`.supplier=`tabSupplier`.name\n\t)\nWHERE\n\t`tabSupplier`.docstatus<2\nORDER BY\n\t`tabSupplier`.name asc",
|
|
||||||
"ref_doctype": "Supplier",
|
|
||||||
"report_name": "Supplier Addresses and Contacts",
|
|
||||||
"report_type": "Query Report"
|
|
||||||
}
|
|
@ -172,8 +172,12 @@ def get_data():
|
|||||||
{
|
{
|
||||||
"type": "report",
|
"type": "report",
|
||||||
"is_query_report": True,
|
"is_query_report": True,
|
||||||
"name": "Supplier Addresses and Contacts",
|
"name": "Addresses And Contacts",
|
||||||
"doctype": "Supplier"
|
"label": "Supplier Addresses And Contacts",
|
||||||
|
"doctype": "Address",
|
||||||
|
"route_options": {
|
||||||
|
"party_type": "Supplier"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -265,6 +265,26 @@ def get_data():
|
|||||||
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"label": _("Employee Loan Management"),
|
||||||
|
"icon": "icon-list",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Loan Type",
|
||||||
|
"description": _("Define various loan types")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Employee Loan Application",
|
||||||
|
"description": _("Employee Loan Application")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Employee Loan"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"label": _("Help"),
|
"label": _("Help"),
|
||||||
"icon": "fa fa-facetime-video",
|
"icon": "fa fa-facetime-video",
|
||||||
|
@ -159,23 +159,6 @@ def get_data():
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"label": _("LMS"),
|
|
||||||
"items": [
|
|
||||||
{
|
|
||||||
"type": "doctype",
|
|
||||||
"name": "Announcement"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "doctype",
|
|
||||||
"name": "Topic"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "doctype",
|
|
||||||
"name": "Discussion"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"label": _("Setup"),
|
"label": _("Setup"),
|
||||||
"items": [
|
"items": [
|
||||||
|
@ -117,6 +117,16 @@ def get_data():
|
|||||||
"link": "Tree/Sales Person",
|
"link": "Tree/Sales Person",
|
||||||
"description": _("Manage Sales Person Tree."),
|
"description": _("Manage Sales Person Tree."),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "report",
|
||||||
|
"is_query_report": True,
|
||||||
|
"name": "Addresses And Contacts",
|
||||||
|
"label": "Sales Partner Addresses And Contacts",
|
||||||
|
"doctype": "Address",
|
||||||
|
"route_options": {
|
||||||
|
"party_type": "Sales Partner"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "report",
|
"type": "report",
|
||||||
"is_query_report": True,
|
"is_query_report": True,
|
||||||
@ -215,8 +225,12 @@ def get_data():
|
|||||||
{
|
{
|
||||||
"type": "report",
|
"type": "report",
|
||||||
"is_query_report": True,
|
"is_query_report": True,
|
||||||
"name": "Customer Addresses And Contacts",
|
"name": "Addresses And Contacts",
|
||||||
"doctype": "Contact"
|
"label": "Customer Addresses And Contacts",
|
||||||
|
"doctype": "Address",
|
||||||
|
"route_options": {
|
||||||
|
"party_type": "Customer"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "report",
|
"type": "report",
|
||||||
|
@ -25,6 +25,7 @@ erpnext.LeadController = frappe.ui.form.Controller.extend({
|
|||||||
refresh: function() {
|
refresh: function() {
|
||||||
var doc = this.frm.doc;
|
var doc = this.frm.doc;
|
||||||
erpnext.toggle_naming_series();
|
erpnext.toggle_naming_series();
|
||||||
|
frappe.dynamic_link = {doc: this.frm.doc, fieldname: 'name', doctype: 'Lead'}
|
||||||
|
|
||||||
if(!this.frm.doc.__islocal && this.frm.doc.__onload && !this.frm.doc.__onload.is_customer) {
|
if(!this.frm.doc.__islocal && this.frm.doc.__onload && !this.frm.doc.__onload.is_customer) {
|
||||||
this.frm.add_custom_button(__("Customer"), this.create_customer, __("Make"));
|
this.frm.add_custom_button(__("Customer"), this.create_customer, __("Make"));
|
||||||
@ -34,9 +35,9 @@ erpnext.LeadController = frappe.ui.form.Controller.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!this.frm.doc.__islocal) {
|
if(!this.frm.doc.__islocal) {
|
||||||
erpnext.utils.render_address_and_contact(cur_frm);
|
frappe.geo.render_address_and_contact(cur_frm);
|
||||||
} else {
|
} else {
|
||||||
erpnext.utils.clear_address_and_contact(cur_frm);
|
frappe.geo.clear_address_and_contact(cur_frm);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ from frappe.utils import cstr, validate_email_add, cint, comma_and, has_gravatar
|
|||||||
from frappe.model.mapper import get_mapped_doc
|
from frappe.model.mapper import get_mapped_doc
|
||||||
|
|
||||||
from erpnext.controllers.selling_controller import SellingController
|
from erpnext.controllers.selling_controller import SellingController
|
||||||
from erpnext.utilities.address_and_contact import load_address_and_contact
|
from frappe.geo.address_and_contact import load_address_and_contact
|
||||||
from erpnext.accounts.party import set_taxes
|
from erpnext.accounts.party import set_taxes
|
||||||
|
|
||||||
sender_field = "email_id"
|
sender_field = "email_id"
|
||||||
|
@ -106,30 +106,6 @@ class Opportunity(TransactionBase):
|
|||||||
lead_name, company_name = frappe.db.get_value("Lead", self.lead, ["lead_name", "company_name"])
|
lead_name, company_name = frappe.db.get_value("Lead", self.lead, ["lead_name", "company_name"])
|
||||||
self.customer_name = company_name or lead_name
|
self.customer_name = company_name or lead_name
|
||||||
|
|
||||||
def get_cust_address(self,name):
|
|
||||||
details = frappe.db.sql("""select customer_name, address, territory, customer_group
|
|
||||||
from `tabCustomer` where name = %s and docstatus != 2""", (name), as_dict = 1)
|
|
||||||
if details:
|
|
||||||
ret = {
|
|
||||||
'customer_name': details and details[0]['customer_name'] or '',
|
|
||||||
'address' : details and details[0]['address'] or '',
|
|
||||||
'territory' : details and details[0]['territory'] or '',
|
|
||||||
'customer_group' : details and details[0]['customer_group'] or ''
|
|
||||||
}
|
|
||||||
# ********** get primary contact details (this is done separately coz. , in case there is no primary contact thn it would not be able to fetch customer details in case of join query)
|
|
||||||
|
|
||||||
contact_det = frappe.db.sql("""select contact_name, contact_no, email_id
|
|
||||||
from `tabContact` where customer = %s and is_customer = 1
|
|
||||||
and is_primary_contact = 'Yes' and docstatus != 2""", name, as_dict = 1)
|
|
||||||
|
|
||||||
ret['contact_person'] = contact_det and contact_det[0]['contact_name'] or ''
|
|
||||||
ret['contact_no'] = contact_det and contact_det[0]['contact_no'] or ''
|
|
||||||
ret['email_id'] = contact_det and contact_det[0]['email_id'] or ''
|
|
||||||
|
|
||||||
return ret
|
|
||||||
else:
|
|
||||||
frappe.throw(_("Customer {0} does not exist").format(name), frappe.DoesNotExistError)
|
|
||||||
|
|
||||||
def on_update(self):
|
def on_update(self):
|
||||||
self.add_calendar_event()
|
self.add_calendar_event()
|
||||||
|
|
||||||
|
Binary file not shown.
After Width: | Height: | Size: 209 KiB |
BIN
erpnext/docs/assets/img/human-resources/employee-loan.png
Normal file
BIN
erpnext/docs/assets/img/human-resources/employee-loan.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 380 KiB |
Binary file not shown.
After Width: | Height: | Size: 162 KiB |
BIN
erpnext/docs/assets/img/human-resources/loan-type.png
Normal file
BIN
erpnext/docs/assets/img/human-resources/loan-type.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 120 KiB |
BIN
erpnext/docs/assets/img/human-resources/repayment-info.png
Normal file
BIN
erpnext/docs/assets/img/human-resources/repayment-info.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 64 KiB |
BIN
erpnext/docs/assets/img/human-resources/repayment-schedule.png
Normal file
BIN
erpnext/docs/assets/img/human-resources/repayment-schedule.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 424 KiB |
@ -0,0 +1,56 @@
|
|||||||
|
# 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">
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -15,4 +15,5 @@ holiday-list
|
|||||||
human-resource-setup
|
human-resource-setup
|
||||||
daily-work-summary
|
daily-work-summary
|
||||||
fleet-management
|
fleet-management
|
||||||
|
employee-loan-management
|
||||||
articles
|
articles
|
||||||
|
@ -107,7 +107,6 @@ portal_menu_items = [
|
|||||||
{"title": _("Shipments"), "route": "/shipments", "reference_doctype": "Delivery Note", "role":"Customer"},
|
{"title": _("Shipments"), "route": "/shipments", "reference_doctype": "Delivery Note", "role":"Customer"},
|
||||||
{"title": _("Issues"), "route": "/issues", "reference_doctype": "Issue", "role":"Customer"},
|
{"title": _("Issues"), "route": "/issues", "reference_doctype": "Issue", "role":"Customer"},
|
||||||
{"title": _("Addresses"), "route": "/addresses", "reference_doctype": "Address"},
|
{"title": _("Addresses"), "route": "/addresses", "reference_doctype": "Address"},
|
||||||
{"title": _("Announcements"), "route": "/announcement", "reference_doctype": "Announcement"},
|
|
||||||
{"title": _("Fees"), "route": "/fees", "reference_doctype": "Fees", "role":"Student"}
|
{"title": _("Fees"), "route": "/fees", "reference_doctype": "Fees", "role":"Student"}
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -122,18 +121,7 @@ has_website_permission = {
|
|||||||
"Sales Invoice": "erpnext.controllers.website_list_for_contact.has_website_permission",
|
"Sales Invoice": "erpnext.controllers.website_list_for_contact.has_website_permission",
|
||||||
"Supplier Quotation": "erpnext.controllers.website_list_for_contact.has_website_permission",
|
"Supplier Quotation": "erpnext.controllers.website_list_for_contact.has_website_permission",
|
||||||
"Delivery Note": "erpnext.controllers.website_list_for_contact.has_website_permission",
|
"Delivery Note": "erpnext.controllers.website_list_for_contact.has_website_permission",
|
||||||
"Issue": "erpnext.support.doctype.issue.issue.has_website_permission",
|
"Issue": "erpnext.support.doctype.issue.issue.has_website_permission"
|
||||||
"Discussion": "erpnext.schools.web_form.discussion.discussion.has_website_permission"
|
|
||||||
}
|
|
||||||
|
|
||||||
permission_query_conditions = {
|
|
||||||
"Contact": "erpnext.utilities.address_and_contact.get_permission_query_conditions_for_contact",
|
|
||||||
"Address": "erpnext.utilities.address_and_contact.get_permission_query_conditions_for_address"
|
|
||||||
}
|
|
||||||
|
|
||||||
has_permission = {
|
|
||||||
"Contact": "erpnext.utilities.address_and_contact.has_permission",
|
|
||||||
"Address": "erpnext.utilities.address_and_contact.has_permission"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dump_report_map = "erpnext.startup.report_data_map.data_map"
|
dump_report_map = "erpnext.startup.report_data_map.data_map"
|
||||||
@ -153,7 +141,7 @@ doc_events = {
|
|||||||
"after_insert": "frappe.email.doctype.contact.contact.update_contact",
|
"after_insert": "frappe.email.doctype.contact.contact.update_contact",
|
||||||
"validate": "erpnext.hr.doctype.employee.employee.validate_employee_role",
|
"validate": "erpnext.hr.doctype.employee.employee.validate_employee_role",
|
||||||
"on_update": "erpnext.hr.doctype.employee.employee.update_user_permissions",
|
"on_update": "erpnext.hr.doctype.employee.employee.update_user_permissions",
|
||||||
"on_update": "erpnext.utilities.address_and_contact.set_default_role"
|
"on_update": "frappe.geo.address_and_contact.set_default_role"
|
||||||
},
|
},
|
||||||
("Sales Taxes and Charges Template", 'Price List'): {
|
("Sales Taxes and Charges Template", 'Price List'): {
|
||||||
"on_update": "erpnext.shopping_cart.doctype.shopping_cart_settings.shopping_cart_settings.validate_cart_settings"
|
"on_update": "erpnext.shopping_cart.doctype.shopping_cart_settings.shopping_cart_settings.validate_cart_settings"
|
||||||
|
88
erpnext/hr/doctype/employee_loan/employee_loan.js
Normal file
88
erpnext/hr/doctype/employee_loan/employee_loan.js
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
// 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"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
$.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
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
refresh: function(frm) {
|
||||||
|
frm.trigger("toggle_fields");
|
||||||
|
|
||||||
|
if(frm.doc.docstatus==1) {
|
||||||
|
frm.add_custom_button(__('Ledger'), function() {
|
||||||
|
frappe.route_options = {
|
||||||
|
"voucher_no": frm.doc.name,
|
||||||
|
"from_date": frm.doc.posting_date,
|
||||||
|
"to_date": frm.doc.posting_date,
|
||||||
|
"company": frm.doc.company,
|
||||||
|
group_by_voucher: 0
|
||||||
|
};
|
||||||
|
frappe.set_route("query-report", "General Ledger");
|
||||||
|
}, "fa fa-table");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
employee_loan_application: function(frm) {
|
||||||
|
return frm.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")
|
||||||
|
}
|
||||||
|
});
|
892
erpnext/hr/doctype/employee_loan/employee_loan.json
Normal file
892
erpnext/hr/doctype/employee_loan/employee_loan.json
Normal file
@ -0,0 +1,892 @@
|
|||||||
|
{
|
||||||
|
"allow_copy": 0,
|
||||||
|
"allow_import": 1,
|
||||||
|
"allow_rename": 0,
|
||||||
|
"autoname": "ELN.####",
|
||||||
|
"beta": 0,
|
||||||
|
"creation": "2016-12-02 10:11:49.673604",
|
||||||
|
"custom": 0,
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "DocType",
|
||||||
|
"document_type": "Document",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"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_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_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": 0,
|
||||||
|
"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": "employee_loan_application",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Employee Loan Application",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Employee Loan Application",
|
||||||
|
"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_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "loan_type",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Loan Type",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Loan 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,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "column_break_3",
|
||||||
|
"fieldtype": "Column Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 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_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"default": "",
|
||||||
|
"fieldname": "posting_date",
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Posting Date",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 1,
|
||||||
|
"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": "company",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 1,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Company",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Company",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 1,
|
||||||
|
"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": "status",
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Status",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Loan Unpaid\nLoan Paid\nEMI in progress\nLoan Repaid",
|
||||||
|
"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_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "repay_from_salary",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Repay from Salary",
|
||||||
|
"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_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "section_break_8",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Loan Details",
|
||||||
|
"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_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "loan_amount",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Loan Amount",
|
||||||
|
"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": 1,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"default": "",
|
||||||
|
"fieldname": "rate_of_interest",
|
||||||
|
"fieldtype": "Percent",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Rate of Interest (%) / Year",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "loan_type.rate_of_interest",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 1,
|
||||||
|
"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": "disbursement_date",
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Disbursement 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": 1,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "column_break_11",
|
||||||
|
"fieldtype": "Column Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 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_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"default": "Repay Over Number of Periods",
|
||||||
|
"fieldname": "repayment_method",
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Repayment Method",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "\nRepay Fixed Amount per Period\nRepay Over Number of Periods",
|
||||||
|
"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,
|
||||||
|
"default": "",
|
||||||
|
"depends_on": "",
|
||||||
|
"fieldname": "repayment_periods",
|
||||||
|
"fieldtype": "Int",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Repayment Period in Months",
|
||||||
|
"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_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"default": "",
|
||||||
|
"depends_on": "",
|
||||||
|
"fieldname": "monthly_repayment_amount",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Repayment Amount",
|
||||||
|
"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_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "account_info",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Account Info",
|
||||||
|
"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_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "mode_of_payment",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Mode of Payment",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Mode of Payment",
|
||||||
|
"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": "payment_account",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Payment Account",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Account",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 1,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "column_break_9",
|
||||||
|
"fieldtype": "Column Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 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_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "employee_loan_account",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Employee Loan Account",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Account",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 1,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "section_break_15",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Repayment Schedule",
|
||||||
|
"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_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "repayment_schedule",
|
||||||
|
"fieldtype": "Table",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Repayment Schedule",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 1,
|
||||||
|
"options": "Repayment Schedule",
|
||||||
|
"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_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "section_break_17",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Totals",
|
||||||
|
"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_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"default": "0",
|
||||||
|
"fieldname": "total_payment",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Total Payment",
|
||||||
|
"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,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "column_break_19",
|
||||||
|
"fieldtype": "Column Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 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_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"default": "0",
|
||||||
|
"fieldname": "total_interest_payable",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Total Interest Payable",
|
||||||
|
"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,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "amended_from",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Amended From",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 1,
|
||||||
|
"options": "Employee Loan",
|
||||||
|
"permlevel": 0,
|
||||||
|
"print_hide": 1,
|
||||||
|
"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
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"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-01-17 07:13:10.704520",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "HR",
|
||||||
|
"name": "Employee Loan",
|
||||||
|
"name_case": "",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [
|
||||||
|
{
|
||||||
|
"amend": 0,
|
||||||
|
"apply_user_permissions": 0,
|
||||||
|
"cancel": 1,
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"if_owner": 0,
|
||||||
|
"import": 0,
|
||||||
|
"is_custom": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "HR Manager",
|
||||||
|
"set_user_permissions": 0,
|
||||||
|
"share": 1,
|
||||||
|
"submit": 1,
|
||||||
|
"write": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"quick_entry": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"read_only_onload": 0,
|
||||||
|
"search_fields": "posting_date",
|
||||||
|
"sort_field": "creation",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"track_changes": 1,
|
||||||
|
"track_seen": 0
|
||||||
|
}
|
128
erpnext/hr/doctype/employee_loan/employee_loan.py
Normal file
128
erpnext/hr/doctype/employee_loan/employee_loan.py
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe, math
|
||||||
|
import erpnext
|
||||||
|
from frappe import _
|
||||||
|
from frappe.utils import flt, rounded, add_months, nowdate
|
||||||
|
from erpnext.controllers.accounts_controller import AccountsController
|
||||||
|
from erpnext.accounts.general_ledger import make_gl_entries
|
||||||
|
|
||||||
|
class EmployeeLoan(AccountsController):
|
||||||
|
def validate(self):
|
||||||
|
check_repayment_method(self.repayment_method, self.loan_amount, self.monthly_repayment_amount, self.repayment_periods)
|
||||||
|
if not self.company:
|
||||||
|
self.company = erpnext.get_default_company()
|
||||||
|
if not self.posting_date:
|
||||||
|
self.posting_date = nowdate()
|
||||||
|
if self.loan_type and not self.rate_of_interest:
|
||||||
|
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)
|
||||||
|
|
||||||
|
self.make_repayment_schedule()
|
||||||
|
self.set_repayment_period()
|
||||||
|
self.calculate_totals()
|
||||||
|
|
||||||
|
def on_submit(self):
|
||||||
|
self.make_gl_entries()
|
||||||
|
|
||||||
|
def on_cancel(self):
|
||||||
|
self.make_gl_entries()
|
||||||
|
|
||||||
|
def make_gl_entries(self):
|
||||||
|
gl_entries = []
|
||||||
|
# Gl entries for employee loan account
|
||||||
|
gl_entries.append(
|
||||||
|
self.get_gl_dict({
|
||||||
|
"account": self.employee_loan_account,
|
||||||
|
"party_type": "Employee",
|
||||||
|
"party": self.employee,
|
||||||
|
"debit": self.loan_amount,
|
||||||
|
"debit_in_account_currency": self.loan_amount
|
||||||
|
})
|
||||||
|
)
|
||||||
|
# Gl entries for payment account
|
||||||
|
gl_entries.append(
|
||||||
|
self.get_gl_dict({
|
||||||
|
"account": self.payment_account,
|
||||||
|
"credit": self.loan_amount,
|
||||||
|
"credit_in_account_currency": self.loan_amount
|
||||||
|
})
|
||||||
|
)
|
||||||
|
make_gl_entries(gl_entries, cancel=(self.docstatus == 2))
|
||||||
|
|
||||||
|
def make_repayment_schedule(self):
|
||||||
|
self.repayment_schedule = []
|
||||||
|
payment_date = self.disbursement_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
|
||||||
|
balance_amount = rounded(balance_amount + interest_amount - self.monthly_repayment_amount)
|
||||||
|
|
||||||
|
if balance_amount < 0:
|
||||||
|
principal_amount += balance_amount
|
||||||
|
balance_amount = 0.0
|
||||||
|
|
||||||
|
total_payment = principal_amount + interest_amount
|
||||||
|
|
||||||
|
self.append("repayment_schedule", {
|
||||||
|
"payment_date": payment_date,
|
||||||
|
"principal_amount": principal_amount,
|
||||||
|
"interest_amount": interest_amount,
|
||||||
|
"total_payment": total_payment,
|
||||||
|
"balance_loan_amount": balance_amount
|
||||||
|
})
|
||||||
|
|
||||||
|
next_payment_date = add_months(payment_date, 1)
|
||||||
|
payment_date = next_payment_date
|
||||||
|
|
||||||
|
def set_repayment_period(self):
|
||||||
|
if self.repayment_method == "Repay Fixed Amount per Period":
|
||||||
|
repayment_periods = len(self.repayment_schedule)
|
||||||
|
|
||||||
|
self.repayment_periods = repayment_periods
|
||||||
|
|
||||||
|
def calculate_totals(self):
|
||||||
|
self.total_payment = 0
|
||||||
|
self.total_interest_payable = 0
|
||||||
|
for data in self.repayment_schedule:
|
||||||
|
self.total_payment += data.total_payment
|
||||||
|
self.total_interest_payable +=data.interest_amount
|
||||||
|
|
||||||
|
def update_status(self):
|
||||||
|
if self.disbursement_date:
|
||||||
|
self.status = "Loan Paid"
|
||||||
|
if len(self.repayment_schedule)>0:
|
||||||
|
self.status = "repayment in progress"
|
||||||
|
|
||||||
|
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:
|
||||||
|
frappe.throw(_("Please enter Repayment Periods"))
|
||||||
|
|
||||||
|
if repayment_method == "Repay Fixed Amount per Period":
|
||||||
|
if not monthly_repayment_amount:
|
||||||
|
frappe.throw(_("Please enter repayment Amount"))
|
||||||
|
if monthly_repayment_amount > loan_amount:
|
||||||
|
frappe.throw(_("Monthly Repayment Amount cannot be greater than Loan Amount"))
|
||||||
|
|
||||||
|
def get_monthly_repayment_amount(repayment_method, loan_amount, rate_of_interest, repayment_periods):
|
||||||
|
if repayment_method == "Repay Over Number of Periods":
|
||||||
|
if rate_of_interest:
|
||||||
|
monthly_interest_rate = flt(rate_of_interest) / (12 *100)
|
||||||
|
monthly_repayment_amount = math.ceil((loan_amount * monthly_interest_rate *
|
||||||
|
(1 + monthly_interest_rate)**repayment_periods) \
|
||||||
|
/ ((1 + monthly_interest_rate)**repayment_periods - 1))
|
||||||
|
else:
|
||||||
|
monthly_repayment_amount = math.ceil(flt(loan_amount) / repayment_periods)
|
||||||
|
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
|
68
erpnext/hr/doctype/employee_loan/test_employee_loan.py
Normal file
68
erpnext/hr/doctype/employee_loan/test_employee_loan.py
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
# See license.txt
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
import erpnext
|
||||||
|
import unittest
|
||||||
|
from frappe.utils import nowdate
|
||||||
|
from erpnext.hr.doctype.salary_structure.test_salary_structure import make_employee
|
||||||
|
|
||||||
|
class TestEmployeeLoan(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)
|
||||||
|
|
||||||
|
def test_employee_loan(self):
|
||||||
|
employee_loan = frappe.get_doc("Employee Loan", {"employee":self.employee})
|
||||||
|
self.assertEquals(employee_loan.monthly_repayment_amount, 15052)
|
||||||
|
self.assertEquals(employee_loan.total_interest_payable, 21034)
|
||||||
|
self.assertEquals(employee_loan.total_payment, 301034)
|
||||||
|
|
||||||
|
schedule = employee_loan.repayment_schedule
|
||||||
|
|
||||||
|
self.assertEquals(len(schedule), 20)
|
||||||
|
|
||||||
|
for idx, principal_amount, interest_amount, balance_loan_amount in [[3, 13369, 1683, 227079], [19, 14941, 105, 0], [17, 14740, 312, 29785]]:
|
||||||
|
self.assertEquals(schedule[idx].principal_amount, principal_amount)
|
||||||
|
self.assertEquals(schedule[idx].interest_amount, interest_amount)
|
||||||
|
self.assertEquals(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()
|
||||||
|
|
||||||
|
self.assertEquals(len(employee_loan.repayment_schedule), 22)
|
||||||
|
self.assertEquals(employee_loan.total_interest_payable, 22712)
|
||||||
|
self.assertEquals(employee_loan.total_payment, 302712)
|
||||||
|
|
||||||
|
|
||||||
|
def create_loan_type(loan_name, maximum_loan_amount, rate_of_interest):
|
||||||
|
if not frappe.db.get_value("Loan Type", loan_name):
|
||||||
|
frappe.get_doc({
|
||||||
|
"doctype": "Loan Type",
|
||||||
|
"loan_name": loan_name,
|
||||||
|
"maximum_loan_amount": maximum_loan_amount,
|
||||||
|
"rate_of_interest": rate_of_interest
|
||||||
|
}).insert()
|
||||||
|
|
||||||
|
def create_employee_loan(employee, loan_type, loan_amount, repayment_method, repayment_periods):
|
||||||
|
if not frappe.db.get_value("Employee Loan", {"employee":employee}):
|
||||||
|
employee_loan = frappe.new_doc("Employee Loan")
|
||||||
|
employee_loan.update({
|
||||||
|
"employee": employee,
|
||||||
|
"loan_type": loan_type,
|
||||||
|
"loan_amount": loan_amount,
|
||||||
|
"repayment_method": repayment_method,
|
||||||
|
"repayment_periods": repayment_periods,
|
||||||
|
"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")
|
||||||
|
})
|
||||||
|
employee_loan.insert()
|
||||||
|
return employee_loan
|
||||||
|
else:
|
||||||
|
return frappe.get_doc("Employee Loan", {"employee":employee})
|
@ -0,0 +1,16 @@
|
|||||||
|
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
frappe.ui.form.on('Employee Loan Application', {
|
||||||
|
refresh: function(frm) {
|
||||||
|
frm.trigger("toggle_fields")
|
||||||
|
},
|
||||||
|
repayment_method: function(frm) {
|
||||||
|
frm.trigger("toggle_fields")
|
||||||
|
},
|
||||||
|
|
||||||
|
toggle_fields: function(frm) {
|
||||||
|
frm.toggle_enable("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")
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,681 @@
|
|||||||
|
{
|
||||||
|
"allow_copy": 0,
|
||||||
|
"allow_import": 0,
|
||||||
|
"allow_rename": 0,
|
||||||
|
"autoname": "ELA/.#####",
|
||||||
|
"beta": 0,
|
||||||
|
"creation": "2016-12-02 12:35:56.046811",
|
||||||
|
"custom": 0,
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "DocType",
|
||||||
|
"document_type": "",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"default": "Today",
|
||||||
|
"fieldname": "posting_date",
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Posting 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,
|
||||||
|
"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_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": 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_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_on_submit": 1,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "status",
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Status",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Open\nApproved\nRejected",
|
||||||
|
"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_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "company",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Company",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Company",
|
||||||
|
"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": "section_break_4",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Loan Info",
|
||||||
|
"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_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "loan_type",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Loan Type",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Loan 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,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "loan_amount",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Loan Amount",
|
||||||
|
"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": 1,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "required_by_date",
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Required by 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,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "column_break_7",
|
||||||
|
"fieldtype": "Column Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 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_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "description",
|
||||||
|
"fieldtype": "Small Text",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Reason",
|
||||||
|
"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_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "repayment_info",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Repayment Info",
|
||||||
|
"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_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "repayment_method",
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Repayment Method",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "\nRepay Fixed Amount per Period\nRepay Over Number of Periods",
|
||||||
|
"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": "rate_of_interest",
|
||||||
|
"fieldtype": "Percent",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Rate of Interest",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "loan_type.rate_of_interest",
|
||||||
|
"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": "total_payable_interest",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Total Payable Interest",
|
||||||
|
"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,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "column_break_11",
|
||||||
|
"fieldtype": "Column Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 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_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"depends_on": "",
|
||||||
|
"fieldname": "repayment_amount",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Repayment Amount",
|
||||||
|
"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_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"depends_on": "",
|
||||||
|
"fieldname": "repayment_periods",
|
||||||
|
"fieldtype": "Int",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Repayment Period in Months",
|
||||||
|
"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_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "total_payable_amount",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Total Payable Amount",
|
||||||
|
"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,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "amended_from",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Amended From",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 1,
|
||||||
|
"options": "Employee Loan Application",
|
||||||
|
"permlevel": 0,
|
||||||
|
"print_hide": 1,
|
||||||
|
"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
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"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-01-09 12:02:36.562577",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "HR",
|
||||||
|
"name": "Employee Loan Application",
|
||||||
|
"name_case": "",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [
|
||||||
|
{
|
||||||
|
"amend": 0,
|
||||||
|
"apply_user_permissions": 0,
|
||||||
|
"cancel": 1,
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"if_owner": 0,
|
||||||
|
"import": 0,
|
||||||
|
"is_custom": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "HR Manager",
|
||||||
|
"set_user_permissions": 0,
|
||||||
|
"share": 1,
|
||||||
|
"submit": 1,
|
||||||
|
"write": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"amend": 0,
|
||||||
|
"apply_user_permissions": 0,
|
||||||
|
"cancel": 0,
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"if_owner": 0,
|
||||||
|
"import": 0,
|
||||||
|
"is_custom": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "Employee",
|
||||||
|
"set_user_permissions": 0,
|
||||||
|
"share": 1,
|
||||||
|
"submit": 1,
|
||||||
|
"write": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"quick_entry": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"read_only_onload": 0,
|
||||||
|
"search_fields": "employee, employee_name, loan_type, loan_amount",
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"timeline_field": "employee",
|
||||||
|
"title_field": "employee_name",
|
||||||
|
"track_changes": 1,
|
||||||
|
"track_seen": 0
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe, math
|
||||||
|
from frappe import _
|
||||||
|
from frappe.utils import flt
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
from erpnext.hr.doctype.employee_loan.employee_loan import get_monthly_repayment_amount, check_repayment_method
|
||||||
|
|
||||||
|
class EmployeeLoanApplication(Document):
|
||||||
|
def validate(self):
|
||||||
|
check_repayment_method(self.repayment_method, self.loan_amount, self.repayment_amount, self.repayment_periods)
|
||||||
|
self.validate_loan_amount()
|
||||||
|
self.get_repayment_details()
|
||||||
|
|
||||||
|
def validate_loan_amount(self):
|
||||||
|
maximum_loan_limit = frappe.db.get_value('Loan Type', self.loan_type, 'maximum_loan_amount')
|
||||||
|
if self.loan_amount > maximum_loan_limit:
|
||||||
|
frappe.throw(_("Loan Amount cannot exceed Maximum Loan Amount of {0}").format(maximum_loan_limit))
|
||||||
|
|
||||||
|
def get_repayment_details(self):
|
||||||
|
if self.repayment_method == "Repay Over Number of Periods":
|
||||||
|
self.repayment_amount = get_monthly_repayment_amount(self.repayment_method, self.loan_amount, self.rate_of_interest, self.repayment_periods)
|
||||||
|
|
||||||
|
if self.repayment_method == "Repay Fixed Amount per Period":
|
||||||
|
monthly_interest_rate = flt(self.rate_of_interest) / (12 *100)
|
||||||
|
self.repayment_periods = math.ceil((math.log(self.repayment_amount) - math.log(self.repayment_amount - \
|
||||||
|
(self.loan_amount*monthly_interest_rate)))/(math.log(1+monthly_interest_rate)))
|
||||||
|
|
||||||
|
self.total_payable_amount = self.repayment_amount * self.repayment_periods
|
||||||
|
self.total_payable_interest = self.total_payable_amount - self.loan_amount
|
@ -0,0 +1,51 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
# See license.txt
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
import unittest
|
||||||
|
from erpnext.hr.doctype.salary_structure.test_salary_structure import make_employee
|
||||||
|
|
||||||
|
class TestEmployeeLoanApplication(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.create_loan_type()
|
||||||
|
self.employee = make_employee("kate_loan@loan.com")
|
||||||
|
self.create_loan_application()
|
||||||
|
|
||||||
|
def create_loan_type(self):
|
||||||
|
if not frappe.db.get_value("Loan Type", "Home Loan"):
|
||||||
|
frappe.get_doc({
|
||||||
|
"doctype": "Loan Type",
|
||||||
|
"loan_name": "Home Loan",
|
||||||
|
"maximum_loan_amount": 500000,
|
||||||
|
"rate_of_interest": 9.2
|
||||||
|
}).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")
|
||||||
|
loan_application.update({
|
||||||
|
"employee": self.employee,
|
||||||
|
"loan_type": "Home Loan",
|
||||||
|
"rate_of_interest": 9.2,
|
||||||
|
"loan_amount": 250000,
|
||||||
|
"repayment_method": "Repay Over Number of Periods",
|
||||||
|
"repayment_periods": 24
|
||||||
|
})
|
||||||
|
loan_application.insert()
|
||||||
|
|
||||||
|
|
||||||
|
def test_loan_totals(self):
|
||||||
|
loan_application = frappe.get_doc("Employee Loan Application", {"employee":self.employee})
|
||||||
|
self.assertEquals(loan_application.repayment_amount, 11445)
|
||||||
|
self.assertEquals(loan_application.total_payable_interest, 24680)
|
||||||
|
self.assertEquals(loan_application.total_payable_amount, 274680)
|
||||||
|
|
||||||
|
loan_application.repayment_method = "Repay Fixed Amount per Period"
|
||||||
|
loan_application.repayment_amount = 15000
|
||||||
|
loan_application.save()
|
||||||
|
|
||||||
|
self.assertEquals(loan_application.repayment_periods, 18)
|
||||||
|
self.assertEquals(loan_application.total_payable_interest, 20000)
|
||||||
|
self.assertEquals(loan_application.total_payable_amount, 270000)
|
7
erpnext/hr/doctype/loan_type/loan_type.js
Normal file
7
erpnext/hr/doctype/loan_type/loan_type.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
frappe.ui.form.on('Loan Type', {
|
||||||
|
refresh: function(frm) {
|
||||||
|
}
|
||||||
|
});
|
@ -1,15 +1,15 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"allow_copy": 0,
|
||||||
"allow_import": 1,
|
"allow_import": 0,
|
||||||
"allow_rename": 0,
|
"allow_rename": 0,
|
||||||
"autoname": "Discussion.####",
|
"autoname": "field:loan_name",
|
||||||
"beta": 0,
|
"beta": 0,
|
||||||
"creation": "2016-06-13 07:57:38.326925",
|
"creation": "2016-12-02 10:41:40.732843",
|
||||||
"custom": 0,
|
"custom": 0,
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "Document",
|
"document_type": "",
|
||||||
"editable_grid": 0,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@ -17,7 +17,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"fieldname": "subject",
|
"fieldname": "loan_name",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
@ -25,7 +25,7 @@
|
|||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
"in_list_view": 0,
|
"in_list_view": 0,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"label": "Subject",
|
"label": "Loan Name",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
@ -36,7 +36,7 @@
|
|||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 1,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
@ -45,18 +45,17 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"fieldname": "course",
|
"fieldname": "maximum_loan_amount",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Currency",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
"in_list_view": 1,
|
"in_list_view": 0,
|
||||||
"in_standard_filter": 1,
|
"in_standard_filter": 0,
|
||||||
"label": "Course",
|
"label": "Maximum Loan Amount",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"options": "Course",
|
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
@ -65,7 +64,92 @@
|
|||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 1,
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "rate_of_interest",
|
||||||
|
"fieldtype": "Percent",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Rate of Interest (%) Yearly",
|
||||||
|
"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": 1,
|
||||||
|
"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_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_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"default": "",
|
||||||
|
"fieldname": "disabled",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Disabled",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "",
|
||||||
|
"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,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
@ -96,34 +180,6 @@
|
|||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "amended_from",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Amended From",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
|
||||||
"options": "Discussion",
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 1,
|
|
||||||
"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
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"hide_heading": 0,
|
"hide_heading": 0,
|
||||||
@ -132,14 +188,14 @@
|
|||||||
"image_view": 0,
|
"image_view": 0,
|
||||||
"in_create": 0,
|
"in_create": 0,
|
||||||
"in_dialog": 0,
|
"in_dialog": 0,
|
||||||
"is_submittable": 1,
|
"is_submittable": 0,
|
||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2016-11-07 05:28:34.032169",
|
"modified": "2016-12-29 15:54:17.716285",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Schools",
|
"module": "HR",
|
||||||
"name": "Discussion",
|
"name": "Loan Type",
|
||||||
"name_case": "",
|
"name_case": "",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
@ -158,18 +214,17 @@
|
|||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 1,
|
"report": 1,
|
||||||
"role": "Academics User",
|
"role": "HR Manager",
|
||||||
"set_user_permissions": 0,
|
"set_user_permissions": 0,
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"submit": 1,
|
"submit": 0,
|
||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 1,
|
"quick_entry": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"read_only_onload": 0,
|
"read_only_onload": 0,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"title_field": "subject",
|
"track_seen": 0
|
||||||
"track_seen": 1
|
|
||||||
}
|
}
|
10
erpnext/hr/doctype/loan_type/loan_type.py
Normal file
10
erpnext/hr/doctype/loan_type/loan_type.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
class LoanType(Document):
|
||||||
|
pass
|
12
erpnext/hr/doctype/loan_type/test_loan_type.py
Normal file
12
erpnext/hr/doctype/loan_type/test_loan_type.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
# See license.txt
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
# test_records = frappe.get_test_records('Loan Type')
|
||||||
|
|
||||||
|
class TestLoanType(unittest.TestCase):
|
||||||
|
pass
|
@ -1,60 +1,30 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"allow_copy": 0,
|
||||||
"allow_import": 0,
|
"allow_import": 0,
|
||||||
"allow_rename": 1,
|
"allow_rename": 0,
|
||||||
"autoname": "Topic.####",
|
|
||||||
"beta": 0,
|
"beta": 0,
|
||||||
"creation": "2016-06-28 07:06:38.749398",
|
"creation": "2016-12-20 15:32:25.078334",
|
||||||
"custom": 0,
|
"custom": 0,
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "Document",
|
"document_type": "",
|
||||||
"editable_grid": 0,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 2,
|
||||||
"fieldname": "course",
|
"fieldname": "payment_date",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Date",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 1,
|
|
||||||
"label": "Course",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Course",
|
|
||||||
"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": 1,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "topic_name",
|
|
||||||
"fieldtype": "Data",
|
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"label": "Topic Name",
|
"label": "Payment Date",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
@ -64,7 +34,7 @@
|
|||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 1,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
@ -73,26 +43,26 @@
|
|||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 2,
|
||||||
"fieldname": "introduction",
|
"fieldname": "principal_amount",
|
||||||
"fieldtype": "Text",
|
"fieldtype": "Currency",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
"in_list_view": 0,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"label": "Introduction",
|
"label": "Principal Amount",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 1,
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 1,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 1,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
@ -101,26 +71,82 @@
|
|||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 2,
|
||||||
"fieldname": "content",
|
"fieldname": "interest_amount",
|
||||||
"fieldtype": "Text Editor",
|
"fieldtype": "Currency",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
"in_list_view": 0,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"label": "Content",
|
"label": "Interest Amount",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 1,
|
||||||
|
"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": 2,
|
||||||
|
"fieldname": "total_payment",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Total Payment",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 1,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 1,
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 2,
|
||||||
|
"fieldname": "balance_loan_amount",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Balance Loan Amount",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 1,
|
||||||
|
"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,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
@ -134,42 +160,20 @@
|
|||||||
"in_dialog": 0,
|
"in_dialog": 0,
|
||||||
"is_submittable": 0,
|
"is_submittable": 0,
|
||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2016-11-07 05:29:20.531725",
|
"modified": "2017-01-09 12:00:10.818772",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Schools",
|
"module": "HR",
|
||||||
"name": "Topic",
|
"name": "Repayment Schedule",
|
||||||
"name_case": "",
|
"name_case": "",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [],
|
||||||
{
|
|
||||||
"amend": 0,
|
|
||||||
"apply_user_permissions": 0,
|
|
||||||
"cancel": 0,
|
|
||||||
"create": 1,
|
|
||||||
"delete": 1,
|
|
||||||
"email": 1,
|
|
||||||
"export": 1,
|
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"is_custom": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "Academics User",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"read_only_onload": 0,
|
"read_only_onload": 0,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"title_field": "course",
|
"track_changes": 1,
|
||||||
"track_seen": 0
|
"track_seen": 0
|
||||||
}
|
}
|
10
erpnext/hr/doctype/repayment_schedule/repayment_schedule.py
Normal file
10
erpnext/hr/doctype/repayment_schedule/repayment_schedule.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
class RepaymentSchedule(Document):
|
||||||
|
pass
|
@ -110,6 +110,7 @@ cur_frm.cscript.depends_on_lwp = function(doc,dt,dn){
|
|||||||
calculate_earning_total(doc, dt, dn, true);
|
calculate_earning_total(doc, dt, dn, true);
|
||||||
calculate_ded_total(doc, dt, dn, true);
|
calculate_ded_total(doc, dt, dn, true);
|
||||||
calculate_net_pay(doc, dt, dn);
|
calculate_net_pay(doc, dt, dn);
|
||||||
|
refresh_many(['amount','gross_pay', 'rounded_total', 'net_pay', 'loan_repayment']);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Calculate earning total
|
// Calculate earning total
|
||||||
|
@ -1266,7 +1266,35 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"description": "Gross Pay + Arrear Amount +Encashment Amount - Total Deduction",
|
"fieldname": "loan_repayment",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Loan Repayment",
|
||||||
|
"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,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"description": "Gross Pay + Arrear Amount + Encashment Amount - Total Deduction - Loan Repayment",
|
||||||
"fieldname": "net_pay",
|
"fieldname": "net_pay",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@ -1362,7 +1390,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2016-12-14 08:26:31.400930",
|
"modified": "2017-01-09 12:37:03.802501",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "Salary Slip",
|
"name": "Salary Slip",
|
||||||
@ -1413,7 +1441,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"amend": 0,
|
||||||
"apply_user_permissions": 0,
|
"apply_user_permissions": 1,
|
||||||
"cancel": 0,
|
"cancel": 0,
|
||||||
"create": 0,
|
"create": 0,
|
||||||
"delete": 0,
|
"delete": 0,
|
||||||
@ -1430,6 +1458,7 @@
|
|||||||
"set_user_permissions": 0,
|
"set_user_permissions": 0,
|
||||||
"share": 0,
|
"share": 0,
|
||||||
"submit": 0,
|
"submit": 0,
|
||||||
|
"user_permission_doctypes": "[\"Employee\"]",
|
||||||
"write": 0
|
"write": 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -1440,5 +1469,6 @@
|
|||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"timeline_field": "employee",
|
"timeline_field": "employee",
|
||||||
"title_field": "employee_name",
|
"title_field": "employee_name",
|
||||||
|
"track_changes": 0,
|
||||||
"track_seen": 0
|
"track_seen": 0
|
||||||
}
|
}
|
@ -330,10 +330,20 @@ class SalarySlip(TransactionBase):
|
|||||||
self.sum_components('earnings', 'gross_pay')
|
self.sum_components('earnings', 'gross_pay')
|
||||||
self.sum_components('deductions', 'total_deduction')
|
self.sum_components('deductions', 'total_deduction')
|
||||||
|
|
||||||
self.net_pay = flt(self.gross_pay) - flt(self.total_deduction)
|
self.set_loan_repayment()
|
||||||
|
|
||||||
|
self.net_pay = flt(self.gross_pay) - (flt(self.total_deduction) + flt(self.loan_repayment))
|
||||||
self.rounded_total = rounded(self.net_pay,
|
self.rounded_total = rounded(self.net_pay,
|
||||||
self.precision("net_pay") if disable_rounded_total else 0)
|
self.precision("net_pay") if disable_rounded_total else 0)
|
||||||
|
|
||||||
|
def set_loan_repayment(self):
|
||||||
|
employee_loan = frappe.db.sql("""select sum(total_payment) as loan_repayment from `tabRepayment Schedule`
|
||||||
|
where payment_date between %s and %s and parent in (select name from `tabEmployee Loan`
|
||||||
|
where employee = %s and repay_from_salary = 1 and docstatus = 1)""",
|
||||||
|
(self.start_date, self.end_date, self.employee), as_dict=True)
|
||||||
|
if employee_loan:
|
||||||
|
self.loan_repayment = employee_loan[0].loan_repayment
|
||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
if self.net_pay < 0:
|
if self.net_pay < 0:
|
||||||
frappe.throw(_("Net Pay cannot be less than 0"))
|
frappe.throw(_("Net Pay cannot be less than 0"))
|
||||||
|
@ -7,7 +7,7 @@ import frappe
|
|||||||
import erpnext
|
import erpnext
|
||||||
import calendar
|
import calendar
|
||||||
from erpnext.accounts.utils import get_fiscal_year
|
from erpnext.accounts.utils import get_fiscal_year
|
||||||
from frappe.utils import getdate, nowdate, add_days
|
from frappe.utils import getdate, nowdate, add_days, flt
|
||||||
from erpnext.hr.doctype.salary_structure.salary_structure import make_salary_slip
|
from erpnext.hr.doctype.salary_structure.salary_structure import make_salary_slip
|
||||||
from erpnext.hr.doctype.process_payroll.test_process_payroll import get_salary_component_account
|
from erpnext.hr.doctype.process_payroll.test_process_payroll import get_salary_component_account
|
||||||
from erpnext.hr.doctype.process_payroll.process_payroll import get_month_details
|
from erpnext.hr.doctype.process_payroll.process_payroll import get_month_details
|
||||||
@ -24,7 +24,6 @@ class TestSalarySlip(unittest.TestCase):
|
|||||||
|
|
||||||
frappe.db.set_value("Company", erpnext.get_default_company(), "default_holiday_list", "Salary Slip Test Holiday List")
|
frappe.db.set_value("Company", erpnext.get_default_company(), "default_holiday_list", "Salary Slip Test Holiday List")
|
||||||
|
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 0)
|
frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 0)
|
||||||
frappe.set_user("Administrator")
|
frappe.set_user("Administrator")
|
||||||
@ -40,12 +39,12 @@ class TestSalarySlip(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertEquals(ss.total_working_days, no_of_days[0])
|
self.assertEquals(ss.total_working_days, no_of_days[0])
|
||||||
self.assertEquals(ss.payment_days, no_of_days[0])
|
self.assertEquals(ss.payment_days, no_of_days[0])
|
||||||
self.assertEquals(ss.earnings[0].amount, 5000)
|
self.assertEquals(ss.earnings[0].amount, 25000)
|
||||||
self.assertEquals(ss.earnings[1].amount, 3000)
|
self.assertEquals(ss.earnings[1].amount, 3000)
|
||||||
self.assertEquals(ss.deductions[0].amount, 5000)
|
self.assertEquals(ss.deductions[0].amount, 5000)
|
||||||
self.assertEquals(ss.deductions[1].amount, 2500)
|
self.assertEquals(ss.deductions[1].amount, 5000)
|
||||||
self.assertEquals(ss.gross_pay, 10500)
|
self.assertEquals(ss.gross_pay, 40500)
|
||||||
self.assertEquals(ss.net_pay, 3000)
|
self.assertEquals(ss.net_pay, 29918)
|
||||||
|
|
||||||
def test_salary_slip_with_holidays_excluded(self):
|
def test_salary_slip_with_holidays_excluded(self):
|
||||||
no_of_days = self.get_no_of_days()
|
no_of_days = self.get_no_of_days()
|
||||||
@ -58,13 +57,13 @@ class TestSalarySlip(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertEquals(ss.total_working_days, no_of_days[0] - no_of_days[1])
|
self.assertEquals(ss.total_working_days, no_of_days[0] - no_of_days[1])
|
||||||
self.assertEquals(ss.payment_days, no_of_days[0] - no_of_days[1])
|
self.assertEquals(ss.payment_days, no_of_days[0] - no_of_days[1])
|
||||||
self.assertEquals(ss.earnings[0].amount, 5000)
|
self.assertEquals(ss.earnings[0].amount, 25000)
|
||||||
self.assertEquals(ss.earnings[0].default_amount, 5000)
|
self.assertEquals(ss.earnings[0].default_amount, 25000)
|
||||||
self.assertEquals(ss.earnings[1].amount, 3000)
|
self.assertEquals(ss.earnings[1].amount, 3000)
|
||||||
self.assertEquals(ss.deductions[0].amount, 5000)
|
self.assertEquals(ss.deductions[0].amount, 5000)
|
||||||
self.assertEquals(ss.deductions[1].amount, 2500)
|
self.assertEquals(ss.deductions[1].amount, 5000)
|
||||||
self.assertEquals(ss.gross_pay, 10500)
|
self.assertEquals(ss.gross_pay, 40500)
|
||||||
self.assertEquals(ss.net_pay, 3000)
|
self.assertEquals(ss.net_pay, 29918)
|
||||||
|
|
||||||
def test_payment_days(self):
|
def test_payment_days(self):
|
||||||
no_of_days = self.get_no_of_days()
|
no_of_days = self.get_no_of_days()
|
||||||
@ -130,9 +129,23 @@ class TestSalarySlip(unittest.TestCase):
|
|||||||
ss = frappe.get_doc("Salary Slip",
|
ss = frappe.get_doc("Salary Slip",
|
||||||
self.make_employee_salary_slip("test_employee@salary.com", "Monthly"))
|
self.make_employee_salary_slip("test_employee@salary.com", "Monthly"))
|
||||||
ss.submit()
|
ss.submit()
|
||||||
|
|
||||||
email_queue = frappe.db.sql("""select name from `tabEmail Queue`""")
|
email_queue = frappe.db.sql("""select name from `tabEmail Queue`""")
|
||||||
self.assertTrue(email_queue)
|
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")
|
||||||
|
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()
|
||||||
|
ss = frappe.get_doc("Salary Slip",
|
||||||
|
self.make_employee_salary_slip("test_employee@salary.com", "Monthly"))
|
||||||
|
ss.submit()
|
||||||
|
self.assertEquals(ss.loan_repayment, 582)
|
||||||
|
self.assertEquals(ss.net_pay, (flt(ss.gross_pay) - (flt(ss.total_deduction) + flt(ss.loan_repayment))))
|
||||||
|
|
||||||
def test_payroll_frequency(self):
|
def test_payroll_frequency(self):
|
||||||
fiscal_year = get_fiscal_year(nowdate(), company="_Test Company")[0]
|
fiscal_year = get_fiscal_year(nowdate(), company="_Test Company")[0]
|
||||||
month = "%02d" % getdate(nowdate()).month
|
month = "%02d" % getdate(nowdate()).month
|
||||||
@ -167,7 +180,7 @@ class TestSalarySlip(unittest.TestCase):
|
|||||||
}).insert()
|
}).insert()
|
||||||
|
|
||||||
if not frappe.db.get_value("Employee", {"user_id": user}):
|
if not frappe.db.get_value("Employee", {"user_id": user}):
|
||||||
frappe.get_doc({
|
employee = frappe.get_doc({
|
||||||
"doctype": "Employee",
|
"doctype": "Employee",
|
||||||
"naming_series": "EMP-",
|
"naming_series": "EMP-",
|
||||||
"employee_name": user,
|
"employee_name": user,
|
||||||
@ -183,6 +196,9 @@ class TestSalarySlip(unittest.TestCase):
|
|||||||
"status": "Active",
|
"status": "Active",
|
||||||
"employment_type": "Intern"
|
"employment_type": "Intern"
|
||||||
}).insert()
|
}).insert()
|
||||||
|
return employee.name
|
||||||
|
else:
|
||||||
|
return frappe.get_value("Employee", {"employee_name":user}, "name")
|
||||||
|
|
||||||
def make_holiday_list(self):
|
def make_holiday_list(self):
|
||||||
fiscal_year = get_fiscal_year(nowdate(), company="_Test Company")
|
fiscal_year = get_fiscal_year(nowdate(), company="_Test Company")
|
||||||
@ -278,7 +294,7 @@ def make_salary_structure(sal_struct, payroll_frequency, employee):
|
|||||||
|
|
||||||
def get_employee_details(employee):
|
def get_employee_details(employee):
|
||||||
return [{"employee": employee,
|
return [{"employee": employee,
|
||||||
"base": 25000,
|
"base": 50000,
|
||||||
"variable": 5000
|
"variable": 5000
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -289,14 +305,14 @@ def get_earnings_component():
|
|||||||
"salary_component": 'Basic Salary',
|
"salary_component": 'Basic Salary',
|
||||||
"abbr":'BS',
|
"abbr":'BS',
|
||||||
"condition": 'base > 10000',
|
"condition": 'base > 10000',
|
||||||
"formula": 'base*.2',
|
"formula": 'base*.5',
|
||||||
"idx": 1
|
"idx": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"salary_component": 'Basic Salary',
|
"salary_component": 'Basic Salary',
|
||||||
"abbr":'BS',
|
"abbr":'BS',
|
||||||
"condition": 'base < 10000',
|
"condition": 'base < 10000',
|
||||||
"formula": 'base*.1',
|
"formula": 'base*.2',
|
||||||
"idx": 2
|
"idx": 2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -320,13 +336,13 @@ def get_deductions_component():
|
|||||||
"salary_component": 'Professional Tax',
|
"salary_component": 'Professional Tax',
|
||||||
"abbr":'PT',
|
"abbr":'PT',
|
||||||
"condition": 'base > 10000',
|
"condition": 'base > 10000',
|
||||||
"formula": 'base*.2',
|
"formula": 'base*.1',
|
||||||
"idx": 1
|
"idx": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"salary_component": 'TDS',
|
"salary_component": 'TDS',
|
||||||
"abbr":'T',
|
"abbr":'T',
|
||||||
"formula": 'base*.5',
|
"formula": 'base*.1',
|
||||||
"idx": 2
|
"idx": 2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -19,8 +19,8 @@ class TestSalaryStructure(unittest.TestCase):
|
|||||||
frappe.db.set_value("Company", erpnext.get_default_company(), "default_holiday_list", "Salary Structure Test Holiday List")
|
frappe.db.set_value("Company", erpnext.get_default_company(), "default_holiday_list", "Salary Structure Test Holiday List")
|
||||||
make_earning_salary_component(["Basic Salary", "Allowance", "HRA"])
|
make_earning_salary_component(["Basic Salary", "Allowance", "HRA"])
|
||||||
make_deduction_salary_component(["Professional Tax", "TDS"])
|
make_deduction_salary_component(["Professional Tax", "TDS"])
|
||||||
self.make_employee("test_employee@salary.com")
|
make_employee("test_employee@salary.com")
|
||||||
self.make_employee("test_employee_2@salary.com")
|
make_employee("test_employee_2@salary.com")
|
||||||
|
|
||||||
def make_holiday_list(self):
|
def make_holiday_list(self):
|
||||||
if not frappe.db.get_value("Holiday List", "Salary Structure Test Holiday List"):
|
if not frappe.db.get_value("Holiday List", "Salary Structure Test Holiday List"):
|
||||||
@ -34,7 +34,18 @@ class TestSalaryStructure(unittest.TestCase):
|
|||||||
holiday_list.get_weekly_off_dates()
|
holiday_list.get_weekly_off_dates()
|
||||||
holiday_list.save()
|
holiday_list.save()
|
||||||
|
|
||||||
def make_employee(self, user):
|
def test_amount_totals(self):
|
||||||
|
sal_slip = frappe.get_value("Salary Slip", {"employee_name":"test_employee@salary.com"})
|
||||||
|
if not sal_slip:
|
||||||
|
sal_slip = make_salary_slip_from_salary_structure(employee=frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}))
|
||||||
|
self.assertEquals(sal_slip.get("salary_structure"), 'Salary Structure Sample')
|
||||||
|
self.assertEquals(sal_slip.get("earnings")[0].amount, 5000)
|
||||||
|
self.assertEquals(sal_slip.get("deductions")[0].amount, 5000)
|
||||||
|
self.assertEquals(sal_slip.get("deductions")[1].amount, 2500)
|
||||||
|
self.assertEquals(sal_slip.get("total_deduction"), 7500)
|
||||||
|
self.assertEquals(sal_slip.get("net_pay"), 7500)
|
||||||
|
|
||||||
|
def make_employee(user):
|
||||||
if not frappe.db.get_value("User", user):
|
if not frappe.db.get_value("User", user):
|
||||||
frappe.get_doc({
|
frappe.get_doc({
|
||||||
"doctype": "User",
|
"doctype": "User",
|
||||||
@ -65,18 +76,6 @@ class TestSalaryStructure(unittest.TestCase):
|
|||||||
else:
|
else:
|
||||||
return frappe.get_value("Employee", {"employee_name":user}, "name")
|
return frappe.get_value("Employee", {"employee_name":user}, "name")
|
||||||
|
|
||||||
def test_amount_totals(self):
|
|
||||||
sal_slip = frappe.get_value("Salary Slip", {"employee_name":"test_employee@salary.com"})
|
|
||||||
if not sal_slip:
|
|
||||||
sal_slip = make_salary_slip_from_salary_structure(employee=frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}))
|
|
||||||
self.assertEquals(sal_slip.get("salary_structure"), 'Salary Structure Sample')
|
|
||||||
self.assertEquals(sal_slip.get("earnings")[0].amount, 5000)
|
|
||||||
self.assertEquals(sal_slip.get("deductions")[0].amount, 5000)
|
|
||||||
self.assertEquals(sal_slip.get("deductions")[1].amount, 2500)
|
|
||||||
self.assertEquals(sal_slip.get("total_deduction"), 7500)
|
|
||||||
self.assertEquals(sal_slip.get("net_pay"), 7500)
|
|
||||||
|
|
||||||
|
|
||||||
def make_salary_slip_from_salary_structure(employee):
|
def make_salary_slip_from_salary_structure(employee):
|
||||||
sal_struct = make_salary_structure('Salary Structure Sample')
|
sal_struct = make_salary_structure('Salary Structure Sample')
|
||||||
sal_slip = make_salary_slip(sal_struct, employee = employee)
|
sal_slip = make_salary_slip(sal_struct, employee = employee)
|
||||||
|
@ -30,15 +30,18 @@ def get_columns(leave_types):
|
|||||||
return columns
|
return columns
|
||||||
|
|
||||||
def get_data(filters, leave_types):
|
def get_data(filters, leave_types):
|
||||||
|
user = frappe.session.user
|
||||||
allocation_records_based_on_to_date = get_leave_allocation_records(filters.to_date)
|
allocation_records_based_on_to_date = get_leave_allocation_records(filters.to_date)
|
||||||
|
|
||||||
active_employees = frappe.get_all("Employee",
|
active_employees = frappe.get_all("Employee",
|
||||||
filters = { "status": "Active", "company": filters.company},
|
filters = { "status": "Active", "company": filters.company},
|
||||||
fields = ["name", "employee_name", "department"])
|
fields = ["name", "employee_name", "department", "user_id"])
|
||||||
|
|
||||||
data = []
|
data = []
|
||||||
for employee in active_employees:
|
for employee in active_employees:
|
||||||
|
leave_approvers = [l.leave_approver for l in frappe.db.sql("""select leave_approver from `tabEmployee Leave Approver` where parent = %s""",
|
||||||
|
(employee.name),as_dict=True)]
|
||||||
|
if (len(leave_approvers) and user in leave_approvers) or (user in ["Administrator", employee.user_id]) or ("HR Manager" in frappe.get_roles(user)):
|
||||||
row = [employee.name, employee.employee_name, employee.department]
|
row = [employee.name, employee.employee_name, employee.department]
|
||||||
|
|
||||||
for leave_type in leave_types:
|
for leave_type in leave_types:
|
||||||
|
@ -8,7 +8,7 @@ from erpnext.setup.setup_wizard import domainify
|
|||||||
|
|
||||||
def execute():
|
def execute():
|
||||||
frappe.reload_doctype('Role')
|
frappe.reload_doctype('Role')
|
||||||
for dt in ("assessment", "announcement", "course", "fees"):
|
for dt in ("assessment", "course", "fees"):
|
||||||
frappe.reload_doc("schools", "doctype", dt)
|
frappe.reload_doc("schools", "doctype", dt)
|
||||||
|
|
||||||
frappe.reload_doc('website', 'doctype', 'portal_menu_item')
|
frappe.reload_doc('website', 'doctype', 'portal_menu_item')
|
||||||
|
@ -20,7 +20,8 @@ def execute():
|
|||||||
frappe.reload_doc("schools", "doctype", "evaluation_criteria")
|
frappe.reload_doc("schools", "doctype", "evaluation_criteria")
|
||||||
|
|
||||||
|
|
||||||
for assessment in frappe.get_all("Assessment Plan", fields=["name", "grading_scale"]):
|
for assessment in frappe.get_all("Assessment Plan", fields=["name", "grading_scale"], filters = [["docstatus", "!=", 2 ]]):
|
||||||
|
print assessment
|
||||||
for stud_result in frappe.db.sql("select * from `tabAssessment Result` where parent= %s", assessment.name, as_dict=True):
|
for stud_result in frappe.db.sql("select * from `tabAssessment Result` where parent= %s", assessment.name, as_dict=True):
|
||||||
if stud_result.result:
|
if stud_result.result:
|
||||||
assessment_result = frappe.new_doc("Assessment Result")
|
assessment_result = frappe.new_doc("Assessment Result")
|
||||||
@ -30,6 +31,7 @@ def execute():
|
|||||||
assessment_result.grading_scale = assessment.grading_scale
|
assessment_result.grading_scale = assessment.grading_scale
|
||||||
assessment_result.total_score = stud_result.result
|
assessment_result.total_score = stud_result.result
|
||||||
assessment_result.flags.ignore_validate = True
|
assessment_result.flags.ignore_validate = True
|
||||||
|
assessment_result.flags.ignore_mandatory = True
|
||||||
assessment_result.save()
|
assessment_result.save()
|
||||||
|
|
||||||
frappe.db.sql("""delete from `tabAssessment Result` where parent != '' or parent is not null""")
|
frappe.db.sql("""delete from `tabAssessment Result` where parent != '' or parent is not null""")
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"allow_copy": 0,
|
||||||
"allow_import": 1,
|
"allow_import": 1,
|
||||||
"allow_rename": 0,
|
"allow_rename": 1,
|
||||||
"autoname": "TASK.#####",
|
"autoname": "TASK.#####",
|
||||||
"beta": 0,
|
"beta": 0,
|
||||||
"creation": "2013-01-29 19:25:50",
|
"creation": "2013-01-29 19:25:50",
|
||||||
@ -944,7 +944,7 @@
|
|||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 5,
|
"max_attachments": 5,
|
||||||
"menu_index": 0,
|
"menu_index": 0,
|
||||||
"modified": "2016-11-07 05:12:23.294476",
|
"modified": "2017-01-27 01:26:24.985167",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Projects",
|
"module": "Projects",
|
||||||
"name": "Task",
|
"name": "Task",
|
||||||
@ -960,7 +960,6 @@
|
|||||||
"export": 0,
|
"export": 0,
|
||||||
"if_owner": 0,
|
"if_owner": 0,
|
||||||
"import": 0,
|
"import": 0,
|
||||||
"is_custom": 0,
|
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
@ -979,5 +978,6 @@
|
|||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"timeline_field": "project",
|
"timeline_field": "project",
|
||||||
"title_field": "subject",
|
"title_field": "subject",
|
||||||
|
"track_changes": 0,
|
||||||
"track_seen": 1
|
"track_seen": 1
|
||||||
}
|
}
|
@ -31,7 +31,8 @@ erpnext.financial_statements = {
|
|||||||
"account": data.account,
|
"account": data.account,
|
||||||
"company": frappe.query_report_filters_by_name.company.get_value(),
|
"company": frappe.query_report_filters_by_name.company.get_value(),
|
||||||
"from_date": data.from_date || data.year_start_date,
|
"from_date": data.from_date || data.year_start_date,
|
||||||
"to_date": data.to_date || data.year_end_date
|
"to_date": data.to_date || data.year_end_date,
|
||||||
|
"project": $.grep(frappe.query_report.filters, function(e){ return e.df.fieldname == 'project'; })[0].$input.val()
|
||||||
};
|
};
|
||||||
frappe.set_route("query-report", "General Ledger");
|
frappe.set_route("query-report", "General Ledger");
|
||||||
},
|
},
|
||||||
|
@ -36,7 +36,7 @@ $.extend(erpnext.queries, {
|
|||||||
|
|
||||||
customer_filter: function(doc) {
|
customer_filter: function(doc) {
|
||||||
if(!doc.customer) {
|
if(!doc.customer) {
|
||||||
frappe.throw(__("Please set {0}", __(frappe.meta.get_label(doc.doctype, "customer", doc.name))));
|
frappe.throw(__("Please set {0}", [__(frappe.meta.get_label(doc.doctype, "customer", doc.name))]));
|
||||||
}
|
}
|
||||||
|
|
||||||
return { filters: { customer: doc.customer } };
|
return { filters: { customer: doc.customer } };
|
||||||
@ -45,8 +45,8 @@ $.extend(erpnext.queries, {
|
|||||||
contact_query: function(doc) {
|
contact_query: function(doc) {
|
||||||
if(frappe.dynamic_link) {
|
if(frappe.dynamic_link) {
|
||||||
if(!doc[frappe.dynamic_link.fieldname]) {
|
if(!doc[frappe.dynamic_link.fieldname]) {
|
||||||
frappe.throw(__("Please set {0}", __(frappe.meta.get_label(doc.doctype,
|
frappe.throw(__("Please set {0}",
|
||||||
frappe.dynamic_link.fieldname, doc.name))));
|
[__(frappe.meta.get_label(doc.doctype, frappe.dynamic_link.fieldname, doc.name))]));
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -58,8 +58,8 @@ $.extend(erpnext.queries, {
|
|||||||
address_query: function(doc) {
|
address_query: function(doc) {
|
||||||
if(frappe.dynamic_link) {
|
if(frappe.dynamic_link) {
|
||||||
if(!doc[frappe.dynamic_link.fieldname]) {
|
if(!doc[frappe.dynamic_link.fieldname]) {
|
||||||
frappe.throw(__("Please set {0}", __(frappe.meta.get_label(doc.doctype,
|
frappe.throw(__("Please set {0}",
|
||||||
frappe.dynamic_link.fieldname, doc.name))));
|
[__(frappe.meta.get_label(doc.doctype, frappe.dynamic_link.fieldname, doc.name))]));
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -68,9 +68,16 @@ $.extend(erpnext.queries, {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
company_address_query: function(doc) {
|
||||||
|
return {
|
||||||
|
query: 'frappe.geo.doctype.address.address.address_query',
|
||||||
|
filters: { is_your_company_address: 1, link_doctype: 'Company', link_name: doc.company || '' }
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
supplier_filter: function(doc) {
|
supplier_filter: function(doc) {
|
||||||
if(!doc.supplier) {
|
if(!doc.supplier) {
|
||||||
frappe.throw(__("Please set {0}", __(frappe.meta.get_label(doc.doctype, "supplier", doc.name))));
|
frappe.throw(__("Please set {0}", [__(frappe.meta.get_label(doc.doctype, "supplier", doc.name))]));
|
||||||
}
|
}
|
||||||
|
|
||||||
return { filters: { supplier: doc.supplier } };
|
return { filters: { supplier: doc.supplier } };
|
||||||
@ -78,8 +85,8 @@ $.extend(erpnext.queries, {
|
|||||||
|
|
||||||
lead_filter: function(doc) {
|
lead_filter: function(doc) {
|
||||||
if(!doc.lead) {
|
if(!doc.lead) {
|
||||||
frappe.throw(__("Please specify a") + " " +
|
frappe.throw(__("Please specify a {0}",
|
||||||
__(frappe.meta.get_label(doc.doctype, "lead", doc.name)));
|
[__(frappe.meta.get_label(doc.doctype, "lead", doc.name))]));
|
||||||
}
|
}
|
||||||
|
|
||||||
return { filters: { lead: doc.lead } };
|
return { filters: { lead: doc.lead } };
|
||||||
|
@ -82,32 +82,6 @@ $.extend(erpnext, {
|
|||||||
|
|
||||||
|
|
||||||
$.extend(erpnext.utils, {
|
$.extend(erpnext.utils, {
|
||||||
clear_address_and_contact: function(frm) {
|
|
||||||
$(frm.fields_dict['address_html'].wrapper).html("");
|
|
||||||
frm.fields_dict['contact_html'] && $(frm.fields_dict['contact_html'].wrapper).html("");
|
|
||||||
},
|
|
||||||
|
|
||||||
render_address_and_contact: function(frm) {
|
|
||||||
// render address
|
|
||||||
$(frm.fields_dict['address_html'].wrapper)
|
|
||||||
.html(frappe.render_template("address_list",
|
|
||||||
cur_frm.doc.__onload))
|
|
||||||
.find(".btn-address").on("click", function() {
|
|
||||||
frappe.new_doc("Address");
|
|
||||||
});
|
|
||||||
|
|
||||||
// render contact
|
|
||||||
if(frm.fields_dict['contact_html']) {
|
|
||||||
$(frm.fields_dict['contact_html'].wrapper)
|
|
||||||
.html(frappe.render_template("contact_list",
|
|
||||||
cur_frm.doc.__onload))
|
|
||||||
.find(".btn-contact").on("click", function() {
|
|
||||||
frappe.new_doc("Contact");
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
set_party_dashboard_indicators: function(frm) {
|
set_party_dashboard_indicators: function(frm) {
|
||||||
if(frm.doc.__onload && frm.doc.__onload.dashboard_info) {
|
if(frm.doc.__onload && frm.doc.__onload.dashboard_info) {
|
||||||
var info = frm.doc.__onload.dashboard_info;
|
var info = frm.doc.__onload.dashboard_info;
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
// Copyright (c) 2016, Frappe and contributors
|
|
||||||
// For license information, please see license.txt
|
|
||||||
|
|
||||||
frappe.ui.form.on('Announcement', {
|
|
||||||
onload: function(frm) {
|
|
||||||
frm.add_fetch('instructor', 'instructor_name' , 'posted_by');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
@ -1,315 +0,0 @@
|
|||||||
{
|
|
||||||
"allow_copy": 0,
|
|
||||||
"allow_import": 0,
|
|
||||||
"allow_rename": 0,
|
|
||||||
"autoname": "announcement.#####",
|
|
||||||
"beta": 0,
|
|
||||||
"creation": "2016-06-23 05:37:33.996289",
|
|
||||||
"custom": 0,
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "DocType",
|
|
||||||
"document_type": "Document",
|
|
||||||
"editable_grid": 0,
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"default": "",
|
|
||||||
"fieldname": "receiver",
|
|
||||||
"fieldtype": "Select",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"label": "Receiver",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Student\nStudent Group\nAll Students",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 1,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"fieldname": "instructor",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"label": "Instructor",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Instructor",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"fieldname": "column_break_3",
|
|
||||||
"fieldtype": "Column Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"depends_on": "eval: doc.receiver == \"Student\"",
|
|
||||||
"fieldname": "student",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"label": "Student",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Student",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 1,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"depends_on": "eval: doc.receiver == \"Student Group\"",
|
|
||||||
"fieldname": "student_group",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"label": "Student Group",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Student Group",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 1,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"fieldname": "posted_by",
|
|
||||||
"fieldtype": "Data",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"label": "Posted By",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"fieldname": "section_break_5",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"fieldname": "subject",
|
|
||||||
"fieldtype": "Small Text",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"label": "Subject",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"fieldname": "description",
|
|
||||||
"fieldtype": "Text Editor",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"label": "Description",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"fieldname": "amended_from",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"label": "Amended From",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
|
||||||
"options": "Announcement",
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 1,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 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": "2016-07-21 06:30:12.825629",
|
|
||||||
"modified_by": "r@r.com",
|
|
||||||
"module": "Schools",
|
|
||||||
"name": "Announcement",
|
|
||||||
"name_case": "",
|
|
||||||
"owner": "demo@erpnext.com",
|
|
||||||
"permissions": [
|
|
||||||
{
|
|
||||||
"amend": 1,
|
|
||||||
"apply_user_permissions": 0,
|
|
||||||
"cancel": 1,
|
|
||||||
"create": 1,
|
|
||||||
"delete": 1,
|
|
||||||
"email": 1,
|
|
||||||
"export": 1,
|
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "Academics User",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 1,
|
|
||||||
"write": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"quick_entry": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"read_only_onload": 0,
|
|
||||||
"sort_field": "modified",
|
|
||||||
"sort_order": "DESC",
|
|
||||||
"title_field": "subject",
|
|
||||||
"track_seen": 1
|
|
||||||
}
|
|
@ -1,75 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2015, Frappe and contributors
|
|
||||||
# For license information, please see license.txt
|
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
import frappe
|
|
||||||
from frappe.model.document import Document
|
|
||||||
from frappe import _
|
|
||||||
|
|
||||||
class Announcement(Document):
|
|
||||||
def validate(self):
|
|
||||||
self.validate_receiver()
|
|
||||||
self.set_posted_by()
|
|
||||||
|
|
||||||
def validate_receiver(self):
|
|
||||||
if self.receiver == "Student":
|
|
||||||
if not self.student:
|
|
||||||
frappe.throw(_("Please select a Student"))
|
|
||||||
self.student_group = None
|
|
||||||
elif self.receiver == "Student Group":
|
|
||||||
if not self.student_group:
|
|
||||||
frappe.throw(_("Please select a Student Group"))
|
|
||||||
self.student = None
|
|
||||||
else:
|
|
||||||
self.student_group = None
|
|
||||||
self.student = None
|
|
||||||
|
|
||||||
def set_posted_by(self):
|
|
||||||
if self.instructor:
|
|
||||||
self.posted_by = frappe.db.get_value("Instructor", self.instructor, "instructor_name")
|
|
||||||
else:
|
|
||||||
self.posted_by = frappe.session.user
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_message_list(doctype, txt, filters, limit_start, limit_page_length=20):
|
|
||||||
user = frappe.session.user
|
|
||||||
student = frappe.db.sql("select name from `tabStudent` where student_email_id= %s", user)
|
|
||||||
if student:
|
|
||||||
sg_list = frappe.db.sql("""select parent from `tabStudent Group Student` as sgs
|
|
||||||
where sgs.student = %s """,(student))
|
|
||||||
|
|
||||||
data = frappe.db.sql("""select name, receiver, subject, description, posted_by, modified,
|
|
||||||
student, student_group
|
|
||||||
from `tabAnnouncement` as announce
|
|
||||||
where (announce.receiver = "Student" and announce.student = %s)
|
|
||||||
or (announce.receiver = "Student Group" and announce.student_group in %s)
|
|
||||||
or announce.receiver = "All Students"
|
|
||||||
and announce.docstatus = 1
|
|
||||||
order by announce.idx asc limit {0} , {1}"""
|
|
||||||
.format(limit_start, limit_page_length), (student,sg_list), as_dict = True)
|
|
||||||
|
|
||||||
for announcement in data:
|
|
||||||
try:
|
|
||||||
num_attachments = frappe.db.sql(""" select count(file_url) from tabFile as file
|
|
||||||
where file.attached_to_name=%s
|
|
||||||
and file.attached_to_doctype=%s""",(announcement.name,"Announcement"))
|
|
||||||
|
|
||||||
except IOError or frappe.DoesNotExistError:
|
|
||||||
pass
|
|
||||||
frappe.local.message_log.pop()
|
|
||||||
|
|
||||||
announcement.num_attachments = num_attachments[0][0]
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
def get_list_context(context=None):
|
|
||||||
return {
|
|
||||||
"show_sidebar": True,
|
|
||||||
'no_breadcrumbs': True,
|
|
||||||
"title": _("Announcements"),
|
|
||||||
"get_list": get_message_list,
|
|
||||||
"row_template": "templates/includes/announcement/announcement_row.html"
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2015, Frappe and Contributors
|
|
||||||
# See license.txt
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import frappe
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
# test_records = frappe.get_test_records('Announcement')
|
|
||||||
|
|
||||||
class TestAnnouncement(unittest.TestCase):
|
|
||||||
pass
|
|
@ -13,7 +13,7 @@ class AssessmentPlan(Document):
|
|||||||
frappe.throw(_("Please select Student Group or Student Batch"))
|
frappe.throw(_("Please select Student Group or Student Batch"))
|
||||||
self.validate_student_batch()
|
self.validate_student_batch()
|
||||||
self.validate_overlap()
|
self.validate_overlap()
|
||||||
|
self.validate_max_score()
|
||||||
|
|
||||||
def validate_overlap(self):
|
def validate_overlap(self):
|
||||||
"""Validates overlap for Student Group/Student Batch, Instructor, Room"""
|
"""Validates overlap for Student Group/Student Batch, Instructor, Room"""
|
||||||
@ -43,3 +43,10 @@ class AssessmentPlan(Document):
|
|||||||
def validate_student_batch(self):
|
def validate_student_batch(self):
|
||||||
if self.student_group:
|
if self.student_group:
|
||||||
self.student_batch = frappe.db.get_value("Student Group", self.student_group, "student_batch")
|
self.student_batch = frappe.db.get_value("Student Group", self.student_group, "student_batch")
|
||||||
|
|
||||||
|
def validate_max_score(self):
|
||||||
|
max_score = 0
|
||||||
|
for d in self.evaluation_criterias:
|
||||||
|
max_score += d.maximum_score
|
||||||
|
if self.maximum_assessment_score != max_score:
|
||||||
|
frappe.throw(_("Sum of Scores of Evaluation Criterias needs to be {0}.".format(self.maximum_assessment_score)))
|
@ -1,8 +0,0 @@
|
|||||||
// Copyright (c) 2016, Frappe and contributors
|
|
||||||
// For license information, please see license.txt
|
|
||||||
|
|
||||||
frappe.ui.form.on('Discussion', {
|
|
||||||
refresh: function(frm) {
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
@ -1,37 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2015, Frappe and contributors
|
|
||||||
# For license information, please see license.txt
|
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
import frappe
|
|
||||||
from frappe import _
|
|
||||||
from frappe.model.document import Document
|
|
||||||
|
|
||||||
class Discussion(Document):
|
|
||||||
def validate(self):
|
|
||||||
if not self.owner== frappe.session.user:
|
|
||||||
frappe.throw(_("Not Permitted"))
|
|
||||||
|
|
||||||
def get_discussions(doctype, txt, filters, limit_start, limit_page_length=20):
|
|
||||||
from frappe.www.list import get_list
|
|
||||||
if not filters:
|
|
||||||
filters = []
|
|
||||||
filters.append(("Discussion", "course", "=", frappe.form_dict.course))
|
|
||||||
return get_list(doctype, txt, filters, limit_start, limit_page_length, ignore_permissions=True)
|
|
||||||
|
|
||||||
def get_list_context(context=None):
|
|
||||||
course_name = frappe.form_dict.course
|
|
||||||
portal_items = [{'reference_doctype': u'Topic', 'route': u"/topic?course=" + str(course_name), 'show_always': 0L, 'title': u'Topics'},
|
|
||||||
{'reference_doctype': u'Discussion', 'route': u"/discussion?course=" + str(course_name), 'show_always': 0L, 'title': u'Discussions'},
|
|
||||||
|
|
||||||
]
|
|
||||||
sidebar_title = course_name
|
|
||||||
return {
|
|
||||||
"show_sidebar": True,
|
|
||||||
'no_breadcrumbs': True,
|
|
||||||
"get_list" : get_discussions,
|
|
||||||
"title": _("Discussions"),
|
|
||||||
"sidebar_items" : portal_items,
|
|
||||||
"sidebar_title" : sidebar_title,
|
|
||||||
"row_template": "templates/includes/discussion/discussion_row.html"
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2015, Frappe and Contributors
|
|
||||||
# See license.txt
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import frappe
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
# test_records = frappe.get_test_records('Discussion')
|
|
||||||
|
|
||||||
class TestDiscussion(unittest.TestCase):
|
|
||||||
pass
|
|
@ -1,12 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2015, Frappe and Contributors
|
|
||||||
# See license.txt
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import frappe
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
# test_records = frappe.get_test_records('Topic')
|
|
||||||
|
|
||||||
class TestTopic(unittest.TestCase):
|
|
||||||
pass
|
|
@ -1,8 +0,0 @@
|
|||||||
// Copyright (c) 2016, Frappe and contributors
|
|
||||||
// For license information, please see license.txt
|
|
||||||
|
|
||||||
frappe.ui.form.on('Topic', {
|
|
||||||
refresh: function(frm) {
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
@ -1,49 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2015, Frappe and contributors
|
|
||||||
# For license information, please see license.txt
|
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
import frappe
|
|
||||||
from frappe.model.document import Document
|
|
||||||
from frappe import _
|
|
||||||
|
|
||||||
class Topic(Document):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def get_topic_list(doctype, txt, filters, limit_start, limit_page_length=20):
|
|
||||||
user = frappe.session.user
|
|
||||||
student = frappe.db.sql("select name from `tabStudent` where student_email_id= %s", user)
|
|
||||||
if student:
|
|
||||||
data = frappe. db.sql('''select name, course, modified,topic_name, introduction, content from `tabTopic` as topic
|
|
||||||
where topic.course = %s
|
|
||||||
order by idx asc limit {0} , {1}'''.format(limit_start, limit_page_length),filters.course,as_dict = True)
|
|
||||||
|
|
||||||
for topic in data:
|
|
||||||
try:
|
|
||||||
num_attachments = frappe.db.sql(""" select count(file_url) from tabFile as file
|
|
||||||
where file.attached_to_name=%s
|
|
||||||
and file.attached_to_doctype=%s""",(topic.name,"Topic"))
|
|
||||||
|
|
||||||
except IOError or frappe.DoesNotExistError:
|
|
||||||
pass
|
|
||||||
frappe.local.message_log.pop()
|
|
||||||
|
|
||||||
topic.num_attachments = num_attachments[0][0]
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
def get_list_context(context=None):
|
|
||||||
course = frappe.get_doc('Course', frappe.form_dict.course)
|
|
||||||
portal_items = [{'reference_doctype': u'Topic', 'route': u"/topic?course=" + str(course.name), 'show_always': 0L, 'title': u'Topics'},
|
|
||||||
{'reference_doctype': u'Discussion', 'route': u"/discussion?course=" + str(course.name), 'show_always': 0L, 'title': u'Discussions'},
|
|
||||||
|
|
||||||
]
|
|
||||||
return {
|
|
||||||
"show_sidebar": True,
|
|
||||||
"title": _("Topic"),
|
|
||||||
'no_breadcrumbs': True,
|
|
||||||
"sidebar_items" : portal_items,
|
|
||||||
"sidebar_title" : course.name,
|
|
||||||
"get_list": get_topic_list,
|
|
||||||
"row_template": "templates/includes/topic/topic_row.html"
|
|
||||||
}
|
|
@ -61,7 +61,7 @@ def get_attendance_list(from_date, to_date, student_batch, students_list):
|
|||||||
students_with_leave_application = get_students_with_leave_application(from_date, to_date, students_list)
|
students_with_leave_application = get_students_with_leave_application(from_date, to_date, students_list)
|
||||||
for d in attendance_list:
|
for d in attendance_list:
|
||||||
att_map.setdefault(d.student, frappe._dict()).setdefault(d.date, "")
|
att_map.setdefault(d.student, frappe._dict()).setdefault(d.date, "")
|
||||||
if students_with_leave_application and d.student in students_with_leave_application.get(d.date,[]):
|
if students_with_leave_application and d.student in students_with_leave_application.get(d.date):
|
||||||
att_map[d.student][d.date] = "Present"
|
att_map[d.student][d.date] = "Present"
|
||||||
else:
|
else:
|
||||||
att_map[d.student][d.date] = d.status
|
att_map[d.student][d.date] = d.status
|
||||||
|
@ -37,7 +37,7 @@ frappe.ui.form.on("Customer", {
|
|||||||
frm.toggle_display(['address_html','contact_html'], !frm.doc.__islocal);
|
frm.toggle_display(['address_html','contact_html'], !frm.doc.__islocal);
|
||||||
|
|
||||||
if(!frm.doc.__islocal) {
|
if(!frm.doc.__islocal) {
|
||||||
erpnext.utils.render_address_and_contact(frm);
|
frappe.geo.render_address_and_contact(frm);
|
||||||
|
|
||||||
// custom buttons
|
// custom buttons
|
||||||
frm.add_custom_button(__('Accounting Ledger'), function() {
|
frm.add_custom_button(__('Accounting Ledger'), function() {
|
||||||
@ -53,7 +53,7 @@ frappe.ui.form.on("Customer", {
|
|||||||
erpnext.utils.set_party_dashboard_indicators(frm);
|
erpnext.utils.set_party_dashboard_indicators(frm);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
erpnext.utils.clear_address_and_contact(frm);
|
frappe.geo.clear_address_and_contact(frm);
|
||||||
}
|
}
|
||||||
|
|
||||||
var grid = cur_frm.get_field("sales_team").grid;
|
var grid = cur_frm.get_field("sales_team").grid;
|
||||||
|
@ -9,7 +9,7 @@ import frappe.defaults
|
|||||||
from frappe.utils import flt, cint, cstr
|
from frappe.utils import flt, cint, cstr
|
||||||
from frappe.desk.reportview import build_match_conditions
|
from frappe.desk.reportview import build_match_conditions
|
||||||
from erpnext.utilities.transaction_base import TransactionBase
|
from erpnext.utilities.transaction_base import TransactionBase
|
||||||
from erpnext.utilities.address_and_contact import load_address_and_contact, delete_contact_and_address
|
from frappe.geo.address_and_contact import load_address_and_contact, delete_contact_and_address
|
||||||
from erpnext.accounts.party import validate_party_accounts, get_timeline_data # keep this
|
from erpnext.accounts.party import validate_party_accounts, get_timeline_data # keep this
|
||||||
from erpnext.accounts.party_status import get_party_status
|
from erpnext.accounts.party_status import get_party_status
|
||||||
from erpnext import get_default_currency
|
from erpnext import get_default_currency
|
||||||
@ -95,9 +95,14 @@ class Customer(TransactionBase):
|
|||||||
def create_lead_address_contact(self):
|
def create_lead_address_contact(self):
|
||||||
if self.lead_name:
|
if self.lead_name:
|
||||||
# assign lead address to customer (if already not set)
|
# assign lead address to customer (if already not set)
|
||||||
address_name = frappe.get_value('Dynamic Link', dict(parenttype='Address', link_doctype='Lead', link_name=self.name))
|
address_names = frappe.get_all('Dynamic Link', filters={
|
||||||
if address_name:
|
"parenttype":"Address",
|
||||||
address = frappe.get_doc('Address', address_name)
|
"link_doctype":"Lead",
|
||||||
|
"link_name":self.lead_name
|
||||||
|
}, fields=["parent as name"])
|
||||||
|
|
||||||
|
for address_name in address_names:
|
||||||
|
address = frappe.get_doc('Address', address_name.get('name'))
|
||||||
if not address.has_link('Customer', self.name):
|
if not address.has_link('Customer', self.name):
|
||||||
address.append('links', dict(link_doctype='Customer', link_name=self.name))
|
address.append('links', dict(link_doctype='Customer', link_name=self.name))
|
||||||
address.save()
|
address.save()
|
||||||
@ -105,17 +110,17 @@ class Customer(TransactionBase):
|
|||||||
lead = frappe.db.get_value("Lead", self.lead_name, ["lead_name", "email_id", "phone", "mobile_no"], as_dict=True)
|
lead = frappe.db.get_value("Lead", self.lead_name, ["lead_name", "email_id", "phone", "mobile_no"], as_dict=True)
|
||||||
|
|
||||||
# create contact from lead
|
# create contact from lead
|
||||||
c = frappe.new_doc('Contact')
|
contact = frappe.new_doc('Contact')
|
||||||
c.first_name = lead.lead_name
|
contact.first_name = lead.lead_name
|
||||||
c.email_id = lead.email_id
|
contact.email_id = lead.email_id
|
||||||
c.phone = lead.phone
|
contact.phone = lead.phone
|
||||||
c.mobile_no = lead.mobile_no
|
contact.mobile_no = lead.mobile_no
|
||||||
c.is_primary_contact = 1
|
contact.is_primary_contact = 1
|
||||||
c.append('links', dict(link_doctype='Customer', link_name=self.name))
|
contact.append('links', dict(link_doctype='Customer', link_name=self.name))
|
||||||
c.flags.ignore_permissions = self.flags.ignore_permissions
|
contact.flags.ignore_permissions = self.flags.ignore_permissions
|
||||||
c.autoname()
|
contact.autoname()
|
||||||
if not frappe.db.exists("Contact", c.name):
|
if not frappe.db.exists("Contact", contact.name):
|
||||||
c.insert()
|
contact.insert()
|
||||||
|
|
||||||
def validate_name_with_customer_group(self):
|
def validate_name_with_customer_group(self):
|
||||||
if frappe.db.exists("Customer Group", self.name):
|
if frappe.db.exists("Customer Group", self.name):
|
||||||
@ -133,7 +138,7 @@ class Customer(TransactionBase):
|
|||||||
def on_trash(self):
|
def on_trash(self):
|
||||||
delete_contact_and_address('Customer', self.name)
|
delete_contact_and_address('Customer', self.name)
|
||||||
if self.lead_name:
|
if self.lead_name:
|
||||||
frappe.db.sql("update `tabLead` set status='Interested' where name=%s",self.lead_name)
|
frappe.db.sql("update `tabLead` set status='Interested' where name=%s", self.lead_name)
|
||||||
|
|
||||||
def after_rename(self, olddn, newdn, merge=False):
|
def after_rename(self, olddn, newdn, merge=False):
|
||||||
if frappe.defaults.get_global_default('cust_master_name') == 'Customer Name':
|
if frappe.defaults.get_global_default('cust_master_name') == 'Customer Name':
|
||||||
|
@ -12,9 +12,9 @@ def get_funnel_data(from_date, to_date):
|
|||||||
where (date(`modified`) between %s and %s)
|
where (date(`modified`) between %s and %s)
|
||||||
and status != "Do Not Contact" """, (from_date, to_date))[0][0]
|
and status != "Do Not Contact" """, (from_date, to_date))[0][0]
|
||||||
|
|
||||||
active_leads += frappe.db.sql("""select count(distinct customer) from `tabContact`
|
active_leads += frappe.db.sql("""select count(distinct contact.name) from `tabContact` contact
|
||||||
where (date(`modified`) between %s and %s)
|
left join `tabDynamic Link` dl on (dl.parent=contact.name) where dl.link_doctype='Customer'
|
||||||
and status != "Passive" """, (from_date, to_date))[0][0]
|
and (date(contact.modified) between %s and %s) and status != "Passive" """, (from_date, to_date))[0][0]
|
||||||
|
|
||||||
opportunities = frappe.db.sql("""select count(*) from `tabOpportunity`
|
opportunities = frappe.db.sql("""select count(*) from `tabOpportunity`
|
||||||
where (date(`creation`) between %s and %s)
|
where (date(`creation`) between %s and %s)
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
{
|
|
||||||
"add_total_row": 0,
|
|
||||||
"apply_user_permissions": 1,
|
|
||||||
"creation": "2012-10-04 18:45:27",
|
|
||||||
"disabled": 0,
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "Report",
|
|
||||||
"idx": 1,
|
|
||||||
"is_standard": "Yes",
|
|
||||||
"modified": "2015-08-24 11:44:00.711112",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "Selling",
|
|
||||||
"name": "Customer Addresses And Contacts",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"query": "SELECT\n\t`tabCustomer`.name as \"Customer ID:Link/Customer\",\n\t`tabCustomer`.customer_name as \"Customer Name\",\n\t`tabCustomer`.customer_group as \"Customer Group:Link/Customer Group\",\n\t`tabAddress`.address_line1 as \"Address Line 1\",\n\t`tabAddress`.address_line2 as \"Address Line 2\",\n\t`tabAddress`.city as \"City\",\n\t`tabAddress`.state as \"State\",\n\t`tabAddress`.pincode as \"Postal Code\",\n\t`tabAddress`.country as \"Country\",\n\t`tabAddress`.is_primary_address as \"Is Primary Address:Check\", \n\t`tabContact`.first_name as \"First Name\",\n\t`tabContact`.last_name as \"Last Name\",\n\t`tabContact`.phone as \"Phone\",\n\t`tabContact`.mobile_no as \"Mobile No\",\n\t`tabContact`.email_id as \"Email Address\",\n\t`tabContact`.is_primary_contact as \"Is Primary Contact:Check\"\nFROM\n\t`tabCustomer`\n\tleft join `tabAddress` on (\n\t\t`tabAddress`.customer=`tabCustomer`.name\n\t)\n\tleft join `tabContact` on (\n\t\t`tabContact`.customer=`tabCustomer`.name\n\t)\nWHERE\n\t`tabCustomer`.docstatus<2\nORDER BY\n\t`tabCustomer`.name asc",
|
|
||||||
"ref_doctype": "Customer",
|
|
||||||
"report_name": "Customer Addresses And Contacts",
|
|
||||||
"report_type": "Query Report"
|
|
||||||
}
|
|
@ -1,16 +1,18 @@
|
|||||||
{
|
{
|
||||||
|
"add_total_row": 0,
|
||||||
"apply_user_permissions": 1,
|
"apply_user_permissions": 1,
|
||||||
"creation": "2013-10-22 11:58:16",
|
"creation": "2013-10-22 11:58:16",
|
||||||
|
"disabled": 0,
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Report",
|
"doctype": "Report",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"is_standard": "Yes",
|
"is_standard": "Yes",
|
||||||
"modified": "2015-02-02 11:39:57.231750",
|
"modified": "2017-01-19 15:44:59.742195",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Selling",
|
"module": "Selling",
|
||||||
"name": "Lead Details",
|
"name": "Lead Details",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"query": "SELECT\n `tabLead`.name as \"Lead Id:Link/Lead:120\",\n `tabLead`.lead_name as \"Lead Name::120\",\n\t`tabLead`.company_name as \"Company Name::120\",\n\t`tabLead`.status as \"Status::120\",\n\tconcat_ws(', ', \n\t\ttrim(',' from `tabAddress`.address_line1), \n\t\ttrim(',' from tabAddress.address_line2)\n\t) as 'Address::180',\n\t`tabAddress`.state as \"State::100\",\n\t`tabAddress`.pincode as \"Pincode::70\",\n\t`tabAddress`.country as \"Country::100\",\n\t`tabLead`.phone as \"Phone::100\",\n\t`tabLead`.mobile_no as \"Mobile No::100\",\n\t`tabLead`.email_id as \"Email Address::120\",\n\t`tabLead`.lead_owner as \"Lead Owner::120\",\n\t`tabLead`.source as \"Source::120\",\n\t`tabLead`.territory as \"Territory::120\",\n `tabLead`.owner as \"Owner:Link/User:120\"\nFROM\n\t`tabLead`\n\tleft join `tabAddress` on (\n\t\t`tabAddress`.lead=`tabLead`.name\n\t)\nWHERE\n\t`tabLead`.docstatus<2\nORDER BY\n\t`tabLead`.name asc",
|
"query": "SELECT\n `tabLead`.name as \"Lead Id:Link/Lead:120\",\n `tabLead`.lead_name as \"Lead Name::120\",\n\t`tabLead`.company_name as \"Company Name::120\",\n\t`tabLead`.status as \"Status::120\",\n\tconcat_ws(', ', \n\t\ttrim(',' from `tabAddress`.address_line1), \n\t\ttrim(',' from tabAddress.address_line2)\n\t) as 'Address::180',\n\t`tabAddress`.state as \"State::100\",\n\t`tabAddress`.pincode as \"Pincode::70\",\n\t`tabAddress`.country as \"Country::100\",\n\t`tabLead`.phone as \"Phone::100\",\n\t`tabLead`.mobile_no as \"Mobile No::100\",\n\t`tabLead`.email_id as \"Email Id::120\",\n\t`tabLead`.lead_owner as \"Lead Owner::120\",\n\t`tabLead`.source as \"Source::120\",\n\t`tabLead`.territory as \"Territory::120\",\n `tabLead`.owner as \"Owner:Link/User:120\"\nFROM\n\t`tabLead`\n\tleft join `tabDynamic Link` on (\n\t\t`tabDynamic Link`.link_name=`tabLead`.name\n\t)\n\tleft join `tabAddress` on (\n\t\t`tabAddress`.name=`tabDynamic Link`.parent\n\t)\nWHERE\n\t`tabLead`.docstatus<2\nORDER BY\n\t`tabLead`.name asc",
|
||||||
"ref_doctype": "Lead",
|
"ref_doctype": "Lead",
|
||||||
"report_name": "Lead Details",
|
"report_name": "Lead Details",
|
||||||
"report_type": "Query Report"
|
"report_type": "Query Report"
|
||||||
|
@ -73,11 +73,23 @@ def delete_bins(company_name):
|
|||||||
|
|
||||||
def delete_lead_addresses(company_name):
|
def delete_lead_addresses(company_name):
|
||||||
"""Delete addresses to which leads are linked"""
|
"""Delete addresses to which leads are linked"""
|
||||||
for lead in frappe.get_all("Lead", filters={"company": company_name}):
|
leads = frappe.get_all("Lead", filters={"company": company_name})
|
||||||
frappe.db.sql("""delete from `tabAddress`
|
leads = [ "'%s'"%row.get("name") for row in leads ]
|
||||||
where lead=%s and (customer='' or customer is null) and (supplier='' or supplier is null)""", lead.name)
|
addresses = []
|
||||||
|
if leads:
|
||||||
|
addresses = frappe.db.sql_list("""select parent from `tabDynamic Link` where link_name
|
||||||
|
in ({leads})""".format(leads=",".join(leads)), debug=True)
|
||||||
|
addresses = ["'%s'"%addr for addr in addresses]
|
||||||
|
|
||||||
frappe.db.sql("""update `tabAddress` set lead=null, lead_name=null where lead=%s""", lead.name)
|
frappe.db.sql("""delete from tabAddress where name in ({addresses}) and
|
||||||
|
name not in (select distinct dl1.parent from `tabDynamic Link` dl1
|
||||||
|
inner join `tabDynamic Link` dl2 on dl1.parent=dl2.parent
|
||||||
|
and dl1.link_doctype<>dl2.link_doctype)""".format(addresses=",".join(addresses)), debug=True)
|
||||||
|
|
||||||
|
frappe.db.sql("""delete from `tabDynamic Link` where link_doctype='Lead' and parenttype='Address'
|
||||||
|
and link_name in ({leads})""".format(leads=",".join(leads)), debug=True)
|
||||||
|
|
||||||
|
frappe.db.sql("""update tabCustomer set lead_name=NULL where lead_name in ({leads})""".format(leads=",".join(leads)), debug=True)
|
||||||
|
|
||||||
def delete_communications(doctype, company_name, company_fieldname):
|
def delete_communications(doctype, company_name, company_fieldname):
|
||||||
frappe.db.sql("""
|
frappe.db.sql("""
|
||||||
|
@ -6,12 +6,12 @@ frappe.ui.form.on('Sales Partner', {
|
|||||||
frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Sales Person'}
|
frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Sales Person'}
|
||||||
|
|
||||||
if(frm.doc.__islocal){
|
if(frm.doc.__islocal){
|
||||||
hide_field(['address_html', 'contact_html']);
|
hide_field(['address_html', 'contact_html', 'address_contacts']);
|
||||||
erpnext.utils.clear_address_and_contact(frm);
|
frappe.geo.clear_address_and_contact(frm);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
unhide_field(['address_html', 'contact_html']);
|
unhide_field(['address_html', 'contact_html', 'address_contacts']);
|
||||||
erpnext.utils.render_address_and_contact(frm);
|
frappe.geo.render_address_and_contact(frm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -5,7 +5,7 @@ from __future__ import unicode_literals
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe.utils import cstr, filter_strip_join
|
from frappe.utils import cstr, filter_strip_join
|
||||||
from frappe.website.website_generator import WebsiteGenerator
|
from frappe.website.website_generator import WebsiteGenerator
|
||||||
from erpnext.utilities.address_and_contact import load_address_and_contact
|
from frappe.geo.address_and_contact import load_address_and_contact
|
||||||
|
|
||||||
class SalesPartner(WebsiteGenerator):
|
class SalesPartner(WebsiteGenerator):
|
||||||
website = frappe._dict(
|
website = frappe._dict(
|
||||||
@ -28,15 +28,6 @@ class SalesPartner(WebsiteGenerator):
|
|||||||
if self.partner_website and not self.partner_website.startswith("http"):
|
if self.partner_website and not self.partner_website.startswith("http"):
|
||||||
self.partner_website = "http://" + self.partner_website
|
self.partner_website = "http://" + self.partner_website
|
||||||
|
|
||||||
def get_contacts(self, nm):
|
|
||||||
if nm:
|
|
||||||
return frappe.db.convert_to_lists(frappe.db.sql("""
|
|
||||||
select name, CONCAT(IFNULL(first_name,''),
|
|
||||||
' ',IFNULL(last_name,'')),contact_no,email_id
|
|
||||||
from `tabContact` where sales_partner = %s""", nm))
|
|
||||||
else:
|
|
||||||
return ''
|
|
||||||
|
|
||||||
def get_context(self, context):
|
def get_context(self, context):
|
||||||
address = frappe.db.get_value("Address",
|
address = frappe.db.get_value("Address",
|
||||||
{"sales_partner": self.name, "is_primary_address": 1},
|
{"sales_partner": self.name, "is_primary_address": 1},
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
{% extends "templates/web.html" %}
|
|
||||||
|
|
||||||
{% block header %}
|
|
||||||
<h1> {{doc.subject}} </h1>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block page_content %}
|
|
||||||
|
|
||||||
<p class="post-description"> {{doc.description}} </p>
|
|
||||||
<p class="post-by text-muted small">
|
|
||||||
{% for file in attached_files%}
|
|
||||||
<a href="{{file.file_url}}" target="_new">{{file.file_name}}</a>
|
|
||||||
<br>
|
|
||||||
{% endfor %}
|
|
||||||
<br>
|
|
||||||
<i>{{ doc.posted_by }}</i>
|
|
||||||
<i class="blog-dot"></i> {{ frappe.format_date(doc.modified) }}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
{% endblock %}
|
|
@ -1,18 +0,0 @@
|
|||||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
|
||||||
# License: GNU General Public License v3. See license.txt
|
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
import frappe
|
|
||||||
|
|
||||||
def get_context(context):
|
|
||||||
announcement = frappe.get_doc('Announcement', frappe.form_dict.announcement)
|
|
||||||
context.no_cache = 1
|
|
||||||
context.show_sidebar = True
|
|
||||||
announcement.has_permission('read')
|
|
||||||
context.doc = announcement
|
|
||||||
attachments = frappe.db.sql("""select file_url, file_name from tabFile as file
|
|
||||||
where file.attached_to_name=%s """,(announcement.name), as_dict = True)
|
|
||||||
|
|
||||||
context.attached_files = attachments
|
|
||||||
|
|
||||||
|
|
@ -15,14 +15,6 @@ def get_context(context):
|
|||||||
course = frappe.get_doc('Course', frappe.form_dict.course)
|
course = frappe.get_doc('Course', frappe.form_dict.course)
|
||||||
course.has_permission('read')
|
course.has_permission('read')
|
||||||
context.doc = course
|
context.doc = course
|
||||||
portal_items = [{'reference_doctype': u'Topic', 'route': u"/topic?course=" + str(course.name), 'show_always': 0L, 'title': u'Topics'},
|
|
||||||
{'reference_doctype': u'Discussion', 'route': u"/discussion?course=" + str(course.name), 'show_always': 0L, 'title': u'Discussions'},
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
context.sidebar_items = portal_items
|
|
||||||
|
|
||||||
context.sidebar_title = sidebar_title
|
context.sidebar_title = sidebar_title
|
||||||
|
|
||||||
context.intro = course.course_intro
|
context.intro = course.course_intro
|
||||||
|
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
{% extends "templates/web.html" %}
|
|
||||||
|
|
||||||
{% block header %}
|
|
||||||
<h2> {{doc.subject}} </h2>
|
|
||||||
<p> {{doc.description}} </p>
|
|
||||||
<p class="text-muted small">Started by: {{doc.owner}} </p>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block page_content %}
|
|
||||||
|
|
||||||
<div>
|
|
||||||
{% include 'templates/includes/comments/comments.html' %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% endblock %}
|
|
@ -1,21 +0,0 @@
|
|||||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
|
||||||
# License: GNU General Public License v3. See license.txt
|
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
import frappe
|
|
||||||
from frappe.website.utils import get_comment_list
|
|
||||||
|
|
||||||
def get_context(context):
|
|
||||||
context.doc = frappe.get_doc('Discussion', frappe.form_dict.discussion)
|
|
||||||
portal_items = [{'reference_doctype': u'Topic', 'route': u"/topic?course=" + str(context.doc.course), 'show_always': 0L, 'title': u'Topics'},
|
|
||||||
{'reference_doctype': u'Discussion', 'route': u"/discussion?course=" + str(context.doc.course), 'show_always': 0L, 'title': u'Discussions'},
|
|
||||||
|
|
||||||
]
|
|
||||||
context.show_sidebar = True
|
|
||||||
context.sidebar_items = portal_items
|
|
||||||
context.no_cache = 1
|
|
||||||
context.doc.has_permission('read')
|
|
||||||
context.sidebar_title = context.doc.course
|
|
||||||
context.reference_doctype = "Discussion"
|
|
||||||
context.reference_name = context.doc.name
|
|
||||||
context.comment_list = get_comment_list(context.doc.doctype,context.doc.name)
|
|
@ -1,12 +0,0 @@
|
|||||||
{% extends "templates/web.html" %}
|
|
||||||
|
|
||||||
|
|
||||||
{% block header %}
|
|
||||||
<h2> {{ doc.introduction }} </h1>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block page_content %}
|
|
||||||
|
|
||||||
<p class="post-description"> {{ doc.content }} </p>
|
|
||||||
|
|
||||||
{% endblock %}
|
|
@ -1,15 +0,0 @@
|
|||||||
# License: GNU General Public License v3. See license.txt
|
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
import frappe
|
|
||||||
|
|
||||||
|
|
||||||
def get_context(context):
|
|
||||||
topic = frappe.get_doc('Topic', frappe.form_dict.topic)
|
|
||||||
context.no_cache = 1
|
|
||||||
context.show_sidebar = True
|
|
||||||
context.doc = topic
|
|
||||||
attachments = frappe.db.sql("""select file_url, file_name from tabFile as file
|
|
||||||
where file.attached_to_name=%s """,(topic.name), as_dict = True)
|
|
||||||
|
|
||||||
context.attached_files = attachments
|
|
@ -1,134 +0,0 @@
|
|||||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
|
||||||
# License: GNU General Public License v3. See license.txt
|
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
import frappe
|
|
||||||
|
|
||||||
def load_address_and_contact(doc, key):
|
|
||||||
"""Loads address list and contact list in `__onload`"""
|
|
||||||
from frappe.geo.doctype.address.address import get_address_display
|
|
||||||
|
|
||||||
address_list = [frappe.get_value('Address', a.parent, '*')
|
|
||||||
for a in frappe.get_all('Dynamic Link', fields='parent',
|
|
||||||
filters=dict(parenttype='Address', link_doctype=doc.doctype, link_name=doc.name))]
|
|
||||||
|
|
||||||
address_list = [a.update({"display": get_address_display(a)})
|
|
||||||
for a in address_list]
|
|
||||||
|
|
||||||
address_list = sorted(address_list,
|
|
||||||
lambda a, b:
|
|
||||||
(int(a.is_primary_address - b.is_primary_address)) or
|
|
||||||
(1 if a.modified - b.modified else 0))
|
|
||||||
|
|
||||||
doc.set_onload('addr_list', address_list)
|
|
||||||
|
|
||||||
if doc.doctype != "Lead":
|
|
||||||
contact_list = [frappe.get_value('Contact', a.parent, '*')
|
|
||||||
for a in frappe.get_all('Dynamic Link', fields='parent',
|
|
||||||
filters=dict(parenttype='Contact', link_doctype=doc.doctype, link_name=doc.name))]
|
|
||||||
|
|
||||||
contact_list = sorted(contact_list,
|
|
||||||
lambda a, b:
|
|
||||||
(int(a.is_primary_contact - b.is_primary_contact)) or
|
|
||||||
(1 if a.modified - b.modified else 0))
|
|
||||||
|
|
||||||
doc.set_onload('contact_list', contact_list)
|
|
||||||
|
|
||||||
def set_default_role(doc, method):
|
|
||||||
'''Set customer, supplier, student based on email'''
|
|
||||||
if frappe.flags.setting_role:
|
|
||||||
return
|
|
||||||
contact_name = frappe.get_value('Contact', dict(email_id=doc.email))
|
|
||||||
if contact_name:
|
|
||||||
contact = frappe.get_doc('Contact', contact_name)
|
|
||||||
for link in contact.links:
|
|
||||||
frappe.flags.setting_role = True
|
|
||||||
if link.link_doctype=='Customer':
|
|
||||||
doc.add_roles('Customer')
|
|
||||||
elif link.link_doctype=='Supplier':
|
|
||||||
doc.add_roles('Supplier')
|
|
||||||
elif frappe.get_value('Student', dict(student_email_id=doc.email)):
|
|
||||||
doc.add_roles('Student')
|
|
||||||
|
|
||||||
def has_permission(doc, ptype, user):
|
|
||||||
links = get_permitted_and_not_permitted_links(doc.doctype)
|
|
||||||
if not links.get("not_permitted_links"):
|
|
||||||
# optimization: don't determine permissions based on link fields
|
|
||||||
return True
|
|
||||||
|
|
||||||
# True if any one is True or all are empty
|
|
||||||
names = []
|
|
||||||
for df in (links.get("permitted_links") + links.get("not_permitted_links")):
|
|
||||||
doctype = df.options
|
|
||||||
name = doc.get(df.fieldname)
|
|
||||||
names.append(name)
|
|
||||||
|
|
||||||
if name and frappe.has_permission(doctype, ptype, doc=name):
|
|
||||||
return True
|
|
||||||
|
|
||||||
if not any(names):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def get_permission_query_conditions_for_contact(user):
|
|
||||||
return get_permission_query_conditions("Contact")
|
|
||||||
|
|
||||||
def get_permission_query_conditions_for_address(user):
|
|
||||||
return get_permission_query_conditions("Address")
|
|
||||||
|
|
||||||
def get_permission_query_conditions(doctype):
|
|
||||||
links = get_permitted_and_not_permitted_links(doctype)
|
|
||||||
|
|
||||||
if not links.get("not_permitted_links"):
|
|
||||||
# when everything is permitted, don't add additional condition
|
|
||||||
return ""
|
|
||||||
|
|
||||||
elif not links.get("permitted_links"):
|
|
||||||
conditions = []
|
|
||||||
|
|
||||||
# when everything is not permitted
|
|
||||||
for df in links.get("not_permitted_links"):
|
|
||||||
# like ifnull(customer, '')='' and ifnull(supplier, '')=''
|
|
||||||
conditions.append("ifnull(`tab{doctype}`.`{fieldname}`, '')=''".format(doctype=doctype, fieldname=df.fieldname))
|
|
||||||
|
|
||||||
return "( " + " and ".join(conditions) + " )"
|
|
||||||
|
|
||||||
else:
|
|
||||||
conditions = []
|
|
||||||
|
|
||||||
for df in links.get("permitted_links"):
|
|
||||||
# like ifnull(customer, '')!='' or ifnull(supplier, '')!=''
|
|
||||||
conditions.append("ifnull(`tab{doctype}`.`{fieldname}`, '')!=''".format(doctype=doctype, fieldname=df.fieldname))
|
|
||||||
|
|
||||||
return "( " + " or ".join(conditions) + " )"
|
|
||||||
|
|
||||||
def get_permitted_and_not_permitted_links(doctype):
|
|
||||||
permitted_links = []
|
|
||||||
not_permitted_links = []
|
|
||||||
|
|
||||||
meta = frappe.get_meta(doctype)
|
|
||||||
|
|
||||||
for df in meta.get_link_fields():
|
|
||||||
if df.options not in ("Customer", "Supplier", "Company", "Sales Partner"):
|
|
||||||
continue
|
|
||||||
|
|
||||||
if frappe.has_permission(df.options):
|
|
||||||
permitted_links.append(df)
|
|
||||||
else:
|
|
||||||
not_permitted_links.append(df)
|
|
||||||
|
|
||||||
return {
|
|
||||||
"permitted_links": permitted_links,
|
|
||||||
"not_permitted_links": not_permitted_links
|
|
||||||
}
|
|
||||||
|
|
||||||
def delete_contact_and_address(doctype, name):
|
|
||||||
for parenttype in ('Contact', 'Address'):
|
|
||||||
items = frappe.db.sql("""select parent from `tabDynamic Link`
|
|
||||||
where parenttype=%s and link_doctype=%s and link_name=%s""",
|
|
||||||
(parenttype, doctype, name))
|
|
||||||
|
|
||||||
for name in items:
|
|
||||||
doc = frappe.get_doc(parenttype, name)
|
|
||||||
if len(doc.links)==1:
|
|
||||||
doc.delete()
|
|
Loading…
Reference in New Issue
Block a user