bzr revid: hmo@tinyerp.com-20101013104406-byc7tlrbqrna2h7c
This commit is contained in:
Harry (OpenERP) 2010-10-13 16:14:06 +05:30
commit 896ebda0ae
23 changed files with 273 additions and 111 deletions

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!--
Invoices
-->
@ -434,6 +433,7 @@
<field name="help">Most of customer invoices are automatically generated in draft mode by OpenERP flows, following a purchase order for instance. Review, confirm or cancel, pay or refund your customers' invoices here. A manual invoice can be created here.</field>
</record>
<record id="action_invoice_tree1_view1" model="ir.actions.act_window.view">
<field eval="1" name="sequence"/>
<field name="view_mode">tree</field>
@ -446,6 +446,7 @@
<field name="view_id" ref="invoice_form"/>
<field name="act_window_id" ref="action_invoice_tree1"/>
</record>
<menuitem action="action_invoice_tree1" id="menu_action_invoice_tree1" parent="menu_finance_receivables"/>
<record id="action_invoice_tree2" model="ir.actions.act_window">

View File

@ -16,9 +16,7 @@
<action
string="New Files"
name="%(document.action_view_all_document_tree1)d"
view_mode="tree"
domain="[('name','=',time.strftime('%%Y')),('month','=',time.strftime('%%m'))]"/>
view_mode="tree,form"/>
<action
string="File Size by Month"
name="%(document.action_view_size_month)d"
@ -28,7 +26,8 @@
<action
string="Files by Resource Type"
name="%(document.action_view_document_by_resourcetype_graph)d"
view_mode="graph,tree"/>
view_mode="graph,tree"
/>
<action
string="Files by Partner"

View File

@ -41,7 +41,7 @@ class document_file(osv.osv):
fbrl = self.browse(cr, uid, ids, context=context)
nctx = nodes.get_node_context(cr, uid, context={})
# nctx will /not/ inherit the caller's context. Most of
# it would be useless, anyway (like active_id, active_model,
# it would be useless, anyway (like active_id, active_model,
# bin_size etc.)
result = {}
bin_size = context.get('bin_size', False)
@ -91,10 +91,11 @@ class document_file(osv.osv):
'company_id': fields.many2one('res.company', 'Company'),
'file_size': fields.integer('File Size', required=True),
'file_type': fields.char('Content Type', size=128),
# fields used for file storage
'store_fname': fields.char('Stored Filename', size=200),
}
_order = "create_date desc"
def __get_def_directory(self, cr, uid, context=None):
dirobj = self.pool.get('document.directory')
@ -150,7 +151,7 @@ class document_file(osv.osv):
return False
if not self._check_duplication(cr, uid, vals, ids, 'write'):
raise osv.except_osv(_('ValidateError'), _('File name must be unique!'))
# if nodes call this write(), they must skip the code below
from_node = context and context.get('__from_node', False)
if (('parent_id' in vals) or ('name' in vals)) and not from_node:

View File

@ -50,7 +50,6 @@ class document_directory(osv.osv):
],
'Type', required=True, select=1,
help="Each directory can either have the type Static or be linked to another resource. A static directory, as with Operating Systems, is the classic directory that can contain a set of files. The directories linked to systems resources automatically possess sub-directories for each of resource types defined in the parent directory."),
'ressource_type_id': fields.many2one('ir.model', 'Resource model',
help="Select an object here and there will be one folder per record of that resource."),
'resource_field': fields.many2one('ir.model.fields', 'Name field', help='Field to be used as name on resource directories. If empty, the "name" will be used.'),

View File

@ -292,7 +292,7 @@
<field name="parent_id" />
<field name="user_id">
<filter icon="terp-personal"
domain="[('user_id','=', False)]"
domain="[('user_id','=',uid)]"
help="Filter on my documents" />
</field>
<field name="partner_id"/>
@ -334,7 +334,7 @@
<field name="res_model">ir.attachment</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>
<field name="help">The Documents repository gives you access to all attachments, such as mails, project documents, invoices etc.</field>
</record>
<menuitem name="Documents" id="menu_document_doc" parent="knowledge.menu_document" sequence="0"/>
<menuitem

View File

