From 8acb043a8a8a6dfa652fa6adc599b91b5f885cf1 Mon Sep 17 00:00:00 2001 From: Nijil Y Date: Thu, 22 Dec 2011 13:08:25 +0530 Subject: [PATCH 01/23] update --- erpnext/projects/doctype/ticket/ticket.py | 334 +++++++++++---------- erpnext/projects/doctype/ticket/ticket.txt | 16 +- 2 files changed, 192 insertions(+), 158 deletions(-) diff --git a/erpnext/projects/doctype/ticket/ticket.py b/erpnext/projects/doctype/ticket/ticket.py index 4d3e988f117..6d53d6a8411 100644 --- a/erpnext/projects/doctype/ticket/ticket.py +++ b/erpnext/projects/doctype/ticket/ticket.py @@ -1,12 +1,14 @@ # Please edit this list and import only required elements 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.util.email_lib import sendmail from webnotes.model import db_exists from webnotes.model.doc import Document, addchild, removechild, getchildren, make_autoname, SuperDocType 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 import session, form, is_testing, msgprint, errprint + sql = webnotes.conn.sql set = webnotes.conn.set get_value = webnotes.conn.get_value @@ -15,161 +17,183 @@ get_value = webnotes.conn.get_value class DocType: - def __init__(self,doc,doclist=[]): - self.doc = doc - self.doclist = doclist - - def get_project_details(self): - cust = sql("select customer, customer_name from `tabProject` where name = %s", self.doc.project) - if cust: - ret = {'customer': cust and cust[0][0] or '', 'customer_name': cust and cust[0][1] or ''} - return ret - - def get_customer_details(self): - cust = sql("select customer_name from `tabCustomer` where name=%s", self.doc.customer) - if cust: - ret = {'customer_name': cust and cust[0][0] or ''} - return ret - - def get_allocated_to_name(self): - 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 ''} - return ret + def __init__(self,doc,doclist=[]): + self.doc = doc + self.doclist = doclist + + def get_project_details(self): + cust = sql("select customer, customer_name from `tabProject` where name = %s", self.doc.project) + if cust: + ret = {'customer': cust and cust[0][0] or '', 'customer_name': cust and cust[0][1] or ''} + return ret + + def get_customer_details(self): + cust = sql("select customer_name from `tabCustomer` where name=%s", self.doc.customer) + if cust: + ret = {'customer_name': cust and cust[0][0] or ''} + return ret + + def get_allocated_to_name(self): + 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 ''} + return ret - # validate - #-------------------------------------------- + # validate + #-------------------------------------------- - def validate(self): - if not self.doc.opening_date: - msgprint("Please enter Opening Date.") - raise Exception - elif getdate(self.doc.opening_date) > getdate(nowdate()): - msgprint("Opening date can not be future date") - 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): - msgprint("'Expected Start Date' can not be greater than 'Expected End Date'") - 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): - msgprint("'Actual Start Date' can not be greater than 'Actual End Date'") - raise Exception - - 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 ") - raise Exception - - 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 ") - raise Exception + def validate(self): + if not self.doc.opening_date: + msgprint("Please enter Opening Date.") + raise Exception + elif getdate(self.doc.opening_date) > getdate(nowdate()): + msgprint("Opening date can not be future date") + 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): + msgprint("'Expected Start Date' can not be greater than 'Expected End Date'") + 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): + msgprint("'Actual Start Date' can not be greater than 'Actual End Date'") + raise Exception + + 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 ") + raise Exception + + 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 ") + raise Exception - # 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
\ - Project:%s
Review Date:%s
Closing Date:%s
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() + # on update + #-------------------------------------------- + + def on_update(self): + if (self.doc.status =='Open') and (self.doc.task_email_notify==1): + if (self.doc.allocated_to == self.doc.allocated_to_old): + return + else: + self.doc.allocated_to_old = self.doc.allocated_to + msg2="""A task %s has been assigned to you by %s on %s

Project: %s

\ + Review Date: %s

Closing Date: %s

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) + self.add_calendar_event() + sendmail(self.doc.allocated_to, sender='automail@webnotestech.com',subject='A task has been assigned',\ + parts=[['text/plain',msg2]]) + self.doc.sent_reminder=0 + pass + #Function to be called from server inside scheduler ... set reminder/events + #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 delete_event_from_calender(self): Add later + + def add_calendar_event(self): + in_calendar_of = self.doc.allocated_to + event = Document('Event') + event.owner = in_calendar_of + event.description ='' + #'Task:%s
By:%s
Project:%s
Details:%s' \ + #%(self.doc.name,self.doc.senders_name,self.doc.project,self.doc.details) + event.event_date = self.doc.exp_start_date + event.event_hour = self.doc.exp_total_hrs and exp_total_hrs or '' + event.event_type = 'Private' + event.ref_type = 'Task' + event.ref_name = self.doc.name + event.save(1) + + + def on_cancel(self): + self.cancel_task() diff --git a/erpnext/projects/doctype/ticket/ticket.txt b/erpnext/projects/doctype/ticket/ticket.txt index cd984aca942..17c0f2d5b93 100644 --- a/erpnext/projects/doctype/ticket/ticket.txt +++ b/erpnext/projects/doctype/ticket/ticket.txt @@ -5,14 +5,14 @@ { 'creation': '2011-01-28 17:52:35', 'docstatus': 0, - 'modified': '2011-12-21 16:32:30', + 'modified': '2011-12-21 17:22:20', 'modified_by': 'Administrator', 'owner': 'Administrator' }, # These values are common for all DocType { - '_last_update': '1324394580', + '_last_update': '1324465350', 'allow_trash': 1, 'autoname': 'TIC/.####', 'colour': 'White:FFF', @@ -26,7 +26,7 @@ 'show_in_menu': 0, 'subject': '%(subject)s', 'tag_fields': 'status', - 'version': 247 + 'version': 248 }, # These values are common for all DocField @@ -249,6 +249,16 @@ 'width': '50%' }, + # DocField + { + 'doctype': 'DocField', + 'fieldname': 'allocated_to_old', + 'fieldtype': 'Link', + 'hidden': 1, + 'label': 'Allocated To Old', + 'permlevel': 0 + }, + # DocField { 'colour': 'White:FFF', From b3058a3d5a5292ef6ad199d74c061c7265bc1edf Mon Sep 17 00:00:00 2001 From: Nijil Y Date: Thu, 22 Dec 2011 17:39:18 +0530 Subject: [PATCH 02/23] Task Notification donw, reminder left --- .../project_control/project_control.py | 170 +++++++++--------- erpnext/projects/doctype/ticket/ticket.py | 53 +++--- erpnext/projects/doctype/ticket/ticket.txt | 18 +- 3 files changed, 128 insertions(+), 113 deletions(-) diff --git a/erpnext/projects/doctype/project_control/project_control.py b/erpnext/projects/doctype/project_control/project_control.py index 82cb1c77e7e..2702ff9b965 100644 --- a/erpnext/projects/doctype/project_control/project_control.py +++ b/erpnext/projects/doctype/project_control/project_control.py @@ -18,99 +18,99 @@ convert_to_lists = webnotes.conn.convert_to_lists class DocType: - def __init__(self,d,dl): - self.doc, self.doclist = d,dl - - def get_projects(self, arg): - # project list - pl=[] - status={} - if arg == 'Open': - pl = [p[0] for p in sql("select name from `tabProject` where status = 'Open' order by creation desc limit 20")] - for p1 in pl: - status[p1] = 'Open' - elif arg == 'Completed': - pl = [p[0] for p in sql("select name from `tabProject` where status = 'Completed' order by creation desc limit 20")] - for p2 in pl: - status[p2] = 'Completed' - elif arg == 'Cancelled': - pl = [p[0] for p in sql("select name from `tabProject` where status = 'Cancelled' order by creation desc limit 20")] - for p3 in pl: - status[p3] = 'Cancelled' - else: - #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) - for p4 in pl1: - status[p4['name']] = p4['status'] - pl.append(p4['name']) - - # 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")) + def __init__(self,d,dl): + self.doc, self.doclist = d,dl + + def get_projects(self, arg): + # project list + pl=[] + status={} + if arg == 'Open': + pl = [p[0] for p in sql("select name from `tabProject` where status = 'Open' order by creation desc limit 20")] + for p1 in pl: + status[p1] = 'Open' + elif arg == 'Completed': + pl = [p[0] for p in sql("select name from `tabProject` where status = 'Completed' order by creation desc limit 20")] + for p2 in pl: + status[p2] = 'Completed' + elif arg == 'Cancelled': + pl = [p[0] for p in sql("select name from `tabProject` where status = 'Cancelled' order by creation desc limit 20")] + for p3 in pl: + status[p3] = 'Cancelled' + else: + #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) + for p4 in pl1: + status[p4['name']] = p4['status'] + pl.append(p4['name']) + + # 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")) - # percent of activity completed per project - comp = {} - n_tasks = {} - - for p in pl: - t1 = sql('select count(*) from tabTicket where project=%s and docstatus!=2', p)[0][0] - n_tasks[p] = t1 or 0 - if t1: - 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) - - return {'pl':pl, 'ml':ml, 'comp':comp, 'n_tasks':n_tasks, 'status':status} - - def get_resources(self): - ret = {} + # percent of activity completed per project + comp = {} + n_tasks = {} + + for p in pl: + t1 = sql('select count(*) from tabTicket where project=%s and docstatus!=2', p)[0][0] + n_tasks[p] = t1 or 0 + if t1: + 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) + + return {'pl':pl, 'ml':ml, 'comp':comp, 'n_tasks':n_tasks, 'status':status} + + def get_resources(self): + ret = {} - # resource list - rl = sql("select distinct allocated_to, assignee_email from tabTicket") + # resource list + rl = sql("select distinct allocated_to, assignee_email from tabTicket") - # get open & closed tickets - for r in rl: - if r[0]: - ret[r[1]] = {} - 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]]['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']) + # get open & closed tickets + for r in rl: + if r[0]: + ret[r[1]] = {} + 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]]['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']) - return ret + return ret - # -------------------------------------------------------------- - # for Gantt Chart + # -------------------------------------------------------------- + # for Gantt Chart - def get_init_data(self, arg=''): - 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,"") != ""')] - return {'pl':pl, 'rl':rl} + def get_init_data(self, arg=''): + 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,"") != ""')] + return {'pl':pl, 'rl':rl} - def get_tasks(self, arg): - start_date, end_date, project, resource = arg.split('~~~') + def get_tasks(self, arg): + start_date, end_date, project, resource = arg.split('~~~') - cl = '' - if project and project != 'All': - cl = " and ifnull(project,'') = '%s'" % project + cl = '' + if project and project != 'All': + cl = " and ifnull(project,'') = '%s'" % project - if resource and resource != 'All': - cl = " and ifnull(allocated_to,'') = '%s'" % resource + if resource and resource != 'All': + cl = " and ifnull(allocated_to,'') = '%s'" % resource - tl = sql(""" - select subject, allocated_to, project, exp_start_date, exp_end_date, priority, status, name - from tabTicket - where - ((exp_start_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}) + tl = sql(""" + select subject, allocated_to, project, exp_start_date, exp_end_date, priority, status, name + from tabTicket + where + ((exp_start_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}) - return convert_to_lists(tl) - - def declare_proj_completed(self, arg): - chk = sql("select name from `tabTicket` where project=%s and status='Open'", arg) - if 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.") - return cstr('false') - else: - sql("update `tabProject` set status = 'Completed' where name = %s", arg) - return cstr('true') \ No newline at end of file + return convert_to_lists(tl) + + def declare_proj_completed(self, arg): + chk = sql("select name from `tabTicket` where project=%s and status='Open'", arg) + if 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.") + return cstr('false') + else: + sql("update `tabProject` set status = 'Completed' where name = %s", arg) + return cstr('true') diff --git a/erpnext/projects/doctype/ticket/ticket.py b/erpnext/projects/doctype/ticket/ticket.py index 6d53d6a8411..250c4390ecb 100644 --- a/erpnext/projects/doctype/ticket/ticket.py +++ b/erpnext/projects/doctype/ticket/ticket.py @@ -2,7 +2,7 @@ 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, set_default, str_esc_quote, user_format, validate_email_add -from webnotes.util.email_lib import sendmail +from webnotes.utils.email_lib import sendmail from webnotes.model import db_exists from webnotes.model.doc import Document, addchild, removechild, getchildren, make_autoname, SuperDocType from webnotes.model.doclist import getlist, copy_doclist @@ -70,22 +70,27 @@ class DocType: #-------------------------------------------- def on_update(self): - if (self.doc.status =='Open') and (self.doc.task_email_notify==1): - if (self.doc.allocated_to == self.doc.allocated_to_old): - return - else: - self.doc.allocated_to_old = self.doc.allocated_to - msg2="""A task %s has been assigned to you by %s on %s

