| REPOSITORY | |
|---|---|
| REPOSITORY | OCA/contract |
| GIT | |
| GIT | https://github.com/OCA/contract.git |
| GIT FOLDER | |
| GIT FOLDER | https://github.com/OCA/contract/tree/18.0/contract_forecast |
| VERSION | |
| VERSION | 1.0.1 |
| CATEGORY | |
| CATEGORY | Uncategorized |
| LICENSE | |
| LICENSE | AGPL-3 |
| APPLICATION | |
| APPLICATION | No |
| AUTO-INSTALLABLE | |
| AUTO-INSTALLABLE | No |
| AUTHORS | |
| AUTHORS | Odoo Community Association (OCA), ACSONE SA/NV |
| MAINTAINERS | |
| MAINTAINERS | Odoo Community Association (OCA), ACSONE SA/NV |
| COMMITTERS | |
| COMMITTERS | sbejaoui, Weblate, OCA-git-bot, oca-ci, hda |
| WEBSITE | |
| WEBSITE | https://github.com/OCA/contract |
| LAST TRACKING UPDATE | |
| LAST TRACKING UPDATE | 2026-07-06 19:30:10 |
| ODOO DEPENDENCIES | |
| ODOO DEPENDENCIES |
OCA/contract: - contract_line_successor - contract OCA/queue: - queue_job odoo/odoo: - base - account - base_setup - web - onboarding - product - bus - web_tour - html_editor - uom - analytic - portal - web_editor - http_routing - auth_signup - digest - resource - base_sparse_field |
| PYTHON DEPENDENCIES | |
| PYTHON DEPENDENCIES |
requests |
| SYSTEM DEPENDENCIES | |
| SYSTEM DEPENDENCIES | Not have |
| DESCRIPTION | |
| DESCRIPTION | 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. |
| XML ID | Name | Model | Type | Status |
|---|---|---|---|---|
contract_contract_form_view |
contract.contract | xpath | Inherits contract.contract_contract_form_view | |
contract_line_forecast_period_graph_view |
contract.line.forecast.period.graph (in contract_forecast) | contract.line.forecast.period | graph | New |
contract_line_forecast_period_pivot_view |
contract.line.forecast.period.pivot (in contract_forecast) | contract.line.forecast.period | pivot | New |
contract_line_forecast_period_search_view |
contract.line.forecast.period | search | New | |
contract_line_forecast_period_tree_view |
contract.line.forecast.period | list | New | |
res_config_settings_form_view |
res.config.settings | xpath | Inherits contract.res_config_settings_form_view |
No new fields.
Public methods (2)action_show_contract_forecast(self)
write(self, values)
forecast_period_ids
One2many → contract.line.forecast.period
comodel_name='contract.line.forecast.period'
inverse_name='contract_line_id'
required=False
string='Forecast Periods'
create(self, vals_list)
write(self, values)
company_id
Many2one → res.company
comodel_name='res.company'
string='Company'
contract_id
Many2one → contract.contract
comodel_name='contract.contract'
index=True
ondelete='cascade'
readonly=True
related='contract_line_id.contract_id'
required=True
store=True
contract_line_id
Many2one → contract.line
comodel_name='contract.line'
index=True
ondelete='cascade'
readonly=True
required=True
currency_id
Many2one
related='contract_id.currency_id'
store=True
date_end
Date
readonly=True
required=True
date_invoice
Date
readonly=True
required=True
string='Invoice Date'
date_start
Date
readonly=True
required=True
discount
Float
digits='Discount'
help='Discount that is applied in generated invoices. It should be less or equal to 100'
string='Discount (%)'
name
Char
readonly=True
required=True
price_subtotal
Monetary
compute='_compute_price_subtotal'
store=True
string='Amount Untaxed'
price_unit
Monetary
string='Unit Price'
product_id
Many2one → product.product
comodel_name='product.product'
index=True
readonly=True
related='contract_line_id.product_id'
required=True
store=True
quantity
Float
default=1.0
required=True
sequence
Integer
related='contract_line_id.sequence'
store=True
No public methods.
contract_forecast_interval
Integer
default=12
string='Number of contract forecast Periods'
contract_forecast_rule_type
Selection
default='monthly'
args: [('monthly', 'Month(s)'), ('yearly', 'Year(s)')]
enable_contract_forecast
Boolean
default=True
string='Enable contract forecast'
No public methods.
contract_forecast_interval
Integer
readonly=False
related='company_id.contract_forecast_interval'
contract_forecast_rule_type
Selection
readonly=False
related='company_id.contract_forecast_rule_type'
enable_contract_forecast
Boolean
readonly=False
related='company_id.enable_contract_forecast'
No public methods.
| REPOSITORY | |
|---|---|
| REPOSITORY | OCA/contract |
| GIT | |
| GIT | https://github.com/OCA/contract.git |
| GIT FOLDER | |
| GIT FOLDER | https://github.com/OCA/contract/tree/16.0/contract_forecast |
| VERSION | |
| VERSION | 1.1.0 |
| CATEGORY | |
| CATEGORY | Uncategorized |
| LICENSE | |
| LICENSE | AGPL-3 |
| APPLICATION | |
| APPLICATION | No |
| AUTO-INSTALLABLE | |
| AUTO-INSTALLABLE | No |
| AUTHORS | |
| AUTHORS | Odoo Community Association (OCA), ACSONE SA/NV |
| MAINTAINERS | |
| MAINTAINERS | Odoo Community Association (OCA), ACSONE SA/NV |
| COMMITTERS | |
| COMMITTERS | Weblate, OCA-git-bot, oca-ci, Florent Cayré, Lena MONTENOT / Honeyxilia |
| WEBSITE | |
| WEBSITE | https://github.com/OCA/contract |
| LAST TRACKING UPDATE | |
| LAST TRACKING UPDATE | 2026-07-06 00:53:43 |
| ODOO DEPENDENCIES | |
| ODOO DEPENDENCIES |
OCA/contract: - contract OCA/queue: - queue_job odoo/odoo: - base - account - base_setup - web - product - bus - web_tour - uom - analytic - portal - web_editor - http_routing - auth_signup - digest - resource - base_sparse_field |
| PYTHON DEPENDENCIES | |
| PYTHON DEPENDENCIES |
python-dateutil requests |
| SYSTEM DEPENDENCIES | |
| SYSTEM DEPENDENCIES | Not have |
| DESCRIPTION | |
| DESCRIPTION | |
| XML ID | Name | Model | Type | Status |
|---|---|---|---|---|
contract_contract_form_view |
contract.contract.form (in contract_forcast) | contract.contract | xpath | Inherits contract.contract_contract_form_view |
contract_line_forecast_period_graph_view |
contract.line.forecast.period.graph (in contract_forecast) | contract.line.forecast.period | graph | New |
contract_line_forecast_period_pivot_view |
contract.line.forecast.period.pivot (in contract_forecast) | contract.line.forecast.period | pivot | New |
contract_line_forecast_period_search_view |
contract.line.forecast.period.search (in contract_forecast) | contract.line.forecast.period | search | New |
contract_line_forecast_period_tree_view |
contract.line.forecast.period.tree (in contract_forecast) | contract.line.forecast.period | tree | New |
res_config_settings_form_view |
res.config.settings | xpath | Inherits contract.res_config_settings_form_view |
No new fields.
Public methods (2)action_show_contract_forecast(self)
write(self, values)
forecast_period_ids
One2many → contract.line.forecast.period
comodel_name='contract.line.forecast.period'
inverse_name='contract_line_id'
required=False
string='Forecast Periods'
create(self, vals_list)
write(self, values)
company_id
Many2one → res.company
comodel_name='res.company'
string='Company'
contract_id
Many2one → contract.contract
comodel_name='contract.contract'
index=True
ondelete='cascade'
readonly=True
related='contract_line_id.contract_id'
required=True
store=True
string='Contract'
contract_line_id
Many2one → contract.line
comodel_name='contract.line'
index=True
ondelete='cascade'
readonly=True
required=True
string='Contract Line'
date_end
Date
readonly=True
required=True
date_invoice
Date
readonly=True
required=True
string='Invoice Date'
date_start
Date
readonly=True
required=True
discount
Float
digits='Discount'
help='Discount that is applied in generated invoices. It should be less or equal to 100'
string='Discount (%)'
name
Char
readonly=True
required=True
price_subtotal
Float
compute='_compute_price_subtotal'
digits='Account'
store=True
string='Amount Untaxed'
price_unit
Float
string='Unit Price'
product_id
Many2one → product.product
comodel_name='product.product'
index=True
readonly=True
related='contract_line_id.product_id'
required=True
store=True
string='Product'
quantity
Float
default=1.0
required=True
sequence
Integer
related='contract_line_id.sequence'
store=True
string='Sequence'
No public methods.
contract_forecast_interval
Integer
default=12
string='Number of contract forecast Periods'
contract_forecast_rule_type
Selection
default='monthly'
args: [('monthly', 'Month(s)'), ('yearly', 'Year(s)')]
enable_contract_forecast
Boolean
default=True
string='Enable contract forecast'
No public methods.
contract_forecast_interval
Integer
readonly=False
related='company_id.contract_forecast_interval'
string='Number of contract forecast Periods'
contract_forecast_rule_type
Selection
readonly=False
related='company_id.contract_forecast_rule_type'
enable_contract_forecast
Boolean
readonly=False
related='company_id.enable_contract_forecast'
string='Enable contract forecast'
No public methods.
| REPOSITORY | |
|---|---|
| REPOSITORY | OCA/contract |
| GIT | |
| GIT | https://github.com/OCA/contract.git |
| GIT FOLDER | |
| GIT FOLDER | https://github.com/OCA/contract/tree/12.0/contract_forecast |
| VERSION | |
| VERSION | 1.2.0 |
| CATEGORY | |
| CATEGORY | Uncategorized |
| LICENSE | |
| LICENSE | AGPL-3 |
| APPLICATION | |
| APPLICATION | No |
| AUTO-INSTALLABLE | |
| AUTO-INSTALLABLE | No |
| AUTHORS | |
| AUTHORS | Odoo Community Association (OCA), ACSONE SA/NV |
| MAINTAINERS | |
| MAINTAINERS | Odoo Community Association (OCA), ACSONE SA/NV |
| COMMITTERS | |
| COMMITTERS | sbejaoui, Luis Felipe Mileo, OCA Transbot, oca-travis, OCA-git-bot |
| WEBSITE | |
| WEBSITE | https://github.com/OCA/contract |
| LAST TRACKING UPDATE | |
| LAST TRACKING UPDATE | 2026-07-06 00:29:15 |
| ODOO DEPENDENCIES | |
| ODOO DEPENDENCIES |
OCA/contract: - contract OCA/queue: - queue_job odoo/odoo: - base - account - base_setup - web - product - decimal_precision - bus - web_tour - uom - analytic - portal - http_routing - digest - auth_signup |
| PYTHON DEPENDENCIES | |
| PYTHON DEPENDENCIES |
python-dateutil requests |
| SYSTEM DEPENDENCIES | |
| SYSTEM DEPENDENCIES | Not have |
| DESCRIPTION | |
| DESCRIPTION | |
| XML ID | Name | Model | Type | Status |
|---|---|---|---|---|
contract_contract_form_view |
contract.contract.form (in contract_forcast) | contract.contract | xpath | Inherits contract.contract_contract_form_view |
contract_line_forecast_period_graph_view |
contract.line.forecast.period.graph (in contract_forecast) | contract.line.forecast.period | graph | New |
contract_line_forecast_period_pivot_view |
contract.line.forecast.period.pivot (in contract_forecast) | contract.line.forecast.period | pivot | New |
contract_line_forecast_period_search_view |
contract.line.forecast.period.search (in contract_forecast) | contract.line.forecast.period | search | New |
contract_line_forecast_period_tree_view |
contract.line.forecast.period.tree (in contract_forecast) | contract.line.forecast.period | tree | New |
res_config_settings_form_view |
res.config.settings | xpath | Inherits contract.res_config_settings_form_view |
No new fields.
Public methods (2)action_show_contract_forecast(self)
write(self, values)
forecast_period_ids
One2many → contract.line.forecast.period
comodel_name='contract.line.forecast.period'
inverse_name='contract_line_id'
required=False
string='Forecast Periods'
create(self, values)
write(self, values)
company_id
Many2one → res.company
comodel_name='res.company'
string='Company'
contract_id
Many2one → contract.contract
comodel_name='contract.contract'
index=True
ondelete='cascade'
readonly=True
related='contract_line_id.contract_id'
required=True
store=True
string='Contract'
contract_line_id
Many2one → contract.line
comodel_name='contract.line'
index=True
ondelete='cascade'
readonly=True
required=True
string='Contract Line'
date_end
Date
readonly=True
required=True
string='Date End'
date_invoice
Date
readonly=True
required=True
string='Invoice Date'
date_start
Date
readonly=True
required=True
string='Date Start'
discount
Float
digits=dp.get_precision('Discount')
help='Discount that is applied in generated invoices. It should be less or equal to 100'
string='Discount (%)'
name
Char
readonly=True
required=True
string='Name'
price_subtotal
Float
compute='_compute_price_subtotal'
digits=dp.get_precision('Account')
store=True
string='Amount Untaxed'
price_unit
Float
string='Unit Price'
product_id
Many2one → product.product
comodel_name='product.product'
index=True
readonly=True
related='contract_line_id.product_id'
required=True
store=True
string='Product'
quantity
Float
default=1.0
required=True
sequence
Integer
related='contract_line_id.sequence'
store=True
string='Sequence'
No public methods.
contract_forecast_interval
Integer
default=12
string='Number of contract forecast Periods'
contract_forecast_rule_type
Selection
default='monthly'
args: [('monthly', 'Month(s)'), ('yearly', 'Year(s)')]
enable_contract_forecast
Boolean
default=True
string='Enable contract forecast'
No public methods.
contract_forecast_interval
Integer
default=12
readonly=False
related='company_id.contract_forecast_interval'
string='Number of contract forecast Periods'
contract_forecast_rule_type
Selection
default='monthly'
readonly=False
related='company_id.contract_forecast_rule_type'
args: [('monthly', 'Month(s)'), ('yearly', 'Year(s)')]
enable_contract_forecast
Boolean
default=True
readonly=False
related='company_id.enable_contract_forecast'
string='Enable contract forecast'
No public methods.
| STATUS | |
|---|---|
| STATUS | Open migration PR - not merged yet for this version |
| REPOSITORY | |
| REPOSITORY | OCA/contract |
| PULL REQUEST | |
| PULL REQUEST | [19.0][MIG] contract_forecast (#1464) |