commit
40deced91c
@ -1,13 +1,13 @@
|
|||||||
# Please edit this list and import only required elements
|
# Please edit this list and import only required elements
|
||||||
import webnotes
|
import webnotes
|
||||||
|
|
||||||
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
|
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, set_default, str_esc_quote, user_format, validate_email_add, add_days
|
||||||
from webnotes.model import db_exists
|
from webnotes.model import db_exists
|
||||||
from webnotes.model.doc import Document, addchild, removechild, getchildren, make_autoname, SuperDocType
|
from webnotes.model.doc import Document, addchild, removechild, getchildren, make_autoname, SuperDocType
|
||||||
from webnotes.model.doclist import getlist, copy_doclist
|
from webnotes.model.doclist import getlist, copy_doclist
|
||||||
from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
|
from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
|
||||||
from webnotes import session, form, is_testing, msgprint, errprint
|
from webnotes import session, form, is_testing, msgprint, errprint
|
||||||
|
from webnotes.utils.email_lib import sendmail
|
||||||
set = webnotes.conn.set
|
set = webnotes.conn.set
|
||||||
sql = webnotes.conn.sql
|
sql = webnotes.conn.sql
|
||||||
get_value = webnotes.conn.get_value
|
get_value = webnotes.conn.get_value
|
||||||
@ -18,99 +18,125 @@ convert_to_lists = webnotes.conn.convert_to_lists
|
|||||||
|
|
||||||
|
|
||||||
class DocType:
|
class DocType:
|
||||||
def __init__(self,d,dl):
|
def __init__(self,d,dl):
|
||||||
self.doc, self.doclist = d,dl
|
self.doc, self.doclist = d,dl
|
||||||
|
|
||||||
def get_projects(self, arg):
|
def get_projects(self, arg):
|
||||||
# project list
|
# project list
|
||||||
pl=[]
|
pl=[]
|
||||||
status={}
|
status={}
|
||||||
if arg == 'Open':
|
if arg == 'Open':
|
||||||
pl = [p[0] for p in sql("select name from `tabProject` where status = 'Open' order by creation desc limit 20")]
|
pl = [p[0] for p in sql("select name from `tabProject` where status = 'Open' order by creation desc limit 20")]
|
||||||
for p1 in pl:
|
for p1 in pl:
|
||||||
status[p1] = 'Open'
|
status[p1] = 'Open'
|
||||||
elif arg == 'Completed':
|
elif arg == 'Completed':
|
||||||
pl = [p[0] for p in sql("select name from `tabProject` where status = 'Completed' order by creation desc limit 20")]
|
pl = [p[0] for p in sql("select name from `tabProject` where status = 'Completed' order by creation desc limit 20")]
|
||||||
for p2 in pl:
|
for p2 in pl:
|
||||||
status[p2] = 'Completed'
|
status[p2] = 'Completed'
|
||||||
elif arg == 'Cancelled':
|
elif arg == 'Cancelled':
|
||||||
pl = [p[0] for p in sql("select name from `tabProject` where status = 'Cancelled' order by creation desc limit 20")]
|
pl = [p[0] for p in sql("select name from `tabProject` where status = 'Cancelled' order by creation desc limit 20")]
|
||||||
for p3 in pl:
|
for p3 in pl:
|
||||||
status[p3] = 'Cancelled'
|
status[p3] = 'Cancelled'
|
||||||
else:
|
else:
|
||||||
#pl = [p[0] for p in sql("select name from `tabProject` order by creation desc limit 20")]
|
#pl = [p[0] for p in sql("select name from `tabProject` order by creation desc limit 20")]
|
||||||
pl1 = sql("select name, status from `tabProject` order by creation desc limit 20", as_dict=1)
|
pl1 = sql("select name, status from `tabProject` order by creation desc limit 20", as_dict=1)
|
||||||
for p4 in pl1:
|
for p4 in pl1:
|
||||||
status[p4['name']] = p4['status']
|
status[p4['name']] = p4['status']
|
||||||
pl.append(p4['name'])
|
pl.append(p4['name'])
|
||||||
|
|
||||||
# milestones in the next 7 days for active projects
|
# milestones in the next 7 days for active projects
|
||||||
ml = convert_to_lists(sql("select t1.milestone_date, t1.milestone, t1.parent from `tabProject Milestone` t1, tabProject t2 where t1.parent = t2.name and t2.status='Open' and DATEDIFF(t1.milestone_date, CURDATE()) BETWEEN 0 AND 7 ORDER BY t1.milestone_date ASC"))
|
ml = convert_to_lists(sql("select t1.milestone_date, t1.milestone, t1.parent from `tabProject Milestone` t1, tabProject t2 where t1.parent = t2.name and t2.status='Open' and DATEDIFF(t1.milestone_date, CURDATE()) BETWEEN 0 AND 7 ORDER BY t1.milestone_date ASC"))
|
||||||
|
|
||||||
# percent of activity completed per project
|
# percent of activity completed per project
|
||||||
comp = {}
|
comp = {}
|
||||||
n_tasks = {}
|
n_tasks = {}
|
||||||
|
|
||||||
for p in pl:
|
for p in pl:
|
||||||
t1 = sql('select count(*) from tabTicket where project=%s and docstatus!=2', p)[0][0]
|
t1 = sql('select count(*) from tabTicket where project=%s and docstatus!=2', p)[0][0]
|
||||||
n_tasks[p] = t1 or 0
|
n_tasks[p] = t1 or 0
|
||||||
if t1:
|
if t1:
|
||||||
t2 = sql('select count(*) from tabTicket where project=%s and docstatus!=2 and status="Closed"', p)[0][0]
|
t2 = sql('select count(*) from tabTicket where project=%s and docstatus!=2 and status="Closed"', p)[0][0]
|
||||||
comp[p] = cint(flt(t2)*100/t1)
|
comp[p] = cint(flt(t2)*100/t1)
|
||||||
|
|
||||||
return {'pl':pl, 'ml':ml, 'comp':comp, 'n_tasks':n_tasks, 'status':status}
|
return {'pl':pl, 'ml':ml, 'comp':comp, 'n_tasks':n_tasks, 'status':status}
|
||||||
|
|
||||||
def get_resources(self):
|
def get_resources(self):
|
||||||
ret = {}
|
ret = {}
|
||||||
|
|
||||||
# resource list
|
# resource list
|
||||||
rl = sql("select distinct allocated_to, assignee_email from tabTicket")
|
rl = sql("select distinct allocated_to, assignee_email from tabTicket")
|
||||||
|
|
||||||
# get open & closed tickets
|
# get open & closed tickets
|
||||||
for r in rl:
|
for r in rl:
|
||||||
if r[0]:
|
if r[0]:
|
||||||
ret[r[1]] = {}
|
ret[r[1]] = {}
|
||||||
ret[r[1]]['id'] = r[0]
|
ret[r[1]]['id'] = r[0]
|
||||||
ret[r[1]]['Total'] = sql("select count(*) from tabTicket where allocated_to=%s and docstatus!=2", r[0])[0][0]
|
ret[r[1]]['Total'] = sql("select count(*) from tabTicket where allocated_to=%s and docstatus!=2", r[0])[0][0]
|
||||||
ret[r[1]]['Closed'] = sql("select count(*) from tabTicket where allocated_to=%s and status='Closed' and docstatus!=2", r[0])[0][0]
|
ret[r[1]]['Closed'] = sql("select count(*) from tabTicket where allocated_to=%s and status='Closed' and docstatus!=2", r[0])[0][0]
|
||||||
ret[r[1]]['percent'] = cint(flt(ret[r[1]]['Closed']) * 100 / ret[r[1]]['Total'])
|
ret[r[1]]['percent'] = cint(flt(ret[r[1]]['Closed']) * 100 / ret[r[1]]['Total'])
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
# --------------------------------------------------------------
|
# --------------------------------------------------------------
|
||||||
# for Gantt Chart
|
# for Gantt Chart
|
||||||
|
|
||||||
def get_init_data(self, arg=''):
|
def get_init_data(self, arg=''):
|
||||||
pl = [p[0] for p in sql('select name from tabProject where docstatus != 2')]
|
pl = [p[0] for p in sql('select name from tabProject where docstatus != 2')]
|
||||||
rl = [p[0] for p in sql('select distinct allocated_to from tabTicket where docstatus != 2 and ifnull(allocated_to,"") != ""')]
|
rl = [p[0] for p in sql('select distinct allocated_to from tabTicket where docstatus != 2 and ifnull(allocated_to,"") != ""')]
|
||||||
return {'pl':pl, 'rl':rl}
|
return {'pl':pl, 'rl':rl}
|
||||||
|
|
||||||
def get_tasks(self, arg):
|
def get_tasks(self, arg):
|
||||||
start_date, end_date, project, resource = arg.split('~~~')
|
start_date, end_date, project, resource = arg.split('~~~')
|
||||||
|
|
||||||
cl = ''
|
cl = ''
|
||||||
if project and project != 'All':
|
if project and project != 'All':
|
||||||
cl = " and ifnull(project,'') = '%s'" % project
|
cl = " and ifnull(project,'') = '%s'" % project
|
||||||
|
|
||||||
if resource and resource != 'All':
|
if resource and resource != 'All':
|
||||||
cl = " and ifnull(allocated_to,'') = '%s'" % resource
|
cl = " and ifnull(allocated_to,'') = '%s'" % resource
|
||||||
|
|
||||||
tl = sql("""
|
tl = sql("""
|
||||||
select subject, allocated_to, project, exp_start_date, exp_end_date, priority, status, name
|
select subject, allocated_to, project, exp_start_date, exp_end_date, priority, status, name
|
||||||
from tabTicket
|
from tabTicket
|
||||||
where
|
where
|
||||||
((exp_start_date between '%(st)s' and '%(end)s') or
|
((exp_start_date between '%(st)s' and '%(end)s') or
|
||||||
(exp_end_date between '%(st)s' and '%(end)s') or
|
(exp_end_date between '%(st)s' and '%(end)s') or
|
||||||
(exp_start_date < '%(st)s' and exp_end_date > '%(end)s')) %(cond)s order by exp_start_date limit 100""" % {'st': start_date, 'end': end_date, 'cond':cl})
|
(exp_start_date < '%(st)s' and exp_end_date > '%(end)s')) %(cond)s order by exp_start_date limit 100""" % {'st': start_date, 'end': end_date, 'cond':cl})
|
||||||
|
|
||||||
return convert_to_lists(tl)
|
return convert_to_lists(tl)
|
||||||
|
|
||||||
def declare_proj_completed(self, arg):
|
def declare_proj_completed(self, arg):
|
||||||
chk = sql("select name from `tabTicket` where project=%s and status='Open'", arg)
|
chk = sql("select name from `tabTicket` where project=%s and status='Open'", arg)
|
||||||
if chk:
|
if chk:
|
||||||
chk_lst = [x[0] for x in chk]
|
chk_lst = [x[0] for x in chk]
|
||||||
msgprint("Task(s) "+','.join(chk_lst)+" has staus 'Open'. Please submit all tasks against this project before closing the project.")
|
msgprint("Task(s) "+','.join(chk_lst)+" has staus 'Open'. Please submit all tasks against this project before closing the project.")
|
||||||
return cstr('false')
|
return cstr('false')
|
||||||
else:
|
else:
|
||||||
sql("update `tabProject` set status = 'Completed' where name = %s", arg)
|
sql("update `tabProject` set status = 'Completed' where name = %s", arg)
|
||||||
return cstr('true')
|
return cstr('true')
|
||||||
|
|
||||||
|
|
||||||
|
def sent_reminder_task():
|
||||||
|
task_list = sql("""
|
||||||
|
select subject, allocated_to, project, exp_start_date, exp_end_date,
|
||||||
|
priority, status, name, senders_name, opening_date, review_date, description
|
||||||
|
from tabTicket
|
||||||
|
where task_email_notify=1
|
||||||
|
and sent_reminder=0
|
||||||
|
and status='Open'
|
||||||
|
and exp_start_date is not null""",as_dict=1)
|
||||||
|
for i in task_list:
|
||||||
|
if date_diff(i['exp_start_date'],nowdate()) ==2:
|
||||||
|
msg2="""<h2>Two days to complete: %(name)s</h2>
|
||||||
|
<p>This is a reminder for the task %(name)s has been assigned to you
|
||||||
|
by %(senders_name)s on %(opening_date)s</p>
|
||||||
|
<p><b>Project:</b> %(project)s</p>
|
||||||
|
<p><b>Review Date:</b> %(review_date)s</p>
|
||||||
|
<p><b>Details:</b> %(description)s</p>
|
||||||
|
<p>If you have already completed this task, please update the system</p>
|
||||||
|
<p>Good Luck!</p>
|
||||||
|
<p>(This notification is autogenerated)</p>""" % i
|
||||||
|
sendmail(i['allocated_to'], sender='automail@webnotestech.com', msg=msg2,send_now=1, \
|
||||||
|
subject='A task has been assigned')
|
||||||
|
sql("update `tabTicket` set sent_reminder='1' where name='%(name)s' and allocated_to= '%(allocated_to)s'" % i)
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,14 @@
|
|||||||
# Please edit this list and import only required elements
|
# Please edit this list and import only required elements
|
||||||
import webnotes
|
import webnotes
|
||||||
|
|
||||||
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
|
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, set_default, str_esc_quote, user_format, validate_email_add
|
||||||
|
from webnotes.utils.email_lib import sendmail
|
||||||
from webnotes.model import db_exists
|
from webnotes.model import db_exists
|
||||||
from webnotes.model.doc import Document, addchild, removechild, getchildren, make_autoname, SuperDocType
|
from webnotes.model.doc import Document, addchild, removechild, getchildren, make_autoname, SuperDocType
|
||||||
from webnotes.model.doclist import getlist, copy_doclist
|
from webnotes.model.doclist import getlist, copy_doclist
|
||||||
from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
|
from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
|
||||||
from webnotes import session, form, is_testing, msgprint, errprint
|
from webnotes import session, form, is_testing, msgprint, errprint
|
||||||
|
|
||||||
sql = webnotes.conn.sql
|
sql = webnotes.conn.sql
|
||||||
set = webnotes.conn.set
|
set = webnotes.conn.set
|
||||||
get_value = webnotes.conn.get_value
|
get_value = webnotes.conn.get_value
|
||||||
@ -15,161 +17,196 @@ get_value = webnotes.conn.get_value
|
|||||||
|
|
||||||
|
|
||||||
class DocType:
|
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 get_project_details(self):
|
def get_project_details(self):
|
||||||
cust = sql("select customer, customer_name from `tabProject` where name = %s", self.doc.project)
|
cust = sql("select customer, customer_name from `tabProject` where name = %s", self.doc.project)
|
||||||
if cust:
|
if cust:
|
||||||
ret = {'customer': cust and cust[0][0] or '', 'customer_name': cust and cust[0][1] or ''}
|
ret = {'customer': cust and cust[0][0] or '', 'customer_name': cust and cust[0][1] or ''}
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def get_customer_details(self):
|
def get_customer_details(self):
|
||||||
cust = sql("select customer_name from `tabCustomer` where name=%s", self.doc.customer)
|
cust = sql("select customer_name from `tabCustomer` where name=%s", self.doc.customer)
|
||||||
if cust:
|
if cust:
|
||||||
ret = {'customer_name': cust and cust[0][0] or ''}
|
ret = {'customer_name': cust and cust[0][0] or ''}
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def get_allocated_to_name(self):
|
def get_allocated_to_name(self):
|
||||||
as_em = sql("select first_name, last_name from `tabProfile` where name=%s",str(self.doc.allocated_to))
|
as_em = sql("select first_name, last_name from `tabProfile` where name=%s",str(self.doc.allocated_to))
|
||||||
ret = { 'allocated_to_name' : as_em and (as_em[0][0] + ' ' + as_em[0][1]) or ''}
|
ret = { 'allocated_to_name' : as_em and (as_em[0][0] + ' ' + as_em[0][1]) or ''}
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
# validate
|
# validate
|
||||||
#--------------------------------------------
|
#--------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
if not self.doc.opening_date:
|
if not self.doc.opening_date:
|
||||||
msgprint("Please enter Opening Date.")
|
msgprint("Please enter Opening Date.")
|
||||||
raise Exception
|
raise Exception
|
||||||
elif getdate(self.doc.opening_date) > getdate(nowdate()):
|
elif getdate(self.doc.opening_date) > getdate(nowdate()):
|
||||||
msgprint("Opening date can not be future date")
|
msgprint("Opening date can not be future date")
|
||||||
raise Exception
|
raise Exception
|
||||||
|
|
||||||
if self.doc.exp_start_date and self.doc.exp_end_date and getdate(self.doc.exp_start_date) > getdate(self.doc.exp_end_date):
|
if self.doc.exp_start_date and self.doc.exp_end_date and getdate(self.doc.exp_start_date) > getdate(self.doc.exp_end_date):
|
||||||
msgprint("'Expected Start Date' can not be greater than 'Expected End Date'")
|
msgprint("'Expected Start Date' can not be greater than 'Expected End Date'")
|
||||||
raise Exception
|
raise Exception
|
||||||
|
|
||||||
if self.doc.act_start_date and self.doc.act_end_date and getdate(self.doc.act_start_date) > getdate(self.doc.act_end_date):
|
if self.doc.act_start_date and self.doc.act_end_date and getdate(self.doc.act_start_date) > getdate(self.doc.act_end_date):
|
||||||
msgprint("'Actual Start Date' can not be greater than 'Actual End Date'")
|
msgprint("'Actual Start Date' can not be greater than 'Actual End Date'")
|
||||||
raise Exception
|
raise Exception
|
||||||
|
|
||||||
if self.doc.opening_date and self.doc.review_date and getdate(self.doc.opening_date) > getdate(self.doc.review_date):
|
if self.doc.opening_date and self.doc.review_date and getdate(self.doc.opening_date) > getdate(self.doc.review_date):
|
||||||
msgprint("Review Date should be greater than or equal to Opening Date ")
|
msgprint("Review Date should be greater than or equal to Opening Date ")
|
||||||
raise Exception
|
raise Exception
|
||||||
|
|
||||||
if self.doc.closing_date and self.doc.review_date and getdate(self.doc.closing_date) < getdate(self.doc.review_date):
|
if self.doc.closing_date and self.doc.review_date and getdate(self.doc.closing_date) < getdate(self.doc.review_date):
|
||||||
msgprint("Closing Date should be greater than or equal to Review Date ")
|
msgprint("Closing Date should be greater than or equal to Review Date ")
|
||||||
raise Exception
|
raise Exception
|
||||||
|
|
||||||
|
# on update
|
||||||
|
#--------------------------------------------
|
||||||
|
|
||||||
|
def on_update(self):
|
||||||
|
if self.doc.status =='Open' and self.doc.allocated_to:
|
||||||
|
if self.doc.task_email_notify and (self.doc.allocated_to != self.doc.allocated_to_old):
|
||||||
|
self.doc.sent_reminder = 0
|
||||||
|
self.doc.allocated_to_old = self.doc.allocated_to
|
||||||
|
self.sent_notification()
|
||||||
|
if self.doc.exp_start_date:
|
||||||
|
sql("delete from tabEvent where ref_type='Task' and ref_name=%s", self.doc.name)
|
||||||
|
self.add_calendar_event()
|
||||||
|
else:
|
||||||
|
msgprint("An Expeted start date has not been set for this task.Please set a, 'Expected Start date'\
|
||||||
|
to add an event to allocated persons calender.You can save a task without this also.")
|
||||||
|
|
||||||
|
|
||||||
|
def validate_for_pending_review(self):
|
||||||
|
if not self.doc.allocated_to:
|
||||||
|
msgprint("Please enter allocated_to.")
|
||||||
|
raise Exception
|
||||||
|
self.validate_with_timesheet_dates()
|
||||||
|
|
||||||
|
#Sent Notification
|
||||||
|
def sent_notification(self):
|
||||||
|
msg2="""<h2>%(name)s</h2>
|
||||||
|
<p>This is a Notification for the task %(name)s that has been assigned to you
|
||||||
|
by %(senders_name)s on %(opening_date)s</p>
|
||||||
|
<p><b>Project:</b> %(project)s</p>
|
||||||
|
<p><b>Review Date:</b> %(review_date)s</p>
|
||||||
|
<p><b>Details:</b> %(description)s</p>
|
||||||
|
<p>You will also recieve another reminder 2 days before the commencement of the task</p>
|
||||||
|
<p>Good Luck!</p>
|
||||||
|
<p>(This notification is autogenerated)</p>""" % i
|
||||||
|
sendmail(self.doc.allocated_to, sender='automail@webnotestech.com', msg=msg2,send_now=1,\
|
||||||
|
subject='A task has been assigned')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#validate before closing task
|
||||||
|
def validate_for_closed(self):
|
||||||
|
self.check_non_submitted_timesheets()
|
||||||
|
self.get_actual_total_hrs()
|
||||||
|
|
||||||
|
def check_non_submitted_timesheets(self):
|
||||||
|
chk = sql("select t1.name from `tabTimesheet` t1, `tabTimesheet Detail` t2 where t2.parent=t1.name and t2.task_id=%s and t1.status='Draft'", self.doc.name)
|
||||||
|
if chk:
|
||||||
|
chk_lst = [x[0] for x in chk]
|
||||||
|
msgprint("Please submit timesheet(s) : "+','.join(chk_lst)+" before declaring this task as completed. As details of this task present in timesheet(s)")
|
||||||
|
raise Exception
|
||||||
|
|
||||||
|
#calculate actual total hours taken to complete task from timesheets
|
||||||
|
def get_actual_total_hrs(self):
|
||||||
|
import datetime
|
||||||
|
import time
|
||||||
|
chk = sql("select t2.act_total_hrs from `tabTimesheet` t1, `tabTimesheet Detail` t2 where t2.parent = t1.name and t2.task_id = %s and t1.status = 'Submitted' and ifnull(t2.act_total_hrs, '')!='' order by t1.timesheet_date asc", self.doc.name)
|
||||||
|
if chk:
|
||||||
|
chk_lst = [x[0] for x in chk]
|
||||||
|
actual_total = total =0
|
||||||
|
|
||||||
|
for m in chk_lst:
|
||||||
|
m1, m2=[], 0
|
||||||
|
m1 = m.split(":")
|
||||||
|
m2 = (datetime.timedelta(minutes=cint(m1[1]), hours=cint(m1[0]))).seconds
|
||||||
|
total = total + m2
|
||||||
|
|
||||||
|
actual_total = time.strftime("%H:%M", time.gmtime(total))
|
||||||
|
set(self.doc, 'act_total_hrs', actual_total)
|
||||||
|
|
||||||
|
# validate and fetch actual start and end date
|
||||||
|
def validate_with_timesheet_dates(self):
|
||||||
|
chk = sql("select t1.name, t1.timesheet_date from `tabTimesheet` t1, `tabTimesheet Detail` t2 where t2.parent = t1.name and t2.task_id = %s and t1.status = 'Submitted' order by t1.timesheet_date asc", self.doc.name, as_dict=1)
|
||||||
|
if chk:
|
||||||
|
if self.doc.act_start_date:
|
||||||
|
if chk[0]['timesheet_date'] > getdate(self.doc.act_start_date) or chk[0]['timesheet_date'] < getdate(self.doc.act_start_date):
|
||||||
|
msgprint("Actual start date of this task is "+cstr(chk[0]['timesheet_date'])+" as per timesheet "+cstr(chk[0]['name']))
|
||||||
|
raise Exception
|
||||||
|
else:
|
||||||
|
self.doc.act_start_date = chk[0]['timesheet_date']
|
||||||
|
|
||||||
|
if self.doc.act_end_date:
|
||||||
|
if chk[len(chk)-1]['timesheet_date'] < getdate(self.doc.act_end_date) or chk[len(chk)-1]['timesheet_date'] > getdate(self.doc.act_end_date):
|
||||||
|
msgprint("Actual end date of this task is "+cstr(chk[len(chk)-1]['timesheet_date'])+" as per timesheet "+cstr(chk[len(chk)-1]['name']))
|
||||||
|
raise Exception
|
||||||
|
else:
|
||||||
|
self.doc.act_end_date = chk[len(chk)-1]['timesheet_date']
|
||||||
|
|
||||||
|
def set_for_review(self):
|
||||||
|
self.check_non_submitted_timesheets()
|
||||||
|
self.validate_for_pending_review()
|
||||||
|
self.get_actual_total_hrs()
|
||||||
|
self.doc.review_date = nowdate()
|
||||||
|
self.doc.status = 'Pending Review'
|
||||||
|
self.doc.save()
|
||||||
|
return cstr('true')
|
||||||
|
|
||||||
|
def reopen_task(self):
|
||||||
|
self.doc.status = 'Open'
|
||||||
|
self.doc.save()
|
||||||
|
return cstr('true')
|
||||||
|
|
||||||
|
def declare_completed(self):
|
||||||
|
if self.doc.status == 'Open':
|
||||||
|
self.validate_for_pending_review()
|
||||||
|
self.doc.review_date = nowdate()
|
||||||
|
else:
|
||||||
|
self.validate_with_timesheet_dates()
|
||||||
|
self.validate_for_closed()
|
||||||
|
self.doc.closing_date = nowdate()
|
||||||
|
self.doc.status = 'Closed'
|
||||||
|
self.remove_event_from_calender()
|
||||||
|
self.doc.docstatus = 1
|
||||||
|
self.doc.save()
|
||||||
|
return cstr('true')
|
||||||
|
|
||||||
|
def remove_event_from_calender(self):
|
||||||
|
sql("delete from tabEvent where ref_type='Task' and ref_name=%s", self.doc.name)
|
||||||
|
self.doc.save()
|
||||||
|
|
||||||
|
def cancel_task(self):
|
||||||
|
chk = sql("select distinct t1.name from `tabTimesheet` t1, `tabTimesheet Detail` t2 where t2.parent = t1.name and t2.task_id = %s and t1.status!='Cancelled'", self.doc.name)
|
||||||
|
if chk:
|
||||||
|
chk_lst = [x[0] for x in chk]
|
||||||
|
msgprint("Timesheet(s) "+','.join(chk_lst)+" created against this task. Thus can not be cancelled")
|
||||||
|
raise Exception
|
||||||
|
else:
|
||||||
|
self.doc.status = 'Cancelled'
|
||||||
|
self.doc.docstatus = 2
|
||||||
|
self.remove_event_from_calender()
|
||||||
|
self.doc.save()
|
||||||
|
return cstr('true')
|
||||||
|
|
||||||
|
|
||||||
|
def add_calendar_event(self):
|
||||||
|
event = Document('Event')
|
||||||
|
event.owner = self.doc.allocated_to
|
||||||
|
event.description =''
|
||||||
|
event.event_date = self.doc.exp_start_date and self.doc.exp_start_date or ''
|
||||||
|
event.event_hour = self.doc.event_hour and self.doc.event_hour or '10:00'
|
||||||
|
event.event_type = 'Private'
|
||||||
|
event.ref_type = 'Task'
|
||||||
|
event.ref_name = self.doc.name
|
||||||
|
event.save(1)
|
||||||
|
|
||||||
# on update
|
|
||||||
#--------------------------------------------
|
|
||||||
|
|
||||||
def on_update(self):
|
|
||||||
if (self.doc.status =='Open') and (self.doc.task_email_notify==1):
|
|
||||||
msg2= 'A task %s has been assigned to you by %s on %s <br/> \
|
|
||||||
Project:%s <br/> Review Date:%s <br /> Closing Date:%s <br /> Details %s' \
|
|
||||||
%(self.doc.name,self.doc.senders_name,self.doc.opening_date,self.doc.project, \
|
|
||||||
self.doc.review_date,self.doc.closing_date,self.doc.description)
|
|
||||||
sendmail(self.doc.allocated_to, sender='automail@webnotestech.com', \
|
|
||||||
subject='A task has been assigned', parts=[['text/plain',msg2]])
|
|
||||||
pass
|
|
||||||
|
|
||||||
#validate before sending for approval
|
|
||||||
def validate_for_pending_review(self):
|
|
||||||
if not self.doc.allocated_to:
|
|
||||||
msgprint("Please enter allocated_to.")
|
|
||||||
raise Exception
|
|
||||||
self.validate_with_timesheet_dates()
|
|
||||||
|
|
||||||
#validate before closing task
|
|
||||||
def validate_for_closed(self):
|
|
||||||
self.check_non_submitted_timesheets()
|
|
||||||
self.get_actual_total_hrs()
|
|
||||||
|
|
||||||
def check_non_submitted_timesheets(self):
|
|
||||||
chk = sql("select t1.name from `tabTimesheet` t1, `tabTimesheet Detail` t2 where t2.parent=t1.name and t2.task_id=%s and t1.status='Draft'", self.doc.name)
|
|
||||||
if chk:
|
|
||||||
chk_lst = [x[0] for x in chk]
|
|
||||||
msgprint("Please submit timesheet(s) : "+','.join(chk_lst)+" before declaring this task as completed. As details of this task present in timesheet(s)")
|
|
||||||
raise Exception
|
|
||||||
|
|
||||||
#calculate actual total hours taken to complete task from timesheets
|
|
||||||
def get_actual_total_hrs(self):
|
|
||||||
import datetime
|
|
||||||
import time
|
|
||||||
chk = sql("select t2.act_total_hrs from `tabTimesheet` t1, `tabTimesheet Detail` t2 where t2.parent = t1.name and t2.task_id = %s and t1.status = 'Submitted' and ifnull(t2.act_total_hrs, '')!='' order by t1.timesheet_date asc", self.doc.name)
|
|
||||||
if chk:
|
|
||||||
chk_lst = [x[0] for x in chk]
|
|
||||||
actual_total = total =0
|
|
||||||
|
|
||||||
for m in chk_lst:
|
|
||||||
m1, m2=[], 0
|
|
||||||
m1 = m.split(":")
|
|
||||||
m2 = (datetime.timedelta(minutes=cint(m1[1]), hours=cint(m1[0]))).seconds
|
|
||||||
total = total + m2
|
|
||||||
|
|
||||||
actual_total = time.strftime("%H:%M", time.gmtime(total))
|
|
||||||
set(self.doc, 'act_total_hrs', actual_total)
|
|
||||||
|
|
||||||
# validate and fetch actual start and end date
|
|
||||||
def validate_with_timesheet_dates(self):
|
|
||||||
chk = sql("select t1.name, t1.timesheet_date from `tabTimesheet` t1, `tabTimesheet Detail` t2 where t2.parent = t1.name and t2.task_id = %s and t1.status = 'Submitted' order by t1.timesheet_date asc", self.doc.name, as_dict=1)
|
|
||||||
if chk:
|
|
||||||
if self.doc.act_start_date:
|
|
||||||
if chk[0]['timesheet_date'] > getdate(self.doc.act_start_date) or chk[0]['timesheet_date'] < getdate(self.doc.act_start_date):
|
|
||||||
msgprint("Actual start date of this task is "+cstr(chk[0]['timesheet_date'])+" as per timesheet "+cstr(chk[0]['name']))
|
|
||||||
raise Exception
|
|
||||||
else:
|
|
||||||
self.doc.act_start_date = chk[0]['timesheet_date']
|
|
||||||
|
|
||||||
if self.doc.act_end_date:
|
|
||||||
if chk[len(chk)-1]['timesheet_date'] < getdate(self.doc.act_end_date) or chk[len(chk)-1]['timesheet_date'] > getdate(self.doc.act_end_date):
|
|
||||||
msgprint("Actual end date of this task is "+cstr(chk[len(chk)-1]['timesheet_date'])+" as per timesheet "+cstr(chk[len(chk)-1]['name']))
|
|
||||||
raise Exception
|
|
||||||
else:
|
|
||||||
self.doc.act_end_date = chk[len(chk)-1]['timesheet_date']
|
|
||||||
|
|
||||||
def set_for_review(self):
|
|
||||||
self.check_non_submitted_timesheets()
|
|
||||||
self.validate_for_pending_review()
|
|
||||||
self.get_actual_total_hrs()
|
|
||||||
self.doc.review_date = nowdate()
|
|
||||||
set(self.doc, 'status', 'Pending Review')
|
|
||||||
self.doc.save()
|
|
||||||
return cstr('true')
|
|
||||||
|
|
||||||
def reopen_task(self):
|
|
||||||
set(self.doc, 'status', 'Open')
|
|
||||||
self.doc.save()
|
|
||||||
return cstr('true')
|
|
||||||
|
|
||||||
def declare_completed(self):
|
|
||||||
if self.doc.status == 'Open':
|
|
||||||
self.validate_for_pending_review()
|
|
||||||
self.doc.review_date = nowdate()
|
|
||||||
else:
|
|
||||||
self.validate_with_timesheet_dates()
|
|
||||||
self.validate_for_closed()
|
|
||||||
self.doc.closing_date = nowdate()
|
|
||||||
set(self.doc, 'status', 'Closed')
|
|
||||||
set(self.doc, 'docstatus', 1)
|
|
||||||
self.doc.save()
|
|
||||||
return cstr('true')
|
|
||||||
|
|
||||||
def cancel_task(self):
|
|
||||||
chk = sql("select distinct t1.name from `tabTimesheet` t1, `tabTimesheet Detail` t2 where t2.parent = t1.name and t2.task_id = %s and t1.status!='Cancelled'", self.doc.name)
|
|
||||||
if chk:
|
|
||||||
chk_lst = [x[0] for x in chk]
|
|
||||||
msgprint("Timesheet(s) "+','.join(chk_lst)+" created against this task. Thus can not be cancelled")
|
|
||||||
raise Exception
|
|
||||||
else:
|
|
||||||
set(self.doc, 'status', 'Cancelled')
|
|
||||||
set(self.doc, 'docstatus', 2)
|
|
||||||
self.doc.save()
|
|
||||||
return cstr('true')
|
|
||||||
|
|
||||||
def on_cancel(self):
|
|
||||||
self.cancel_task()
|
|
||||||
|
|||||||
@ -5,14 +5,14 @@
|
|||||||
{
|
{
|
||||||
'creation': '2011-01-28 17:52:35',
|
'creation': '2011-01-28 17:52:35',
|
||||||
'docstatus': 0,
|
'docstatus': 0,
|
||||||
'modified': '2011-12-21 16:32:30',
|
'modified': '2011-12-23 12:02:29',
|
||||||
'modified_by': 'Administrator',
|
'modified_by': 'Administrator',
|
||||||
'owner': 'Administrator'
|
'owner': 'Administrator'
|
||||||
},
|
},
|
||||||
|
|
||||||
# These values are common for all DocType
|
# These values are common for all DocType
|
||||||
{
|
{
|
||||||
'_last_update': '1324394580',
|
'_last_update': '1324619022',
|
||||||
'allow_trash': 1,
|
'allow_trash': 1,
|
||||||
'autoname': 'TIC/.####',
|
'autoname': 'TIC/.####',
|
||||||
'colour': 'White:FFF',
|
'colour': 'White:FFF',
|
||||||
@ -26,7 +26,7 @@
|
|||||||
'show_in_menu': 0,
|
'show_in_menu': 0,
|
||||||
'subject': '%(subject)s',
|
'subject': '%(subject)s',
|
||||||
'tag_fields': 'status',
|
'tag_fields': 'status',
|
||||||
'version': 247
|
'version': 252
|
||||||
},
|
},
|
||||||
|
|
||||||
# These values are common for all DocField
|
# These values are common for all DocField
|
||||||
@ -249,6 +249,17 @@
|
|||||||
'width': '50%'
|
'width': '50%'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
# DocField
|
||||||
|
{
|
||||||
|
'doctype': 'DocField',
|
||||||
|
'fieldname': 'allocated_to_old',
|
||||||
|
'fieldtype': 'Link',
|
||||||
|
'hidden': 1,
|
||||||
|
'label': 'Allocated To Old',
|
||||||
|
'no_copy': 1,
|
||||||
|
'permlevel': 0
|
||||||
|
},
|
||||||
|
|
||||||
# DocField
|
# DocField
|
||||||
{
|
{
|
||||||
'colour': 'White:FFF',
|
'colour': 'White:FFF',
|
||||||
@ -275,6 +286,17 @@
|
|||||||
'permlevel': 0
|
'permlevel': 0
|
||||||
},
|
},
|
||||||
|
|
||||||
|
# DocField
|
||||||
|
{
|
||||||
|
'doctype': 'DocField',
|
||||||
|
'fieldname': 'sent_reminder',
|
||||||
|
'fieldtype': 'Data',
|
||||||
|
'hidden': 1,
|
||||||
|
'label': 'Sent Reminder',
|
||||||
|
'no_copy': 1,
|
||||||
|
'permlevel': 0
|
||||||
|
},
|
||||||
|
|
||||||
# DocField
|
# DocField
|
||||||
{
|
{
|
||||||
'doctype': 'DocField',
|
'doctype': 'DocField',
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user