# Agile Sprints & Board for Projects

> Scrum and Kanban on Odoo Project: backlog, sprints, story points, epics, releases, a board with swimlanes and WIP limits, velocity, burndown and cumulative flow - the half of Jira a team misses.

- **What it is:** Scrum and Kanban on Odoo Project: backlog, sprints, story points, epics, releases, a board with swimlanes and WIP limits, velocity, burndown and cumulative flow - the half of Jira a team misses.
- **For:** Project
- **Odoo versions:** 16.0, 17.0, 18.0, 19.0, 20.0 - Community and Enterprise
- **Runs on:** Odoo.sh or Odoo you host yourself - not Odoo Online, which accepts no third-party apps
- **Price:** 199 EUR, one-time, on the Odoo Apps Store
- **Technical name:** bambooforge_agile
- **Not for:** Every stage has a WIP limit (Configuration → Stages). Zero means none. With a limit, the column header shows the count in the whole project against the limit: amber at the limit, red over it.; Tick Enforce and the move is refused instead - on the board, in the kanban, in the list, from an import - with the stage's name and the limit in the message. The count is per project, so two projects sharing a stage do not count against each other. Moving a task that is already in the stage never counts as a new entry.
- **Manual:** https://docs.bambooforge.dev/bambooforge_agile/
- **Live demo:** https://demo20.bambooforge.dev/odoo/action-bambooforge_agile.action_bf_agile_board
- **Store page:** https://apps.odoo.com/apps/modules/20.0/bambooforge_agile
- **Manual last updated:** 2026-09-21

---
# Agile Sprints & Board for Projects

Odoo Project has tasks, stages and a kanban. A software or product team
that leaves Jira misses the rest. This app adds it, on project.task, so
the hours the team logs still land on the same invoices.

## What you get

- A **backlog** of every task not yet in a sprint, ranked by dragging the
  handle, with an issue type (story, bug, task, spike), **story points**,
  an **epic**, a **release** and a blocked flag - all editable in the row.
- **Sprints** with a goal, two dates and a capacity in points. One active
  sprint per project. Close one and the **velocity** is frozen, unfinished
  work goes back to the backlog, and the chatter says what was left.
- A **board**: the project's own stages as columns, **swimlanes** by epic,
  assignee or issue type, drag between columns and to re-rank, a sprint
  bar with goal, points and days left.
- **WIP limits** per stage: the column turns amber when full and red when
  over; tick *Enforce* and the move is refused.
- **Epics** and **releases** with points-based progress.
- **Burndown** per sprint (remaining, ideal and scope), **velocity** per
  closed sprint, a **cumulative flow diagram** rebuilt from the tasks'
  own stage history, and created-vs-resolved per week.
- The project form carries the mean velocity of the last three sprints -
  the number to plan the next one against.
- Written in OWL like the rest of Odoo. No Jira licence, no bundled board
  library, nothing phoning home.

## Install

1. Install **BambooForge Agile** (depends on Project only).
2. An **Agile** menu appears in the Project app: Board, Backlog, Sprints,
   Epics, Releases and Agile Reports. Every project form gets **Board**,
   **Sprints** and **Backlog** buttons.
3. Open *Configuration → Stages* and give a stage a **WIP limit** if you
   run Kanban; leave it at zero otherwise.

## The backlog

*Agile → Backlog* lists every open task with no sprint, in rank order.
Drag the handle to reorder; the rank is stored on the task, so the board
and the sprint planning kanban show the same order. Type, points, epic,
sprint, release and the blocked flag are edited in the row.

Switch to the **kanban**: cards are grouped by sprint, with the backlog as
the first column. Dragging a card into a sprint column plans it; the day it
entered is stamped on the task, and the burndown reads it.

## Sprints

A sprint belongs to one project and has a **goal** (one sentence the team
can say yes or no to at the review), a start and an end date, and a
**capacity** in points that the form compares with the points committed.

- **Start** marks it active. Only one sprint per project may be active;
  starting a second one is refused with the first one's name. Missing
  dates are filled: today, and two weeks later.
- **Close** freezes the **velocity** (points done) and the committed total
  as they stand, sends every unfinished task back to the backlog, and
  posts what went back in the chatter. Reopening a task later changes the
  task, not the velocity the next sprint was planned on.
- **Reopen** puts a closed sprint back to planned; the frozen numbers stay
  until it is closed again.

Story points are typed by the team. The app never derives them from hours.

## The board

*Agile → Board* (or the **Board** button on a project or a sprint) shows
the project's stages as columns and, by default, the active sprint's tasks.
Pick another sprint, or *Whole project*, in the second selector.

- **Swimlanes** by epic, assignee or issue type split every column into
  rows; each row shows its card and point count.
- **Drag a card** to another column to change its stage; drop it above
  another card to put it before that card in the rank.
- **Click** a card to open the task; the ban icon toggles *blocked*.
- **Search** filters by name or epic; **Only mine** keeps the cards
  assigned to you.
- The **sprint bar** shows the goal, points done of committed, a progress
  bar and the days left (red once the end date has passed).

## WIP limits

