From 5d9d5562a2ec32cc32664305ecdd508d12419262 Mon Sep 17 00:00:00 2001
From: "nch@tinyerp.com" <>
Date: Tue, 29 Dec 2009 18:35:00 +0530
Subject: [PATCH 1/9] [ADD,FIX]:Group by customer and shop in sale order and a
small bug in stock/product.py
bzr revid: nch@tinyerp.com-20091229130500-b3crhavxmrkmni4q
---
addons/sale/sale_view.xml | 52 +++++++++++++++++++++++++++++++++++++--
addons/stock/product.py | 2 ++
2 files changed, 52 insertions(+), 2 deletions(-)
diff --git a/addons/sale/sale_view.xml b/addons/sale/sale_view.xml
index a7535336982..83c847a4ef2 100644
--- a/addons/sale/sale_view.xml
+++ b/addons/sale/sale_view.xml
@@ -131,7 +131,7 @@
on_change="product_id_change(parent.pricelist_id,product_id,product_uom_qty,product_uom,product_uos_qty,product_uos,name,parent.partner_id, 'lang' in context and context['lang'], False, parent.date_order, product_packaging, parent.fiscal_position)"
domain="[('product_id','=',product_id)]"
groups="base.group_extended"/>
-
+
@@ -264,6 +264,54 @@
+
+
+ sale.order.gp.tree
+ sale.order
+ tree
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Sale Order Group By Customer
+ ir.actions.act_window
+ sale.order
+ {'group_by':'partner_id'}
+ tree
+ form,graph
+
+
+
+
+ Sale Order Group By Shop
+ ir.actions.act_window
+ sale.order
+ {'group_by':'shop_id'}
+ tree
+ form,graph
+
+
+
+
+
+
+
All Sales Order
ir.actions.act_window
@@ -415,7 +463,7 @@
-
+
diff --git a/addons/stock/product.py b/addons/stock/product.py
index 5c42cdbdab2..544cc1b2789 100644
--- a/addons/stock/product.py
+++ b/addons/stock/product.py
@@ -175,6 +175,8 @@ class product_product(osv.osv):
}
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
res = super(product_product,self).fields_view_get(cr, uid, view_id, view_type, context, toolbar=toolbar, submenu=submenu)
+ if context == None:
+ context = {}
if ('location' in context) and context['location']:
location_info = self.pool.get('stock.location').browse(cr, uid, context['location'])
fields=res.get('fields',{})
From 926d2b9de8a089460b4d8c2693cc08db7cf5eba9 Mon Sep 17 00:00:00 2001
From: "Rvo (Open ERP)"
Date: Tue, 12 Jan 2010 14:50:13 +0530
Subject: [PATCH 2/9] Changes in project/project.py and hr/hr_view.xml
bzr revid: rvo@tinyerp.co.in-20100112092013-g0nq8vhxssg1ha1n
---
addons/hr/hr_view.xml | 9 ++++++-
addons/project/project.py | 53 ++++++++-------------------------------
2 files changed, 19 insertions(+), 43 deletions(-)
diff --git a/addons/hr/hr_view.xml b/addons/hr/hr_view.xml
index dd8a2d3a3fd..45d55d8b785 100644
--- a/addons/hr/hr_view.xml
+++ b/addons/hr/hr_view.xml
@@ -155,7 +155,7 @@
-
+
+
+
+ 38 Hours/Week
+
+
+
+ Fabien Pinckaers
+
+
+
+
+
+
+ Monday morning
+ 0
+ 08
+ 12
+
+
+
+ Monday evening
+ 0
+ 13
+ 18
+
+
+
+ Tuesday morning
+ 1
+ 08
+ 12
+
+
+
+ Tuesday evening
+ 1
+ 13
+ 18
+
+
+
+ Wednesday morning
+ 2
+ 08
+ 12
+
+
+
+ Wednesday evening
+ 2
+ 13
+ 18
+
+
+
+ Thursday morning
+ 3
+ 08
+ 12
+
+
+
+ Thursday evening
+ 13
+ 18
+ 3
+
+
+
+ Friday morning
+ 4
+ 08
+ 12
+
+
+
+ Friday evening
+ 4
+ 13
+ 18
+
+
+
+
+
diff --git a/addons/resource/hr_department.py b/addons/resource/hr_department.py
new file mode 100755
index 00000000000..907bc55a435
--- /dev/null
+++ b/addons/resource/hr_department.py
@@ -0,0 +1,153 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL ().
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# 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
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+from osv import fields,osv
+import tools
+
+class hr_department(osv.osv):
+ _name = "hr.department"
+ _columns = {
+ 'name': fields.char('Department Name', size=64, required=True),
+ 'company_id': fields.many2one('res.company', 'Company', select=True, required=True),
+ 'parent_id': fields.many2one('hr.department', 'Parent Department', select=True),
+ 'child_ids': fields.one2many('hr.department', 'parent_id', 'Child Departments'),
+ 'note': fields.text('Note'),
+ 'manager_id': fields.many2one('res.users', 'Manager', required=True),
+ 'member_ids': fields.many2many('res.users', 'hr_department_user_rel', 'department_id', 'user_id', 'Members'),
+ }
+ def _get_members(self,cr, uid, context={}):
+ mids = self.search(cr, uid, [('manager_id','=',uid)])
+ result = {uid:1}
+ for m in self.browse(cr, uid, mids, context):
+ for user in m.member_ids:
+ result[user.id] = 1
+ return result.keys()
+ def _check_recursion(self, cr, uid, ids):
+ level = 100
+ while len(ids):
+ cr.execute('select distinct parent_id from hr_department where id in ('+','.join(map(str, ids))+')')
+ ids = filter(None, map(lambda x:x[0], cr.fetchall()))
+ if not level:
+ return False
+ level -= 1
+ return True
+
+ _constraints = [
+ (_check_recursion, 'Error! You can not create recursive departments.', ['parent_id'])
+ ]
+
+hr_department()
+
+
+class ir_action_window(osv.osv):
+ _inherit = 'ir.actions.act_window'
+
+ def read(self, cr, uid, ids, fields=None, context=None,
+ load='_classic_read'):
+ select = ids
+ if isinstance(ids, (int, long)):
+ select = [ids]
+ res = super(ir_action_window, self).read(cr, uid, select, fields=fields,
+ context=context, load=load)
+ for r in res:
+ mystring = 'department_users_get()'
+ if mystring in (r.get('domain', '[]') or ''):
+ r['domain'] = r['domain'].replace(mystring, str(
+ self.pool.get('hr.department')._get_members(cr, uid)))
+ if isinstance(ids, (int, long)):
+ if res:
+ return res[0]
+ else:
+ return False
+ return res
+
+ir_action_window()
+
+class res_users(osv.osv):
+ _inherit = 'res.users'
+ _description = 'res.users'
+
+ def _parent_compute(self, cr, uid, ids, name, args, context={}):
+ result = {}
+ obj_dept = self.pool.get('hr.department')
+ for user_id in ids:
+ ids_dept = obj_dept.search(cr, uid, [('member_ids', 'in', [user_id])])
+ parent_ids = []
+ if ids_dept:
+ data_dept = obj_dept.read(cr, uid, ids_dept, ['manager_id'])
+ parent_ids = map(lambda x: x['manager_id'][0], data_dept)
+ result[user_id] = parent_ids
+ return result
+
+ def _parent_search(self, cr, uid, obj, name, args):
+ parent = []
+ for arg in args:
+ if arg[0] == 'parent_id':
+ parent = arg[2]
+ child_ids = self._child_compute(cr, uid, parent,name, args, {})
+ if not child_ids:
+ return [('id', 'in', [0])]
+ return [('id', 'in', child_ids.get(uid,[]))]
+
+ def _child_compute(self, cr, uid, ids, name, args, context={}):
+ obj_dept = self.pool.get('hr.department')
+ obj_user = self.pool.get('res.users')
+ result = {}
+ for manager_id in ids:
+ child_ids = []
+ mgnt_dept_ids = obj_dept.search(cr, uid, [('manager_id', '=', manager_id)])
+ ids_dept = obj_dept.search(cr, uid, [('id', 'child_of', mgnt_dept_ids)])
+ if ids_dept:
+ data_dept = obj_dept.read(cr, uid, ids_dept, ['member_ids'])
+ childs = map(lambda x: x['member_ids'], data_dept)
+ childs = tools.flatten(childs)
+ childs = obj_user.search(cr, uid, [('id','in',childs),('active','=',True)])
+ if manager_id in childs:
+ childs.remove(manager_id)
+
+ child_ids.extend(tools.flatten(childs))
+ set = {}
+ map(set.__setitem__, child_ids, [])
+ child_ids = set.keys()
+ else:
+ child_ids = []
+ result[manager_id] = child_ids
+ return result
+
+ def _child_search(self, cr, uid, obj, name, args):
+ parent = []
+ for arg in args:
+ if arg[0] == 'child_ids':
+ parent = arg[2]
+ child_ids = self._child_compute(cr, uid, parent,name, args, {})
+ if not child_ids:
+ return [('id', 'in', [0])]
+ return [('id', 'in', child_ids.get(uid,[]))]
+
+ _columns = {
+ 'parent_id': fields.function(_parent_compute, relation='res.users',fnct_search=_parent_search, method=True, string="Managers", type='many2many'),
+ 'child_ids': fields.function(_child_compute, relation='res.users', fnct_search=_child_search,method=True, string="Subordinates", type='many2many'),
+ }
+
+
+res_users()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
diff --git a/addons/resource/hr_department_demo.xml b/addons/resource/hr_department_demo.xml
new file mode 100755
index 00000000000..c7ea68f1dc3
--- /dev/null
+++ b/addons/resource/hr_department_demo.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+ Management
+
+
+
+
+ Administration
+
+
+
+
+
+
+ Technical department
+
+
+
+
+
+
+ IT
+
+
+
+
+
+
+ Marketing
+
+
+
+
+
+
+ Sales
+
+
+
+
+
+
+ Sales Europe
+
+
+
+
+
+
+ Sales America
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/resource/hr_department_view.xml b/addons/resource/hr_department_view.xml
new file mode 100755
index 00000000000..fe65d988237
--- /dev/null
+++ b/addons/resource/hr_department_view.xml
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+ hr.department.form
+ hr.department
+ form
+
+
+
+
+
+ hr.department.tree
+ hr.department
+ tree
+ child_ids
+
+
+
+
+
+
+
+
+
+ Departments
+ hr.department
+ tree
+ [('parent_id','=',False)]
+
+
+
+
+ Departments
+ hr.department
+ form
+
+
+
+
+
+
+ res.users.form
+ form
+ res.users
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/resource/hr_view.xml b/addons/resource/hr_view.xml
new file mode 100755
index 00000000000..abf3c5f023f
--- /dev/null
+++ b/addons/resource/hr_view.xml
@@ -0,0 +1,296 @@
+
+
+
+
+
+
+
+
+
+ hr.employee.form
+ hr.employee
+ form
+
+
+
+
+
+
+ hr.employee.tree
+ hr.employee
+ tree
+ child_ids
+
+
+
+
+
+
+
+
+
+
+
+ Employees Structure
+ hr.employee
+ tree
+ tree,form
+
+ [('parent_id','=',False)]
+
+
+
+ Employees
+ hr.employee
+ form
+ tree,form
+
+
+
+
+
+
+
+ All Employees
+ hr.employee
+ form
+ tree,form
+ []
+
+
+
+
+
+ hr.employee.tree
+ hr.employee
+ tree
+ child_ids
+
+
+
+
+
+
+
+
+
+
+ Employee Hierarchy
+ ir.actions.act_window
+ hr.employee
+ [('id','in',active_ids)]
+ tree
+
+
+
+
+
+
+ Employees Hierarchy
+
+
+
+
+
+
+
+
+ resource.calendar.form
+ resource.calendar
+ form
+
+
+
+
+
+ Working Time Categories
+ resource.calendar
+ form
+
+
+
+
+
+ resource.calendar.week.tree
+ resource.calendar.week
+ tree
+
+
+
+
+
+
+
+
+
+
+ resource.calendar.week.form
+ resource.calendar.week
+ form
+
+
+
+
+
+
+
+
+ hr.employee.category.form
+ hr.employee.category
+ form
+
+
+
+
+
+ hr.employee.category.list
+ hr.employee.category
+ tree
+
+
+
+
+
+
+
+
+
+ hr.employee.category.tree
+ hr.employee.category
+ tree
+ child_ids
+
+
+
+
+
+
+
+ Categories of Employee
+ hr.employee.category
+ form
+ tree,form
+
+
+
+
+ Categories structure
+ hr.employee.category
+ tree
+
+ [('parent_id','=',False)]
+
+
+
+ Employees
+ ir.actions.act_window
+ hr.employee
+ form
+ tree,form
+ [('category_id','child_of',[active_id])]
+ {'category_id':active_id}
+
+
+
+
+
+ Employees by Categories
+
+
+
+
+
+
+
+
diff --git a/addons/resource/resource.py b/addons/resource/resource.py
new file mode 100755
index 00000000000..2d225527f0e
--- /dev/null
+++ b/addons/resource/resource.py
@@ -0,0 +1,195 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL ().
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# 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
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+import mx.DateTime
+import time
+import math
+from osv import fields, osv
+from tools.translate import _
+
+class resource_calendar(osv.osv):
+ _name = "resource.calendar"
+ _description = "Resource Calendar"
+ _columns = {
+ 'name' : fields.char("Name", size=64, required=True),
+ 'company_id' : fields.many2one('res.company', 'Company', required=True),
+ 'week_id' : fields.one2many('resource.calendar.week', 'calendar_id', 'Working Time'),
+ 'manager' : fields.many2one('res.users', 'Workgroup manager'),
+ }
+ _defaults = {
+ 'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'resource.calendar', c)
+ }
+ def interval_min_get(self, cr, uid, id, dt_from, hours , resource=0):
+ dt_leave = []
+ if not id:
+ return [(dt_from-mx.DateTime.RelativeDateTime(hours=int(hours)*3), dt_from)]
+ if resource:
+ resource_leave_ids = self.pool.get('resource.calendar.leaves').search(cr,uid,[('resource_id','=',resource)])
+ if resource_leave_ids:
+ res_leaves = self.pool.get('resource.calendar.leaves').read(cr,uid,resource_leave_ids,['date_from','date_to'])
+ print 'Leave Details',res_leaves
+ for i in range(len(res_leaves)):
+ dtf = mx.DateTime.strptime(res_leaves[i]['date_from'],'%Y-%m-%d %H:%M:%S')
+ dtt = mx.DateTime.strptime(res_leaves[i]['date_to'],'%Y-%m-%d %H:%M:%S')
+ leave_days = ((dtt - dtf).days) + 1
+ print 'No Of Leaves:::::::::',int(leave_days)
+ for x in range(int(leave_days)):
+ dt_leave.append((dtf + mx.DateTime.RelativeDateTime(days=x)).strftime('%Y-%m-%d'))
+ dt_leave.sort()
+ print 'Sorted Leave Dates::::',dt_leave
+ todo = hours
+ cycle = 0
+ result = []
+ maxrecur = 100
+ current_hour = dt_from.hour
+ while (todo>0) and maxrecur:
+ cr.execute("select hour_from,hour_to from resource_calendar_week where dayofweek='%s' and calendar_id=%s order by hour_from", (dt_from.day_of_week,id))
+ for (hour_from,hour_to) in cr.fetchall():
+ if (hour_to>current_hour) and (todo>0):
+ m = max(hour_from, current_hour)
+ if (hour_to-m)>todo:
+ hour_to = m+todo
+ d1 = mx.DateTime.DateTime(dt_from.year,dt_from.month,dt_from.day,int(math.floor(m)),int((m%1) * 60))
+ d2 = mx.DateTime.DateTime(dt_from.year,dt_from.month,dt_from.day,int(math.floor(hour_to)),int((hour_to%1) * 60))
+ dt1 = d1.strftime('%Y-%m-%d')
+ dt2 = d2.strftime('%Y-%m-%d')
+ print 'Date 1',dt1
+ print 'Date 2',dt2
+ for i in range(len(dt_leave)):
+ if dt1 == dt_leave[i]:
+ print 'Leave::::::::'
+ dt_from += mx.DateTime.RelativeDateTime(days=1)
+ d1 = mx.DateTime.DateTime(dt_from.year,dt_from.month,dt_from.day,int(math.floor(m)),int((m%1) * 60))
+ d2 = mx.DateTime.DateTime(dt_from.year,dt_from.month,dt_from.day,int(math.floor(hour_to)),int((hour_to%1) * 60))
+ dt1 = d1.strftime('%Y-%m-%d')
+ dt2 = d2.strftime('%Y-%m-%d')
+ result.append((d1, d2))
+ current_hour = hour_to
+ todo -= (hour_to - m)
+ dt_from += mx.DateTime.RelativeDateTime(days=1)
+ current_hour = 0
+ maxrecur -= 1
+ return result
+
+ def interval_get(self, cr, uid, id, dt_from, hours, resource=0, byday=True):
+ dt_leave = []
+ if not id:
+ return [(dt_from,dt_from+mx.DateTime.RelativeDateTime(hours=int(hours)*3))]
+ if resource:
+ resource_leave_ids = self.pool.get('resource.calendar.leaves').search(cr,uid,[('resource_id','=',resource)])
+ if resource_leave_ids:
+ res_leaves = self.pool.get('resource.calendar.leaves').read(cr,uid,resource_leave_ids,['date_from','date_to'])
+ print 'Leave Details',res_leaves
+ for i in range(len(res_leaves)):
+ dtf = mx.DateTime.strptime(res_leaves[i]['date_from'],'%Y-%m-%d %H:%M:%S')
+ dtt = mx.DateTime.strptime(res_leaves[i]['date_to'],'%Y-%m-%d %H:%M:%S')
+ no = dtt - dtf
+ leave_days = no.days + 1
+ print 'No Of Leaves:::::::::',int(leave_days)
+ for x in range(int(leave_days)):
+ dt_leave.append((dtf + mx.DateTime.RelativeDateTime(days=x)).strftime('%Y-%m-%d'))
+ dt_leave.sort()
+ print 'Sorted Leave Dates::::',dt_leave
+ todo = hours
+ cycle = 0
+ result = []
+ maxrecur = 100
+ current_hour = dt_from.hour
+ while (todo>0) and maxrecur:
+ cr.execute("select hour_from,hour_to from resource_calendar_week where dayofweek='%s' and calendar_id=%s order by hour_from", (dt_from.day_of_week,id))
+ for (hour_from,hour_to) in cr.fetchall():
+ if (hour_to>current_hour) and (todo>0):
+ m = max(hour_from, current_hour)
+ if (hour_to-m)>todo:
+ hour_to = m+todo
+ d1 = mx.DateTime.DateTime(dt_from.year,dt_from.month,dt_from.day,int(math.floor(m)),int((m%1) * 60))
+ d2 = mx.DateTime.DateTime(dt_from.year,dt_from.month,dt_from.day,int(math.floor(hour_to)),int((hour_to%1) * 60))
+ dt1 = d1.strftime('%Y-%m-%d')
+ dt2 = d2.strftime('%Y-%m-%d')
+ print 'Date 1',dt1
+ print 'Date 2',dt2
+ for i in range(len(dt_leave)):
+ if dt1 == dt_leave[i]:
+ print 'Leave::::::::'
+ dt_from += mx.DateTime.RelativeDateTime(days=1)
+ d1 = mx.DateTime.DateTime(dt_from.year,dt_from.month,dt_from.day,int(math.floor(m)),int((m%1) * 60))
+ d2 = mx.DateTime.DateTime(dt_from.year,dt_from.month,dt_from.day,int(math.floor(hour_to)),int((hour_to%1) * 60))
+ dt1 = d1.strftime('%Y-%m-%d')
+ dt2 = d2.strftime('%Y-%m-%d')
+ result.append((d1, d2))
+ current_hour = hour_to
+ todo -= (hour_to - m)
+ dt_from += mx.DateTime.RelativeDateTime(days=1)
+ current_hour = 0
+ maxrecur -= 1
+ return result
+
+resource_calendar()
+
+class resource_calendar_week(osv.osv):
+ _name = "resource.calendar.week"
+ _description = "Work Detail"
+ _columns = {
+ 'name' : fields.char("Name", size=64, required=True),
+ 'dayofweek': fields.selection([('0','Monday'),('1','Tuesday'),('2','Wednesday'),('3','Thursday'),('4','Friday'),('5','Saturday'),('6','Sunday')], 'Day of week'),
+ 'date_from' : fields.date('Starting date'),
+ 'hour_from' : fields.float('Work from', size=8, required=True),
+ 'hour_to' : fields.float("Work to", size=8, required=True),
+ 'calendar_id' : fields.many2one("resource.calendar", "Resource's Calendar", required=True),
+ }
+ _order = 'dayofweek, hour_from'
+resource_calendar_week()
+
+class resource_resource(osv.osv):
+ _name = "resource.resource"
+ _description = "Resource Detail"
+ _columns = {
+ 'name' : fields.char("Name", size=64, required=True),
+ 'code': fields.char('Code', size=16),
+ 'active' : fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the resource record without removing it."),
+ 'company_id' : fields.many2one('res.company', 'Company', required=True),
+ 'resource_type': fields.selection([('user','Human'),('material','Material')], 'Resource Type', required=True),
+ 'user_id' : fields.many2one('res.users', 'User'),
+ 'time_efficiency' : fields.float('Efficiency factor', size=8, help="This field depict the efficency of the ressource to complete tasks. e.g ressource put alone on a phase of 5 days with 5 tasks assigned to him, will show a load of 100% for this phase by default, but if we put a efficency of 200%, then his load will only be 50%."),
+ 'calendar_id' : fields.many2one("resource.calendar", "Working time", required=True, help="Define the schedule of resource"),
+ }
+ _defaults = {
+ 'resource_type' : lambda *a: 'user',
+ 'time_efficiency' : lambda *a: 1,
+ 'active' : lambda *a: True,
+ 'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'resource.resource', c)
+ }
+resource_resource()
+
+class resource_calendar_leaves(osv.osv):
+ _name = "resource.calendar.leaves"
+ _description = "Leave Detail"
+ _columns = {
+ 'name' : fields.char("Name", size=64),
+ 'company_id' : fields.related('calendar_id','company_id',type='many2one',relation='res.company',string="Company",required=True),
+ #'company_id':fields.many2one('res.company', 'Company', required=True),
+ 'calendar_id' : fields.many2one("resource.calendar", "Working time"),
+ 'date_from' : fields.datetime('Start Date', required=True),
+ 'date_to' : fields.datetime('End Date', required=True),
+ 'resource_id' : fields.many2one("resource.resource", "Resource", help="If empty, this is a generic holiday for the company. If a resource is set, the holiday/leave is only for this resource"),
+
+ }
+resource_calendar_leaves()
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/resource/resource_view.xml b/addons/resource/resource_view.xml
new file mode 100755
index 00000000000..80d0650e0c8
--- /dev/null
+++ b/addons/resource/resource_view.xml
@@ -0,0 +1,174 @@
+
+
+
+
+
+
+
+
+
+ resource.calendar.form
+ resource.calendar
+ form
+
+
+
+
+
+ Resource Calendar
+ resource.calendar
+ form
+
+
+
+
+
+ resource.calendar.week.tree
+ resource.calendar.week
+ tree
+
+
+
+
+
+
+
+
+
+
+ resource.calendar.week.form
+ resource.calendar.week
+ form
+
+
+
+
+
+
+ resource.calendar.leaves.calendar
+ resource.calendar.leaves
+ calendar
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ resource.resource.form
+ resource.resource
+ form
+
+
+
+
+
+ resource.resource.tree
+ resource.resource
+ tree
+
+
+
+
+
+
+
+
+
+
+
+
+ Resources
+ resource.resource
+ tree,form
+
+
+
+
+ resource.calendar.leaves.form
+ resource.calendar.leaves
+ form
+
+
+
+
+
+ resource.calendar.leaves.tree
+ resource.calendar.leaves
+ tree
+
+
+
+
+
+
+
+
+
+
+
+
+ Leaves
+ resource.calendar.leaves
+ tree,form,calendar
+
+
+
+
+
+
From ebf3b965270287c284eebcf230181952a213ef97 Mon Sep 17 00:00:00 2001
From: "Rvo (Open ERP)"
Date: Tue, 12 Jan 2010 18:15:02 +0530
Subject: [PATCH 5/9] [ADD]:added module project_long_term
bzr revid: rvo@tinyerp.co.in-20100112124502-k2adb24jmfixtngm
---
addons/project_long_term/__init__.py | 25 ++
addons/project_long_term/__terp__.py | 42 +++
addons/project_long_term/project.py | 119 +++++++++
addons/project_long_term/project_data.xml | 16 ++
.../project_data_scheduler.xml | 23 ++
addons/project_long_term/project_demo.xml | 252 ++++++++++++++++++
addons/project_long_term/project_report.xml | 8 +
addons/project_long_term/project_view.xml | 101 +++++++
addons/project_long_term/project_wizard.xml | 8 +
9 files changed, 594 insertions(+)
create mode 100644 addons/project_long_term/__init__.py
create mode 100644 addons/project_long_term/__terp__.py
create mode 100644 addons/project_long_term/project.py
create mode 100644 addons/project_long_term/project_data.xml
create mode 100644 addons/project_long_term/project_data_scheduler.xml
create mode 100644 addons/project_long_term/project_demo.xml
create mode 100644 addons/project_long_term/project_report.xml
create mode 100644 addons/project_long_term/project_view.xml
create mode 100644 addons/project_long_term/project_wizard.xml
diff --git a/addons/project_long_term/__init__.py b/addons/project_long_term/__init__.py
new file mode 100644
index 00000000000..33adeb520b9
--- /dev/null
+++ b/addons/project_long_term/__init__.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL ().
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# 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
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+import project
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+
diff --git a/addons/project_long_term/__terp__.py b/addons/project_long_term/__terp__.py
new file mode 100644
index 00000000000..1b5dfa348ad
--- /dev/null
+++ b/addons/project_long_term/__terp__.py
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL ().
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# 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
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+
+{
+ "name" : "Long Term Project Management",
+ "version": "1.1",
+ "author" : "Tiny",
+ "website" : "http://www.openerp.com",
+ "category" : "Generic Modules/Projects & Services",
+ "depends" : ["project"],
+ "description": """Long Term Project management module that track planning, scheduling, resources allocation.
+ """,
+ "init_xml" : [],
+ "demo_xml" : [#"project_demo.xml"
+],
+ "update_xml": [
+ "project_view.xml",
+ ],
+ 'installable': True,
+ 'active': False,
+ 'certificate': None,
+}
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/project_long_term/project.py b/addons/project_long_term/project.py
new file mode 100644
index 00000000000..f04e18babfd
--- /dev/null
+++ b/addons/project_long_term/project.py
@@ -0,0 +1,119 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL ().
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# 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
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+from lxml import etree
+from mx import DateTime
+from mx.DateTime import now
+import time
+from tools.translate import _
+
+from osv import fields, osv
+from tools.translate import _
+
+class project_phase(osv.osv):
+ _name = "project.phase"
+ _description = "Project Phase"
+
+ def _check_recursion(self,cr,uid,ids):
+ level = 100
+ while len(ids):
+ cr.execute('select distinct next_phase_id from project_phase_next_rel where phase_id in ('+','.join(map(str, ids))+')')
+ ids = filter(None, map(lambda x:x[0], cr.fetchall()))
+ next_ids = ids
+ while(next_ids):
+ cr.execute('select distinct prev_phase_id from project_phase_prev_rel where phase_id in ('+','.join(map(str, ids))+')')
+ prev_ids = filter(None, map(lambda x:x[0], cr.fetchall()))
+
+ return True
+
+ while(ids):
+ cr.execute('select distinct child_id from account_account_consol_rel where parent_id in ('+','.join(map(str, ids))+')')
+ child_ids = filter(None, map(lambda x: x[0], cr.fetchall()))
+ c_ids = child_ids
+ if (p_id and (p_id in c_ids)) or (obj_self.id in c_ids):
+ return False
+ while len(c_ids):
+ s_ids = self.search(cr, uid, [('parent_id', 'in', c_ids)])
+ if p_id and (p_id in s_ids):
+ return False
+ c_ids = s_ids
+ ids = child_ids
+ return True
+
+
+
+ _columns = {
+ 'name': fields.char("Phase Name", size=64, required=True),
+ 'date_start': fields.datetime('Starting Date'),
+ 'date_end': fields.datetime('End Date'),
+ 'constraint_date_start': fields.datetime('Constraint Starting Date'),
+ 'constraint_date_end': fields.datetime('Constraint End Date'),
+ 'project_id': fields.many2one('project.project', 'Project', required=True),
+ 'next_phase_ids': fields.many2many('project.phase', 'project_phase_next_rel', 'phase_id', 'next_phase_id', 'Next Phases'),
+ 'previous_phase_ids': fields.many2many('project.phase', 'project_phase_previous_rel', 'phase_id', 'prv_phase_id', 'Previous Phases'),
+ 'duration': fields.float('Duration'),
+ 'product_uom': fields.many2one('product.uom', 'Duration UoM', help="UoM (Unit of Measure) is the unit of measurement for Duration"),
+ 'task_ids': fields.one2many('project.task', 'phase_id', "Project Tasks"),
+ 'resource_ids': fields.one2many('project.resource.allocation', 'phase_id', "Project Resources"),
+ }
+
+ _defaults = {
+ 'date_start': lambda *a: time.strftime('%Y-%m-%d'),
+ }
+
+ _order = "name"
+ _constraints = [
+ (_check_recursion,'Error ! Loops In Phases Not Allowed',['next_phase_ids','previous_phase_ids'])
+ ]
+project_phase()
+
+class project_resource_allocation(osv.osv):
+ _name = 'project.resource.allocation'
+ _description = 'Project Resource Allocation'
+ _columns = {
+ 'resource_id': fields.many2one('resource.resource', 'Resource', required=True),
+ 'phase_id': fields.many2one('project.phase', 'Project Phase', required=True),
+ 'useability': fields.float('Useability', help="Useability of this ressource for this project phase in percentage (=50%)"),
+ }
+ _defaults = {
+ 'useability': lambda *a: 100,
+ }
+project_resource_allocation()
+
+class project(osv.osv):
+ _inherit = "project.project"
+
+ _columns = {
+ 'phase_ids': fields.one2many('project.phase', 'project_id', "Project Phases")
+ }
+
+project()
+
+class task(osv.osv):
+ _inherit = "project.task"
+
+ _columns = {
+ 'phase_id': fields.many2one('project.phase', 'Project Phase')
+ }
+
+task()
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+
diff --git a/addons/project_long_term/project_data.xml b/addons/project_long_term/project_data.xml
new file mode 100644
index 00000000000..2addd68fa19
--- /dev/null
+++ b/addons/project_long_term/project_data.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+ Project
+ project.project
+
+
+ Project task
+ project.task
+
+
+
diff --git a/addons/project_long_term/project_data_scheduler.xml b/addons/project_long_term/project_data_scheduler.xml
new file mode 100644
index 00000000000..32e74725d58
--- /dev/null
+++ b/addons/project_long_term/project_data_scheduler.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+ Calculate Project Task Length Scheduler
+
+
+ 1
+ minutes
+ -1
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/project_long_term/project_demo.xml b/addons/project_long_term/project_demo.xml
new file mode 100644
index 00000000000..e762d3874ba
--- /dev/null
+++ b/addons/project_long_term/project_demo.xml
@@ -0,0 +1,252 @@
+
+
+
+
+
+
+
+
+
+
+ Analysis
+
+
+ New Feature
+
+
+ Quotation
+
+
+ Bug
+
+
+
+ 1
+ Open ERP Integration
+
+
+
+ 1
+ 10
+
+ Study + Prototype
+
+
+
+
+ 20
+
+ Specific Developements
+
+
+
+
+ 30
+
+ Install, data import, configuration
+
+
+
+
+
+ 38.0
+ 38.0
+
+
+
+ BoM, After sales returns, interventions. Tracability.
+ Specific adaptation to MRP
+
+
+ 16.0
+ 16.0
+
+
+
+ Data importation + Doc
+
+
+ 16.0
+ 16.0
+
+
+
+ Modifications asked by the customer.
+
+
+ 16.0
+ 16.0
+
+
+ 0
+
+ Customer analysis + Architecture
+
+
+ 15
+ 8.0
+ 8.0
+
+
+
+ Internal testing + Software Install
+ 2008-06-06
+
+
+ 17
+ 16.0
+ 16.0
+
+
+ 2
+ open
+
+ Analysis, Data Importation
+
+
+ 20
+ 16.0
+ 16.0
+ open
+
+
+ Parameters
+
+
+ 20
+ 32.0
+ 32.0
+
+ open
+
+ Start of the doc redaction + MRP
+
+
+ 25
+ 24.0
+ 24.0
+
+
+ done
+ MRP Tests
+
+
+ 29
+ 24.0
+ 24.0
+
+
+ MRP; functionnal layer
+ done
+
+
+
+ 30
+ 24.0
+ 24.0
+
+
+ Products Adaptation
+
+
+ 30
+ 24.0
+ 24.0
+
+
+ Install + Super User Training
+
+
+ 30
+ 32.0
+ 32.0
+
+
+ Customer docs
+
+
+ 30
+ 24.0
+ 24.0
+
+
+ Development of the presentation layer
+
+
+ 40
+ 32.0
+ 32.0
+
+
+ Free Time
+
+
+ 40
+ 50.0
+ 50.0
+
+
+ Specific tests
+
+
+ 40
+ 24.0
+ 24.0
+
+
+ Sale module
+
+
+ 40
+ 32.0
+ 32.0
+
+
+ open
+ In house training
+ 2007-06-06
+
+
+ 50
+ 24.0
+ 24.0
+
+
+ Validation + latest modifications.
+
+
+ 50
+ 24.0
+ 24.0
+
+
+ Adaptations buy module
+
+
+ 60
+ 16.0
+ 16.0
+
+
+ Presentation of the software.
+
+
+ 60
+ 24.0
+ 24.0
+
+
+ Adaptations Stock module
+
+
+ 70
+ 24.0
+ 24.0
+
+
+ Latest in house tests
+
+
+
diff --git a/addons/project_long_term/project_report.xml b/addons/project_long_term/project_report.xml
new file mode 100644
index 00000000000..c3b681cdd8b
--- /dev/null
+++ b/addons/project_long_term/project_report.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/addons/project_long_term/project_view.xml b/addons/project_long_term/project_view.xml
new file mode 100644
index 00000000000..5afbad59af8
--- /dev/null
+++ b/addons/project_long_term/project_view.xml
@@ -0,0 +1,101 @@
+
+
+
+
+ project.resource.allocation.form
+ project.resource.allocation
+ form
+
+
+
+
+
+ project.resource.allocation.list
+ project.resource.allocation
+ tree
+
+
+
+
+
+
+
+
+
+
+ project.phase.form
+ project.phase
+ form
+
+
+
+
+
+ project.phase.list
+ project.phase
+ tree
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Project phases
+ project.phase
+ form
+
+
+
+
+
+
+
+
+
diff --git a/addons/project_long_term/project_wizard.xml b/addons/project_long_term/project_wizard.xml
new file mode 100644
index 00000000000..109a003da4a
--- /dev/null
+++ b/addons/project_long_term/project_wizard.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
From 5fe81283a19b22f102204f539e3d1f30c8e605fe Mon Sep 17 00:00:00 2001
From: "pap (openerp)"
Date: Wed, 13 Jan 2010 16:17:23 +0530
Subject: [PATCH 6/9] [IMP]:removed duplicate fields from hr.employee module,
put resource_id also while creating resource.calendar.leaves record when
hr.holidays record is confirmed
bzr revid: pap@tinyerp.co.in-20100113104723-lcpmbsa63nv6ioam
---
addons/hr/hr.py | 5 -----
addons/hr_holidays/hr.py | 8 +++++---
addons/resource/resource.py | 23 +++++------------------
3 files changed, 10 insertions(+), 26 deletions(-)
mode change 100644 => 100755 addons/hr/hr.py
mode change 100644 => 100755 addons/hr_holidays/hr.py
diff --git a/addons/hr/hr.py b/addons/hr/hr.py
old mode 100644
new mode 100755
index 181d783d98d..4d77cf715b8
--- a/addons/hr/hr.py
+++ b/addons/hr/hr.py
@@ -57,11 +57,6 @@ class hr_employee(osv.osv):
_description = "Employee"
_inherits = {'resource.resource':"resource_id"}
_columns = {
- 'name' : fields.char("Employee's Name", size=128, required=True),
- 'active' : fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the employee record without removing it."),
- 'company_id': fields.many2one('res.company', 'Company'),
- 'user_id' : fields.many2one('res.users', 'Related User', help='Related user name for an employee to manage his access rights.'),
-
'country_id' : fields.many2one('res.country', 'Nationality'),
'birthday' : fields.date("Birthday"),
'ssnid': fields.char('SSN No', size=32, help='Social Security Number'),
diff --git a/addons/hr_holidays/hr.py b/addons/hr_holidays/hr.py
old mode 100644
new mode 100755
index 6c5e12771e1..a77eb046a33
--- a/addons/hr_holidays/hr.py
+++ b/addons/hr_holidays/hr.py
@@ -242,7 +242,6 @@ class hr_holidays(osv.osv):
'state':'validate',
}
ids2 = self.pool.get('hr.employee').search(cr, uid, [('user_id','=', uid)])
-
if ids2:
vals['manager_id'] = ids2[0]
else:
@@ -272,9 +271,12 @@ class hr_holidays(osv.osv):
vals= {
'name':record.name,
'date_from':record.date_from,
- 'date_to':record.date_to
+ 'date_to':record.date_to,
+ 'calendar_id':record.employee_id.calendar_id.id,
+ 'company_id':record.employee_id.company_id.id,
+ 'resource_id':record.employee_id.resource_id.id
}
- self.pool.get('resource.calendar.leaves').create(cr,uid,vals,context)
+ self.pool.get('resource.calendar.leaves').create(cr,uid,vals)
return True
diff --git a/addons/resource/resource.py b/addons/resource/resource.py
index 2d225527f0e..dad8aedf5cf 100755
--- a/addons/resource/resource.py
+++ b/addons/resource/resource.py
@@ -44,16 +44,13 @@ class resource_calendar(osv.osv):
resource_leave_ids = self.pool.get('resource.calendar.leaves').search(cr,uid,[('resource_id','=',resource)])
if resource_leave_ids:
res_leaves = self.pool.get('resource.calendar.leaves').read(cr,uid,resource_leave_ids,['date_from','date_to'])
- print 'Leave Details',res_leaves
for i in range(len(res_leaves)):
dtf = mx.DateTime.strptime(res_leaves[i]['date_from'],'%Y-%m-%d %H:%M:%S')
dtt = mx.DateTime.strptime(res_leaves[i]['date_to'],'%Y-%m-%d %H:%M:%S')
leave_days = ((dtt - dtf).days) + 1
- print 'No Of Leaves:::::::::',int(leave_days)
for x in range(int(leave_days)):
dt_leave.append((dtf + mx.DateTime.RelativeDateTime(days=x)).strftime('%Y-%m-%d'))
dt_leave.sort()
- print 'Sorted Leave Dates::::',dt_leave
todo = hours
cycle = 0
result = []
@@ -70,11 +67,8 @@ class resource_calendar(osv.osv):
d2 = mx.DateTime.DateTime(dt_from.year,dt_from.month,dt_from.day,int(math.floor(hour_to)),int((hour_to%1) * 60))
dt1 = d1.strftime('%Y-%m-%d')
dt2 = d2.strftime('%Y-%m-%d')
- print 'Date 1',dt1
- print 'Date 2',dt2
for i in range(len(dt_leave)):
if dt1 == dt_leave[i]:
- print 'Leave::::::::'
dt_from += mx.DateTime.RelativeDateTime(days=1)
d1 = mx.DateTime.DateTime(dt_from.year,dt_from.month,dt_from.day,int(math.floor(m)),int((m%1) * 60))
d2 = mx.DateTime.DateTime(dt_from.year,dt_from.month,dt_from.day,int(math.floor(hour_to)),int((hour_to%1) * 60))
@@ -96,17 +90,14 @@ class resource_calendar(osv.osv):
resource_leave_ids = self.pool.get('resource.calendar.leaves').search(cr,uid,[('resource_id','=',resource)])
if resource_leave_ids:
res_leaves = self.pool.get('resource.calendar.leaves').read(cr,uid,resource_leave_ids,['date_from','date_to'])
- print 'Leave Details',res_leaves
for i in range(len(res_leaves)):
dtf = mx.DateTime.strptime(res_leaves[i]['date_from'],'%Y-%m-%d %H:%M:%S')
dtt = mx.DateTime.strptime(res_leaves[i]['date_to'],'%Y-%m-%d %H:%M:%S')
no = dtt - dtf
leave_days = no.days + 1
- print 'No Of Leaves:::::::::',int(leave_days)
for x in range(int(leave_days)):
dt_leave.append((dtf + mx.DateTime.RelativeDateTime(days=x)).strftime('%Y-%m-%d'))
dt_leave.sort()
- print 'Sorted Leave Dates::::',dt_leave
todo = hours
cycle = 0
result = []
@@ -123,11 +114,8 @@ class resource_calendar(osv.osv):
d2 = mx.DateTime.DateTime(dt_from.year,dt_from.month,dt_from.day,int(math.floor(hour_to)),int((hour_to%1) * 60))
dt1 = d1.strftime('%Y-%m-%d')
dt2 = d2.strftime('%Y-%m-%d')
- print 'Date 1',dt1
- print 'Date 2',dt2
for i in range(len(dt_leave)):
if dt1 == dt_leave[i]:
- print 'Leave::::::::'
dt_from += mx.DateTime.RelativeDateTime(days=1)
d1 = mx.DateTime.DateTime(dt_from.year,dt_from.month,dt_from.day,int(math.floor(m)),int((m%1) * 60))
d2 = mx.DateTime.DateTime(dt_from.year,dt_from.month,dt_from.day,int(math.floor(hour_to)),int((hour_to%1) * 60))
@@ -161,14 +149,14 @@ class resource_resource(osv.osv):
_name = "resource.resource"
_description = "Resource Detail"
_columns = {
- 'name' : fields.char("Name", size=64, required=True),
+ 'name' : fields.char("Name", size=64, required=True ),
'code': fields.char('Code', size=16),
'active' : fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the resource record without removing it."),
'company_id' : fields.many2one('res.company', 'Company', required=True),
'resource_type': fields.selection([('user','Human'),('material','Material')], 'Resource Type', required=True),
- 'user_id' : fields.many2one('res.users', 'User'),
- 'time_efficiency' : fields.float('Efficiency factor', size=8, help="This field depict the efficency of the ressource to complete tasks. e.g ressource put alone on a phase of 5 days with 5 tasks assigned to him, will show a load of 100% for this phase by default, but if we put a efficency of 200%, then his load will only be 50%."),
- 'calendar_id' : fields.many2one("resource.calendar", "Working time", required=True, help="Define the schedule of resource"),
+ 'user_id' : fields.many2one('res.users', 'User',help='Related user name for the resource to manage its access.'),
+ 'time_efficiency' : fields.float('Efficiency factor', size=8, help="This field depict the efficiency of the resource to complete tasks. e.g resource put alone on a phase of 5 days with 5 tasks assigned to him, will show a load of 100% for this phase by default, but if we put a efficency of 200%, then his load will only be 50%."),
+ 'calendar_id' : fields.many2one("resource.calendar", "Working time", help="Define the schedule of resource"),
}
_defaults = {
'resource_type' : lambda *a: 'user',
@@ -183,8 +171,7 @@ class resource_calendar_leaves(osv.osv):
_description = "Leave Detail"
_columns = {
'name' : fields.char("Name", size=64),
- 'company_id' : fields.related('calendar_id','company_id',type='many2one',relation='res.company',string="Company",required=True),
- #'company_id':fields.many2one('res.company', 'Company', required=True),
+ 'company_id' : fields.related('calendar_id','company_id',type='many2one',relation='res.company',string="Company",readonly=True),
'calendar_id' : fields.many2one("resource.calendar", "Working time"),
'date_from' : fields.datetime('Start Date', required=True),
'date_to' : fields.datetime('End Date', required=True),
From 386ce8c18e59afa6a991ce62e11dd0c34d0cc81b Mon Sep 17 00:00:00 2001
From: "Rvo (Open ERP)"
Date: Mon, 18 Jan 2010 18:36:09 +0530
Subject: [PATCH 7/9] [FIX]:Removed the scheduler method compute_date from
project__terp__.py
bzr revid: rvo@tinyerp.co.in-20100118130609-5hqc8dl0detz72y7
---
addons/project/__terp__.py | 2 +-
addons/project/project.py | 7 ++++++-
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/addons/project/__terp__.py b/addons/project/__terp__.py
index 97a4c94deb0..1a11e64f134 100644
--- a/addons/project/__terp__.py
+++ b/addons/project/__terp__.py
@@ -42,7 +42,7 @@ works done on tasks, eso. It is able to render planning, order tasks, eso.
"process/task_process.xml"
],
'demo_xml': [#'project_demo.xml'
- 'project_data_scheduler.xml'
+
],
'installable': True,
'active': False,
diff --git a/addons/project/project.py b/addons/project/project.py
index 4081524f0ec..95a8c9497e7 100644
--- a/addons/project/project.py
+++ b/addons/project/project.py
@@ -21,12 +21,17 @@
from lxml import etree
import mx.DateTime
+import datetime
import time
from tools.translate import _
-
from osv import fields, osv
from tools.translate import _
+#from resource.faces import *
+#from resource.faces.lib import workbreakdown
+#from resource.faces.lib import generator
+#from resource.faces.lib import resource
+
class project(osv.osv):
_name = "project.project"
_description = "Project"
From cfe2942d8ab2170dc1c412ebfb9288f4114a592e Mon Sep 17 00:00:00 2001
From: "pap (openerp)"
Date: Mon, 18 Jan 2010 19:14:53 +0530
Subject: [PATCH 8/9] [IMP]: 1) start_date < end_date in leave form 2) remove
duplicate fields from mrp.workcenter 3) remove recursion in project phases,
start_date < end_date start_date < end_date in project.task and
project.project
bzr revid: pap@tinyerp.co.in-20100118134453-uptuohuxvyqhizfq
---
addons/mrp/mrp.py | 5 +-
addons/mrp/mrp_view.xml | 2 +-
addons/project/project.py | 40 ++++++++++++++--
addons/project/project_view.xml | 6 ++-
addons/project_long_term/project.py | 72 +++++++++++++++++++----------
addons/resource/resource.py | 11 ++++-
6 files changed, 101 insertions(+), 35 deletions(-)
diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py
index 726d5a3e34e..c3a272f06ca 100644
--- a/addons/mrp/mrp.py
+++ b/addons/mrp/mrp.py
@@ -42,7 +42,7 @@ class mrp_workcenter(osv.osv):
_description = 'Work Center'
_inherits = {'resource.resource':"resource_id"}
_columns = {
- 'name': fields.char('Work Center Name', size=64, required=True),
+# 'name': fields.char('Work Center Name', size=64, required=True),
'note': fields.text('Description', help="Description of the workcenter. Explain here what's a cycle according to this workcenter."),
'capacity_per_cycle': fields.float('Capacity per Cycle', help="Number of operations this workcenter can do in parallel. If this workcenter represents a team of 5 workers, the capacity per cycle is 5."),
'time_cycle': fields.float('Time for 1 cycle (hour)', help="Time in hours for doing one cycle."),
@@ -56,7 +56,8 @@ class mrp_workcenter(osv.osv):
help="Complete this only if you want automatic analytic accounting entries on production orders."),
'costs_journal_id': fields.many2one('account.analytic.journal', 'Analytic Journal'),
'costs_general_account_id': fields.many2one('account.account', 'General Account', domain=[('type','<>','view')]),
- 'company_id': fields.many2one('res.company','Company',required=True),
+# 'company_id': fields.many2one('res.company','Company',required=True),
+ 'resource_id': fields.many2one('resource.resource','Resource',ondelete='cascade'),
}
_defaults = {
'capacity_per_cycle': lambda *a: 1.0,
diff --git a/addons/mrp/mrp_view.xml b/addons/mrp/mrp_view.xml
index 7c567ef0b7a..0e7ff6db167 100644
--- a/addons/mrp/mrp_view.xml
+++ b/addons/mrp/mrp_view.xml
@@ -114,7 +114,7 @@
-
+
diff --git a/addons/project/project.py b/addons/project/project.py
index 95a8c9497e7..89cf75e454c 100644
--- a/addons/project/project.py
+++ b/addons/project/project.py
@@ -130,6 +130,16 @@ class project(osv.osv):
# 'state': lambda *a: 'open',
# 'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'project.project', context=c)
}
+ def _check_dates(self, cr, uid, ids):
+ leave = self.read(cr, uid, ids[0],['date_start','date'])
+ if leave['date_start'] and leave['date']:
+ if leave['date_start'] > leave['date']:
+ return False
+ return True
+
+ _constraints = [
+ (_check_dates, 'Error! project start-date must be lower then project end-date.', ['date_start', 'date'])
+ ]
# _order = "parent_id,priority,name"
# _constraints = [
@@ -221,6 +231,32 @@ class task(osv.osv):
_description = "Tasks"
_date_name = "date_start"
+# def compute_date(self,cr,uid):
+# project_id = self.pool.get('project.project').search(cr,uid,[])
+# for i in range(len(project_id)):
+# task_ids = self.pool.get('project.task').search(cr,uid,[('project_id','=',project_id[i])])
+# if task_ids:
+# task_obj = self.pool.get('project.task').browse(cr,uid,task_ids)
+# task_1 = task_obj[0]
+# task_1.date_start = self.pool.get('project.project').browse(cr,uid,project_id[i]).date_start
+## print '1st Date Start::::',task_1.date_start,type(task_1.date_start)
+# dt = mx.DateTime.strptime(task_1.date_start,"%Y-%m-%d").strftime("%Y-%m-%d")
+## print 'Hours:::::',task_1.planned_hours
+## print 'Date',dt
+# def Project_1():
+# title = "New Project"
+# start = dt
+#
+# def task1():
+# start = dt
+# effort = task_1.planned_hours
+# title = "Task 1"
+## project_1 = BalancedProject(Project_1)
+## print 'Title::::::',project_1.title
+## for t in project_1:
+## print 'details:::',t.indent_name(), t.start, t.end, t.effort
+
+
def _str_get(self, task, level=0, border='***', context={}):
return border+' '+(task.user_id and task.user_id.name.upper() or '')+(level and (': L'+str(level)) or '')+(' - %.1fh / %.1fh'%(task.effective_hours or 0.0,task.planned_hours))+' '+border+'\n'+ \
border[0]+' '+(task.name or '')+'\n'+ \
@@ -266,14 +302,10 @@ class task(osv.osv):
if date_start and planned:
resource_id = self.pool.get('resource.resource').search(cr,uid,[('user_id','=',res.user_id.id)])
resource_obj = self.pool.get('resource.resource').browse(cr,uid,resource_id)[0]
- print 'Resource Calendar::::',resource_obj.calendar_id.id
d = mx.DateTime.strptime(date_start,'%Y-%m-%d %H:%M:%S')
hrs = (planned)/(occupation_rate)
- print 'Hours::::',hrs
work_times = self.pool.get('resource.calendar').interval_get(cr, uid, resource_obj.calendar_id.id or False, d, hrs or 0.0, resource_obj.id)
- print 'Date_end',work_times
result['date_end'] = work_times[-1][1].strftime('%Y-%m-%d %H:%M:%S')
- print 'Date End',result['date_end']
result['remaining_hours'] = planned-effective
return {'value':result}
diff --git a/addons/project/project_view.xml b/addons/project/project_view.xml
index fe6122bd559..5dffaac2b34 100644
--- a/addons/project/project_view.xml
+++ b/addons/project/project_view.xml
@@ -309,8 +309,9 @@
-
-
+
+
+
@@ -324,6 +325,7 @@
+
diff --git a/addons/project_long_term/project.py b/addons/project_long_term/project.py
index f04e18babfd..c5734263ea5 100644
--- a/addons/project_long_term/project.py
+++ b/addons/project_long_term/project.py
@@ -33,32 +33,44 @@ class project_phase(osv.osv):
_description = "Project Phase"
def _check_recursion(self,cr,uid,ids):
- level = 100
- while len(ids):
- cr.execute('select distinct next_phase_id from project_phase_next_rel where phase_id in ('+','.join(map(str, ids))+')')
- ids = filter(None, map(lambda x:x[0], cr.fetchall()))
- next_ids = ids
- while(next_ids):
- cr.execute('select distinct prev_phase_id from project_phase_prev_rel where phase_id in ('+','.join(map(str, ids))+')')
- prev_ids = filter(None, map(lambda x:x[0], cr.fetchall()))
-
- return True
-
- while(ids):
- cr.execute('select distinct child_id from account_account_consol_rel where parent_id in ('+','.join(map(str, ids))+')')
- child_ids = filter(None, map(lambda x: x[0], cr.fetchall()))
- c_ids = child_ids
- if (p_id and (p_id in c_ids)) or (obj_self.id in c_ids):
- return False
- while len(c_ids):
- s_ids = self.search(cr, uid, [('parent_id', 'in', c_ids)])
- if p_id and (p_id in s_ids):
- return False
- c_ids = s_ids
- ids = child_ids
- return True
-
+ obj_self = self.browse(cr, uid, ids[0])
+ prev_ids = obj_self.previous_phase_ids
+ next_ids = obj_self.next_phase_ids
+ #it should nither be in prev_ids nor in next_ids
+ if (obj_self in prev_ids) or (obj_self in next_ids):
+ return False
+ ids = [id for id in prev_ids if id in next_ids]
+
+ #both prev_ids and next_ids must be unique
+ if ids:
+ return False
+ #unrelated project
+
+ prev_ids = [rec.id for rec in prev_ids]
+ next_ids = [rec.id for rec in next_ids]
+ #iter prev_ids
+ while prev_ids:
+ cr.execute('select distinct prv_phase_id from project_phase_previous_rel where phase_id in ('+','.join(map(str, prev_ids))+')')
+ prv_phase_ids = filter(None, map(lambda x: x[0], cr.fetchall()))
+ if obj_self.id in prv_phase_ids:
+ return False
+ ids = [id for id in prv_phase_ids if id in next_ids]
+ if ids:
+ return False
+ prev_ids = prv_phase_ids
+
+ #iter next_ids
+ while next_ids:
+ cr.execute('select distinct next_phase_id from project_phase_next_rel where phase_id in ('+','.join(map(str, next_ids))+')')
+ next_phase_ids = filter(None, map(lambda x: x[0], cr.fetchall()))
+ if obj_self.id in next_phase_ids:
+ return False
+ ids = [id for id in next_phase_ids if id in prev_ids]
+ if ids:
+ return False
+ next_ids = next_phase_ids
+ return True
_columns = {
'name': fields.char("Phase Name", size=64, required=True),
@@ -113,6 +125,16 @@ class task(osv.osv):
_columns = {
'phase_id': fields.many2one('project.phase', 'Project Phase')
}
+ def _check_dates(self, cr, uid, ids):
+ leave = self.read(cr, uid, ids[0],['date_start','date_end'])
+ if leave['date_start'] and leave['date_end']:
+ if leave['date_start'] > leave['date_end']:
+ return False
+ return True
+
+ _constraints = [
+ (_check_dates, 'Error! task start-date must be lower then task end-date.', ['date_start', 'date_end'])
+ ]
task()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/resource/resource.py b/addons/resource/resource.py
index dad8aedf5cf..7ac36e5e7bd 100755
--- a/addons/resource/resource.py
+++ b/addons/resource/resource.py
@@ -176,7 +176,16 @@ class resource_calendar_leaves(osv.osv):
'date_from' : fields.datetime('Start Date', required=True),
'date_to' : fields.datetime('End Date', required=True),
'resource_id' : fields.many2one("resource.resource", "Resource", help="If empty, this is a generic holiday for the company. If a resource is set, the holiday/leave is only for this resource"),
-
}
+ def check_dates(self, cr, uid, ids):
+ leave = self.read(cr, uid, ids[0],['date_from','date_to'])
+ if leave['date_from'] and leave['date_to']:
+ if leave['date_from'] > leave['date_to']:
+ return False
+ return True
+
+ _constraints = [
+ (check_dates, 'Error! leave start-date must be lower then leave end-date.', ['date_from', 'date_to'])
+ ]
resource_calendar_leaves()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
From aa41d4010c1dbd338f0133a1176a90f3c4090e0b Mon Sep 17 00:00:00 2001
From: "pap (openerp)"
Date: Mon, 18 Jan 2010 19:46:37 +0530
Subject: [PATCH 9/9] [REM]:removed print statement
bzr revid: pap@tinyerp.co.in-20100118141637-lo24jfayx1qxr6fx
---
addons/hr_holidays/hr.py | 1 -
1 file changed, 1 deletion(-)
diff --git a/addons/hr_holidays/hr.py b/addons/hr_holidays/hr.py
index a77eb046a33..ff33621cbe0 100755
--- a/addons/hr_holidays/hr.py
+++ b/addons/hr_holidays/hr.py
@@ -165,7 +165,6 @@ class hr_holidays(osv.osv):
_order = 'date_from desc'
def create(self, cr, uid, vals, context={}):
- print 'create', vals, context
if context:
if context.has_key('type'):
vals['type'] = context['type']