Project: %s

\ - Review Date: %s

Closing Date: %s

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) + if self.doc.status =='Open' and self.doc.allocated_to: + if self.doc.task_email_notify==1: + if (self.doc.allocated_to == self.doc.allocated_to_old): + return + else: + self.doc.allocated_to_old = self.doc.allocated_to + msg2="""This is an auto generated email.
A task %s has been assigned to you by %s on %s

\ + Project: %s

Review Date: %s

Closing Date: %s

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', msg=msg2,send_now=1,\ + subject='A task has been assigned') + self.doc.sent_reminder=0 + 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() - sendmail(self.doc.allocated_to, sender='automail@webnotestech.com',subject='A task has been assigned',\ - parts=[['text/plain',msg2]]) - self.doc.sent_reminder=0 - pass - #Function to be called from server inside scheduler ... set reminder/events - #validate before sending for approval + 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.") + pass + def validate_for_pending_review(self): if not self.doc.allocated_to: msgprint("Please enter allocated_to.") @@ -163,10 +168,13 @@ class DocType: self.validate_for_closed() self.doc.closing_date = nowdate() set(self.doc, 'status', 'Closed') + self.remove_event_from_calender() set(self.doc, 'docstatus', 1) self.doc.save() return cstr('true') - + def remove_event_from_calender(): + 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: @@ -178,22 +186,17 @@ class DocType: set(self.doc, 'docstatus', 2) self.doc.save() return cstr('true') - # def delete_event_from_calender(self): Add later + def add_calendar_event(self): in_calendar_of = self.doc.allocated_to event = Document('Event') event.owner = in_calendar_of event.description ='' - #'Task:%s
By:%s
Project:%s
Details:%s' \ - #%(self.doc.name,self.doc.senders_name,self.doc.project,self.doc.details) - event.event_date = self.doc.exp_start_date - event.event_hour = self.doc.exp_total_hrs and exp_total_hrs or '' + event.event_date = self.doc.exp_start_date and self.doc.exp_start_date or '' + event.event_hour = '10:00' event.event_type = 'Private' event.ref_type = 'Task' event.ref_name = self.doc.name event.save(1) - - def on_cancel(self): - self.cancel_task() diff --git a/erpnext/projects/doctype/ticket/ticket.txt b/erpnext/projects/doctype/ticket/ticket.txt index 17c0f2d5b93..4d18953f780 100644 --- a/erpnext/projects/doctype/ticket/ticket.txt +++ b/erpnext/projects/doctype/ticket/ticket.txt @@ -5,14 +5,14 @@ { 'creation': '2011-01-28 17:52:35', 'docstatus': 0, - 'modified': '2011-12-21 17:22:20', + 'modified': '2011-12-22 14:31:07', 'modified_by': 'Administrator', 'owner': 'Administrator' }, # These values are common for all DocType { - '_last_update': '1324465350', + '_last_update': '1324468340', 'allow_trash': 1, 'autoname': 'TIC/.####', 'colour': 'White:FFF', @@ -26,7 +26,7 @@ 'show_in_menu': 0, 'subject': '%(subject)s', 'tag_fields': 'status', - 'version': 248 + 'version': 250 }, # These values are common for all DocField @@ -256,6 +256,7 @@ 'fieldtype': 'Link', 'hidden': 1, 'label': 'Allocated To Old', + 'no_copy': 1, 'permlevel': 0 }, @@ -285,6 +286,17 @@ 'permlevel': 0 }, + # DocField + { + 'doctype': 'DocField', + 'fieldname': 'sent_reminder', + 'fieldtype': 'Date', + 'hidden': 1, + 'label': 'Sent Reminder', + 'no_copy': 1, + 'permlevel': 0 + }, + # DocField { 'doctype': 'DocField', From d0a892ffe7a8c87c2d4c785a176e955360cc9f1f Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 22 Dec 2011 19:04:49 +0530 Subject: [PATCH 03/23] print hide price list flds --- .../receivable_voucher/receivable_voucher.txt | 34 ++++++++++++++-- erpnext/patches/print_hide_price_list.py | 3 ++ .../selling/doctype/quotation/quotation.txt | 39 ++++++++++++++++--- .../doctype/sales_order/sales_order.txt | 39 ++++++++++++++++--- .../doctype/delivery_note/delivery_note.txt | 28 +++++++++++-- 5 files changed, 125 insertions(+), 18 deletions(-) create mode 100644 erpnext/patches/print_hide_price_list.py diff --git a/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.txt b/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.txt index 497c99febe4..c194e7cc0c7 100644 --- a/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.txt +++ b/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.txt @@ -5,7 +5,7 @@ { 'creation': '2010-08-08 17:09:18', 'docstatus': 0, - 'modified': '2011-12-20 18:23:36', + 'modified': '2011-12-22 19:04:07', 'modified_by': 'Administrator', 'owner': 'Administrator' }, @@ -34,13 +34,12 @@ 'server_code_error': ' ', 'show_in_menu': 0, 'subject': 'To %(customer_name)s worth %(currency)s %(grand_total_export)s due on %(due_date)s | %(outstanding_amount)s outstanding', - 'version': 391 + 'version': 392 }, # These values are common for all DocFormat { 'doctype': 'DocFormat', - 'format': 'POS Invoice', 'name': '__common__', 'parent': 'Receivable Voucher', 'parentfield': 'formats', @@ -126,7 +125,32 @@ # DocFormat { - 'doctype': 'DocFormat' + 'doctype': 'DocFormat', + 'format': 'POS Invoice' + }, + + # DocFormat + { + 'doctype': 'DocFormat', + 'format': 'POS Invoice' + }, + + # DocFormat + { + 'doctype': 'DocFormat', + 'format': 'Sales Invoice Classic' + }, + + # DocFormat + { + 'doctype': 'DocFormat', + 'format': 'Sales Invoice Modern' + }, + + # DocFormat + { + 'doctype': 'DocFormat', + 'format': 'Sales Invoice Spartan' }, # DocField @@ -477,6 +501,7 @@ 'label': 'Price List Currency', 'options': 'link:Currency', 'permlevel': 0, + 'print_hide': 1, 'reqd': 1 }, @@ -489,6 +514,7 @@ 'fieldtype': 'Currency', 'label': 'Price List Currency Conversion Rate', 'permlevel': 0, + 'print_hide': 1, 'reqd': 1 }, diff --git a/erpnext/patches/print_hide_price_list.py b/erpnext/patches/print_hide_price_list.py new file mode 100644 index 00000000000..833ab988085 --- /dev/null +++ b/erpnext/patches/print_hide_price_list.py @@ -0,0 +1,3 @@ +def execute(): + import webnotes + webnotes.conn.sql("update `tabDocField` set print_hide = 1 where fieldname in ('price_list_currency', 'plc_conversion_rate')") diff --git a/erpnext/selling/doctype/quotation/quotation.txt b/erpnext/selling/doctype/quotation/quotation.txt index 86b7b5f324e..ac58dc4db9a 100644 --- a/erpnext/selling/doctype/quotation/quotation.txt +++ b/erpnext/selling/doctype/quotation/quotation.txt @@ -5,11 +5,20 @@ { 'creation': '2010-08-08 17:09:17', 'docstatus': 0, - 'modified': '2011-12-20 14:01:09', + 'modified': '2011-12-22 19:03:04', 'modified_by': 'Administrator', 'owner': 'Administrator' }, + # These values are common for all DocField + { + 'doctype': 'DocField', + 'name': '__common__', + 'parent': 'Quotation', + 'parentfield': 'fields', + 'parenttype': 'DocType' + }, + # These values are common for all DocType { '_last_update': '1322549700', @@ -32,15 +41,15 @@ 'show_in_menu': 0, 'subject': 'To %(customer_name)s on %(transaction_date)s worth %(currency)s %(grand_total_export)s', 'tag_fields': 'status', - 'version': 597 + 'version': 598 }, - # These values are common for all DocField + # These values are common for all DocFormat { - 'doctype': 'DocField', + 'doctype': 'DocFormat', 'name': '__common__', 'parent': 'Quotation', - 'parentfield': 'fields', + 'parentfield': 'formats', 'parenttype': 'DocType' }, @@ -169,6 +178,24 @@ 'role': 'Maintenance User' }, + # DocFormat + { + 'doctype': 'DocFormat', + 'format': 'Quotation Classic' + }, + + # DocFormat + { + 'doctype': 'DocFormat', + 'format': 'Quotation Modern' + }, + + # DocFormat + { + 'doctype': 'DocFormat', + 'format': 'Quotation Spartan' + }, + # DocField { 'colour': 'White:FFF', @@ -568,6 +595,7 @@ 'label': 'Price List Currency', 'options': 'link:Currency', 'permlevel': 0, + 'print_hide': 1, 'reqd': 1 }, @@ -580,6 +608,7 @@ 'fieldtype': 'Currency', 'label': 'Price List Currency Conversion Rate', 'permlevel': 0, + 'print_hide': 1, 'reqd': 1 }, diff --git a/erpnext/selling/doctype/sales_order/sales_order.txt b/erpnext/selling/doctype/sales_order/sales_order.txt index d59f236e5b2..2e6ea999663 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.txt +++ b/erpnext/selling/doctype/sales_order/sales_order.txt @@ -5,11 +5,20 @@ { 'creation': '2010-08-08 17:09:21', 'docstatus': 0, - 'modified': '2011-12-20 12:55:02', + 'modified': '2011-12-22 19:03:25', 'modified_by': 'Administrator', 'owner': 'Administrator' }, + # These values are common for all DocField + { + 'doctype': 'DocField', + 'name': '__common__', + 'parent': 'Sales Order', + 'parentfield': 'fields', + 'parenttype': 'DocType' + }, + # These values are common for all DocType { '_last_update': '1324295218', @@ -29,15 +38,15 @@ 'show_in_menu': 0, 'subject': 'From %(customer_name)s on %(transaction_date)s worth %(currency)s %(grand_total_export)s | %(per_delivered)s% delivered | %(per_billed)s% billed', 'tag_fields': 'delivery_status,billing_status', - 'version': 608 + 'version': 609 }, - # These values are common for all DocField + # These values are common for all DocFormat { - 'doctype': 'DocField', + 'doctype': 'DocFormat', 'name': '__common__', 'parent': 'Sales Order', - 'parentfield': 'fields', + 'parentfield': 'formats', 'parenttype': 'DocType' }, @@ -166,6 +175,24 @@ 'role': 'Maintenance User' }, + # DocFormat + { + 'doctype': 'DocFormat', + 'format': 'Sales Order Classic' + }, + + # DocFormat + { + 'doctype': 'DocFormat', + 'format': 'Sales Order Modern' + }, + + # DocFormat + { + 'doctype': 'DocFormat', + 'format': 'Sales Order Spartan' + }, + # DocField { 'colour': 'White:FFF', @@ -581,6 +608,7 @@ 'label': 'Price List Currency', 'options': 'link:Currency', 'permlevel': 0, + 'print_hide': 1, 'reqd': 1 }, @@ -593,6 +621,7 @@ 'fieldtype': 'Currency', 'label': 'Price List Currency Conversion Rate', 'permlevel': 0, + 'print_hide': 1, 'reqd': 1 }, diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.txt b/erpnext/stock/doctype/delivery_note/delivery_note.txt index dc905f569d9..5340955e675 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.txt +++ b/erpnext/stock/doctype/delivery_note/delivery_note.txt @@ -5,7 +5,7 @@ { 'creation': '2011-04-18 15:58:20', 'docstatus': 0, - 'modified': '2011-12-20 13:23:33', + 'modified': '2011-12-22 19:03:44', 'modified_by': 'Administrator', 'owner': 'Administrator' }, @@ -37,13 +37,12 @@ 'show_in_menu': 0, 'subject': 'To %(customer_name)s on %(transaction_date)s | %(per_billed)s% billed', 'tag_fields': 'billing_status', - 'version': 459 + 'version': 460 }, # These values are common for all DocFormat { 'doctype': 'DocFormat', - 'format': 'Delivery Note Packing List Wise', 'name': '__common__', 'parent': 'Delivery Note', 'parentfield': 'formats', @@ -143,7 +142,26 @@ # DocFormat { - 'doctype': 'DocFormat' + 'doctype': 'DocFormat', + 'format': 'Delivery Note Packing List Wise' + }, + + # DocFormat + { + 'doctype': 'DocFormat', + 'format': 'Delivery Note Classic' + }, + + # DocFormat + { + 'doctype': 'DocFormat', + 'format': 'Delivery Note Modern' + }, + + # DocFormat + { + 'doctype': 'DocFormat', + 'format': 'Delivery Note Spartan' }, # DocField @@ -567,6 +585,7 @@ 'label': 'Price List Currency', 'options': 'link:Currency', 'permlevel': 0, + 'print_hide': 1, 'reqd': 1 }, @@ -579,6 +598,7 @@ 'fieldtype': 'Currency', 'label': 'Price List Currency Conversion Rate', 'permlevel': 0, + 'print_hide': 1, 'reqd': 1 }, From e80496cef431f25c2455a3d721f6d070cdfd5bc5 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 23 Dec 2011 11:25:37 +0530 Subject: [PATCH 04/23] Consider description also to check item duplication in purchase cycle --- .../buying/doctype/purchase_common/purchase_common.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.py b/erpnext/buying/doctype/purchase_common/purchase_common.py index 7612c190b72..84bfffb7ede 100644 --- a/erpnext/buying/doctype/purchase_common/purchase_common.py +++ b/erpnext/buying/doctype/purchase_common/purchase_common.py @@ -248,7 +248,7 @@ class DocType(TransactionBase): raise Exception # list criteria that should not repeat if item is stock item - e = [d.schedule_date, d.item_code, d.warehouse, d.uom, d.fields.has_key('prevdoc_docname') and d.prevdoc_docname or '', d.fields.has_key('prevdoc_detail_docname') and d.prevdoc_detail_docname or '', d.fields.has_key('batch_no') and d.batch_no or ''] + e = [d.schedule_date, d.item_code, d.description, d.warehouse, d.uom, d.fields.has_key('prevdoc_docname') and d.prevdoc_docname or '', d.fields.has_key('prevdoc_detail_docname') and d.prevdoc_detail_docname or '', d.fields.has_key('batch_no') and d.batch_no or ''] # if is not stock item f = [d.schedule_date, d.item_code, d.description] @@ -258,16 +258,16 @@ class DocType(TransactionBase): if ch and ch[0][0] == 'Yes': # check for same items if e in check_list: - msgprint("Item %s has been entered more than once with same schedule date, warehouse and uom." % d.item_code) - raise Exception + msgprint("""Item %s has been entered more than once with same description, schedule date, warehouse and uom.\n + Please change any of the field value to enter the item twice""" % d.item_code, raise_exception = 1) else: check_list.append(e) elif ch and ch[0][0] == 'No': # check for same items if f in chk_dupl_itm: - msgprint("Item %s has been entered more than once." % d.item_code) - raise Exception + msgprint("""Item %s has been entered more than once with same description, schedule date.\n + Please change any of the field value to enter the item twice.""" % d.item_code, raise_exception = 1) else: chk_dupl_itm.append(f) From f1e98b9d8b3821c4d35c1350ae35bddca188c70a Mon Sep 17 00:00:00 2001 From: Nijil Y Date: Fri, 23 Dec 2011 12:01:31 +0530 Subject: [PATCH 05/23] Scheduler added for reminder notification - which will be sent 2 days before the task begins --- .../doctype/project_control/project_control.py | 18 ++++++++++++++++-- erpnext/projects/doctype/ticket/ticket.py | 17 ++++++++++------- erpnext/projects/doctype/ticket/ticket.txt | 8 ++++---- 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/erpnext/projects/doctype/project_control/project_control.py b/erpnext/projects/doctype/project_control/project_control.py index 2702ff9b965..c6e9102cf0d 100644 --- a/erpnext/projects/doctype/project_control/project_control.py +++ b/erpnext/projects/doctype/project_control/project_control.py @@ -1,13 +1,13 @@ # Please edit this list and import only required elements 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.doc import Document, addchild, removechild, getchildren, make_autoname, SuperDocType 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 import session, form, is_testing, msgprint, errprint - +from webnotes.utils.email_lib import sendmail set = webnotes.conn.set sql = webnotes.conn.sql get_value = webnotes.conn.get_value @@ -114,3 +114,17 @@ class DocType: else: sql("update `tabProject` set status = 'Completed' where name = %s", arg) return cstr('true') +def sent_reminder_task(self): + task_list = sql("select subject, allocated_to, project, exp_start_date, exp_end_date, \ + priority, status, name from tabTicket where email_notify=1 and reminder=0 and status='Open'",as_dict=1) + for i in task_list: + if (add_days(nowdate(),2) > i['exp_start_date']) and (add_days(nowdate(),3) < i['exp_start_date']): + msg2="""This is an auto generated email.