Every stage has a **WIP limit** (*Configuration → Stages*). Zero means
none. With a limit, the column header shows the count in the whole
project against the limit: amber at the limit, red over it.

Tick **Enforce** and the move is refused instead - on the board, in the
kanban, in the list, from an import - with the stage's name and the limit
in the message. The count is per project, so two projects sharing a stage
do not count against each other. Moving a task that is already in the
stage never counts as a new entry.

## Epics and releases

An **epic** is a body of work too big for a sprint: tasks point at it, and
its progress is the story points done over the points total. It has a
colour (shown on the cards), a target date and an open/done state.

A **release** groups the tasks that ship together, with a planned date.
*Mark Released* records the actual date and posts in the chatter how many
tasks were done - and which were not.

## Reports

- **Burndown** (button on the sprint, or on the board): one point per day
  from the sprint's start to its end. *Remaining* is the points of tasks
  in the sprint and not yet done on that day; *Ideal* is the straight
  line from the committed total to zero; *Scope* is the committed total on
  that day, so a task pulled in mid-sprint shows as a step up rather than
  as history rewritten. The chart stops at today: the ideal line's slope
  says where the sprint is heading, and a remaining line that pretended
  to know tomorrow would be a lie.
- **Velocity** (*Agile Reports → Velocity*): a bar per closed sprint,
  committed beside done.
- **Cumulative flow** (button on the project): for each of the last thirty
  days, how many tasks sat in each stage. It is rebuilt from the chatter's
  tracking of stage changes, which Odoo has always recorded, so it works
  on tasks that existed before this app was installed.
- **Created per week** and **Resolved per week**: two graphs over the
  tasks themselves; resolved reads the done date this app stamps.

## Coming from Jira

*Agile -> Import from Jira*. In Jira: Filters, search the project,
Export, CSV (all fields). Pick the Odoo project, the file, and:

- **epics** become epics, with their state;
- **stories, bugs and tasks** become tasks with their points, priority
  (Highest/High become starred), status, assignee, labels as tags,
  description and the comments, in the chatter as notes;
- **sub-tasks** hang under their parent;
- **sprints** are created by name, in the planned state, for you to
  date and start;
- a Jira **status** with no stage of that name becomes a stage (folded
  when it is Done/Closed/Resolved), unless you untick it;
- an **assignee** is matched to a user by name, email or login;
  unmatched ones are listed and go to the user you name, or nobody.

The Jira key stays on every task as its *External key*, so the same
file imported again updates instead of duplicating - run the export
twice a week during the transition - and a commit that says
`PROJ-12` still lands on the right task after the move.

## Commits and pull requests on the task

On the project form, tab **Git**: pick GitHub or GitLab, press *New
secret*, copy the webhook address and the secret into the repository's
webhook settings (GitHub: content type JSON, events *push* and *pull
requests*; GitLab: *push* and *merge request* events, the secret as the
token). From then on:

- a commit message, a pull request title or body that names a task -
  `#123`, `task-123`, or its Jira key - leaves a note on the task
  with the author and a link to the commit or the PR;
- `fixes #123`, `closes task-123`, `resolves PROJ-12` moves the
  task to the project's folded stage - when the commit reaches the
  default branch you named, or when the pull request is merged; on a
  feature branch, or an open PR, it only leaves the note;
- a payload that does not carry the right signature (GitHub) or token
  (GitLab) is refused and writes nothing.

## Break a story into subtasks with AI

With **AI Assistant** installed and configured, the story gains *Break
into subtasks with AI*: the model reads the title and the description
and proposes subtasks with a point estimate each. You untick what you
do not want, edit the rest, and press Create; the subtasks land under
the story, in its sprint and epic. Installed by the *Agile: break a
story into subtasks with AI* bridge, by itself.

## Where the done date comes from

A task is *done* when its stage is folded or, on Odoo 17 and later, when
its state is Done or Cancelled. The first time that happens the app stamps
**Done on**; reopening the task clears it. The burndown, the velocity and
the resolved chart read that stamp, so a task done and reopened twice is
counted where it ended up, not three times.

## Limits, stated plainly

- One sprint per task at a time; the closed sprint remembers returned
  work in its chatter, not in its points.
- The board does not create stages: use the project's own.
- Story points are typed, never guessed from timesheets or hours.
- The cumulative flow diagram covers thirty days and reads only stage
  changes that went through the chatter tracking (every ordinary write
  does).

## How we make sure it works

Before every release, **35 automated checks** run against this app on Odoo 16, 17, 18, 19 and 20.
Among them:

- One pull request naming the task twice leaves one note.
- A file that is not jira is refused.
- A merged pull request closes and an open one does not.
- A signed push leaves a note and fixes closes.
- An unknown status becomes a stage or not.

The complete list is in the source you receive.

## What changed in 1.1

- **Import from Jira**: the CSV export becomes epics, tasks, sub-tasks,
  sprints, points, tags and comments; imported twice, it updates.
- **Commits and pull requests on the task**: a GitHub or GitLab webhook
  per project; a commit that names a task leaves a note, "fixes #123"
  moves it to done on the default branch or when the PR is merged.
- **Break into subtasks with AI**, with the AI Assistant bridge.
