laravel-geo-checkin maintained by vnuswilliams
vnuswilliams/laravel-geo-checkin
Package Laravel de pointage de présence par géolocalisation, conçu pour être installé à la fois dans Squarhe (application admin RH/paie) et dans le portail employé, deux applications séparées qui partagent la même base de données.
Principe central : sans localisation définie par l'entreprise, aucun pointage ne peut être validé.
Fonctionnement
- L'entreprise (côté Squarhe) définit un ou plusieurs sites de travail : nom, coordonnées GPS (latitude/longitude) et rayon de tolérance en mètres.
- L'employé, depuis le portail employé, clique sur « Pointer ». Le navigateur renvoie sa position GPS (latitude, longitude, précision).
- Le package calcule la distance entre la position de l'employé et le site de référence via la formule de Haversine.
- Si
distance <= radius_meters→ pointagevalid. Sinon →out_of_range(conservé pour traçabilité, mais marqué suspect). - Le pointage est enregistré dans deux tables : le log brut (
attendances) et la synthèse journalière (attendance_days). - Côté Squarhe, un tableau de bord permet de consulter, filtrer et exporter ces présences.
Installation
Pendant le développement (path repository)
// composer.json des deux projets (Squarhe + portail employé)
"repositories": [
{ "type": "path", "url": "../laravel-geo-checkin" }
]
composer require vnuswilliams/laravel-geo-checkin
php artisan migrate
Le ServiceProvider est auto-découvert (extra.laravel.providers). La base étant partagée, il suffit d'exécuter les migrations depuis un seul des deux projets.
Publication de la configuration (optionnel)
php artisan vendor:publish --tag=geo-checkin-config
Configuration
| Clé | Valeur par défaut | Description |
|---|---|---|
geo-checkin.models.employee |
Illuminate\Foundation\Auth\User::class |
Modèle employé de votre application (ex. App\Models\Employee::class). |
geo-checkin.accuracy_threshold_meters |
150 |
Au-delà de cette précision GPS, le pointage passe en statut pending (attente de validation manuelle). |
Tables créées
work_locations — les sites de référence
| Colonne | Type | Description |
|---|---|---|
id |
uuid | Identifiant du site |
company_id |
uuid | Entreprise propriétaire du site |
name |
string | Nom du site |
latitude / longitude |
decimal(10,7) | Coordonnées GPS |
radius_meters |
unsigned int | Rayon de tolérance (mètres) |
is_active |
boolean | Désactive un site sans le supprimer |
attendances — le log brut de chaque pointage
| Colonne | Type | Description |
|---|---|---|
id |
uuid | Identifiant du pointage |
employee_id |
uuid | Employé qui a pointé |
work_location_id |
uuid, nullable | Site auquel le pointage a été comparé |
type |
string | check_in ou check_out |
latitude / longitude |
decimal(10,7) | Position GPS au moment du pointage |
distance_meters |
unsigned int, nullable | Distance calculée (Haversine) |
accuracy_meters |
unsigned int, nullable | Précision GPS renvoyée par le navigateur |
status |
string | valid, out_of_range, no_location_defined ou pending |
ip_address |
string(45), nullable | IP de la requête (anti-triche indicatif) |
recorded_at |
datetime | Date/heure exacte du pointage |
attendance_days — la synthèse journalière
| Colonne | Type | Description |
|---|---|---|
id |
uuid | Identifiant |
employee_id |
uuid | Employé concerné |
work_location_id |
uuid, nullable | Site du jour |
date |
date | Le jour concerné (unique avec employee_id) |
check_in_at / check_out_at |
datetime, nullable | Heures d'arrivée et de départ |
check_in_status / check_out_status |
string, nullable | Statuts des pointages |
worked_minutes |
unsigned int, nullable | Durée travaillée (départ − arrivée) |
Services
GeoDistanceService
use VnusWilliams\GeoCheckin\Services\GeoDistanceService;
$distance = app(GeoDistanceService::class)
->distanceInMeters(4.0511, 9.7679, 3.8480, 11.5021); // ≈ 200 000 m
CheckinService — point d'entrée unique
use VnusWilliams\GeoCheckin\Enums\AttendanceType;
use VnusWilliams\GeoCheckin\Services\CheckinService;
$attendance = app(CheckinService::class)->register(
employee: $employee,
latitude: $lat,
longitude: $lng,
accuracyMeters: $accuracy,
type: AttendanceType::CheckIn,
);
$attendance->status; // AttendanceStatus::Valid | OutOfRange | NoLocationDefined | Pending
Règles de résolution du site de référence :
- le site assigné à l'employé via sa relation
workLocation(si active) ; - le premier site actif de son entreprise ;
- le premier site actif globalement.
Composants Livewire 4 (single-file, natifs)
Les composants sont enregistrés sous le namespace geo-checkin dans le ServiceProvider du package et utilisables directement dans les deux applications.
Côté employé (portail)
<livewire:geo-checkin::employee-checkin-widget />
Boutons « Pointer (arrivée) » et « Dépointer (départ) », récupération de la position GPS via l'API du navigateur (navigator.geolocation).
Côté admin (Squarhe)
<livewire:geo-checkin::admin-work-location-manager />
<livewire:geo-checkin::admin-attendance-report />
admin-work-location-manager: CRUD des sites avec carte cliquable (Leaflet.js + OpenStreetMap, sans clé API).admin-attendance-report: tableau de bord filtrable par employé, période et statut, avec export CSV. Les exports Excel (FastExcel) et PDF (DomPDF) peuvent être branchés par l'application en réutilisant ses propres patterns.
Sécurité et fiabilité
- Pas de site = pas de validation : statut
no_location_definedexplicite plutôt qu'une erreur. - Précision GPS : au-delà du seuil configuré, statut
pending(validation manuelle) plutôt qu'un rejet injuste. - Anti-triche : l'IP de chaque pointage est journalisée à titre indicatif. La géolocalisation navigateur reste falsifiable ; une app mobile native serait nécessaire pour une fiabilité renforcée.
- Multi-site : les sites sont liés à
company_id; chaque synthèse journalière conserve le site utilisé.
Tests
composer install
vendor/bin/phpunit
vendor/bin/pint --test
27 tests (unitaires + fonctionnels) couvrent : le calcul de distance, la validation dans/à l'extérieur du rayon, l'absence de site, la faible précision GPS, la synthèse journalière unique, le calcul des minutes travaillées, la résolution multi-site, la journalisation IP, et les composants Livewire.
Évolutions possibles
- Calcul automatique des retards (horaires d'ouverture de l'entreprise).
- Détection des absences (aucun
AttendanceDayun jour ouvré). - Application mobile native pour une géolocalisation plus fiable.
- Connexion de
worked_minutesau module paie de Squarhe.