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: