Skip to main content

Organization Model

The Organization model represents a tenant in the multi-tenant OPBX system. All data is scoped to an organization, providing complete data isolation between tenants.

Overview

PropertyValue
NamespaceApp\Models
Tableorganizations
Primary Keyid
Soft DeletesYes

Database Schema

ColumnTypeNullableDefaultDescription
idbigint unsignedNoautoPrimary key
namevarchar(255)No-Organization name
slugvarchar(255)No-URL-friendly identifier (auto-generated)
statusvarchar(50)NoactiveOrganization status
timezonevarchar(100)NoUTCDefault timezone
settingsjsonYesnullOrganization configuration
deleted_attimestampYesnullSoft delete timestamp
created_attimestampNo-Creation timestamp
updated_attimestampNo-Last update timestamp

Indexes

  • PRIMARY on id
  • UNIQUE on slug
  • INDEX on status

Attributes

Fillable

protected $fillable = [
'name',
'slug',
'status',
'timezone',
'settings',
];

Casts

AttributeCastDescription
settingsarrayJSON array for flexible configuration

Lifecycle Hooks

Boot - Auto-generate Slug

When creating an organization, the slug is automatically generated from the name if not provided:

static::creating(function (Organization $organization): void {
if (empty($organization->slug)) {
$organization->slug = Str::slug($organization->name);
}
});

Example:

  • Name: "Acme Corporation"
  • Auto-generated slug: "acme-corporation"

Relationships

Has Many

users(): HasMany

All users belonging to this organization.

$organization->users; // Collection of User models
$organization->users()->count(); // User count

extensions(): HasMany

All extensions in this organization.

$organization->extensions; // Collection of Extension models

didNumbers(): HasMany

All DID numbers assigned to this organization.

$organization->didNumbers; // Collection of DidNumber models

ringGroups(): HasMany

All ring groups in this organization.

$organization->ringGroups; // Collection of RingGroup models

businessHoursSchedules(): HasMany

All business hours schedules for this organization.

$organization->businessHoursSchedules; // Collection of BusinessHoursSchedule

callLogs(): HasMany

All call logs for this organization.

$organization->callLogs; // Collection of CallLog models

Has One

cloudonixSettings(): HasOne

Cloudonix integration settings for this organization.

$organization->cloudonixSettings; // CloudonixSettings model or null

Methods

isActive(): bool

Check if the organization is active.

if ($organization->isActive()) {
// Organization can use the system
}

Settings Structure

The settings JSON column stores organization-specific configuration:

{
"features": {
"call_recording": false,
"voicemail": true,
"music_on_hold": true,
"call_waiting": true
},
"ui": {
"language": "en",
"date_format": "Y-m-d",
"time_format": "H:i"
},
"pbx": {
"default_extension_length": 4,
"extension_range_start": "1000",
"extension_range_end": "9999"
}
}

Default Settings

When creating an organization, default settings are applied:

$defaults = [
'features' => [
'call_recording' => false,
'voicemail' => true,
'music_on_hold' => true,
'call_waiting' => true,
],
'ui' => [
'language' => 'en',
'date_format' => 'Y-m-d',
'time_format' => 'H:i',
],
'pbx' => [
'default_extension_length' => 4,
'extension_range_start' => '1000',
'extension_range_end' => '9999',
],
];

Usage Examples

Creating an Organization

use App\Models\Organization;

$organization = Organization::create([
'name' => 'Acme Corporation',
'timezone' => 'America/New_York',
'settings' => [
'features' => [
'call_recording' => true,
'voicemail' => true,
],
],
]);

// Slug is auto-generated: "acme-corporation"

Checking Status

$organization = Organization::find(1);

if ($organization->isActive()) {
// Allow operations
} else {
// Organization suspended or inactive
}
$organization = Organization::with([
'users',
'extensions',
'didNumbers',
'cloudonixSettings'
])->find(1);

// Count resources
$userCount = $organization->users->count();
$extensionCount = $organization->extensions->count();

// Get Cloudonix settings
$apiKey = $organization->cloudonixSettings?->api_key;

Updating Settings

$organization = Organization::find(1);

// Get current settings
$settings = $organization->settings ?? [];

// Modify
$settings['features']['call_recording'] = true;

// Save
$organization->update(['settings' => $settings]);

Soft Delete

// Delete (soft)
$organization->delete();

// Check if deleted
if ($organization->trashed()) {
// Organization is soft-deleted
}

// Restore
$organization->restore();

// Force delete (permanent)
$organization->forceDelete();

Multi-Tenancy

All models that belong to an organization use the OrganizationScope global scope:

#[ScopedBy([OrganizationScope::class])]
class User extends Model
{
// Automatically filtered by organization_id
}

This ensures complete data isolation between organizations.