Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
19dda2e
[12.0][ADD] - Add new addon: contract_forecast
sbejaoui Mar 7, 2019
24c6100
[IMP] - improve post_init_hook and _generate_forecast_periods
sbejaoui Mar 14, 2019
232928d
[FIX] - forecast should continue after contract line date_end if ot i…
sbejaoui Mar 14, 2019
f30690a
[IMP] - set date_invoice as default group by for forecast pivot view
sbejaoui Mar 14, 2019
ea4c09a
[FIX] - Create a new contract must create forecast lines with a queue…
sbejaoui Mar 14, 2019
4aaf9a1
[IMP] - Add forecast trigger for contract update
sbejaoui Apr 2, 2019
3b33380
[RMV] - Remove active field
sbejaoui Apr 30, 2019
fa36067
[ADD] - Add multi-company to forecasts
sbejaoui Sep 3, 2019
05b9df8
[REF] Contract Forecast: remove dependency on product_contract
ThomasBinsfeld Sep 30, 2019
c7fe42a
[REF] Contract Forecast: split from analytic account
ThomasBinsfeld Sep 30, 2019
f182f09
[REF] Contract Forecast: pylint
ThomasBinsfeld Sep 30, 2019
113e433
[12.0][FIX] - change deprecated attribute
sbejaoui Oct 29, 2019
1d4cfd7
[UPD] README.rst
OCA-git-bot Dec 4, 2019
3c3f77c
[ADD] icon.png
OCA-git-bot Dec 4, 2019
780caac
[IMP] - add failing test for monthlylastday, pre-paid case
sbejaoui Dec 18, 2019
56e2fee
[FIX] - use the next_period dates to compute forecast dates
sbejaoui Dec 18, 2019
fda53fb
contract_forecast 12.0.1.0.2
OCA-git-bot Dec 23, 2019
fa3bfa7
[IMP] - Add failing test for forecast generation of auto renewal cont…
sbejaoui Jan 7, 2020
83f49d3
[IMP] - add a non-regression test: forecast for undefined date end co…
sbejaoui Jan 7, 2020
e69579e
[FIX] - for auto-renew contract lines, don't stop the forecast at the…
sbejaoui Jan 7, 2020
2211b2d
[FIX] - Fix unit test: is_auto_renew is considered in the forecast ge…
sbejaoui Jan 7, 2020
f5a72de
contract_forecast 12.0.1.0.3
OCA-git-bot Jan 7, 2020
e9f47da
[UPD] README.rst
OCA-git-bot Mar 25, 2020
ad8bdb2
[UPD] README.rst
OCA-git-bot Mar 25, 2020
6e038e7
[IMP] - add an option to enable forecasts by company
sbejaoui Oct 7, 2020
147207c
[IMP] - use next period computed fields to init forecast
sbejaoui Aug 26, 2020
123ce31
contract_forecast 12.0.1.0.4
OCA-git-bot Mar 10, 2021
38146a5
[NEW] Report > Contract Forecast Menu
mileo Mar 11, 2021
4e4ef16
contract_forecast 12.0.1.1.0
OCA-git-bot May 9, 2021
82a0b5d
contract_forecast 12.0.1.2.0
OCA-git-bot May 19, 2021
7d0f20e
[UPD] README.rst
OCA-git-bot Sep 3, 2023
0e38de9
[18.0][MIG] contract_forecast
sbejaoui Apr 21, 2025
240997e
[FIX] contract_forecast: multi-company rule for all authorized companies
glitchov Aug 12, 2025
c26064e
[IMP] contract_forecast: pre-commit auto fixes
Larsq1 Jun 15, 2026
a1045eb
[MIG] contract_forecast: Migration to 19.0
Larsq1 Jun 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 136 additions & 0 deletions contract_forecast/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
.. image:: https://odoo-community.org/readme-banner-image
:target: https://odoo-community.org/get-involved?utm_source=readme
:alt: Odoo Community Association

=================
Contract Forecast
=================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:b6a80d9d2f3ccac7d2f85b5edbea96e5c5e5b115564bb079c40015a5e68eded7
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |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/license-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%2Fcontract-lightgray.png?logo=github
:target: https://github.com/OCA/contract/tree/19.0/contract_forecast
:alt: OCA/contract
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/contract-19-0/contract-19-0-contract_forecast
: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/contract&target_branch=19.0
:alt: Try me on Runboat

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