This is a reminder for the task %s has been assigned \ + to you by %s on %s

Project: %s

Review Date: %s

Closing Date: %s \ +

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', msg=msg2,send_now=1,\ + subject='A task has been assigned') + self.doc.sent_reminder=1 + diff --git a/erpnext/projects/doctype/ticket/ticket.py b/erpnext/projects/doctype/ticket/ticket.py index 250c4390ecb..1868eeb93d9 100644 --- a/erpnext/projects/doctype/ticket/ticket.py +++ b/erpnext/projects/doctype/ticket/ticket.py @@ -76,13 +76,7 @@ class DocType: return else: self.doc.allocated_to_old = self.doc.allocated_to - msg2="""This is an auto generated email.
A task %s has been assigned to you by %s on %s

\ - Project: %s

Review Date: %s

Closing Date: %s

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', msg=msg2,send_now=1,\ - subject='A task has been assigned') - self.doc.sent_reminder=0 + 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() @@ -96,6 +90,15 @@ class DocType: msgprint("Please enter allocated_to.") raise Exception self.validate_with_timesheet_dates() + #Sent Notification + def sent_notification(self): + msg2="""This is an auto generated email.
A task %s has been assigned to you by %s on %s

\ + Project: %s

Review Date: %s

Closing Date: %s

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', msg=msg2,send_now=1,\ + subject='A task has been assigned') + self.doc.sent_reminder=0 #validate before closing task def validate_for_closed(self): diff --git a/erpnext/projects/doctype/ticket/ticket.txt b/erpnext/projects/doctype/ticket/ticket.txt index 4d18953f780..6efae3e82d4 100644 --- a/erpnext/projects/doctype/ticket/ticket.txt +++ b/erpnext/projects/doctype/ticket/ticket.txt @@ -5,14 +5,14 @@ { 'creation': '2011-01-28 17:52:35', 'docstatus': 0, - 'modified': '2011-12-22 14:31:07', + 'modified': '2011-12-23 11:13:42', 'modified_by': 'Administrator', 'owner': 'Administrator' }, # These values are common for all DocType { - '_last_update': '1324468340', + '_last_update': '1324544468', 'allow_trash': 1, 'autoname': 'TIC/.####', 'colour': 'White:FFF', @@ -26,7 +26,7 @@ 'show_in_menu': 0, 'subject': '%(subject)s', 'tag_fields': 'status', - 'version': 250 + 'version': 251 }, # These values are common for all DocField @@ -290,7 +290,7 @@ { 'doctype': 'DocField', 'fieldname': 'sent_reminder', - 'fieldtype': 'Date', + 'fieldtype': 'Data', 'hidden': 1, 'label': 'Sent Reminder', 'no_copy': 1, From 4d64379aa629ec202b8af34a816d77288b3e40b9 Mon Sep 17 00:00:00 2001 From: Nijil Y Date: Fri, 23 Dec 2011 12:32:08 +0530 Subject: [PATCH 06/23] scheduler added to project control for reminder --- erpnext/projects/doctype/project_control/project_control.py | 5 +++-- erpnext/projects/doctype/ticket/ticket.txt | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/erpnext/projects/doctype/project_control/project_control.py b/erpnext/projects/doctype/project_control/project_control.py index c6e9102cf0d..4d74e8c1827 100644 --- a/erpnext/projects/doctype/project_control/project_control.py +++ b/erpnext/projects/doctype/project_control/project_control.py @@ -116,12 +116,13 @@ class DocType: return cstr('true') def sent_reminder_task(self): task_list = sql("select subject, allocated_to, project, exp_start_date, exp_end_date, \ - priority, status, name from tabTicket where email_notify=1 and reminder=0 and status='Open'",as_dict=1) + priority, status, name 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 (add_days(nowdate(),2) > i['exp_start_date']) and (add_days(nowdate(),3) < i['exp_start_date']): msg2="""This is an auto generated email.

