Skip to content

Entities

Entities are the core records in the CRM — they represent people, companies, or organizations.

Entity Model

Field Type Default Description
name str required Entity name (unique)
legal_name str \| None None Legal/registered name
status Literal['Active', 'Inactive'] 'Active' Entity status
note str \| None None Free-text note
assigned_to User \| None None Owner (FK to User)
custom_fields dict[str, Any] \| None None Custom field values (via CustomFieldsMixin)
created_at datetime auto Creation timestamp (via TimestampMixin)
updated_at datetime auto Last update timestamp (via TimestampMixin)

The EntityManager automatically calls select_related('assigned_to') on all queries.

Example

from amsdal_crm.models.entity import Entity

# Create an entity
entity = Entity(
    name='Acme Corp',
    legal_name='Acme Corporation Ltd.',
    status='Active',
    note='Key enterprise client',
)
entity.save(force_insert=True)

EntityRelationship

Many-to-many relationships between entities.

Field Type Default Description
from_entity Entity required Source entity (FK)
to_entity Entity required Target entity (FK)
start_date str \| None None Relationship start date
end_date str \| None None Relationship end date
relationship_group_name str \| None None Group/type of relationship
custom_fields dict[str, Any] \| None None Custom field values
created_at / updated_at datetime auto Timestamps

EntityIdentifier

Unique identifiers for an entity (e.g., tax ID, registration number).

Field Type Default Description
entity Entity required Parent entity (FK)
value str required Identifier value
country str \| None None Country code
is_primary bool False Whether this is the primary identifier

EntityContactPoint

Contact information for an entity (email, phone, etc.).

Field Type Default Description
entity Entity required Parent entity (FK)
value str required Contact point value (email, phone, etc.)
is_primary bool False Whether this is the primary contact point
can_contact bool True Whether the entity can be contacted via this point

Example

from amsdal_crm.models.entity import EntityContactPoint

contact_point = EntityContactPoint(
    entity=entity,
    value='info@acme.com',
    is_primary=True,
    can_contact=True,
)
contact_point.save(force_insert=True)

EntityAddress

Physical addresses for an entity.

Field Type Default Description
line1 str \| None required Address line 1
line2 str \| None None Address line 2
city str \| None required City
region str \| None None Region/State
postal_code str \| None None Postal code
country str \| None required Country
is_primary bool False Whether this is the primary address

Example

from amsdal_crm.models.entity import EntityAddress

address = EntityAddress(
    line1='123 Main Street',
    city='San Francisco',
    region='CA',
    postal_code='94105',
    country='US',
    is_primary=True,
)
address.save(force_insert=True)

Permissions

Entity, and all related models, use the owner-based permission model:

  • The user in assigned_to has full access
  • Users with the super_admin scope have full access
  • Unauthenticated users have no access

Lifecycle Hooks

Entity triggers workflow rules on update via post_update() / apost_update():

# Automatically called after entity.save() on update
WorkflowService.execute_rules('Entity', 'update', entity)

Custom fields are validated on both create and update via pre_create() / pre_update() hooks from the CustomFieldsMixin.