Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
258 changes: 258 additions & 0 deletions crm_stage_validation/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,258 @@
====================
CRM Stage Validation
====================

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

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

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

This module extends the CRM functionality by allowing you to validate
that specific fields are filled when moving a lead/opportunity to a
certain stage.

Main Features
-------------

- **Field Validation per Stage**: Configure which fields must be filled
when a lead/opportunity reaches a specific stage
- **Flexible Configuration**: Select any field from the CRM lead model
to be validated
- **Clear Error Messages**: Users receive detailed validation errors
indicating which fields need to be filled
- **Multi-record Support**: Validation works when moving multiple
leads/opportunities at once

Benefits
--------

- Ensure data quality by requiring important fields at specific pipeline
stages
- Prevent leads from advancing without crucial information
- Customize validation rules for each stage of your sales pipeline
- Improve reporting accuracy by ensuring complete data at each stage

Dependencies
------------

This module requires:

- ``crm``: Odoo's CRM module

**Table of contents**

.. contents::
:local:

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

This module requires configuration of the fields to validate for each
stage.

Installation
------------

1. Go to the **Apps** menu
2. Remove the "Apps" filter if necessary
3. Search for "CRM Stage Validation"
4. Click **Install**

Configuration
-------------

**Setting up Field Validation for Stages**

1. Go to **CRM > Configuration > Stages**
2. Select a stage you want to configure
3. In the **Stage Validation** section, find the **Fields to Validate**
field
4. Select one or more fields that must be filled when a lead/opportunity
reaches this stage
5. Save the stage

**Example Configuration**

For a "Proposition" stage, you might require:

- **Expected Closing** - to ensure a deadline is set
- **Expected Revenue** - to track potential revenue
- **Contact Name** - to ensure a contact person is identified

For a "Won" stage, you might require:

- **Expected Revenue** - to ensure the deal value is recorded
- **Partner** - to ensure a customer is linked

Permissions
-----------

The module uses the same access permissions as the base CRM module:

- Users with access to **CRM Configuration** can configure field
validation on stages
- All CRM users are subject to the validation rules when moving
leads/opportunities

No additional permission configuration is required.

Usage
=====

This guide explains how to use the CRM Stage Validation module to
enforce data quality in your sales pipeline.

How Validation Works
--------------------

When a user attempts to move a lead/opportunity to a stage that has
validation rules configured, the system will:

1. Check if all required fields are filled
2. If any required field is empty, display a validation error
3. Block the stage change until all required fields are completed

Working with Validated Stages
-----------------------------

**Moving a Lead/Opportunity**

1. Open a lead/opportunity in the CRM
2. Try to move it to a stage with validation rules (drag-and-drop in
kanban or change stage in form)
3. If validation fails, you will see an error message like:
"Lead/Opportunity [Name] can't be moved to the stage [Stage Name]
until the following fields are set: [Field Names]."

4. Fill in the required fields
5. Try moving the lead/opportunity again

**Bulk Operations**

When moving multiple leads/opportunities at once:

- Each record is validated individually
- All validation errors are displayed together
- No records are moved until all validations pass

Validation Error Messages
-------------------------

The validation error message includes:

- The name of the lead/opportunity that failed validation
- The name of the target stage
- A list of all fields that need to be filled

**Example Error Message:**

Lead/Opportunity "Big Deal Corp" can't be moved to the stage
"Proposition" until the following fields are set: Expected Closing,
Expected Revenue.

Usage Examples
--------------

**Example 1: Requiring Expected Revenue at Proposition Stage**

1. Configure the "Proposition" stage to require "Expected Revenue"
2. User tries to move a lead to "Proposition" without filling expected
revenue
3. System displays: "Lead/Opportunity can't be moved to the stage
Proposition until the following fields are set: Expected Revenue."
4. User fills in the expected revenue
5. Lead is successfully moved to "Proposition"

**Example 2: Multiple Required Fields**

1. Configure the "Negotiation" stage to require "Expected Closing" and
"Contact Name"
2. User tries to move an opportunity to "Negotiation" with only contact
name filled
3. System displays the validation error for "Expected Closing"
4. User fills in the expected closing date
5. Opportunity is successfully moved to "Negotiation"

**Example 3: Batch Move Validation**

1. User selects 5 opportunities in kanban view
2. User drags them to a stage requiring "Expected Revenue"
3. 2 opportunities don't have expected revenue filled
4. System displays validation errors for those 2 opportunities
5. User fills in the missing data
6. Retries the batch move successfully