This is a reminder for the task %s has been assigned \ to you by %s on %s

Project: %s

Review Date: %s

Closing Date: %s \ -

Details: %s

""" \ +

Details: %s

The expected start date of this task is on %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', msg=msg2,send_now=1,\ diff --git a/erpnext/projects/doctype/ticket/ticket.txt b/erpnext/projects/doctype/ticket/ticket.txt index 6efae3e82d4..a1ac330e1d3 100644 --- a/erpnext/projects/doctype/ticket/ticket.txt +++ b/erpnext/projects/doctype/ticket/ticket.txt @@ -5,14 +5,14 @@ { 'creation': '2011-01-28 17:52:35', 'docstatus': 0, - 'modified': '2011-12-23 11:13:42', + 'modified': '2011-12-23 12:02:29', 'modified_by': 'Administrator', 'owner': 'Administrator' }, # These values are common for all DocType { - '_last_update': '1324544468', + '_last_update': '1324619022', 'allow_trash': 1, 'autoname': 'TIC/.####', 'colour': 'White:FFF', @@ -26,7 +26,7 @@ 'show_in_menu': 0, 'subject': '%(subject)s', 'tag_fields': 'status', - 'version': 251 + 'version': 252 }, # These values are common for all DocField From cc0e502d0faf2467d622203a179c0acbb47dcaab Mon Sep 17 00:00:00 2001 From: Nijil Y Date: Fri, 23 Dec 2011 15:08:43 +0530 Subject: [PATCH 07/23] scheduler --- .../project_control/project_control.py | 21 ++++++++++++------- erpnext/projects/doctype/ticket/ticket.py | 3 ++- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/erpnext/projects/doctype/project_control/project_control.py b/erpnext/projects/doctype/project_control/project_control.py index 4d74e8c1827..92ed64b3892 100644 --- a/erpnext/projects/doctype/project_control/project_control.py +++ b/erpnext/projects/doctype/project_control/project_control.py @@ -114,18 +114,23 @@ class DocType: else: sql("update `tabProject` set status = 'Completed' where name = %s", arg) return cstr('true') -def sent_reminder_task(self): + + +def sent_reminder_task(): task_list = sql("select subject, allocated_to, project, exp_start_date, exp_end_date, \ - priority, status, name from tabTicket where task_email_notify=1 and sent_reminder=0 and status='Open' and \ + 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) + msgprint(task_list) for i in task_list: - if (add_days(nowdate(),2) > i['exp_start_date']) and (add_days(nowdate(),3) < i['exp_start_date']): + if date_diff(i['exp_start_date'],nowdate())==2: + msgprint(i['exp_start_date']) + msgprint(add_days(nowdate(),2)) msg2="""This is an auto generated email.

