diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py index b6fb9a8aac..3db66f050d 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 . +# along with this program. If not, see . # Please edit this list and import only required elements import webnotes @@ -34,59 +34,78 @@ convert_to_lists = webnotes.conn.convert_to_lists 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 527201e17d..43cab3958e 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 @@ -100,6 +79,15 @@ 'permlevel': 0 }, + # 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', @@ -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 @@ -343,6 +261,85 @@ 'search_index': 0 }, + # 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', @@ -474,32 +471,6 @@ 'search_index': 0 }, - # 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', @@ -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 bfd98db127..7f023ca41f 100644 --- a/erpnext/projects/doctype/task/task.py +++ b/erpnext/projects/doctype/task/task.py @@ -216,7 +216,7 @@ class DocType: """ 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'