Problem/Motivation

  • CRM ships Group relation plugins (GroupContact, deriver) in the main crm module while group is not a dependency. That works when Group is enabled, but Group-specific integration cannot grow in crm without either hard-depending on Group or weaker workarounds.
  • We need two distinct Group integration concepts:
    • Existing: CRM contacts as group content via the GroupContact relation (members, roster, group-scoped contact permissions).
    • New: A group represents one canonical CRM contact (principal/workspace) — e.g. organization, household, or custom contact type — with enforced uniqueness, configuration per group type, and access for group members to edit that contact.
  • CRM-only sites (no Group) must remain supported.
  • Sites that already use CRM + Group must keep current behavior after upgrade without manual reconfiguration.

Steps to reproduce

  1. Enable crm and group.
  2. Configure a group type; install “Group contact (Person|Organization|Household)” relations.
  3. Add CRM contacts to a group as content — works today via plugins in crm.
  4. There is no supported way to model “this group represents contact X” with uniqueness, API, or group-scoped edit access for that principal contact.

Proposed resolution

Add submodule crm_group

  • Dependencies: crm:crm, group:group.
  • Update group integration documentation to require crm_group when using Group with CRM.

Upgrade path (preserve existing users)

  • Ship crm_group in the same project as crm.
  • On crm update: post-update hook and/or hook_modules_installed() in crm — if group is already enabled, install crm_group automatically when the extension is present and not yet enabled.
  • After upgrade, existing “Group contact” relations and adding contacts to groups should behave as before.

New: group represents a contact

  • Add entity crm_group_contact_mapping as source of truth:
    • group (entity reference, required), crm_contact (entity reference, required), denormalized and group_type.
    • Unique: one mapping per group; one group per contact per group_type.
  • GroupContactMappingService and event(s), parallel to crm_user_contact_mapping (ensure, load, validate, delete).
  • Third-party settings on group.type.* (CRM): represent_contact, allowed_contact_bundles (label sync / auto-create may be follow-up issues if deferred).
  • Group permissions for represented contact (view, edit); extend CRM contact access for group members — principal is not required to be group content.
  • Display principal on the group via a computed field (or equivalent) loaded from the mapping, with cache tags cleared when the mapping changes — not a stored synced entity reference on the group.
  • Group edit form: control to assign or change principal contact; writes the mapping only.
  • Admin UI for mappings (list, add, edit, delete), similar to user contact mappings.
  • Member contacts remain GroupContact group content; principal contact remains the mapping entity only.

Remaining tasks

  • Scaffold crm_group (info, services, permissions, routing).
  • Implement crm_group_contact_mapping entity, constraints, and admin UI.
  • Implement mapping service and event(s).
  • Group type CRM third-party settings form and validation against allowed_contact_bundles.
  • Represented-contact group permissions and contact access integration.
  • Computed principal contact on applicable group bundles; group form integration.
  • crm post-update / hook_modules_installed() to install crm_group when group is present; uninstall symmetry.
  • Update docs/integration/group-integration.md (member vs principal, enable crm_group).
  • Tests: auto-install on update; mapping uniqueness and bundle rules; represented-contact access; computed field cache invalidation.

User interface changes

  • crm_group on Extend (requires CRM and Group).
  • After upgrade, sites with Group enabled should get crm_group enabled automatically unless opted out.
  • Admin screens for group–contact mappings.
  • Group type edit: CRM settings (represent contact, allowed contact bundles).
  • Group type roles: permissions for represented contact.
  • Group edit/view: principal contact (computed); form to set principal where configured.
  • Existing “Group contact (…)” UI unchanged in behavior.

API changes

  • New extension crm_group.
  • New entity type crm_group_contact_mapping and mapping service (machine name TBD).
  • New event(s) for altering mapping on create/update (names TBD).
  • Third-party settings on group.type.* under CRM key.
  • Contact access grants via group membership and represented-contact permissions.
  • crm: hooks/post-update to install crm_group when Group is present.
  • No intentional API changes to crm_contact, crm_relationship, or crm_user_contact_mapping.

Data model changes

  • New table for crm_group_contact_mapping: id, uuid, group, crm_contact, group_type, created, changed.
  • Unique constraints on group and on (crm_contact, group_type).
  • No change to existing contact, relationship, or group content storage for member contacts.
  • No stored principal entity reference field on the group entity.
  • Config: CRM Group third-party settings on group types.

Issue fork crm-3591445

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

bluegeek9 created an issue. See original summary.

bluegeek9’s picture

Category: Feature request » Plan
bluegeek9’s picture

The existing group plugin could stay with CRM, and a seperate project that makes the contact map to a group could be a seperate project.

mortona2k made their first commit to this issue’s fork.

mortona2k’s picture

Assigned: Unassigned » mortona2k
Issue summary: View changes

Agree with #3. This should make crm_group functionality optional, for sites that want to do the integration differently, but still want the existing group/contact relation plugins.

mortona2k’s picture

Here's the new group type settings.

Group type edit form for CRM integration

mortona2k’s picture

Here's the primary contact field on the group edit form. It is synced from the crm_group_contact_mapping entity after that is created.

This probably needs adjustment. It's confusing to create the Group before the contact, and if the automatic setting is selected, corresponding groups should automatically be created if there is are existing contacts, and if a group is created before the contact, the corresponding contact could be generated with the same name (or creating the group first just doesn't make sense).

This is in violation of "No stored principal entity reference field on the group entity." but I wasn't sure what else to do. It's an entity reference field, but the intent is to manage it from crm_group_contact_mapping.

Only local images are allowed.

mortona2k’s picture

Issue summary: View changes

Removed mentions of moving GroupContact relationship plugin.

bluegeek9’s picture

Status: Active » Needs work
mortona2k’s picture

Status: Needs work » Active

I think we need to specify a way for contacts with a given relationship to automatically be added as group contacts, or members of the group with a role.

For example, contacts with an employee relationship get automatically added as group content so they can be viewed and edited by members of the group. And contacts with an admin relationship get added as members of the group with an admin role that grants edit permissions.

mortona2k’s picture

Status: Active » Needs work

We'll also need way to re-sync things if config is changed, or if this module is added to an existing site.

bluegeek9 changed the visibility of the branch 1.0.x to hidden.

bluegeek9’s picture

Assigned: mortona2k » bluegeek9
Category: Plan » Task
Status: Needs work » Active

I created a new project: https://www.drupal.org/project/crm_group

The crm project needs to integrate with core modules, and has a larger than average code base. The group content plugin will remain in the crm namespace, but the rest of the group integration will live in crm_group.

bluegeek9’s picture

Assigned: bluegeek9 » Unassigned
Status: Active » Fixed
//www.flaticon.com/free-icons/thank-you Thank you for your contribution! Your continued support makes this project sustainable.
There are multiple ways to show appreciation for the work contributed to this project including:
  • Triage issues and adding more context to existing issues.
  • Flagging CRM as a favorite on the project page to help others discover it and show your support.
  • Review the Developer Docs for accuracy and clarity.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

  • bluegeek9 committed c3c14cf1 on 1.0.x
    task: #3591445 Integrate Group: Contact as a Group
    

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.