This is a reminder for the task %s has been assigned \ - to you by %s on %s

Project: %s

Review Date: %s

Closing Date: %s \ + to you by %s on %s

Project: %s

Review Date: %s \

Details: %s

The expected start date of this task is on %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', msg=msg2,send_now=1,\ + %(i['name'], i['senders_name'], i['opening_date'], i['project'], i['review_date'], i['description'], i['exp_start_date']) + sendmail(i['allocated_to'], sender='automail@webnotestech.com', msg=msg2,send_now=1,\ subject='A task has been assigned') - self.doc.sent_reminder=1 + i['sent_reminder']=1 diff --git a/erpnext/projects/doctype/ticket/ticket.py b/erpnext/projects/doctype/ticket/ticket.py index 1868eeb93d9..a378194aeda 100644 --- a/erpnext/projects/doctype/ticket/ticket.py +++ b/erpnext/projects/doctype/ticket/ticket.py @@ -175,7 +175,7 @@ class DocType: set(self.doc, 'docstatus', 1) self.doc.save() return cstr('true') - def remove_event_from_calender(): + 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): @@ -187,6 +187,7 @@ class DocType: else: set(self.doc, 'status', 'Cancelled') set(self.doc, 'docstatus', 2) + self.remove_event_from_calender() self.doc.save() return cstr('true') From 9239afa2223c35f732f69a336b9897357018aa0d Mon Sep 17 00:00:00 2001 From: Nijil Y Date: Fri, 23 Dec 2011 16:18:49 +0530 Subject: [PATCH 08/23] Update erpnext/projects/doctype/ticket/ticket.py --- erpnext/projects/doctype/ticket/ticket.py | 25 +++++++++++------------ 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/erpnext/projects/doctype/ticket/ticket.py b/erpnext/projects/doctype/ticket/ticket.py index a378194aeda..d07c3730aff 100644 --- a/erpnext/projects/doctype/ticket/ticket.py +++ b/erpnext/projects/doctype/ticket/ticket.py @@ -71,25 +71,23 @@ class DocType: def on_update(self): if self.doc.status =='Open' and self.doc.allocated_to: - if self.doc.task_email_notify==1: - if (self.doc.allocated_to == self.doc.allocated_to_old): - return - else: - self.doc.allocated_to_old = self.doc.allocated_to - self.sent_notification() + if self.doc.task_email_notify and (self.doc.allocated_to != self.doc.allocated_to_old): + 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.") - pass - + + 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="""This is an auto generated email.
A task %s has been assigned to you by %s on %s

\ @@ -175,9 +173,11 @@ class DocType: set(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: @@ -185,20 +185,19 @@ class DocType: 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.status = 'Cancelled' + self.doc.docstatus = 2 self.remove_event_from_calender() self.doc.save() return cstr('true') def add_calendar_event(self): - in_calendar_of = self.doc.allocated_to event = Document('Event') - event.owner = in_calendar_of + 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 = '10:00' + 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 From 89e5624730a4459dc983997a3292c0be1bca050e Mon Sep 17 00:00:00 2001 From: Nijil Y Date: Fri, 23 Dec 2011 16:21:51 +0530 Subject: [PATCH 09/23] Update erpnext/projects/doctype/ticket/ticket.py --- erpnext/projects/doctype/ticket/ticket.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/erpnext/projects/doctype/ticket/ticket.py b/erpnext/projects/doctype/ticket/ticket.py index d07c3730aff..b1ecf04af0f 100644 --- a/erpnext/projects/doctype/ticket/ticket.py +++ b/erpnext/projects/doctype/ticket/ticket.py @@ -151,12 +151,12 @@ class DocType: self.validate_for_pending_review() self.get_actual_total_hrs() self.doc.review_date = nowdate() - set(self.doc, 'status', 'Pending Review') + self.doc.status = 'Pending Review' self.doc.save() return cstr('true') def reopen_task(self): - set(self.doc, 'status', 'Open') + self.doc.status = 'Open' self.doc.save() return cstr('true') @@ -168,9 +168,9 @@ class DocType: self.validate_with_timesheet_dates() self.validate_for_closed() self.doc.closing_date = nowdate() - set(self.doc, 'status', 'Closed') + self.doc.status = 'Closed' self.remove_event_from_calender() - set(self.doc, 'docstatus', 1) + self.doc.docstatus = 1 self.doc.save() return cstr('true') From cc64682baaff4f7688008a7cbe1d6f2e63b86416 Mon Sep 17 00:00:00 2001 From: Nijil Y Date: Fri, 23 Dec 2011 17:35:18 +0530 Subject: [PATCH 10/23] fixed --- .../project_control/project_control.py | 36 +++++++++++-------- erpnext/projects/doctype/ticket/ticket.py | 4 ++- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/erpnext/projects/doctype/project_control/project_control.py b/erpnext/projects/doctype/project_control/project_control.py index 92ed64b3892..42a9ba3d629 100644 --- a/erpnext/projects/doctype/project_control/project_control.py +++ b/erpnext/projects/doctype/project_control/project_control.py @@ -117,20 +117,26 @@ class DocType: 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) - msgprint(task_list) - for i in task_list: - if date_diff(i['exp_start_date'],nowdate())==2: - msgprint(i['exp_start_date']) - msgprint(add_days(nowdate(),2)) - msg2="""This is an auto generated email.

This is a reminder for the task %s has been assigned \ - to you by %s on %s

Project: %s

Review Date: %s \ -

Details: %s

The expected start date of this task is on %s """ \ - %(i['name'], i['senders_name'], i['opening_date'], i['project'], i['review_date'], i['description'], i['exp_start_date']) - sendmail(i['allocated_to'], sender='automail@webnotestech.com', msg=msg2,send_now=1,\ + 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="""

Two days to complete: %(name)s

+

This is a reminder for the task %(name)s has been assigned to you + by %(senders_name)s on %(opening_date)s

+

Project: %(project)s

+

Review Date: %(review_date)s

+

Details: %(description)s

+

If you have already completed this task, please update the system

+

Good Luck!

+

(This notification is autogenerated)

""" % i + sendmail(i['allocated_to'], sender='automail@webnotestech.com', msg=msg2,send_now=1, \ subject='A task has been assigned') - i['sent_reminder']=1 + sql("update `tabTicket` set sent_reminder='1' where name='%(name)s' and allocated_to= '%(allocated_to)s'" % i) diff --git a/erpnext/projects/doctype/ticket/ticket.py b/erpnext/projects/doctype/ticket/ticket.py index b1ecf04af0f..5f299c337c6 100644 --- a/erpnext/projects/doctype/ticket/ticket.py +++ b/erpnext/projects/doctype/ticket/ticket.py @@ -74,6 +74,7 @@ class DocType: if self.doc.task_email_notify and (self.doc.allocated_to != self.doc.allocated_to_old): self.doc.allocated_to_old = self.doc.allocated_to self.sent_notification() + self.doc.sent_reminder = 0 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() @@ -96,7 +97,8 @@ class DocType: self.doc.project, self.doc.review_date, self.doc.closing_date, self.doc.description) sendmail(self.doc.allocated_to, sender='automail@webnotestech.com', msg=msg2,send_now=1,\ subject='A task has been assigned') - self.doc.sent_reminder=0 + + #validate before closing task def validate_for_closed(self): From 0cfecf29203bb2bc907f151bb091824d4d949cb5 Mon Sep 17 00:00:00 2001 From: Nijil Y Date: Fri, 23 Dec 2011 17:54:07 +0530 Subject: [PATCH 11/23] email message fix for task --- .../doctype/project_control/project_control.py | 2 +- erpnext/projects/doctype/ticket/ticket.py | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/erpnext/projects/doctype/project_control/project_control.py b/erpnext/projects/doctype/project_control/project_control.py index 42a9ba3d629..6d41ea95dc0 100644 --- a/erpnext/projects/doctype/project_control/project_control.py +++ b/erpnext/projects/doctype/project_control/project_control.py @@ -127,7 +127,7 @@ def sent_reminder_task(): 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="""

