Merge branch 'master' of github.com:webnotes/erpnext
diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py
index b6fb9a8..3db66f0 100644
--- a/erpnext/projects/doctype/project/project.py
+++ b/erpnext/projects/doctype/project/project.py
@@ -8,11 +8,11 @@
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Please edit this list and import only required elements
import webnotes
@@ -34,59 +34,78 @@
class DocType:
- def __init__(self, doc, doclist=[]):
- self.doc = doc
- self.doclist = doclist
-
- # Get Customer Details along with its primary contact details
- # ==============================================================
- def get_customer_details(self):
- details =sql("select address, territory, customer_group,customer_name from `tabCustomer` where name=%s and docstatus!=2",(self.doc.customer),as_dict=1)
- if details:
- ret = {
- 'customer_address' : details and details[0]['address'] or '',
- 'territory' : details and details[0]['territory'] or '',
- 'customer_group' : details and details[0]['customer_group'] or '',
- 'customer_name' : details and details[0]['customer_name'] or ''
- }
- #get primary contact details(this is done separately coz. , if join query used & no primary contact thn it would not be able to fetch customer details)
- contact_det = sql("select contact_name, phone, email_id from `tabContact` where customer_name='%s' and is_customer=1 and is_primary_contact=1 and docstatus!=2" %(self.doc.customer), as_dict = 1)
- ret['contact_person'] = contact_det and contact_det[0]['contact_name'] or ''
- ret['contact_no'] = contact_det and contact_det[0]['phone'] or ''
- ret['email_id'] = contact_det and contact_det[0]['email_id'] or ''
- return ret
- else:
- msgprint("Customer : %s does not exist in system." % (self.doc.customer))
- raise Exception
-
- # Get customer's contact person details
- # ==============================================================
- def get_contact_details(self):
- contact = sql("select contact_no, email_id from `tabContact` where contact_name = '%s' and customer_name = '%s' and docstatus != 2" %(self.doc,contact_person,self.doc.customer), as_dict=1)
- if contact:
- ret = {
- 'contact_no' : contact and contact[0]['contact_no'] or '',
- 'email_id' : contact and contact[0]['email_id'] or ''
- }
- return ret
- else:
- msgprint("Contact Person : %s does not exist in the system." % (self.doc,contact_person))
- raise Exception
-
- #calculate gross profit
- #=============================================
- def get_gross_profit(self):
- pft, per_pft =0, 0
- pft = flt(self.doc.project_value) - flt(self.doc.est_material_cost)
- #if pft > 0:
- per_pft = (flt(pft) / flt(self.doc.project_value)) * 100
- ret = {'gross_margin_value': pft, 'per_gross_margin': per_pft}
- return ret
-
- # validate
- #================================================
- def validate(self):
- if self.doc.project_start_date and self.doc.completion_date:
- if getdate(self.doc.completion_date) < getdate(self.doc.project_start_date):
- msgprint("Expected Completion Date can not be less than Project Start Date")
- raise Exception
+ def __init__(self, doc, doclist=[]):
+ self.doc = doc
+ self.doclist = doclist
+
+ # Get Customer Details along with its primary contact details
+ # ==============================================================
+ def get_customer_details(self):
+ details =sql("select address, territory, customer_group,customer_name from `tabCustomer` where name=%s and docstatus!=2",(self.doc.customer),as_dict=1)
+ if details:
+ ret = {
+ 'customer_address' : details and details[0]['address'] or '',
+ 'territory' : details and details[0]['territory'] or '',
+ 'customer_group' : details and details[0]['customer_group'] or '',
+ 'customer_name' : details and details[0]['customer_name'] or ''
+ }
+ #get primary contact details(this is done separately coz. , if join query used & no primary contact thn it would not be able to fetch customer details)
+ contact_det = sql("select contact_name, phone, email_id from `tabContact` where customer_name='%s' and is_customer=1 and is_primary_contact=1 and docstatus!=2" %(self.doc.customer), as_dict = 1)
+ ret['contact_person'] = contact_det and contact_det[0]['contact_name'] or ''
+ ret['contact_no'] = contact_det and contact_det[0]['phone'] or ''
+ ret['email_id'] = contact_det and contact_det[0]['email_id'] or ''
+ return ret
+ else:
+ msgprint("Customer : %s does not exist in system." % (self.doc.customer))
+ raise Exception
+
+ # Get customer's contact person details
+ # ==============================================================
+ def get_contact_details(self):
+ contact = sql("select contact_no, email_id from `tabContact` where contact_name = '%s' and customer_name = '%s' and docstatus != 2" %(self.doc,contact_person,self.doc.customer), as_dict=1)
+ if contact:
+ ret = {
+ 'contact_no' : contact and contact[0]['contact_no'] or '',
+ 'email_id' : contact and contact[0]['email_id'] or ''
+ }
+ return ret
+ else:
+ msgprint("Contact Person : %s does not exist in the system." % (self.doc,contact_person))
+ raise Exception
+
+ #calculate gross profit
+ #=============================================
+ def get_gross_profit(self):
+ pft, per_pft =0, 0
+ pft = flt(self.doc.project_value) - flt(self.doc.est_material_cost)
+ #if pft > 0:
+ per_pft = (flt(pft) / flt(self.doc.project_value)) * 100
+ ret = {'gross_margin_value': pft, 'per_gross_margin': per_pft}
+ return ret
+
+ # validate
+ #================================================
+ def validate(self):
+ if self.doc.project_start_date and self.doc.completion_date:
+ if getdate(self.doc.completion_date) < getdate(self.doc.project_start_date):
+ msgprint("Expected Completion Date can not be less than Project Start Date")
+ raise Exception
+
+ def on_update(self):
+ # update milestones
+ webnotes.conn.sql("""delete from tabEvent where ref_type='Project' and ref_name=%s""",
+ self.doc.name)
+ for d in self.doclist:
+ if d.doctype=='Project Milestone' and d.docstatus!=2:
+ self.add_calendar_event(d.milestone, d.milestone_date)
+
+ def add_calendar_event(self, milestone, date):
+ """ Add calendar event for task in calendar of Allocated person"""
+ event = Document('Event')
+ event.description = milestone + ' for ' + self.doc.name
+ event.event_date = date
+ event.event_hour = '10:00'
+ event.event_type = 'Public'
+ event.ref_type = 'Project'
+ event.ref_name = self.doc.name
+ event.save(1)
\ No newline at end of file
diff --git a/erpnext/projects/doctype/project/project.txt b/erpnext/projects/doctype/project/project.txt
index 527201e..43cab39 100644
--- a/erpnext/projects/doctype/project/project.txt
+++ b/erpnext/projects/doctype/project/project.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-03-27 14:36:05',
+ 'creation': '2012-05-03 18:41:42',
'docstatus': 0,
- 'modified': '2012-03-27 14:36:05',
+ 'modified': '2012-08-07 15:48:47',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -29,7 +29,7 @@
'show_in_menu': 0,
'subject': u' ',
'tag_fields': u'status',
- 'version': 33
+ 'version': 1
},
# These values are common for all DocField
@@ -43,12 +43,17 @@
# These values are common for all DocPerm
{
+ 'cancel': 1,
+ 'create': 1,
'doctype': u'DocPerm',
'name': '__common__',
'parent': u'Project',
'parentfield': u'permissions',
'parenttype': u'DocType',
- 'read': 1
+ 'permlevel': 0,
+ 'read': 1,
+ 'role': u'Projects User',
+ 'write': 1
},
# DocType, Project
@@ -59,33 +64,7 @@
# DocPerm
{
- 'amend': 0,
- 'cancel': 1,
- 'create': 1,
- 'doctype': u'DocPerm',
- 'permlevel': 0,
- 'role': u'All',
- 'submit': 0,
- 'write': 1
- },
-
- # DocPerm
- {
- 'amend': 0,
- 'cancel': 1,
- 'create': 1,
- 'doctype': u'DocPerm',
- 'permlevel': 0,
- 'role': u'Projects User',
- 'submit': 0,
- 'write': 1
- },
-
- # DocPerm
- {
- 'doctype': u'DocPerm',
- 'permlevel': 1,
- 'role': u'All'
+ 'doctype': u'DocPerm'
},
# DocField
@@ -102,6 +81,15 @@
# DocField
{
+ 'doctype': u'DocField',
+ 'fieldname': u'cb_project_status',
+ 'fieldtype': u'Column Break',
+ 'label': u'Status',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
'description': u'Project will get saved and will be searchable with project name given',
'doctype': u'DocField',
'fieldname': u'project_name',
@@ -163,71 +151,10 @@
# DocField
{
'doctype': u'DocField',
- 'fieldname': u'project_value',
- 'fieldtype': u'Currency',
- 'label': u'Project Value',
- 'no_copy': 0,
- 'oldfieldname': u'project_value',
- 'oldfieldtype': u'Currency',
- 'permlevel': 0,
- 'reqd': 1,
- 'search_index': 0,
- 'trigger': u'Client'
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'gross_margin_value',
- 'fieldtype': u'Currency',
- 'label': u'Gross Margin Value',
- 'no_copy': 0,
- 'oldfieldname': u'gross_margin_value',
- 'oldfieldtype': u'Currency',
- 'permlevel': 0,
- 'reqd': 1,
- 'search_index': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'per_gross_margin',
- 'fieldtype': u'Currency',
- 'label': u'Gross Margin %',
- 'no_copy': 0,
- 'oldfieldname': u'per_gross_margin',
- 'oldfieldtype': u'Currency',
- 'permlevel': 0,
- 'reqd': 1,
- 'search_index': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'est_material_cost',
- 'fieldtype': u'Currency',
- 'label': u'Estimated Material Cost',
- 'no_copy': 0,
- 'oldfieldname': u'est_material_cost',
- 'oldfieldtype': u'Currency',
- 'permlevel': 0,
- 'search_index': 0,
- 'trigger': u'Client'
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'project_type',
- 'fieldtype': u'Data',
- 'label': u'Project Type',
- 'no_copy': 0,
- 'oldfieldname': u'project_type',
- 'oldfieldtype': u'Data',
- 'permlevel': 0,
- 'search_index': 0
+ 'fieldname': u'cb_project_dates',
+ 'fieldtype': u'Column Break',
+ 'label': u'Dates',
+ 'permlevel': 0
},
# DocField
@@ -273,51 +200,41 @@
# DocField
{
'doctype': u'DocField',
- 'fieldname': u'amended_from',
- 'fieldtype': u'Data',
- 'hidden': 1,
- 'label': u'Amended From',
- 'no_copy': 1,
- 'oldfieldname': u'amended_from',
+ 'fieldname': u'project_type',
+ 'fieldtype': u'Select',
+ 'label': u'Project Type',
+ 'no_copy': 0,
+ 'oldfieldname': u'project_type',
'oldfieldtype': u'Data',
- 'permlevel': 1,
- 'print_hide': 0,
+ 'options': u'Internal\nExternal\nOther',
+ 'permlevel': 0,
'search_index': 0
},
# DocField
{
+ 'colour': u'White:FFF',
+ 'description': u'Important dates and commitments in your project life cycle',
'doctype': u'DocField',
- 'fieldname': u'amemdment_date',
- 'fieldtype': u'Date',
- 'hidden': 1,
- 'label': u'Amemdment Date',
- 'no_copy': 1,
- 'oldfieldname': u'amemdment_date',
- 'oldfieldtype': u'Date',
- 'permlevel': 1,
- 'search_index': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'project_details',
+ 'fieldname': u'sb_milestones',
'fieldtype': u'Section Break',
- 'label': u'Project Details',
+ 'label': u'Milestones',
'oldfieldtype': u'Section Break',
- 'options': u'Simple',
'permlevel': 0
},
# DocField
{
'doctype': u'DocField',
- 'fieldname': u'column_break0',
- 'fieldtype': u'Column Break',
- 'oldfieldtype': u'Column Break',
+ 'fieldname': u'project_milestones',
+ 'fieldtype': u'Table',
+ 'label': u'Project Milestones',
+ 'no_copy': 0,
+ 'oldfieldname': u'project_milestones',
+ 'oldfieldtype': u'Table',
+ 'options': u'Project Milestone',
'permlevel': 0,
- 'width': u'50%'
+ 'search_index': 0
},
# DocField
@@ -325,6 +242,7 @@
'doctype': u'DocField',
'fieldname': u'section_break0',
'fieldtype': u'Section Break',
+ 'label': u'Project Details',
'oldfieldtype': u'Section Break',
'options': u'Simple',
'permlevel': 0
@@ -346,6 +264,85 @@
# DocField
{
'doctype': u'DocField',
+ 'fieldname': u'project_details',
+ 'fieldtype': u'Section Break',
+ 'label': u'Project Costing',
+ 'oldfieldtype': u'Section Break',
+ 'options': u'Simple',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'project_value',
+ 'fieldtype': u'Currency',
+ 'label': u'Project Value',
+ 'no_copy': 0,
+ 'oldfieldname': u'project_value',
+ 'oldfieldtype': u'Currency',
+ 'permlevel': 0,
+ 'reqd': 1,
+ 'search_index': 0,
+ 'trigger': u'Client'
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'est_material_cost',
+ 'fieldtype': u'Currency',
+ 'label': u'Estimated Material Cost',
+ 'no_copy': 0,
+ 'oldfieldname': u'est_material_cost',
+ 'oldfieldtype': u'Currency',
+ 'permlevel': 0,
+ 'search_index': 0,
+ 'trigger': u'Client'
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'column_break0',
+ 'fieldtype': u'Column Break',
+ 'label': u'Margin',
+ 'oldfieldtype': u'Column Break',
+ 'permlevel': 0,
+ 'width': u'50%'
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'gross_margin_value',
+ 'fieldtype': u'Currency',
+ 'label': u'Gross Margin Value',
+ 'no_copy': 0,
+ 'oldfieldname': u'gross_margin_value',
+ 'oldfieldtype': u'Currency',
+ 'permlevel': 0,
+ 'reqd': 1,
+ 'search_index': 0
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'per_gross_margin',
+ 'fieldtype': u'Currency',
+ 'label': u'Gross Margin %',
+ 'no_copy': 0,
+ 'oldfieldname': u'per_gross_margin',
+ 'oldfieldtype': u'Currency',
+ 'permlevel': 0,
+ 'reqd': 1,
+ 'search_index': 0
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
'fieldname': u'customer_details',
'fieldtype': u'Section Break',
'label': u'Customer Details',
@@ -476,32 +473,6 @@
# DocField
{
- 'colour': u'White:FFF',
- 'description': u'Important dates and commitments in your project life cycle',
- 'doctype': u'DocField',
- 'fieldname': u'milestones',
- 'fieldtype': u'Section Break',
- 'label': u'Milestones',
- 'oldfieldtype': u'Section Break',
- 'permlevel': 0
- },
-
- # DocField
- {
- 'doctype': u'DocField',
- 'fieldname': u'project_milestones',
- 'fieldtype': u'Table',
- 'label': u'Project Milestones',
- 'no_copy': 0,
- 'oldfieldname': u'project_milestones',
- 'oldfieldtype': u'Table',
- 'options': u'Project Milestone',
- 'permlevel': 0,
- 'search_index': 0
- },
-
- # DocField
- {
'doctype': u'DocField',
'fieldname': u'trash_reason',
'fieldtype': u'Small Text',
@@ -517,12 +488,15 @@
# DocField
{
+ 'colour': u'White:FFF',
'doctype': u'DocField',
'fieldname': u'file_list',
'fieldtype': u'Small Text',
+ 'hidden': 1,
'label': u'File List',
'no_copy': 1,
'permlevel': 0,
+ 'print_hide': 1,
'search_index': 0
}
]
\ No newline at end of file
diff --git a/erpnext/projects/doctype/task/task.py b/erpnext/projects/doctype/task/task.py
index bfd98db..7f023ca 100644
--- a/erpnext/projects/doctype/task/task.py
+++ b/erpnext/projects/doctype/task/task.py
@@ -216,7 +216,7 @@
""" Add calendar event for task in calendar of Allocated person"""
event = Document('Event')
event.owner = self.doc.allocated_to
- event.description = self.doc.name
+ event.description = self.doc.subject
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/utilities/page/calendar/calendar.js b/erpnext/utilities/page/calendar/calendar.js
index 9aa5df8..3d3519b 100644
--- a/erpnext/utilities/page/calendar/calendar.js
+++ b/erpnext/utilities/page/calendar/calendar.js
@@ -83,6 +83,7 @@
d.make_body([
['HTML','Heading']
,['Text','Description']
+ ,['HTML', 'Ref Link']
,['Check', 'Public Event']
,['Check', 'Cancel Event']
,['HTML', 'Event Link']
@@ -111,12 +112,17 @@
this.widgets['Public Event'].checked = true;
this.widgets['Event Link'].innerHTML = '';
+ this.widgets['Ref Link'].innerHTML = '';
- // link
- var div = $a(this.widgets['Event Link'], 'div', 'link_type', {margin:'4px 0px'});
- div.onclick = function() { me.event_dialog.hide(); loaddoc('Event', me.event_dialog.ev.name); }
- div.innerHTML = 'View Event details, add or edit participants';
-
+ if(this.ev.ref_type) {
+ $(repl('<span>Reference: <a href="#Form/%(ref_type)s/%(ref_name)s" \
+ onclick="cur_dialog.hide()">%(ref_type)s: %(ref_name)s</a></span>', this.ev))
+ .appendTo(this.widgets['Ref Link'])
+ }
+
+ $(repl('<a href="#Form/Event/%(name)s" \
+ onclick="cur_dialog.hide()">More Options</a>', this.ev))
+ .appendTo(this.widgets['Event Link'])
}
// event save
diff --git a/erpnext/utilities/page/todo/todo.css b/erpnext/utilities/page/todo/todo.css
index 7c7dcaf..9fe5955 100644
--- a/erpnext/utilities/page/todo/todo.css
+++ b/erpnext/utilities/page/todo/todo.css
@@ -49,7 +49,7 @@
padding-right: 15px;
}
-.layout-main {
+.todo-layout {
background-color: #FFFDC9;
min-height: 300px;
}
\ No newline at end of file
diff --git a/erpnext/utilities/page/todo/todo.html b/erpnext/utilities/page/todo/todo.html
index 88dcbf3..37b07a8 100644
--- a/erpnext/utilities/page/todo/todo.html
+++ b/erpnext/utilities/page/todo/todo.html
@@ -1,6 +1,6 @@
<div class="layout-wrapper layout-wrapper-background">
<div class="appframe-area"></div>
- <div class="layout-main">
+ <div class="layout-main todo-layout">
<div>
<div id="todo-list">
<h4>My List</h4><br>
diff --git a/erpnext/utilities/page/todo/todo.js b/erpnext/utilities/page/todo/todo.js
index 1ab8982..89c1ed8 100644
--- a/erpnext/utilities/page/todo/todo.js
+++ b/erpnext/utilities/page/todo/todo.js
@@ -144,10 +144,10 @@
width: 480,
title: 'To Do',
fields: [
- {fieldtype:'Date', fieldname:'date', label:'Event Date', reqd:1},
{fieldtype:'Text', fieldname:'description', label:'Description',
reqd:1, description:'Use <a href="#markdown-reference">markdown</a> to \
format content'},
+ {fieldtype:'Date', fieldname:'date', label:'Event Date', reqd:1},
{fieldtype:'Check', fieldname:'checked', label:'Completed'},
{fieldtype:'Select', fieldname:'priority', label:'Priority', reqd:1, 'options':['Medium','High','Low'].join('\n')},
{fieldtype:'Button', fieldname:'save', label:'Save'}