[MERGE] trunk-dev-addons2 branch

bzr revid: hmo@tinyerp.com-20100927114233-jz3ovtj6s8ut2m4n
This commit is contained in:
Harry (OpenERP)
2010-09-27 17:12:33 +05:30
111 changed files with 1820 additions and 2111 deletions
+1 -1
View File
@@ -73,7 +73,7 @@
</separator>
<xpath expr="//label[@string='description']" position="attributes">
<attribute name="string">Add extra Accounting Addons to the ones already installed. Remember you can always install them at a later stage.</attribute>
<attribute name="string">Add extra Accounting functionalities to the ones already installed.</attribute>
</xpath>
<xpath expr="//button[@string='Install Modules']" position="attributes">
<attribute name="string">Configure</attribute>
+1 -1
View File
@@ -72,7 +72,7 @@
<field name="priority">2</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<page string="Notes" position="before">
<page string="History" position="before">
<page string="Accounting">
<group col="2" colspan="2">
<separator string="Customer Accounting Properties" colspan="2"/>
+10 -5
View File
@@ -27,13 +27,18 @@ class profile_association_config_install_modules_wizard(osv.osv_memory):
_inherit = 'res.config.installer'
_columns = {
'hr_expense':fields.boolean('Expenses Tracking', help="Tracks the personal expenses process, from the employee expense encoding, to the reimbursement of the employee up to the reinvoicing to the final customer."),
'project':fields.boolean('Project Management'),
'event_project':fields.boolean('Organization and management of Events', help="This module allows you to create retro planning for managing your events."),
'hr_expense':fields.boolean('Expenses Tracking', help="Tracks and manages employee expenses, and can "
"automatically re-invoice clients if the expenses are "
"project-related."),
'project':fields.boolean('Project Management',
help="Helps you manage your projects and tasks by tracking them, "
"generating plannings, etc..."),
'event_project':fields.boolean('Events', help="Helps you to manage and organize your events."),
'project_gtd':fields.boolean('Getting Things Done',
help="GTD is a methodology to efficiently organise yourself and your tasks. This module fully integrates GTD principle with OpenERP's project management."),
'wiki': fields.boolean('Wiki',
help="An integrated wiki content management system. This is really usefull to manage FAQ, quality manuals, etc.")
'wiki': fields.boolean('Wiki', help="Lets you create wiki pages and page groups in order "
"to keep track of business knowledge and share it with "
"and between your employees."),
}
profile_association_config_install_modules_wizard()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -14,11 +14,13 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Action Rule">
<field name="name"/>
<field name="model_id" select="1" on_change="onchange_model_id(model_id)"/>
<field name="filter_id" />
<field name="sequence"/>
<field name="active"/>
<group col="6" colspan="4">
<field name="name"/>
<field name="model_id" select="1" on_change="onchange_model_id(model_id)"/>
<field name="filter_id" />
<field name="sequence"/>
<field name="active"/>
</group>
<notebook colspan="4">
<page string="Conditions">
<group col="2" colspan="2" name="model">
+14 -11
View File
@@ -128,6 +128,11 @@
<field name="event_date" select="1"/>
<newline/>
<group expand="0" string="Group By...">
<filter string="Responsible" icon="terp-personal" domain="[]"
context="{'group_by':'user_id'}" />
<filter string="Contact" icon="terp-partner" domain="[]"
context="{'group_by':'partner_address_id'}" />
<separator orientation="vertical" />
<filter string="Type" icon="terp-stock_symbol-selection" help="Invitation Type"
domain="[]" context="{'group_by':'cutype'}" />
<filter string="Role" icon="terp-gtk-select-all"
@@ -135,10 +140,6 @@
<filter string="Required Reply" icon="terp-mail-replied"
domain="[]" context="{'group_by':'rsvp'}" />
<separator orientation="vertical" />
<filter string="User" icon="terp-personal" domain="[]"
context="{'group_by':'user_id'}" />
<filter string="Contact" icon="terp-gtk-jump-to-ltr" domain="[]"
context="{'group_by':'partner_address_id'}" />
<filter string="State" icon="terp-stock_effects-object-colorize" help="Invitation Type"
domain="[]" context="{'group_by':'state'}" />
</group>
@@ -457,21 +458,23 @@
<field name="user_id" select="1"/>
<separator orientation="vertical"/>
<field name="show_as" select="1"/>
<field name="class" select="1"/>
<field name="class" select="1" string="Privacy"/>
</group>
<newline/>
<group expand="0" string="Group By...">
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]"
context="{'group_by':'state'}" />
<filter string="Date" icon="terp-go-month"
domain="[]" context="{'group_by':'date'}" />
<filter string="Responsible" icon="terp-personal" domain="[]"
context="{'group_by':'user_id'}" />
<separator orientation="vertical" />
<filter string="Availability" icon="terp-camera_test"
domain="[]" context="{'group_by':'show_as'}" />
<filter string="Privacy" icon="terp-locked"
domain="[]" context="{'group_by':'class'}" />
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]"
context="{'group_by':'state'}" />
<separator orientation="vertical" />
<filter string="Responsible" icon="terp-personal" domain="[]"
context="{'group_by':'user_id'}" />
<filter string="Date" icon="terp-go-month"
domain="[]" context="{'group_by':'date'}" />
</group>
</search>
</field>
+2 -2
View File
@@ -58,7 +58,7 @@ class base_setup_installer(osv.osv_memory):
help="Helps you manage your purchase-related processes such as "
"requests for quotations, supplier invoices, etc..."),
'hr':fields.boolean('Human Resources',
help="Helps you manage your human resources by encoding your employees structure, generating work sheets, tracking attendance and more"),
help="Helps you manage your human resources by encoding your employees structure, generating work sheets, tracking attendance and more."),
'point_of_sale':fields.boolean('Point of Sales',
help="Helps you get the most out of your points of sales with "
"fast sale encoding, simplified payment mode encoding, "
@@ -74,7 +74,7 @@ class base_setup_installer(osv.osv_memory):
# Vertical modules
'product_expiry':fields.boolean('Food Industry',
help="Installs a preselected set of OpenERP applications "
"which will help you manage your industry"),
"which will help you manage your industry."),
'association':fields.boolean('Associations',
help="Installs a preselected set of OpenERP "
"applications which will help you manage your association "
+120 -64
View File
@@ -103,7 +103,12 @@ class node_calendar_collection(nodes.node_dir):
class node_calendar(nodes.node_class):
our_type = 'collection'
DAV_PROPS = {
"http://calendarserver.org/ns/" : ('getctag',),
"DAV:": ('principal-collection-set'),
"http://cal.me.com/_namespace/" : ('user-state'),
"http://calendarserver.org/ns/" : (
'dropbox-home-URL',
'notification-URL',
'getctag',),
'http://groupdav.org/': ('resourcetype',),
"urn:ietf:params:xml:ns:caldav" : (
'calendar-description',
@@ -114,6 +119,7 @@ class node_calendar(nodes.node_class):
'schedule-outbox-URL',)}
DAV_M_NS = {
"DAV:" : '_get_dav',
"http://cal.me.com/_namespace/": '_get_dav',
'http://groupdav.org/': '_get_gdav',
"http://calendarserver.org/ns/" : '_get_dav',
"urn:ietf:params:xml:ns:caldav" : '_get_caldav'}
@@ -134,6 +140,35 @@ class node_calendar(nodes.node_class):
result = self._get_ttag(cr) + ':' + str(time.time())
return str(result)
def _get_dav_dropbox_home_URL(self, cr):
import xml.dom.minidom
import urllib
uid = self.context.uid
ctx = self.context.context.copy()
ctx.update(self.dctx)
calendar_obj = self.context._dirobj.pool.get('basic.calendar')
calendar = calendar_obj.browse(cr, uid, self.calendar_id, context=ctx)
res = '%s/%s' %(calendar.collection_id.name, calendar.name)
url = urllib.quote('/%s/%s' % (cr.dbname, res))
return url
def _get_dav_notification_URL(self, cr):
import xml.dom.minidom
import urllib
uid = self.context.uid
ctx = self.context.context.copy()
ctx.update(self.dctx)
calendar_obj = self.context._dirobj.pool.get('basic.calendar')
calendar = calendar_obj.browse(cr, uid, self.calendar_id, context=ctx)
res = '%s/%s' %(calendar.collection_id.name, calendar.name)
url = urllib.quote('/%s/%s' % (cr.dbname, res))
return url
def _get_dav_user_state(self, cr):
#TODO
return True
def get_dav_resourcetype(self, cr):
res = [ ('collection', 'DAV:'),
(str(self.cal_type + '-collection'), 'http://groupdav.org/'),
@@ -258,6 +293,86 @@ class node_calendar(nodes.node_class):
def rmcol(self, cr):
return False
def _get_caldav_calendar_data(self, cr):
res = []
for child in self.children(cr):
res.append(child._get_caldav_calendar_data(cr))
return res
def _get_caldav_calendar_description(self, cr):
uid = self.context.uid
calendar_obj = self.context._dirobj.pool.get('basic.calendar')
ctx = self.context.context.copy()
ctx.update(self.dctx)
calendar = calendar_obj.browse(cr, uid, self.calendar_id, context=ctx)
return calendar.description
def _get_dav_principal_collection_set(self, uri):
import urllib
uid = self.context.uid
ctx = self.context.context.copy()
ctx.update(self.dctx)
calendar_obj = self.context._dirobj.pool.get('basic.calendar')
calendar = calendar_obj.browse(cr, uid, self.calendar_id, context=ctx)
res = '%s/%s' %(calendar.collection_id.name, calendar.name)
doc = xml.dom.minidom.getDOMImplementation().createDocument(None, 'href', None)
href = doc.documentElement
href.tagName = 'D:href'
huri = doc.createTextNode(urllib.quote('/%s/%s' % (cr.dbname, res)))
href.appendChild(huri)
return href
def _get_caldav_calendar_home_set(self, cr):
import xml.dom.minidom
import urllib
uid = self.context.uid
ctx = self.context.context.copy()
ctx.update(self.dctx)
doc = xml.dom.minidom.getDOMImplementation().createDocument(None, 'href', None)
calendar_obj = self.context._dirobj.pool.get('basic.calendar')
calendar = calendar_obj.browse(cr, uid, self.calendar_id, context=ctx)
huri = doc.createTextNode(urllib.quote('/%s/%s' % (cr.dbname, calendar.collection_id.name)))
href = doc.documentElement
href.tagName = 'D:href'
href.appendChild(huri)
return href
def _get_caldav_calendar_user_address_set(self, cr):
import xml.dom.minidom
dirobj = self.context._dirobj
uid = self.context.uid
ctx = self.context.context.copy()
ctx.update(self.dctx)
user_obj = self.context._dirobj.pool.get('res.users')
user = user_obj.browse(cr, uid, uid, context=ctx)
doc = xml.dom.minidom.getDOMImplementation().createDocument(None, 'href', None)
href = doc.documentElement
href.tagName = 'D:href'
huri = doc.createTextNode('MAILTO:' + str(user.email) or str(user.name))
href.appendChild(huri)
return href
def _get_caldav_schedule_outbox_URL(self, cr):
return self._get_caldav_schedule_inbox_URL(cr)
def _get_caldav_schedule_inbox_URL(self, cr):
import xml.dom.minidom
import urllib
uid = self.context.uid
ctx = self.context.context.copy()
ctx.update(self.dctx)
calendar_obj = self.context._dirobj.pool.get('basic.calendar')
calendar = calendar_obj.browse(cr, uid, self.calendar_id, context=ctx)
res = '%s/%s' %(calendar.collection_id.name, calendar.name)
doc = xml.dom.minidom.getDOMImplementation().createDocument(None, 'href', None)
href = doc.documentElement
href.tagName = 'D:href'
huri = doc.createTextNode(urllib.quote('/%s/%s' % (cr.dbname, res)))
href.appendChild(huri)
return href
class res_node_calendar(nodes.node_class):
our_type = 'file'
@@ -309,6 +424,9 @@ class res_node_calendar(nodes.node_class):
context.update({'model': self.model, 'res_id':self.res_id})
res = calendar_obj.export_cal(cr, uid, [self.calendar_id], context=context)
return res
def _get_caldav_calendar_data(self, cr):
return self.get_data(cr)
def get_data_len(self, cr, fil_obj = None):
return self.content_length
@@ -327,67 +445,6 @@ class res_node_calendar(nodes.node_class):
res = '%d' % (self.calendar_id)
return res
def _get_caldav_calendar_data(self, cr):
return self.get_data(cr)
def _get_caldav_calendar_description(self, cr):
uid = self.context.uid
calendar_obj = self.context._dirobj.pool.get('basic.calendar')
ctx = self.context.context.copy()
ctx.update(self.dctx)
calendar = calendar_obj.browse(cr, uid, self.calendar_id, context=ctx)
return calendar.description
def _get_caldav_calendar_home_set(self, cr):
import xml.dom.minidom
import urllib
uid = self.context.uid
ctx = self.context.context.copy()
ctx.update(self.dctx)
doc = xml.dom.minidom.getDOMImplementation().createDocument(None, 'href', None)
calendar_obj = self.context._dirobj.pool.get('basic.calendar')
calendar = calendar_obj.browse(cr, uid, self.calendar_id, context=ctx)
huri = doc.createTextNode(urllib.quote('/%s/%s' % (cr.dbname, calendar.collection_id.name)))
href = doc.documentElement
href.tagName = 'D:href'
href.appendChild(huri)
return href
def _get_caldav_calendar_user_address_set(self, cr):
import xml.dom.minidom
dirobj = self.context._dirobj
uid = self.context.uid
ctx = self.context.context.copy()
ctx.update(self.dctx)
user_obj = self.context._dirobj.pool.get('res.users')
user = user_obj.browse(cr, uid, uid, context=ctx)
doc = xml.dom.minidom.getDOMImplementation().createDocument(None, 'href', None)
href = doc.documentElement
href.tagName = 'D:href'
huri = doc.createTextNode('MAILTO:' + user.email)
href.appendChild(huri)
return href
def _get_caldav_schedule_inbox_URL(self, cr):
import xml.dom.minidom
import urllib
uid = self.context.uid
ctx = self.context.context.copy()
ctx.update(self.dctx)
calendar_obj = self.context._dirobj.pool.get('basic.calendar')
calendar = calendar_obj.browse(cr, uid, self.calendar_id, context=ctx)
res = '%s/%s' %(calendar.name, calendar.collection_id.name)
doc = xml.dom.minidom.getDOMImplementation().createDocument(None, 'href', None)
href = doc.documentElement
href.tagName = 'D:href'
huri = doc.createTextNode(urllib.quote('/%s/%s' % (cr.dbname, res)))
href.appendChild(huri)
return href
def rm(self, cr):
uid = self.context.uid
@@ -401,7 +458,6 @@ class res_node_calendar(nodes.node_class):
return res
def _get_caldav_schedule_outbox_URL(self, cr):
return self._get_caldav_schedule_inbox_URL(cr)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4
+1 -1
View File
@@ -453,7 +453,7 @@ class CalDAV(object):
else:
for key1, val1 in self.ical_get(field, 'mapping').items():
if val1 == data[map_field]:
vevent.add(field).value = key1
vevent.add(field).value = key1.upper()
return vevent
def check_import(self, cr, uid, vals, context=None):
+2 -2
View File
@@ -587,7 +587,7 @@ class crm_case_categ(osv.osv):
_description = "Category of case"
_columns = {
'name': fields.char('Case Category Name', size=64, required=True, translate=True),
'name': fields.char('Name', size=64, required=True, translate=True),
'section_id': fields.many2one('crm.case.section', 'Sales Team'),
'object_id': fields.many2one('ir.model', 'Object Name'),
}
@@ -636,7 +636,7 @@ class crm_case_stage(osv.osv):
'section_id': fields.many2one('crm.case.section', 'Sales Team'),
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of case stages."),
'object_id': fields.many2one('ir.model', 'Object Name'),
'probability': fields.float('Probability (%)', required=True),
'probability': fields.float('Probability (%)', required=True, help="This percentage depicts the default/average probability of the Case for this stage to be a success"),
'on_change': fields.boolean('Change Probability Automatically', \
help="Change Probability on next and previous stages."),
'requirements': fields.text('Requirements')
+5 -5
View File
@@ -33,15 +33,15 @@ class crm_installer(osv.osv_memory):
_columns = {
'name': fields.char('Name', size=64),
'crm_helpdesk': fields.boolean('Helpdesk', help="Manages an Helpdesk service."),
'crm_helpdesk': fields.boolean('Helpdesk', help="Manages a Helpdesk service."),
'crm_fundraising': fields.boolean('Fundraising', help="This may help associations in their fundraising process and tracking."),
'crm_claim': fields.boolean('Claims', help="Manages the suppliers and customers claims, including your corrective or preventive actions."),
'crm_caldav': fields.boolean('Calendar Synchronizing', help="Helps you to synchronize the meetings with other calendar clients and mobiles."),
'sale_crm': fields.boolean('Opportunity to Quotation', help="This module relates sale from opportunity cases in the CRM."),
'fetchmail': fields.boolean('Fetch Emails', help="Fetchmail Server."),
'thunderbird': fields.boolean('Thunderbird', help="Allows you to link your e-mail to OpenERP's documents. You can attach it to any existing one in OpenERP or create a new one"),
'outlook': fields.boolean('MS-Outlook', help="Allows you to link your e-mail to OpenERP's documents. You can attach it to any existing one in OpenERP or create a new one"),
'wiki_sale_faq': fields.boolean('Sale FAQ', help="Sale FAQ."),
'fetchmail': fields.boolean('Fetch Emails', help="Allows you to receive E-Mails from POP/IMAP server."),
'thunderbird': fields.boolean('Thunderbird', help="Allows you to link your e-mail to OpenERP's documents. You can attach it to any existing one in OpenERP or create a new one."),
'outlook': fields.boolean('MS-Outlook', help="Allows you to link your e-mail to OpenERP's documents. You can attach it to any existing one in OpenERP or create a new one."),
'wiki_sale_faq': fields.boolean('Sale FAQ', help="Helps you manage wiki pages for Frequently Asked Questions on Sales Application."),
}
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
+1 -1
View File
@@ -16,7 +16,7 @@
</separator>
<xpath expr="//label[@string='description']"
position="attributes">
<attribute name="string">Enhance your CRM basic Application with additional Addons.</attribute>
<attribute name="string">Enhance your core CRM Application with additional functionalities.</attribute>
</xpath>
<xpath expr='//separator[@string="vsep"]' position='attributes'>
<attribute name='rowspan'>13</attribute>
+1
View File
@@ -125,6 +125,7 @@ class crm_lead(crm_case, osv.osv):
domain="['|',('section_id','=',section_id),('section_id','=',False)]"),
'channel_id': fields.many2one('res.partner.canal', 'Channel'),
'contact_name': fields.char('Contact Name', size=64),
'partner_name': fields.char("Partner Name", size=64),
'optin': fields.boolean('Opt-In'),
'optout': fields.boolean('Opt-Out'),
+12 -8
View File
@@ -55,7 +55,7 @@
<field name="arch" type="xml">
<form string="Leads Form">
<group colspan="4" col="7">
<field name="name" required="1" string="Name"/>
<field name="name" required="1" string="Subject"/>
<field name="priority"/>
<field name="categ_id"
widget="selection"
@@ -83,9 +83,12 @@
</group>
<notebook colspan="4">
<page string="Lead">
<group colspan="4" col="2">
<field name="partner_name" string="Partner Name" />
</group>
<group colspan="2" col="4">
<separator string="Contact" colspan="4" col="4"/>
<field name="partner_name" colspan="4"/>
<field name="contact_name" colspan="4"/>
<newline/>
<field domain="[('domain', '=', 'contact')]" name="title"/>
<field name="function" />
@@ -211,7 +214,7 @@
</notebook>
</form>
</field>
<button string="Add New Note"
<button string="Add Internal Note"
name="%(crm.action_crm_add_note)d"
context="{'model': 'crm.lead' }"
icon="terp-document-new" type="action" />
@@ -235,8 +238,8 @@
<tree string="Leads" colors="blue:state=='pending';grey:state in ('cancel', 'done')">
<field name="date_deadline" invisible="1"/>
<field name="create_date"/>
<field name="name"/>
<field name="partner_name"/>
<field name="name" string="Subject"/>
<field name="contact_name"/>
<field name="country_id" invisible="context.get('invisible_country', True)" />
<field name="email_from"/>
<field name="phone"/>
@@ -299,7 +302,7 @@
<search string="Search Leads">
<filter icon="terp-check"
string="Current"
default="1" name="current"
default="1" name="current" help="Draft and Open Leads"
domain="[('state','in',('draft','open'))]"/>
<filter icon="terp-camera_test"
string="Open"
@@ -317,7 +320,7 @@
domain="[('create_date','&lt;', time.strftime('%%Y-%%m-%%d 23:59:59')),('create_date','&gt;=',(datetime.date.today()-datetime.timedelta(days=7)).strftime('%%Y-%%m-%%d 00:00:00'))]"
/>
<separator orientation="vertical"/>
<field name="name"/>
<field name="name" string="Subject"/>
<field name="partner_name"/>
<field name="email_from"/>
<field name="user_id">
@@ -337,6 +340,7 @@
help="Show Sales Team"/>
</field>
<newline/>
<group expand="0" string="Extended Filters..." groups="base.group_extended">
<field name="stage_id" widget="selection" domain="[('object_id.model', '=', 'crm.lead')]"/>
<field name="categ_id" widget="selection" domain="[('object_id.model', '=', 'crm.lead')]"/>
@@ -365,7 +369,7 @@
<filter string="Salesman" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>
<filter string="Referrer" icon="terp-personal" domain="[]" context="{'group_by':'referred'}"/>
<separator orientation="vertical"/>
<filter string="Creation" icon="terp-go-month"
<filter string="Creation Month" icon="terp-go-month"
domain="[]" context="{'group_by':'create_date'}" />
</group>
</search>
+20 -21
View File
@@ -317,32 +317,31 @@
</field>
<field name="user_id" select="1"/>
</group>
<newline/>
<group expand="0" string="Group By...">
<filter string="Date" icon="terp-go-month"
domain="[]" context="{'group_by':'date'}" />
<filter string="Privacy" icon="terp-locked"
domain="[]" context="{'group_by':'class'}" />
<filter string="Show time as" icon="terp-project"
domain="[]" context="{'group_by':'show_as'}" />
<separator orientation="vertical" />
<filter string="Responsible" icon="terp-personal" domain="[]"
context="{'group_by':'user_id'}" />
<filter string="Partner" icon="terp-personal" domain="[]"
context="{'group_by':'partner_id'}" />
<separator orientation="vertical" />
<filter string="Meeting Type" help="Meeting Type"
icon="terp-stock_symbol-selection" domain="[]"
context="{'group_by':'categ_id'}" />
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]"
context="{'group_by':'state'}" />
<separator orientation="vertical" />
</group>
<newline/>
<group expand="0" string="Extended Options...">
<field name="class" select="1" string="Privacy"/>
<field name="show_as" string="Show time as" select="1"/>
</group>
<newline/>
<group expand="0" string="Group By...">
<filter string="Responsible" icon="terp-personal" domain="[]"
context="{'group_by':'user_id'}" />
<filter string="Partner" icon="terp-partner" domain="[]"
context="{'group_by':'partner_id'}" />
<separator orientation="vertical" />
<filter string="Type" help="Meeting Type"
icon="terp-stock_symbol-selection" domain="[]"
context="{'group_by':'categ_id'}" />
<filter string="Privacy" icon="terp-locked"
domain="[]" context="{'group_by':'class'}" />
<filter string="Show time as" icon="terp-project"
domain="[]" context="{'group_by':'show_as'}" />
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]"
context="{'group_by':'state'}" />
<separator orientation="vertical" />
<filter string="Date" icon="terp-go-month" help="Meeting date"
domain="[]" context="{'group_by':'date'}" />
</group>
</search>
</field>
</record>
+9 -9
View File
@@ -133,7 +133,7 @@
<field colspan="4" name="email_cc" string="Global CC" widget="char" size="512"/>
</group>
<field name="message_ids" colspan="4" nolabel="1" mode="tree,form">
<tree string="Communication history">
<tree string="History">
<field name="display_text" string="History Information"/>
<field name="history" invisible="1"/>
<button
@@ -142,7 +142,7 @@
context="{'mail':'reply', 'model': 'crm.lead', 'include_original' : True}"
icon="terp-mail-replied" type="action" />
</tree>
<form string="Communication history">
<form string="History">
<group col="4" colspan="4">
<field name="email_from"/>
<field name="date"/>
@@ -171,7 +171,7 @@
</notebook>
</form>
</field>
<button string="Add New Note"
<button string="Add Internal Note"
name="%(crm.action_crm_add_note)d"
context="{'model': 'crm.lead' }"
icon="terp-document-new" type="action" />
@@ -272,7 +272,7 @@
<field name="arch" type="xml">
<search string="Search Opportunities">
<filter icon="terp-check"
string="Current" help="Current Opportunities"
string="Current" help="Draft and Open Opportunities"
name="current"
domain="[('state','in',('draft','open'))]"/>
<filter icon="terp-camera_test"
@@ -326,9 +326,12 @@
</group>
<newline/>
<group expand="0" string="Group By..." colspan="16">
<filter string="Salesman" icon="terp-personal"
domain="[]" context="{'group_by':'user_id'}" />
<filter string="Team" help="Sales Team" icon="terp-personal+" domain="[]" context="{'group_by':'section_id'}"/>
<separator orientation="vertical" />
<filter string="Stage" icon="terp-stage" domain="[]"
context="{'group_by':'stage_id'}" />
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
<filter string="Priority" icon="terp-rating-rated" domain="[]"
context="{'group_by':'priority'}" />
<filter string="Category" icon="terp-stock_symbol-selection"
@@ -337,10 +340,7 @@
domain="[]" context="{'group_by':'type_id'}" />
<filter string="Channel" icon="terp-stock_symbol-selection"
domain="[]" context="{'group_by':'channel_id'}" />
<separator orientation="vertical" />
<filter string="Salesman" icon="terp-personal"
domain="[]" context="{'group_by':'user_id'}" />
<filter string="Team" help="Sales Team" icon="terp-personal+" domain="[]" context="{'group_by':'section_id'}"/>
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
<separator orientation="vertical" />
<filter string="Creation" icon="terp-go-month"
domain="[]" context="{'group_by':'create_date'}" />
+3 -2
View File
@@ -13,7 +13,8 @@
groups="base.group_extended"
/>
<act_window
<!-- TO CONFIRM: This is fine -->
<!-- act_window
id="act_crm_phonecall_crm_meeting_new"
name="Meetings"
res_model="crm.meeting"
@@ -21,7 +22,7 @@
view_mode="tree,form,calendar,"
context="{'default_duration': 4.0, 'default_phonecall_id': active_id}"
domain="[('phonecall_id', '=', active_id)]"
view_type="form"/>
view_type="form"/-->
<!-- PHONE CALLS (menu) -->
+14 -23
View File
@@ -16,19 +16,6 @@
<menuitem action="crm_phonecall_categ_action" name="Categories"
id="menu_crm_case_phonecall-act" parent="menu_crm_config_phonecall" />
<!-- ResourceType Form View -->
<record id="crm_phonecall_resource_act" model="ir.actions.act_window">
<field name="name">Phonecall Campaigns</field>
<field name="res_model">crm.case.resource.type</field>
<field name="view_type">form</field>
<field name="view_id" ref="crm.crm_case_resource_type_tree"/>
</record>
<menuitem action="crm_phonecall_resource_act"
id="menu_crm_phonecall_resource_act" name="Campaigns"
parent="menu_crm_config_phonecall" />
<!-- PhoneCalls Tree View -->
<record model="ir.ui.view" id="crm_case_phone_tree_view">
@@ -47,9 +34,10 @@
<button string="Opportunity"
name="%(phonecall2opportunity_act)d"
states="draft,open,pending"
icon="gtk-index"
type="action" attrs="{'invisible':[('opportunity_id','!=',False)]}" />
<button string="Meeting"
states="draft,open,pending"
states="draft,open,pending" icon="gtk-redo"
name="action_make_meeting" type="object" />
<field name="state"/>
<button name="case_open" string="Open" states="draft,pending" type="object" icon="gtk-go-forward"/>
@@ -94,7 +82,7 @@
<field name="partner_id"
on_change="onchange_partner_id(partner_id, email_from)" />
<button string="Create a Partner"
icon="terp-crm"
icon="gtk-index"
name="%(action_crm_phonecall2partner)d"
type="action"
attrs="{'invisible':[('partner_id','!=',False)]}" />
@@ -121,7 +109,7 @@
states="draft,pending" type="object"
icon="gtk-go-forward" />
<button name="case_pending" string="Not Held"
states="open" type="object" icon="gtk-undo" />
states="open" type="object" icon="gtk-media-pause" />
<button name="case_close" string="Held"
states="open,draft,pending" type="object"
icon="gtk-jump-to" />
@@ -172,7 +160,7 @@
<field name="partner_id"
on_change="onchange_partner_id(partner_id, email_from)" />
<button string="Create a Partner"
icon="terp-crm"
icon="gtk-index"
name="%(action_crm_phonecall2partner)d"
type="action"
attrs="{'invisible':[('partner_id','!=',False)]}" />
@@ -219,10 +207,14 @@
string="Type" />
<field name="state" invisible="1"/>
<field name="create_date" invisible="1"/>
<button string="Schedule Other Call"
icon="terp-call-start"
name="%(phonecall_to_phonecall_act)d"
type="action" />
<button string="Opportunity"
name="%(phonecall2opportunity_act)d"
states="draft,open,pending"
icon="gtk-convert"
icon="gtk-index"
type="action" attrs="{'invisible':[('opportunity_id','!=',False)]}" />
<button string="Meeting"
states="draft,open,pending" icon="gtk-redo"
@@ -254,10 +246,9 @@
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Search Phonecalls">
<filter icon="terp-go-today" string="Current"
<filter icon="terp-check" string="Current"
name="current"
domain="[('state','in', ('draft','open','pending'))]"/>
<separator orientation="vertical"/>
<filter icon="terp-go-today" string="Today"
domain="[('date','&lt;', time.strftime('%%Y-%%m-%%d 23:59:59')),\
('date','&gt;=',datetime.strftime('%%Y-%%m-%%d 00:00:00'))]"
@@ -286,15 +277,15 @@
</field>
<newline/>
<group expand="0" string="Group By..." colspan="4">
<filter string="Partner" icon="terp-personal" domain="[]"
<filter string="Partner" icon="terp-partner" domain="[]"
context="{'group_by':'partner_id'}" />
<filter string="Responsible" icon="terp-personal"
domain="[]" context="{'group_by':'user_id'}" />
<separator orientation="vertical" />
<filter string="Creation" icon="terp-go-month"
<filter string="Creation" icon="terp-go-month" help="Creation Date"
domain="[]" context="{'group_by':'create_date'}" />
<filter string="Date" icon="terp-go-month" domain="[]"
context="{'group_by':'date'}" />
context="{'group_by':'date'}" help="Date of Call" />
</group>
</search>
</field>
+9 -5
View File
@@ -113,7 +113,7 @@
<form string="Stage">
<separator string="Stage Definition" colspan="4"/>
<field name="name" select="1"/>
<field name="section_id" select="1" widget="selection"/>
<field name="section_id" select="1"/>
<field name="object_id" invisible="1" />
<field name="sequence"/>
<field name="probability"/>
@@ -142,7 +142,7 @@
<field name="arch" type="xml">
<form string="Case Category">
<field name="name" select="1"/>
<field name="section_id" select="1" widget="selection"/>
<field name="section_id" select="1"/>
<field name="object_id" invisible="1" />
</form>
</field>
@@ -199,6 +199,10 @@
<field name="view_id" ref="crm_case_resource_type_tree"/>
</record>
<menuitem action="crm_case_resource_type_act"
id="menu_crm_case_resource_type_act" sequence="4"
parent="base.menu_sale_config_sales" />
<record id="crm_case_section_act_tree" model="ir.actions.act_window">
<field name="name">Cases by Sales Team</field>
<field name="res_model">crm.case.section</field>
@@ -528,7 +532,7 @@
<field colspan="4" name="email_cc" widget="char" size="512"/>
</group>
<field name="message_ids" colspan="4" nolabel="1" mode="tree,form">
<tree string="Communication history">
<tree string="History">
<field name="display_text" string="History Information"/>
<field name="history" invisible="1"/>
<button
@@ -537,7 +541,7 @@
context="{'mail':'reply', 'model': 'crm.case.custom', 'include_original' : True}"
icon="terp-mail-replied" type="action" />
</tree>
<form string="Communication history">
<form string="History">
<group col="4" colspan="4">
<field name="email_from"/>
<field name="date"/>
@@ -566,7 +570,7 @@
</notebook>
</form>
</field>
<button string="Add New Note"
<button string="Add Internal Note"
name="%(crm.action_crm_add_note)d"
context="{'model': 'crm.lead' }"
icon="terp-document-new" type="action" />
+1 -1
View File
@@ -156,7 +156,7 @@ class crm_lead_report(osv.osv):
(SELECT count(id) FROM mailgate_message WHERE model='crm.lead' AND res_id=c.id AND history=True) AS email,
date_trunc('day',c.create_date) as create_date,
extract('epoch' from (c.date_closed-c.create_date))/(3600*24) as delay_close,
extract('epoch' from (c.date_deadline - c.date_closed))/(3600*24) as delay_expected,
abs(extract('epoch' from (c.date_deadline - c.date_closed))/(3600*24)) as delay_expected,
extract('epoch' from (c.date_open-c.create_date))/(3600*24) as delay_open
FROM
crm_lead c
+33 -35
View File
@@ -9,7 +9,7 @@
<field name="model">crm.lead.report</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree colors="blue:state in ('draft');black:state in ('open','pending','done');gray:state in ('cancel') " string="Leads Analysis">
<tree string="Leads Analysis">
<field name="name" invisible="1"/>
<field name="state" invisible="1"/>
<field name="stage_id" invisible="1"/>
@@ -23,12 +23,12 @@
<field name="user_id" invisible="1"/>
<field name="company_id" invisible="1"/>
<field name="partner_id" invisible="1"/>
<field name="country_id" invisible="1"/>
<field name="day" invisible="1"/>
<field name="nbr" sum="# Leads"/>
<field name="email" sum="# Mails"/>
<field name="delay_open"/>
<field name="delay_close"/>
<field name="delay_expected"/>
<field name="avg_answers"/>
</tree>
</field>
@@ -71,41 +71,40 @@
<field name="arch" type="xml">
<search string="Leads Analysis">
<group col="20" colspan="8">
<filter string="Leads"
icon="terp-check"
name="filter_lead"
groups="base.group_extended"
domain="[('type','=','lead')]"/>
<filter string="Opportunities"
icon="terp-check"
name="filter_opportunity"
domain="[('type','=','opportunity')]"/>
<separator orientation="vertical" />
<filter string="30 Days" icon="terp-go-month" name="this_month"
domain="[('create_date','&gt;',(datetime.date.today()-datetime.timedelta(days=30)).strftime('%%Y-%%m-%%d'))]"/>
<filter icon="terp-go-week" string="7 Days" separator="1"
domain="[('create_date','&gt;',(datetime.date.today()-datetime.timedelta(days=7)).strftime('%%Y-%%m-%%d'))]"/>
<filter string=" Year " icon="terp-go-year"
domain="[('create_date','&lt;=', time.strftime('%%Y-%%m-%%d')),('create_date','&gt;=',time.strftime('%%Y-01-01'))]"
help="Leads/Opportunities created in current year"/>
<filter string=" Month " icon="terp-go-month" name="this_month"
domain="[('create_date','&lt;=', time.strftime('%%Y-%%m-%%d')),('create_date','&gt;=',time.strftime('%%Y-%%m-01'))]"
help="Leads/Opportunities created in current month"/>
<filter icon="terp-go-month" string=" Month-1 " separator="1"
domain="[('create_date','&lt;=', (datetime.date (int(time.strftime('%%Y')), datetime.date.today().month, 1) - datetime.timedelta (days = 1)).strftime('%%Y-%%m-%%d')),('create_date','&gt;',(datetime.date (int(time.strftime('%%Y')), datetime.date.today().month-1, 1)).strftime('%%Y-%%m-%%d'))]"
help="Leads/Opportunities created in last month"/>
<separator orientation="vertical" />
<filter icon="terp-check"
string="Current"
domain="[('state','in',('draft','open'))]"/>
<filter icon="terp-check"
string="Active"
domain="[('state','in',('draft','open'))]"
help="Leads/Opportunities which are in draft and open state"/>
<filter icon="gtk-media-pause"
string="Pending"
domain="[('state','=','pending')]"/>
<filter icon="terp-check"
domain="[('state','=','pending')]"
help="Leads/Opportunities which are in pending state"/>
<filter icon="terp-dialog-close"
string="Closed"
domain="[('state','=','done')]"/>
domain="[('state','=','done')]"
help="Leads/Opportunities which are in done state"/>
<separator orientation="vertical" />
<field name="section_id"
default="context.get('section_id', False)"
widget="selection"
context="{'invisible_section': False}">
<filter icon="terp-crm"
context="{'invisible_section': False}"
domain="[('section_id.user_id','=',uid)]"
help="My section" />
help="My team" />
</field>
<field name="user_id">
<field name="user_id" string="Salesman">
<filter icon="terp-personal+" string="My Case" help="My Case" domain="[('user_id','=',uid)]" />
</field>
</group>
@@ -128,12 +127,15 @@
<group expand="1" string="Group By...">
<filter string="User" name="user" icon="terp-personal"
domain="[]" context="{'group_by':'user_id'}" />
<filter string="Sales Team" icon="terp-personal+"
domain="[]"
context="{'group_by':'section_id'}" />
<filter string="Partner" icon="terp-personal" context="{'group_by':'partner_id'}" />
<filter string="Country" icon="terp-go-home" context="{'group_by':'country_id'}" />
<separator orientation="vertical" />
<filter string="Section" icon="terp-personal+"
domain="[]"
context="{'group_by':'section_id'}" />
<separator orientation="vertical" />
<filter string="Stage" icon="terp-stage" domain="[]" context="{'group_by':'stage_id'}"/>
<filter string="Priority" icon="terp-rating-rated" domain="[]" context="{'group_by':'priority'}" />
<filter string="Category" icon="terp-stock_symbol-selection"
domain="[]" context="{'group_by':'categ_id'}" />
<filter string="Campaign" icon="terp-stock_symbol-selection"
@@ -141,10 +143,6 @@
<filter string="Channel" icon="terp-stock_symbol-selection"
domain="[]" context="{'group_by':'channel_id'}" />
<separator orientation="vertical" />
<filter string="Stage" icon="terp-stage" domain="[]" context="{'group_by':'stage_id'}"/>
<separator orientation="vertical"/>
<filter string="Priority" icon="terp-rating-rated" domain="[]" context="{'group_by':'priority'}" />
<separator orientation="vertical" />
<filter string="State" icon="terp-stock_effects-object-colorize"
domain="[]" context="{'group_by':'state'}" />
<separator orientation="vertical" />
@@ -153,11 +151,11 @@
context="{'group_by':'company_id'}" />
<separator orientation="vertical" />
<filter string="Day" icon="terp-go-today"
domain="[]" context="{'group_by':'day'}"/>
domain="[]" context="{'group_by':'day'}" help="Day on which lead/opportunity is created"/>
<filter string="Month" icon="terp-go-month"
domain="[]" context="{'group_by':'month'}" />
domain="[]" context="{'group_by':'month'}" help="Month in which lead/opportunity is created"/>
<filter string="Year" icon="terp-go-year"
domain="[]" context="{'group_by':'name'}" />
domain="[]" context="{'group_by':'name'}" help="Year in which lead/opportunity is created"/>
</group>
</search>
</field>
+3 -3
View File
@@ -119,9 +119,9 @@ class crm_phonecall_report(osv.osv):
create or replace view crm_phonecall_report as (
select
id,
to_char(c.create_date, 'YYYY') as name,
to_char(c.create_date, 'MM') as month,
to_char(c.create_date, 'YYYY-MM-DD') as day,
to_char(c.date, 'YYYY') as name,
to_char(c.date, 'MM') as month,
to_char(c.date, 'YYYY-MM-DD') as day,
to_char(c.create_date, 'YYYY-MM-DD') as creation_date,
to_char(c.date_open, 'YYYY-MM-DD') as opening_date,
to_char(c.date_closed, 'YYYY-mm-dd') as date_closed,
+40 -37
View File
@@ -9,7 +9,7 @@
<field name="model">crm.phonecall.report</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree colors="blue:state in ('draft');black:state in ('open','pending','done');gray:state in ('cancel') " string="Phone calls">
<tree string="Phone calls">
<field name="name" invisible="1"/>
<field name="month" invisible="1"/>
<field name="section_id" invisible="1"/>
@@ -75,37 +75,41 @@
<field name="arch" type="xml">
<search string="Search">
<group col="16" colspan="8">
<filter string="This Year" icon="terp-go-year"
domain="[('create_date','&lt;=', time.strftime('%%Y-%%m-%%d')), ('create_date','&gt;',(datetime.date.today()-datetime.timedelta(days=365)).strftime('%%Y-%%m-%%d'))]"/>
<filter string=" Year " icon="terp-go-year"
domain="[('create_date','&lt;=', time.strftime('%%Y-%%m-%%d')),('create_date','&gt;=',time.strftime('%%Y-01-01'))]"
help="Phone calls made in current year"/>
<filter string="This Month" icon="terp-go-month" name="This Month"
domain="[('create_date','&lt;=', time.strftime('%%Y-%%m-%%d')), ('create_date','&gt;',(datetime.date.today()-datetime.timedelta(days=30)).strftime('%%Y-%%m-%%d'))]"/>
<filter string=" Month " icon="terp-go-month" name="This Month"
domain="[('create_date','&lt;=', time.strftime('%%Y-%%m-%%d')),('create_date','&gt;=',time.strftime('%%Y-%%m-01'))]"
help="Phone calls made in current month"/>
<filter icon="terp-go-week" string="7 Days" separator="1"
domain="[('create_date','&lt;=', time.strftime('%%Y-%%m-%%d')), ('create_date','&gt;',(datetime.date.today()-datetime.timedelta(days=7)).strftime('%%Y-%%m-%%d'))]"/>
<filter icon="terp-go-month" string=" Month-1 " separator="1"
domain="[('create_date','&lt;=', (datetime.date (int(time.strftime('%%Y')), datetime.date.today().month, 1) - datetime.timedelta (days = 1)).strftime('%%Y-%%m-%%d')),('create_date','&gt;',(datetime.date (int(time.strftime('%%Y')), datetime.date.today().month-1, 1)).strftime('%%Y-%%m-%%d'))]"
help="Phone calls made in last month"/>
<separator orientation="vertical" />
<filter icon="terp-check"
string="Current"
domain="[('state','in',('draft','oprn'))]"/>
<filter icon="terp-hr"
string="Pending"
domain="[('state','=','pending')]"/>
<filter icon="terp-sale"
string="Done"
domain="[('state','=','done')]"/>
<separator orientation="vertical" />
<filter string="Stage" icon="terp-crm" domain="[]"
context="{'group_by':'stage_id'}" />
<filter icon="terp-personal+"
context="{'invisible_section': False}"
domain="[('section_id.user_id','=',uid)]"
help="My section" />
<field name="user_id" select="1">
string="Todo"
domain="[('state','in',('draft','open'))]"
help="Phone calls which are in draft and open state"/>
<filter icon="gtk-media-pause"
string="Not Held"
domain="[('state','=','pending')]"
help="Phone calls which are in pending state"/>
<filter icon="terp-camera_test"
string="Held"
domain="[('state','=','done')]"
help="Phone calls which are in closed state"/>
<separator orientation="vertical" />
<field name="section_id" string="Sales Team"
default="context.get('section_id', False)"
context="{'invisible_section': False}">
<filter icon="terp-personal+"
context="{'invisible_section': False}"
domain="[('section_id.user_id','=',uid)]"
help="My team" />
</field>
<field name="user_id" string="Salesman" select="1">
<filter icon="terp-crm" string="My Case" help="My Case" domain="[('user_id','=',uid)]" />
</field>
</group>
@@ -128,29 +132,28 @@
domain="[]" context="{'group_by':'user_id'}" />
<filter string="Partner" icon="terp-personal" context="{'group_by':'partner_id'}" />
<separator orientation="vertical" />
<filter string="Section" icon="terp-sale"
<filter string="Sales Team" icon="terp-personal+"
domain="[]"
context="{'group_by':'section_id'}" />
<filter string="Category" icon="terp-stock_symbol-selection"
domain="[]" context="{'group_by':'categ_id'}" />
<separator orientation="vertical" />
<filter string="Stage" icon="terp-stage" domain="[]" context="{'group_by':'stage_id'}"/>
<separator orientation="vertical"/>
<filter string="Priority" icon="terp-rating-rated" domain="[]" context="{'group_by':'priority'}" />
<filter string="Type" icon="terp-stock_symbol-selection"
domain="[]" context="{'group_by':'categ_id'}" />
<separator orientation="vertical" />
<filter string="State" icon="terp-stock_effects-object-colorize"
domain="[]" context="{'group_by':'state'}" />
<separator orientation="vertical" />
<filter string="Company" icon="terp-go-home"
domain="[]"
context="{'group_by':'company_id'}" />
context="{'group_by':'company_id'}" groups="base.group_multi_company"/>
<separator orientation="vertical" />
<filter string="Day" icon="terp-go-today"
domain="[]" context="{'group_by':'day'}"/>
domain="[]" context="{'group_by':'day'}" help="Date of call"/>
<filter string="Month" icon="terp-go-month"
domain="[]" context="{'group_by':'month'}" />
domain="[]" context="{'group_by':'month'}" help="Month of call"/>
<filter string="Year" icon="terp-go-year"
domain="[]" context="{'group_by':'name'}" />
domain="[]" context="{'group_by':'name'}" help="Year of call"/>
</group>
</search>
</field>
@@ -159,7 +162,7 @@
<!-- Phone calls by user and section Action -->
<record id="action_report_crm_phonecall" model="ir.actions.act_window">
<field name="name">Phone Calls</field>
<field name="name">Phone Calls Analysis</field>
<field name="res_model">crm.phonecall.report</field>
<field name="view_type">form</field>
<field name="view_mode">tree,graph</field>
+1 -1
View File
@@ -10,7 +10,7 @@
"access_crm_phonecall_system","crm.phonecall.system","model_crm_phonecall","base.group_system",1,0,0,0
"access_crm_phonecall_manager","crm.phonecall.manager","model_crm_phonecall","base.group_sale_manager",1,0,0,0
"access_crm_case_categ","crm.case.categ","model_crm_case_categ","base.group_user",1,0,0,0
"access_crm_meeting","crm.meeting","model_crm_meeting","base.group_sale_salesman",1,1,1,0
"access_crm_meeting","crm.meeting","model_crm_meeting","base.group_sale_salesman",1,0,0,0
"access_crm_meeting_all","crm.meeting_allll","model_crm_meeting","base.group_user",1,0,0,0
"access_crm_lead","crm.lead","model_crm_lead","base.group_sale_salesman",1,1,1,1
"access_crm_lead.all","crm.lead.all","model_crm_lead","base.group_user",1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
10 access_crm_phonecall_system crm.phonecall.system model_crm_phonecall base.group_system 1 0 0 0
11 access_crm_phonecall_manager crm.phonecall.manager model_crm_phonecall base.group_sale_manager 1 0 0 0
12 access_crm_case_categ crm.case.categ model_crm_case_categ base.group_user 1 0 0 0
13 access_crm_meeting crm.meeting model_crm_meeting base.group_sale_salesman 1 1 0 1 0 0
14 access_crm_meeting_all crm.meeting_allll model_crm_meeting base.group_user 1 0 0 0
15 access_crm_lead crm.lead model_crm_lead base.group_sale_salesman 1 1 1 1
16 access_crm_lead.all crm.lead.all model_crm_lead base.group_user 1 0 0 0
+1 -1
View File
@@ -9,7 +9,7 @@ AVAILABLE_STATES = crm.AVAILABLE_STATES + [('unchanged', 'Unchanged')]
class crm_add_note(osv.osv_memory):
"""Adds a new note to the case."""
_name = 'crm.add.note'
_description = "Add New Note"
_description = "Add Internal Note"
_columns = {
'body': fields.text('Note Body', required=True),
+2 -2
View File
@@ -105,8 +105,8 @@ class crm_lead2opportunity(osv.osv_memory):
return value
_columns = {
'name' : fields.char('Opportunity Summary', size=64, required=True, select=1),
'probability': fields.float('Success Probability'),
'name' : fields.char('Opportunity', size=64, required=True, select=1),
'probability': fields.float('Success Rate (%)'),
'planned_revenue': fields.float('Expected Revenue'),
'partner_id': fields.many2one('res.partner', 'Partner'),
}
+2 -2
View File
@@ -143,13 +143,13 @@ class crm_lead2partner(osv.osv_memory):
for lead in lead_obj.browse(cr, uid, rec_ids):
if data.action == 'create':
partner_id = partner_obj.create(cr, uid, {
'name': lead.partner_name or lead.name,
'name': lead.partner_name or lead.contact_name or lead.name,
'user_id': lead.user_id.id,
'comment': lead.description,
})
contact_id = contact_obj.create(cr, uid, {
'partner_id': partner_id,
'name': lead.name,
'name': lead.contact_name,
'phone': lead.phone,
'mobile': lead.mobile,
'email': lead.email_from,
@@ -34,5 +34,10 @@
<field name="target">new</field>
</record>
<act_window id="action_merge_opportunities"
key2="client_action_multi" name="Merge Opportunities"
res_model="crm.merge.opportunity" src_model="crm.lead"
view_mode="form" target="new" view_type="form" />
</data>
</openerp>
@@ -16,7 +16,7 @@
<field name="date" string="Planned Date"/>
<newline/>
<field name="user_id" />
<field name="section_id"/>
<field name="section_id" widget="selection" />
<field name="categ_id" widget="selection" domain="[('object_id.model', '=', 'crm.phonecall')]"/>
<separator string="" colspan="4"/>
<label string ="" colspan="2"/>
+1 -1
View File
@@ -81,7 +81,7 @@
<separator string=" " colspan="4"/>
<group colspan="4" col="3" >
<label string=" " />
<button name="action_cancel" string="_Cancel" icon="gtk-cancel" special="cancel" />
<button string="_Cancel" icon="gtk-cancel" special="cancel" />
<button name="action_send" type="object" string="_Send Reply" icon="gtk-go-forward" />
</group>
</form>
+2 -4
View File
@@ -46,10 +46,8 @@ class crm_claim(crm.crm_case, osv.osv):
'ref' : fields.reference('Reference', selection=crm._links_get, size=128),
'ref2' : fields.reference('Reference 2', selection=crm._links_get, size=128),
'canal_id': fields.many2one('res.partner.canal', 'Channel', \
help="The channels represent the different communication"\
"modes available with the customer." \
" With each commercial opportunity, you can indicate the"\
"canall which is this opportunity source."),
help="The channels represent the different communication \
modes available with the customer."),
'planned_revenue': fields.float('Planned Revenue'),
'planned_cost': fields.float('Planned Costs'),
'categ_id': fields.many2one('crm.case.categ', 'Category', \
+7 -20
View File
@@ -35,21 +35,6 @@
<menuitem action="crm_claim_stage_act" name="Stages"
id="menu_crm_claim_stage_act" parent="menu_config_claim" />
<!-- Claim Resource Type -->
<record id="crm_claim_resource_act" model="ir.actions.act_window">
<field name="name">Claim Resource Type</field>
<field name="res_model">crm.case.resource.type</field>
<field name="view_type">form</field>
<field name="view_id" ref="crm.crm_case_resource_type_tree"/>
<field name="domain">[('object_id.model', '=', 'crm.claim')]</field>
<field name="context">{'object_id':'crm.claim'}</field>
</record>
<menuitem action="crm_claim_resource_act" name="Resource Type"
id="menu_crm_claim_type_act"
parent="menu_config_claim" />
<!-- Claims -->
<record model="ir.ui.view" id="crm_case_claims_tree_view">
@@ -57,7 +42,7 @@
<field name="model">crm.claim</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Claims" colors="blue:state=='pending';black:state=='open';gray:state in ('close', 'cancel')">
<tree string="Claims" colors="blue:state=='pending';black:state=='open';gray:state in ('close', 'cancel');red:date_deadline and (date_deadline &lt; current_date)">
<field name="name"/>
<field name="partner_id"/>
<field name="user_id" />
@@ -168,7 +153,7 @@
<field colspan="4" name="email_cc" string="Global CC" widget="char"/>
</group>
<field name="message_ids" colspan="4" nolabel="1" mode="tree,form">
<tree string="Communication history">
<tree string="History">
<field name="display_text" string="History Information"/>
<button
string="Reply"
@@ -176,7 +161,7 @@
context="{'mail':'reply', 'model': 'crm.claim', 'include_original' : True}"
icon="terp-mail-replied" type="action" attrs="{'invisible': [('history', '!=', True)]}" />
</tree>
<form string="Communication history">
<form string="History">
<group col="4" colspan="4">
<field name="email_from"/>
<field name="date"/>
@@ -205,7 +190,7 @@
</notebook>
</form>
</field>
<button string="Add New Note"
<button string="Add Internal Note"
name="%(crm.action_crm_add_note)d"
context="{'model': 'crm.lead' }"
icon="terp-document-new" type="action" />
@@ -269,7 +254,7 @@
<search string="Search Claims">
<filter icon="terp-check" string="Current" name="current"
domain="[('state','in',('draft', 'open'))]"
separator="1" help="Current Claims" default="1"
separator="1" help="Draft and Open Claims" default="1"
/>
<filter icon="terp-camera_test"
string="In Progress"
@@ -330,6 +315,7 @@
context="{'default_partner_id': active_id}"
id="act_claim_partner"
name="Report a Claim"
view_mode="form,tree"
res_model="crm.claim"
src_model="res.partner"/>
@@ -339,6 +325,7 @@
context="{'default_partner_address_id': active_id}"
id="act_claim_partner_address"
name="Report a Claim"
view_mode="form,tree"
res_model="crm.claim"
src_model="res.partner.address"/>
+2 -2
View File
@@ -87,8 +87,8 @@ msgstr "Day"
#. module: crm_claim
#: help:crm.claim,canal_id:0
msgid "The channels represent the different communicationmodes available with the customer. With each commercial opportunity, you can indicate thecanall which is this opportunity source."
msgstr "The channels represent the different communicationmodes available with the customer. With each commercial opportunity, you can indicate thecanall which is this opportunity source."
msgid "The channels represent the different communication modes available with the customer."
msgstr "The channels represent the different communication modes available with the customer."
#. module: crm_claim
#: help:crm.claim,section_id:0
+11 -7
View File
@@ -74,6 +74,8 @@ class crm_claim_report(osv.osv):
'type_id': fields.many2one('crm.case.resource.type', 'Claim Type',\
domain="[('section_id','=',section_id),\
('object_id.model', '=', 'crm.claim')]"),
'date_closed': fields.date('Closed', readonly=True),
'delay_expected': fields.float('Overpassed Deadline',digits=(16,2),readonly=True, group_operator="avg"),
}
def init(self, cr):
@@ -87,9 +89,10 @@ class crm_claim_report(osv.osv):
create or replace view crm_claim_report as (
select
min(c.id) as id,
to_char(c.create_date, 'YYYY') as name,
to_char(c.create_date, 'MM') as month,
to_char(c.create_date, 'YYYY-MM-DD') as day,
to_char(c.date, 'YYYY') as name,
to_char(c.date, 'MM') as month,
to_char(c.date, 'YYYY-MM-DD') as day,
to_char(c.date_closed, 'YYYY-MM-DD') as date_closed,
c.state,
c.user_id,
c.stage_id,
@@ -101,13 +104,14 @@ class crm_claim_report(osv.osv):
c.priority as priority,
c.type_id as type_id,
date_trunc('day',c.create_date) as create_date,
avg(extract('epoch' from (c.date_closed-c.create_date)))/(3600*24) as delay_close
avg(extract('epoch' from (c.date_closed-c.create_date)))/(3600*24) as delay_close,
extract('epoch' from (c.date_deadline - c.date_closed))/(3600*24) as delay_expected
from
crm_claim c
group by to_char(c.create_date, 'YYYY'), to_char(c.create_date, 'MM'), \
group by to_char(c.date, 'YYYY'), to_char(c.date, 'MM'),to_char(c.date, 'YYYY-MM-DD'),\
c.state, c.user_id,c.section_id, c.stage_id,\
c.categ_id,c.partner_id,c.company_id,c.create_date,to_char(c.create_date, 'YYYY-MM-DD')
,c.priority,c.type_id
c.categ_id,c.partner_id,c.company_id,c.create_date,
c.priority,c.type_id,c.date_deadline,c.date_closed
)""")
crm_claim_report()
@@ -19,6 +19,7 @@
<field name="day" invisible="1"/>
<field name="nbr" string="#Claim" sum="#Claim"/>
<field name="delay_close" avg="Avg Closing Delay"/>
<field name="delay_expected"/>
<field name="state" invisible="1"/>
<field name="stage_id" invisible="1"/>
<field name="categ_id" invisible="1"/>
@@ -42,6 +43,7 @@
<field name="section_id" select="1"/>
<field name="nbr" select="1"/>
<field name="delay_close"/>
<field name="delay_expected"/>
<field name="amount_revenue"/>
<field name="amount_costs"/>
<field name="amount_revenue_prob"/>
@@ -75,14 +77,17 @@
<field name="arch" type="xml">
<search string="Search">
<group col="16" colspan="8">
<filter string="This Year" icon="terp-go-year"
domain="[('create_date','&lt;=', time.strftime('%%Y-%%m-%%d')), ('create_date','&gt;',(datetime.date.today()-datetime.timedelta(days=365)).strftime('%%Y-%%m-%%d'))]"/>
<filter string=" Year " icon="terp-go-year"
domain="[('create_date','&lt;=', time.strftime('%%Y-%%m-%%d')),('create_date','&gt;=',time.strftime('%%Y-01-01'))]"
help="Claims created in current year"/>
<filter string="This Month" icon="terp-go-month" name="This Month"
domain="[('create_date','&lt;=', time.strftime('%%Y-%%m-%%d')), ('create_date','&gt;',(datetime.date.today()-datetime.timedelta(days=30)).strftime('%%Y-%%m-%%d'))]"/>
<filter string=" Month " icon="terp-go-month" name="This Month"
domain="[('create_date','&lt;=', time.strftime('%%Y-%%m-%%d')),('create_date','&gt;=',time.strftime('%%Y-%%m-01'))]"
help="Claims created in current month"/>
<filter icon="terp-go-week" string="7 Days" separator="1"
domain="[('create_date','&lt;=', time.strftime('%%Y-%%m-%%d')), ('create_date','&gt;',(datetime.date.today()-datetime.timedelta(days=7)).strftime('%%Y-%%m-%%d'))]"/>
<filter icon="terp-go-month" string=" Month-1 " separator="1"
domain="[('create_date','&lt;=', (datetime.date (int(time.strftime('%%Y')), datetime.date.today().month, 1) - datetime.timedelta (days = 1)).strftime('%%Y-%%m-%%d')),('create_date','&gt;',(datetime.date (int(time.strftime('%%Y')), datetime.date.today().month-1, 1)).strftime('%%Y-%%m-%%d'))]"
help="Claims created in last month"/>
<separator orientation="vertical" />
<filter icon="terp-document-new"
@@ -96,25 +101,24 @@
domain="[('state','=','pending')]"/>
<separator orientation="vertical" />
<field name="section_id"
<field name="section_id" string="Sales Team"
default="context.get('section_id', False)"
widget="selection"
context="{'invisible_section': False}">
<filter icon="terp-personal+"
context="{'invisible_section': False}"
domain="[('section_id.user_id','=',uid)]"
help="My section" />
help="My team" />
</field>
<field name="company_id" widget="selection">
<field name="company_id">
<filter icon="terp-go-home"
context="{'invisible_section': False}"
domain="[('section_id.user_id.company_id','=',uid)]"
help="My company"/>
</field>
<field name="user_id" select="1" widget="selection">
<field name="user_id" string="Salesman" select="1">
<filter icon="terp-personal+" string="My Case" help="My Case" domain="[('user_id','=',uid)]" />
</field>
</group>
@@ -139,42 +143,41 @@
<group expand="1" string="Group By...">
<filter string="User" name="User" icon="terp-personal"
domain="[]" context="{'group_by':'user_id'}" />
<filter string="Company" icon="terp-go-home"
domain="[]"
context="{'group_by':'company_id'}" groups="base.group_multi_company"/>
<filter string="Section" icon="terp-personal+"
<filter string="Sales Team" icon="terp-personal+"
domain="[]"
context="{'group_by':'section_id'}" />
<separator orientation="vertical" />
<filter string="State" icon="terp-stock_effects-object-colorize"
domain="[]" context="{'group_by':'state'}" />
<filter string="Stage" icon="terp-stage" domain="[]"
context="{'group_by':'stage_id'}" />
<filter string="Priority" icon="terp-rating-rated" domain="[]"
context="{'group_by':'priority'}" />
<filter string="Category" icon="terp-stock_symbol-selection"
domain="[]" context="{'group_by':'categ_id'}" />
<separator orientation="vertical"/>
<filter string="Priority" icon="terp-rating-rated" domain="[]"
context="{'group_by':'priority'}" />
<filter string="Type" icon="terp-stock_symbol-selection" domain="[]"
<filter string="Type" icon="terp-stock_symbol-selection" domain="[]"
context="{'group_by':'type_id'}" />
<filter string="State" icon="terp-stock_effects-object-colorize"
domain="[]" context="{'group_by':'state'}" />
<separator orientation="vertical" />
<filter string="Company" icon="terp-go-home"
domain="[]"
context="{'group_by':'company_id'}" groups="base.group_multi_company"/>
<separator orientation="vertical" />
<filter string="Day" icon="terp-go-today"
domain="[]" context="{'group_by':'day'}"/>
domain="[]" context="{'group_by':'day'}"
help="Date of claim"/>
<filter string="Month" icon="terp-go-month"
domain="[]" context="{'group_by':'month'}" />
domain="[]" context="{'group_by':'month'}"
help="Month of claim"/>
<filter string="Year" icon="terp-go-year"
domain="[]" context="{'group_by':'name'}" />
domain="[]" context="{'group_by':'name'}"
help="Year of claim"/>
</group>
</search>
</field>
</record>
@@ -182,7 +185,7 @@
<!-- CRM Claim Report Action -->
<record id="action_report_crm_claim" model="ir.actions.act_window">
<field name="name">Claims</field>
<field name="name">Claims Analysis</field>
<field name="res_model">crm.claim.report</field>
<field name="view_type">form</field>
<field name="view_mode">tree,graph</field>
+2 -4
View File
@@ -71,10 +71,8 @@ class crm_fundraising(crm.crm_case, osv.osv):
'ref': fields.reference('Reference', selection=crm._links_get, size=128),
'ref2': fields.reference('Reference 2', selection=crm._links_get, size=128),
'canal_id': fields.many2one('res.partner.canal', 'Channel', \
help="The channels represent the different communication "\
"modes available with the customer." \
" With each commercial opportunity, you can indicate\
the canall which is this opportunity source."),
help="The channels represent the different communication \
modes available with the customer."),
'state': fields.selection(crm.AVAILABLE_STATES, 'State', size=16, readonly=True,
help='The state is set to \'Draft\', when a case is created.\
\nIf the case is in progress the state is set to \'Open\'.\
@@ -37,24 +37,6 @@
id="menu_crm_fundraising_stage_act"
parent="menu_config_fundrising" />
<!-- Fund Resource Type Form View -->
<record id="crm_fundraising_resource_act" model="ir.actions.act_window">
<field name="name">Fundraising Resource Type</field>
<field name="res_model">crm.case.resource.type</field>
<field name="view_type">form</field>
<field name="view_id" ref="crm.crm_case_resource_type_tree"/>
<field name="domain">[('object_id.model', '=', 'crm.fundraising')]</field>
<field name="context">{'object_id':'crm.fundraising'}</field>
</record>
<menuitem action="crm_fundraising_resource_act"
groups="base.group_extended" name="Resource Type"
id="menu_crm_fundraising_resource_act"
parent="menu_config_fundrising" />
<!-- Fund Raising Tree View -->
<record model="ir.ui.view" id="crm_case_tree_view_fund">
@@ -63,7 +45,7 @@
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Funds Tree"
colors="red:state=='open';black:state in ('draft', 'cancel','done','pending')">
colors="blue:state=='pending';grey:state in ('cancel', 'done')">
<field name="name" string="Fund Description" />
<field name="categ_id" />
<field name="type_id" string="Payment Mode" />
@@ -159,7 +141,7 @@
<field colspan="4" name="email_cc" string="Global CC" widget="char"/>
</group>
<field name="message_ids" colspan="4" nolabel="1" mode="tree,form">
<tree string="Communication history">
<tree string="History">
<field name="display_text" string="History Information"/>
<field name="history" invisible="1"/>
<button
@@ -168,7 +150,7 @@
context="{'mail':'reply', 'model': 'crm.fundraising', 'include_original' : True}"
icon="terp-mail-replied" type="action" />
</tree>
<form string="Communication history">
<form string="History">
<group col="4" colspan="4">
<field name="email_from"/>
<field name="date"/>
@@ -197,7 +179,7 @@
</notebook>
</form>
</field>
<button string="Add New Note"
<button string="Add Internal Note"
name="%(crm.action_crm_add_note)d"
context="{'model': 'crm.lead' }"
icon="terp-document-new" type="action" />
@@ -298,7 +280,7 @@
</group>
<newline/>
<group expand="0" string="Group By...">
<filter string="Partner" icon="terp-personal"
<filter string="Partner" icon="terp-partner"
domain="[]"
context="{'group_by':'partner_id'}" />
<filter string="Responsible" icon="terp-personal"
+2 -2
View File
@@ -38,8 +38,8 @@ msgstr "Avg. Probability"
#. module: crm_fundraising
#: help:crm.fundraising,canal_id:0
msgid "The channels represent the different communication modes available with the customer. With each commercial opportunity, you can indicate the canall which is this opportunity source."
msgstr "The channels represent the different communication modes available with the customer. With each commercial opportunity, you can indicate the canall which is this opportunity source."
msgid "The channels represent the different communication modes available with the customer."
msgstr "The channels represent the different communication modes available with the customer."
#. module: crm_fundraising
#: constraint:ir.actions.act_window:0
@@ -61,6 +61,10 @@ class crm_fundraising_report(osv.osv):
'delay_close': fields.float('Delay to close', digits=(16,2),readonly=True, group_operator="avg",help="Number of Days to close the case"),
'partner_id': fields.many2one('res.partner', 'Partner'),
'company_id': fields.many2one('res.company', 'Company'),
'type_id': fields.many2one('crm.case.resource.type', 'Fundraising Type', \
domain="[('section_id','=',section_id),\
('object_id.model', '=', 'crm.fundraising')]"),
'planned_cost': fields.float('Planned Costs',readonly=True,digits=(16,2)),
}
def init(self, cr):
@@ -74,26 +78,28 @@ class crm_fundraising_report(osv.osv):
create or replace view crm_fundraising_report as (
select
min(c.id) as id,
to_char(c.create_date, 'YYYY') as name,
to_char(c.create_date, 'MM') as month,
to_char(c.create_date, 'YYYY-MM-DD') as day,
to_char(c.date, 'YYYY') as name,
to_char(c.date, 'MM') as month,
to_char(c.date, 'YYYY-MM-DD') as day,
c.state,
c.user_id,
c.section_id,
c.categ_id,
c.type_id,
c.company_id,
c.partner_id,
count(*) as nbr,
date_trunc('day',c.create_date) as create_date,
sum(planned_revenue) as amount_revenue,
sum(planned_cost) as planned_cost,
sum(planned_revenue*probability)::decimal(16,2) as amount_revenue_prob,
avg(probability)::decimal(16,2) as probability,
avg(extract('epoch' from (c.date_closed-c.create_date)))/(3600*24) as delay_close
from
crm_fundraising c
group by to_char(c.create_date, 'YYYY'), to_char(c.create_date, 'MM'),\
c.state, c.user_id,c.section_id,c.categ_id,c.partner_id,c.company_id,
c.create_date,to_char(c.create_date, 'YYYY-MM-DD')
group by to_char(c.date, 'YYYY'), to_char(c.date, 'MM'),\
c.state, c.user_id,c.section_id,c.categ_id,type_id,c.partner_id,c.company_id,
c.create_date,to_char(c.date, 'YYYY-MM-DD')
)""")
crm_fundraising_report()
@@ -9,7 +9,7 @@
<field name="model">crm.fundraising.report</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree colors="blue:state in ('draft');black:state in ('open','pending');gray:state in ('done','cancel') " string="Fundraising">
<tree string="Fundraising">
<field name="name" invisible="1"/>
<field name="month" invisible="1"/>
<field name="section_id" invisible="1"/>
@@ -17,6 +17,7 @@
<field name="company_id" invisible="1"/>
<field name="partner_id" invisible="1"/>
<field name="nbr" string='#Fundraising' sum="#Fundraising"/>
<field name="planned_cost" sum='Planned Costs'/>
<field name="amount_revenue" sum='Est.Revenue'/>
<field name="probability" avg='Avg. Probability' widget="progressbar"/>
<field name="amount_revenue_prob" sum='Est. Rev*Prob.'/>
@@ -24,6 +25,7 @@
<field name="state" invisible="1"/>
<field name="categ_id" invisible="1"/>
<field name="day" invisible="1"/>
<field name="type_id" invisible="1"/>
</tree>
</field>
@@ -74,14 +76,17 @@
<field name="arch" type="xml">
<search string="Search">
<group col="16" colspan="8">
<filter string="This Year" icon="terp-go-year"
domain="[('create_date','&lt;=', time.strftime('%%Y-%%m-%%d')), ('create_date','&gt;',(datetime.date.today()-datetime.timedelta(days=365)).strftime('%%Y-%%m-%%d'))]"/>
<filter string=" Year " icon="terp-go-year"
domain="[('create_date','&lt;=', time.strftime('%%Y-%%m-%%d')),('create_date','&gt;=',time.strftime('%%Y-01-01'))]"
help="Funds raised in current year"/>
<filter string="This Month" icon="terp-go-month" name="This Month"
domain="[('create_date','&lt;=', time.strftime('%%Y-%%m-%%d')), ('create_date','&gt;',(datetime.date.today()-datetime.timedelta(days=30)).strftime('%%Y-%%m-%%d'))]"/>
<filter string=" Month " icon="terp-go-month" name="This Month"
domain="[('create_date','&lt;=', time.strftime('%%Y-%%m-%%d')),('create_date','&gt;=',time.strftime('%%Y-%%m-01'))]"
help="Funds raised in current month"/>
<filter icon="terp-go-week" string="7 Days" separator="1"
domain="[('create_date','&lt;=', time.strftime('%%Y-%%m-%%d')), ('create_date','&gt;',(datetime.date.today()-datetime.timedelta(days=7)).strftime('%%Y-%%m-%%d'))]"/>
<filter icon="terp-go-month" string=" Month-1 " separator="1"
domain="[('create_date','&lt;=', (datetime.date (int(time.strftime('%%Y')), datetime.date.today().month, 1) - datetime.timedelta (days = 1)).strftime('%%Y-%%m-%%d')),('create_date','&gt;',(datetime.date (int(time.strftime('%%Y')), datetime.date.today().month-1, 1)).strftime('%%Y-%%m-%%d'))]"
help="Funds raised in last month"/>
<separator orientation="vertical" />
<filter icon="terp-document-new"
@@ -95,25 +100,24 @@
domain="[('state','=','pending')]"/>
<separator orientation="vertical" />
<field name="section_id"
<field name="section_id" string="Sales Team"
default="context.get('section_id', False)"
widget="selection"
context="{'invisible_section': False}">
<filter icon="terp-personal+"
context="{'invisible_section': False}"
domain="[('section_id.user_id','=',uid)]"
help="My section" />
help="My team" />
</field>
<field name="company_id" widget="selection">
<field name="company_id">
<filter icon="terp-go-home"
context="{'invisible_section': False}"
domain="[('section_id.user_id.company_id','=',uid)]"
help="My company"/>
</field>
<field name="user_id" select="1" widget="selection">
<field name="user_id" select="1" string="Salesman">
<filter icon="terp-personal+" string="My Case" help="My Case" domain="[('user_id','=',uid)]" />
</field>
</group>
@@ -137,27 +141,31 @@
<filter string="User" name="User" icon="terp-personal"
domain="[]" context="{'group_by':'user_id'}" />
<filter string="Company" icon="terp-go-home"
domain="[]"
context="{'group_by':'company_id'}" />
<filter string="Section" icon="terp-personal+"
<filter string="Sales Team" icon="terp-personal+"
domain="[]"
context="{'group_by':'section_id'}" />
<separator orientation="vertical" />
<filter string="State" icon="terp-stock_effects-object-colorize"
<filter string="State" icon="terp-stock_effects-object-colorize"
domain="[]" context="{'group_by':'state'}" />
<filter string="Category" icon="terp-stock_symbol-selection"
domain="[]" context="{'group_by':'categ_id'}" />
<filter string="Payment Mode" help="Payment Mode"
icon="terp-dolar" domain="[]"
context="{'group_by':'type_id'}" />
<separator orientation="vertical" />
<filter string="Company" icon="terp-go-home"
domain="[]"
context="{'group_by':'company_id'}" />
<separator orientation="vertical" />
<filter string="Day" icon="terp-go-today"
domain="[]" context="{'group_by':'day'}"/>
domain="[]" context="{'group_by':'day'}"
help="Date of fundraising"/>
<filter string="Month" icon="terp-go-month"
domain="[]" context="{'group_by':'month'}" />
domain="[]" context="{'group_by':'month'}"
help="Month of fundraising"/>
<filter string="Year" icon="terp-go-year"
domain="[]" context="{'group_by':'name'}" />
@@ -169,7 +177,7 @@
<!-- Fundraising by user and section Action -->
<record id="action_report_crm_fundraising" model="ir.actions.act_window">
<field name="name">Fundraising</field>
<field name="name">Fundraising Analysis</field>
<field name="res_model">crm.fundraising.report</field>
<field name="view_type">form</field>
<field name="view_mode">tree,graph</field>
+5 -5
View File
@@ -96,7 +96,7 @@
<field colspan="4" name="email_cc" string="Global CC" widget="char"/>
</group>
<field name="message_ids" colspan="4" nolabel="1" mode="tree,form">
<tree string="Communication history">
<tree string="History">
<field name="display_text" string="History Information"/>
<field name="history" invisible="1"/>
<button
@@ -105,7 +105,7 @@
context="{'mail':'reply', 'model': 'crm.helpdesk', 'include_original' : True}"
icon="terp-mail-replied" type="action" />
</tree>
<form string="Communication history">
<form string="History">
<group col="4" colspan="4">
<field name="email_from"/>
<field name="date"/>
@@ -134,7 +134,7 @@
</notebook>
</form>
</field>
<button string="Add New Note"
<button string="Add Internal Note"
name="%(crm.action_crm_add_note)d"
context="{'model': 'crm.lead' }"
icon="terp-document-new" type="action" />
@@ -264,10 +264,10 @@
domain="[]" help="Sales Team"
context="{'group_by':'section_id'}" />
<separator orientation="vertical"/>
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]"
context="{'group_by':'state'}" />
<filter string="Priority" icon="terp-rating-rated"
domain="[]" context="{'group_by':'priority'}" />
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]"
context="{'group_by':'state'}" />
<separator orientation="vertical"/>
<filter string="Date" icon="terp-go-month"
domain="[]" help="Request Date"
+2 -2
View File
@@ -547,8 +547,8 @@ msgstr "Probability (%)"
#. module: crm_helpdesk
#: help:crm.helpdesk,canal_id:0
msgid "The channels represent the different communication modes available with the customer."
msgstr "The channels represent the different communication modes available with the customer."
msgid "The channels represent the different communication modes available with the customer."
msgstr "The channels represent the different communication modes available with the customer."
#. module: crm_helpdesk
#: view:crm.helpdesk.report:0
@@ -50,12 +50,22 @@ class crm_helpdesk_report(osv.osv):
('07', 'July'), ('08', 'August'),\
('09', 'September'), ('10', 'October'),\
('11', 'November'), ('12', 'December')], 'Month', readonly=True),
'delay_close': fields.char('Delay to close', size=20, readonly=True),
'delay_close': fields.float('Delay to Close',digits=(16,2),readonly=True, group_operator="avg"),
'partner_id': fields.many2one('res.partner', 'Partner' , readonly=True),
'company_id': fields.many2one('res.company', 'Company', readonly=True),
'date_deadline': fields.date('Deadline'),
'priority': fields.selection([('5', 'Lowest'), ('4', 'Low'), \
('3', 'Normal'), ('2', 'High'), ('1', 'Highest')], 'Priority'),
'canal_id': fields.many2one('res.partner.canal', 'Channel'),
'categ_id': fields.many2one('crm.case.categ', 'Category', \
domain="[('section_id','=',section_id),\
('object_id.model', '=', 'crm.helpdesk')]"),
'planned_cost': fields.float('Planned Costs'),
'create_date': fields.date('Creation Date' , readonly=True),
'date_closed': fields.date('Close Date', readonly=True),
'delay_expected': fields.float('Overpassed Deadline',digits=(16,2),readonly=True, group_operator="avg"),
'day': fields.char('Day', size=128, readonly=True),
'email': fields.integer('# Emails', size=128, readonly=True),
}
def init(self, cr):
@@ -70,8 +80,11 @@ class crm_helpdesk_report(osv.osv):
create or replace view crm_helpdesk_report as (
select
min(c.id) as id,
to_char(c.create_date, 'YYYY') as name,
to_char(c.create_date, 'MM') as month,
to_char(c.date, 'YYYY') as name,
to_char(c.date, 'MM') as month,
to_char(c.date, 'YYYY-MM-DD') as day,
to_char(c.create_date, 'YYYY-MM-DD') as create_date,
to_char(c.date_closed, 'YYYY-mm-dd') as date_closed,
c.state,
c.user_id,
c.section_id,
@@ -79,13 +92,19 @@ class crm_helpdesk_report(osv.osv):
c.company_id,
c.priority,
c.date_deadline,
c.categ_id,
c.canal_id,
c.planned_cost,
count(*) as nbr,
to_char(avg(date_closed-c.create_date), 'DD"d" HH24:MI:SS') as delay_close
extract('epoch' from (c.date_closed-c.create_date))/(3600*24) as delay_close,
(SELECT count(id) FROM mailgate_message WHERE model='crm.helpdesk' AND res_id=c.id AND history=True) AS email,
abs(avg(extract('epoch' from (c.date_deadline - c.date_closed)))/(3600*24)) as delay_expected
from
crm_helpdesk c
group by to_char(c.create_date, 'YYYY'), to_char(c.create_date, 'MM'),\
group by to_char(c.date, 'YYYY'), to_char(c.date, 'MM'),to_char(c.date, 'YYYY-MM-DD'),\
c.state, c.user_id,c.section_id,c.priority,\
c.partner_id,c.company_id,c.date_deadline
c.partner_id,c.company_id,c.date_deadline,c.create_date,c.date,c.date_closed,\
c.categ_id,c.canal_id,c.planned_cost,c.id
)""")
crm_helpdesk_report()
@@ -9,18 +9,23 @@
<field name="model">crm.helpdesk.report</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree colors="blue:state in ('draft');black:state in ('open','pending');gray:state in ('done','cancel') " string="Helpdesk">
<field name="name" />
<field name="month"/>
<field name="section_id" />
<field name="user_id" />
<field name="company_id"/>
<field name="partner_id" />
<tree string="Helpdesk">
<field name="name" invisible="1"/>
<field name="month" invisible="1"/>
<field name="section_id" invisible="1"/>
<field name="user_id" invisible="1"/>
<field name="company_id" invisible="1"/>
<field name="partner_id" invisible="1"/>
<field name="date_deadline" invisible="1"/>
<field name="priority" invisible="1"/>
<field name="nbr" string="#Helpdesk" />
<field name="nbr" string="#Helpdesk" sum="#Helpdesk"/>
<field name="email" sum="# Mails"/>
<field name="delay_close"/>
<field name="delay_expected"/>
<field name="planned_cost"/>
<field name="state" invisible="1"/>
<field name="day" invisible="1"/>
<field name="canal_id" invisible="1"/>
</tree>
</field>
</record>
@@ -71,13 +76,15 @@
<field name="arch" type="xml">
<search string="Search">
<group col="16" colspan="9">
<filter string="This Year" icon="terp-go-year"
domain="[('name','=',time.localtime()[0])]"
default="1" />
<filter string="This Month" icon="terp-go-month"
domain="[('month','=',time.strftime('%%m'))]"
default="1" />
<filter string=" Year " icon="terp-go-year"
domain="[('create_date','&lt;=', time.strftime('%%Y-%%m-%%d')),('create_date','&gt;=',time.strftime('%%Y-01-01'))]"
help="Helpdesk requests occurred in current year"/>
<filter string=" Month " icon="terp-go-month" name="this_month"
domain="[('create_date','&lt;=', time.strftime('%%Y-%%m-%%d')),('create_date','&gt;=',time.strftime('%%Y-%%m-01'))]"
help="Helpdesk requests occurred in current month"/>
<filter icon="terp-go-month" string=" Month-1 " separator="1"
domain="[('create_date','&lt;=', (datetime.date (int(time.strftime('%%Y')), datetime.date.today().month, 1) - datetime.timedelta (days = 1)).strftime('%%Y-%%m-%%d')),('create_date','&gt;',(datetime.date (int(time.strftime('%%Y')), datetime.date.today().month-1, 1)).strftime('%%Y-%%m-%%d'))]"
help="Helpdesk requests occurred in last month"/>
<separator orientation="vertical" />
<filter string="Current" icon="terp-check"
@@ -89,29 +96,26 @@
<filter string="Lost" icon="terp-dialog-close"
domain="[('state','=','cancel')]" />
<filter string="Deadline" icon="terp-go-month"
domain="[('date_deadline','=',time.strftime('%%m/%%d/%%Y'))]" />
<separator orientation="vertical" />
<field name="section_id"
<field name="section_id" string="Sales Team"
default="context.get('section_id', False)"
widget="selection"
context="{'invisible_section': False}">
<filter icon="terp-personal+"
context="{'invisible_section': False}"
domain="[('section_id.user_id','=',uid)]"
help="My section" />
help="My team" />
</field>
<field name="company_id" widget="selection">
<filter icon="terp-go-home"
<field name="company_id">
<filter icon="terp-go-home"
context="{'invisible_section': False}"
domain="[('section_id.user_id.company_id','=',uid)]"
help="My company"/>
</field>
<field name="user_id" widget="selection"/>
<field name="user_id" string="Salesman">
<filter icon="terp-personal+" string="My Case" help="My Case" domain="[('user_id','=',uid)]" />
</field>
</group>
<newline/>
<group expand="0" string="Extended Filters..." groups="base.group_extended">
@@ -123,29 +127,34 @@
<filter string="User" icon="terp-personal"
domain="[]" context="{'group_by':'user_id'}"
default="1" />
<filter string="Company" icon="terp-go-home"
domain="[]"
context="{'group_by':'company_id'}" />
<filter string="Section" icon="terp-personal+"
<filter string="Sales Team" icon="terp-personal+"
domain="[]"
context="{'group_by':'section_id'}" />
<separator orientation="vertical" />
<filter string="State" icon="terp-stock_effects-object-colorize"
domain="[]" context="{'group_by':'state'}" />
<filter string="Partner" icon="terp-personal"
domain="[]"
context="{'group_by':'partner_id'}" />
<separator orientation="vertical" />
<filter string="Channel" icon="terp-call-start"
domain="[]"
context="{'group_by':'canal_id'}" />
<separator orientation="vertical" />
<filter string="State" icon="terp-stock_effects-object-colorize"
domain="[]" context="{'group_by':'state'}" />
<separator orientation="vertical" />
<filter string="Company" icon="terp-go-home"
domain="[]"
context="{'group_by':'company_id'}" />
<separator orientation="vertical" />
<filter string="Day" icon="terp-go-today"
domain="[]" context="{'group_by':'day'}" help="Date of helpdesk requests"/>
<filter string="Month" icon="terp-go-month"
domain="[]" context="{'group_by':'month'}" />
domain="[]" context="{'group_by':'month'}" help="Month of helpdesk requests"/>
<filter string="Year" icon="terp-go-year"
domain="[]" context="{'group_by':'name'}" />
domain="[]" context="{'group_by':'name'}" help="Year of helpdesk requests" />
</group>
</search>
</field>
@@ -154,10 +163,11 @@
<!-- Helpdesk report after Sales Services Action -->
<record id="action_report_crm_helpdesk" model="ir.actions.act_window">
<field name="name">Helpdesk</field>
<field name="name">Helpdesk Analysis</field>
<field name="res_model">crm.helpdesk.report</field>
<field name="view_type">form</field>
<field name="view_mode">tree,graph</field>
<field name="context">{"search_default_User":1,"search_default_This Month":1,'group_by_no_leaf':1,'group_by':[]}</field>
<field name="view_id" ref="view_report_crm_helpdesk_tree"/>
<field name="search_view_id" ref="view_report_crm_helpdesk_filter"/>
<field name="help">Helpdesk allows you to consult different informations relative to support demands. Check for treatments delays, number of responses given and emails send and costs. You can sort out your analysis on different groups to get fine grained analysis.</field>
+8 -10
View File
@@ -44,7 +44,7 @@
<field name="name" />
<newline/>
<group expand="0" string="Group By..." groups="base.group_extended">
<filter string="Type" domain="[]" context="{'group_by':'type'}"/>
<filter string="Type" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by':'type'}"/>
</group>
</search>
</field>
@@ -80,7 +80,7 @@
<separator string="Directory Type" colspan="4"/>
<field name="type"/>
<group colspan="4" col="4" attrs="{'invisible': [('type','!=','ressource')]}">
<field name="ressource_type_id" on_change="onchange_content_id(ressource_type_id)"
<field name="ressource_type_id" on_change="onchange_content_id(ressource_type_id)"
attrs="{'required': [('type','=','ressource')] }"/>
<field name="resource_find_all" groups="base.group_extended" />
<newline/>
@@ -93,7 +93,7 @@
<field name="ressource_parent_type_id"/>
<field name="ressource_id" select="2" readonly="1"/>
</group>
</page>
<page string="Generated Files" groups="base.group_extended">
<label colspan="4" string="For each entry here, virtual files will appear in this folder." />
@@ -168,7 +168,7 @@
<field name="storage_id" />
<newline/>
<group expand="0" string="Group By..." groups="base.group_extended">
<filter string="Type" domain="[]" context="{'group_by':'type'}"/>
<filter string="Type" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by':'type'}"/>
<filter string="Owner" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>
<filter string="Storage" domain="[]" context="{'group_by':'storage_id'}"/>
</group>
@@ -282,10 +282,9 @@
<field name="model">ir.attachment</field>
<field name="type">search</field>
<field name="arch" type="xml">
<search string="IR Attachment">
<filter icon="terp-go-month" string="Recent Month"
help="Attachment modified/created last 30 days"
domain="[('create_date','&lt;=', time.strftime('%%Y-%%m-%%d')),('create_date','&gt;',(datetime.date.today()-datetime.timedelta(days=30)).strftime('%%Y-%%m-%%d'))]"
<search string="Document">
<filter icon="terp-go-month" string="Month"
domain="[('create_date','&lt;=', time.strftime('%%Y-%%m-%%d')),('create_date','&gt;=',time.strftime('%%Y-%%m-01'))]"
/>
<separator orientation="vertical"/>
<field name="name"/>
@@ -293,7 +292,7 @@
<field name="user_id">
<filter icon="terp-personal"
domain="[('user_id','=', False)]"
help="Filter on my Attachment" />
help="Filter on my documents" />
</field>
<field name="partner_id"/>
<field name="company_id" groups="base.group_multi_company"/>
@@ -332,7 +331,6 @@
<field name="name">Documents</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">ir.attachment</field>
<field name="name">Document</field>
<field name="view_type">form</field>
<field name="search_view_id" ref="view_attach_filter"/>
<field name="help">Documents give your access to all attached documents; it's a repository of all attached documents (mails, documents attached to a project, etc.)</field>
@@ -4,7 +4,7 @@
<record id="ftp_browse_form" model="ir.ui.view">
<field name="name">Document FTP Browse</field>
<field name="model">document.ftp.browse</field>
<field name="type">form</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Browse Document">
<separator string="Browse Document" colspan="4"/>
@@ -12,7 +12,7 @@
<separator colspan="4"/>
<group col="4" colspan="4">
<label string="" colspan="2"/>
<button special="cancel" string="_Close" icon="gtk-cancel"/>
<button special="cancel" string="_Cancel" icon="gtk-cancel"/>
<button name="browse_ftp" string="_Browse" type="object" icon="gtk-ok"/>
</group>
</form>
@@ -32,7 +32,7 @@
<menuitem
name="Shared Repository (FTP)"
action="action_ftp_browse"
id="menu_document_browse"
id="menu_document_browse"
icon="STOCK_EXECUTE"
parent="document.menu_document_doc" sequence="1"/>
@@ -3,7 +3,7 @@
<record model="ir.actions.url" id="action_document_browse">
<field name="name">Browse Files</field>
<field name="url">ftp://localhost:8021/</field>
</record>
</record>
+3 -3
View File
@@ -371,7 +371,7 @@
<field colspan="4" name="email_cc" string="CC" widget="char" size="512"/>
</group>
<field name="message_ids" colspan="4" nolabel="1" mode="tree,form">
<tree string="Communication history">
<tree string="History">
<field name="display_text" string="History Information"/>
<field name="history" invisible="1"/>
<button
@@ -380,7 +380,7 @@
context="{'mail':'reply', 'model': 'event.registration', 'include_original' : True}"
icon="terp-mail-replied" type="action" />
</tree>
<form string="Communication history">
<form string="History">
<group col="4" colspan="4">
<field name="email_from"/>
<field name="date"/>
@@ -409,7 +409,7 @@
</notebook>
</form>
</field>
<button string="Add New Note"
<button string="Add Internal Note"
name="%(crm.action_crm_add_note)d"
context="{'model': 'crm.lead' }"
icon="terp-document-new" type="action" />
+1 -1
View File
@@ -19,7 +19,7 @@
<attribute name='string'></attribute>
</xpath>
<xpath expr="//label[@string='description']" position="attributes">
<attribute name="string">You can enhance the base HR Application by installing few HR-related modules.</attribute>
<attribute name="string">You can enhance the base HR Application by installing few HR-related functionalities.</attribute>
</xpath>
<group colspan="8">
<field name="hr_holidays"/>
+2 -2
View File
@@ -35,7 +35,7 @@ class hr_installer(osv.osv_memory):
help="Helps you manage and streamline your recruitment process."),
'hr_timesheet_sheet':fields.boolean('Timesheets',
help="Tracks and helps employees encode and validate timesheets "
"and attendance."),
"and attendances."),
'hr_contract': fields.boolean("Employee's Contracts",
help="Extends employee profiles to help manage their contracts."),
'hr_evaluation': fields.boolean('Periodic Evaluations',
@@ -44,7 +44,7 @@ class hr_installer(osv.osv_memory):
'hr_attendance': fields.boolean('Attendances',
help="Simplifies the management of employee's attendances."),
'hr_payroll': fields.boolean('Payroll',
help="Generic Payroll system"),
help="Generic Payroll system."),
'hr_payroll_account': fields.boolean('Payroll Accounting',
help="Generic Payroll system Integrated with Accountings."),
}
@@ -142,7 +142,7 @@
<field colspan="4" name="email_cc" string="Global CC" widget="char"/>
</group>
<field name="message_ids" colspan="4" nolabel="1" mode="tree,form">
<tree string="Communication history">
<tree string="History">
<field name="display_text" string="History Information"/>
<field name="history" invisible="1"/>
<button
@@ -151,7 +151,7 @@
context="{'mail':'reply', 'model': 'hr.applicant', 'include_original' : True}"
icon="terp-mail-replied" type="action" />
</tree>
<form string="Communication history">
<form string="History">
<group col="4" colspan="4">
<field name="email_from"/>
<field name="date"/>
@@ -180,7 +180,7 @@
</notebook>
</form>
</field>
<button string="Add New Note"
<button string="Add Internal Note"
name="%(crm.action_crm_add_note)d"
context="{'model': 'crm.lead' }"
icon="terp-document-new" type="action" />
+2 -2
View File
@@ -28,7 +28,7 @@ class mrp_installer(osv.osv_memory):
# Manufacturing Resource Planning
'stock_location': fields.boolean('Advanced Routes',
help="Manages product routes and paths within and between "
"locations (e.g. warehouses)"),
"locations (e.g. warehouses)."),
'mrp_jit': fields.boolean('Just In Time Scheduling',
help="Enables Just In Time computation of procurement orders."
"\n\nWhile it's more resource intensive than the default "
@@ -37,7 +37,7 @@ class mrp_installer(osv.osv_memory):
"procurement scheduler manually."),
'mrp_operations': fields.boolean('Manufacturing Operations',
help="Enhances production orders with readiness states as well "
"as the date of start and end of execution of the order."),
"as the start date and end date of execution of the order."),
'mrp_subproduct': fields.boolean('MRP Subproducts',
help="Enables multiple product output from a single production "
"order: without this, a production order can have only one "
+11 -10
View File
@@ -35,7 +35,7 @@
<field name="flow_start"/>
<field name="kind" select="1"/>
<field name="subflow_id" attrs="{'invisible':[('kind','!=','subflow')]}"/>
</group>
<notebook colspan="4">
<page string="Properties">
@@ -74,14 +74,14 @@
</group>
</group>
</page>
<page string="Notes">
<page string="Notes">
<field name="note" nolabel="1" colspan="4"/>
</page>
</notebook>
</form>
</field>
</page>
<page string="Extra Information">
<page string="Notes">
<field name="note" colspan="4" nolabel="1"/>
</page>
</notebook>
@@ -114,7 +114,7 @@
</group>
<newline/>
<group expand="0" string="Group By..." colspan="4" col="4">
<filter string="Object" icon="terp-personal" domain="[]" context="{'group_by':'model_id'}"/>
<filter string="Object" icon="terp-stock_align_left_24" domain="[]" context="{'group_by':'model_id'}"/>
</group>
</search>
</field>
@@ -160,7 +160,7 @@
<field name="flow_start"/>
<field name="kind" select="1"/>
<field name="subflow_id" attrs="{'invisible':[('kind','!=','subflow')]}"/>
</group>
<notebook colspan="4">
<page string="Properties">
@@ -199,7 +199,7 @@
</group>
</group>
</page>
<page string="Notes">
<page string="Notes">
<field name="note" nolabel="1" colspan="4"/>
</page>
</notebook>
@@ -220,8 +220,8 @@
</group>
<newline/>
<group expand="0" string="Group By..." colspan="4" col="4">
<filter string="Object" icon="terp-personal" domain="[]" context="{'group_by':'model_id'}"/>
<filter string="Kind Of Node" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'kind'}"/>
<filter string="Object" icon="terp-stock_align_left_24" domain="[]" context="{'group_by':'model_id'}"/>
<filter string="Kind Of Node" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by':'kind'}"/>
</group>
</search>
</field>
@@ -261,9 +261,8 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Process Transition">
<group>
<group col="6" colspan="4">
<field name="name" select="1"/>
<newline/>
<field name="source_node_id" select="1"/>
<field name="target_node_id" select="1"/>
</group>
@@ -308,11 +307,13 @@
<field name="source_node_id"/>
<field name="target_node_id" />
</group>
<!--
<newline/>
<group expand="0" string="Group By..." colspan="4" col="4">
<filter string="Source Node" icon="terp-personal" domain="[]" context="{'group_by':'source_node_id'}"/>
<filter string="Target Node" icon="terp-personal" domain="[]" context="{'group_by':'target_node_id'}"/>
</group>
-->
</search>
</field>
</record>
+3 -3
View File
@@ -25,9 +25,9 @@ class misc_tools_installer(osv.osv_memory):
_inherit = 'res.config.installer'
_columns = {
'lunch':fields.boolean('Lunch',help='Helps to manage Lunch Orders'),
'subscription':fields.boolean('Recurring Documents',help='Helps to add subscription on documents'),
'survey':fields.boolean('Survey',help='Manages Custom Surveys'),
'lunch':fields.boolean('Lunch',help='Helps to manage Lunch Orders.'),
'subscription':fields.boolean('Recurring Documents',help='Helps to add subscription on documents.'),
'survey':fields.boolean('Survey',help='Manages Custom Surveys.'),
'idea':fields.boolean('Idea',help='Manages ideas and votes'),
'audittrail':fields.boolean('Audit Trail',help="Lets you to track user's operations on specific Objects."),
}
+5 -8
View File
@@ -31,32 +31,29 @@ class project_installer(osv.osv_memory):
'Long Term Planning',
help="Enables long-term projects tracking, including "
"multiple-phase projects and resource allocation handling."),
'project_wiki': fields.boolean('Specifications in a Wiki',
help=""),
'hr_timesheet_sheet': fields.boolean('Timesheets',
help="Tracks and helps employees encode and validate timesheets "
"and attendance."),
"and attendances."),
'hr_timesheet_invoice': fields.boolean('Invoice Based on Hours',
help="Helps generate invoice based on human resources "
help="Helps generate invoices based on human resources "
"costs and general expenses."),
'account_budget': fields.boolean('Budgets',
help="Helps accountants manage analytic and crossover budgets."),
'project_messages': fields.boolean('Project Messages',
help="Lets employees send messages to other members of the "
"projects they're working on."),
'project_crm': fields.boolean('Issues Tracker',
'project_issue': fields.boolean('Issues Tracker',
help="Automatically synchronizes project tasks and crm cases."),
# Methodologies
'project_scrum': fields.boolean('SCRUM',
help="Implements and tracks the concepts and task types defined "
"in the SCRUM methodology."),
'project_gtd': fields.boolean('Getting Things Done',
help="Embeds the 'Getting Things Done concepts' into OpenERP's "
"project management."),
help="GTD is a methodology to efficiently organise yourself and your tasks. This module fully integrates GTD principle with OpenERP's project management."),
}
_defaults={
'project_crm': True,
'project_issue': True,
}
project_installer()
+30 -9
View File
@@ -251,7 +251,7 @@ class project(osv.osv):
context['active_test'] = False
default['state'] = 'open'
if not default.get('name', False):
default['name'] = proj.name+_(' (copy)')
default['name'] = proj.name + _(' (copy)')
res = super(project, self).copy(cr, uid, id, default, context)
return res
@@ -393,6 +393,8 @@ class task(osv.osv):
if not default.get('remaining_hours', False):
default['remaining_hours'] = float(self.read(cr, uid, id, ['planned_hours'])['planned_hours'])
default['active'] = True
if not default.get('name', False):
default['name'] = self.browse(cr, uid, id, context=context).name + _(' (copy)')
return super(task, self).copy_data(cr, uid, id, default, context)
def _check_dates(self, cr, uid, ids, context=None):
@@ -401,7 +403,7 @@ class task(osv.osv):
if task['date_start'] > task['date_end']:
return False
return True
def _is_template(self, cr, uid, ids, field_name, arg, context=None):
res = {}
for task in self.browse(cr, uid, ids, context=context):
@@ -415,7 +417,7 @@ class task(osv.osv):
'active': fields.function(_is_template, method=True, store=True, string='Not a Template Task', type='boolean', help="This field is computed automatically and have the same behavior than the boolean 'active' field: if the task is linked to a template or unactivated project, it will be hidden unless specifically asked."),
'name': fields.char('Task Summary', size=128, required=True),
'description': fields.text('Description'),
'priority' : fields.selection([('4','Very Low'), ('3','Low'), ('2','Medium'), ('1','Urgent'), ('0','Very urgent')], 'Importance'),
'priority' : fields.selection([('4','Very Low'), ('3','Low'), ('2','Medium'), ('1','Urgent'), ('0','Very urgent')], 'Priority'),
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of tasks."),
'type_id': fields.many2one('project.task.type', 'Stage',),
'state': fields.selection([('draft', 'Draft'),('open', 'In Progress'),('pending', 'Pending'), ('cancelled', 'Cancelled'), ('done', 'Done')], 'State', readonly=True, required=True,
@@ -425,8 +427,7 @@ class task(osv.osv):
'date_start': fields.datetime('Starting Date'),
'date_end': fields.datetime('Ending Date'),
'date_deadline': fields.date('Deadline'),
'project_id': fields.many2one('project.project', 'Project', ondelete='cascade',
help="If you have [?] in the project name, it means there are no analytic account linked to this project."),
'project_id': fields.many2one('project.project', 'Project', ondelete='cascade'),
'parent_ids': fields.many2many('project.task', 'project_task_parent_rel', 'task_id', 'parent_id', 'Parent Tasks'),
'child_ids': fields.many2many('project.task', 'project_task_parent_rel', 'parent_id', 'task_id', 'Delegated Tasks'),
'notes': fields.text('Notes'),
@@ -457,15 +458,15 @@ class task(osv.osv):
}
_order = "sequence, priority, date_start, id"
def _check_recursion(self, cr, uid, ids):
obj_task = self.browse(cr, uid, ids[0])
parent_ids = [x.id for x in obj_task.parent_ids]
children_ids = [x.id for x in obj_task.child_ids]
if (obj_task.id in children_ids) or (obj_task.id in parent_ids):
return False
while(ids):
cr.execute('SELECT DISTINCT task_id '\
'FROM project_task_parent_rel '\
@@ -518,6 +519,26 @@ class task(osv.osv):
res['fields'][f]['string'] = res['fields'][f]['string'].replace('Hours',tm)
return res
def action_close(self, cr, uid, ids, context=None):
# This action open wizard to send email to partner or project manager after close task.
project_id = len(ids) and ids[0] or False
if not project_id: return False
task = self.browse(cr, uid, project_id, context=context)
project = task.project_id
res = self.do_close(cr, uid, [project_id], context=context)
if project.warn_manager or project.warn_customer:
return {
'name': _('Send Email after close task'),
'view_type': 'form',
'view_mode': 'form',
'res_model': 'project.task.close',
'type': 'ir.actions.act_window',
'target': 'new',
'nodestroy': True,
'context': {'active_id': task.id}
}
return res
def do_close(self, cr, uid, ids, context=None):
"""
Close Task
@@ -539,7 +560,7 @@ class task(osv.osv):
'ref_doc1': 'project.task,%d'% (task.id,),
'ref_doc2': 'project.project,%d'% (project.id,),
})
for parent_id in task.parent_ids:
if parent_id.state in ('pending','draft'):
reopen = True
+1 -2
View File
@@ -24,9 +24,8 @@
<attribute name="string">Configure</attribute>
</xpath>
<group colspan="8">
<field name="project_crm"/>
<field name="project_issue"/>
<field name="project_long_term" groups="base.group_extended"/>
<field name="project_wiki" groups="base.group_extended"/>
<field name="hr_timesheet_sheet"/>
<field name="hr_timesheet_invoice"/>
<field name="account_budget" groups="base.group_extended"/>
+21 -20
View File
@@ -21,8 +21,8 @@
<field name="name" string="Project Name" select="1"/>
<field name="parent_id" string="Parent Project"/>
<field name="user_id" string="Project Manager" select="1" attrs="{'readonly':[('state','in',['close', 'cancelled'])]}"/>
<field name="date_start" attrs="{'readonly':[('state','in',['close', 'cancelled'])]}"/>
<field name="date" attrs="{'readonly':[('state','in',['close', 'cancelled'])]}"/>
<field name="date_start" string="Start Date" attrs="{'readonly':[('state','in',['close', 'cancelled'])]}"/>
<field name="date" string="End Date" attrs="{'readonly':[('state','in',['close', 'cancelled'])]}"/>
<field name="progress_rate" widget="progressbar"/>
</group>
<notebook colspan="4">
@@ -43,12 +43,13 @@
<field name="warn_manager"/>
</group>
<newline/>
<separator colspan="4"/>
<group col="9" colspan="8">
<field name="state" select="1" readonly="1"/>
<button name="set_template" string="Set as Template" type="object" states="open" icon="gtk-convert"/>
<button name="set_open" string="Reactivate Project" type="object" states="pending,cancelled,close" icon="gtk-ok"/>
<button name="set_pending" string="Pending" type="object" states="open" icon="gtk-media-pause"/>
<button name="set_done" string="Done" type="object" states="open,pending" icon="gtk-jump-to"/>
<button name="set_done" string="Done" type="object" states="open,pending" icon="terp-dialog-close"/>
<button name="set_cancel" string="Cancel" type="object" states="open,pending" icon="gtk-cancel"/>
<button name="reset_project" string="Reset as Project" type="object" states="template" icon="gtk-convert"/>
<button
@@ -110,9 +111,9 @@
<newline />
<group expand="0" string="Group By..." colspan="4" col="20" groups="base.group_extended">
<filter string="Manager" name="Manager" icon="terp-personal" domain = "[]" context="{'group_by':'user_id'}"/>
<filter string="Partner" name="Partner" icon="terp-personal" domain = "[]" context="{'group_by':'partner_id'}"/>
<filter string="Partner" name="Partner" icon="terp-partner" domain = "[]" context="{'group_by':'partner_id'}"/>
<separator orientation="vertical"/>
<filter string="Parent" name="Parent" icon="terp-folder-blue" domain = "[]" context="{'group_by':'parent_id'}"/>
<filter string="Parent" name="Parent" help="Parent Project" icon="terp-folder-blue" domain = "[]" context="{'group_by':'parent_id'}"/>
</group>
</search>
</field>
@@ -239,7 +240,7 @@
<button name="%(action_project_task_reevaluate)d" states="done,cancelled" string="Reactivate" type="action" icon="gtk-convert" context="{'button_reactivate':True}" />
<button name="do_pending" states="open" string="Pending" type="object" icon="gtk-media-pause"/>
<button groups="base.group_extended" name="%(action_project_task_delegate)d" states="pending,open" string="Delegate" type="action" icon="gtk-sort-descending"/>
<button name="%(action_project_task_close)d" states="pending,open" string="Done" type="action" icon="gtk-apply"/>
<button name="action_close" states="pending,open" string="Done" type="object" icon="terp-dialog-close"/>
<button name="do_cancel" states="draft,open,pending" string="Cancel" type="object" icon="gtk-cancel"/>
</group>
</page>
@@ -300,8 +301,11 @@
<field name="project_id" icon="gtk-indent" domain="['|',('user_id','=',uid),('members','=',uid)]"/>
<field name="user_id"/>
<field name="delegated_user_id" invisible="context.get('show_delegated', True)"/>
<field name="planned_hours"/>
<field name="remaining_hours" widget="float_time" sum="Remaining Hours" invisible="context.get('set_visible',False)"/>
<field name="delay_hours"/>
<field name="date_deadline" invisible="context.get('set_visible',False)"/>
<field name="type_id" groups="base.group_extended" invisible="context.get('set_visible',False)"/>
<button name="next_type" invisible="context.get('set_visible',False)"
states="draft,open,pending"
string="Change Stage"
@@ -309,14 +313,13 @@
icon="gtk-go-forward"
groups="base.group_extended"
help="Change Type"/>
<field name="type_id" groups="base.group_extended" invisible="context.get('set_visible',False)"/>
<field name="date_start" invisible="1"/>
<field name="date_end" invisible="1"/>
<field name="progress" widget="progressbar" invisible="context.get('set_visible',False)"/>
<field name="state" invisible="context.get('set_visible',False)"/>
<button name="do_open" states="pending,draft,done,cancel" string="Start Task" type="object" icon="gtk-execute" help="For changing to open state" invisible="context.get('set_visible',False)"/>
<button groups="base.group_extended" name="%(action_project_task_delegate)d" states="pending,open,draft" string="Delegate" type="action" icon="gtk-sort-descending" help="For changing to delegate state"/>
<button name="%(action_project_task_close)d" states="draft,pending,open" string="Done" type="action" icon="gtk-apply" help="For changing to done state"/>
<button name="action_close" states="draft,pending,open" string="Done" type="object" icon="gtk-apply" help="For changing to done state"/>
<button name="do_cancel" states="draft,open,pending" string="Cancel" type="object" icon="gtk-cancel" help="For cancelling the task"/>
</tree>
</field>
@@ -369,8 +372,8 @@
<field name="arch" type="xml">
<search string="Task Edition">
<group col="20" colspan="4">
<filter string="Current" domain="[('state','in',('open','draft'))]" name="current" help="Draft, Open and Pending Tasks" icon="terp-check" default="1"/>
<filter string="In Progress" domain="[('state','=','open')]" help="Open Tasks" icon="terp-camera_test"/>
<filter string="Current" domain="[('state','in',('open','draft'))]" name="current" help="Draft, In Progress and Pending Tasks" icon="terp-check" default="1"/>
<filter string="In Progress" domain="[('state','=','open')]" help="In Progress Tasks" icon="terp-camera_test"/>
<filter string="Pending" domain="[('state','=','pending')]" context="{'show_delegated':False}" help="Pending Tasks" icon="terp-gtk-media-pause"/>
<separator orientation="vertical"/>
<filter name="edit"
@@ -385,7 +388,7 @@
<filter domain="[('project_id.user_id','=',uid)]" help="My Projects" icon="terp-personal"/>
</field>
<field name="user_id" select="1">
<filter domain="[('user_id','=',False)]" help="Unassigned Tasks" icon="terp-personal" separator="1"/>
<filter domain="[('user_id','=',False)]" help="Unassigned Tasks" icon="terp-personal-" separator="1"/>
</field>
</group>
<newline/>
@@ -397,9 +400,10 @@
<filter string="Stages" name="group_stage_id" icon="terp-stage" domain="[]" context="{'group_by':'type_id'}"/>
<filter string="State" name="group_state" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
<separator orientation="vertical"/>
<filter string="Deadline" icon="terp-gnome-cpu-frequency-applet+" domain="[]" context="{'group_by':'date_deadline'}"/>
<separator orientation="vertical"/>
<filter string="Start Date" icon="terp-go-month" domain="[]" context="{'group_by':'date_start'}"/>
<filter string="End Date" icon="terp-go-month" domain="[]" context="{'group_by':'date_end'}"/>
<filter string="Deadline" icon="terp-gnome-cpu-frequency-applet+" domain="[]" context="{'group_by':'date_deadline'}"/>
</group>
</search>
</field>
@@ -414,10 +418,7 @@
<field name="view_id" ref="view_task_tree2"/>
<field name="context">{"search_default_project_id":project_id, "search_default_user_id":uid, "search_default_current": 1}</field>
<field name="search_view_id" ref="view_task_search_form"/>
<field name="help">In OpenERP, a project is made of a set of activities (or tasks) for completion.A list view allows the manager to quickly check for task status and make it evolve, delegate task, etc. A search tool allows a multi-criteria sort of activities.
Issues like bugs in a system, client complain, materials breakdown are collected here.A list view allows the manager to quickly check for them, assign them, make their status evolved.
</field>
<field name="help">In OpenERP, a project is made of a set of activities (or tasks) for completion. A list view allows the manager to quickly check for task status and make it evolve, delegate task, etc. A search tool allows a multi-criteria sort of activities.</field>
</record>
<menuitem action="action_view_task" id="menu_action_view_task" parent="project.menu_project_management" sequence="2"/>
@@ -486,10 +487,10 @@ Issues like bugs in a system, client complain, materials breakdown are collected
<menuitem id="menu_tasks_config" name="Tasks" parent="project.menu_definitions" sequence="1" groups="base.group_system"/>
<menuitem action="open_task_type_form" id="menu_task_types_view" parent="menu_tasks_config" sequence="1"/>
<act_window domain="[('user_id', '=', active_id)]" id="act_res_users_2_project_project" name="User's projects" res_model="project.project" src_model="res.users" view_mode="tree,form" view_type="form"/>
<act_window context="{'search_default_user_id': [active_id]}" id="act_res_users_2_project_project" name="User's projects" res_model="project.project" src_model="res.users" view_mode="tree,form" view_type="form"/>
<act_window
domain="[('project_id', '=', active_id)]"
context="{'search_default_project_id': [active_id]}"
id="act_project_project_2_project_task_all"
name="Tasks"
res_model="project.task"
@@ -537,7 +538,7 @@ Issues like bugs in a system, client complain, materials breakdown are collected
</page>
</field>
</record>
<act_window domain="[('user_id', '=', active_id),('state', '&lt;&gt;', 'cancelled'),('state', '&lt;&gt;', 'done')]" id="act_res_users_2_project_task_opened" name="Assigned tasks" res_model="project.task" src_model="res.users" view_mode="tree,form,gantt,calendar,graph" view_type="form"/>
<act_window domain="[('user_id', '=', active_id),('date', '&gt;=', time.strftime('%Y-%m-01'))]" id="act_res_users_2_project_task_work_month" name="Month works" res_model="project.task.work" src_model="res.users" view_mode="tree,form" view_type="form"/>
<act_window context="{'search_default_user_id': [active_id]}" domain="[('state', '&lt;&gt;', 'cancelled'),('state', '&lt;&gt;', 'done')]" id="act_res_users_2_project_task_opened" name="Assigned tasks" res_model="project.task" src_model="res.users" view_mode="tree,form,gantt,calendar,graph" view_type="form"/>
<act_window context="{'search_default_user_id': [active_id]}" domain="[('date', '&gt;=', time.strftime('%Y-%m-01'))]" id="act_res_users_2_project_task_work_month" name="Month works" res_model="project.task.work" src_model="res.users" view_mode="tree,form" view_type="form"/>
</data>
</openerp>
+1 -1
View File
@@ -49,7 +49,7 @@ class report_project_task_user(osv.osv):
'delay_endings_days': fields.float('Overpassed Deadline', digits=(16,2), readonly=True),
'nbr': fields.integer('# of tasks', readonly=True),
'priority' : fields.selection([('4','Very Low'), ('3','Low'), ('2','Medium'), ('1','Urgent'),
('0','Very urgent')], 'Importance', readonly=True),
('0','Very urgent')], 'Priority', readonly=True),
'month':fields.selection([('01','January'), ('02','February'), ('03','March'), ('04','April'), ('05','May'), ('06','June'), ('07','July'), ('08','August'), ('09','September'), ('10','October'), ('11','November'), ('12','December')], 'Month', readonly=True),
'state': fields.selection([('draft', 'Draft'), ('open', 'In Progress'), ('pending', 'Pending'), ('cancelled', 'Cancelled'), ('done', 'Done')],'State', readonly=True),
'company_id': fields.many2one('res.company', 'Company', readonly=True, groups="base.group_multi_company"),
+15 -15
View File
@@ -58,18 +58,18 @@
<field name="arch" type="xml">
<search string="Tasks Analysis">
<group colspan="10" col="12">
<filter icon="terp-go-year" string=" 365 Days "
domain="[('date_start','&lt;=', time.strftime('%%Y-%%m-%%d')),('date_start','&gt;',(datetime.date.today()-datetime.timedelta(days=365)).strftime('%%Y-%%m-%%d'))]"
help="Tasks performed in last 365 Days"/>
<filter icon="terp-go-month" string=" 30 Days "
<filter icon="terp-go-year" string=" Year "
domain="[('date_start','&lt;=', time.strftime('%%Y-%%m-%%d')),('date_start','&gt;=',time.strftime('%%Y-01-01'))]"
help="Current Year"/>
<filter icon="terp-go-month" string=" Month "
name="month"
domain="[('date_start','&lt;=', time.strftime('%%Y-%%m-%%d')), ('date_start','&gt;',(datetime.date.today()-datetime.timedelta(days=30)).strftime('%%Y-%%m-%%d'))]"
help="Tasks performed in last 30 days"/>
domain="[('date_start','&lt;=', time.strftime('%%Y-%%m-%%d')),('date_start','&gt;=',time.strftime('%%Y-%%m-01'))]"
help="Current Month"/>
<filter icon="terp-go-week"
string=" 7 Days "
string=" Month-1 "
separator="1"
domain="[('date_start','&lt;=', time.strftime('%%Y-%%m-%%d')), ('date_start','&gt;',(datetime.date.today()-datetime.timedelta(days=7)).strftime('%%Y-%%m-%%d'))]"
help="Tasks during last 7 days"/>
domain="[('date_start','&lt;=', (datetime.date (int(time.strftime('%%Y')), datetime.date.today().month, 1) - datetime.timedelta (days = 1)).strftime('%%Y-%%m-%%d')),('date_start','&gt;',(datetime.date (int(time.strftime('%%Y')), datetime.date.today().month-1, 1)).strftime('%%Y-%%m-%%d'))]"
help="Previous Month"/>
<separator orientation="vertical"/>
<filter string="Draft"
icon="terp-document-new"
@@ -120,18 +120,18 @@
<newline/>
<group expand="1" string="Group By..." colspan="10" col="12">
<filter string="Project" name="project" icon="terp-folder-blue" context="{'group_by':'project_id'}"/>
<filter string="Assigned to" name="User" icon="terp-personal" context="{'group_by':'user_id'}" />
<separator orientation="vertical"/>
<filter string="Partner" icon="terp-personal" context="{'group_by':'partner_id'}" />
<filter string="Task" icon="terp-stock_align_left_24" context="{'group_by':'name'}" />
<separator orientation="vertical"/>
<filter string="Partner" icon="terp-partner" context="{'group_by':'partner_id'}" />
<filter string="Assigned to" name="User" icon="terp-personal" context="{'group_by':'user_id'}" />
<separator orientation="vertical"/>
<filter string="State" icon="terp-stock_effects-object-colorize" context="{'group_by':'state'}"/>
<filter string="Company" icon="terp-go-home" context="{'group_by':'company_id'}" groups="base.group_multi_company"/>
<filter string="Stage" icon="terp-stage" context="{'group_by':'type_id'}" />
<separator orientation="vertical"/>
<filter string="Day" icon="terp-go-today" context="{'group_by':'day'}"/>
<filter string="Month" icon="terp-go-month" context="{'group_by':'month'}"/>
<filter string="Year" icon="terp-go-year" context="{'group_by':'year'}"/>
<filter string="Day" icon="terp-go-today" context="{'group_by':'day'}" help="Current Day"/>
<filter string="Month" icon="terp-go-month" context="{'group_by':'month'}" help="Current Month"/>
<filter string="Year" icon="terp-go-year" context="{'group_by':'year'}" help="Current Year"/>
</group>
</search>
</field>
@@ -6,6 +6,10 @@
<field name="name">Project / Financial Manager</field>
</record>
<record id="group_project_finance_user" model="res.groups">
<field name="name">Project / Financial User</field>
</record>
<record id="group_project_manager" model="res.groups">
<field name="name">Project / Manager</field>
</record>
@@ -43,5 +47,12 @@
<field name="domain_force">['|','|','|',('user_id','=',False),('user_id','=',user.id),('project_id.members','in', [user.id]),('project_id.user_id','=',user.id)]</field>
</record>
<record model="ir.rule" id="project_details_comp_rule">
<field name="name" >Projects According to User</field>
<field name="model_id" ref="model_project_project"/>
<field name="groups" eval="[(6, 0, [ref('group_project_manager')])]"/>
<field name="domain_force">[('user_id','=',user.id)]</field>
</record>
</data>
</openerp>
+4 -11
View File
@@ -56,24 +56,18 @@ class project_task_close(osv.osv_memory):
partner = task.partner_id or task.project_id.partner_id
if 'description' in fields:
res.update({'description': task.description})
res.update({'description': task.description or False})
if 'manager_warn' in fields:
res.update({'manager_warn': project.warn_manager})
res.update({'manager_warn': project.warn_manager or False})
if 'partner_warn' in fields:
res.update({'partner_warn': project.warn_customer})
res.update({'partner_warn': project.warn_customer or False})
if 'manager_email' in fields:
res.update({'manager_email': manager and manager.user_email or False})
if partner and len(partner.address) and 'partner_email' in fields:
res.update({'partner_email': partner.address[0].email})
return res
def done(self, cr, uid, ids, context=None):
task_pool = self.pool.get('project.task')
task_id = context.get('active_id', False)
res = task_pool.do_close(cr, uid, [task_id], context=context)
return res
def confirm(self, cr, uid, ids, context=None):
def send(self, cr, uid, ids, context=None):
if context is None:
context = {}
@@ -83,7 +77,6 @@ class project_task_close(osv.osv_memory):
return {}
task = task_pool.browse(cr, uid, task_id, context=context)
for data in self.browse(cr, uid, ids, context=context):
res = task_pool.do_close(cr, uid, [task.id], context=context)
if res:
# Send Warn Message by Email to Manager and Customer
if data.manager_warn and not data.manager_email:
@@ -3,34 +3,32 @@
<data>
<record id="view_project_task_close" model="ir.ui.view">
<field name="name">Done Task</field>
<field name="name">Send Email</field>
<field name="model">project.task.close</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Done Task" >
<separator string="Done Task and Inform to Project Manager or Customer by Email " colspan="4"/>
<form string="Send Email" >
<group colspan="4" col="4">
<field name="manager_warn" invisible="1"/>
<field name="manager_email" widget="email" attrs="{'invisible':[('manager_warn','=',False)], 'required':[('manager_warn','=',True)]}"/>
<field name="partner_warn" invisible="1"/>
<field name="partner_email" widget="email" attrs="{'invisible':[('partner_warn','=',False)], 'required':[('partner_warn','=',True)]}"/>
<separator string="Warn Message" colspan="4"/>
<separator string="Warn Message" colspan="4"/>
<field name="description" nolabel="1" colspan="4"/>
</group>
<separator string="" colspan="4"/>
<group colspan="2" col="2">
</group>
</group>
<group colspan="2" col="3">
<button icon="gtk-close" special="cancel" string="_Close"/>
<button icon="gtk-jump-to" string="_Done" special="cancel" name="done" type="object"/>
<button icon="terp-mail-message-new" string="_Send+Done" name="confirm" type="object"/>
<button icon="gtk-cancel" special="cancel" string="_Cancel"/>
<button icon="terp-mail-message-new" string="_Send" name="send" type="object"/>
</group>
</form>
</field>
</record>
<record id="action_project_task_close" model="ir.actions.act_window">
<field name="name">Done Task</field>
<field name="name">Send Email</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">project.task.close</field>
<field name="view_type">form</field>
@@ -30,7 +30,7 @@ class project_task_delegate(osv.osv_memory):
_columns = {
'name': fields.char('Delegated Title', size=64, required=True, help="New title of the task delegated to the user"),
'prefix': fields.char('Your Task Title', size=64, required=True, help="New title of your own task to validate the work done"),
'prefix': fields.char('Your Task Title', size=64, required=True, help="Title for your validation task"),
'user_id': fields.many2one('res.users', 'Assign To', required=True, help="User you want to delegate this task to"),
'new_task_description': fields.text('New Task Description', help="Reinclude the description of the task in the task of the user"),
'planned_hours': fields.float('Planned Hours', help="Estimated time to close this task by the delegated user"),
@@ -51,7 +51,7 @@ class project_task_delegate(osv.osv_memory):
project = task.project_id
manager = project.user_id or False
partner = task.partner_id or task.project_id.partner_id
if 'name' in fields:
if task.name.startswith(_('CHECK: ')):
newname = str(task.name).replace(_('CHECK: '), '')
@@ -15,17 +15,17 @@
<field name="name" colspan="4"/>
<field name="new_task_description" colspan="4" />
</group>
<group colspan="2" col="2">
<group colspan="2" col="2">
<separator string="Validation Task" colspan="4"/>
<field name="planned_hours_me" widget="float_time" colspan="4"/>
<field name="prefix" colspan="4"/>
<field name="prefix" string="Validatation Task Title" colspan="4"/>
<field name="state" colspan="4"/>
</group>
<separator string="" colspan="4"/>
<group colspan="2" col="2">
</group>
</group>
<group colspan="2" col="2">
<button icon="gtk-close" special="cancel" string="_Close"/>
<button icon="gtk-close" special="cancel" string="_Cancel"/>
<button icon="gtk-ok" name="delegate" string="_Delegate" type="object"/>
</group>
</form>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_project_task_reevaluate" model="ir.ui.view">
<field name="name">Re-evaluate Task</field>
<field name="model">project.task.reevaluate</field>
@@ -14,7 +14,7 @@
<group col="2" colspan="2">
</group>
<group col="2" colspan="2">
<button icon="gtk-close" special="cancel" string="_Close"/>
<button icon="gtk-close" special="cancel" string="_Cancel"/>
<button icon="gtk-apply" name="compute_hours" string="_Evaluate" type="object" default_focus="1"/>
</group>
</form>
+1 -1
View File
@@ -114,7 +114,7 @@ class project_task(osv.osv):
if res['type'] == 'search':
tt = timebox_obj.browse(cr, uid, timebox_obj.search(cr,uid,[]))
search_extended ='''<newline/><group col="%d" expand="0" string="%s" groups="project_gtd.group_project_getting">''' % (len(tt)+7,_('Getting Things Done'))
search_extended += '''<filter domain="[('timebox_id','=', False)]" context="{'set_editable':True,'set_visible':True,'gtd_visible':True}" icon="gtk-new" string="%s"/>''' % (_('Inbox'),)
search_extended += '''<filter domain="[('timebox_id','=', False)]" context="{'set_editable':True,'set_visible':True,'gtd_visible':True}" icon="gtk-new" help="Undefined Timebox" string="%s"/>''' % (_('Inbox'),)
search_extended += '''<separator orientation="vertical"/>'''
for time in tt:
if time.icon:
+2 -2
View File
@@ -19,7 +19,7 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Context">
<field name="name"/>
<field name="name" select="1"/>
<field name="sequence"/>
</form>
</field>
@@ -53,7 +53,7 @@
<field name="arch" type="xml">
<form string="Timeboxes">
<separator string="Timebox Definition" colspan="4"/>
<field name="name"/>
<field name="name" select="1"/>
<field name="sequence"/>
<field name="icon"/>
</form>
+3 -3
View File
@@ -70,7 +70,7 @@ class project_issue(crm.crm_case, osv.osv):
message = _('Issue ') + " '" + name + "' "+ _("is Closed.")
self.log(cr, uid, id, message)
return res
def _compute_day(self, cr, uid, ids, fields, args, context=None):
if context is None:
context = {}
@@ -152,7 +152,7 @@ class project_issue(crm.crm_case, osv.osv):
domain="[('partner_id','=',partner_id)]"),
'company_id': fields.many2one('res.company', 'Company'),
'description': fields.text('Description'),
'state': fields.selection([('draft', 'Draft'), ('open', 'Todo'), ('cancel', 'Cancelled'), ('done', 'Closed'),('pending', 'Pending'), ], 'State', size=16, readonly=True,
'state': fields.selection([('draft', 'Draft'), ('open', 'To Do'), ('cancel', 'Cancelled'), ('done', 'Closed'),('pending', 'Pending'), ], 'State', size=16, readonly=True,
help='The state is set to \'Draft\', when a case is created.\
\nIf the case is in progress the state is set to \'Open\'.\
\nWhen the case is over, the state is set to \'Done\'.\
@@ -409,7 +409,7 @@ class project(osv.osv):
'project_escalation_id' : fields.many2one('project.project','Project Escalation', help='If any issue is escalated from the current Project, it will be listed under the project selected here.', states={'close':[('readonly',True)], 'cancelled':[('readonly',True)]}),
'reply_to' : fields.char('Reply-To Email Address', size=256)
}
def _check_escalation(self, cr, uid, ids):
project_obj = self.browse(cr, uid, ids[0])
if project_obj.project_escalation_id:
@@ -22,19 +22,16 @@
<record model="crm.case.resource.type" id="type1">
<field name="name">Version 4.2</field>
<field name="section_id" ref="crm.section_sales_department"/>
<field name="object_id" search="[('model','=','project.issue')]" model="ir.model"/>
</record>
<record model="crm.case.resource.type" id="type2">
<field name="name">Version 5.0</field>
<field name="section_id" ref="crm.section_sales_department"/>
<field name="object_id" search="[('model','=','project.issue')]" model="ir.model"/>
</record>
<record model="crm.case.resource.type" id="type3">
<field name="name">Version 6.0</field>
<field name="section_id" ref="crm.section_sales_department"/>
<field name="object_id" search="[('model','=','project.issue')]" model="ir.model"/>
</record>
<!-- Case Stage -->
+3 -3
View File
@@ -12,10 +12,10 @@
<field name="view_type">form</field>
<field name="view_mode">tree,calendar</field>
<field name="view_id" ref="project_issue_tree_view"/>
<field name="domain" eval="[('categ_id','=',ref('bug_categ'))]"/>
<field name="domain" eval=""/>
<field name="context">{"search_default_user_id": uid, "search_default_current":1, "search_default_project_id":project_id}</field>
<field name="search_view_id" ref="view_project_issue_filter"/>
<field name="help">Issues like bugs in a system, client complain, materials breakdown are collected here.A list view allows the manager to quickly check for them, assign them, make their status evolved.</field>
<field name="help">Issues like bugs in a system, client complain, materials breakdown are collected here. A list view allows the manager to quickly check for them, assign them, make their status evolved.</field>
</record>
<record model="ir.actions.act_window.view" id="action_crm_tag_tree_view0">
@@ -40,7 +40,7 @@
</record>
<act_window
domain="[('project_id', '=', active_id)]"
context="{'search_default_project_id': [active_id]}"
id="act_project_project_2_project_issue_all"
name="Issues"
res_model="project.issue"
+29 -22
View File
@@ -66,7 +66,7 @@
<group col="8" colspan="4">
<field name="state" />
<button name="case_open" string="Open" states="draft,pending" type="object" icon="gtk-go-forward"/>
<button name="case_close" string="Close" states="open,draft,pending" type="object" icon="gtk-jump-to"/>
<button name="case_close" string="Close" states="open,draft,pending" type="object" icon="terp-dialog-close"/>
<button name="case_pending" string="Pending" states="draft,open" type="object" icon="gtk-media-pause"/>
<button name="case_cancel" string="Cancel" states="draft,open,pending" type="object" icon="gtk-cancel"/>
<button name="case_escalate" string="Escalate" states="open,draft,pending" type="object" icon="gtk-go-up"/>
@@ -75,10 +75,10 @@
</page>
<page string="Emails" groups="base.group_extended">
<group colspan="4">
<field colspan="4" name="email_cc" string="Global CC" widget="char"/>
<field colspan="4" name="email_cc" string="Global CC" widget="url"/>
</group>
<field name="message_ids" colspan="4" nolabel="1" mode="tree,form">
<tree string="Communication history">
<tree string="History">
<field name="display_text" string="History Information"/>
<field name="history" invisible="1"/>
<button
@@ -87,7 +87,7 @@
context="{'mail':'reply', 'model': 'project.issue', 'include_original' : True}"
icon="terp-mail-replied" type="action" />
</tree>
<form string="Communication history">
<form string="History">
<group col="4" colspan="4">
<field name="email_from"/>
<field name="date"/>
@@ -117,7 +117,7 @@
</form>
</field>
<separator colspan="4"/>
<button string="Add New Note"
<button string="Add Internal Note"
name="%(crm.action_crm_add_note)d"
context="{'model': 'crm.lead' }"
icon="terp-document-new" type="action" />
@@ -157,13 +157,13 @@
<field name="model">project.issue</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Issue Tracker Tree" colors="red:state=='open';blue:state=='pending';grey:state in ('cancel', 'done')">
<tree string="Issue Tracker Tree" colors="black:state=='open';blue:state=='pending';grey:state in ('cancel', 'done')">
<field name="id"/>
<field name="create_date"/>
<field name="name"/>
<field name="partner_id"/>
<field name="project_id" />
<field name="priority" string="Severity"/>
<field name="priority" string="Priority"/>
<field name="stage_id" string="Resolution"/>
<button icon="gtk-go-back" string="" name="stage_previous" type="object"
states="open,draft,pending,done,cancel" />
@@ -174,11 +174,12 @@
<field name="assigned_to"/>
<field name="state"/>
<button name="case_close" string="Done" states="open,draft,pending" type="object" icon="gtk-jump-to"/>
<button name="case_open" string="Open" states="draft,pending" type="object" icon="gtk-go-forward"/>
<button name="case_open" string="Open" states="draft,pending" type="object" icon="gtk-go-forward" help="To Do"/>
<button name="case_cancel" string="Cancel" states="draft,open,pending" type="object" icon="gtk-cancel"/>
<button name="case_pending" string="Pending" states="draft,open" type="object" icon="gtk-media-pause"/>
<button name="case_escalate" string="Escalate" states="open,draft,pending" type="object" icon="gtk-go-up"/>
<button name="case_reset" string="Reset to Draft" states="done,cancel" type="object" icon="gtk-convert"/>
<field name="categ_id" invisible="1"/>
</tree>
</field>
</record>
@@ -190,8 +191,8 @@
<field name="arch" type="xml">
<search string="Issue Tracker Search">
<group>
<filter string="Current" name="current" domain="[('state','in',('open','draft'))]" help="Draft and Open Issues" icon="terp-check" default="1"/>
<filter string="In Progress" domain="[('state','=','open')]" help="Open Issues" icon="terp-camera_test"/>
<filter string="Current" name="current" domain="[('state','in',('open','draft'))]" help="Draft and To Do" icon="terp-check" default="1"/>
<filter string="To Do" domain="[('state','=','open')]" help="To Do Issues" icon="terp-camera_test"/>
<filter string="Pending" domain="[('state','=','pending')]" help="Pending Issues" icon="terp-gtk-media-pause"/>
<separator orientation="vertical"/>
<filter icon="terp-go-today" string=" Today " separator="1" domain="[('date','=',time.strftime('%%Y-%%m-%%d'))]" help="Today's bugs" />
@@ -204,25 +205,31 @@
<field name="user_id"/>
<field name="project_id" string="Project"/>
<field name="state"/>
<field name="categ_id"/>
</group>
<newline/>
<group expand="0" string="Group By..." groups="base.group_extended">
<filter string="Responsible" icon="terp-personal"
domain="[]" context="{'group_by':'user_id'}" />
<filter string="Partner" icon="terp-partner" domain="[]"
context="{'group_by':'partner_id'}" />
<separator orientation="vertical"/>
<filter string="Project" icon="terp-folder-blue" domain="[]"
context="{'group_by':'project_id'}" />
<filter string="Stage" icon="terp-stage" domain="[]"
context="{'group_by':'stage_id'}" />
<filter string="Priority" icon="terp-rating-rated" domain="[]"
context="{'group_by':'priority'}" />
<filter string="Version" icon="terp-gtk-jump-to-rtl"
domain="[]" context="{'group_by':'type_id'}" />
<separator orientation="vertical" />
<filter string="Partner" icon="terp-personal" domain="[]"
context="{'group_by':'partner_id'}" />
<filter string="Salesman" icon="terp-personal"
domain="[]" context="{'group_by':'user_id'}" />
<separator orientation="vertical"/>
<filter string="Category" icon="terp-stock_symbol-selection" domain="[]"
context="{'group_by':'categ_id'}" />
<filter string="Priority" icon="terp-rating-rated" domain="[]"
context="{'group_by':'priority'}" />
<filter string="Stage" icon="terp-stage" domain="[]"
context="{'group_by':'stage_id'}" />
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]"
context="{'group_by':'state'}" />
<separator orientation="vertical" />
<filter string="Month" icon="terp-go-month"
domain="[]" context="{'group_by':'create_date'}" />
domain="[]" context="{'group_by':'create_date'}" help="Creation Month"/>
</group>
</search>
</field>
@@ -254,7 +261,7 @@
<field name="id"/>
<field name="name" string="Feature description"/>
<field name="partner_id"/>
<field name="priority" string="Severity"/>
<field name="priority" string="Priority"/>
<field name="stage_id" string="Resolution"/>
<button icon="gtk-go-back" string="" name="stage_previous" type="object"
states="open,draft,pending,done,cancel" />
@@ -316,6 +323,6 @@
</field>
</field>
</record>
</data>
</openerp>
@@ -87,7 +87,7 @@ class project_issue_report(osv.osv):
'company_id' : fields.many2one('res.company', 'Company'),
'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'),
'project_id':fields.many2one('project.project', 'Project',readonly=True),
'type_id': fields.many2one('crm.case.resource.type', 'Version', domain="[('object_id.model', '=', 'project.issue')]"),
'type_id': fields.many2one('crm.case.resource.type', 'Version'),
'assigned_to' : fields.many2one('res.users', 'Assigned to',readonly=True),
'partner_id': fields.many2one('res.partner','Partner',domain="[('object_id.model', '=', 'project.issue')]"),
'canal_id': fields.many2one('res.partner.canal', 'Channel',readonly=True),
@@ -54,14 +54,16 @@
<field name="arch" type="xml">
<search string="Search">
<group col="16" colspan="8">
<filter string="365 Days" icon="terp-go-year"
domain="[('create_date','&lt;=', time.strftime('%%Y-%%m-%%d')), ('create_date','&gt;',(datetime.date.today()-datetime.timedelta(days=365)).strftime('%%Y-%%m-%%d'))]"/>
<filter string="Year" icon="terp-go-year" help="Current Year"
domain="[('create_date','&lt;=', time.strftime('%%Y-%%m-%%d')),('create_date','&gt;=',time.strftime('%%Y-01-01'))]"
/>
<filter string="30 Days" icon="terp-go-month" name="This Month"
domain="[('create_date','&lt;=', time.strftime('%%Y-%%m-%%d')), ('create_date','&gt;',(datetime.date.today()-datetime.timedelta(days=30)).strftime('%%Y-%%m-%%d'))]"/>
<filter icon="terp-go-week" string="7 Days" separator="1"
domain="[('create_date','&lt;=', time.strftime('%%Y-%%m-%%d')), ('create_date','&gt;',(datetime.date.today()-datetime.timedelta(days=7)).strftime('%%Y-%%m-%%d'))]"/>
<filter string="Month" icon="terp-go-month" name="This Month"
domain="[('create_date','&lt;=', time.strftime('%%Y-%%m-%%d')),('create_date','&gt;=',time.strftime('%%Y-%%m-01'))]"
/>
<filter icon="terp-go-week" string="Month-1" separator="1" help="Previous Month"
domain="[('create_date','&lt;=', (datetime.date (int(time.strftime('%%Y')), datetime.date.today().month, 1) - datetime.timedelta (days = 1)).strftime('%%Y-%%m-%%d')),('create_date','&gt;',(datetime.date (int(time.strftime('%%Y')), datetime.date.today().month-1, 1)).strftime('%%Y-%%m-%%d'))]"
/>
<separator orientation="vertical" />
<filter icon="terp-camera_test"
@@ -76,6 +78,7 @@
<separator orientation="vertical" />
<field name="section_id"
string="Sale Team "
default="context.get('section_id', False)"
widget="selection"
context="{'invisible_section': False}">
@@ -83,7 +86,7 @@
<filter icon="terp-crm"
context="{'invisible_section': False}"
domain="[('section_id.user_id','=',uid)]"
help="My section" />
help="My Sale Team" />
</field>
<field name="project_id"/>
@@ -96,7 +99,7 @@
<separator orientation="vertical"/>
<field name="priority" />
<separator orientation="vertical"/>
<field name="type_id" widget="selection" domain="[('object_id.model', '=', 'project.issue')]"/>
<field name="type_id" widget="selection" />
<field name="categ_id" widget="selection" domain="[('object_id.model', '=', 'project.issue')]"/>
<field name="stage_id" widget="selection" domain="[('object_id.model', '=', 'project.issue')]" />
<separator orientation="vertical"/>
@@ -108,45 +111,42 @@
</group>
<newline/>
<group expand="1" string="Group By..." colspan="4" col="8">
<filter string="Project" name="project" icon="terp-folder-blue" context="{'group_by':'project_id'}" />
<filter string="Task" icon="terp-stock_align_left_24" domain="[]" context="{'group_by':'task_id'}"/>
<separator orientation="vertical" />
<filter name="User" string="Responsible" icon="terp-personal"
<filter name="User" string="Responsible" icon="terp-personal"
domain="[]" context="{'group_by':'user_id'}" />
<filter string="Assigned to" name="Responsible" icon="terp-personal"
domain="[]" context="{'group_by':'assigned_to'}" />
<filter string="Partner" icon="terp-personal" context="{'group_by':'partner_id'}" />
<separator orientation="vertical" />
<filter string="Section" icon="terp-sale"
<filter string="Partner" icon="terp-partner" context="{'group_by':'partner_id'}" />
<separator orientation="vertical" />
<filter string="Sale Team" icon="terp-personal+"
domain="[]"
context="{'group_by':'section_id'}" />
<separator orientation="vertical" />
<filter string="Project" name="project" icon="terp-folder-blue" context="{'group_by':'project_id'}" />
<filter string="Task" icon="terp-stock_align_left_24" domain="[]" context="{'group_by':'task_id'}"/>
<separator orientation="vertical" />
<filter string="Category" icon="terp-stock_symbol-selection"
domain="[]" context="{'group_by':'categ_id'}" />
<separator orientation="vertical" />
<filter string="Version" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by':'type_id'}"/>
<separator orientation="vertical" />
<filter string="Priority" icon="terp-rating-rated" domain="[]" context="{'group_by':'priority'}" />
<filter string="Stage" icon="terp-stage" domain="[]" context="{'group_by':'stage_id'}"/>
<separator orientation="vertical"/>
<filter string="Priority" icon="terp-rating-rated" domain="[]" context="{'group_by':'priority'}" />
<separator orientation="vertical" />
<filter string="State" icon="terp-stock_effects-object-colorize"
domain="[]" context="{'group_by':'state'}" />
<separator orientation="vertical"/>
<filter string="Company" icon="terp-go-home"
domain="[]"
context="{'group_by':'company_id'}" />
<separator orientation="vertical" />
<filter string="Day" icon="terp-go-today"
domain="[]" context="{'group_by':'day'}"/>
domain="[]" context="{'group_by':'day'}" help="Current Day"/>
<filter string="Month" icon="terp-go-month"
domain="[]" context="{'group_by':'month'}" />
domain="[]" context="{'group_by':'month'}" help="Current Month"/>
<filter string="Year" icon="terp-go-year"
domain="[]" context="{'group_by':'name'}" />
domain="[]" context="{'group_by':'name'}" help="Current Year"/>
</group>
</search>
</field>
</record>
+303 -15
View File
@@ -21,9 +21,10 @@
import time
from datetime import date, datetime, timedelta
from tools.translate import _
from osv import fields, osv
from resource.faces import task as Task
import operator
class project_phase(osv.osv):
_name = "project.phase"
@@ -181,38 +182,55 @@ class project_phase(osv.osv):
uom_obj = self.pool.get('product.uom')
if context is None:
context = {}
res = super(project_phase, self).write(cr, uid, ids, vals, context=context)
if context.get('scheduler',False):
return super(project_phase, self).write(cr, uid, ids, vals, context=context)
return res
# Consider calendar and efficiency if the phase is performed by a resource
# otherwise consider the project's working calendar
#TOCHECK : why need this ?
if isinstance(ids, (int, long)):
ids = [ids]
phase = self.browse(cr, uid, ids[0], context=context)
calendar_id = phase.project_id.resource_calendar_id and phase.project_id.resource_calendar_id.id or False
resource_id = resource_obj.search(cr, uid, [('user_id', '=', phase.responsible_id.id)],context=context)
if resource_id:
default_uom_id = self._get_default_uom_id(cr, uid)
for phase in self.browse(cr, uid, ids, context=context):
calendar_id = phase.project_id.resource_calendar_id and phase.project_id.resource_calendar_id.id or False
resource_id = resource_obj.search(cr, uid, [('user_id', '=', phase.responsible_id.id)],context=context)
if resource_id:
cal_id = resource_obj.browse(cr, uid, resource_id[0], context=context).calendar_id.id
if cal_id:
calendar_id = cal_id
default_uom_id = self._get_default_uom_id(cr, uid)
avg_hours = uom_obj._compute_qty(cr, uid, phase.product_uom.id, phase.duration, default_uom_id)
# Change the date_start and date_end
# for previous and next phases respectively based on valid condition
if vals.get('date_start', False) and vals['date_start'] < phase.date_start:
avg_hours = uom_obj._compute_qty(cr, uid, phase.product_uom.id, phase.duration, default_uom_id)
# Change the date_start and date_end
# for previous and next phases respectively based on valid condition
if vals.get('date_start', False) and vals['date_start'] < phase.date_start:
dt_start = datetime.strptime(vals['date_start'], '%Y-%m-%d')
work_times = resource_calendar_obj.interval_get(cr, uid, calendar_id, dt_start, avg_hours or 0.0, resource_id and resource_id[0] or False)
if work_times:
vals['date_end'] = work_times[-1][1].strftime('%Y-%m-%d')
for prv_phase in phase.previous_phase_ids:
if prv_phase.id == phase.id:
continue
self._check_date_start(cr, uid, prv_phase, dt_start, context=context)
if vals.get('date_end', False) and vals['date_end'] > phase.date_end:
if vals.get('date_end', False) and vals['date_end'] > phase.date_end:
dt_end = datetime.strptime(vals['date_end'], '%Y-%m-%d')
work_times = resource_calendar_obj.interval_min_get(cr, uid, calendar_id, dt_end, avg_hours or 0.0, resource_id and resource_id[0] or False)
if work_times:
vals['date_start'] = work_times[0][0].strftime('%Y-%m-%d')
for next_phase in phase.next_phase_ids:
if next_phase.id == phase.id:
continue
self._check_date_end(cr, uid, next_phase, dt_end, context=context)
return super(project_phase, self).write(cr, uid, ids, vals, context=context)
return res
def copy(self, cr, uid, id, default=None, context=None):
if default is None:
default = {}
if not default.get('name', False):
default['name'] = self.browse(cr, uid, id, context=context).name + _(' (copy)')
return super(project_phase, self).copy(cr, uid, id, default, context)
def set_draft(self, cr, uid, ids, *args):
self.write(cr, uid, ids, {'state': 'draft'})
@@ -234,6 +252,118 @@ class project_phase(osv.osv):
self.write(cr, uid, ids, {'state': 'done'})
return True
def generate_resources(self, cr, uid, ids, context=None):
"""
Return a list of Resource Class objects for the resources allocated to the phase.
"""
res = {}
if context is None:
context = {}
resource_pool = self.pool.get('resource.resource')
for phase in self.browse(cr, uid, ids, context=context):
user_ids = map(lambda x:x.resource_id.user_id.id, phase.resource_ids)
project = phase.project_id
calendar_id = project.resource_calendar_id and project.resource_calendar_id.id or False
resource_objs = resource_pool.generate_resources(cr, uid, user_ids, calendar_id, context=context)
res[phase.id] = resource_objs
return res
def generate_schedule(self, cr, uid, ids, start_date, calendar_id=False, context=None):
"""
Schedule phase with the start date till all the next phases are completed.
@param: start_dsate : start date for the phase
@param: calendar_id : working calendar of the project
"""
if context is None:
context = {}
resource_pool = self.pool.get('resource.resource')
uom_pool = self.pool.get('product.uom')
phase_resource = False
if context is None:
context = {}
default_uom_id = self._get_default_uom_id(cr, uid)
for phase in self.browse(cr, uid, ids, context=context):
if not phase.responsible_id:
raise osv.except_osv(_('No responsible person assigned !'),_("You must assign a responsible person for phase '%s' !") % (phase.name,))
phase_resource_obj = resource_pool.generate_resources(cr, uid, [phase.responsible_id.id], calendar_id, context=context)
avg_hours = uom_pool._compute_qty(cr, uid, phase.product_uom.id, phase.duration, default_uom_id)
duration = str(avg_hours) + 'H'
# Create a new project for each phase
def Project():
start = start_date
minimum_time_unit = 1
resource = phase_resource_obj
# If project has working calendar then that
# else the default one would be considered
if calendar_id:
working_days = resource_pool.compute_working_calendar(cr, uid, calendar_id, context=context)
vacation = tuple(resource_pool.compute_vacation(cr, uid, calendar_id))
def phase():
effort = duration
project = Task.BalancedProject(Project)
s_date = project.phase.start.to_datetime()
e_date = project.phase.end.to_datetime()
# Recalculate date_start and date_end
# according to constraints on date start and date end on phase
if phase.constraint_date_start and str(s_date) < phase.constraint_date_start:
start_date = datetime.strptime(phase.constraint_date_start, '%Y-%m-%d')
else:
start_date = s_date
if phase.constraint_date_end and str(e_date) > phase.constraint_date_end:
end_date= datetime.strptime(phase.constraint_date_end, '%Y-%m-%d')
date_start = phase.constraint_date_end
else:
end_date = e_date
date_start = end_date
# Write the calculated dates back
ctx = context.copy()
ctx.update({'scheduler': True})
self.write(cr, uid, [phase.id], {
'date_start': start_date.strftime('%Y-%m-%d'),
'date_end': end_date.strftime('%Y-%m-%d')
}, context=ctx)
# Recursive call till all the next phases scheduled
for phase in phase.next_phase_ids:
if phase.state in ['draft', 'open', 'pending']:
id_cal = phase.project_id.resource_calendar_id and phase.project_id.resource_calendar_id.id or False
self.generate_schedule(cr, uid, [phase.id], date_start, id_cal, context=context)
else:
continue
return True
def schedule_tasks(self, cr, uid, ids, context=None):
"""
Schedule the tasks according to resource available and priority.
"""
task_pool = self.pool.get('project.task')
resource_pool = self.pool.get('resource.resource')
if context is None:
context = {}
resources_list = self.generate_resources(cr, uid, ids, context=context)
return_msg = {}
for phase in self.browse(cr, uid, ids, context=context):
start_date = phase.date_start
if not start_date and phase.project_id.date_start:
start_date = phase.project_id.date_start
if not start_date:
start_date = datetime.now().strftime("%Y-%m-%d")
resources = resources_list.get(phase.id, [])
calendar_id = phase.project_id.resource_calendar_id.id
task_ids = map(lambda x : x.id, (filter(lambda x : x.state in ['open', 'draft', 'pending'] , phase.task_ids)))
if task_ids:
task_pool.generate_schedule(cr, uid, task_ids, resources, calendar_id, start_date, context=context)
if not task_ids:
warning_msg = _("No tasks to compute for Phase '%s'.") % (phase.name)
if "warning" not in return_msg:
return_msg["warning"] = warning_msg
else:
return_msg["warning"] = return_msg["warning"] + "\n" + warning_msg
return return_msg
project_phase()
class project_resource_allocation(osv.osv):
@@ -259,14 +389,172 @@ class project(osv.osv):
'phase_ids': fields.one2many('project.phase', 'project_id', "Project Phases"),
'resource_calendar_id': fields.many2one('resource.calendar', 'Working Time', help="Timetable working hours to adjust the gantt diagram report", states={'close':[('readonly',True)]} ),
}
def generate_members(self, cr, uid, ids, context=None):
"""
Return a list of Resource Class objects for the resources allocated to the phase.
"""
res = {}
resource_pool = self.pool.get('resource.resource')
if context is None:
context = {}
for project in self.browse(cr, uid, ids, context=context):
user_ids = map(lambda x:x.id, project.members)
calendar_id = project.resource_calendar_id and project.resource_calendar_id.id or False
resource_objs = resource_pool.generate_resources(cr, uid, user_ids, calendar_id, context=context)
res[project.id] = resource_objs
return res
def schedule_phases(self, cr, uid, ids, context=None):
"""
Schedule the phases.
"""
if context is None:
context = {}
if type(ids) in (long, int,):
ids = [ids]
phase_pool = self.pool.get('project.phase')
for project in self.browse(cr, uid, ids, context=context):
phase_ids = phase_pool.search(cr, uid, [('project_id', '=', project.id),
('state', 'in', ['draft', 'open', 'pending']),
('previous_phase_ids', '=', False)
])
start_date = project.date_start
if not start_date:
start_date = datetime.now().strftime("%Y-%m-%d")
start_dt = datetime.strftime((datetime.strptime(start_date, "%Y-%m-%d")), "%Y-%m-%d %H:%M")
calendar_id = project.resource_calendar_id and project.resource_calendar_id.id or False
phase_pool.generate_schedule(cr, uid, phase_ids, start_dt, calendar_id, context=context)
return True
def schedule_tasks(self, cr, uid, ids, context=None):
"""
Schedule the tasks according to resource available and priority.
"""
if type(ids) in (long, int,):
ids = [ids]
user_pool = self.pool.get('res.users')
task_pool = self.pool.get('project.task')
resource_pool = self.pool.get('resource.resource')
if context is None:
context = {}
resources_list = self.generate_members(cr, uid, ids, context=context)
return_msg = {}
for project in self.browse(cr, uid, ids, context=context):
start_date = project.date_start
if not start_date:
start_date = datetime.now().strftime("%Y-%m-%d")
resources = resources_list.get(project.id, [])
calendar_id = project.resource_calendar_id.id
task_ids = task_pool.search(cr, uid, [('project_id', '=', project.id),
('state', 'in', ['draft', 'open', 'pending'])
])
if task_ids:
task_pool.generate_schedule(cr, uid, task_ids, resources, calendar_id, start_date, context=context)
else:
warning_msg = _("No tasks to compute for Project '%s'.") % (project.name)
if "warning" not in return_msg:
return_msg["warning"] = warning_msg
else:
return_msg["warning"] = return_msg["warning"] + "\n" + warning_msg
return return_msg
project()
class task(osv.osv):
class resource_resource(osv.osv):
_inherit = "resource.resource"
def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False):
if context is None:
context = {}
if context.get('project_id',False):
project_pool = self.pool.get('project.project')
project_rec = project_pool.browse(cr, uid, context['project_id'])
user_ids = [user_id.id for user_id in project_rec.members]
args.append(('user_id','in',user_ids))
return super(resource_resource, self).search(cr, uid, args, offset, limit, order, context, count)
resource_resource()
class project_task(osv.osv):
_inherit = "project.task"
_columns = {
'phase_id': fields.many2one('project.phase', 'Project Phase'),
}
def generate_schedule(self, cr, uid, ids, resources, calendar_id, start_date, context=None):
"""
Schedule the tasks according to resource available and priority.
"""
if not ids:
return False
if context is None:
context = {}
user_pool = self.pool.get('res.users')
project_pool = self.pool.get('project.project')
priority_dict = {'0': 1000, '1': 800, '2': 500, '3': 300, '4': 100}
# Create dynamic no of tasks with the resource specified
def create_tasks(task_number, eff, priorty=500, obj=False):
def task():
"""
task is a dynamic method!
"""
effort = eff
if obj:
resource = obj
priority = priorty
task.__doc__ = "TaskNO%d" %task_number
task.__name__ = "task%d" %task_number
return task
task()
# Create a 'Faces' project with all the tasks and resources
def Project():
title = "Project"
start = datetime.strftime(datetime.strptime(start_date, "%Y-%m-%d"), "%Y-%m-%d %H:%M")
try:
resource = reduce(operator.or_, resources)
except:
raise osv.except_osv(_('Error'), _('Should have Resources Allocation or Project Members!'))
minimum_time_unit = 1
if calendar_id: # If project has working calendar
working_days = resource_pool.compute_working_calendar(cr, uid, calendar_id, context=context)
vacation = tuple(resource_pool.compute_vacation(cr, uid, calendar_id, context=context))
# Dynamic creation of tasks
task_number = 0
for openobect_task in self.browse(cr, uid, ids, context=context):
hours = str(openobect_task.planned_hours )+ 'H'
if openobect_task.priority in priority_dict.keys():
priorty = priority_dict[openobect_task.priority]
real_resource = False
if openobect_task.user_id:
for task_resource in resources:
if task_resource.__name__ == task_resource:
real_resource = task_resource
break
task = create_tasks(task_number, hours, priorty, real_resource)
task_number += 1
face_projects = Task.BalancedProject(Project)
loop_no = 0
# Write back the computed dates
for face_project in face_projects:
s_date = face_project.start.to_datetime()
e_date = face_project.end.to_datetime()
if loop_no > 0:
ctx = context.copy()
ctx.update({'scheduler': True})
user_id = user_pool.search(cr, uid, [('name', '=', face_project.booked_resource[0].__name__)])
self.write(cr, uid, [ids[loop_no-1]], {
'date_start': s_date.strftime('%Y-%m-%d %H:%M:%S'),
'date_end': e_date.strftime('%Y-%m-%d %H:%M:%S'),
'user_id': user_id[0]
}, context=ctx)
loop_no += 1
return True
project_task()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -1,741 +1,393 @@
<?xml version="1.0" ?>
<openerp>
<data noupdate="1">
<!-- Users -->
<record id="res_users_demouser1" model="res.users">
<field model="ir.actions.actions" name="menu_id" search="[('name', '=', u'Menu')]"/>
<field name="address_id" ref="base.main_address"/>
<field name="context_lang">en_US</field>
<field name="name">Demo User1</field>
<field eval="[(6, 0, [ref('base.group_user')])]" name="groups_id"/>
<field name="signature">Mr Demo</field>
<field name="company_id" ref="base.main_company"/>
<field eval="[(6, 0, [])]" name="roles_id"/>
<field eval="[(6, 0, [])]" name="rules_id"/>
<field eval="1" name="active"/>
<field model="ir.actions.actions" name="action_id" search="[('name', '=', u'Setup')]"/>
<field name="login">demo1</field>
<field name="password">demo1</field>
<field eval="[(6, 0, [])]" name="company_ids"/>
</record>
<record id="res_users_manager0" model="res.users">
<field model="ir.actions.actions" name="menu_id" search="[('name', '=', u'Menu')]"/>
<field name="context_lang">en_US</field>
<field name="name">Manager1</field>
<!--
This Demo data file includes Users, Human Resources, Projects and it' members list, Phases and Resources,Tasks allocation and also run scheduling of phase and tasks.
-->
<!-- Users -->
<record id="res_users_analyst" model="res.users">
<field name="name">Phoung</field>
<field eval="[(6, 0, [ref('base.group_user'), ref('project.group_project_manager')])]" name="groups_id"/>
<field name="company_id" ref="base.main_company"/>
<field eval="[(6, 0, [])]" name="roles_id"/>
<field eval="[(6, 0, [])]" name="rules_id"/>
<field eval="1" name="active"/>
<field model="ir.actions.actions" name="action_id" search="[('name', '=', u'Menu')]"/>
<field name="login">manager1</field>
<field name="password">manager1</field>
<field eval="[(6, 0, [])]" name="company_ids"/>
<field name="login">phu</field>
<field name="password">phu</field>
</record>
<record id="res_users_manager1" model="res.users">
<field model="ir.actions.actions" name="menu_id" search="[('name', '=', u'Menu')]"/>
<field name="context_lang">en_US</field>
<field name="name">Manager2</field>
<record id="res_users_project_manager" model="res.users">
<field name="name">Anthony</field>
<field eval="[(6, 0, [ref('base.group_user'), ref('project.group_project_manager')])]" name="groups_id"/>
<field name="company_id" ref="base.main_company"/>
<field eval="[(6, 0, [])]" name="roles_id"/>
<field eval="[(6, 0, [])]" name="rules_id"/>
<field eval="1" name="active"/>
<field model="ir.actions.actions" name="action_id" search="[('name', '=', u'Menu')]"/>
<field name="login">manager2</field>
<field name="password">manager2</field>
<field eval="[(6, 0, [])]" name="company_ids"/>
<field name="login">al</field>
<field name="password">al</field>
</record>
<record id="res_users_user0" model="res.users">
<field model="ir.actions.actions" name="menu_id" search="[('name', '=', u'Menu')]"/>
<field name="context_lang">en_US</field>
<field name="name">user1</field>
<record id="res_users_technical_leader" model="res.users">
<field name="name">Qwintin</field>
<field eval="[(6, 0, [ref('base.group_user'), ref('project.group_project_user')])]" name="groups_id"/>
<field name="company_id" ref="base.main_company"/>
<field eval="[(6, 0, [])]" name="roles_id"/>
<field eval="[(6, 0, [])]" name="rules_id"/>
<field eval="1" name="active"/>
<field model="ir.actions.actions" name="action_id" search="[('name', '=', u'Menu')]"/>
<field name="login">user1</field>
<field name="password">USER1</field>
<field eval="[(6, 0, [])]" name="company_ids"/>
<field name="login">qdp</field>
<field name="password">qdp</field>
</record>
<record id="res_users_user1" model="res.users">
<field model="ir.actions.actions" name="menu_id" search="[('name', '=', u'Menu')]"/>
<field name="context_lang">en_US</field>
<field name="name">user2</field>
<record id="res_users_developer" model="res.users">
<field name="name">Francois</field>
<field eval="[(6, 0, [ref('base.group_user'), ref('project.group_project_user')])]" name="groups_id"/>
<field name="company_id" ref="base.main_company"/>
<field eval="[(6, 0, [])]" name="roles_id"/>
<field eval="[(6, 0, [])]" name="rules_id"/>
<field eval="1" name="active"/>
<field model="ir.actions.actions" name="action_id" search="[('name', '=', u'Menu')]"/>
<field name="login">user2</field>
<field name="password">user2</field>
<field eval="[(6, 0, [])]" name="company_ids"/>
<field name="login">fpi</field>
<field name="password">fpi</field>
</record>
<record id="res_users_userfinance0" model="res.users">
<field model="ir.actions.actions" name="menu_id" search="[('name', '=', u'Menu')]"/>
<field name="context_lang">en_US</field>
<field name="name">user_finance</field>
<record id="res_users_designer" model="res.users">
<field name="name">Julien</field>
<field eval="[(6, 0, [ref('base.group_user'), ref('project.group_project_user')])]" name="groups_id"/>
<field name="login">jth</field>
<field name="password">jth</field>
</record>
<record id="res_users_tester" model="res.users">
<field name="name">Alien</field>
<field eval="[(6, 0, [ref('base.group_user'), ref('project.group_project_user')])]" name="groups_id"/>
<field name="login">apr</field>
<field name="password">apr</field>
</record>
<record id="res_users_finacial_manager" model="res.users">
<field name="name">Fabian</field>
<field eval="[(6, 0, [ref('base.group_user'), ref('project.group_project_finance')])]" name="groups_id"/>
<field name="company_id" ref="base.main_company"/>
<field eval="[(6, 0, [])]" name="roles_id"/>
<field eval="[(6, 0, [])]" name="rules_id"/>
<field eval="1" name="active"/>
<field model="ir.actions.actions" name="action_id" search="[('name', '=', u'Menu')]"/>
<field name="login">user_finance</field>
<field name="password">user_finance</field>
<field eval="[(6, 0, [])]" name="company_ids"/>
<field name="login">fbs</field>
<field name="password">fbs</field>
</record>
<record id="res_users_userdesign0" model="res.users">
<field model="ir.actions.actions" name="menu_id" search="[('name', '=', u'Menu')]"/>
<field name="context_lang">en_US</field>
<field name="name">user_design1</field>
<field eval="[(6, 0, [ref('base.group_user')])]" name="groups_id"/>
<field name="company_id" ref="base.main_company"/>
<field eval="[(6, 0, [])]" name="roles_id"/>
<field eval="[(6, 0, [])]" name="rules_id"/>
<field eval="1" name="active"/>
<field model="ir.actions.actions" name="action_id" search="[('name', '=', u'Menu')]"/>
<field name="login">user_design1</field>
<field name="password">user_design1</field>
<field eval="[(6, 0, [])]" name="company_ids"/>
</record>
<record id="res_users_userdesign1" model="res.users">
<field model="ir.actions.actions" name="menu_id" search="[('name', '=', u'Menu')]"/>
<field name="context_lang">en_US</field>
<field name="name">user_design2</field>
<field eval="[(6, 0, [ref('base.group_user')])]" name="groups_id"/>
<field name="company_id" ref="base.main_company"/>
<field eval="[(6, 0, [])]" name="roles_id"/>
<field eval="[(6, 0, [])]" name="rules_id"/>
<field eval="1" name="active"/>
<field model="ir.actions.actions" name="action_id" search="[('name', '=', u'Menu')]"/>
<field name="login">user_design2</field>
<field name="password">user_design2</field>
<field eval="[(6, 0, [])]" name="company_ids"/>
</record>
<record id="res_users_userdeveloper0" model="res.users">
<field model="ir.actions.actions" name="menu_id" search="[('name', '=', u'Menu')]"/>
<field name="context_lang">en_US</field>
<field name="name">user_developer1</field>
<field eval="[(6, 0, [ref('base.group_user')])]" name="groups_id"/>
<field name="company_id" ref="base.main_company"/>
<field eval="[(6, 0, [])]" name="roles_id"/>
<field eval="[(6, 0, [])]" name="rules_id"/>
<field eval="1" name="active"/>
<field model="ir.actions.actions" name="action_id" search="[('name', '=', u'Menu')]"/>
<field name="login">user_developer1</field>
<field name="password">user_developer1</field>
<field eval="[(6, 0, [])]" name="company_ids"/>
</record>
<record id="res_users_userdeveloper1" model="res.users">
<field model="ir.actions.actions" name="menu_id" search="[('name', '=', u'Menu')]"/>
<field name="context_lang">en_US</field>
<field name="name">user_developer2</field>
<field eval="[(6, 0, [ref('base.group_user')])]" name="groups_id"/>
<field name="company_id" ref="base.main_company"/>
<field eval="[(6, 0, [])]" name="roles_id"/>
<field eval="[(6, 0, [])]" name="rules_id"/>
<field eval="1" name="active"/>
<field model="ir.actions.actions" name="action_id" search="[('name', '=', u'Menu')]"/>
<field name="login">user_developer2</field>
<field name="password">user_developer1</field>
<field eval="[(6, 0, [])]" name="company_ids"/>
</record>
<record id="res_users_usertester0" model="res.users">
<field model="ir.actions.actions" name="menu_id" search="[('name', '=', u'Menu')]"/>
<field name="context_lang">en_US</field>
<field name="name">user_tester1</field>
<field eval="[(6,0,[ref('base.group_user')])]" name="groups_id"/>
<field name="company_id" ref="base.main_company"/>
<field eval="[(6, 0, [])]" name="roles_id"/>
<field eval="[(6, 0, [])]" name="rules_id"/>
<field eval="1" name="active"/>
<field model="ir.actions.actions" name="action_id" search="[('name', '=', u'Menu')]"/>
<field name="login">user_tester1</field>
<field name="password">user_tester1</field>
<field eval="[(6, 0, [])]" name="company_ids"/>
</record>
<record id="res_users_usertester1" model="res.users">
<field model="ir.actions.actions" name="menu_id" search="[('name', '=', u'Menu')]"/>
<field name="context_lang">en_US</field>
<field name="name">user_tester2</field>
<field eval="[(6, 0, [ref('base.group_user')])]" name="groups_id"/>
<field name="company_id" ref="base.main_company"/>
<field eval="[(6, 0, [])]" name="roles_id"/>
<field eval="[(6, 0, [])]" name="rules_id"/>
<field eval="1" name="active"/>
<field model="ir.actions.actions" name="action_id" search="[('name', '=', u'Menu')]"/>
<field name="login">user_tester2</field>
<field name="password">user_tester2</field>
<field eval="[(6, 0, [])]" name="company_ids"/>
</record>
<record id="res_users_useranalyst0" model="res.users">
<field model="ir.actions.actions" name="menu_id" search="[('name', '=', u'Menu')]"/>
<field name="context_lang">en_US</field>
<field name="name">user_analyst</field>
<field eval="[(6, 0, [ref('base.group_user')])]" name="groups_id"/>
<field name="company_id" ref="base.main_company"/>
<field eval="[(6, 0, [])]" name="roles_id"/>
<field eval="[(6, 0, [])]" name="rules_id"/>
<field eval="1" name="active"/>
<field model="ir.actions.actions" name="action_id" search="[('name', '=', u'Menu')]"/>
<field name="login">user_analyst</field>
<field name="password">user_analyst</field>
<field eval="[(6, 0, [])]" name="company_ids"/>
</record>
<!-- Resources -->
<record id="resource_resource_analyst0" model="resource.resource">
<field eval="1.0" name="time_efficiency"/>
<field name="user_id" ref="res_users_useranalyst0"/>
<!-- Human Resources -->
<record id="resource_analyst" model="resource.resource">
<field name="user_id" ref="res_users_analyst"/>
<field name="name">Analyst</field>
<field name="company_id" ref="base.main_company"/>
<field eval="1" name="active"/>
<field name="calendar_id" ref="resource.timesheet_group1"/>
<field name="resource_type">user</field>
</record>
<record id="resource_resource_programmer0" model="resource.resource">
<field eval="1.0" name="time_efficiency"/>
<field name="user_id" ref="res_users_userdeveloper0"/>
<field name="name">Programmer</field>
<field name="company_id" ref="base.main_company"/>
<field eval="1" name="active"/>
<record id="resource_project_manager" model="resource.resource">
<field name="user_id" ref="res_users_project_manager"/>
<field name="name">Project Manager</field>
<field name="calendar_id" ref="resource.timesheet_group1"/>
<field name="resource_type">user</field>
</record>
<record id="resource_resource_tester0" model="resource.resource">
<field eval="1.0" name="time_efficiency"/>
<field name="user_id" ref="res_users_usertester0"/>
<record id="resource_technical_leader" model="resource.resource">
<field name="user_id" ref="res_users_technical_leader"/>
<field name="name">Technical Leader</field>
<field name="calendar_id" ref="resource.timesheet_group1"/>
</record>
<record id="resource_developer" model="resource.resource">
<field name="user_id" ref="res_users_developer"/>
<field name="name">Developer</field>
<field name="calendar_id" ref="resource.timesheet_group1"/>
</record>
<record id="resource_designer" model="resource.resource">
<field name="user_id" ref="res_users_designer"/>
<field name="name">Designer</field>
<field name="calendar_id" ref="resource.timesheet_group1"/>
</record>
<record id="resource_tester" model="resource.resource">
<field name="user_id" ref="res_users_tester"/>
<field name="name">Tester</field>
<field name="company_id" ref="base.main_company"/>
<field eval="1" name="active"/>
<field name="calendar_id" ref="resource.timesheet_group1"/>
<field name="resource_type">user</field>
</record>
<record id="resource_resource_webdesigner0" model="resource.resource">
<field eval="1.0" name="time_efficiency"/>
<field name="user_id" ref="res_users_userdesign0"/>
<field name="name">Web Designer</field>
<field name="company_id" ref="base.main_company"/>
<field eval="1" name="active"/>
<record id="resource_finacial_manager" model="resource.resource">
<field name="user_id" ref="res_users_finacial_manager"/>
<field name="name">Project Finacial Manager</field>
<field name="calendar_id" ref="resource.timesheet_group1"/>
<field name="resource_type">user</field>
</record>
<!-- Projects -->
<record id="project_project_openerpwebsitedevelopment0" model="project.project">
<field eval="10" name="sequence"/>
<field name="company_currency_id" ref="base.EUR"/>
<field eval="1" name="active"/>
<field eval="1" name="warn_manager"/>
<field eval="0" name="warn_customer"/>
<field name="date_start" eval="(DateTime.now()-timedelta(70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="company_id" ref="base.main_company"/>
<field eval="1" name="priority"/>
<record id="project_integrate_openerp" model="project.project">
<field name="date_start" eval="time.strftime('%Y-%m-01 10:00:00')"/>
<field name="state">open</field>
<field name="type">normal</field>
<field name="description">Develop an OpenERP Website.</field>
<field eval="[(6, 0, [ref('res_users_manager0'), ref('res_users_user0'), ref('res_users_userfinance0'), ref('res_users_userdesign0'), ref('res_users_userdeveloper0'), ref('res_users_usertester0'), ref('res_users_useranalyst0')])]" name="members"/>
<field name="date" eval="(DateTime.now()+timedelta(60-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="user_id" ref="base.user_root"/>
<field name="currency_id" ref="base.EUR"/>
<field eval="[(6, 0, [])]" name="type_ids"/>
<field name="name">OpenERP Website Development</field>
<field name="description">Integrate an Sale and Warehouse Management.</field>
<field eval="[(6, 0, [
ref('res_users_analyst'),
ref('res_users_project_manager'),
ref('res_users_technical_leader'),
ref('res_users_developer'),
ref('res_users_designer'),
ref('res_users_tester'),
ref('res_users_finacial_manager')])]" name="members"/>
<field name="user_id" ref="res_users_project_manager"/>
<field name="name">Integrate an Sale and Warehouse Management.</field>
</record>
<!-- Project Phases -->
<record id="project_phase_informationgatheringandunderstanding0" model="project.phase">
<record id="project_phase_1" model="project.phase">
<field eval="[(6, 0, [])]" name="previous_phase_ids"/>
<field name="name">Information Gathering and Understanding</field>
<field name="name">Collect Requirement and Make SRS</field>
<field name="product_uom" ref="product.uom_day"/>
<field eval="10" name="sequence"/>
<field name="constraint_date_end" eval="(DateTime.now()+timedelta(18-70)).strftime('%Y-%m-%d')"/>
<field name="date_start" eval="(DateTime.now()-timedelta(70)).strftime('%Y-%m-%d')"/>
<field name="state">draft</field>
<field name="responsible_id" ref="res_users_demouser1"/>
<field eval="15.0" name="duration"/>
<field name="project_id" ref="project_project_openerpwebsitedevelopment0"/>
<field name="constraint_date_start" eval="(DateTime.now()+timedelta(2-70)).strftime('%Y-%m-%d')"/>
<field name="date_end" eval="(DateTime.now()+timedelta(15-70)).strftime('%Y-%m-%d')"/>
<field eval="1" name="sequence"/>
<field name="duration">30</field>
<field name="responsible_id" ref="res_users_analyst"/>
<field name="project_id" ref="project_integrate_openerp"/>
</record>
<record id="project_phase_planning0" model="project.phase">
<field eval="[(6, 0, [ref('project_phase_informationgatheringandunderstanding0')])]" name="previous_phase_ids"/>
<field name="name">Planning</field>
<record id="project_phase_2" model="project.phase">
<field eval="[(6, 0, [ref('project_phase_1')])]" name="previous_phase_ids"/>
<field name="name">Design Model</field>
<field name="product_uom" ref="product.uom_day"/>
<field eval="10" name="sequence"/>
<field name="constraint_date_end" eval="(DateTime.now()+timedelta(28-70)).strftime('%Y-%m-%d')"/>
<field name="date_start" eval="(DateTime.now()+timedelta(10-70)).strftime('%Y-%m-%d')"/>
<field name="state">draft</field>
<field name="responsible_id" ref="res_users_manager0"/>
<field eval="15.0" name="duration"/>
<field name="project_id" ref="project_project_openerpwebsitedevelopment0"/>
<field name="constraint_date_start" eval="(DateTime.now()+timedelta(13-70)).strftime('%Y-%m-%d')"/>
<field name="date_end" eval="(DateTime.now()+timedelta(25-70)).strftime('%Y-%m-%d')"/>
<field eval="2" name="sequence"/>
<field name="duration">20</field>
<field name="responsible_id" ref="res_users_project_manager"/>
<field name="project_id" ref="project_integrate_openerp"/>
</record>
<record id="project_phase_webdesign0" model="project.phase">
<field eval="[(6, 0, [ref('project_phase_planning0')])]" name="previous_phase_ids"/>
<field name="name">Web Design </field>
<record id="project_phase_3" model="project.phase">
<field eval="[(6, 0, [ref('project_phase_2')])]" name="previous_phase_ids"/>
<field name="name">Planning and compute Risk analysis, Time chart </field>
<field name="product_uom" ref="product.uom_day"/>
<field eval="10" name="sequence"/>
<field name="constraint_date_end" eval="(DateTime.now()+timedelta(45-70)).strftime('%Y-%m-%d')"/>
<field name="date_start" eval="(DateTime.now()+timedelta(20-70)).strftime('%Y-%m-%d')"/>
<field name="state">draft</field>
<field name="responsible_id" ref="res_users_userdesign0"/>
<field eval="20.0" name="duration"/>
<field name="project_id" ref="project_project_openerpwebsitedevelopment0"/>
<field name="constraint_date_start" eval="(DateTime.now()+timedelta(25-70)).strftime('%Y-%m-%d')"/>
<field name="date_end" eval="(DateTime.now()+timedelta(40-70)).strftime('%Y-%m-%d')"/>
<field eval="3" name="sequence"/>
<field name="duration">20</field>
<field name="responsible_id" ref="res_users_project_manager"/>
<field name="project_id" ref="project_integrate_openerp"/>
</record>
<record id="project_phase_developmentintegrationandtesting0" model="project.phase">
<field eval="[(6, 0, [ref('project_phase_webdesign0')])]" name="previous_phase_ids"/>
<field name="name">Development, Integration and Testing</field>
<record id="project_phase_4" model="project.phase">
<field eval="[(6, 0, [ref('project_phase_2')])]" name="previous_phase_ids"/>
<field name="name">Development and Integration</field>
<field name="product_uom" ref="product.uom_day"/>
<field eval="10" name="sequence"/>
<field name="constraint_date_end" eval="(DateTime.now()+timedelta(57-70)).strftime('%Y-%m-%d')"/>
<field name="date_start" eval="(DateTime.now()+timedelta(30-70)).strftime('%Y-%m-%d')"/>
<field name="state">draft</field>
<field name="responsible_id" ref="res_users_manager0"/>
<field eval="22.0" name="duration"/>
<field name="project_id" ref="project_project_openerpwebsitedevelopment0"/>
<field name="constraint_date_start" eval="(DateTime.now()+timedelta(35-70)).strftime('%Y-%m-%d')"/>
<field name="date_end" eval="(DateTime.now()+timedelta(52-70)).strftime('%Y-%m-%d')"/>
<field eval="4" name="sequence"/>
<field name="duration">90</field>
<field name="responsible_id" ref="res_users_technical_leader"/>
<field name="project_id" ref="project_integrate_openerp"/>
</record>
<record id="project_phase_websitedeployment0" model="project.phase">
<field eval="[(6, 0, [ref('project_phase_developmentintegrationandtesting0')])]" name="previous_phase_ids"/>
<field name="name">Website Deployment</field>
<record id="project_phase_5" model="project.phase">
<field eval="[(6, 0, [ref('project_phase_4')])]" name="previous_phase_ids"/>
<field name="name">Review and Testing</field>
<field name="product_uom" ref="product.uom_day"/>
<field eval="10" name="sequence"/>
<field name="constraint_date_end" eval="(DateTime.now()+timedelta(63-70)).strftime('%Y-%m-%d')"/>
<field name="date_start" eval="(DateTime.now()+timedelta(55-70)).strftime('%Y-%m-%d')"/>
<field name="state">draft</field>
<field name="responsible_id" ref="res_users_manager0"/>
<field eval="5.0" name="duration"/>
<field name="project_id" ref="project_project_openerpwebsitedevelopment0"/>
<field name="constraint_date_start" eval="(DateTime.now()+timedelta(58-70)).strftime('%Y-%m-%d')"/>
<field name="date_end" eval="(DateTime.now()+timedelta(60-70)).strftime('%Y-%m-%d')"/>
<field eval="5" name="sequence"/>
<field name="duration">30</field>
<field name="responsible_id" ref="res_users_project_manager"/>
<field name="project_id" ref="project_integrate_openerp"/>
</record>
<record id="project_phase_6" model="project.phase">
<field eval="[(6, 0, [ref('project_phase_5')])]" name="previous_phase_ids"/>
<field name="name">Deployement and Training</field>
<field name="product_uom" ref="product.uom_day"/>
<field eval="5" name="sequence"/>
<field name="duration">10</field>
<field name="responsible_id" ref="res_users_analyst"/>
<field name="project_id" ref="project_integrate_openerp"/>
</record>
<!-- Project Resource Allocation -->
<record id="project_resource_allocation_0" model="project.resource.allocation">
<field name="resource_id" ref="resource_resource_analyst0"/>
<field name="phase_id" ref="project_phase_informationgatheringandunderstanding0"/>
<field eval="40.0" name="useability"/>
<record id="resource_allocation_1" model="project.resource.allocation">
<field name="resource_id" ref="resource_analyst"/>
<field name="phase_id" ref="project_phase_1"/>
</record>
<record id="project_resource_allocation_1" model="project.resource.allocation">
<field name="resource_id" ref="resource_resource_programmer0"/>
<field name="phase_id" ref="project_phase_informationgatheringandunderstanding0"/>
<field eval="60.0" name="useability"/>
<record id="resource_allocation_2" model="project.resource.allocation">
<field name="resource_id" ref="resource_project_manager"/>
<field name="phase_id" ref="project_phase_2"/>
</record>
<record id="project_resource_allocation_2" model="project.resource.allocation">
<field name="resource_id" ref="resource_resource_tester0"/>
<field name="phase_id" ref="project_phase_informationgatheringandunderstanding0"/>
<field eval="40.0" name="useability"/>
<record id="resource_allocation_3" model="project.resource.allocation">
<field name="resource_id" ref="resource_project_manager"/>
<field name="phase_id" ref="project_phase_3"/>
</record>
<record id="project_resource_allocation_3" model="project.resource.allocation">
<field name="resource_id" ref="resource_resource_analyst0"/>
<field name="phase_id" ref="project_phase_planning0"/>
<field eval="70.0" name="useability"/>
<record id="resource_allocation_4" model="project.resource.allocation">
<field name="resource_id" ref="resource_technical_leader"/>
<field name="phase_id" ref="project_phase_4"/>
</record>
<record id="project_resource_allocation_4" model="project.resource.allocation">
<field name="resource_id" ref="resource_resource_programmer0"/>
<field name="phase_id" ref="project_phase_planning0"/>
<field eval="70.0" name="useability"/>
<record id="resource_allocation_5" model="project.resource.allocation">
<field name="resource_id" ref="resource_developer"/>
<field name="phase_id" ref="project_phase_4"/>
</record>
<record id="project_resource_allocation_5" model="project.resource.allocation">
<field name="resource_id" ref="resource_resource_webdesigner0"/>
<field name="phase_id" ref="project_phase_webdesign0"/>
<field eval="80.0" name="useability"/>
<record id="resource_allocation_6" model="project.resource.allocation">
<field name="resource_id" ref="resource_designer"/>
<field name="phase_id" ref="project_phase_4"/>
</record>
<record id="project_resource_allocation_6" model="project.resource.allocation">
<field name="resource_id" ref="resource_resource_programmer0"/>
<field name="phase_id" ref="project_phase_webdesign0"/>
<field eval="30.0" name="useability"/>
<record id="resource_allocation_7" model="project.resource.allocation">
<field name="resource_id" ref="resource_tester"/>
<field name="phase_id" ref="project_phase_4"/>
</record>
<record id="project_resource_allocation_7" model="project.resource.allocation">
<field name="resource_id" ref="resource_resource_programmer0"/>
<field name="phase_id" ref="project_phase_developmentintegrationandtesting0"/>
<field eval="100.0" name="useability"/>
<record id="resource_allocation_8" model="project.resource.allocation">
<field name="resource_id" ref="resource_project_manager"/>
<field name="phase_id" ref="project_phase_5"/>
</record>
<record id="project_resource_allocation_8" model="project.resource.allocation">
<field name="resource_id" ref="resource_resource_tester0"/>
<field name="phase_id" ref="project_phase_developmentintegrationandtesting0"/>
<field eval="50.0" name="useability"/>
<record id="resource_allocation_9" model="project.resource.allocation">
<field name="resource_id" ref="resource_analyst"/>
<field name="phase_id" ref="project_phase_6"/>
</record>
<!-- Tasks -->
<record id="project_task_preparerequirementsdocument0" model="project.task">
<field eval="15" name="sequence"/>
<record id="project_task_1" model="project.task">
<field eval="100.0" name="planned_hours"/>
<field name="user_id" ref="res_users_user0"/>
<field name="state">open</field>
<field name="date_start" eval="(DateTime.now()-timedelta(70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="company_id" ref="base.main_company"/>
<field name="user_id" ref="res_users_analyst"/>
<field name="priority">2</field>
<field name="project_id" ref="project_project_openerpwebsitedevelopment0"/>
<field eval="[(6, 0, [])]" name="child_ids"/>
<field eval="[(6, 0, [])]" name="parent_ids"/>
<field eval="1" name="active"/>
<field name="project_id" ref="project_integrate_openerp"/>
<field name="name">Prepare Requirements Document</field>
<field name="date_deadline" eval="(DateTime.now()+timedelta(55-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field eval="100.0" name="total_hours"/>
<field eval="100.0" name="remaining_hours"/>
<field name="phase_id" ref="project_phase_informationgatheringandunderstanding0"/>
<field name="phase_id" ref="project_phase_1"/>
</record>
<record id="project_task_definewebsitegoalspurposesandtargetaudience0" model="project.task">
<field eval="10" name="sequence"/>
<record id="project_task_2" model="project.task">
<field eval="80.0" name="planned_hours"/>
<field name="user_id" ref="res_users_useranalyst0"/>
<field name="state">open</field>
<field name="date_start" eval="(DateTime.now()-timedelta(70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="company_id" ref="base.main_company"/>
<field name="user_id" ref="res_users_analyst"/>
<field name="priority">2</field>
<field name="project_id" ref="project_project_openerpwebsitedevelopment0"/>
<field eval="[(6, 0, [])]" name="child_ids"/>
<field eval="[(6, 0, [])]" name="parent_ids"/>
<field eval="1" name="active"/>
<field name="name">Define Website Goals, Purposes and Target Audience</field>
<field name="date_deadline" eval="(DateTime.now()+timedelta(10-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field eval="80.0" name="total_hours"/>
<field eval="80.0" name="remaining_hours"/>
<field name="phase_id" ref="project_phase_informationgatheringandunderstanding0"/>
<field name="project_id" ref="project_integrate_openerp"/>
<field name="name">Make SRS</field>
<field name="phase_id" ref="project_phase_1"/>
</record>
<record id="project_task_usecases0" model="project.task">
<field eval="17" name="sequence"/>
<record id="project_task_3" model="project.task">
<field eval="40.0" name="planned_hours"/>
<field name="user_id" ref="res_users_userdesign0"/>
<field name="state">open</field>
<field name="date_start" eval="(DateTime.now()+timedelta(48-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="company_id" ref="base.main_company"/>
<field name="user_id" ref="res_users_project_manager"/>
<field name="priority">2</field>
<field name="project_id" ref="project_project_openerpwebsitedevelopment0"/>
<field eval="[(6, 0, [])]" name="child_ids"/>
<field eval="[(6, 0, [])]" name="parent_ids"/>
<field eval="1" name="active"/>
<field name="name">Use Cases</field>
<field name="date_deadline" eval="(DateTime.now()+timedelta(55-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field eval="40.0" name="total_hours"/>
<field eval="40.0" name="remaining_hours"/>
<field name="phase_id" ref="project_phase_informationgatheringandunderstanding0"/>
<field name="project_id" ref="project_integrate_openerp"/>
<field name="name">Design Use Cases</field>
<field name="phase_id" ref="project_phase_2"/>
</record>
<record id="project_task_budgetplanning0" model="project.task">
<field eval="10" name="sequence"/>
<record id="project_task_4" model="project.task">
<field eval="25.0" name="planned_hours"/>
<field name="user_id" ref="res_users_userfinance0"/>
<field name="state">open</field>
<field name="date_start" eval="(DateTime.now()+timedelta(10-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="company_id" ref="base.main_company"/>
<field name="user_id" ref="res_users_project_manager"/>
<field name="priority">2</field>
<field name="project_id" ref="project_project_openerpwebsitedevelopment0"/>
<field eval="[(6, 0, [])]" name="child_ids"/>
<field eval="[(6, 0, [])]" name="parent_ids"/>
<field eval="1" name="active"/>
<field name="project_id" ref="project_integrate_openerp"/>
<field name="name">Budget Planning</field>
<field name="date_deadline" eval="(DateTime.now()+timedelta(18-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field eval="25.0" name="total_hours"/>
<field eval="25.0" name="remaining_hours"/>
<field name="phase_id" ref="project_phase_planning0"/>
<field name="phase_id" ref="project_phase_3"/>
</record>
<record id="project_task_qualityplanning0" model="project.task">
<field eval="10" name="sequence"/>
<record id="project_task_5" model="project.task">
<field eval="25.0" name="planned_hours"/>
<field name="user_id" ref="res_users_user0"/>
<field name="state">open</field>
<field name="date_start" eval="(DateTime.now()+timedelta(10-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="company_id" ref="base.main_company"/>
<field name="user_id" ref="res_users_project_manager"/>
<field name="priority">2</field>
<field name="project_id" ref="project_project_openerpwebsitedevelopment0"/>
<field eval="[(6, 0, [])]" name="child_ids"/>
<field eval="[(6, 0, [])]" name="parent_ids"/>
<field eval="1" name="active"/>
<field name="project_id" ref="project_integrate_openerp"/>
<field name="name">Quality Planning</field>
<field name="date_deadline" eval="(DateTime.now()+timedelta(18-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field eval="25.0" name="total_hours"/>
<field eval="25.0" name="remaining_hours"/>
<field name="phase_id" ref="project_phase_planning0"/>
<field name="phase_id" ref="project_phase_3"/>
</record>
<record id="project_task_riskmanagementplanning0" model="project.task">
<field eval="10" name="sequence"/>
<record id="project_task_6" model="project.task">
<field eval="20.0" name="planned_hours"/>
<field name="user_id" ref="res_users_user1"/>
<field name="state">open</field>
<field name="date_start" eval="(DateTime.now()+timedelta(13-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="company_id" ref="base.main_company"/>
<field name="user_id" ref="res_users_project_manager"/>
<field name="priority">2</field>
<field name="project_id" ref="project_project_openerpwebsitedevelopment0"/>
<field eval="[(6, 0, [])]" name="child_ids"/>
<field eval="[(6, 0, [])]" name="parent_ids"/>
<field eval="1" name="active"/>
<field name="project_id" ref="project_integrate_openerp"/>
<field name="name">Risk Management Planning</field>
<field name="date_deadline" eval="(DateTime.now()+timedelta(20-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field eval="20.0" name="total_hours"/>
<field eval="20.0" name="remaining_hours"/>
<field name="phase_id" ref="project_phase_planning0"/>
<field name="phase_id" ref="project_phase_3"/>
</record>
<record id="project_task_createprojectschedules0" model="project.task">
<field eval="10" name="sequence"/>
<record id="project_task_7" model="project.task">
<field eval="30.0" name="planned_hours"/>
<field name="user_id" ref="res_users_manager0"/>
<field name="state">open</field>
<field name="date_start" eval="(DateTime.now()+timedelta(20-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="company_id" ref="base.main_company"/>
<field name="user_id" ref="res_users_project_manager"/>
<field name="priority">2</field>
<field name="project_id" ref="project_project_openerpwebsitedevelopment0"/>
<field eval="[(6, 0, [])]" name="child_ids"/>
<field eval="[(6, 0, [])]" name="parent_ids"/>
<field eval="1" name="active"/>
<field name="project_id" ref="project_integrate_openerp"/>
<field name="name">Create Project Schedules</field>
<field name="date_deadline" eval="(DateTime.now()+timedelta(25-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field eval="30.0" name="total_hours"/>
<field eval="30.0" name="remaining_hours"/>
<field name="phase_id" ref="project_phase_planning0"/>
<field name="phase_id" ref="project_phase_3"/>
</record>
<record id="project_task_dataflowdesign0" model="project.task">
<field eval="10" name="sequence"/>
<record id="project_task_8" model="project.task">
<field eval="10.0" name="planned_hours"/>
<field name="user_id" ref="res_users_manager0"/>
<field name="state">open</field>
<field name="date_start" eval="(DateTime.now()+timedelta(20-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="company_id" ref="base.main_company"/>
<field name="user_id" ref="res_users_project_manager"/>
<field name="priority">2</field>
<field name="project_id" ref="project_project_openerpwebsitedevelopment0"/>
<field eval="[(6, 0, [])]" name="child_ids"/>
<field eval="[(6, 0, [])]" name="parent_ids"/>
<field eval="1" name="active"/>
<field name="project_id" ref="project_integrate_openerp"/>
<field name="name">Dataflow Design</field>
<field name="date_deadline" eval="(DateTime.now()+timedelta(23-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field eval="10.0" name="total_hours"/>
<field eval="10.0" name="remaining_hours"/>
<field name="phase_id" ref="project_phase_webdesign0"/>
<field name="phase_id" ref="project_phase_3"/>
</record>
<record id="project_task_userinterfacedesign0" model="project.task">
<field eval="10" name="sequence"/>
<record id="project_task_9" model="project.task">
<field eval="50.0" name="planned_hours"/>
<field name="user_id" ref="res_users_userdesign0"/>
<field name="state">open</field>
<field name="date_start" eval="(DateTime.now()+timedelta(22-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="company_id" ref="base.main_company"/>
<field name="user_id" ref="res_users_project_manager"/>
<field name="priority">2</field>
<field name="project_id" ref="project_project_openerpwebsitedevelopment0"/>
<field eval="[(6, 0, [])]" name="child_ids"/>
<field eval="[(6, 0, [])]" name="parent_ids"/>
<field eval="1" name="active"/>
<field name="project_id" ref="project_integrate_openerp"/>
<field name="name">User Interface Design</field>
<field name="date_deadline" eval="(DateTime.now()+timedelta(40-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field eval="150.0" name="total_hours"/>
<field eval="150.0" name="remaining_hours"/>
<field name="phase_id" ref="project_phase_webdesign0"/>
<field name="phase_id" ref="project_phase_3"/>
</record>
<record id="project_task_tasklevelwbs0" model="project.task">
<field eval="10" name="sequence"/>
<record id="project_task_10" model="project.task">
<field eval="40.0" name="planned_hours"/>
<field name="user_id" ref="res_users_userdesign0"/>
<field name="state">open</field>
<field name="date_start" eval="(DateTime.now()+timedelta(30-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="company_id" ref="base.main_company"/>
<field name="user_id" ref="res_users_developer"/>
<field name="priority">2</field>
<field name="project_id" ref="project_project_openerpwebsitedevelopment0"/>
<field eval="[(6, 0, [])]" name="child_ids"/>
<field eval="[(6, 0, [])]" name="parent_ids"/>
<field eval="1" name="active"/>
<field name="name">Task Level WBS</field>
<field name="date_deadline" eval="(DateTime.now()+timedelta(40-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field eval="40.0" name="total_hours"/>
<field eval="40.0" name="remaining_hours"/>
<field name="phase_id" ref="project_phase_webdesign0"/>
<field name="project_id" ref="project_integrate_openerp"/>
<field name="name">Develop Module in Sale Management</field>
<field name="phase_id" ref="project_phase_4"/>
</record>
<record id="project_task_modularprogramming0" model="project.task">
<field eval="10" name="sequence"/>
<record id="project_task_11" model="project.task">
<field eval="90.0" name="planned_hours"/>
<field name="user_id" ref="res_users_userdeveloper0"/>
<field name="state">open</field>
<field name="date_start" eval="(DateTime.now()+timedelta(30-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="company_id" ref="base.main_company"/>
<field name="user_id" ref="res_users_developer"/>
<field name="priority">2</field>
<field name="project_id" ref="project_project_openerpwebsitedevelopment0"/>
<field eval="[(6, 0, [])]" name="child_ids"/>
<field eval="[(6, 0, [])]" name="parent_ids"/>
<field eval="1" name="active"/>
<field name="name">Modular Programming</field>
<field name="date_deadline" eval="(DateTime.now()+timedelta(50-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field eval="90.0" name="total_hours"/>
<field eval="90.0" name="remaining_hours"/>
<field name="phase_id" ref="project_phase_developmentintegrationandtesting0"/>
<field name="project_id" ref="project_integrate_openerp"/>
<field name="name">Develop module in Warehouse</field>
<field name="phase_id" ref="project_phase_4"/>
</record>
<record id="project_task_integratemodules0" model="project.task">
<field eval="10" name="sequence"/>
<record id="project_task_12" model="project.task">
<field eval="20.0" name="planned_hours"/>
<field name="user_id" ref="res_users_userdeveloper1"/>
<field name="state">open</field>
<field name="date_start" eval="(DateTime.now()+timedelta(45-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="company_id" ref="base.main_company"/>
<field name="user_id" ref="res_users_developer"/>
<field name="priority">2</field>
<field name="project_id" ref="project_project_openerpwebsitedevelopment0"/>
<field eval="[(6, 0, [])]" name="child_ids"/>
<field eval="[(6, 0, [])]" name="parent_ids"/>
<field eval="1" name="active"/>
<field name="project_id" ref="project_integrate_openerp"/>
<field name="name">Integrate Modules</field>
<field name="date_deadline" eval="(DateTime.now()+timedelta(53-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field eval="20.0" name="total_hours"/>
<field eval="20.0" name="remaining_hours"/>
<field name="phase_id" ref="project_phase_developmentintegrationandtesting0"/>
<field name="phase_id" ref="project_phase_4"/>
</record>
<record id="project_task_unittesting0" model="project.task">
<field eval="10" name="sequence"/>
<record id="project_task_13" model="project.task">
<field eval="50.0" name="planned_hours"/>
<field name="user_id" ref="res_users_usertester0"/>
<field name="state">open</field>
<field name="date_start" eval="(DateTime.now()+timedelta(40-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="company_id" ref="base.main_company"/>
<field name="user_id" ref="res_users_tester"/>
<field name="priority">2</field>
<field name="project_id" ref="project_project_openerpwebsitedevelopment0"/>
<field eval="[(6, 0, [])]" name="child_ids"/>
<field eval="[(6, 0, [])]" name="parent_ids"/>
<field eval="1" name="active"/>
<field name="project_id" ref="project_integrate_openerp"/>
<field name="name">Unit Testing</field>
<field name="date_deadline" eval="(DateTime.now()+timedelta(55-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field eval="50.0" name="total_hours"/>
<field eval="50.0" name="remaining_hours"/>
<field name="phase_id" ref="project_phase_developmentintegrationandtesting0"/>
<field name="phase_id" ref="project_phase_4"/>
</record>
<record id="project_task_regressiontest0" model="project.task">
<field eval="10" name="sequence"/>
<record id="project_task_14" model="project.task">
<field eval="30.0" name="planned_hours"/>
<field name="user_id" ref="res_users_usertester0"/>
<field name="state">open</field>
<field name="date_start" eval="(DateTime.now()+timedelta(40-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="company_id" ref="base.main_company"/>
<field name="user_id" ref="res_users_tester"/>
<field name="priority">2</field>
<field name="project_id" ref="project_project_openerpwebsitedevelopment0"/>
<field eval="[(6, 0, [])]" name="child_ids"/>
<field eval="[(6, 0, [])]" name="parent_ids"/>
<field eval="1" name="active"/>
<field name="project_id" ref="project_integrate_openerp"/>
<field name="name">Regression Test</field>
<field name="date_deadline" eval="(DateTime.now()+timedelta(55-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field eval="30.0" name="total_hours"/>
<field eval="30.0" name="remaining_hours"/>
<field name="phase_id" ref="project_phase_developmentintegrationandtesting0"/>
<field name="phase_id" ref="project_phase_4"/>
</record>
<record id="project_task_documentation0" model="project.task">
<field eval="10" name="sequence"/>
<record id="project_task_15" model="project.task">
<field eval="15.0" name="planned_hours"/>
<field name="user_id" ref="res_users_demouser1"/>
<field name="state">open</field>
<field name="date_start" eval="(DateTime.now()+timedelta(40-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="company_id" ref="base.main_company"/>
<field name="user_id" ref="res_users_developer"/>
<field name="priority">2</field>
<field name="project_id" ref="project_project_openerpwebsitedevelopment0"/>
<field eval="[(6, 0, [])]" name="child_ids"/>
<field eval="[(6, 0, [])]" name="parent_ids"/>
<field eval="1" name="active"/>
<field name="project_id" ref="project_integrate_openerp"/>
<field name="name">Documentation</field>
<field name="date_deadline" eval="(DateTime.now()+timedelta(55-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field eval="15.0" name="total_hours"/>
<field eval="15.0" name="remaining_hours"/>
<field name="phase_id" ref="project_phase_websitedeployment0"/>
<field name="phase_id" ref="project_phase_4"/>
</record>
<record id="project_task_performancetuning0" model="project.task">
<record id="project_task_16" model="project.task">
<field eval="10" name="sequence"/>
<field eval="40.0" name="planned_hours"/>
<field name="user_id" ref="res_users_usertester1"/>
<field name="state">open</field>
<field name="date_start" eval="(DateTime.now()+timedelta(45-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="company_id" ref="base.main_company"/>
<field name="user_id" ref="res_users_tester"/>
<field name="priority">2</field>
<field name="project_id" ref="project_project_openerpwebsitedevelopment0"/>
<field eval="[(6, 0, [])]" name="child_ids"/>
<field eval="[(6, 0, [])]" name="parent_ids"/>
<field eval="1" name="active"/>
<field name="project_id" ref="project_integrate_openerp"/>
<field name="name">Performance Tuning</field>
<field name="date_deadline" eval="(DateTime.now()+timedelta(55-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field eval="40.0" name="total_hours"/>
<field eval="40.0" name="remaining_hours"/>
<field name="phase_id" ref="project_phase_developmentintegrationandtesting0"/>
<field name="phase_id" ref="project_phase_4"/>
</record>
<record id="project_task_deploywebsite0" model="project.task">
<field eval="10" name="sequence"/>
<record id="project_task_17" model="project.task">
<field eval="5.0" name="planned_hours"/>
<field name="user_id" ref="res_users_userdeveloper0"/>
<field name="state">open</field>
<field name="date_start" eval="(DateTime.now()+timedelta(55-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="company_id" ref="base.main_company"/>
<field name="user_id" ref="res_users_analyst"/>
<field name="priority">2</field>
<field name="project_id" ref="project_project_openerpwebsitedevelopment0"/>
<field eval="[(6, 0, [])]" name="child_ids"/>
<field eval="[(6, 0, [])]" name="parent_ids"/>
<field eval="1" name="active"/>
<field name="name">Deploy Website</field>
<field name="date_deadline" eval="(DateTime.now()+timedelta(60-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field eval="5.0" name="total_hours"/>
<field eval="5.0" name="remaining_hours"/>
<field name="phase_id" ref="project_phase_websitedeployment0"/>
<field name="project_id" ref="project_integrate_openerp"/>
<field name="name">Deploy and Review on Customer System</field>
<field name="phase_id" ref="project_phase_6"/>
</record>
<record id="project_task_presentation0" model="project.task">
<field eval="10" name="sequence"/>
<record id="project_task_18" model="project.task">
<field eval="10.0" name="planned_hours"/>
<field name="user_id" ref="res_users_demouser1"/>
<field name="state">open</field>
<field name="date_start" eval="(DateTime.now()+timedelta(58-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="company_id" ref="base.main_company"/>
<field name="user_id" ref="res_users_analyst"/>
<field name="priority">2</field>
<field name="project_id" ref="project_project_openerpwebsitedevelopment0"/>
<field eval="[(6, 0, [])]" name="child_ids"/>
<field eval="[(6, 0, [])]" name="parent_ids"/>
<field eval="1" name="active"/>
<field name="name">Presentation</field>
<field name="date_deadline" eval="(DateTime.now()+timedelta(65-70)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field eval="10.0" name="total_hours"/>
<field eval="10.0" name="remaining_hours"/>
<field name="phase_id" ref="project_phase_websitedeployment0"/>
<field name="project_id" ref="project_integrate_openerp"/>
<field name="name">Training and Presentation</field>
<field name="phase_id" ref="project_phase_6"/>
</record>
<!-- run scheduling of phase -->
<function model="project.project" name="schedule_phases" eval="(ref('project_integrate_openerp'),)"/>
<!-- run scheduling of tasks -->
<function model="project.project" name="schedule_tasks" eval="(ref('project_integrate_openerp'),)"/>
</data>
</openerp>
@@ -30,7 +30,7 @@
<form string="Project Resource Allocation">
<field name="resource_id" select="1"/>
<field name="phase_id"/>
<field name="useability"/>
<field name="useability" string="Availability"/>
</form>
</field>
</record>
@@ -60,8 +60,9 @@
<field name="phase_id"/>
</group>
<newline/>
<group expand="1" string="Group By..." colspan="4" col="20">
<group expand="0" string="Group By..." colspan="4" col="20">
<filter name="resource" string="Resource" icon="terp-folder-blue" domain="[]" context="{'group_by':'resource_id'}"/>
<separator orientation="vertical"/>
<filter string="Phase" icon="terp-project" domain="[]" context="{'group_by':'phase_id'}"/>
</group>
</search>
@@ -89,16 +90,21 @@
<field name="arch" type="xml">
<form string="Project Phase">
<group colspan="6" col="6">
<field name="name" select="1"/>
<field name="project_id" on_change="onchange_project(project_id)"/>
<field name="responsible_id"/>
</group>
<group colspan="6" col="6">
<field name="duration" />
<field name="product_uom" nolabel="1" domain="[('category_id.name', '=', 'Working Time')]"/>
<field name="date_start"/>
<field name="date_end"/>
</group>
<group colspan="2" col="2">
<field name="name" select="1"/>
<field name="date_start"/>
</group>
<group colspan="2" col="4">
<field name="project_id" on_change="onchange_project(project_id)" colspan="4"/>
<newline/>
<field name="duration" colspan="1"/>
<field name="product_uom" nolabel="1" domain="[('category_id.name', '=', 'Working Time')]"/>
</group>
<group colspan="2" col="2">
<field name="responsible_id"/>
<field name="date_end"/>
</group>
</group>
<notebook colspan="4">
<page string="Resource Allocation">
<field colspan="4" name="resource_ids" nolabel="1">
@@ -115,9 +121,9 @@
<group col="12" colspan="4">
<field name="state" select="1"/>
<button string="Draft" name="set_draft" states="open" icon="gtk-indent"/>
<button string="Start Phase" name="set_open" states="pending,draft" icon="gtk-execute"/>
<button string="Done" name="set_done" states="pending,open" icon="gtk-apply"/>
<button string="Pending" name="set_pending" states="open" icon="gtk-media-pause"/>
<button string="Done" name="set_done" states="pending,open" icon="terp-dialog-close"/>
<button string="Start Phase" name="set_open" states="pending,draft" icon="gtk-execute"/>
<button string="Cancel" name="set_cancel" states="draft,open,pending" icon="gtk-cancel"/>
</group>
</page>
@@ -184,7 +190,7 @@
<field name="type">tree</field>
<field name="priority" eval="5"/>
<field name="arch" type="xml">
<tree string="Project Phases">
<tree colors="grey:state in ('cancelled','done');blue:state in ('pending')" string="Project Phases">
<field name="name"/>
<field name="project_id" on_change="onchange_project(project_id)"/>
<field name="responsible_id"/>
@@ -228,23 +234,26 @@
<field name="arch" type="xml">
<search string="Project Phases">
<group colspan="4" col="20">
<filter string="Draft" domain="[('state','=','draft')]" help="Draft Phases" icon="terp-check" default="1"/>
<filter string="Draft" domain="[('state','=','draft')]" help="Draft Phases" icon="terp-document-new" default="1"/>
<filter string="In Progress" name="Progress" domain="[('state','=','open')]" help="Open Phases" icon="terp-camera_test"/>
<filter string="Pending" domain="[('state','=','pending')]" help="Pending Phases" icon="terp-gtk-media-pause"/>
<separator orientation="vertical"/>
<field name="name"/>
<field name="project_id">
<filter domain="[('project_id.user_id','=',uid)]" help="My Projects" icon="terp-folder-blue"/>
<filter domain="[('project_id.user_id','=',uid)]" help="My Projects" icon="terp-personal"/>
</field>
<field name="responsible_id"/>
<field name="date_start"/>
</group>
<newline/>
<group expand="1" string="Group By..." colspan="4" col="20" groups="base.group_extended">
<filter string="Project" icon="terp-folder-blue" domain="[]" context="{'group_by':'project_id'}"/>
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
<group expand="0" string="Group By..." colspan="4" col="20" groups="base.group_extended">
<filter string="User" icon="terp-personal" domain="[]" context="{'group_by':'responsible_id'}"/>
<filter string="Start Date" icon="terp-gtk-jump-to-ltr" domain="[]" context="{'group_by':'date_start'}"/>
<separator orientation="vertical"/>
<filter string="Project" icon="terp-folder-blue" domain="[]" context="{'group_by':'project_id'}" name="project"/>
<separator orientation="vertical"/>
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
<separator orientation="vertical"/>
<filter string="Month" icon="terp-go-month" domain="[]" context="{'group_by':'date_start'}" help="Start Month"/>
</group>
</search>
</field>
@@ -257,7 +266,7 @@
<field name="view_mode">tree,form,gantt,calendar</field>
<field name="context">{'search_default_responsible_id':uid}</field>
<field name="search_view_id" ref="view_project_phase_search"/>
<field name="help">You can subdivide your larger projects into several phases. For each phase, you can define your resources allocation (humans or engine), describe de differend task and link your phase with previous and next one, add constraints date and scheduling. A gantt view of your project phase is also available from this menu. Gantt view is a graphically draw of the project plan; it includes any task dependencies by visually adjusting task durations and priorities, and by linking tasks to each other.</field>
<field name="help">You can subdivide your larger projects into several phases. For each phase, you can define your resources allocation (humans or engine), describe de differend task and link your phase with previous and next one, add constraints date and scheduling. A gantt view of your project phase is also available from this menu. Gantt view is a graphically draw of the project plan; it includes any task dependencies by visually adjusting task durations and priorities, and by linking tasks to each other.</field>
</record>
<record id="act_project_phase_list" model="ir.actions.act_window">
@@ -297,10 +306,10 @@
res_model="project.task"
src_model="project.phase"
view_mode="tree,form"
domain="[('phase_id','=',active_id)]"/>
context="{'search_default_phase_id': [active_id]}"/>
<act_window
domain="[('project_id', '=', active_id)]"
context="{'search_default_project_id': [active_id]}"
id="act_project_phases"
name="Phases"
res_model="project.phase"
@@ -320,7 +329,7 @@
name="Resource Allocations" parent="base.menu_project_long_term" sequence="2"/>
<menuitem id="menu_pm_resources_project1"
groups="base.group_extended"
groups="base.group_extended"
name="Resources" parent="project.menu_definitions" sequence="3"/>
<menuitem id="menu_phase_schedule" name="Scheduling" parent="base.menu_project_long_term" sequence="4" groups="project.group_project_user,project.group_project_manager,base.group_system"/>
@@ -1,9 +1,10 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"access_project_phase","project.phase","model_project_phase",project.group_project_user,1,1,1,0
"access_project_resource_allocation","project.resource.allocation","model_project_resource_allocation",project.group_project_user,1,1,1,0
"access_project_phase_manager","project.phase manager","model_project_phase",project.group_project_manager,1,0,0,0
"access_project_resource_allocation_manager","project.resource.allocation manager","model_project_resource_allocation",project.group_project_manager,1,0,0,0
"access_project_resource_allocation_system","project.resource.allocation system","model_project_resource_allocation",base.group_system,1,0,0,0
"access_project_phase_system","project.phase system","model_project_phase",base.group_system,1,0,0,0
"access_resource_resource_user","resource.resource user","resource.model_resource_resource",project.group_project_user,1,1,1,1
"access_project_phase","project.phase","model_project_phase","project.group_project_user",1,1,1,0
"access_project_resource_allocation","project.resource.allocation","model_project_resource_allocation","project.group_project_user",1,1,1,0
"access_project_phase_manager","project.phase manager","model_project_phase","project.group_project_manager",1,0,0,0
"access_project_resource_allocation_manager","project.resource.allocation manager","model_project_resource_allocation","project.group_project_manager",1,0,0,0
"access_project_resource_allocation_system","project.resource.allocation system","model_project_resource_allocation","base.group_system",1,0,0,0
"access_project_phase_system","project.phase system","model_project_phase","base.group_system",1,0,0,0
"access_resource_resource_user","resource.resource user","resource.model_resource_resource","project.group_project_user",1,0,1,1
"access_resource_calendar_leaves_user","resource.calendar.leaves user","resource.model_resource_calendar_leaves","project.group_project_user",1,1,1,1
"access_resource_resource_manager","resource.resource manager","resource.model_resource_resource","project.group_project_manager",1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_project_phase project.phase model_project_phase project.group_project_user 1 1 1 0
3 access_project_resource_allocation project.resource.allocation model_project_resource_allocation project.group_project_user 1 1 1 0
4 access_project_phase_manager project.phase manager model_project_phase project.group_project_manager 1 0 0 0
5 access_project_resource_allocation_manager project.resource.allocation manager model_project_resource_allocation project.group_project_manager 1 0 0 0
6 access_project_resource_allocation_system project.resource.allocation system model_project_resource_allocation base.group_system 1 0 0 0
7 access_project_phase_system project.phase system model_project_phase base.group_system 1 0 0 0
8 access_resource_resource_user resource.resource user resource.model_resource_resource project.group_project_user 1 1 0 1 1
9 access_resource_calendar_leaves_user resource.calendar.leaves user resource.model_resource_calendar_leaves project.group_project_user 1 1 1 1
10 access_resource_resource_manager resource.resource manager resource.model_resource_resource project.group_project_manager 1 1 1 1
@@ -2,32 +2,31 @@
Create project 'Develop an outlook-openerp synchronization plugin'
-
!record {model: project.project, id: project_project_project0}:
company_id: base.main_company
name: Project123
name: Develop an outlook-openerp synchronization plugin
members:
- project_long_term.res_users_manager0
- project_long_term.res_users_user0
- project_long_term.res_users_userfinance0
- project_long_term.res_users_userdesign0
- project_long_term.res_users_userdeveloper0
- project_long_term.res_users_usertester0
- project_long_term.res_users_useranalyst0
- project_long_term.res_users_project_manager
- project_long_term.res_users_technical_leader
- project_long_term.res_users_developer
- project_long_term.res_users_designer
- project_long_term.res_users_tester
- project_long_term.res_users_analyst
- project_long_term.res_users_finacial_manager
-
Create phase 'Develop GUI' in Outlook
-
!record {model: project.phase, id: project_phase_phase0}:
date_start: '2010-06-02'
duration: 200.0
name: phase123
name: Develop GUI in Outlook
product_uom: product.uom_day
project_id: project_project_project0
state: draft
resource_ids:
- resource_id: project_long_term.resource_resource_analyst0
- resource_id: project_long_term.resource_analyst
useability: 80.0
- resource_id: project_long_term.resource_resource_programmer0
- resource_id: project_long_term.resource_developer
useability: 30.0
- resource_id: project_long_term.resource_resource_webdesigner0
- resource_id: project_long_term.resource_designer
useability: 30.0
@@ -35,66 +34,60 @@
Create the phase task 'Develop GUI for Server Configuration'
-
!record {model: project.task, id: project_task_t0}:
name: t1
name: Develop GUI for Server Configuration
planned_hours: 20.0
remaining_hours: 20.0
state: draft
phase_id: project_phase_phase0
project_id: project_project_project0
user_id: project_long_term.res_users_userdeveloper0
user_id: project_long_term.res_users_developer
-
Create the phase task 'Develop GUI for Modules Configuration'
-
!record {model: project.task, id: project_task_t1}:
name: t2
name: Develop GUI for Modules Configuration
planned_hours: 25.0
remaining_hours: 25.0
state: draft
phase_id: project_phase_phase0
project_id: project_project_project0
user_id: project_long_term.res_users_userdeveloper0
user_id: project_long_term.res_users_developer
-
Create the phase task 'Develop GUI for OpenERP Synchronisation'
-
!record {model: project.task, id: project_task_t2}:
name: t3
name: Develop GUI for OpenERP Synchronisation
planned_hours: 30.0
remaining_hours: 30.0
state: draft
phase_id: project_phase_phase0
project_id: project_project_project0
user_id: project_long_term.res_users_userdeveloper0
user_id: project_long_term.res_users_developer
-
Create the phase task 'Develop required Menus'
Create the phase task 'Design required GUI/Menus'
-
!record {model: project.task, id: project_task_3}:
name: t4
name: Design required GUI/Menus
planned_hours: 25.0
remaining_hours: 25.0
state: draft
phase_id: project_phase_phase0
project_id: project_project_project0
user_id: project_long_term.res_users_userdesign0
user_id: project_long_term.res_users_designer
-
Schedule phase tasks
-
!python {model: project.schedule.tasks}: |
res = self.compute_date(cr, uid, {"lang": "en_US", "tz": False,
"active_id": ref("project_phase_phase0"),
# rest may be obsolete:
# "active_model": "project.phase", "active_ids": [ref("project_phase_phase0")],
# "record_id": 138, "project_id": ref("project_project_project0"),
})
print res
!python {model: project.phase}: |
res = self.schedule_tasks(cr, uid, [ref("project_phase_phase0")])
-
Check if tasks scheduled, check that either of task's start_date, end_date and user_id is not null
-
!python {model: project.phase}: |
phase=self.browse(cr, uid, [ref("project_phase_phase0")])[0]
phase = self.browse(cr, uid, [ref("project_phase_phase0")])[0]
for task in phase.task_ids:
if (not task.user_id) or (not task.date_start) or (not task.date_end):
raise AssertionError("Phase Tasks not scheduled: %d uid=%r start=%r end=%r" % \
(task.id, task.user_id, task.date_start, task.date_end))
(task.id, task.user_id, task.date_start, task.date_end))
@@ -2,7 +2,6 @@
Create a project 'World Bank's Project'
-
!record {model: project.project, id: project_project_worldbanksproject0}:
company_id: base.main_company
name: "World Bank's Project"
priority: 4
@@ -15,7 +14,6 @@
name: "Defining Client's Basic Idea of Project"
product_uom: product.uom_day
project_id: project_project_worldbanksproject0
state: draft
-
@@ -27,7 +25,6 @@
name: Establishing Project Feasibility
product_uom: product.uom_day
project_id: project_project_worldbanksproject0
state: draft
-
Create project phase 'Preparation of Engineering Designs'
@@ -38,7 +35,6 @@
name: Preparation of Engineering Designs
product_uom: product.uom_hour
project_id: project_project_worldbanksproject0
state: draft
-
@@ -50,7 +46,6 @@
name: Procurement of Works and Goods
product_uom: product.uom_hour
project_id: project_project_worldbanksproject0
state: draft
-
@@ -62,7 +57,6 @@
name: Project Construction
product_uom: product.uom_hour
project_id: project_project_worldbanksproject0
state: draft
-
@@ -74,7 +68,6 @@
name: Project Completion
product_uom: product.uom_hour
project_id: project_project_worldbanksproject0
state: draft
-
Set previous phase for phase 'Establishing Project Feasibility'
@@ -125,11 +118,8 @@
-
Schedule project phases
-
!python {model: project.compute.phases}: |
self.check_selection(cr, uid, [ref("project_compute_phases_0")], {"lang": "en_US",
"project_id": False, "tz": False, "active_model": "ir.ui.menu", "department_id":
False, "section_id": False, "record_id": 279, "active_ids": [ref("project_long_term.menu_compute_phase")],
"active_id": ref("project_long_term.menu_compute_phase"), })
!python {model: project.project}: |
self.schedule_phases(cr, uid, ref("project_project_worldbanksproject0"))
-
Check if phases scheduled, check that either of phase's start_date, end_date and user_id is not null
@@ -140,4 +130,4 @@
if (not phase.responsible_id) or (not phase.date_start) or (not phase.date_end):
raise AssertionError("Tasks not scheduled")
@@ -2,103 +2,93 @@
Create project 'Develop a thunderbird-openerp synchronization plugin'
-
!record {model: project.project, id: project_project_project1}:
company_id: base.main_company
name: Project2
name: Develop a thunderbird-openerp synchronization plugin
members:
- project_long_term.res_users_manager0
- project_long_term.res_users_user0
- project_long_term.res_users_userfinance0
- project_long_term.res_users_userdesign0
- project_long_term.res_users_userdeveloper0
- project_long_term.res_users_usertester0
- project_long_term.res_users_useranalyst0
- project_long_term.res_users_project_manager
- project_long_term.res_users_technical_leader
- project_long_term.res_users_developer
- project_long_term.res_users_designer
- project_long_term.res_users_tester
- project_long_term.res_users_analyst
- project_long_term.res_users_finacial_manager
-
Create phase 'Develop GUI' in Thunderbird
Create phase 'Develop GUI' in thunderbird
-
!record {model: project.phase, id: project_phase_phase1}:
date_start: '2010-06-02'
duration: 100.0
name: phase22
duration: 200.0
name: Develop GUI in thunderbird
product_uom: product.uom_day
project_id: project_project_project1
state: draft
resource_ids:
- resource_id: project_long_term.resource_resource_analyst0
- resource_id: project_long_term.resource_analyst
useability: 80.0
- resource_id: project_long_term.resource_resource_programmer0
- resource_id: project_long_term.resource_developer
useability: 30.0
- resource_id: project_long_term.resource_resource_webdesigner0
- resource_id: project_long_term.resource_designer
useability: 30.0
-
Create the phase task 'Develop GUI for Server Configuration'
-
!record {model: project.task, id: project_task_t00}:
name: t1
!record {model: project.task, id: project_task_t10}:
name: Develop GUI for Server Configuration
planned_hours: 20.0
remaining_hours: 20.0
state: draft
phase_id: project_phase_phase1
project_id: project_project_project1
user_id: project_long_term.res_users_userdeveloper0
user_id: project_long_term.res_users_developer
-
Create the phase task 'Develop GUI for Modules Configuration'
-
!record {model: project.task, id: project_task_t11}:
name: t2
name: Develop GUI for Modules Configuration
planned_hours: 25.0
remaining_hours: 25.0
state: draft
phase_id: project_phase_phase1
project_id: project_project_project1
user_id: project_long_term.res_users_userdeveloper0
user_id: project_long_term.res_users_developer
-
Create the phase task 'Develop GUI for OpenERP Synchronisation'
-
!record {model: project.task, id: project_task_t22}:
name: t3
!record {model: project.task, id: project_task_t12}:
name: Develop GUI for OpenERP Synchronisation
planned_hours: 30.0
remaining_hours: 30.0
state: draft
phase_id: project_phase_phase1
project_id: project_project_project1
user_id: project_long_term.res_users_developer
-
Create the phase task 'Develop required Menus'
Create the phase task 'Design required GUI/Menus'
-
!record {model: project.task, id: project_task_t33}:
name: t4
!record {model: project.task, id: project_task_13}:
name: Design required GUI/Menus
planned_hours: 25.0
remaining_hours: 25.0
state: draft
phase_id: project_phase_phase1
project_id: project_project_project1
-
Get the project to schedule the tasks
-
!record {model: project.compute.tasks, id: project_compute_tasks_0}:
project_id: project_project_project1
user_id: project_long_term.res_users_designer
-
Schedule tasks
-
!python {model: project.compute.tasks}: |
self.compute_date(cr, uid, [ref("project_compute_tasks_0")], {"lang": "en_US", "tz": False,
"active_id": ref("project_long_term.menu_compute_tasks"),
"active_model": "ir.ui.menu", "active_ids": [ref("project_long_term.menu_compute_tasks")],
})
!python {model: project.project}: |
self.schedule_tasks(cr, uid, ref("project_project_project1"))
-
Check if tasks scheduled, check that either of task's start_date, end_date and user_id is not null
-
!python {model: project.project}: |
prj=self.browse(cr, uid, [ref("project_project_project1")])[0]
prj = self.browse(cr, uid, [ref("project_project_project1")])[0]
for task in prj.tasks:
if (not task.user_id) or (not task.date_start) or (not task.date_end):
raise AssertionError("Project Tasks not scheduled")
@@ -22,6 +22,5 @@
import project_compute_phases
import project_compute_tasks
import project_schedule_tasks
import working_calendar
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -18,18 +18,11 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import datetime
from resource.faces import *
from new import classobj
from tools.translate import _
from osv import fields, osv
import working_calendar as wkcal
class project_compute_phases(osv.osv_memory):
_name = 'project.compute.phases'
_description = 'Project Compute Phases'
_columns = {
@@ -48,118 +41,24 @@ class project_compute_phases(osv.osv_memory):
data_select = self.read(cr, uid, ids, ['target_project'])[0]
return self.compute_date(cr, uid, ids, context=context)
def _phase_schedule(self, cr, uid, phase, start_date, calendar_id=False, context=None):
if context is None:
context = {}
"""Schedule phase with the start date till all the next phases are completed.
Arguements: start_dsate -- start date for the phase
calendar_id -- working calendar of the project
"""
phase_obj = self.pool.get('project.phase')
resource_obj = self.pool.get('resource.resource')
uom_obj = self.pool.get('product.uom')
phase_resource_obj = False
if context is None:
context = {}
if phase:
leaves = []
time_efficiency = 1.0
resource_id = resource_obj.search(cr, uid, [('user_id', '=', phase.responsible_id.id)])
if resource_id:
# Create a new resource object with
# all the attributes of the Resource Class
resource = resource_obj.browse(cr, uid, resource_id, context=context)[0]
time_efficiency = resource.time_efficiency
leaves = wkcal.compute_leaves(cr, uid, calendar_id , resource.id, resource.calendar_id.id)
if not phase.responsible_id:
raise osv.except_osv(_('No responsible person assigned !'),_("You must assign a responsible person for phase '%s' !") % (phase.name,))
phase_resource_obj = classobj((phase.responsible_id.name.encode('utf8')), (Resource,),{
'__doc__': phase.responsible_id.name,
'__name__': phase.responsible_id.name,
'vacation': tuple(leaves),
'efficiency': time_efficiency
})
default_uom_id = phase_obj._get_default_uom_id(cr, uid)
avg_hours = uom_obj._compute_qty(cr, uid, phase.product_uom.id, phase.duration, default_uom_id)
duration = str(avg_hours) + 'H'
# Create a new project for each phase
def Project():
start = start_date
minimum_time_unit = 1
resource = phase_resource_obj
# If project has working calendar then that
# else the default one would be considered
if calendar_id:
working_days = wkcal.compute_working_calendar(cr, uid, calendar_id, context=context)
vacation = tuple(wkcal.compute_leaves(cr, uid, calendar_id))
def phase():
effort = duration
project = BalancedProject(Project)
s_date = project.phase.start.to_datetime()
e_date = project.phase.end.to_datetime()
# Recalculate date_start and date_end
# according to constraints on date start and date end on phase
if phase.constraint_date_start and str(s_date) < phase.constraint_date_start:
start_date = datetime.datetime.strptime(phase.constraint_date_start, '%Y-%m-%d')
else:
start_date = s_date
if phase.constraint_date_end and str(e_date) > phase.constraint_date_end:
end_date= datetime.datetime.strptime(phase.constraint_date_end, '%Y-%m-%d')
date_start = phase.constraint_date_end
else:
end_date = e_date
date_start = end_date
# Write the calculated dates back
ctx = context.copy()
ctx.update({'scheduler': True})
phase_obj.write(cr, uid, [phase.id], {
'date_start': start_date.strftime('%Y-%m-%d'),
'date_end': end_date.strftime('%Y-%m-%d')
}, context=ctx)
# Recursive call till all the next phases scheduled
for phase in phase.next_phase_ids:
if phase.state in ['draft', 'open', 'pending']:
id_cal = phase.project_id.resource_calendar_id and phase.project_id.resource_calendar_id.id or False
self._phase_schedule(cr, uid, phase, date_start, id_cal, context=context)
else:
continue
def compute_date(self, cr, uid, ids, context=None):
"""
Compute the phases for scheduling.
"""
if context is None:
context = {}
phase_obj = self.pool.get('project.phase')
project_pool = self.pool.get('project.project')
data = self.read(cr, uid, ids, [], context=context)[0]
if not data['project_id'] and data['target_project'] == 'one':
raise osv.except_osv(_('Error!'), _('Please Specify Project to be schedule'))
if data['project_id']: # If project mentioned find its phases
project_id = data['project_id']
phase_ids = phase_obj.search(cr, uid, [('project_id', '=', project_id),
('state', 'in', ['draft', 'open', 'pending']),
('previous_phase_ids', '=', False)
])
project_ids = [data['project_id']]
else: # Else take all the draft,open,pending states phases
phase_ids = phase_obj.search(cr, uid,[('state', 'in', ['draft', 'open', 'pending']),
('previous_phase_ids', '=', False)
], context=context)
phase_ids.sort()
phases = phase_obj.browse(cr, uid, phase_ids, context=context)
for phase in phases:
start_date = phase.project_id.date_start
if not phase.project_id.date_start:
start_date = datetime.datetime.now().strftime("%Y-%m-%d")
start_dt = datetime.datetime.strftime((datetime.datetime.strptime(start_date, "%Y-%m-%d")), "%Y-%m-%d %H:%M")
calendar_id = phase.project_id.resource_calendar_id and phase.project_id.resource_calendar_id.id or False
self._phase_schedule(cr, uid, phase, start_dt, calendar_id, context=context)
project_ids = project_pool.search(cr, uid, [], context=context)
project_pool.schedule_phases(cr, uid, project_ids, context=context)
return self._open_phases_list(cr, uid, data, context=context)
def _open_phases_list(self, cr, uid, data, context=None):
@@ -173,10 +72,7 @@ class project_compute_phases(osv.osv_memory):
result = mod_obj._get_id(cr, uid, 'project_long_term', 'act_project_phase_list')
id = mod_obj.read(cr, uid, [result], ['res_id'])[0]['res_id']
result = act_obj.read(cr, uid, [id], context=context)[0]
result['domain'] = [('state', 'not in', ['cancelled','done'])]
if data['project_id']:
result['domain'] = [('project_id', '=', data['project_id']),
('state', 'not in', ['cancelled','done'])]
result['context'] = {"search_default_project_id":data['project_id'], "search_default_responsible_id":uid, "search_default_current": 1}
return result
project_compute_phases()
@@ -16,7 +16,7 @@
<group colspan="2" col="2">
</group>
<group colspan="2" col="2"> <!-- Improve me -->
<button icon="gtk-close" special="cancel" string="_Close"/>
<button icon="gtk-cancel" special="cancel" string="_Cancel"/>
<button icon="gtk-ok" name="check_selection" string="C_ompute" type="object"/>
</group>
</group>
@@ -20,14 +20,10 @@
##############################################################################
import datetime
from resource.faces import *
from new import classobj
import operator
from tools.translate import _
from osv import osv, fields
import working_calendar as wkcal
class project_compute_tasks(osv.osv_memory):
_name = 'project.compute.tasks'
@@ -40,108 +36,32 @@ class project_compute_tasks(osv.osv_memory):
"""
Schedule the tasks according to resource available and priority.
"""
project_obj = self.pool.get('project.project')
project_pool = self.pool.get('project.project')
task_pool = self.pool.get('project.task')
resource_obj = self.pool.get('resource.resource')
user_obj = self.pool.get('res.users')
if context is None:
context = {}
context['compute_by'] = 'project'
data = self.read(cr, uid, ids, [])[0]
project_id = data['project_id']
project = project_obj.browse(cr, uid, project_id, context=context)
task_ids = task_pool.search(cr, uid, [('project_id', '=', project_id),
('state', 'in', ['draft', 'open', 'pending'])
])
if task_ids:
task_ids.sort()
tasks = task_pool.browse(cr, uid, task_ids, context=context)
calendar_id = project.resource_calendar_id and project.resource_calendar_id.id or False
start_date = project.date_start
if not project.date_start:
start_date = datetime.datetime.now().strftime("%Y-%m-%d")
date_start = datetime.datetime.strftime(datetime.datetime.strptime(start_date, "%Y-%m-%d"), "%Y-%m-%d %H:%M")
# Create Resource Class objects which are the Project Members
resources = []
for user in project.members:
leaves = []
time_efficiency = 1.0
resource_id = resource_obj.search(cr, uid, [('user_id', '=', user.id)], context=context)
if resource_id:
# resource = resource_obj.browse(cr, uid, resource_id, context=context)[0]
resource = resource_obj.read(cr, uid, resource_id, ['calendar_id', 'time_efficiency'], context=context)[0]
if resource.get('calendar_id', False):
leaves = wkcal.compute_leaves(cr, uid, calendar_id , resource_id[0], resource['calendar_id'] and resource['calendar_id'][0] or False)
time_efficiency = resource.get('time_efficiency')
resources.append(classobj((user.name.encode('utf8')), (Resource,), {
'__doc__': user.name,
'__name__': user.name,
'vacation': tuple(leaves),
'efficiency': time_efficiency
}))
priority_dict = {'0': 1000, '1': 800, '2': 500, '3': 300,'4': 100}
# Create dynamic no of tasks with the resource specified
def create_tasks(j, eff, priorty=500, obj=None):
def task():
"""
task is a dynamic method!
"""
effort = eff
if obj:
resource = obj
priority = priorty
task.__doc__ = "TaskNO%d" %j
task.__name__ = "task%d" %j
return task
project_pool.schedule_tasks(cr, uid, [project_id], context=context)
return self._open_task_list(cr, uid, data, context=context)
# Create a 'Faces' project with all the tasks and resources
def Project():
title = project.name
start = date_start
try:
resource = reduce(operator.or_, resources)
except:
raise osv.except_osv(_('Error'), _('Project must have members assigned !'))
minimum_time_unit = 1
if calendar_id: # If project has calendar
working_days = wkcal.compute_working_calendar(cr, uid, calendar_id)
vacation = tuple(wkcal.compute_leaves(cr, uid, calendar_id))
# Dynamic Creation of tasks
i = 0
for each_task in tasks:
hours = str(each_task.planned_hours )+ 'H'
if each_task.priority in priority_dict.keys():
priorty = priority_dict[each_task.priority]
rcre = False
if each_task.user_id:
for resrce in resources:
if resrce.__name__ == each_task.user_id.name: # check me!!
rcre = resrce
break
task = create_tasks(i, hours, priorty, rcre)
i += 1
project = BalancedProject(Project)
loop_no = 0
# Write back the computed dates
for t in project:
s_date = t.start.to_datetime()
e_date = t.end.to_datetime()
if loop_no == 0:
project_obj.write(cr, uid, [project_id], {'date': e_date}, context=context)
else:
ctx = context.copy()
ctx.update({'scheduler': True})
user_id = user_obj.search(cr, uid, [('name', '=', t.booked_resource[0].__name__)])
task_pool.write(cr, uid, [tasks[loop_no-1].id], {
'date_start': s_date.strftime('%Y-%m-%d %H:%M:%S'),
'date_end': e_date.strftime('%Y-%m-%d %H:%M:%S'),
'user_id': user_id[0]
}, context=ctx)
loop_no +=1
return {}
def _open_task_list(self, cr, uid, data, context=None):
"""
Return the scheduled task list.
"""
if context is None:
context = {}
mod_obj = self.pool.get('ir.model.data')
act_obj = self.pool.get('ir.actions.act_window')
result = mod_obj._get_id(cr, uid, 'project', 'action_view_task')
id = mod_obj.read(cr, uid, [result], ['res_id'])[0]['res_id']
result = {}
if not id:
return result
result = act_obj.read(cr, uid, [id], context=context)[0]
result['context'] = {"search_default_project_id":data['project_id'], "search_default_user_id":uid, "search_default_current": 1}
return result
project_compute_tasks()
@@ -9,13 +9,13 @@
<field name="arch" type="xml">
<form string="Compute Scheduling of Task">
<group colspan="4">
<separator colspan="4" string="Compute Scheduling of Task for specified project." />
<separator colspan="4" string="Compute Scheduling of Task for specified project." />
<field name="project_id" widget="selection" colspan="4"/>
<separator colspan="4"/>
<group colspan="2" col="2">
</group>
<group colspan="2" col="2">
<button icon="gtk-close" special="cancel" string="_Close"/>
<button icon="gtk-cancel" special="cancel" string="_Cancel"/>
<button icon="gtk-ok" name="compute_date" string="C_ompute" type="object"/>
</group>
</group>
@@ -20,17 +20,9 @@
##############################################################################
import datetime
from resource.faces import *
from new import classobj
import operator
from tools.translate import _
from osv import osv, fields
import working_calendar as wkcal
from osv import fields, osv
class project_schedule_task(osv.osv_memory):
_name = "project.schedule.tasks"
_description = 'project.schedule.tasks'
_columns = {
@@ -46,126 +38,17 @@ class project_schedule_task(osv.osv_memory):
res = super(project_schedule_task, self).default_get(cr, uid, fields_list, context)
self.compute_date(cr, uid, context=context)
return res
def create_resources(self, cr, uid, phase, context=None):
"""
Return a list of Resource Class objects for the resources allocated to the phase.
"""
resource_objs = []
if context is None:
context = {}
for resource in phase.resource_ids:
res = resource.resource_id
leaves = []
resource_eff = res.time_efficiency
resource_cal = res.calendar_id.id
if resource_cal:
cal_id = phase.project_id.resource_calendar_id and phase.project_id.resource_calendar_id.id or False
leaves = wkcal.compute_leaves(cr, uid, cal_id, res.id, resource_cal, context=context)
resource_objs.append(classobj(res.user_id.name.encode('utf8'), (Resource,),{
'__doc__': res.user_id.name,
'__name__': res.user_id.name,
'vacation': tuple(leaves),
'efficiency': resource_eff,
}))
return resource_objs
def compute_date(self, cr, uid, context=None):
"""
Schedule the tasks according to resource available and priority.
"""
phase_obj = self.pool.get('project.phase')
task_obj = self.pool.get('project.task')
user_obj = self.pool.get('res.users')
phase_pool = self.pool.get('project.phase')
if context is None:
# It makes no sense to continue on empty context
return { 'warning': _("You must select some project phase to compute on")}
context = {}
if not 'active_id' in context:
return {}
phase = phase_obj.browse(cr, uid, context['active_id'], context=context)
task_ids = map(lambda x : x.id, (filter(lambda x : x.state in ['open', 'draft', 'pending'] , phase.task_ids)))
if task_ids:
task_ids.sort()
tasks = task_obj.browse(cr, uid, task_ids, context=context)
start_date = str(phase.date_start)
if not phase.date_start:
if not phase.project_id.date_start:
start_date = datetime.datetime.now().strftime("%Y-%m-%d")
else:
start_date = phase.project_id.date_start
date_start = datetime.datetime.strftime(datetime.datetime.strptime(start_date, "%Y-%m-%d"), "%Y-%m-%d %H:%M")
calendar_id = phase.project_id.resource_calendar_id.id
resources = self.create_resources(cr, uid, phase)
priority_dict = {'0': 1000, '1': 800, '2': 500, '3': 300, '4': 100}
# Create dynamic no of tasks with the resource specified
def create_tasks(j, eff, priorty=500, obj=False):
def task():
"""
task is a dynamic method!
"""
effort = eff
if obj:
resource = obj
priority = priorty
task.__doc__ = "TaskNO%d" %j
task.__name__ = "task%d" %j
return task
# Create a 'Faces' project with all the tasks and resources
def Project():
title = "Project"
start = date_start
try:
resource = reduce(operator.or_, resources)
except:
raise osv.except_osv(_('Error'), _('Phase must have resources assigned !'))
minimum_time_unit = 1
if calendar_id: # If project has working calendar
working_days = wkcal.compute_working_calendar(cr, uid, calendar_id)
vacation = tuple(wkcal.compute_leaves(cr, uid, calendar_id))
# Dynamic creation of tasks
i = 0
for each_task in tasks:
hours = str(each_task.planned_hours )+ 'H'
if each_task.priority in priority_dict.keys():
priorty = priority_dict[each_task.priority]
resc = False
if each_task.user_id:
for resrce in resources:
if resrce.__name__ == each_task.user_id.name:
resc = resrce
break
task = create_tasks(i, hours, priorty, resc)
i += 1
project = BalancedProject(Project)
loop_no = 0
# Write back the computed dates
for t in project:
s_date = t.start.to_datetime()
e_date = t.end.to_datetime()
if loop_no > 0:
ctx = context.copy()
ctx.update({'scheduler': True})
user_id = user_obj.search(cr, uid, [('name', '=', t.booked_resource[0].__name__)])
task_obj.write(cr, uid, [tasks[loop_no-1].id], {
'date_start': s_date.strftime('%Y-%m-%d %H:%M:%S'),
'date_end': e_date.strftime('%Y-%m-%d %H:%M:%S'),
'user_id': user_id[0]
}, context=ctx)
loop_no += 1
else:
return {"warning": _("No tasks to compute for this phase") }
return {}
return phase_pool.schedule_tasks(cr, uid, [context['active_id']], context=context)
project_schedule_task()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -1,124 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
# 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 <http://www.gnu.org/licenses/>.
#
##############################################################################
import datetime
import pooler
def convert_timeformat(cr, uid, time_string, context=None):
if context is None:
context = {}
""" Convert input time string: 8.5 to output time string 8:30."""
split_list = str(time_string).split('.')
hour_part = split_list[0]
mins_part = split_list[1]
round_mins = int(round(float(mins_part) * 60,-2))
converted_string = hour_part + ':' + str(round_mins)[0:2]
return converted_string
def compute_leaves(cr, uid, calendar_id, resource_id=False, resource_calendar=False, context=None):
if context is None:
context = {}
"""Compute the leaves from the working calendar of the resource.
Arguements: calendar_id -- working calendar of the project
resource_id -- resource working on phase/task
resource_calendar -- working calendar of the resource
"""
pool = pooler.get_pool(cr.dbname)
resource_calendar_leaves_obj = pool.get('resource.calendar.leaves')
leave_list = []
if resource_id:
leave_ids = resource_calendar_leaves_obj.search(cr, uid, ['|', ('calendar_id', '=', calendar_id),
('calendar_id', '=', resource_calendar),
('resource_id', '=', resource_id)
], context=context)
else:
leave_ids = resource_calendar_leaves_obj.search(cr, uid, [('calendar_id', '=', calendar_id),
('resource_id', '=', False)
], context=context)
leaves = resource_calendar_leaves_obj.read(cr, uid, leave_ids, ['date_from', 'date_to'], context=context)
for i in range(len(leaves)):
dt_start = datetime.datetime.strptime(leaves[i]['date_from'], '%Y-%m-%d %H:%M:%S')
dt_end = datetime.datetime.strptime(leaves[i]['date_to'], '%Y-%m-%d %H:%M:%S')
no = dt_end - dt_start
[leave_list.append((dt_start + datetime.timedelta(days=x)).strftime('%Y-%m-%d')) for x in range(int(no.days + 1))]
leave_list.sort()
return leave_list
def compute_working_calendar(cr, uid, calendar_id, context=None):
if context is None:
context = {}
"""Change the format of working calendar from 'Openerp' format to bring it into 'Faces' format.
Arguement: calendar_id -- working calendar of the project
"""
pool = pooler.get_pool(cr.dbname)
resource_attendance_obj = pool.get('resource.calendar.attendance')
time_range = "8:00-8:00"
non_working = ""
week_days = {"0": "mon", "1": "tue", "2": "wed","3": "thu", "4": "fri", "5": "sat", "6": "sun"}
wk_days = {}
wk_time = {}
wktime_list = []
wktime_cal = []
week_ids = resource_attendance_obj.search(cr, uid, [('calendar_id', '=', calendar_id)], context=context)
weeks = resource_attendance_obj.read(cr, uid, week_ids, ['dayofweek', 'hour_from', 'hour_to'], context=context)
# Convert time formats into appropriate format required
# and create a list like [('mon', '8:00-12:00'), ('mon', '13:00-18:00')]
for week in weeks:
res_str = ""
if week_days.has_key(week['dayofweek']):
day = week_days[week['dayofweek']]
wk_days[week['dayofweek']] = week_days[week['dayofweek']]
hour_from_str = convert_timeformat(cr, uid, week['hour_from'])
hour_to_str = convert_timeformat(cr, uid, week['hour_to'])
res_str = hour_from_str + '-' + hour_to_str
wktime_list.append((day, res_str))
# Convert into format like [('mon', '8:00-12:00', '13:00-18:00')]
for item in wktime_list:
if wk_time.has_key(item[0]):
wk_time[item[0]].append(item[1])
else:
wk_time[item[0]] = [item[0]]
wk_time[item[0]].append(item[1])
for k,v in wk_time.items():
wktime_cal.append(tuple(v))
# Add for the non-working days like: [('sat, sun', '8:00-8:00')]
for k, v in wk_days.items():
if week_days.has_key(k):
week_days.pop(k)
for v in week_days.itervalues():
non_working += v + ','
if non_working:
wktime_cal.append((non_working[:-1], time_range))
return wktime_cal
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -8,9 +8,9 @@
<field name="inherit_id" ref="project.view_task_form2"/>
<field name="arch" type="xml">
<xpath expr="/form/notebook/page[@string='Extra Info']" position="before">
<page string="Communication History">
<page string="History">
<field name="message_ids" colspan="4" nolabel="1" mode="tree,form">
<tree string="Communication history">
<tree string="History">
<field name="display_text" string="History Information"/>
</tree>
<form string="History">
@@ -29,7 +29,7 @@
</xpath>
</field>
</record>
<record id="view_project_message_form" model="ir.ui.view">
<field name="name">project.messages.form</field>
<field name="model">project.messages</field>
@@ -48,7 +48,7 @@
</form>
</field>
</record>
<record id="view_project_message_tree" model="ir.ui.view">
<field name="name">project.messages.tree</field>
<field name="model">project.messages</field>
@@ -61,7 +61,7 @@
</tree>
</field>
</record>
<record id="view_project_messages_search" model="ir.ui.view">
<field name="name">project.messages.search</field>
<field name="model">project.messages</field>
@@ -72,17 +72,19 @@
<field name="project_id"/>
<field name="from_id"/>
<field name="to_id"/>
<field name="message"/>
</group>
<newline/>
<group expand="0" string="Group By..." colspan="4" col="20">
<filter string="Project" icon="terp-folder-blue" domain="[]" context="{'group_by':'project_id'}"/>
<filter string="Message To" icon="terp-personal" domain="[]" context="{'group_by':'to_id'}"/>
<filter string="Message From" icon="terp-personal" domain="[]" context="{'group_by':'from_id'}"/>
<separator orientation="vertical"/>
<filter string="Project" icon="terp-folder-blue" domain="[]" context="{'group_by':'project_id'}"/>
</group>
</search>
</field>
</record>
<record id="messages_form" model="ir.actions.act_window">
<field name="name">Communication Messages</field>
<field name="res_model">project.messages</field>
@@ -90,11 +92,11 @@
<field name="search_view_id" ref="view_project_messages_search"/>
<field name="context">{"search_default_to_id":uid}</field>
<field name="view_id" ref="view_project_message_tree"/>
<field name="help">An in-project messagery system permits an efficient and trackable communication between project members. The messages are kept in the system and can then be used for post-analysis.</field>
<field name="help">An in-project messagery system permits an efficient and trackable communication between project members. The messages are kept in the system and can then be used for post-analysis.</field>
</record>
<act_window domain="[('project_id', '=', active_id)]" id="act_project_messages" name="Messages" res_model="project.messages" src_model="project.project"/>
<act_window context="{'search_default_project_id': [active_id]}" id="act_project_messages" name="Messages" res_model="project.messages" src_model="project.project"/>
<!--Actions for deshboard -->
<record id="action_view_project_editable_messages_tree" model="ir.actions.act_window">
@@ -1,2 +1,3 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"access_project_messages","project.messages","model_project_messages",project.group_project_user,1,1,1,1
"access_project_messages","project.messages","model_project_messages","project.group_project_user",1,1,1,1
"access_project_messages_manager","project.messages manager","model_project_messages","project.group_project_manager",1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_project_messages project.messages model_project_messages project.group_project_user 1 1 1 1
3 access_project_messages_manager project.messages manager model_project_messages project.group_project_manager 1 1 1 1
+3 -3
View File
@@ -53,10 +53,10 @@
'security/ir.model.access.csv',
'project_scrum_report.xml',
'wizard/project_scrum_backlog_create_task_view.xml',
'project_scrum_view.xml',
'process/project_scrum_process.xml',
'wizard/project_scrum_backlog_sprint_view.xml',
'wizard/project_scrum_backlog_merger_view.xml',
'project_scrum_view.xml',
'wizard/project_scrum_backlog_sprint_view.xml',
'process/project_scrum_process.xml',
"board_project_scrum_view.xml",
],
'demo_xml': ['project_scrum_demo.xml'],
+7 -5
View File
@@ -162,10 +162,11 @@ class project_scrum_product_backlog(osv.osv):
args=[]
if not context:
context={}
match = re.match('^S\(([0-9]+)\)$', name)
if match:
ids = self.search(cr, uid, [('sprint_id','=', int(match.group(1)))], limit=limit, context=context)
return self.name_get(cr, uid, ids, context=context)
if name:
match = re.match('^S\(([0-9]+)\)$', name)
if match:
ids = self.search(cr, uid, [('sprint_id','=', int(match.group(1)))], limit=limit, context=context)
return self.name_get(cr, uid, ids, context=context)
return super(project_scrum_product_backlog, self).name_search(cr, uid, name, args, operator,context, limit=limit)
def _compute(self, cr, uid, ids, fields, arg, context=None):
@@ -318,7 +319,8 @@ class project_scrum_meeting(osv.osv):
'question_today': fields.text('Tasks for today'),
'question_blocks': fields.text('Blocks encountered'),
'question_backlog': fields.text('Backlog Accurate'),
'task_ids': fields.many2many('project.task', 'meeting_task_rel', 'metting_id', 'task_id', 'Tasks')
'task_ids': fields.many2many('project.task', 'meeting_task_rel', 'metting_id', 'task_id', 'Tasks'),
'user_id': fields.related('sprint_id', 'scrum_master_id', type='many2one', relation='res.users', string='Responsible', readonly=True),
}
#
# TODO: Find the right sprint thanks to users and date
+83 -44
View File
@@ -40,13 +40,14 @@
<field name="sprint_id"/>
<field name="user_id"/>
<field name="progress" widget="progressbar"/>
<field name="expected_hours" sum="Planned hours" widget="float_time"/>
<field name="effective_hours" sum="Effective hours" widget="float_time"/>
<field name="expected_hours" sum="Planned hours" widget="float_time" string="Total Planned Hours"/>
<field name="effective_hours" sum="Effective hours" widget="float_time" string="Total Spent Hours"/>
<field name="state"/>
<button type="object" string="Open" name="button_open" states="draft,pending" icon="gtk-execute"/>
<button type="object" string="Open" name="button_open" states="draft,pending" icon="terp-camera_test"/>
<button type="object" string="Pending" name="button_pending" states="open" icon="gtk-media-pause"/>
<button type="action" string="Convert to Task" name="%(action_scrum_backlog_to_task)d" states="pending" icon="gtk-execute"/>
<button type="object" string="Close" name="button_close" states="open,pending" icon="gtk-jump-to"/>
<button type="action" string="Convert to Task" name="%(action_scrum_backlog_to_task)d" states="pending" icon="terp-stock_effects-object-colorize"/>
<button type="action" string="Merge Backlogs" name="%(action_scrum_backlog_merge)d" states="pending" icon="terp-stock_effects-object-colorize"/>
<button type="object" string="Close" name="button_close" states="open,pending" icon="terp-dialog-close"/>
</tree>
</field>
</record>
@@ -102,22 +103,22 @@
help="Change Type"/>
<field name="progress" widget="progressbar" invisible="context.get('set_visible',False)"/>
<field name="state" invisible="context.get('set_visible',False)"/>
<button name="do_open" states="pending,draft,done,cancel" string="Start Task" type="object" icon="gtk-execute" help="For changing to open state" invisible="context.get('set_visible',False)"/>
<button groups="base.group_extended" name="%(project.action_project_task_delegate)d" states="pending,open,draft" string="Delegate" type="action" icon="gtk-execute" help="For changing to delegate state"/>
<button name="do_open" states="pending,draft,done,cancel" string="Start Task" type="object" icon="terp-camera_test" help="For changing to open state" invisible="context.get('set_visible',False)"/>
<button groups="base.group_extended" name="%(project.action_project_task_delegate)d" states="pending,open,draft" string="Delegate" type="action" icon="gtk-sort-descending" help="For changing to delegate state"/>
<button name="do_close" states="draft,pending,open" string="Done" type="object" icon="gtk-jump-to" help="For changing to done state"/>
<button name="do_cancel" states="draft,open,pending" string="Cancel" type="object" icon="gtk-cancel" help="For cancelling the task"/>
<button name="do_cancel" states="draft,open,pending" string="Cancel" type="object" icon="gtk-stop" help="For cancelling the task"/>
</tree>
</field>
</page>
</notebook>
<group col="8" colspan="4">
<field name="state" select="1" readonly="1"/>
<button type="object" string="Open" name="button_open" states="draft,pending" icon="gtk-jump-to"/>
<button type="object" string="Open" name="button_open" states="draft,pending" icon="terp-camera_test"/>
<button type="action" string="Convert to Task" name="%(action_scrum_backlog_to_task)d" states="pending" icon="gtk-execute"/>
<button type="object" string="Pending" name="button_pending" states="open" icon="gtk-media-pause"/>
<button type="object" string="Close" name="button_close" states="open,pending" icon="gtk-jump-to"/>
<button type="object" string="Close" name="button_close" states="open,pending" icon="terp-dialog-close"/>
<button type="object" string="Set to Draft" name="button_draft" states="cancel,done" icon="gtk-convert"/>
<button type="object" string="Cancel" name="button_cancel" states="open,pending" icon="gtk-cancel"/>
<button type="object" string="Cancel" name="button_cancel" states="open,pending" icon="gtk-stop"/>
</group>
</form>
</field>
@@ -135,25 +136,27 @@
string="Current"
name="current"
domain="['|','&amp;',('sprint_id.date_start','&lt;=',time.strftime('%%Y-%%m-%%d')), ('sprint_id.date_stop','&gt;=',time.strftime('%%Y-%%m-%%d')), ('state','in',['draft','open','pending'])]"
help="Current Backlogs"/>
help="Draft, Open and Pending Backlogs"/>
<separator orientation="vertical"/>
<filter icon="terp-document-new" string="Draft" domain="[('state','=','draft')]" help="Draft Backlogs"/>
<filter icon="terp-camera_test" string="Open" domain="[('state','=','open')]" help="Open Backlogs"/>
<filter icon="terp-gtk-media-pause" string="Pending" domain="[('state','=','pending')]" help="Pending Backlogs"/>
<separator orientation="vertical"/>
<filter string="Editable" icon="terp-folder-blue" domain="[]" context="{'set_editable':'1'}"/>
<separator orientation="vertical"/>
<field name="name"/>
<field name="project_id"/>
<field name="sprint_id" domain="[('state','in',('draft','open'))]">
<filter icon="terp-project"
<filter icon="terp-check"
string="Sprints"
domain="[('sprint_id.state','=','open')]"
help="Backlogs Assigned To Current Sprints"/>
<filter icon="terp-project"
<filter icon="terp-personal-"
string="Sprints"
domain="[('sprint_id','=',False)]"
help="Backlogs Not Assigned To Sprints."/>
</field>
<field name="user_id">
<filter icon="terp-project"
<filter icon="terp-personal"
string="My Backlogs"
name="my_user_id"
domain="[('user_id','=',uid)]"
@@ -162,15 +165,13 @@
</group>
<newline/>
<group expand="0" string="Group By..." colspan="4" col="20" groups="base.group_extended">
<filter string="Author" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>
<separator orientation="vertical"/>
<filter string="Project" icon="terp-folder-blue" domain="[]" context="{'group_by':'project_id'}"/>
<filter string="Sprint" icon="terp-gtk-jump-to-ltr" domain="[]" context="{'group_by':'sprint_id'}"/>
<filter string="Responsible" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>
<separator orientation="vertical"/>
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
</group>
<newline/>
<group expand="0" string="Extended Options..." colspan="4" col="20" groups="base.group_extended">
<filter string="Editable" icon="terp-folder-blue" domain="[]" context="{'set_editable':'1'}"/>
</group>
</search>
</field>
</record>
@@ -179,7 +180,7 @@
<field name="name">Product Backlogs</field>
<field name="res_model">project.scrum.product.backlog</field>
<field name="view_type">form</field>
<field name="context">{'search_default_current': 1}</field>
<field name="context">{'search_default_current': 1,'search_default_user_id':uid,'search_default_project_id':project_id}</field>
<field name="search_view_id" ref="view_scrum_product_backlog_search"/>
</record>
<menuitem
@@ -197,7 +198,7 @@
<field name="model">project.scrum.sprint</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree colors="blue:state in ('pending');grey:state in ('cancel','done')" string="Scrum Sprint">
<tree colors="blue:state in ('draft','pending');grey:state in ('cancel','done')" string="Scrum Sprint">
<field name="name"/>
<field name="project_id"/>
<field name="scrum_master_id"/>
@@ -207,9 +208,9 @@
<field name="effective_hours" sum="Effective hours" widget="float_time"/>
<field name="expected_hours" sum="Planned hours" widget="float_time"/>
<field name="state"/>
<button type="object" string="Open" name="button_open" states="draft,pending" icon="gtk-execute"/>
<button type="object" string="Open" name="button_open" states="draft,pending" icon="terp-camera_test"/>
<button type="object" string="Pending" name="button_pending" states="open" icon="gtk-media-pause"/>
<button type="object" string="Close" name="button_close" states="open,pending" icon="gtk-jump-to"/>
<button type="object" string="Close" name="button_close" states="open,pending" icon="terp-dialog-close"/>
<button type="object" string="Set to Draft" name="button_draft" states="cancel,done" icon="gtk-convert"/>
</tree>
</field>
@@ -227,7 +228,7 @@
<notebook colspan="4">
<page string="Sprint Info">
<group colspan="2" col="2">
<separator string="Owners" colspan="2"/>
<separator string="Responsible" colspan="2"/>
<field name="product_owner_id"/>
<field name="scrum_master_id"/>
</group>
@@ -244,7 +245,39 @@
</group>
</page>
<page string="Daily Meetings">
<field colspan="4" name="meeting_ids" nolabel="1" widget="one2many_list"/>
<field colspan="4" name="meeting_ids" nolabel="1" widget="one2many_list">
<form string="Scrum Sprint">
<group colspan="4" col="6">
<field name="date"/>
<field name="user_id"/>
</group>
<notebook colspan="4">
<page string="Scrum Meeting">
<separator colspan="4" string="What did you do since the last meeting?"/>
<field colspan="4" name="question_yesterday" nolabel="1"/>
<separator colspan="4" string="What do you plan to do till the next meeting?"/>
<field colspan="4" name="question_today" nolabel="1"/>
<separator colspan="4" string="Are there anything blocking you?"/>
<field colspan="4" name="question_blocks" nolabel="1"/>
<separator colspan="4" string=""/>
<button name="button_send_to_master" type="object" string="Send to Scrum Master" icon="gtk-ok"/>
<button name="button_send_product_owner" type="object" string="Send to Product Owner" icon="gtk-ok"/>
</page>
<page string="Optional Info">
<separator colspan="4" string="Are your Sprint Backlog estimate accurate ?"/>
<field colspan="4" name="question_backlog" nolabel="1"/>
</page>
<page string="Links">
<separator colspan="4" string="Tasks"/>
<field colspan="4" name="task_ids" nolabel="1" domain="[('sprint_id','=',sprint_id)]"/>
</page>
</notebook>
</form>
<tree string="Scrum Meeting">
<field name="date"/>
<field name="user_id"/>
</tree>
</field>
</page>
<page string="Review">
<field colspan="4" name="review" nolabel="1"/>
@@ -255,9 +288,9 @@
</notebook>
<group col="6" colspan="4">
<field name="state" readonly="1"/>
<button type="object" string="Open" name="button_open" states="draft,pending" icon="gtk-jump-to"/>
<button type="object" string="Open" name="button_open" states="draft,pending" icon="terp-camera_test"/>
<button type="object" string="Pending" name="button_pending" states="open" icon="gtk-media-pause"/>
<button type="object" string="Close" name="button_close" states="open,pending" icon="gtk-jump-to"/>
<button type="object" string="Close" name="button_close" states="open,pending" icon="terp-dialog-close"/>
<button type="object" string="Set to Draft" name="button_draft" states="cancel,done" icon="gtk-convert"/>
</group>
</form>
@@ -273,8 +306,8 @@
<group col="10" colspan="4">
<filter name="terp-check" icon="terp-check" string="Current" domain="[('state','in',('draft','open'))]" help="Draft and open Sprints"/>
<separator orientation="vertical"/>
<filter icon="terp-document-new" string="Draft" domain="[('state','=','draft')]" help="Draft Sprints"/>
<filter icon="terp-camera_test" string="Open" domain="[('state','=','open')]" help="Open Sprints"/>
<filter icon="gtk-media-pause" string="Pending" domain="[('state','=','pending')]" help="Pending Sprints"/>
<separator orientation="vertical"/>
<field name="name"/>
<field name="project_id"/>
@@ -283,12 +316,14 @@
</group>
<newline/>
<group expand="0" string="Group By..." colspan="4" col="20">
<filter string="Project" icon="terp-folder-blue" domain="[]" context="{'group_by':'project_id'}"/>
<filter string="Managers" icon="terp-personal" domain="[]" context="{'group_by':'scrum_master_id'}"/>
<filter string="Product owner" icon="terp-personal" domain="[]" context="{'group_by':'product_owner_id'}"/>
<filter string="Scrum Master" icon="terp-personal" domain="[]" context="{'group_by':'scrum_master_id'}"/>
<separator orientation="vertical"/>
<filter string="Project" icon="terp-folder-blue" domain="[]" context="{'group_by':'project_id'}"/>
<separator orientation="vertical"/>
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
<separator orientation="vertical"/>
<filter string="Start Date" icon="terp-gtk-jump-to-ltr" domain="[]" context="{'group_by':'date_start'}"/>
<filter string="Month" icon="terp-go-month" domain="[]" context="{'group_by':'date_start'}" help="Sprint Month"/>
</group>
</search>
</field>
@@ -304,7 +339,7 @@
<field name="search_view_id" ref="view_scrum_sprint_search"/>
</record>
<menuitem
sequence="30"
sequence="20"
action="action_sprint_all_tree" id="menu_action_sprint_all_tree" parent="menu_scrum"/>
<!--
@@ -316,9 +351,11 @@
<field name="model">project.scrum.meeting</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Scrum Sprint">
<tree string="Scrum Meeting">
<field name="date"/>
<field name="sprint_id"/>
<field name="project_id"/>
<field name="user_id"/>
</tree>
</field>
</record>
@@ -327,10 +364,11 @@
<field name="model">project.scrum.meeting</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Scrum Sprint">
<form string="Scrum Meeting">
<group colspan="4" col="6">
<field name="date"/>
<field name="sprint_id" domain="[('state', '=', 'open')]"/>
<field name="user_id"/>
</group>
<notebook colspan="4">
<page string="Scrum Meeting">
@@ -375,7 +413,8 @@
<newline/>
<group expand="0" string="Group By..." colspan="4" col="20">
<filter string="Sprint" icon="terp-gtk-jump-to-ltr" domain="[]" context="{'group_by':'sprint_id'}"/>
<filter string="Date" icon="terp-go-month" domain="[]" context="{'group_by':'date'}"/>
<separator orientation="vertical"/>
<filter string="Month" icon="terp-go-month" domain="[]" context="{'group_by':'date'}" help="Meeting Date"/>
</group>
</search>
</field>
@@ -386,10 +425,10 @@
<field name="res_model">project.scrum.meeting</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="context">{'search_default_scrum_daily':1}</field>
<field name="context">{'search_default_scrum_daily':1,'search_default_project_id':project_id}</field>
<field name="search_view_id" ref="view_scrum_meeting_search"/>
</record>
<menuitem sequence="20"
<menuitem sequence="30"
action="action_meeting_form" id="menu_action_meeting_form" parent="menu_scrum"/>
<!--
@@ -509,7 +548,7 @@
<field name="project_id" position="after">
<field name="sprint_id" context="{'sprint_invisible':False}">
<filter icon="terp-check" string="Current" context="{'sprint_invisible':False}" domain="[('sprint_id.state','in',('draft','open'))]" help="Current Sprints"/>
<filter icon="terp-check" string="Current" context="{'sprint_invisible':False}" domain="[]" help="View Sprints"/>
<filter icon="gtk-find" string="Current" context="{'sprint_invisible':False}" domain="[]" help="View Sprints"/>
</field>
</field>
</field>
@@ -521,16 +560,16 @@
<field name="type">search</field>
<field name="inherit_id" ref="project.view_task_search_form"/>
<field name="arch" type="xml">
<xpath expr="/search/group[@string='Group By...']/filter[@string='End Date']" position="after">
<xpath expr="/search/group[@string='Group By...']/filter[@string='Project']" position="after">
<separator orientation="vertical"/>
<filter string="Sprint" icon="terp-gtk-jump-to-ltr" domain="[]" context="{'group_by':'sprint_id'}"/>
<filter string="Backlog" icon="terp-gtk-jump-to-rtl" domain="[]" context="{'group_by':'product_backlog_id'}"/>
<separator orientation="vertical"/>
</xpath>
</field>
</record>
<act_window
domain="[('sprint_id', '=', active_id)]"
context="{'search_default_sprint_id': [active_id]}"
id="act_scrum_sprint_2_product_backlog"
name="Backlogs"
res_model="project.scrum.product.backlog"
@@ -539,7 +578,7 @@
view_type="form"/>
<act_window
domain="[('sprint_id', '=', active_id)]"
context="{'search_default_sprint_id': active_id, 'search_default_user_id': uid, 'search_default_current':1}"
id="act_scrum_sprint_2_project_task"
name="Tasks"
res_model="project.task"
@@ -14,8 +14,8 @@
<group col="2" colspan="2">
</group>
<group col="2" colspan="2">
<button special="cancel" string="_Close" icon='gtk-close'/>
<button name="do_create" string="Co_nvert" colspan="1" type="object" icon="gtk-execute"/>
<button special="cancel" string="_Cancel" icon='gtk-cancel'/>
<button name="do_create" string="C_onvert" colspan="1" type="object" icon="gtk-execute"/>
</group>
</form>
</field>
@@ -10,7 +10,7 @@
<separator string="Are you sure you want to merge these Backlogs?" colspan="4"/>
<label colspan="4" string="This wizard merge backlogs and create one new backlog with draft state (Old backlogs Will be deleted). And it also merge old tasks from backlogs" />
<separator colspan="4"/>
<button colspan="2" special="cancel" string="Close" icon="gtk-close"/>
<button colspan="2" special="cancel" string="Cancel" icon="gtk-cancel"/>
<button colspan="2" default_focus="1" name="check_backlogs" string="Merge" type="object" icon="gtk-execute"/>
</form>
</field>
@@ -16,7 +16,7 @@
<group col="2" colspan="2">
</group>
<group col="2" colspan="2">
<button special="cancel" string="_Close" icon='gtk-close'/>
<button special="cancel" string="_Cancel" icon='gtk-cancel'/>
<button name="assign_sprint" string="_Assign" colspan="1" type="object" icon="gtk-execute"/>
</group>
</form>
@@ -20,7 +20,7 @@
</separator>
<xpath expr="//label[@string='description']"
position="attributes">
<attribute name="string">Extend your Purchases Management Application with purchase requisition facility and analytic distribution of purchase orders.</attribute>
<attribute name="string">Extend your Purchases Management Application with additional functionalities.</attribute>
</xpath>
<xpath expr="//button[@string='Install Modules']" position="attributes">
<attribute name="string">Configure</attribute>
+4 -9
View File
@@ -26,17 +26,12 @@ class report_designer_installer(osv.osv_memory):
_columns = {
# Reporting
'base_report_designer':fields.boolean('OpenOffice Report Designer',help="This module adds wizards to import/export .SXW report that "
'base_report_designer':fields.boolean('OpenOffice Report Designer',help="Adds wizards to Import/Export .SXW report which "
"you can modify in OpenOffice.Once you have modified it you can "
"upload the report using the same wizard."),
'base_report_creator':fields.boolean('Query Builder',help="Query Builder allows you to create any statistic "
"reports on several objects. It's a SQL query builder and browser for and users. "
"After installation, it adds a menu to define custom report in the Dashboard menu."),
'olap':fields.boolean('Business Intelligence Report',help="Olap module is used to install BI module in client. Olap provides Online "
"Analytical Process with the mdx query. BI provides Cube Browsing and Cube Designing. "
"After installation you will get Cube Browser and Cube Designer in Reporting Menu. "
"Cube Browser is used to generate the reports with table view (mdx view) of mdx query "
"and Cube Designer is used to make cubes in BI."),
'base_report_creator':fields.boolean('Query Builder',help="Allows you to create any statistic "
"reports on several objects. It's a SQL query builder and browser for end users."),
'olap':fields.boolean('Business Intelligence Report',help="Helps you manage Online Analytical Process with the mdx query and provides Cube Designing and Cube Browsing"),
}
report_designer_installer()
+120 -10
View File
@@ -22,10 +22,11 @@
from datetime import datetime, timedelta
import time
import math
from faces import *
from new import classobj
from osv import fields, osv
from tools.translate import _
import tools
class resource_calendar(osv.osv):
_name = "resource.calendar"
_description = "Resource Calendar"
@@ -187,6 +188,14 @@ class resource_calendar_attendance(osv.osv):
_order = 'dayofweek, hour_from'
resource_calendar_attendance()
def convert_timeformat(time_string):
split_list = str(time_string).split('.')
hour_part = split_list[0]
mins_part = split_list[1]
round_mins = int(round(float(mins_part) * 60,-2))
converted_string = hour_part + ':' + str(round_mins)[0:2]
return converted_string
class resource_resource(osv.osv):
_name = "resource.resource"
_description = "Resource Detail"
@@ -207,17 +216,118 @@ class resource_resource(osv.osv):
'company_id': lambda self, cr, uid, context: self.pool.get('res.company')._company_default_get(cr, uid, 'resource.resource', context=context)
}
def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False):
def copy(self, cr, uid, id, default=None, context=None):
if default is None:
default = {}
if not default.get('name', False):
default['name'] = self.browse(cr, uid, id, context=context).name + _(' (copy)')
return super(resource_resource, self).copy(cr, uid, id, default, context)
def generate_resources(self, cr, uid, user_ids, calendar_id, context=None):
"""
Return a list of Resource Class objects for the resources allocated to the phase.
"""
if context is None:
context = {}
resource_objs = []
user_pool = self.pool.get('res.users')
for user in user_pool.browse(cr, uid, user_ids, context=context):
resource_ids = self.search(cr, uid, [('user_id', '=', user.id)], context=context)
#assert len(resource_ids) < 1, "User should not has more than one resources"
leaves = []
resource_eff = 1.0
if resource_ids:
resource_id = resource_ids[0]
resource = self.browse(cr, uid, resource_id, context=context)
resource_eff = resource.time_efficiency
resource_cal = resource.calendar_id.id
if resource_cal:
leaves = self.compute_vacation(cr, uid, calendar_id, resource.id, resource_cal, context=context)
resource_objs.append(classobj(str(user.name), (Resource,),{
'__doc__': user.name,
'__name__': user.name,
'vacation': tuple(leaves),
'efficiency': resource_eff,
}))
return resource_objs
if context.get('project_id',False):
project_pool = self.pool.get('project.project')
project_rec = project_pool.browse(cr, uid, context['project_id'])
user_ids = [user_id.id for user_id in project_rec.members]
args.append(('user_id','in',user_ids))
def compute_vacation(self, cr, uid, calendar_id, resource_id=False, resource_calendar=False, context=None):
"""
Compute the vacation from the working calendar of the resource.
@param calendar_id : working calendar of the project
@param resource_id : resource working on phase/task
@param resource_calendar : working calendar of the resource
"""
if context is None:
context = {}
resource_calendar_leaves_pool = self.pool.get('resource.calendar.leaves')
leave_list = []
if resource_id:
leave_ids = resource_calendar_leaves_pool.search(cr, uid, ['|', ('calendar_id', '=', calendar_id),
('calendar_id', '=', resource_calendar),
('resource_id', '=', resource_id)
], context=context)
else:
leave_ids = resource_calendar_leaves_pool.search(cr, uid, [('calendar_id', '=', calendar_id),
('resource_id', '=', False)
], context=context)
leaves = resource_calendar_leaves_pool.read(cr, uid, leave_ids, ['date_from', 'date_to'], context=context)
for i in range(len(leaves)):
dt_start = datetime.datetime.strptime(leaves[i]['date_from'], '%Y-%m-%d %H:%M:%S')
dt_end = datetime.datetime.strptime(leaves[i]['date_to'], '%Y-%m-%d %H:%M:%S')
no = dt_end - dt_start
[leave_list.append((dt_start + datetime.timedelta(days=x)).strftime('%Y-%m-%d')) for x in range(int(no.days + 1))]
leave_list.sort()
return leave_list
def compute_working_calendar(cr, uid, calendar_id, context=None):
"""
Change the format of working calendar from 'Openerp' format to bring it into 'Faces' format.
@param calendar_id : working calendar of the project
"""
if context is None:
context = {}
resource_attendance_pool = self.pool.get('resource.calendar.attendance')
time_range = "8:00-8:00"
non_working = ""
week_days = {"0": "mon", "1": "tue", "2": "wed","3": "thu", "4": "fri", "5": "sat", "6": "sun"}
wk_days = {}
wk_time = {}
wktime_list = []
wktime_cal = []
week_ids = resource_attendance_pool.search(cr, uid, [('calendar_id', '=', calendar_id)], context=context)
weeks = resource_attendance_pool.read(cr, uid, week_ids, ['dayofweek', 'hour_from', 'hour_to'], context=context)
# Convert time formats into appropriate format required
# and create a list like [('mon', '8:00-12:00'), ('mon', '13:00-18:00')]
for week in weeks:
res_str = ""
if week_days.has_key(week['dayofweek']):
day = week_days[week['dayofweek']]
wk_days[week['dayofweek']] = week_days[week['dayofweek']]
hour_from_str = convert_timeformat(cr, uid, week['hour_from'])
hour_to_str = convert_timeformat(cr, uid, week['hour_to'])
res_str = hour_from_str + '-' + hour_to_str
wktime_list.append((day, res_str))
# Convert into format like [('mon', '8:00-12:00', '13:00-18:00')]
for item in wktime_list:
if wk_time.has_key(item[0]):
wk_time[item[0]].append(item[1])
else:
wk_time[item[0]] = [item[0]]
wk_time[item[0]].append(item[1])
for k,v in wk_time.items():
wktime_cal.append(tuple(v))
# Add for the non-working days like: [('sat, sun', '8:00-8:00')]
for k, v in wk_days.items():
if week_days.has_key(k):
week_days.pop(k)
for v in week_days.itervalues():
non_working += v + ','
if non_working:
wktime_cal.append((non_working[:-1], time_range))
return wktime_cal
return super(resource_resource, self).search(cr, uid, args, offset, limit, order, context, count)
resource_resource()
class resource_calendar_leaves(osv.osv):
@@ -253,4 +363,4 @@ class resource_calendar_leaves(osv.osv):
resource_calendar_leaves()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+18 -15
View File
@@ -21,9 +21,9 @@
<filter string="User" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>
<separator orientation="vertical"/>
<filter string="Type" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by':'resource_type'}"/>
<separator orientation="vertical"/>
<filter string="Company" icon="terp-go-home" domain="[]" context="{'group_by':'company_id'}" groups="base.group_multi_company"/>
<separator orientation="vertical" groups="base.group_multi_company"/>
<filter string="Company" icon="terp-go-home" domain="[]" context="{'group_by':'company_id'}" groups="base.group_multi_company"/>
<separator orientation="vertical" />
<filter string="Working Time" icon="terp-go-today" domain="[]" context="{'group_by':'calendar_id'}"/>
</group>
</search>
@@ -41,10 +41,6 @@
<field name="manager"/>
<field name="company_id" widget="selection" groups="base.group_multi_company"/>
</group>
<newline/>
<group expand="0" string="Group By..." colspan="4" col="20">
<filter string="Manager" icon="terp-personal" domain="[]" context="{'group_by':'manager'}"/>
</group>
</search>
</field>
</record>
@@ -56,7 +52,7 @@
<field name="arch" type="xml">
<search string="Search Working Period Leaves">
<group col='15' colspan='4'>
<field name="name" string="Name"/>
<field name="name" string="Reason"/>
<field name="resource_id" string="Resource"/>
<field name="company_id" string="Company" widget="selection" groups="base.group_multi_company"/>
<field name="calendar_id" string="Working Time" widget="selection"/>
@@ -214,13 +210,20 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Leave Detail">
<field name="name"/>
<field name="resource_id" on_change="onchange_resource(resource_id)"/>
<field name="company_id" widget="selection" groups="base.group_multi_company"/>
<field name="calendar_id" widget="selection"/>
<newline/>
<field name="date_from"/>
<field name="date_to"/>
<group colspan="4" col="6">
<group colspan="2" col="2">
<field name="resource_id" on_change="onchange_resource(resource_id)"/>
<field name="name" string="Reason"/>
</group>
<group colspan="2" col="2">
<field name="date_from"/>
<field name="calendar_id"/>
<field name="company_id" widget="selection" groups="base.group_multi_company"/>
</group>
<group colspan="2" col="2">
<field name="date_to"/>
</group>
</group>
</form>
</field>
</record>
@@ -230,7 +233,7 @@
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Leave Detail">
<field name="name" />
<field name="name" string="Reason"/>
<field name="resource_id" />
<field name="company_id" groups="base.group_multi_company"/>
<field name="calendar_id" />

Some files were not shown because too many files have changed in this diff Show More