Two days to complete: %(name)s

+ msg2="""

Two days to complete: %(name)s

This is a reminder for the task %(name)s has been assigned to you by %(senders_name)s on %(opening_date)s

Project: %(project)s

diff --git a/erpnext/projects/doctype/ticket/ticket.py b/erpnext/projects/doctype/ticket/ticket.py index 5f299c337c6..b4f1a709231 100644 --- a/erpnext/projects/doctype/ticket/ticket.py +++ b/erpnext/projects/doctype/ticket/ticket.py @@ -72,9 +72,9 @@ class DocType: 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() - self.doc.sent_reminder = 0 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() @@ -91,10 +91,15 @@ class DocType: #Sent Notification def sent_notification(self): - msg2="""This is an auto generated email.
A task %s has been assigned to you by %s on %s

\ - Project: %s

Review Date: %s

Closing Date: %s

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) + msg2="""

%(name)s

+

This is a Notification for the task %(name)s that has been assigned to you + by %(senders_name)s on %(opening_date)s

+

Project: %(project)s

+

Review Date: %(review_date)s

+

Details: %(description)s

+

You will also recieve another reminder 2 days before the commencement of the task

+

Good Luck!

+

(This notification is autogenerated)

""" % i sendmail(self.doc.allocated_to, sender='automail@webnotestech.com', msg=msg2,send_now=1,\ subject='A task has been assigned') From a4e8d1e98363099240bbf6eb62e34dcbded1d970 Mon Sep 17 00:00:00 2001 From: Nijil Y Date: Fri, 23 Dec 2011 18:01:40 +0530 Subject: [PATCH 12/23] . --- erpnext/projects/doctype/ticket/ticket.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/projects/doctype/ticket/ticket.py b/erpnext/projects/doctype/ticket/ticket.py index b4f1a709231..5cd19283eb9 100644 --- a/erpnext/projects/doctype/ticket/ticket.py +++ b/erpnext/projects/doctype/ticket/ticket.py @@ -97,7 +97,7 @@ class DocType:

Project: %(project)s

Review Date: %(review_date)s

Details: %(description)s

-

You will also recieve another reminder 2 days before the commencement of the task

+

You will also recieve another reminder 2 days before the commencement of the task

Good Luck!

(This notification is autogenerated)

