Skip to Content
Odoo Menu
  • Sign in
  • Try it free
  • Apps
    Finance
    • Accounting
    • Invoicing
    • Expenses
    • Spreadsheet (BI)
    • Documents
    • Sign
    Sales
    • CRM
    • Sales
    • POS Shop
    • POS Restaurant
    • Subscriptions
    • Rental
    Websites
    • Website Builder
    • eCommerce
    • Blog
    • Forum
    • Live Chat
    • eLearning
    Supply Chain
    • Inventory
    • Manufacturing
    • PLM
    • Purchase
    • Maintenance
    • Quality
    Human Resources
    • Employees
    • Recruitment
    • Time Off
    • Appraisals
    • Referrals
    • Fleet
    Marketing
    • Social Marketing
    • Email Marketing
    • SMS Marketing
    • Events
    • Marketing Automation
    • Surveys
    Services
    • Project
    • Timesheets
    • Field Service
    • Helpdesk
    • Planning
    • Appointments
    Productivity
    • Discuss
    • Approvals
    • IoT
    • VoIP
    • Knowledge
    • WhatsApp
    Third party apps Odoo Studio Odoo Cloud Platform
  • Industries
    Retail
    • Book Store
    • Clothing Store
    • Furniture Store
    • Grocery Store
    • Hardware Store
    • Toy Store
    Food & Hospitality
    • Bar and Pub
    • Restaurant
    • Fast Food
    • Guest House
    • Beverage Distributor
    • Hotel
    Real Estate
    • Real Estate Agency
    • Architecture Firm
    • Construction
    • Property Management
    • Gardening
    • Property Owner Association
    Consulting
    • Accounting Firm
    • Odoo Partner
    • Marketing Agency
    • Law firm
    • Talent Acquisition
    • Audit & Certification
    Manufacturing
    • Textile
    • Metal
    • Furnitures
    • Food
    • Brewery
    • Corporate Gifts
    Health & Fitness
    • Sports Club
    • Eyewear Store
    • Fitness Center
    • Wellness Practitioners
    • Pharmacy
    • Hair Salon
    Trades
    • Handyman
    • IT Hardware & Support
    • Solar Energy Systems
    • Shoe Maker
    • Cleaning Services
    • HVAC Services
    Others
    • Nonprofit Organization
    • Environmental Agency
    • Billboard Rental
    • Photography
    • Bike Leasing
    • Software Reseller
    Browse all Industries
  • Community
    Learn
    • Tutorials
    • Documentation
    • Certifications
    • Training
    • Blog
    • Podcast
    Empower Education
    • Education Program
    • Scale Up! Business Game
    • Visit Odoo
    Get the Software
    • Download
    • Compare Editions
    • Releases
    Collaborate
    • Github
    • Forum
    • Events
    • Translations
    • Become a Partner
    • Services for Partners
    • Register your Accounting Firm
    Get Services
    • Find a Partner
    • Find an Accountant
      • Get a Tailored Demo
    • Implementation Services
    • Customer References
    • Support
    • Upgrades
    Github Youtube Twitter Linkedin Instagram Facebook Spotify
    +32 2 290 34 90
    • Get a Tailored Demo
  • Pricing
  • Help
  1. APPS
  2. Sales
  3. Contact Guard v 19.0
  4. Sales Conditions FAQ

Contact Guard

by SuiteState https://suitestate.com
Odoo
v 19.0 Third Party 14
Download for v 19.0 Deploy on Odoo.sh
Apps purchases are linked to your Odoo account, please sign in or sign up first.
Availability
Odoo Online
Odoo.sh
On Premise
Odoo Apps Dependencies • Contacts (contacts)
• Discuss (mail)
• Purchase (purchase)
• Invoicing (account)
Lines of code 570
Technical Name suite_contact_guard
LicenseLGPL-3
Websitehttps://suitestate.com
You bought this module and need support? Click here!
Availability
Odoo Online
Odoo.sh
On Premise
Odoo Apps Dependencies • Contacts (contacts)
• Discuss (mail)
• Purchase (purchase)
• Invoicing (account)
Lines of code 570
Technical Name suite_contact_guard
LicenseLGPL-3
Websitehttps://suitestate.com

Contact Guard

Phone uniqueness, contact field permissions, and customer activity status for Odoo 19


Overview

Contact Guard adds three independent governance layers on res.partner:

  • ORM-enforced phone uniqueness, scoped per company
  • Role-based visibility and edit protection on phone, email, and salesperson fields
  • Daily-cron customer activity status (Active / Warning / Sleeping / Dormant) computed from confirmed sale orders

All features are configured per company. None introduce database-level constraints; enforcement happens at the ORM, field, or view layer depending on the rule.


Design principles

This module is designed around the following principles. They explain the technical decisions in subsequent sections.

  • Partner records remain globally readable. All internal users can read res.partner records. Restricting partner read access via ir.rule is not used.
  • Cross-team workflows are preserved. Accounting, Warehouse, Purchase, HR, and CRM modules continue to access partner records through their normal references (invoice addresses, delivery addresses, vendor records, employee partners, lead partners).
  • Protection is applied at the field level. Phone, email, and salesperson are the protected fields. Visibility and edit rules are applied per-field via field-level groups=, ORM write hooks, and view-level groups=.
  • Per-company scoping. Every check, threshold, and configuration is scoped to a single company. Multi-company installations get independent configurations per company.