@ -34,6 +34,7 @@ class report_document_user(osv.osv):
'user_id':fields.integer('Owner', readonly=True),
'user':fields.char('User',size=64,readonly=True),
'directory': fields.char('Directory',size=64,readonly=True),
'datas_fname': fields.char('File Name',size=64,readonly=True),
'create_date': fields.datetime('Date Created', readonly=True),
'change_date': fields.datetime('Modified Date', readonly=True),
'file_size': fields.integer('File Size', readonly=True),
@ -52,6 +53,7 @@ class report_document_user(osv.osv):
u.name as user,
count(*) as nbr,
d.name as directory,
f.datas_fname as datas_fname,
f.create_date as create_date,
f.file_size as file_size,
min(d.type) as type,
@ -59,11 +61,13 @@ class report_document_user(osv.osv):
FROM ir_attachment f
left join document_directory d on (f.parent_id=d.id and d.name<>'')
inner join res_users u on (f.user_id=u.id)
group by to_char(f.create_date, 'YYYY'), to_char(f.create_date, 'MM'),d.name,f.parent_id,d.type,f.create_date,f.user_id,f.file_size,u.name,d.type,f.write_date
group by to_char(f.create_date, 'YYYY'), to_char(f.create_date, 'MM'),d.name,f.parent_id,d.type,f.create_date,f.user_id,f.file_size,u.name,d.type,f.write_date,f.datas_fname
)
""")
report_document_user()
class report_files_partner(osv.osv):
_name = "report.files.partner"
_description = "Files details by Partners"
@ -86,7 +90,7 @@ class report_files_partner(osv.osv):
to_char(date_trunc('month', f.create_date),'MM') AS month,
SUM(f.file_size) AS file_size,
p.name AS partner
FROM ir_attachment f
LEFT JOIN res_partner p ON (f.partner_id=p.id)
WHERE f.datas_fname IS NOT NULL

View File

@ -10,6 +10,7 @@
<field name="name" select="1"/>
<field name="user" select="1"/>
<field name="directory" select="1"/>
<field name="datas_fname" select="1"/>
<field name="file_size"/>
<field name="create_date"/>
</form>
@ -25,10 +26,11 @@
<tree string="Files">
<field name="name" select="1"/>
<field name="month" select="1"/>
<field name="user" select="1"/>
<field name="directory" select="1"/>
<field name="file_size"/>
<field name="create_date"/>
<field name="user" select="1" invisible="1"/>
<field name="directory" select="1" invisible="1"/>
<field name="file_size" invisible="1"/>
<field name="create_date" invisible="1"/>
<field name="nbr"/>
</tree>
</field>
</record>
@ -60,8 +62,8 @@
<field name="name">All Users files</field>
<field name="res_model">report.document.user</field>
<field name="view_type">form</field>
<field name="view_mode">tree</field>
<field name="context">{'search_default_user': 'user_id'}</field>
<field name="view_mode">tree,form</field>
<field name="context">{'group_by': ['name','month']}</field>
<field name="search_view_id" ref="view_report_document_user_search"/>
</record>
@ -112,30 +114,18 @@
<field name="arch" type="xml">
<graph string="Files by Resource Type" type="pie">
<field name="type" />
<!-- <field name="file_size" operator="+"/>-->
<field name="nbr" operator="+"/>
</graph>
</field>
</record>
<!-- <record model="ir.ui.view" id="view_document_by_resourcetype_tree">-->
<!-- <field name="name">report.document.resource.tree.view</field>-->
<!-- <field name="model">report.document.user</field>-->
<!-- <field name="type">tree</field>-->
<!-- <field name="arch" type="xml">-->
<!-- <tree string="Files by Resource Type">-->
<!-- <field name="type" />-->
<!-- <field name="nbr"/>-->
<!-- </tree>-->
<!-- </field>-->
<!-- </record>-->
<record model="ir.actions.act_window" id="action_view_document_by_resourcetype_graph">
<field name="name">Files by Resource Type</field>
<field name="res_model">report.document.user</field>
<field name="view_id" ref="view_document_by_resourcetype_graph"></field>
<field name="view_id" ref="view_document_by_resourcetype_graph"/>
<field name="view_type">form</field>
<field name="view_mode">tree</field>
<field name="view_mode">graph,tree</field>
</record>
<!--***************************************************************************************-->
@ -150,7 +140,7 @@
<field name="file_size" operator="+"/>
</graph>
</field>
</record>
</record>
<record model="ir.ui.view" id="view_size_month_tree">
<field name="name">report.document.user.tree</field>

View File

@ -196,7 +196,7 @@
!python {model: ir.attachment}: |
from document_ftp import test_easyftp as te
ftp = te.get_ftp_folder(cr, uid, self, 'Documents')
ftp.mkd("Test-Folder2")
ftp.mkd("Test-Folder3")
# TODO move
-
I remove the 'Test-Folder3'

View File

@ -8,7 +8,7 @@
<field name="arch" type="xml">
<form string="Browse Document">
<separator string="Browse Document" colspan="4"/>
<field name="url" widget="url" colspan="4"/>
<field name="url" widget="url" colspan="4" width="250"/>
<separator colspan="4"/>
<group col="4" colspan="4">
<label string="" colspan="2"/>

View File

@ -30,7 +30,7 @@ class document_ftp_configuration(osv.osv_memory):
_rec_name = 'host'
_columns = {
'host': fields.char('Address', size=64,
help="Server address or IP and port to which users should connect to for DMS access",
help="Server address or IP and port to which users should connect to for DMS access",
required=True),
}

View File

@ -102,6 +102,7 @@
<menuitem id="menu_project_working_hours" parent="base.menu_project_management_time_tracking" action="act_hr_timesheet_line_evry1_all_form"/>
<menuitem id="menu_hr_working_hours" parent="hr_attendance.menu_hr_time_tracking" action="act_hr_timesheet_line_evry1_all_form"/>
<menuitem id="menu_partner_invc" parent="base.menu_project_management_time_tracking" action="account.action_invoice_tree1"/>
<record id="hr_timesheet_employee_extd_form" model="ir.ui.view">
<field name="name">hr.timesheet.employee.extd_form</field>

View File

@ -637,6 +637,7 @@ class task(osv.osv):
if context is None:
context = {}
request = self.pool.get('res.request')
for task in self.browse(cr, uid, ids, context=context):
project = task.project_id
if project and project.warn_manager and project.user_id.id and (project.user_id.id != uid):
@ -651,6 +652,7 @@ class task(osv.osv):
})
self.write(cr, uid, [task.id], {'state': 'open'})
return True
def do_cancel(self, cr, uid, ids, *args):

View File

@ -89,7 +89,7 @@ class report_project_task_user(osv.osv):
planned_hours as hours_planned,
(extract('epoch' from (t.date_end-t.create_date)))/(3600*24) as closing_days,
(extract('epoch' from (t.date_start-t.create_date)))/(3600*24) as opening_days,
(extract('epoch' from (t.date_deadline-t.date_end)))/(3600*24) as delay_endings_days
abs((extract('epoch' from (t.date_deadline-t.date_end)))/(3600*24)) as delay_endings_days
FROM project_task t
GROUP BY

View File

@ -254,6 +254,7 @@ class project_issue(crm.crm_case, osv.osv):
data_obj = self.pool.get('ir.model.data')
task_obj = self.pool.get('project.task')
if context is None:
context = {}
@ -297,6 +298,7 @@ class project_issue(crm.crm_case, osv.osv):
'nodestroy': True
}
def _convert(self, cr, uid, ids, xml_id, context=None):
data_obj = self.pool.get('ir.model.data')
id2 = data_obj._get_id(cr, uid, 'project_issue', xml_id)
@ -335,6 +337,7 @@ class project_issue(crm.crm_case, osv.osv):
self.write(cr, uid, task.id, {'type_id': index and types[index-1] or False})
return True
def onchange_task_id(self, cr, uid, ids, task_id, context=None):
if context is None:
context = {}

View File

@ -326,6 +326,19 @@
# Project
# ------------------------------------------------------
<record id="project.view_project_resource_form1" model="ir.ui.view">
<field name="name">Project Resource Calendar View</field>
<field name="model">project.project</field>
<field name="type">form</field>
<field name="inherit_id" ref="project.edit_project"/>
<field name="arch" type="xml">
<field name="priority" position="before">
<field name="resource_calendar_id"/>
</field>
</field>
</record>
<record id="view_project_form_inherited" model="ir.ui.view">
<field name="name">project.project.form.inherited</field>
<field name="model">project.project</field>
@ -333,7 +346,6 @@
<field name="inherit_id" ref="project.edit_project"/>
<field name="arch" type="xml">
<field name="priority" position="before">
<field name="resource_calendar_id"/>
<field name="project_escalation_id"/>
<field name="reply_to"/>
</field>

View File

@ -91,8 +91,8 @@ class project_phase(osv.osv):
model_data_obj = self.pool.get('ir.model.data')
model_data_id = model_data_obj._get_id(cr, uid, 'product', 'uom_hour')
return model_data_obj.read(cr, uid, [model_data_id], ['res_id'])[0]['res_id']
def _compute(self, cr, uid, ids,field_name, arg, context=None):
def _compute(self, cr, uid, ids, field_name, arg, context=None):
res = {}
if not ids:
return res
@ -143,7 +143,7 @@ class project_phase(osv.osv):
project_id = project_obj.browse(cr, uid, project, context=context)
result['date_start'] = project_id.date_start
return {'value': result}
def onchange_days(self, cr, uid, ids, project, context=None):
result = {}
for id in ids:
@ -219,7 +219,7 @@ class project_phase(osv.osv):
cal_id = resource_obj.browse(cr, uid, resource_id[0], context=context).calendar_id.id
if cal_id:
calendar_id = cal_id
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
@ -232,7 +232,7 @@ class project_phase(osv.osv):
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:
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)
@ -242,7 +242,7 @@ class project_phase(osv.osv):
if next_phase.id == phase.id:
continue
self._check_date_end(cr, uid, next_phase, dt_end, context=context)
return res
def copy(self, cr, uid, id, default=None, context=None):
@ -293,7 +293,7 @@ class project_phase(osv.osv):
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')
@ -304,7 +304,7 @@ class project_phase(osv.osv):
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'
@ -369,7 +369,7 @@ class project_phase(osv.osv):
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")
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)))
@ -396,7 +396,7 @@ class project_resource_allocation(osv.osv):
'user_id': fields.related('resource_id', 'user_id', type='many2one', relation="res.users", string='User'),
'date_start': fields.date('Start Date', help="Starting Date"),
'date_end': fields.date('End Date', help="Ending Date"),
'useability': fields.float('Usability', help="Usability of this resource for this project phase in percentage (=50%)"),
'useability': fields.float('Availability', help="Usability of this resource for this project phase in percentage (=50%)"),
}
_defaults = {
'useability': 100,
@ -458,19 +458,19 @@ class project(osv.osv):
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")
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)
@ -481,7 +481,7 @@ class project(osv.osv):
else:
return_msg["warning"] = return_msg["warning"] + "\n" + warning_msg
return return_msg
return return_msg
project()
@ -504,7 +504,7 @@ class project_task(osv.osv):
_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.
@ -554,10 +554,10 @@ class project_task(osv.osv):
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

View File

@ -81,9 +81,9 @@
</group>
<newline/>
<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'}"/>
<filter name="resource" string="Resource" icon="terp-personal" domain="[]" context="{'group_by':'resource_id'}"/>
<separator orientation="vertical"/>
<filter string="Project" icon="terp-project" domain="[]" context="{'group_by':'project_id'}"/>
<filter string="Project" icon="terp-folder-blue" domain="[]" context="{'group_by':'project_id'}"/>
<filter string="Phase" icon="terp-project" domain="[]" context="{'group_by':'phase_id'}"/>
</group>
</search>
@ -110,22 +110,18 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Project Phase">
<group colspan="8" col="7">
<group colspan="8">
<field name="name" select="1"/>
<field name="total_hours"/>
<field name="project_id" on_change="onchange_project(project_id)" colspan="2"/>
<field name="responsible_id" colspan="2"/>
</group>
<newline/>
<group colspan="2">
<field name="date_start"/>
<field name="date_end"/>
<group colspan="6" col="6">
<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="date_start"/>
<field name="duration" on_change="onchange_days(project_id)" />
<field name="product_uom" nolabel="1" domain="[('category_id.name', '=', 'Working Time')]"/>
<field name="date_end"/>
</group>
<group colspan="2">
<field name="duration" on_change="onchange_days(project_id)"/>
<field name="product_uom" nolabel="1" domain="[('category_id.name', '=', 'Working Time')]"/>
</group>
</group>
<notebook colspan="4">
<page string="Resource Allocation">
@ -275,7 +271,7 @@
</group>
<newline/>
<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="Responsible" icon="terp-personal" domain="[]" context="{'group_by':'responsible_id'}"/>
<separator orientation="vertical"/>
<filter string="Project" icon="terp-folder-blue" domain="[]" context="{'group_by':'project_id'}" name="project"/>
<separator orientation="vertical"/>
@ -292,7 +288,7 @@
<field name="res_model">project.phase</field>
<field name="view_type">form</field>
<field name="view_mode">gantt,tree,form,calendar</field>
<field name="context">{'search_default_responsible_id':uid}</field>
<field name="context">{'search_default_responsible_id':uid,'group_by':'project_id'}</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>
</record>
@ -302,7 +298,7 @@
<field name="res_model">project.phase</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,calendar</field>
<field name="context">{'search_default_responsible_id':uid}</field>
<field name="context">{'search_default_responsible_id':uid,'group_by':'project_id'}</field>
<field name="search_view_id" ref="view_project_phase_search"/>
</record>
@ -311,8 +307,8 @@
# Project
# ------------------------------------------------------
<record id="view_phase_project_form1" model="ir.ui.view">
<field name="name">phase.project.form1</field>
<record id="project.view_project_resource_form1" model="ir.ui.view">
<field name="name">Project Resource Calendar View</field>
<field name="model">project.project</field>
<field name="type">form</field>
<field name="inherit_id" ref="project.edit_project"/>
@ -327,7 +323,7 @@
# ------------------------------------------------------
# Project Task
# ------------------------------------------------------
<record id="view_phase_task_form2" model="ir.ui.view">
<field name="name">phase.task.form2</field>
<field name="model">project.task</field>
@ -349,8 +345,8 @@
<field name="phase_id" select="1"/>
</field>
</field>
</record>
</record>
<act_window
id="project_phase_task_list"
name="Related Tasks"

View File

@ -55,6 +55,7 @@
'wizard/project_scrum_backlog_create_task_view.xml',
'wizard/project_scrum_backlog_merger_view.xml',
'wizard/project_scrum_postpone_view.xml',
"wizard/project_scrum_email_view.xml",
'project_scrum_view.xml',
'wizard/project_scrum_backlog_sprint_view.xml',
'process/project_scrum_process.xml',

View File

@ -5,8 +5,8 @@
<record id="scrum_sprint_0" model="project.scrum.sprint">
<field name="name">Sprint 1</field>
<field name="date_start" eval="time.strftime('%Y-01-01')"></field>
<field name="date_stop" eval="time.strftime('%Y-01-15')"></field>
<field name="date_start" eval="time.strftime('%Y-06-01')"></field>
<field name="date_stop" eval="time.strftime('%Y-06-15')"></field>
<field name="project_id" ref="project.project_project_9"/>
<field name="product_owner_id" ref="base.user_root"/>
<field model="res.users" name="scrum_master_id" search="[('login','=','admin')]"/>
@ -15,8 +15,8 @@
<record id="scrum_sprint_1" model="project.scrum.sprint">
<field name="name">Sprint 2</field>
<field name="date_start" eval="time.strftime('%Y-01-16')"></field>
<field name="date_stop" eval="time.strftime('%Y-01-31')"></field>
<field name="date_start" eval="time.strftime('%Y-06-16')"></field>
<field name="date_stop" eval="time.strftime('%Y-06-30')"></field>
<field name="expected_hours">100.0</field>
<field name="project_id" ref="project.project_project_9"/>
<field name="product_owner_id" ref="base.user_root"/>
@ -26,8 +26,8 @@
<record id="scrum_sprint_2" model="project.scrum.sprint">
<field name="name">Sprint 3</field>
<field name="date_start" eval="time.strftime('%Y-02-01')"></field>
<field name="date_stop" eval="time.strftime('%Y-02-15')"></field>
<field name="date_start" eval="time.strftime('%Y-07-01')"></field>
<field name="date_stop" eval="time.strftime('%Y-07-15')"></field>
<field name="expected_hours">89.0</field>
<field name="project_id" ref="project.project_project_9"/>
<field name="product_owner_id" ref="base.user_root"/>
@ -37,8 +37,8 @@
<record id="scrum_sprint_3" model="project.scrum.sprint">
<field name="name">Sprint 4</field>
<field name="date_start" eval="time.strftime('%Y-02-16')"></field>
<field name="date_stop" eval="time.strftime('%Y-02-28')"></field>
<field name="date_start" eval="time.strftime('%Y-07-16')"></field>
<field name="date_stop" eval="time.strftime('%Y-07-31')"></field>
<field name="expected_hours">125.0</field>
<field name="project_id" ref="project.project_project_9"/>
<field name="product_owner_id" ref="base.user_root"/>
@ -48,8 +48,8 @@
<record id="scrum_sprint_4" model="project.scrum.sprint">
<field name="name">Sprint 5</field>
<field name="date_start" eval="time.strftime('%Y-03-01')"></field>
<field name="date_stop" eval="time.strftime('%Y-03-15')"></field>
<field name="date_start" eval="time.strftime('%Y-08-01')"></field>
<field name="date_stop" eval="time.strftime('%Y-08-15')"></field>
<field name="expected_hours">178.0</field>
<field name="project_id" ref="project.project_project_9"/>
<field name="product_owner_id" ref="base.user_root"/>
@ -59,8 +59,8 @@
<record id="scrum_sprint_5" model="project.scrum.sprint">
<field name="name">Sprint 6</field>
<field name="date_start" eval="time.strftime('%Y-03-16')"></field>
<field name="date_stop" eval="time.strftime('%Y-03-30')"></field>
<field name="date_start" eval="time.strftime('%Y-08-16')"></field>
<field name="date_stop" eval="time.strftime('%Y-08-31')"></field>
<field name="project_id" ref="project.project_project_9"/>
<field name="expected_hours">200.0</field>
<field name="product_owner_id" ref="base.user_root"/>
@ -70,8 +70,8 @@
<record id="scrum_sprint_6" model="project.scrum.sprint">
<field name="name">Sprint 7</field>
<field name="date_start" eval="time.strftime('%Y-04-01')"></field>
<field name="date_stop" eval="time.strftime('%Y-04-15')"></field>
<field name="date_start" eval="time.strftime('%Y-09-01')"></field>
<field name="date_stop" eval="time.strftime('%Y-09-15')"></field>
<field name="expected_hours">175.0</field>
<field name="project_id" ref="project.project_project_9"/>
<field name="product_owner_id" ref="base.user_root"/>
@ -81,8 +81,8 @@
<record id="scrum_sprint_7" model="project.scrum.sprint">
<field name="name">Sprint 8</field>
<field name="date_start" eval="time.strftime('%Y-04-16')"></field>
<field name="date_stop" eval="time.strftime('%Y-04-30')"></field>
<field name="date_start" eval="time.strftime('%Y-09-16')"></field>
<field name="date_stop" eval="time.strftime('%Y-09-30')"></field>
<field name="project_id" ref="project.project_project_9"/>
<field name="product_owner_id" ref="base.user_root"/>
<field name="expected_hours">122.0</field>
@ -92,8 +92,8 @@
<record id="scrum_sprint_8" model="project.scrum.sprint">
<field name="name">Sprint 9</field>
<field name="date_start" eval="time.strftime('%Y-05-01')"></field>
<field name="date_stop" eval="time.strftime('%Y-05-15')"></field>
<field name="date_start" eval="time.strftime('%Y-10-01')"></field>
<field name="date_stop" eval="time.strftime('%Y-10-15')"></field>
<field name="project_id" ref="project.project_project_9"/>
<field name="product_owner_id" ref="base.user_root"/>
<field model="res.users" name="scrum_master_id" search="[('login','=','demo')]"/>
@ -102,8 +102,8 @@
<record id="scrum_sprint_9" model="project.scrum.sprint">
<field name="name">Sprint 10</field>
<field name="date_start" eval="time.strftime('%Y-05-16')"></field>
<field name="date_stop" eval="time.strftime('%Y-05-30')"></field>
<field name="date_start" eval="time.strftime('%Y-10-16')"></field>
<field name="date_stop" eval="time.strftime('%Y-10-31')"></field>
<field name="expected_hours">78.0</field>
<field name="project_id" ref="project.project_project_9"/>
<field name="product_owner_id" ref="base.user_root"/>
@ -113,8 +113,8 @@
<record id="scrum_sprint_10" model="project.scrum.sprint">
<field name="name">Sprint 11</field>
<field name="date_start" eval="time.strftime('%Y-06-01')"></field>
<field name="date_stop" eval="time.strftime('%Y-06-15')"></field>
<field name="date_start" eval="time.strftime('%Y-11-01')"></field>
<field name="date_stop" eval="time.strftime('%Y-11-15')"></field>
<field name="project_id" ref="project.project_project_9"/>
<field name="product_owner_id" ref="base.user_root"/>
<field model="res.users" name="scrum_master_id" search="[('login','=','demo')]"/>
@ -123,8 +123,8 @@
<record id="scrum_sprint_11" model="project.scrum.sprint">
<field name="name">Sprint 12</field>
<field name="date_start" eval="time.strftime('%Y-06-16')"></field>
<field name="date_stop" eval="time.strftime('%Y-06-30')"></field>
<field name="date_start" eval="time.strftime('%Y-11-16')"></field>
<field name="date_stop" eval="time.strftime('%Y-11-30')"></field>
<field name="project_id" ref="project.project_project_9"/>
<field name="product_owner_id" ref="base.user_root"/>
<field model="res.users" name="scrum_master_id" search="[('login','=','admin')]"/>
@ -133,8 +133,18 @@
<record id="scrum_sprint_12" model="project.scrum.sprint">
<field name="name">Sprint 13</field>
<field name="date_start" eval="time.strftime('%Y-07-1')"></field>
<field name="date_stop" eval="time.strftime('%Y-07-15')"></field>
<field name="date_start" eval="time.strftime('%Y-12-1')"></field>
<field name="date_stop" eval="time.strftime('%Y-12-15')"></field>
<field name="project_id" ref="project.project_project_9"/>
<field name="product_owner_id" ref="base.user_root"/>
<field model="res.users" name="scrum_master_id" search="[('login','=','admin')]"/>
<field name="state">open</field>
</record>
<record id="scrum_sprint_13" model="project.scrum.sprint">
<field name="name">Sprint 14</field>
<field name="date_start" eval="time.strftime('%Y-12-16')"></field>
<field name="date_stop" eval="time.strftime('%Y-12-31')"></field>
<field name="project_id" ref="project.project_project_9"/>
<field name="product_owner_id" ref="base.user_root"/>
<field model="res.users" name="scrum_master_id" search="[('login','=','admin')]"/>
@ -391,7 +401,7 @@ Demo: Work on Editable trees</field>
<field name="question_blocks">
Demo :Bugfix - memory leak
</field>
<field name="sprint_id" ref="scrum_sprint_0"/>
<field name="sprint_id" ref="scrum_sprint_8"/>
<field eval="time.strftime('%Y-%m-%d')" name="date"/>
</record>
<record id="project_task_work_scrum_task1" model="project.task.work" context="{'withoutemployee': True }">

View File

@ -390,10 +390,11 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Scrum Meeting">
<group colspan="4" col="6">
<group colspan="4" col="8">
<field name="date"/>
<field name="sprint_id" domain="[('state', '=', 'open')]"/>
<field name="user_id"/>
<button name="%(action_project_scrum_email)d" string="Send Email" type="action" icon="terp-mail-message-new" />
</group>
<notebook colspan="4">
<page string="Scrum Meeting">
@ -404,8 +405,6 @@
<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 ?"/>

View File

@ -23,6 +23,7 @@ import project_scrum_backlog_create_task
import project_scrum_backlog_sprint
import project_scrum_backlog_merger
import project_scrum_postpone
import project_scrum_email
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,105 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 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/>.
#
##############################################################################
from osv import fields, osv
from tools.translate import _
from datetime import datetime
import tools
class project_scrum_email(osv.osv_memory):
_name = 'project.scrum.email'
def default_get(self, cr, uid, fields, context=None):
"""
This function gets default values
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current users ID for security checks,
@param fields: List of fields for default value
@param context: A standard dictionary for contextual values
@return : default values of fields.
"""
meeting_pool = self.pool.get('project.scrum.meeting')
record_ids = context and context.get('active_ids', []) or []
res = super(project_scrum_email, self).default_get(cr, uid, fields, context=context)
for meeting in meeting_pool.browse(cr, uid, record_ids, context=context):
sprint = meeting.sprint_id
if 'scrum_master_email' in fields:
res.update({'scrum_master_email': sprint.scrum_master_id and sprint.scrum_master_id.user_email or False})
if 'product_owner_email' in fields:
res.update({'product_owner_email': sprint.product_owner_id and sprint.product_owner_id.user_email or False})
if 'subject' in fields:
subject = _("Scrum Meeting : %s") %(meeting.date)
res.update({'subject': subject})
if 'message' in fields:
message = _("Hello , \nI am sending you Scrum Meeting : %s for the Sprint '%s' of Project '%s'") %(meeting.date, sprint.name, sprint.project_id.name)
res.update({'message': message})
return res
_columns = {
'scrum_master_email': fields.char('Scrum Master Email', size=64, help="Email Id of Scrum Master"),
'product_owner_email': fields.char('Product Owner Email', size=64, help="Email Id of Product Owner"),
'subject':fields.char('Subject', size=64),
'message':fields.text('Message'),
}
def button_send_scrum_email(self, cr, uid, ids, context=None):
if context is None:
context={}
active_id = context.get('active_id', False)
scrum_meeting_pool = self.pool.get('project.scrum.meeting')
user_pool = self.pool.get('res.users')
meeting = scrum_meeting_pool.browse(cr, uid, active_id, context=context)
# wizard data
data_id = ids and ids[0] or False
if not data_id or not active_id:
return False
data = self.browse(cr, uid, data_id, context=context)
email_from = tools.config.get('email_from', False)
user = user_pool.browse(cr, uid, uid, context=context)
user_email = email_from or user.address_id.email
body = "%s\n" %(data.message)
body += "\n%s\n" %_('Tasks since yesterday')
body += "_______________________\n"
body += "\n%s\n" %(meeting.question_yesterday or _('None'))
body += "\n%s\n" %_("Task for Today")
body += "_______________________ \n"
body += "\n%s\n" %(meeting.question_today or _('None'))
body += "\n%s\n" % _('Blocking points encountered:')
body += "_______________________ \n"
body += "\n%s\n" %(meeting.question_blocks or _('None'))
body += "\n%s\n%s" %(_('Thank you,'), user.name)
if user.signature:
body += "\n%s" %(user.signature)
if data.scrum_master_email == data.product_owner_email:
data.product_owner_email = False
if data.scrum_master_email:
tools.email_send(user_email, [data.scrum_master_email], data.subject, body, reply_to=user_email)
if data.product_owner_email:
tools.email_send(user_email, [data.product_owner_email], data.subject, body, reply_to=user_email)
return {}
project_scrum_email()

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_project_scrum_email" model="ir.ui.view">
<field name="name">Scrum Meeting</field>
<field name="model">project.scrum.email</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Scrum Meeting">
<separator colspan="4" string="Send Email for Scrum Meeting Details"/>
<field name="scrum_master_email" width="64"/>
<field name="product_owner_email" width="64"/>
<field name="subject" colspan="4"/>
<separator string="Message" colspan="4"/>
<field name="message" nolabel="1" colspan="4"/>
<separator string="" colspan="4"/>
<group colspan="2" col="2">
</group>
<group colspan="2" col="2">
<button icon="gtk-cancel" special="cancel" string="_Cancel"/>
<button icon="gtk-go-forward" name="button_send_scrum_email" string="_Send" type="object" default_focus="1" />
</group>
</form>
</field>
</record>
<record id="action_project_scrum_email" model="ir.actions.act_window">
<field name="name">Scrum Meeting</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">project.scrum.email</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</data>
</openerp>