Skip to content

Commit

Permalink
[ADD] project_scrum
Browse files Browse the repository at this point in the history
  • Loading branch information
adasatorres committed Oct 21, 2024
1 parent bddd912 commit 8fcedea
Show file tree
Hide file tree
Showing 21 changed files with 1,303 additions and 0 deletions.
97 changes: 97 additions & 0 deletions project_scrum/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
=============
Project Scrum
=============

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:1e5f918a26b23d5518e54987bea92f39913aa9d2f54c771f71a1c6572d5601ba
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fproject-lightgray.png?logo=github
:target: https://github.com/OCA/project/tree/16.0/project_scrum
:alt: OCA/project
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/project-16-0/project-16-0-project_scrum
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/project&target_branch=16.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This addon allow you to manage your project with scrum methodology.

**Table of contents**

.. contents::
:local:

Usage
=====

This addon you can create and manage your project with scrum methodology.
For create a sprint you need to go to the project and click on the "Sprint" button.
You can create a sprint with a name, a start date, an end date, a project and a objetive.
You can create a sprint from configuration menu.
You can access the all options from the project options on kanban view or from project view form.
From the project options on kanban view you can access the sprint timeline view and the backlog view.

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/project/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/project/issues/new?body=module:%20project_scrum%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
~~~~~~~

* Binhex

Contributors
~~~~~~~~~~~~

* `Binhex <https://www.binhex.cloud>_`:

* Adasat Torres de León <[email protected]>


Maintainers
~~~~~~~~~~~

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

.. |maintainer-adasatorres| image:: https://github.com/adasatorres.png?size=40px
:target: https://github.com/adasatorres
:alt: adasatorres

Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:

|maintainer-adasatorres|