""" % i sendmail(self.doc.allocated_to, sender='automail@webnotestech.com', msg=msg2,send_now=1,\ From 382dc6e8195a48315c6f5e0e75a93c7c2357bad6 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 23 Dec 2011 18:25:11 +0530 Subject: [PATCH 13/23] GL Mapper changes for JV --- erpnext/accounts/GL Mapper/Journal Voucher/Journal Voucher.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/GL Mapper/Journal Voucher/Journal Voucher.txt b/erpnext/accounts/GL Mapper/Journal Voucher/Journal Voucher.txt index b4a8cf6b9ab..fac38319799 100644 --- a/erpnext/accounts/GL Mapper/Journal Voucher/Journal Voucher.txt +++ b/erpnext/accounts/GL Mapper/Journal Voucher/Journal Voucher.txt @@ -1 +1 @@ -[{'doc_type': 'Journal Voucher', 'modified_by': 'nabin@webnotestech.com', 'name': 'Journal Voucher', 'parent': None, 'creation': '2009-03-12 12:09:24', 'modified': '2010-04-30 17:56:41', 'module': 'Accounts', 'doctype': 'GL Mapper', 'idx': None, 'parenttype': None, 'owner': 'Administrator', 'docstatus': 0, 'parentfield': None}, {'creation': '2009-03-12 12:09:24', 'voucher_type': 'parent:doctype', 'doctype': 'GL Mapper Detail', 'owner': 'Administrator', 'cost_center': 'cost_center', 'voucher_no': 'parent:name', 'modified_by': 'nabin@webnotestech.com', 'against_voucher': "value:d.against_voucher or d.against_invoice or ''", 'table_field': 'entries', 'transaction_date': 'parent:voucher_date', 'debit': 'debit', 'docstatus': 0, 'parent': 'Journal Voucher', 'company': 'parent:company', 'aging_date': 'parent:aging_date', 'fiscal_year': 'parent:fiscal_year', 'is_advance': 'is_advance', 'remarks': 'parent:remark', 'account': 'account', 'name': 'GLMDetail00001', 'idx': 1, 'against_voucher_type': "value:(d.against_voucher and 'Payable Voucher') or (d.against_invoice and 'Receivable Voucher') or ''", 'modified': '2010-04-30 17:56:41', 'against': 'against_account', 'credit': 'credit', 'parenttype': 'GL Mapper', 'is_opening': 'parent:is_opening', 'posting_date': 'parent:posting_date', 'parentfield': 'fields'}, {'creation': '2009-06-11 11:09:11', 'voucher_type': 'doctype', 'doctype': 'GL Mapper Detail', 'owner': 'Administrator', 'cost_center': '', 'voucher_no': 'name', 'modified_by': 'nabin@webnotestech.com', 'against_voucher': '', 'table_field': '', 'transaction_date': 'voucher_date', 'debit': 'value:0', 'docstatus': 0, 'parent': 'Journal Voucher', 'company': 'company', 'aging_date': 'aging_date', 'fiscal_year': 'fiscal_year', 'is_advance': '', 'remarks': 'remark', 'account': 'tax_code', 'name': 'GLMDetail00009', 'idx': 2, 'against_voucher_type': None, 'modified': '2010-04-30 17:56:41', 'against': 'supplier_account', 'credit': 'ded_amount', 'parenttype': 'GL Mapper', 'is_opening': 'is_opening', 'posting_date': 'posting_date', 'parentfield': 'fields'}] \ No newline at end of file +[{'doc_type': 'Journal Voucher', 'modified_by': 'nabin@webnotestech.com', 'name': 'Journal Voucher', 'parent': None, 'creation': '2009-03-12 12:09:24', 'modified': '2010-04-30 17:56:41', 'module': 'Accounts', 'doctype': 'GL Mapper', 'idx': None, 'parenttype': None, 'owner': 'Administrator', 'docstatus': 0, 'parentfield': None}, {'creation': '2009-03-12 12:09:24', 'voucher_type': 'parent:doctype', 'doctype': 'GL Mapper Detail', 'owner': 'Administrator', 'cost_center': 'cost_center', 'voucher_no': 'parent:name', 'modified_by': 'nabin@webnotestech.com', 'against_voucher': "value:d.against_voucher or d.against_invoice or d.against_jv or ''", 'table_field': 'entries', 'transaction_date': 'parent:voucher_date', 'debit': 'debit', 'docstatus': 0, 'parent': 'Journal Voucher', 'company': 'parent:company', 'aging_date': 'parent:aging_date', 'fiscal_year': 'parent:fiscal_year', 'is_advance': 'is_advance', 'remarks': 'parent:remark', 'account': 'account', 'name': 'GLMDetail00001', 'idx': 1, 'against_voucher_type': "value:(d.against_voucher and 'Payable Voucher') or (d.against_invoice and 'Receivable Voucher') or (d.against_jv and 'Journal Voucher') or ''", 'modified': '2010-04-30 17:56:41', 'against': 'against_account', 'credit': 'credit', 'parenttype': 'GL Mapper', 'is_opening': 'parent:is_opening', 'posting_date': 'parent:posting_date', 'parentfield': 'fields'}, {'creation': '2009-06-11 11:09:11', 'voucher_type': 'doctype', 'doctype': 'GL Mapper Detail', 'owner': 'Administrator', 'cost_center': '', 'voucher_no': 'name', 'modified_by': 'nabin@webnotestech.com', 'against_voucher': '', 'table_field': '', 'transaction_date': 'voucher_date', 'debit': 'value:0', 'docstatus': 0, 'parent': 'Journal Voucher', 'company': 'company', 'aging_date': 'aging_date', 'fiscal_year': 'fiscal_year', 'is_advance': '', 'remarks': 'remark', 'account': 'tax_code', 'name': 'GLMDetail00009', 'idx': 2, 'against_voucher_type': None, 'modified': '2010-04-30 17:56:41', 'against': 'supplier_account', 'credit': 'ded_amount', 'parenttype': 'GL Mapper', 'is_opening': 'is_opening', 'posting_date': 'posting_date', 'parentfield': 'fields'}] From c6359a9179c2c5f49b163b0b9a4fb5762b28b4d1 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 23 Dec 2011 18:26:17 +0530 Subject: [PATCH 14/23] Patch to update against_voucher in gle for jv aganst jv --- .../update_gle_against_voucher_for_jv.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 erpnext/patches/update_gle_against_voucher_for_jv.py diff --git a/erpnext/patches/update_gle_against_voucher_for_jv.py b/erpnext/patches/update_gle_against_voucher_for_jv.py new file mode 100644 index 00000000000..3da8dec2efb --- /dev/null +++ b/erpnext/patches/update_gle_against_voucher_for_jv.py @@ -0,0 +1,18 @@ +def execute(): + import webnotes + from webnotes.modules.module_manager import reload_doc + + # reload jv gl mapper + reload_doc('accounts', 'GL Mapper', 'Journal Voucher') + + # select jv where against_jv exists + jv = webnotes.conn.sql("select distinct parent from `tabJournal Voucher Detail` where docstatus = 1 and ifnull(against_jv, '') != ''") + + for d in jv: + jv_obj = get_obj('Journal Voucher', d.journal_voucher, with_children=1) + + # cancel + get_obj(dt='GL Control').make_gl_entries(jv_obj.doc, jv_obj.doclist, cancel =1, adv_adj = 1) + + #re-submit + get_obj(dt='GL Control').make_gl_entries(jv_obj.doc, jv_obj.doclist, cancel =0, adv_adj = 1) From a0286e986e918e3ff742d5abec304aa9345dd12e Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 26 Dec 2011 11:08:32 +0530 Subject: [PATCH 15/23] patch updated --- erpnext/patches/update_gle_against_voucher_for_jv.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/patches/update_gle_against_voucher_for_jv.py b/erpnext/patches/update_gle_against_voucher_for_jv.py index 3da8dec2efb..7dc5a0b38d6 100644 --- a/erpnext/patches/update_gle_against_voucher_for_jv.py +++ b/erpnext/patches/update_gle_against_voucher_for_jv.py @@ -9,7 +9,7 @@ def execute(): jv = webnotes.conn.sql("select distinct parent from `tabJournal Voucher Detail` where docstatus = 1 and ifnull(against_jv, '') != ''") for d in jv: - jv_obj = get_obj('Journal Voucher', d.journal_voucher, with_children=1) + jv_obj = get_obj('Journal Voucher', d[0], with_children=1) # cancel get_obj(dt='GL Control').make_gl_entries(jv_obj.doc, jv_obj.doclist, cancel =1, adv_adj = 1) From f7e1569207e2b251021f8b7149532589ac9798e3 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 26 Dec 2011 11:08:55 +0530 Subject: [PATCH 16/23] ticket.py modified --- erpnext/projects/doctype/ticket/ticket.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/erpnext/projects/doctype/ticket/ticket.py b/erpnext/projects/doctype/ticket/ticket.py index 5cd19283eb9..e2310886a56 100644 --- a/erpnext/projects/doctype/ticket/ticket.py +++ b/erpnext/projects/doctype/ticket/ticket.py @@ -174,16 +174,17 @@ class DocType: 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() + + self.remove_event_from_calender() 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) @@ -200,6 +201,7 @@ class DocType: def add_calendar_event(self): + """ Add calendar event for task in calendar of Allocated person""" event = Document('Event') event.owner = self.doc.allocated_to event.description ='' @@ -209,4 +211,3 @@ class DocType: event.ref_type = 'Task' event.ref_name = self.doc.name event.save(1) - From cf0163d09e8ce9075fe0b31711222cbddee432ea Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 26 Dec 2011 11:13:49 +0530 Subject: [PATCH 17/23] Patch updated --- erpnext/patches/update_gle_against_voucher_for_jv.py | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/patches/update_gle_against_voucher_for_jv.py b/erpnext/patches/update_gle_against_voucher_for_jv.py index 7dc5a0b38d6..96401ba2b87 100644 --- a/erpnext/patches/update_gle_against_voucher_for_jv.py +++ b/erpnext/patches/update_gle_against_voucher_for_jv.py @@ -1,6 +1,7 @@ def execute(): import webnotes from webnotes.modules.module_manager import reload_doc + from webnotes.model.code import get_obj # reload jv gl mapper reload_doc('accounts', 'GL Mapper', 'Journal Voucher') From 16aacdfeeb38dc717a3677a14a291d3b355c24b1 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 26 Dec 2011 11:37:52 +0530 Subject: [PATCH 18/23] Error fixed in ticket --- erpnext/projects/doctype/ticket/ticket.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/erpnext/projects/doctype/ticket/ticket.py b/erpnext/projects/doctype/ticket/ticket.py index e2310886a56..8ef8fb9bf1a 100644 --- a/erpnext/projects/doctype/ticket/ticket.py +++ b/erpnext/projects/doctype/ticket/ticket.py @@ -91,6 +91,15 @@ class DocType: #Sent Notification def sent_notification(self): + i = { + 'name' : self.doc.name, + 'senders_name': self.doc.allocated_to, + 'opening_date': self.doc.exp_start_date, + 'project': self.doc.project, + 'review_date': self.doc.review_date, + 'description': self.doc.description + } + msg2="""

%(name)s

This is a Notification for the task %(name)s that has been assigned to you by %(senders_name)s on %(opening_date)s

From 2a59030e05d4693793e55cc0ffaa772c71f5a389 Mon Sep 17 00:00:00 2001 From: Nijil Y Date: Mon, 26 Dec 2011 12:00:30 +0530 Subject: [PATCH 19/23] task notification fix --- .../project_control/project_control.py | 2 +- erpnext/projects/doctype/ticket/ticket.py | 4 ++-- erpnext/projects/doctype/ticket/ticket.txt | 24 +++++++++---------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/erpnext/projects/doctype/project_control/project_control.py b/erpnext/projects/doctype/project_control/project_control.py index 6d41ea95dc0..68361b2b5e8 100644 --- a/erpnext/projects/doctype/project_control/project_control.py +++ b/erpnext/projects/doctype/project_control/project_control.py @@ -137,6 +137,6 @@ def sent_reminder_task():

Good Luck!

(This notification is autogenerated)