Functionality

1. Phone uniqueness

Phone numbers are normalized to digits-only (stripping +, leading 00, spaces, dashes, parentheses) and stored in an indexed field for duplicate detection.

When a contact is created or its phone field updated with a value already present in the same company, the operation is rejected with an error message identifying the conflicting number.

The check is bypassed in the following scenarios:

  • env.su (system automation, migrations, lead-to-contact sync)
  • Bulk imports via the standard Import Wizard (import_file context)
  • Public users (anonymous self-signup visitors)
  • Portal users (external customers managing their own data)
  • Explicit suite_skip_phone_check context flag

The minimum digit length is configurable per company. Default: 8.

Phone uniqueness duplicate detection

2. Contact field permissions

Phone, email, and salesperson visibility are gated by role. Once a contact has an assigned salesperson, the phone and email fields become accessible only to the assigned salesperson and to administrators. Contacts without an assigned salesperson remain accessible to all internal users.

The salesperson field can be set freely on contact creation (supporting CRM lead-to-contact conversion that carries the lead's salesperson). After creation, only Contact Guard Administrators can reassign the salesperson.

Phone edit protection is enforced at the ORM layer. The protection applies to all code paths including web UI, RPC calls, scripts, and automated actions.

Phone and email visibility per salesperson

3. Customer activity status

When enabled per company, a daily cron computes each customer's activity status from the date of their last confirmed sale order:

Status Condition
Active days since last order < warning threshold
Warning warning ≤ days < sleeping
Sleeping sleeping ≤ days < dormant
Dormant days ≥ dormant
Blank no confirmed sale order on record

The blank status is tracked via a separate suite_has_orders boolean so that "0 days since order" (just placed) and "never ordered" remain distinguishable in views.

Thresholds are configurable per company. The status is displayed on the contact form (Activity Status tab) and the contact list (with colour decoration: yellow for Warning, red for Sleeping, muted grey for Dormant). It is available for filtering and grouping.

The cron processes customers in batches of 1000 with chatter notifications suppressed.

Customer activity status with colour decoration


Permissions

Roles

Role Group Source
Contact Guard Administrator suite_contact_guard.group_contact_guard_admin Added by this module
Sales Manager sales_team.group_sale_manager Native; implies Contact Guard Admin
Contact Manager base.group_partner_manager Native
Purchase Manager purchase.group_purchase_manager Native
Purchase User purchase.group_purchase_user Native
Salesperson of the contact partner.user_id == self.env.user Per-record relationship

The Sales Manager group implies Contact Guard Administrator (one-way implication). Granting Contact Guard Administrator alone does not grant Sales Manager privileges. This allows assigning Contact Guard Administrator to roles outside the sales hierarchy without granting Sales Manager privileges.

Permission matrix

In the table below, Salesperson means the user assigned as salesperson on that specific contact. SM/CGA means Sales Manager or Contact Guard Administrator (equivalent for Contact Guard operations).

Operation Internal User Salesperson of contact Purchase Manager Contact Manager SM / CGA
See phone/email column in list and kanban No No No Yes Yes
See phone/email on form (contact has no salesperson) Yes - Yes Yes Yes
See phone/email on form (contact has salesperson) No Yes No Yes Yes
First-time fill of phone (was empty) Yes Yes Yes Yes Yes
Edit existing phone (no salesperson) No No Yes Yes Yes
Edit existing phone (with salesperson) No No No Yes Yes
Set salesperson on contact creation Yes Yes Yes Yes Yes
Change salesperson on existing contact No No No No Yes
See Activity Status (form tab and list columns) No No No Yes Yes

Enforcement layers

The module enforces these rules at three layers:

  1. ORM layer — Phone edit protection and salesperson change protection are enforced in res.partner.write. Applies to web UI, RPC, scripts, and automated actions. Bypassed only by env.su, import_file context, suite_skip_phone_check context, or for public/portal users.
  2. Field-level groups= — Activity Status fields (suite_last_order_date, suite_days_since_order, suite_activity_status, suite_has_orders) carry groups= on the model. The ORM strips them from search_read, read, exports, and API calls for unauthorized users.
  3. View-level groups= — List columns, kanban card sections, and form pages with groups= are removed from the view arch on the server before being sent to the client.

Implementation notes

Form-level visibility: scope and limitation

Phone and email visibility on the contact form is controlled by an invisible= expression rather than field-level groups=. This is a deliberate design choice. The native Odoo phone and email fields do not carry model-level groups, and adding model-level groups to them would break compatibility with every other module that reads these fields (CRM, Sales, Accounting, WhatsApp, etc.).

The practical implication:

  • The list and kanban views use field-level groups= on the column, which strip data on the server side. Column-level hiding is data-tight.
  • The form view uses invisible=. The field values are sent to the client and hidden by the UI. A technically capable user (browser DevTools, custom RPC client) can read the values.

Deployments requiring data-tight protection on the form must use record rules instead of this module. The trade-off is documented in the next section.

Comparison: field-level approach vs record rules on res.partner

Two technical approaches can implement contact privacy in Odoo: restricting record visibility via ir.rule on res.partner, or restricting field visibility via field-level groups= and ORM hooks. This module uses the latter. The comparison documents the technical differences.

Aspect Record rule on res.partner Field-level + ORM hooks (this module)
Phone/email column hiding in lists and kanban Yes Yes (server-side stripping via field groups=)
Phone/email value hiding on form Data-tight (record not loaded) UI-level via invisible=
Salesperson opens own quotation referencing partner Requires OR clauses on partner_invoice_id, partner_shipping_id Works without modification
User login (res.users self-reference) Requires explicit self-reference carve-out Works without modification
Multi-company partner (companion of res.company) Requires explicit OR clause Works without modification
Chatter, followers, activity assignment on partner-related records Requires carve-outs to prevent Implicitly accessed through 'Users' errors Works without modification
Cross-team partner access (Accounting, Warehouse, Purchase, HR) Restricted to record owners; each cross-team workflow requires per-team carve-outs Unrestricted; partner records remain readable while phone/email/salesperson are gated by role
Maintenance after Odoo upgrades or new module installation Carve-outs may require re-validation when related models add new partner references Stable; relies on Odoo APIs (groups=, invisible=, write hooks) that have remained stable across versions

Cross-team partner access

In typical Odoo deployments, the partner record is referenced by multiple modules:

  • Accounting — invoice addresses, payment partners, bank account holders
  • Warehouse / Inventory — delivery addresses, vendor records on incoming transfers
  • Purchase — vendor records on purchase orders and bills
  • HR — employee records and related contacts
  • CRM — lead and opportunity partners

The field-level approach used in this module preserves cross-team partner access. Accounting users continue to access invoice addresses. Warehouse users continue to access delivery addresses. Purchase users continue to access vendor records. The protected fields — phone, email, salesperson — are gated by role independently of partner record access.

Multi-company company_id default

In native Odoo, the company_id field on the contact form is hidden from single-company users, and Odoo defaults it to blank, which makes the contact globally visible across companies.

This module injects the user's active company as the default company_id on contact creation, so single-company deployments get the same per-company scoping that multi-company deployments configure manually.

The injection is suppressed when the contact is being auto-created as the companion partner of a new res.company. In that case, Odoo's native flow assigns the correct company id, and the injection would otherwise overwrite it with the current active company's id, breaking downstream routing for the new company.


Configuration

Configuration is located at Contacts → Configuration → Contact Guard (visible to System Administrators).

Protection features are active by default and do not require a configuration record. Phone uniqueness, field permissions, and salesperson lock activate when the module is installed. Configuration is only required to tune parameters or enable activity tracking.

Feature Default state Configurable parameters
Phone uniqueness On Minimum digit count (default 8)
Field permissions (phone / email / salesperson) On None; behaviour is fixed by role
Customer activity status Off Enable cron, Warning / Sleeping / Dormant thresholds

Per-company settings:

Setting Default Description
Phone Min Length 8 Minimum digit count after normalization
Track Customer Activity Off Enables the daily activity cron for the company
Warning after (days) 30 Threshold for Warning status
Sleeping after (days) 60 Threshold for Sleeping status
Dormant after (days) 90 Threshold for Dormant status

Thresholds must satisfy 0 < warning < sleeping < dormant.

Per-company configuration


Compatibility

  • Odoo 19.0 (Community and Enterprise)
  • Multi-company aware: every check and configuration is scoped per company
  • No database-level constraints; enforcement at the ORM, field, or view layer
  • Dependencies: contacts, mail, sales_team, sale, purchase (all standard Odoo modules)

License and contact

Released under LGPL-3.0. Maintained by SuiteState. Source repository: github.com/SuiteState/community. Website: suitestate.com.

Please log in to comment on this module

  • The author can leave a single reply to each comment.
  • This section is meant to ask simple questions or leave a rating. Every report of a problem experienced while using the module should be addressed to the author directly (refer to the following point).
  • If you want to start a discussion with the author, please use the developer contact information. They can usually be found in the description.
Community
  • Tutorials
  • Documentation
  • Forum
Open Source
  • Download
  • Github
  • Runbot
  • Translations
Services
  • Odoo.sh Hosting
  • Support
  • Upgrade
  • Custom Developments
  • Education
  • Find an Accountant
  • Find a Partner
  • Become a Partner
About us
  • Our company
  • Brand Assets
  • Contact us
  • Jobs
  • Events
  • Podcast
  • Blog
  • Customers
  • Legal • Privacy
  • Security

Odoo is a suite of open source business apps that cover all your company needs: CRM, eCommerce, accounting, inventory, point of sale, project management, etc.

Odoo's unique value proposition is to be at the same time very easy to use and fully integrated.

Website made with