Merge branch 'master' into edge
Conflicts: home/page/latest_updates/latest_updates.js hr/doctype/employee/employee.txt
This commit is contained in:
commit
c6aecb3f97
@ -307,10 +307,10 @@ erpnext.GeneralLedger = wn.views.GridReport.extend({
|
|||||||
|
|
||||||
make_account_by_name: function() {
|
make_account_by_name: function() {
|
||||||
this.account_by_name = this.make_name_map(wn.report_dump.data["Account"]);
|
this.account_by_name = this.make_name_map(wn.report_dump.data["Account"]);
|
||||||
this.make_voucher_acconuts_map();
|
this.make_voucher_accounts_map();
|
||||||
},
|
},
|
||||||
|
|
||||||
make_voucher_acconuts_map: function() {
|
make_voucher_accounts_map: function() {
|
||||||
this.voucher_accounts = {};
|
this.voucher_accounts = {};
|
||||||
var data = wn.report_dump.data["GL Entry"];
|
var data = wn.report_dump.data["GL Entry"];
|
||||||
for(var i=0, j=data.length; i<j; i++) {
|
for(var i=0, j=data.length; i<j; i++) {
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
erpnext.updates = [
|
erpnext.updates = [
|
||||||
["10th April", ["Redesigned File Uploads and added File Manager in Setup"]],
|
["10th April", ["Redesigned File Uploads and added File Manager in Setup"]],
|
||||||
|
["12th April", ["Employee: List of Leave Approvers who can approve the Employee's Leave Applications"]],
|
||||||
["27th March", ["Rename multiple items together. Go to Setup > Rename Tool"]],
|
["27th March", ["Rename multiple items together. Go to Setup > Rename Tool"]],
|
||||||
["26th March", ["Added project to Stock Ledger and Balance",
|
["26th March", ["Added project to Stock Ledger and Balance",
|
||||||
"Added Default Cash Account in Company."]],
|
"Added Default Cash Account in Company."]],
|
||||||
|
|||||||
@ -14,62 +14,95 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
cur_frm.cscript.onload = function(doc) {
|
wn.provide("erpnext.hr");
|
||||||
// bc
|
erpnext.hr.EmployeeController = wn.ui.form.Controller.extend({
|
||||||
var india_specific = ["esic_card_no", "gratuity_lic_id", "pan_number", "pf_number"]
|
setup: function() {
|
||||||
if(wn.control_panel.country!="India") {
|
this.setup_leave_approver_select();
|
||||||
hide_field(india_specific);
|
this.frm.fields_dict.user_id.get_query = erpnext.utils.profile_query;
|
||||||
}
|
this.frm.fields_dict.reports_to.get_query = erpnext.utils.employee_query;
|
||||||
}
|
},
|
||||||
|
|
||||||
cur_frm.cscript.refresh = function(doc) {
|
onload: function() {
|
||||||
if(!doc.__islocal) {
|
this.frm.toggle_display(["esic_card_no", "gratuity_lic_id", "pan_number", "pf_number"],
|
||||||
hide_field("naming_series");
|
wn.control_panel.country==="India");
|
||||||
cur_frm.add_custom_button('Make Salary Structure',
|
},
|
||||||
cur_frm.cscript['Make Salary Structure']);
|
|
||||||
}
|
refresh: function() {
|
||||||
}
|
var me = this;
|
||||||
|
erpnext.hide_naming_series();
|
||||||
cur_frm.cscript.date_of_birth = function(doc, dt, dn) {
|
if(!this.frm.doc.__islocal) {
|
||||||
get_server_fields('get_retirement_date','','',doc,dt,dn,1);
|
cur_frm.add_custom_button('View Active Salary Structure', function() {
|
||||||
}
|
me.view_active_salary_structure(this); });
|
||||||
|
|
||||||
cur_frm.cscript.salutation = function(doc,dt,dn) {
|
cur_frm.add_custom_button('Make Salary Structure', function() {
|
||||||
if(doc.salutation){
|
me.make_salary_structure(this); });
|
||||||
if(doc.salutation=='Mr')
|
|
||||||
doc.gender='Male';
|
|
||||||
else if(doc.salutation=='Ms')
|
|
||||||
doc.gender='Female';
|
|
||||||
refresh_field('gender');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cur_frm.cscript['Make Salary Structure']=function(){
|
|
||||||
$c_obj(make_doclist (cur_frm.doc.doctype, cur_frm.doc.name), 'check_sal_structure',
|
|
||||||
cur_frm.doc.name, function(r, rt) {
|
|
||||||
if(r.message)
|
|
||||||
msgprint("You have already created Active salary structure.\n \
|
|
||||||
If you want to create new one, please ensure that no active salary structure \
|
|
||||||
exist.\nTo inactive salary structure select 'Is Active' as 'No'.");
|
|
||||||
else
|
|
||||||
cur_frm.cscript.make_salary_structure(cur_frm.doc);
|
|
||||||
}
|
}
|
||||||
);
|
},
|
||||||
}
|
|
||||||
|
setup_leave_approver_select: function() {
|
||||||
cur_frm.cscript.make_salary_structure = function(doc, dt, dn, det){
|
var me = this;
|
||||||
var st = wn.model.make_new_doc_and_get_name('Salary Structure');
|
this.frm.call({
|
||||||
st = locals['Salary Structure'][st];
|
method:"hr.utils.get_leave_approver_list",
|
||||||
st.employee = doc.name;
|
callback: function(r) {
|
||||||
st.employee_name = doc.employee_name;
|
me.frm.fields_dict.employee_leave_approvers.grid.get_field("leave_approver").df.options =
|
||||||
st.branch=doc.branch;
|
$.map(r.message, function(profile) {
|
||||||
st.designation=doc.designation;
|
return {value: profile, label: wn.user_info(profile).fullname};
|
||||||
st.department=doc.department;
|
});
|
||||||
st.fiscal_year = doc.fiscal_year
|
}
|
||||||
st.grade=doc.grade;
|
});
|
||||||
loaddoc('Salary Structure', st.name);
|
},
|
||||||
}
|
|
||||||
|
date_of_birth: function() {
|
||||||
cur_frm.fields_dict.user_id.get_query = erpnext.utils.profile_query;
|
cur_frm.call({
|
||||||
|
method: "get_retirement_date",
|
||||||
cur_frm.fields_dict.reports_to.get_query = erpnext.utils.employee_query;
|
args: {date_of_birth: this.frm.doc.date_of_birth}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
salutation: function() {
|
||||||
|
if(this.frm.doc.salutation) {
|
||||||
|
this.frm.set_value("gender", {
|
||||||
|
"Mr": "Male",
|
||||||
|
"Ms": "Female"
|
||||||
|
}[this.frm.doc.salutation]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
make_salary_structure: function(btn) {
|
||||||
|
var me = this;
|
||||||
|
this.validate_salary_structure(btn, function(r) {
|
||||||
|
if(r.message) {
|
||||||
|
msgprint(wn._("Employee") + ' "' + me.frm.doc.name + '": '
|
||||||
|
+ wn._("An active Salary Structure already exists. \
|
||||||
|
If you want to create new one, please ensure that no active Salary Structure \
|
||||||
|
exists for this Employee. Go to the active Salary Structure and set \
|
||||||
|
\"Is Active\" = \"No\""));
|
||||||
|
} else if(!r.exc) {
|
||||||
|
wn.model.map({
|
||||||
|
source: wn.model.get_doclist(me.frm.doc.doctype, me.frm.doc.name),
|
||||||
|
target: "Salary Structure"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
validate_salary_structure: function(btn, callback) {
|
||||||
|
var me = this;
|
||||||
|
this.frm.call({
|
||||||
|
btn: btn,
|
||||||
|
method: "webnotes.client.get_value",
|
||||||
|
args: {
|
||||||
|
doctype: "Salary Structure",
|
||||||
|
fieldname: "name",
|
||||||
|
filters: {
|
||||||
|
employee: me.frm.doc.name,
|
||||||
|
is_active: "Yes",
|
||||||
|
docstatus: ["!=", 2]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
callback: callback
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
cur_frm.cscript = new erpnext.hr.EmployeeController({frm: cur_frm});
|
||||||
@ -27,7 +27,7 @@ class DocType:
|
|||||||
def __init__(self,doc,doclist=[]):
|
def __init__(self,doc,doclist=[]):
|
||||||
self.doc = doc
|
self.doc = doc
|
||||||
self.doclist = doclist
|
self.doclist = doclist
|
||||||
|
|
||||||
def autoname(self):
|
def autoname(self):
|
||||||
ret = sql("select value from `tabSingles` where doctype = 'Global Defaults' and field = 'emp_created_by'")
|
ret = sql("select value from `tabSingles` where doctype = 'Global Defaults' and field = 'emp_created_by'")
|
||||||
if not ret:
|
if not ret:
|
||||||
@ -49,30 +49,31 @@ class DocType:
|
|||||||
self.validate_email()
|
self.validate_email()
|
||||||
self.validate_name()
|
self.validate_name()
|
||||||
self.validate_status()
|
self.validate_status()
|
||||||
|
self.validate_employee_leave_approver()
|
||||||
def get_retirement_date(self):
|
|
||||||
import datetime
|
|
||||||
ret = {}
|
|
||||||
if self.doc.date_of_birth:
|
|
||||||
dt = getdate(self.doc.date_of_birth) + datetime.timedelta(21915)
|
|
||||||
ret = {'date_of_retirement': dt.strftime('%Y-%m-%d')}
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def check_sal_structure(self, nm):
|
|
||||||
ret_sal_struct=sql("select name from `tabSalary Structure` where employee='%s' and is_active = 'Yes' and docstatus!= 2"%nm)
|
|
||||||
return ret_sal_struct and ret_sal_struct[0][0] or ''
|
|
||||||
|
|
||||||
def on_update(self):
|
def on_update(self):
|
||||||
if self.doc.user_id:
|
if self.doc.user_id:
|
||||||
self.update_user_default()
|
self.update_user_default()
|
||||||
self.update_profile()
|
self.update_profile()
|
||||||
|
|
||||||
def update_user_default(self):
|
def update_user_default(self):
|
||||||
webnotes.conn.set_default("employee", self.doc.name, self.doc.user_id)
|
webnotes.conn.set_default("employee", self.doc.name, self.doc.user_id)
|
||||||
webnotes.conn.set_default("employee_name", self.doc.employee_name, self.doc.user_id)
|
webnotes.conn.set_default("employee_name", self.doc.employee_name, self.doc.user_id)
|
||||||
webnotes.conn.set_default("company", self.doc.company, self.doc.user_id)
|
webnotes.conn.set_default("company", self.doc.company, self.doc.user_id)
|
||||||
if self.doc.reports_to:
|
self.set_default_leave_approver()
|
||||||
webnotes.conn.set_default("leave_approver", webnotes.conn.get_value("Employee", self.doc.reports_to, "user_id"), self.doc.user_id)
|
|
||||||
|
def set_default_leave_approver(self):
|
||||||
|
employee_leave_approvers = self.doclist.get({"parentfield": "employee_leave_approvers"})
|
||||||
|
|
||||||
|
if len(employee_leave_approvers):
|
||||||
|
webnotes.conn.set_default("leave_approver", employee_leave_approvers[0].leave_approver,
|
||||||
|
self.doc.user_id)
|
||||||
|
|
||||||
|
elif self.doc.reports_to:
|
||||||
|
from webnotes.profile import Profile
|
||||||
|
reports_to_user = webnotes.conn.get_value("Employee", self.doc.reports_to, "user_id")
|
||||||
|
if "Leave Approver" in Profile(reports_to_user).get_roles():
|
||||||
|
webnotes.conn.set_default("leave_approver", reports_to_user, self.doc.user_id)
|
||||||
|
|
||||||
def update_profile(self):
|
def update_profile(self):
|
||||||
# add employee role if missing
|
# add employee role if missing
|
||||||
@ -118,7 +119,6 @@ class DocType:
|
|||||||
profile_wrapper.save()
|
profile_wrapper.save()
|
||||||
|
|
||||||
def validate_date(self):
|
def validate_date(self):
|
||||||
import datetime
|
|
||||||
if self.doc.date_of_birth and self.doc.date_of_joining and getdate(self.doc.date_of_birth) >= getdate(self.doc.date_of_joining):
|
if self.doc.date_of_birth and self.doc.date_of_joining and getdate(self.doc.date_of_birth) >= getdate(self.doc.date_of_joining):
|
||||||
msgprint('Date of Joining must be greater than Date of Birth')
|
msgprint('Date of Joining must be greater than Date of Birth')
|
||||||
raise Exception
|
raise Exception
|
||||||
@ -169,3 +169,21 @@ class DocType:
|
|||||||
if self.doc.status == 'Left' and not self.doc.relieving_date:
|
if self.doc.status == 'Left' and not self.doc.relieving_date:
|
||||||
msgprint("Please enter relieving date.")
|
msgprint("Please enter relieving date.")
|
||||||
raise Exception
|
raise Exception
|
||||||
|
|
||||||
|
def validate_employee_leave_approver(self):
|
||||||
|
from webnotes.profile import Profile
|
||||||
|
from hr.doctype.leave_application.leave_application import InvalidLeaveApproverError
|
||||||
|
|
||||||
|
for l in self.doclist.get({"parentfield": "employee_leave_approvers"}):
|
||||||
|
if "Leave Approver" not in Profile(l.leave_approver).get_roles():
|
||||||
|
msgprint(_("Invalid Leave Approver") + ": \"" + l.leave_approver + "\"",
|
||||||
|
raise_exception=InvalidLeaveApproverError)
|
||||||
|
|
||||||
|
@webnotes.whitelist()
|
||||||
|
def get_retirement_date(date_of_birth=None):
|
||||||
|
import datetime
|
||||||
|
ret = {}
|
||||||
|
if date_of_birth:
|
||||||
|
dt = getdate(date_of_birth) + datetime.timedelta(21915)
|
||||||
|
ret = {'date_of_retirement': dt.strftime('%Y-%m-%d')}
|
||||||
|
return ret
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"creation": "2013-03-07 14:48:31",
|
"creation": "2013-03-07 09:04:18",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-02-08 13:07:25",
|
"modified": "2013-04-12 07:16:42",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -320,15 +320,6 @@
|
|||||||
"options": "Grade",
|
"options": "Grade",
|
||||||
"reqd": 0
|
"reqd": 0
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"doctype": "DocField",
|
|
||||||
"fieldname": "reports_to",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"label": "Reports to",
|
|
||||||
"oldfieldname": "reports_to",
|
|
||||||
"oldfieldtype": "Link",
|
|
||||||
"options": "Employee"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"description": "Provide email id registered in company",
|
"description": "Provide email id registered in company",
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
@ -340,6 +331,14 @@
|
|||||||
"oldfieldtype": "Data",
|
"oldfieldtype": "Data",
|
||||||
"reqd": 0
|
"reqd": 0
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"doctype": "DocField",
|
||||||
|
"fieldname": "notice_number_of_days",
|
||||||
|
"fieldtype": "Int",
|
||||||
|
"label": "Notice - Number of Days",
|
||||||
|
"oldfieldname": "notice_number_of_days",
|
||||||
|
"oldfieldtype": "Int"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "salary_information",
|
"fieldname": "salary_information",
|
||||||
@ -403,6 +402,29 @@
|
|||||||
"oldfieldname": "gratuity_lic_id",
|
"oldfieldname": "gratuity_lic_id",
|
||||||
"oldfieldtype": "Data"
|
"oldfieldtype": "Data"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"doctype": "DocField",
|
||||||
|
"fieldname": "organization_profile",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Organization Profile"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "DocField",
|
||||||
|
"fieldname": "reports_to",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Reports to",
|
||||||
|
"oldfieldname": "reports_to",
|
||||||
|
"oldfieldtype": "Link",
|
||||||
|
"options": "Employee"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "The first Leave Approver in the list will be set as the default Leave Approver",
|
||||||
|
"doctype": "DocField",
|
||||||
|
"fieldname": "employee_leave_approvers",
|
||||||
|
"fieldtype": "Table",
|
||||||
|
"label": "Leave Approvers",
|
||||||
|
"options": "Employee Leave Approver"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "contact_details",
|
"fieldname": "contact_details",
|
||||||
@ -427,14 +449,6 @@
|
|||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Personal Email"
|
"label": "Personal Email"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"doctype": "DocField",
|
|
||||||
"fieldname": "notice_number_of_days",
|
|
||||||
"fieldtype": "Int",
|
|
||||||
"label": "Notice - Number of Days",
|
|
||||||
"oldfieldname": "notice_number_of_days",
|
|
||||||
"oldfieldtype": "Int"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "emergency_contact_details",
|
"fieldname": "emergency_contact_details",
|
||||||
|
|||||||
0
hr/doctype/employee_leave_approver/__init__.py
Normal file
0
hr/doctype/employee_leave_approver/__init__.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import webnotes
|
||||||
|
|
||||||
|
class DocType:
|
||||||
|
def __init__(self, d, dl):
|
||||||
|
self.doc, self.doclist = d, dl
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"creation": "2013-04-12 06:56:15",
|
||||||
|
"docstatus": 0,
|
||||||
|
"modified": "2013-04-12 07:53:33",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"owner": "Administrator"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_import": 0,
|
||||||
|
"autoname": "LAPPR-/.#####",
|
||||||
|
"description": "Users who can approve a specific employee's leave applications",
|
||||||
|
"doctype": "DocType",
|
||||||
|
"istable": 1,
|
||||||
|
"module": "HR",
|
||||||
|
"name": "__common__"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "DocField",
|
||||||
|
"fieldname": "leave_approver",
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"label": "Leave Approver",
|
||||||
|
"name": "__common__",
|
||||||
|
"parent": "Employee Leave Approver",
|
||||||
|
"parentfield": "fields",
|
||||||
|
"parenttype": "DocType",
|
||||||
|
"permlevel": 0,
|
||||||
|
"print_hide": 1,
|
||||||
|
"reqd": 1,
|
||||||
|
"width": "200"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "DocType",
|
||||||
|
"name": "Employee Leave Approver"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "DocField"
|
||||||
|
}
|
||||||
|
]
|
||||||
@ -29,7 +29,7 @@ cur_frm.cscript.onload = function(doc,cdt,cdn){
|
|||||||
}
|
}
|
||||||
|
|
||||||
cur_frm.call({
|
cur_frm.call({
|
||||||
method:"get_approver_list",
|
method:"hr.utils.get_expense_approver_list",
|
||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
cur_frm.set_df_property("exp_approver", "options", r.message);
|
cur_frm.set_df_property("exp_approver", "options", r.message);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -52,12 +52,3 @@ class DocType:
|
|||||||
if not getlist(self.doclist, 'expense_voucher_details'):
|
if not getlist(self.doclist, 'expense_voucher_details'):
|
||||||
msgprint("Please add expense voucher details")
|
msgprint("Please add expense voucher details")
|
||||||
raise Exception
|
raise Exception
|
||||||
|
|
||||||
@webnotes.whitelist()
|
|
||||||
def get_approver_list():
|
|
||||||
roles = [r[0] for r in webnotes.conn.sql("""select distinct parent from `tabUserRole`
|
|
||||||
where role='Expense Approver'""")]
|
|
||||||
if not roles:
|
|
||||||
webnotes.msgprint("No Expense Approvers. Please assign 'Expense Approver' \
|
|
||||||
Role to atleast one user.")
|
|
||||||
return roles
|
|
||||||
|
|||||||
@ -26,7 +26,7 @@ cur_frm.cscript.onload = function(doc, dt, dn) {
|
|||||||
}
|
}
|
||||||
cur_frm.set_df_property("leave_approver", "options", "");
|
cur_frm.set_df_property("leave_approver", "options", "");
|
||||||
cur_frm.call({
|
cur_frm.call({
|
||||||
method:"get_approver_list",
|
method:"hr.utils.get_leave_approver_list",
|
||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
cur_frm.set_df_property("leave_approver", "options", $.map(r.message,
|
cur_frm.set_df_property("leave_approver", "options", $.map(r.message,
|
||||||
function(profile) {
|
function(profile) {
|
||||||
|
|||||||
@ -18,11 +18,13 @@ from __future__ import unicode_literals
|
|||||||
import webnotes
|
import webnotes
|
||||||
from webnotes import _
|
from webnotes import _
|
||||||
|
|
||||||
from webnotes.utils import cint, cstr, date_diff, flt, formatdate, getdate, get_url_to_form
|
from webnotes.utils import cint, cstr, date_diff, flt, formatdate, getdate, get_url_to_form, \
|
||||||
|
comma_or, get_fullname
|
||||||
from webnotes import msgprint
|
from webnotes import msgprint
|
||||||
|
|
||||||
class LeaveDayBlockedError(Exception): pass
|
class LeaveDayBlockedError(webnotes.ValidationError): pass
|
||||||
class OverlapError(Exception): pass
|
class OverlapError(webnotes.ValidationError): pass
|
||||||
|
class InvalidLeaveApproverError(webnotes.ValidationError): pass
|
||||||
|
|
||||||
from webnotes.model.controller import DocListController
|
from webnotes.model.controller import DocListController
|
||||||
class DocType(DocListController):
|
class DocType(DocListController):
|
||||||
@ -39,6 +41,7 @@ class DocType(DocListController):
|
|||||||
self.validate_max_days()
|
self.validate_max_days()
|
||||||
self.show_block_day_warning()
|
self.show_block_day_warning()
|
||||||
self.validate_block_days()
|
self.validate_block_days()
|
||||||
|
self.validate_leave_approver()
|
||||||
|
|
||||||
def on_update(self):
|
def on_update(self):
|
||||||
if (not self.previous_doc and self.doc.leave_approver) or (self.previous_doc and \
|
if (not self.previous_doc and self.doc.leave_approver) or (self.previous_doc and \
|
||||||
@ -156,6 +159,21 @@ class DocType(DocListController):
|
|||||||
msgprint("Sorry ! You cannot apply for %s for more than %s days" % (self.doc.leave_type, max_days))
|
msgprint("Sorry ! You cannot apply for %s for more than %s days" % (self.doc.leave_type, max_days))
|
||||||
raise Exception
|
raise Exception
|
||||||
|
|
||||||
|
def validate_leave_approver(self):
|
||||||
|
employee = webnotes.bean("Employee", self.doc.employee)
|
||||||
|
leave_approvers = [l.leave_approver for l in
|
||||||
|
employee.doclist.get({"parentfield": "employee_leave_approvers"})]
|
||||||
|
|
||||||
|
if len(leave_approvers) and self.doc.leave_approver not in leave_approvers:
|
||||||
|
msgprint(("[" + _("For Employee") + ' "' + self.doc.employee + '"] '
|
||||||
|
+ _("Leave Approver can be one of") + ": "
|
||||||
|
+ comma_or(leave_approvers)), raise_exception=InvalidLeaveApproverError)
|
||||||
|
|
||||||
|
elif self.doc.leave_approver and not webnotes.conn.sql("""select name from `tabUserRole`
|
||||||
|
where parent=%s and role='Leave Approver'""", self.doc.leave_approver):
|
||||||
|
msgprint(get_fullname(self.doc.leave_approver) + ": " \
|
||||||
|
+ _("does not have role 'Leave Approver'"), raise_exception=InvalidLeaveApproverError)
|
||||||
|
|
||||||
def notify_employee(self, status):
|
def notify_employee(self, status):
|
||||||
employee = webnotes.doc("Employee", self.doc.employee)
|
employee = webnotes.doc("Employee", self.doc.employee)
|
||||||
if not employee.user_id:
|
if not employee.user_id:
|
||||||
@ -221,15 +239,6 @@ def get_leave_balance(employee, leave_type, fiscal_year):
|
|||||||
ret = {'leave_balance': leave_all - leave_app}
|
ret = {'leave_balance': leave_all - leave_app}
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@webnotes.whitelist()
|
|
||||||
def get_approver_list():
|
|
||||||
roles = [r[0] for r in webnotes.conn.sql("""select distinct parent from `tabUserRole`
|
|
||||||
where role='Leave Approver'""")]
|
|
||||||
if not roles:
|
|
||||||
webnotes.msgprint("No Leave Approvers. Please assign 'Leave Approver' Role to atleast one user.")
|
|
||||||
|
|
||||||
return roles
|
|
||||||
|
|
||||||
def is_lwp(leave_type):
|
def is_lwp(leave_type):
|
||||||
lwp = webnotes.conn.sql("select is_lwp from `tabLeave Type` where name = %s", leave_type)
|
lwp = webnotes.conn.sql("select is_lwp from `tabLeave Type` where name = %s", leave_type)
|
||||||
return lwp and cint(lwp[0][0]) or 0
|
return lwp and cint(lwp[0][0]) or 0
|
||||||
|
|||||||
@ -4,6 +4,23 @@ import unittest
|
|||||||
from hr.doctype.leave_application.leave_application import LeaveDayBlockedError, OverlapError
|
from hr.doctype.leave_application.leave_application import LeaveDayBlockedError, OverlapError
|
||||||
|
|
||||||
class TestLeaveApplication(unittest.TestCase):
|
class TestLeaveApplication(unittest.TestCase):
|
||||||
|
def _clear_roles(self):
|
||||||
|
webnotes.conn.sql("""delete from `tabUserRole` where parent in
|
||||||
|
("test@example.com", "test1@example.com", "test2@example.com")""")
|
||||||
|
|
||||||
|
def _clear_applications(self):
|
||||||
|
webnotes.conn.sql("""delete from `tabLeave Application`""")
|
||||||
|
|
||||||
|
def _add_employee_leave_approver(self, employee, leave_approver):
|
||||||
|
webnotes.session.user = "Administrator"
|
||||||
|
employee = webnotes.bean("Employee", employee)
|
||||||
|
employee.doclist.append({
|
||||||
|
"doctype": "Employee Leave Approver",
|
||||||
|
"parentfield": "employee_leave_approvers",
|
||||||
|
"leave_approver": leave_approver
|
||||||
|
})
|
||||||
|
employee.save()
|
||||||
|
|
||||||
def get_application(self, doclist):
|
def get_application(self, doclist):
|
||||||
application = webnotes.bean(copy=doclist)
|
application = webnotes.bean(copy=doclist)
|
||||||
application.doc.from_date = "2013-01-01"
|
application.doc.from_date = "2013-01-01"
|
||||||
@ -11,8 +28,14 @@ class TestLeaveApplication(unittest.TestCase):
|
|||||||
return application
|
return application
|
||||||
|
|
||||||
def test_block_list(self):
|
def test_block_list(self):
|
||||||
import webnotes
|
webnotes.session.user = "Administrator"
|
||||||
webnotes.conn.set_value("Department", "_Test Department", "leave_block_list", "_Test Leave Block List")
|
self._clear_roles()
|
||||||
|
|
||||||
|
from webnotes.profile import add_role
|
||||||
|
add_role("test1@example.com", "HR User")
|
||||||
|
|
||||||
|
webnotes.conn.set_value("Department", "_Test Department",
|
||||||
|
"leave_block_list", "_Test Leave Block List")
|
||||||
|
|
||||||
application = self.get_application(test_records[1])
|
application = self.get_application(test_records[1])
|
||||||
application.insert()
|
application.insert()
|
||||||
@ -20,9 +43,6 @@ class TestLeaveApplication(unittest.TestCase):
|
|||||||
self.assertRaises(LeaveDayBlockedError, application.submit)
|
self.assertRaises(LeaveDayBlockedError, application.submit)
|
||||||
|
|
||||||
webnotes.session.user = "test1@example.com"
|
webnotes.session.user = "test1@example.com"
|
||||||
|
|
||||||
from webnotes.profile import add_role
|
|
||||||
add_role("test1@example.com", "HR User")
|
|
||||||
|
|
||||||
# clear other applications
|
# clear other applications
|
||||||
webnotes.conn.sql("delete from `tabLeave Application`")
|
webnotes.conn.sql("delete from `tabLeave Application`")
|
||||||
@ -31,11 +51,31 @@ class TestLeaveApplication(unittest.TestCase):
|
|||||||
self.assertTrue(application.insert())
|
self.assertTrue(application.insert())
|
||||||
|
|
||||||
def test_overlap(self):
|
def test_overlap(self):
|
||||||
|
webnotes.session.user = "Administrator"
|
||||||
|
self._clear_roles()
|
||||||
|
self._clear_applications()
|
||||||
|
|
||||||
|
from webnotes.profile import add_role
|
||||||
|
add_role("test@example.com", "Employee")
|
||||||
|
add_role("test2@example.com", "Leave Approver")
|
||||||
|
|
||||||
|
webnotes.session.user = "test@example.com"
|
||||||
application = self.get_application(test_records[1])
|
application = self.get_application(test_records[1])
|
||||||
|
application.doc.leave_approver = "test2@example.com"
|
||||||
|
application.insert()
|
||||||
|
|
||||||
|
application = self.get_application(test_records[1])
|
||||||
|
application.doc.leave_approver = "test2@example.com"
|
||||||
self.assertRaises(OverlapError, application.insert)
|
self.assertRaises(OverlapError, application.insert)
|
||||||
|
|
||||||
def test_global_block_list(self):
|
def test_global_block_list(self):
|
||||||
|
webnotes.session.user = "Administrator"
|
||||||
|
self._clear_roles()
|
||||||
|
|
||||||
|
from webnotes.profile import add_role
|
||||||
|
add_role("test1@example.com", "Employee")
|
||||||
|
add_role("test@example.com", "Leave Approver")
|
||||||
|
|
||||||
application = self.get_application(test_records[3])
|
application = self.get_application(test_records[3])
|
||||||
application.doc.leave_approver = "test@example.com"
|
application.doc.leave_approver = "test@example.com"
|
||||||
|
|
||||||
@ -44,19 +84,120 @@ class TestLeaveApplication(unittest.TestCase):
|
|||||||
webnotes.conn.set_value("Employee", "_T-Employee-0002", "department",
|
webnotes.conn.set_value("Employee", "_T-Employee-0002", "department",
|
||||||
"_Test Department")
|
"_Test Department")
|
||||||
|
|
||||||
webnotes.session.user = "test2@example.com"
|
webnotes.session.user = "test1@example.com"
|
||||||
from webnotes.profile import add_role
|
|
||||||
add_role("test2@example.com", "Employee")
|
|
||||||
|
|
||||||
application.insert()
|
application.insert()
|
||||||
|
|
||||||
webnotes.session.user = "test@example.com"
|
webnotes.session.user = "test@example.com"
|
||||||
from webnotes.profile import add_role
|
|
||||||
add_role("test@example.com", "Leave Approver")
|
|
||||||
|
|
||||||
application.doc.status = "Approved"
|
application.doc.status = "Approved"
|
||||||
self.assertRaises(LeaveDayBlockedError, application.submit)
|
self.assertRaises(LeaveDayBlockedError, application.submit)
|
||||||
|
|
||||||
|
webnotes.conn.set_value("Leave Block List", "_Test Leave Block List",
|
||||||
|
"applies_to_all_departments", 0)
|
||||||
|
|
||||||
|
def test_leave_approval(self):
|
||||||
|
webnotes.session.user = "Administrator"
|
||||||
|
self._clear_roles()
|
||||||
|
|
||||||
|
from webnotes.profile import add_role
|
||||||
|
add_role("test@example.com", "Employee")
|
||||||
|
add_role("test1@example.com", "Leave Approver")
|
||||||
|
add_role("test2@example.com", "Leave Approver")
|
||||||
|
|
||||||
|
self._test_leave_approval_basic_case_1()
|
||||||
|
self._test_leave_approval_basic_case_2()
|
||||||
|
self._test_leave_approval_invalid_leave_approver_insert()
|
||||||
|
self._test_leave_approval_invalid_leave_approver_submit()
|
||||||
|
self._test_leave_approval_valid_leave_approver_insert()
|
||||||
|
|
||||||
|
def _test_leave_approval_basic_case_1(self):
|
||||||
|
self._clear_applications()
|
||||||
|
|
||||||
|
# create leave application as Employee
|
||||||
|
webnotes.session.user = "test@example.com"
|
||||||
|
application = self.get_application(test_records[1])
|
||||||
|
application.doc.leave_approver = "test1@example.com"
|
||||||
|
application.insert()
|
||||||
|
|
||||||
|
# submit leave application by Leave Approver
|
||||||
|
webnotes.session.user = "test1@example.com"
|
||||||
|
application.doc.status = "Approved"
|
||||||
|
application.submit()
|
||||||
|
self.assertEqual(webnotes.conn.get_value("Leave Application", application.doc.name,
|
||||||
|
"docstatus"), 1)
|
||||||
|
|
||||||
|
def _test_leave_approval_basic_case_2(self):
|
||||||
|
self._clear_applications()
|
||||||
|
|
||||||
|
# create leave application by any leave approver,
|
||||||
|
# when no leave approver specified in employee's leave approvers list
|
||||||
|
application = self.get_application(test_records[1])
|
||||||
|
application.doc.leave_approver = "test1@example.com"
|
||||||
|
application.insert()
|
||||||
|
application.doc.status = "Approved"
|
||||||
|
application.submit()
|
||||||
|
self.assertEqual(webnotes.conn.get_value("Leave Application", application.doc.name,
|
||||||
|
"docstatus"), 1)
|
||||||
|
|
||||||
|
def _test_leave_approval_invalid_leave_approver_insert(self):
|
||||||
|
from hr.doctype.leave_application.leave_application import InvalidLeaveApproverError
|
||||||
|
|
||||||
|
self._clear_applications()
|
||||||
|
|
||||||
|
# add a different leave approver in the employee's list
|
||||||
|
# should raise exception if not a valid leave approver
|
||||||
|
self._add_employee_leave_approver("_T-Employee-0001", "test2@example.com")
|
||||||
|
|
||||||
|
# TODO - add test2@example.com leave approver in employee's leave approvers list
|
||||||
|
application = self.get_application(test_records[1])
|
||||||
|
webnotes.session.user = "test@example.com"
|
||||||
|
|
||||||
|
application.doc.leave_approver = "test1@example.com"
|
||||||
|
self.assertRaises(InvalidLeaveApproverError, application.insert)
|
||||||
|
|
||||||
|
webnotes.conn.sql("""delete from `tabEmployee Leave Approver` where parent=%s""",
|
||||||
|
"_T-Employee-0001")
|
||||||
|
|
||||||
|
def _test_leave_approval_invalid_leave_approver_submit(self):
|
||||||
|
self._clear_applications()
|
||||||
|
self._add_employee_leave_approver("_T-Employee-0001", "test2@example.com")
|
||||||
|
|
||||||
|
# create leave application as employee
|
||||||
|
# but submit as invalid leave approver - should raise exception
|
||||||
|
webnotes.session.user = "test@example.com"
|
||||||
|
application = self.get_application(test_records[1])
|
||||||
|
application.doc.leave_approver = "test2@example.com"
|
||||||
|
application.insert()
|
||||||
|
webnotes.session.user = "test1@example.com"
|
||||||
|
application.doc.status = "Approved"
|
||||||
|
|
||||||
|
from webnotes.model.bean import BeanPermissionError
|
||||||
|
self.assertRaises(BeanPermissionError, application.submit)
|
||||||
|
|
||||||
|
webnotes.conn.sql("""delete from `tabEmployee Leave Approver` where parent=%s""",
|
||||||
|
"_T-Employee-0001")
|
||||||
|
|
||||||
|
def _test_leave_approval_valid_leave_approver_insert(self):
|
||||||
|
self._clear_applications()
|
||||||
|
self._add_employee_leave_approver("_T-Employee-0001", "test2@example.com")
|
||||||
|
|
||||||
|
original_department = webnotes.conn.get_value("Employee", "_T-Employee-0001", "department")
|
||||||
|
webnotes.conn.set_value("Employee", "_T-Employee-0001", "department", None)
|
||||||
|
|
||||||
|
# change to valid leave approver and try to create and submit leave application
|
||||||
|
webnotes.session.user = "test2@example.com"
|
||||||
|
application = self.get_application(test_records[1])
|
||||||
|
application.doc.leave_approver = "test2@example.com"
|
||||||
|
application.insert()
|
||||||
|
application.doc.status = "Approved"
|
||||||
|
application.submit()
|
||||||
|
self.assertEqual(webnotes.conn.get_value("Leave Application", application.doc.name,
|
||||||
|
"docstatus"), 1)
|
||||||
|
|
||||||
|
webnotes.conn.sql("""delete from `tabEmployee Leave Approver` where parent=%s""",
|
||||||
|
"_T-Employee-0001")
|
||||||
|
|
||||||
|
webnotes.conn.set_value("Employee", "_T-Employee-0001", "department", original_department)
|
||||||
|
|
||||||
test_dependencies = ["Leave Block List"]
|
test_dependencies = ["Leave Block List"]
|
||||||
|
|
||||||
test_records = [
|
test_records = [
|
||||||
|
|||||||
38
hr/utils.py
Normal file
38
hr/utils.py
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
# ERPNext - web based ERP (http://erpnext.com)
|
||||||
|
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import webnotes
|
||||||
|
from webnotes import _
|
||||||
|
|
||||||
|
@webnotes.whitelist()
|
||||||
|
def get_leave_approver_list():
|
||||||
|
roles = [r[0] for r in webnotes.conn.sql("""select distinct parent from `tabUserRole`
|
||||||
|
where role='Leave Approver'""")]
|
||||||
|
if not roles:
|
||||||
|
webnotes.msgprint(_("No Leave Approvers. Please assign 'Leave Approver' Role to atleast one user."))
|
||||||
|
|
||||||
|
return roles
|
||||||
|
|
||||||
|
|
||||||
|
@webnotes.whitelist()
|
||||||
|
def get_expense_approver_list():
|
||||||
|
roles = [r[0] for r in webnotes.conn.sql("""select distinct parent from `tabUserRole`
|
||||||
|
where role='Expense Approver'""")]
|
||||||
|
if not roles:
|
||||||
|
webnotes.msgprint("No Expense Approvers. Please assign 'Expense Approver' \
|
||||||
|
Role to atleast one user.")
|
||||||
|
return roles
|
||||||
@ -244,4 +244,5 @@ patch_list = [
|
|||||||
"patches.april_2013.p05_update_file_data",
|
"patches.april_2013.p05_update_file_data",
|
||||||
"patches.april_2013.p06_update_file_size",
|
"patches.april_2013.p06_update_file_size",
|
||||||
"patches.april_2013.p05_fixes_in_reverse_modules",
|
"patches.april_2013.p05_fixes_in_reverse_modules",
|
||||||
|
"execute:webnotes.reload_doc('stock', 'DocType Mapper', 'Delivery Note-Packing Slip')"
|
||||||
]
|
]
|
||||||
@ -136,10 +136,7 @@ erpnext.startup.set_periodic_updates = function() {
|
|||||||
|
|
||||||
erpnext.hide_naming_series = function() {
|
erpnext.hide_naming_series = function() {
|
||||||
if(cur_frm.fields_dict.naming_series) {
|
if(cur_frm.fields_dict.naming_series) {
|
||||||
hide_field('naming_series');
|
cur_frm.toggle_display("naming_series", cur_frm.doc.__islocal?true:false);
|
||||||
if(cur_frm.doc.__islocal) {
|
|
||||||
unhide_field('naming_series');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -125,8 +125,7 @@ class DocType(TransactionBase):
|
|||||||
def get_item_details(self, args, obj):
|
def get_item_details(self, args, obj):
|
||||||
import json
|
import json
|
||||||
if not obj.doc.price_list_name:
|
if not obj.doc.price_list_name:
|
||||||
msgprint("Please Select Price List before selecting Items")
|
msgprint("Please Select Price List before selecting Items", raise_exception=True)
|
||||||
raise Exception
|
|
||||||
item = webnotes.conn.sql("""select description, item_name, brand, item_group, stock_uom,
|
item = webnotes.conn.sql("""select description, item_name, brand, item_group, stock_uom,
|
||||||
default_warehouse, default_income_account, default_sales_cost_center,
|
default_warehouse, default_income_account, default_sales_cost_center,
|
||||||
purchase_account, description_html, barcode from `tabItem`
|
purchase_account, description_html, barcode from `tabItem`
|
||||||
|
|||||||
@ -39,10 +39,7 @@ report.get_query = function() {
|
|||||||
sp = this.get_filter('Sales Person', 'Sales Person').get_value();
|
sp = this.get_filter('Sales Person', 'Sales Person').get_value();
|
||||||
|
|
||||||
date_fld = 'transaction_date';
|
date_fld = 'transaction_date';
|
||||||
if(based_on == 'Sales Invoice') {
|
if(based_on == 'Sales Invoice' || based_on == "Delivery Note") date_fld = 'posting_date';
|
||||||
based_on = 'Sales Invoice';
|
|
||||||
date_fld = 'posting_date';
|
|
||||||
}
|
|
||||||
|
|
||||||
sp_cond = '';
|
sp_cond = '';
|
||||||
if (from_date) sp_cond += ' AND t1.' + date_fld + '>= "' + from_date + '"';
|
if (from_date) sp_cond += ' AND t1.' + date_fld + '>= "' + from_date + '"';
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
"creation": "2012-02-02 11:50:33",
|
"creation": "2012-02-02 11:50:33",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-04-05 16:08:22",
|
"modified": "2013-04-16 12:26:28",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -60,6 +60,13 @@
|
|||||||
"match_id": 1,
|
"match_id": 1,
|
||||||
"to_field": "dn_detail"
|
"to_field": "dn_detail"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"doctype": "Field Mapper Detail",
|
||||||
|
"from_field": "eval: flt(obj.qty) - flt(obj.packed_qty)",
|
||||||
|
"map": "Yes",
|
||||||
|
"match_id": 1,
|
||||||
|
"to_field": "qty"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"doctype": "Table Mapper Detail",
|
"doctype": "Table Mapper Detail",
|
||||||
"from_table": "Delivery Note",
|
"from_table": "Delivery Note",
|
||||||
|
|||||||
@ -39,7 +39,8 @@ class DocType(DocListController):
|
|||||||
# webpage updates
|
# webpage updates
|
||||||
self.update_website()
|
self.update_website()
|
||||||
|
|
||||||
bin = sql("select stock_uom from `tabBin` where item_code = '%s' " % self.doc.item_code)
|
bin = sql("select stock_uom from `tabBin` where item_code = %s",
|
||||||
|
self.doc.item_code)
|
||||||
if bin and cstr(bin[0][0]) and cstr(bin[0][0]) != cstr(self.doc.stock_uom):
|
if bin and cstr(bin[0][0]) and cstr(bin[0][0]) != cstr(self.doc.stock_uom):
|
||||||
msgprint("Please Update Stock UOM with the help of Stock UOM Replace Utility.")
|
msgprint("Please Update Stock UOM with the help of Stock UOM Replace Utility.")
|
||||||
raise Exception
|
raise Exception
|
||||||
@ -149,7 +150,7 @@ class DocType(DocListController):
|
|||||||
|
|
||||||
def check_for_active_boms(self, field_label):
|
def check_for_active_boms(self, field_label):
|
||||||
if field_label in ['Is Active', 'Is Purchase Item']:
|
if field_label in ['Is Active', 'Is Purchase Item']:
|
||||||
bom_mat = sql("select distinct t1.parent from `tabBOM Item` t1, `tabBOM` t2 where t1.item_code ='%s' and (t1.bom_no = '' or t1.bom_no is NULL) and t2.name = t1.parent and t2.is_active = 1 and t2.docstatus = 1 and t1.docstatus =1 " % self.doc.name )
|
bom_mat = sql("select distinct t1.parent from `tabBOM Item` t1, `tabBOM` t2 where t1.item_code =%s and (t1.bom_no = '' or t1.bom_no is NULL) and t2.name = t1.parent and t2.is_active = 1 and t2.docstatus = 1 and t1.docstatus =1 ", self.doc.name)
|
||||||
if bom_mat and bom_mat[0][0]:
|
if bom_mat and bom_mat[0][0]:
|
||||||
msgprint("%s should be 'Yes'. As Item %s is present in one or many Active BOMs." % (cstr(field_label), cstr(self.doc.name)))
|
msgprint("%s should be 'Yes'. As Item %s is present in one or many Active BOMs." % (cstr(field_label), cstr(self.doc.name)))
|
||||||
raise Exception
|
raise Exception
|
||||||
@ -157,7 +158,7 @@ class DocType(DocListController):
|
|||||||
and self.doc.is_sub_contracted_item != 'Yes')
|
and self.doc.is_sub_contracted_item != 'Yes')
|
||||||
or (field_label == 'Is Sub Contracted Item'
|
or (field_label == 'Is Sub Contracted Item'
|
||||||
and self.doc.is_manufactured_item != 'Yes')):
|
and self.doc.is_manufactured_item != 'Yes')):
|
||||||
bom = sql("select name from `tabBOM` where item = '%s' and is_active = 1" % cstr(self.doc.name))
|
bom = sql("select name from `tabBOM` where item = %s and is_active = 1", self.doc.name)
|
||||||
if bom and bom[0][0]:
|
if bom and bom[0][0]:
|
||||||
msgprint("%s should be 'Yes'. As Item %s is present in one or many Active BOMs." % (cstr(field_label), cstr(self.doc.name)))
|
msgprint("%s should be 'Yes'. As Item %s is present in one or many Active BOMs." % (cstr(field_label), cstr(self.doc.name)))
|
||||||
raise Exception
|
raise Exception
|
||||||
@ -242,7 +243,7 @@ class DocType(DocListController):
|
|||||||
if vals and ((self.doc.is_stock_item == "No" and vals.is_stock_item == "Yes") or
|
if vals and ((self.doc.is_stock_item == "No" and vals.is_stock_item == "Yes") or
|
||||||
vals.has_serial_no != self.doc.has_serial_no or
|
vals.has_serial_no != self.doc.has_serial_no or
|
||||||
vals.valuation_method != self.doc.valuation_method):
|
vals.valuation_method != self.doc.valuation_method):
|
||||||
if self.check_if_sle_exists():
|
if self.check_if_sle_exists() == "exists":
|
||||||
webnotes.msgprint(_("As there are existing stock transactions for this \
|
webnotes.msgprint(_("As there are existing stock transactions for this \
|
||||||
item, you can not change the values of 'Has Serial No', \
|
item, you can not change the values of 'Has Serial No', \
|
||||||
'Is Stock Item' and 'Valuation Method'"), raise_exception=1)
|
'Is Stock Item' and 'Valuation Method'"), raise_exception=1)
|
||||||
|
|||||||
@ -185,17 +185,6 @@ class DocType:
|
|||||||
|
|
||||||
|
|
||||||
def set_item_details(self, row):
|
def set_item_details(self, row):
|
||||||
res = webnotes.conn.sql("""SELECT item_name, SUM(IFNULL(qty, 0)) as total_qty,
|
|
||||||
IFNULL(packed_qty, 0) as packed_qty, stock_uom
|
|
||||||
FROM `tabDelivery Note Item`
|
|
||||||
WHERE parent=%s AND item_code=%s GROUP BY item_code""",
|
|
||||||
(self.doc.delivery_note, row.item_code), as_dict=1)
|
|
||||||
|
|
||||||
if res and len(res)>0:
|
|
||||||
qty = res[0]['total_qty'] - res[0]['packed_qty']
|
|
||||||
if not row.qty:
|
|
||||||
row.qty = qty >= 0 and qty or 0
|
|
||||||
|
|
||||||
res = webnotes.conn.sql("""SELECT net_weight, weight_uom FROM `tabItem`
|
res = webnotes.conn.sql("""SELECT net_weight, weight_uom FROM `tabItem`
|
||||||
WHERE name=%s""", row.item_code, as_dict=1)
|
WHERE name=%s""", row.item_code, as_dict=1)
|
||||||
|
|
||||||
|
|||||||
@ -14,25 +14,40 @@ def generate(domain):
|
|||||||
import urllib, os
|
import urllib, os
|
||||||
import webnotes
|
import webnotes
|
||||||
import webnotes.webutils
|
import webnotes.webutils
|
||||||
|
from webnotes.utils import nowdate
|
||||||
|
|
||||||
# settings
|
# settings
|
||||||
max_doctypes = 10
|
|
||||||
max_items = 1000
|
max_items = 1000
|
||||||
|
count = 0
|
||||||
|
|
||||||
site_map = ''
|
site_map = ''
|
||||||
page_list = []
|
|
||||||
|
|
||||||
if domain:
|
if domain:
|
||||||
# list of all pages in web cache
|
today = nowdate()
|
||||||
for doctype in webnotes.webutils.page_map:
|
|
||||||
d = webnotes.webutils.page_map[doctype];
|
# generated pages
|
||||||
|
for doctype, opts in webnotes.webutils.get_generators().items():
|
||||||
pages = webnotes.conn.sql("""select page_name, `modified`
|
pages = webnotes.conn.sql("""select page_name, `modified`
|
||||||
from `tab%s` where ifnull(%s,0)=1
|
from `tab%s` where ifnull(%s,0)=1
|
||||||
order by modified desc""" % (doctype, d.condition_field))
|
order by modified desc""" % (doctype, opts.get("condition_field")))
|
||||||
|
|
||||||
for p in pages:
|
for p in pages:
|
||||||
|
if count >= max_items: break
|
||||||
page_url = os.path.join(domain, urllib.quote(p[0]))
|
page_url = os.path.join(domain, urllib.quote(p[0]))
|
||||||
modified = p[1].strftime('%Y-%m-%d')
|
modified = p[1].strftime('%Y-%m-%d')
|
||||||
site_map += link_xml % (page_url, modified)
|
site_map += link_xml % (page_url, modified)
|
||||||
|
count += 1
|
||||||
|
|
||||||
|
if count >= max_items: break
|
||||||
|
|
||||||
|
# standard pages
|
||||||
|
for page, opts in webnotes.get_config()["web"]["pages"].items():
|
||||||
|
if "no_cache" in opts:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if count >= max_items: break
|
||||||
|
page_url = os.path.join(domain, urllib.quote(page))
|
||||||
|
modified = today
|
||||||
|
site_map += link_xml % (page_url, modified)
|
||||||
|
count += 1
|
||||||
|
|
||||||
return frame_xml % site_map
|
return frame_xml % site_map
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user