The contract_forecast module enhances the **Contract** module by
generating and managing **forecast periods** for each contract line. It
automatically calculates future invoicing amounts and dates, allowing
companies to better anticipate and report on expected revenues.

Forecasts are visible directly from the contract in a **pivot view** or
**list view**.

## Features

- Generate forecast periods based on the contract's invoicing rules.
- View forecasts grouped by invoice date.
- Automatic regeneration of forecast periods when contract data changes
(product, quantity, price, dates, etc.).
- Company-wide configuration to enable or disable forecasts.
- Configurable forecast interval and period type (monthly or yearly).
- Forecast period data includes:

- Start and end dates
- Expected invoice date
- Quantity, unit price, discount, and subtotal (untaxed)

- Clean handling of auto-renewing and manually-ended contracts.

**Table of contents**

.. contents::
:local:

Configuration
=============

Go **General Settings** under the **Contract Forecast** section:

- **Enable Contract Forecast**: Enable or disable forecasting for the
company.
- **Number of Contract Forecast Periods**: Define how many future
periods are generated.
- **Forecast Period Type**: Choose between **Monthly** or **Yearly**
periods.

Usage
=====

1. Open a **Contract**.
2. Click on the **Forecast** button to access the generated forecast
periods.
3. Forecasts can be analyzed through:

- **Pivot view** (grouped by Invoice Date)
- **Tree view** (detailed forecast lines)

Forecast periods are regenerated automatically when relevant fields are
modified (e.g., quantity, price, dates).

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

Bugs are tracked on `GitHub Issues <https://github.com/OCA/contract/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/contract/issues/new?body=module:%20contract_forecast%0Aversion:%2019.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
-------

* ACSONE SA/NV

Contributors
------------

- Souheil Bejaoui <souheil.bejaoui@acsone.eu>

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-sbejaoui| image:: https://github.com/sbejaoui.png?size=40px
:target: https://github.com/sbejaoui
:alt: sbejaoui

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

|maintainer-sbejaoui|

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

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
2 changes: 2 additions & 0 deletions contract_forecast/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import models
from .hooks import post_init_hook
21 changes: 21 additions & 0 deletions contract_forecast/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Copyright 2019 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

{
"name": "Contract Forecast",
"version": "19.0.1.0.0",
"license": "AGPL-3",
"author": "ACSONE SA/NV,Odoo Community Association (OCA)",
"website": "https://github.com/OCA/contract",
"depends": ["contract_line_successor", "queue_job"],
"data": [
"data/queue_job_channel.xml",
"data/queue_job_functions.xml",
"security/contract_line_forecast_period.xml",
"views/res_config_settings.xml",
"views/contract_line_forecast_period.xml",
"views/contract.xml",
],
"maintainers": ["sbejaoui"],
"post_init_hook": "post_init_hook",
}
6 changes: 6 additions & 0 deletions contract_forecast/data/queue_job_channel.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<odoo>
<record id="contract_forecast_queue_channel" model="queue.job.channel">
<field name="name">CONTRACT_FORECAST</field>
<field name="parent_id" ref="queue_job.channel_root" />
</record>
</odoo>
7 changes: 7 additions & 0 deletions contract_forecast/data/queue_job_functions.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<odoo>
<record id="job_function_generate_forecast_periods" model="queue.job.function">
<field name="model_id" ref="contract.model_contract_contract" />
<field name="method">_generate_forecast_periods</field>
<field name="channel_id" ref="contract_forecast_queue_channel" />
</record>
</odoo>
23 changes: 23 additions & 0 deletions contract_forecast/hooks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright 2019 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

import logging

_logger = logging.getLogger(__name__)


def post_init_hook(env):
"""Generate contract line forecast periods"""
_logger.info(
"Post init hook for module contract_forecast: "
"Generate contract line forecast periods"
)
offset = 0
while True:
contract_lines = env["contract.line"].search(
[("is_canceled", "=", False)], limit=100, offset=offset
)
contract_lines.with_delay()._generate_forecast_periods()
if len(contract_lines) < 100:
break
offset += 100
Loading
Loading