Tips
----

- Start with key fields that are essential for your sales process
- Don't over-configure - too many required fields can slow down your
team
- Use validation strategically at milestone stages (Qualification,
Proposition, Negotiation)
- Review your validation rules periodically to ensure they match your
current process
- Train your team on the validation requirements to avoid frustration

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

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

* Escodoo

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

- `ESCODOO <https://escodoo.com.br>`__:

- Marcel Savegnago marcel.savegnago@escodoo.com.br

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.

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

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
1 change: 1 addition & 0 deletions crm_stage_validation/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
13 changes: 13 additions & 0 deletions crm_stage_validation/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright 2025 Escodoo
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "CRM Stage Validation",
"summary": "Validate input data when reaching a CRM Lead/Opportunity stage",
"version": "16.0.1.0.0",
"category": "Sales/CRM",
"author": "Escodoo, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/crm",
"depends": ["crm"],
"data": ["views/crm_stage_views.xml"],
"license": "AGPL-3",
}
2 changes: 2 additions & 0 deletions crm_stage_validation/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import crm_lead
from . import crm_stage
49 changes: 49 additions & 0 deletions crm_stage_validation/models/crm_lead.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Copyright 2025 Marcel Savegnago - Escodoo <https://escodoo.com.br>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import _, api, models
from odoo.exceptions import ValidationError


class CrmLead(models.Model):
_inherit = "crm.lead"

def _check_lead_has_empty_fields(self):
self.ensure_one()
error_message = False
field_ids = self.stage_id.sudo().validate_field_ids
field_names = [x.name for x in field_ids]
if not field_names:
return error_message
values = self.sudo().read(field_names)
labels = self.sudo().fields_get(field_names, attributes=["string"])
fields = [
labels[field.name]["string"]
for field in field_ids
if not values[0][field.name]
]
fields = ", ".join(fields)
if fields:
error_message = _(
"Lead/Opportunity %(lead)s can't be moved to the stage %(stage)s "
"until the following fields are set: %(fields)s.",
lead=self.name,
stage=self.stage_id.name,
fields=fields,
)
return error_message

def _validate_stage_fields_error_message(self):
error_message = []
for record in self:
message = record._check_lead_has_empty_fields()
if message:
error_message.append(message)
return error_message

@api.constrains("stage_id")
def _validate_stage_fields(self):
message = self._validate_stage_fields_error_message()
if message:
message = "\n".join(message)
raise ValidationError(message)
15 changes: 15 additions & 0 deletions crm_stage_validation/models/crm_stage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copyright 2025 Marcel Savegnago - Escodoo <https://escodoo.com.br>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import fields, models


class CrmStage(models.Model):
_inherit = "crm.stage"

validate_field_ids = fields.Many2many(
"ir.model.fields",
string="Fields to Validate",
help="Select fields which must be set on the document in this stage",
domain='[("model", "=", "crm.lead")]',
)
38 changes: 38 additions & 0 deletions crm_stage_validation/readme/CONFIGURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
This module requires configuration of the fields to validate for each stage.

## Installation

1. Go to the **Apps** menu
2. Remove the "Apps" filter if necessary
3. Search for "CRM Stage Validation"
4. Click **Install**

## Configuration

**Setting up Field Validation for Stages**

1. Go to **CRM > Configuration > Stages**
2. Select a stage you want to configure
3. In the **Stage Validation** section, find the **Fields to Validate** field
4. Select one or more fields that must be filled when a lead/opportunity reaches this stage
5. Save the stage

**Example Configuration**

For a "Proposition" stage, you might require:
* **Expected Closing** - to ensure a deadline is set
* **Expected Revenue** - to track potential revenue
* **Contact Name** - to ensure a contact person is identified

For a "Won" stage, you might require:
* **Expected Revenue** - to ensure the deal value is recorded
* **Partner** - to ensure a customer is linked

## Permissions

The module uses the same access permissions as the base CRM module:
* Users with access to **CRM Configuration** can configure field validation on stages
* All CRM users are subject to the validation rules when moving leads/opportunities

No additional permission configuration is required.

2 changes: 2 additions & 0 deletions crm_stage_validation/readme/CONTRIBUTORS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- [ESCODOO](https://escodoo.com.br):
- Marcel Savegnago <marcel.savegnago@escodoo.com.br>
Loading