This module is part of the `OCA/project <https://github.com/OCA/project/tree/16.0/project_scrum>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
3 changes: 3 additions & 0 deletions project_scrum/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

from . import models
22 changes: 22 additions & 0 deletions project_scrum/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright 2024 Binhex - Adasat Torres de León (https://www.binhex.cloud)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

{
"name": "Project Scrum",
"version": "16.0.1.0.0",
"category": "Project",
"website": "https://github.com/OCA/project",
"author": "Binhex, Odoo Community Association (OCA)",
"license": "AGPL-3",
"installable": True,
"application": False,
"summary": "This addon allow use the scrum methodology in projects",
"depends": ["project_timeline"],
"data": [
"security/ir.model.access.csv",
"views/project_sprint_views.xml",
"views/project_views.xml",
"data/ir_cron_data.xml",
],
"maintainers": ["adasatorres"],
}
14 changes: 14 additions & 0 deletions project_scrum/data/ir_cron_data.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo noupdate="1">
<record id="cron_update_sprint_state" model="ir.cron">
<field name="name">Update sprint state</field>
<field name="model_id" ref="model_project_sprint" />
<field name="interval_number">5</field>
<field name="interval_type">minutes</field>
<field name="numbercall">-1</field>
<field name="state">code</field>
<field name="code">
model.cron_update_sprint_state()
</field>
</record>
</odoo>
2 changes: 2 additions & 0 deletions project_scrum/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import project_sprint
from . import project
90 changes: 90 additions & 0 deletions project_scrum/models/project.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError


class ProjectProject(models.Model):
_inherit = "project.project"

sprint_ids = fields.One2many(
comodel_name="project.sprint",
inverse_name="project_id",
string="Sprints",
)
sprint_count = fields.Integer(compute="_compute_sprint_count")
backlog_count = fields.Integer(compute="_compute_backlog_count")

def _compute_backlog_count(self):
for project in self:
project.backlog_count = len(
project.task_ids.filtered(
lambda task: not task.sprint_id and task.kanban_state != "done"
)
)

def _compute_sprint_count(self):
for project in self:
project.sprint_count = len(project.sprint_ids)

def action_sprints(self):
self.ensure_one()
return {
"name": _("Sprints"),
"type": "ir.actions.act_window",
"res_model": "project.sprint",
"view_mode": "tree,form,timeline",
"domain": [("project_id", "=", self.id)],
"context": {"default_project_id": self.id},
}

def action_backlog(self):
self.ensure_one()
return {
"name": _("Backlog"),
"type": "ir.actions.act_window",
"res_model": "project.task",
"view_mode": "tree,form",
"domain": [
("project_id", "=", self.id),
("sprint_id", "=", False),
("kanban_state", "!=", "done"),
],
"context": {"default_project_id": self.id},
}

def action_sprint_timeline(self):
self.ensure_one()
return {
"name": _("Sprint Timeline"),
"type": "ir.actions.act_window",
"res_model": "project.task",
"view_mode": "timeline",
"domain": [("project_id", "=", self.id), ("sprint_id", "!=", False)],
"context": {"default_project_id": self.id, "no_create": True},
}


class ProjectTask(models.Model):
_inherit = "project.task"

sprint_id = fields.Many2one(
comodel_name="project.sprint",
string="Sprint",
track_visibility="onchange",
)

sprint_state = fields.Selection(
related="sprint_id.state", string="Sprint State", store=True
)

@api.constrains("user_ids")
def _check_user_ids(self):
for task in self:
if task.user_ids and task.sprint_id:
if not task.user_ids <= task.sprint_id.user_ids:
raise ValidationError(
_("The assignees must be part of the sprint.")
)

@api.onchange("sprint_id")
def _onchange_sprint_id(self):
self.user_ids = False
133 changes: 133 additions & 0 deletions project_scrum/models/project_sprint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
from dateutil.relativedelta import relativedelta

from odoo import _, api, fields, models

DATE_OPTIONS = [
("1_weeks", _("1 Week")),
("2_weeks", _("2 Weeks")),
("1_months", _("1 Month")),
("2_months", _("2 Month")),
("1_years", _("1 Year")),
("2_years", _("2 Years")),
("custom", _("Custom")),
]


class ProjectSprint(models.Model):
_name = "project.sprint"
_inherit = ["mail.thread", "mail.activity.mixin"]
_description = "Project Sprint"
_sql_constraints = [
(
"date_check",
"CHECK (date_start <= date_end)",
_("Error: End date must be greater than start date!"),
),
]

name = fields.Char(required=True, track_visibility="onchange")
user_ids = fields.Many2many(
comodel_name="res.users",
string="Members",
required=True,
domain="[('share', '=', False), ('active', '=', True)]",
track_visibility="onchange",
relation="project_sprint_user_rel",
)
description = fields.Text(track_visibility="onchange")
project_id = fields.Many2one(
comodel_name="project.project",
string="Project",
track_visibility="onchange",
required=True,
)
task_ids = fields.One2many(
comodel_name="project.task",
inverse_name="sprint_id",
string="Tasks",
domain="[('project_id', '=', project_id)]",
)
date_start = fields.Date(
string="Start Date", default=fields.Date.today, required=True
)
date_option = fields.Selection(
selection=DATE_OPTIONS, default=DATE_OPTIONS[0][0], required=True
)
date_end = fields.Date(
string="End Date",
required=True,
compute="_compute_date_end",
store=True,
readonly=False,
)
state = fields.Selection(
selection=[
("draft", "Draft"),
("in_progress", "In progress"),
("done", "Done"),
],
default="draft",
)
tasks_count = fields.Integer(compute="_compute_tasks_count")

def _compute_tasks_count(self):
for sprint in self:
sprint.tasks_count = len(sprint.task_ids)

def action_start(self):
self.write({"state": "in_progress"})

def action_done(self):
self.write({"state": "done"})
self._check_task_state()

def action_tasks(self):
self.ensure_one()
return {
"name": _("Tasks"),
"type": "ir.actions.act_window",
"res_model": "project.task",
"view_mode": "tree,form",
"domain": [("sprint_id", "=", self.id)],
"context": {
"default_project_id": self.project_id.id,
"default_sprint_id": self.id,
},
}

@api.model
def cron_update_sprint_state(self):
date = fields.Date.today()
for sprint in self.search([("state", "=", "draft")]):
if date >= sprint.date_start:
sprint.write({"state": "in_progress"})

for sprint in self.search([("state", "=", "in_progress")]):
if date >= sprint.date_end:
sprint.write({"state": "done"})
sprint._check_task_state()

def _check_task_state(self):
self.ensure_one()
in_progress_sprints = self.project_id.sprint_ids.filtered(
lambda sprint: sprint.state == "in_progress"
)
self.task_ids.filtered(lambda task: task.kanban_state != "done").write(
{
"sprint_id": (
in_progress_sprints[0].id if in_progress_sprints else False
),
"user_ids": False,
}
)

@api.depends("date_start", "date_option")
def _compute_date_end(self):
for record in self:
if record.date_option != "custom":
num, interval = record.date_option.split("_")
record.date_end = record.date_start + relativedelta(
**{interval: int(num)}
)
else:
record.date_end = record.date_start + relativedelta(days=1)
4 changes: 4 additions & 0 deletions project_scrum/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
* `Binhex <https://www.binhex.cloud>_`:

* Adasat Torres de León <[email protected]>

1 change: 1 addition & 0 deletions project_scrum/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This addon allow you to manage your project with scrum methodology.
6 changes: 6 additions & 0 deletions project_scrum/readme/USAGE.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
This addon you can create and manage your project with scrum methodology.
For create a sprint you need to go to the project and click on the "Sprint" button.
You can create a sprint with a name, a start date, an end date, a project and a objetive.
You can create a sprint from configuration menu.
You can access the all options from the project options on kanban view or from project view form.
From the project options on kanban view you can access the sprint timeline view and the backlog view.
3 changes: 3 additions & 0 deletions project_scrum/security/ir.model.access.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_project_sprint_user,project.sprint.user,model_project_sprint,project.group_project_user,1,0,0,0
access_project_sprint_admin,project.sprint.admin,model_project_sprint,project.group_project_manager,1,1,1,1
Binary file added project_scrum/static/description/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 8fcedea

Please sign in to comment.