############################################################################## # # Copyright (c) 2004 TINY SPRL. (http://tiny.be) All Rights Reserved. # Fabien Pinckaers # # WARNING: This program as such is intended to be used by professional # programmers who take the whole responsability of assessing all potential # consequences resulting from its eventual inadequacies and bugs # End users who are looking for a ready-to-use solution with commercial # garantees and support are strongly adviced to contract a Free Software # Service Company # # This program is Free Software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # ############################################################################## import time import netsvc from osv import fields, osv, orm from mx import DateTime class scrum_team(osv.osv): _name = 'scrum.team' _description = 'Scrum Team' _columns = { 'name' : fields.char('Team Name', size=64), 'users_id' : fields.many2many('res.users', 'scrum_team_users_rel', 'team_id','user_id', 'Users'), } scrum_team() class scrum_project(osv.osv): _name = 'scrum.project' _inherit = 'project.project' _table = 'project_project' _description = 'Scrum Project' _columns = { 'product_owner_id': fields.many2one('res.users', 'Product Owner'), 'tasks': fields.one2many('scrum.task', 'project_id', 'Scrum Tasks'), 'sprint_size': fields.integer('Sprint Days'), 'scrum': fields.integer('Is Scrum'), } _defaults = { 'product_owner_id': lambda self,cr,uid,context={}: uid, 'warn_manager': lambda *a: 1, 'sprint_size': lambda *a: 14, 'scrum': lambda *a: 1 } scrum_project() class scrum_sprint(osv.osv): _name = 'scrum.sprint' _description = 'Scrum Sprint' _columns = { 'name' : fields.char('Sprint Name', size=64), 'date_start': fields.date('Starting Date', required=True), 'date_stop': fields.date('Ending Date', required=True), 'project_id': fields.many2one('scrum.project', 'Project', required=True, domain=[('scrum','=',1)]), 'product_owner_id': fields.many2one('res.users', 'Product Owner', required=True), 'scrum_master_id': fields.many2one('res.users', 'Scrum Master', required=True), 'meetings_id': fields.one2many('scrum.meeting', 'sprint_id', 'Daily Scrum'), 'review': fields.text('Sprint Review'), 'retrospective': fields.text('Sprint Retrospective'), 'state': fields.selection([('draft','Draft'),('open','Open'),('done','Done')], 'State', required=True), } _defaults = { 'state': lambda *a: 'draft', 'date_start' : lambda *a:time.strftime('%Y-%m-%d'), } def onchange_project_id(self, cr, uid, ids, project_id): v = {} if project_id: proj = self.pool.get('scrum.project').browse(cr, uid, [project_id])[0] v['product_owner_id']= proj.product_owner_id.id v['scrum_master_id']= proj.manager.id v['date_stop'] = (DateTime.now() + DateTime.RelativeDateTime(days=int(proj.sprint_size or 15))).strftime('%Y-%m-%d') return {'value':v} scrum_sprint() class scrum_product_backlog(osv.osv): _name = 'scrum.product.backlog' _description = 'Product Backlog' _columns = { 'name' : fields.char('Feature', size=64), 'note' : fields.text('Note'), 'project_id': fields.many2one('scrum.project', 'Scrum Project', required=True, domain=[('scrum','=',1)]), 'user_id': fields.many2one('res.users', 'User'), 'sprint_id': fields.many2one('scrum.sprint', 'Sprint'), 'sequence' : fields.integer('Sequence'), 'priority' : fields.selection([('5','Very Low'), ('4','Low'), ('3','Medium'), ('2','Urgent'), ('1','Very urgent')], 'Priority'), 'tasks_id': fields.one2many('scrum.task', 'product_backlog_id', 'Tasks Details'), 'state': fields.selection([('draft','Draft'),('open','Open'),('done','Done')], 'State', required=True) } _defaults = { 'priority': lambda *a: '4', 'state': lambda *a: 'draft' } _order = "priority,sequence" scrum_product_backlog() class scrum_task(osv.osv): _name = 'scrum.task' _inherit = 'project.task' _table = 'project_task' _description = 'Scrum Task' _columns = { 'product_backlog_id': fields.many2one('scrum.product.backlog', 'Product Backlog'), 'scrum': fields.integer('Is Scrum'), } _defaults = { 'scrum': lambda *a: 1, } scrum_task() class scrum_meeting(osv.osv): _name = 'scrum.meeting' _description = 'Scrum Meeting' _columns = { 'name' : fields.char('Meeting Name', size=64, required=True), 'date': fields.date('Meeting Date', required=True), 'sprint_id': fields.many2one('scrum.sprint', 'Sprint', required=True), 'question_yesterday': fields.text('Tasks since yesterday'), 'question_today': fields.text('Tasks for today'), 'question_blocks': fields.text('Blocks encountered'), # # Should be more formal. # 'question_backlog': fields.text('Backlog Accurate'), } # # Find the right sprint thanks to users and date # _defaults = { 'date' : lambda *a:time.strftime('%Y-%m-%d'), } scrum_meeting()