""" % i sendmail(i['allocated_to'], sender='automail@webnotestech.com', msg=msg2,send_now=1, \ - subject='A task has been assigned') + subject='A task has been assigned') sql("update `tabTicket` set sent_reminder='1' where name='%(name)s' and allocated_to= '%(allocated_to)s'" % i) diff --git a/erpnext/projects/doctype/ticket/ticket.py b/erpnext/projects/doctype/ticket/ticket.py index 8ef8fb9bf1a..620bc50bdcd 100644 --- a/erpnext/projects/doctype/ticket/ticket.py +++ b/erpnext/projects/doctype/ticket/ticket.py @@ -110,7 +110,7 @@ class DocType:

Good Luck!

(This notification is autogenerated)

""" % i sendmail(self.doc.allocated_to, sender='automail@webnotestech.com', msg=msg2,send_now=1,\ - subject='A task has been assigned') + subject='A task has been assigned') @@ -213,7 +213,7 @@ class DocType: """ Add calendar event for task in calendar of Allocated person""" event = Document('Event') event.owner = self.doc.allocated_to - event.description ='' + event.description = self.doc.name 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' diff --git a/erpnext/projects/doctype/ticket/ticket.txt b/erpnext/projects/doctype/ticket/ticket.txt index a1ac330e1d3..5b8da14111d 100644 --- a/erpnext/projects/doctype/ticket/ticket.txt +++ b/erpnext/projects/doctype/ticket/ticket.txt @@ -5,14 +5,14 @@ { 'creation': '2011-01-28 17:52:35', 'docstatus': 0, - 'modified': '2011-12-23 12:02:29', + 'modified': '2011-12-26 11:56:35', 'modified_by': 'Administrator', 'owner': 'Administrator' }, # These values are common for all DocType { - '_last_update': '1324619022', + '_last_update': '1324880734', 'allow_trash': 1, 'autoname': 'TIC/.####', 'colour': 'White:FFF', @@ -26,7 +26,7 @@ 'show_in_menu': 0, 'subject': '%(subject)s', 'tag_fields': 'status', - 'version': 252 + 'version': 254 }, # These values are common for all DocField @@ -137,15 +137,6 @@ 'trigger': 'Client' }, - # DocField - { - 'doctype': 'DocField', - 'fieldname': 'task_email_notify', - 'fieldtype': 'Check', - 'label': 'Sent Mail Notification', - 'permlevel': 0 - }, - # DocField { 'doctype': 'DocField', @@ -274,6 +265,15 @@ 'trigger': 'Client' }, + # DocField + { + 'doctype': 'DocField', + 'fieldname': 'task_email_notify', + 'fieldtype': 'Check', + 'label': 'Sent Mail Notification', + 'permlevel': 0 + }, + # DocField { 'doctype': 'DocField', From a0778fec613155c371ca58221e9300b753231b11 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 26 Dec 2011 12:28:14 +0530 Subject: [PATCH 20/23] Reload gl mapper patches --- erpnext/patches/reload_gl_mapper.py | 6 ++++++ erpnext/patches/update_gle_against_voucher_for_jv.py | 4 ---- 2 files changed, 6 insertions(+), 4 deletions(-) create mode 100644 erpnext/patches/reload_gl_mapper.py diff --git a/erpnext/patches/reload_gl_mapper.py b/erpnext/patches/reload_gl_mapper.py new file mode 100644 index 00000000000..edb00bce691 --- /dev/null +++ b/erpnext/patches/reload_gl_mapper.py @@ -0,0 +1,6 @@ +def execute(): + import webnotes + from webnotes.modules.module_manager import reload_doc + + # reload jv gl mapper + reload_doc('accounts', 'GL Mapper', 'Journal Voucher') diff --git a/erpnext/patches/update_gle_against_voucher_for_jv.py b/erpnext/patches/update_gle_against_voucher_for_jv.py index 96401ba2b87..5a03ec799c4 100644 --- a/erpnext/patches/update_gle_against_voucher_for_jv.py +++ b/erpnext/patches/update_gle_against_voucher_for_jv.py @@ -1,11 +1,7 @@ def execute(): import webnotes - from webnotes.modules.module_manager import reload_doc from webnotes.model.code import get_obj - # reload jv gl mapper - reload_doc('accounts', 'GL Mapper', 'Journal Voucher') - # select jv where against_jv exists jv = webnotes.conn.sql("select distinct parent from `tabJournal Voucher Detail` where docstatus = 1 and ifnull(against_jv, '') != ''") From 68de3687f4dd63584c3ef52c6e54d2489b7a57e3 Mon Sep 17 00:00:00 2001 From: Nijil Y Date: Mon, 26 Dec 2011 15:24:55 +0530 Subject: [PATCH 21/23] added fields --- erpnext/projects/doctype/ticket/ticket.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/erpnext/projects/doctype/ticket/ticket.py b/erpnext/projects/doctype/ticket/ticket.py index 620bc50bdcd..4dbcfe78de9 100644 --- a/erpnext/projects/doctype/ticket/ticket.py +++ b/erpnext/projects/doctype/ticket/ticket.py @@ -94,7 +94,9 @@ class DocType: i = { 'name' : self.doc.name, 'senders_name': self.doc.allocated_to, - 'opening_date': self.doc.exp_start_date, + 'opening_date': self.doc.opening_date, + 'exp_start_date': self.doc.exp_start_date, + 'exp_end_date' : self.doc.exp_end_date, 'project': self.doc.project, 'review_date': self.doc.review_date, 'description': self.doc.description @@ -105,6 +107,8 @@ class DocType: by %(senders_name)s on %(opening_date)s

Project: %(project)s

Review Date: %(review_date)s

+

Expected Start Date: %(exp_start_date)s

+

Expected End Date: %(exp_end_date)s

Details: %(description)s

You will also recieve another reminder 2 days before the commencement of the task

Good Luck!

From 04eb52dbe310f1b05fc87cd8b0da96a55d628fc3 Mon Sep 17 00:00:00 2001 From: Nijil Y Date: Mon, 26 Dec 2011 15:30:45 +0530 Subject: [PATCH 22/23] added fields --- erpnext/projects/doctype/project_control/project_control.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/erpnext/projects/doctype/project_control/project_control.py b/erpnext/projects/doctype/project_control/project_control.py index 68361b2b5e8..4b382a555dd 100644 --- a/erpnext/projects/doctype/project_control/project_control.py +++ b/erpnext/projects/doctype/project_control/project_control.py @@ -131,6 +131,8 @@ def sent_reminder_task():

This is a reminder for the task %(name)s has been assigned to you by %(senders_name)s on %(opening_date)s

Project: %(project)s

+

Expected Start Date: %(exp_start_date)s

+

Expected End Date: %(exp_end_date)s

Review Date: %(review_date)s

Details: %(description)s

If you have already completed this task, please update the system

From 3029474b0ef79ed02eaf6e00e5053bc34214c369 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 27 Dec 2011 16:42:03 +0530 Subject: [PATCH 23/23] Fixes in recurring invoice --- .../receivable_voucher/receivable_voucher.py | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.py b/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.py index 9e4baa18ca7..536bb6d8ccf 100644 --- a/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.py +++ b/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.py @@ -645,30 +645,36 @@ class DocType(TransactionBase): ######################################################################## # Repair Outstanding -####################################################################### + def repair_rv_outstanding(self): get_obj(dt = 'GL Control').repair_voucher_outstanding(self) + + #------------------------------------------------------------------------------------- def on_update_after_submit(self): self.convert_into_recurring() def convert_into_recurring(self): if self.doc.convert_into_recurring_invoice: - event = 'accounts.doctype.gl_control.gl_control.manage_recurring_invoices' self.set_next_date() if not self.doc.recurring_id: set(self.doc, 'recurring_id', make_autoname('RECINV/.#####')) - - if sql("select name from `tabReceivable Voucher` where ifnull(convert_into_recurring_invoice, 0) = 1 and next_date <= end_date"): - if not self.check_event_exists(event): - set_event(event, interval = 60*60, recurring = 1) - else: - cancel_event(event) - elif self.doc.recurring_id: sql("""update `tabReceivable Voucher` set convert_into_recurring_invoice = 0 where recurring_id = %s""", self.doc.recurring_id) + self.manage_scheduler() + + def manage_scheduler(self): + """ set/cancel event in scheduler """ + event = 'accounts.doctype.gl_control.gl_control.manage_recurring_invoices' + + if sql("select name from `tabReceivable Voucher` where ifnull(convert_into_recurring_invoice, 0) = 1 and next_date <= end_date"): + if not self.check_event_exists(event): + set_event(event, interval = 60*60, recurring = 1) + else: + cancel_event(event) + def check_event_exists(self, event): try: