Ajoute fiche d'identité informatique, catalogue prestataires et schémas draw.io

- Fiche d'identité par organisation (technicien référent, FAI, IP publiques,
  prestataires liés) accessible depuis un nouveau menu.
- Nouveau module Prestataires dédié (catalogue léger réutilisable entre
  communes, avec journal de suivi des échanges) plutôt que de détourner les
  organisations de type "Fournisseur".
- Nouveau menu Infrastructure par organisation avec schémas réseau/fonctionnel
  édités via draw.io embarqué (URL configurable, cf. réglages admin).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
mrKamoo
2026-08-21 15:55:23 +02:00
co-authored by Claude Sonnet 5
parent 74c0b01a2e
commit 3c87ced1e4
28 changed files with 1365 additions and 1 deletions
+5
View File
@@ -35,6 +35,11 @@ class Document extends Model implements Linkable
return $this->type === 'upload';
}
public function isDiagram(): bool
{
return $this->type === 'diagram';
}
public function renderedMarkdown(): string
{
return (new CommonMarkConverter())->convert($this->content ?? '')->getContent();
+14 -1
View File
@@ -8,7 +8,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Storage;
#[Fillable(['name', 'slug', 'org_type', 'status', 'description', 'allowed_ip_ranges', 'logo_path', 'glpi_entity_id'])]
#[Fillable(['name', 'slug', 'org_type', 'status', 'description', 'allowed_ip_ranges', 'logo_path', 'glpi_entity_id', 'technician_user_id', 'isp_name', 'public_ips'])]
class Organization extends Model
{
use SoftDeletes;
@@ -17,6 +17,7 @@ class Organization extends Model
{
return [
'allowed_ip_ranges' => 'array',
'public_ips' => 'array',
];
}
@@ -86,4 +87,16 @@ class Organization extends Model
{
return $this->hasMany(Shortcut::class);
}
public function technician()
{
return $this->belongsTo(User::class, 'technician_user_id');
}
public function providers()
{
return $this->belongsToMany(Provider::class, 'organization_provider')
->withPivot('id', 'label')
->withTimestamps();
}
}
+34
View File
@@ -0,0 +1,34 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Storage;
#[Fillable(['name', 'logo_path', 'phone', 'email', 'website', 'notes'])]
class Provider extends Model
{
use SoftDeletes;
protected function logoUrl(): Attribute
{
return Attribute::get(
fn () => $this->logo_path ? Storage::disk('public')->url($this->logo_path) : asset('images/default-organization-logo.svg')
);
}
public function organizations()
{
return $this->belongsToMany(Organization::class, 'organization_provider')
->withPivot('id', 'label')
->withTimestamps();
}
public function logEntries()
{
return $this->hasMany(ProviderLogEntry::class)->orderByDesc('created_at');
}
}
+34
View File
@@ -0,0 +1,34 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class ProviderLogEntry extends Model
{
const UPDATED_AT = null;
const CATEGORIES = [
'contact' => 'Échange (mail / appel)',
'observation' => 'Observation',
'incident' => 'Incident',
'info' => 'Information générale',
];
protected $guarded = [];
public function provider()
{
return $this->belongsTo(Provider::class);
}
public function creator()
{
return $this->belongsTo(User::class, 'created_by');
}
public function categoryLabel(): string
{
return self::CATEGORIES[$this->category] ?? $this->category;
}
}