feat: add has_elevator to Address, contact/access fields to AddressAssignment

- Address: has_elevator (bool) column for building elevator status
- AddressAssignment: name_on_door, email, phone, floor, door columns
  for context-specific contact and access info
- AddressAssignment: effective_floor/effective_door accessors
  (assignment overrides base address)
This commit is contained in:
Fabian @ Blax Software 2026-04-17 07:07:11 +02:00
parent 64d2b70ce7
commit 903cd3bb08
3 changed files with 63 additions and 2 deletions

View File

@ -76,6 +76,10 @@ return new class extends Migration
// Altitude in metres above mean sea level (AMSL). Positive = above, negative = below.
$table->decimal('altitude', 10, 2)->nullable();
// ── Building amenities ───────────────────────────────────
// Whether the building has an elevator (relevant for moving, deliveries).
$table->boolean('has_elevator')->default(false);
// ── Additional properties ───────────────────────────────
// Free-form notes (e.g. delivery instructions, landmark descriptions).
$table->text('notes')->nullable();
@ -187,6 +191,28 @@ return new class extends Migration
// Optional human-readable label.
$table->string('label')->nullable();
// ── Contact / access overrides ──────────────────────────
// These let the assignment specify WHO to contact and WHERE
// exactly within the building, independent of the base address.
// The address stays generic ("Main Street 5, 1010 Vienna")
// while the assignment adds context ("3rd floor, door 12, ring Müller").
// Name on the door / bell / intercom.
$table->string('name_on_door')->nullable();
// Contact email for this specific assignment.
$table->string('email')->nullable();
// Contact phone for this specific assignment.
$table->string('phone')->nullable();
// Floor override (when the base address doesn't specify one,
// or this assignment targets a different floor).
$table->string('floor')->nullable();
// Door / apartment / unit number override.
$table->string('door')->nullable();
// ── Extra data ──────────────────────────────────────────
$table->json('meta')->nullable();

View File

@ -28,6 +28,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
* @property float|null $latitude Decimal degrees (90 +90)
* @property float|null $longitude Decimal degrees (180 +180)
* @property float|null $altitude Metres AMSL (positive = above, negative = below)
* @property bool $has_elevator Whether the building has an elevator
* @property string|null $notes Free-form notes / delivery instructions
* @property object|null $meta Arbitrary JSON data
* @property \Carbon\Carbon $created_at
@ -60,6 +61,7 @@ class Address extends Model
'latitude',
'longitude',
'altitude',
'has_elevator',
'notes',
'meta',
];
@ -71,6 +73,7 @@ class Address extends Model
'latitude' => 'float',
'longitude' => 'float',
'altitude' => 'float',
'has_elevator' => 'boolean',
'meta' => 'object',
];

View File

@ -25,6 +25,11 @@ use Illuminate\Database\Eloquent\Model;
* @property int $assignable_id Morph ID of the consuming model
* @property string|null $role Context-specific purpose ("pickup", "delivery", )
* @property string|null $label Free-text label
* @property string|null $name_on_door Name on door / bell / intercom
* @property string|null $email Contact email for this assignment
* @property string|null $phone Contact phone for this assignment
* @property string|null $floor Floor override for this assignment
* @property string|null $door Door / apartment / unit override
* @property object|null $meta Arbitrary JSON data
* @property \Carbon\Carbon $created_at
* @property \Carbon\Carbon $updated_at
@ -42,6 +47,11 @@ class AddressAssignment extends Model
'assignable_id',
'role',
'label',
'name_on_door',
'email',
'phone',
'floor',
'door',
'meta',
];
@ -114,6 +124,28 @@ class AddressAssignment extends Model
return $this->morphTo();
}
/*
|--------------------------------------------------------------------------
| Accessors effective values (assignment overrides base address)
|--------------------------------------------------------------------------
*/
/**
* The effective floor: assignment's floor if set, otherwise the base address's floor.
*/
public function getEffectiveFloorAttribute(): ?string
{
return $this->floor ?? $this->addressLink?->address?->floor;
}
/**
* The effective door/room: assignment's door if set, otherwise the base address's room.
*/
public function getEffectiveDoorAttribute(): ?string
{
return $this->door ?? $this->addressLink?->address?->room;
}
/*
|--------------------------------------------------------------------------
| Scopes