Files
Lesstime/src/DataFixtures/AppFixtures.php
Matthieu 2a0b202d32 feat(absences) : avancement module absences + suppression du portail client
Deux lots regroupés sur la branche feat/absence-management.

Suppression complète du portail client :
- retire ROLE_CLIENT (security.yaml) ; User::getRoles() ajoute toujours ROLE_USER
- supprime l'entité ClientTicket (+ repo, states, relations), User.client et
  User.allowedProjects, NotificationService, ProjectAllowedExtension, le bloc
  ROLE_CLIENT de MailAccessChecker
- front : pages /portal, layout portal, composants client-ticket/,
  AdminClientTicketTab, services/dto/i18n/docs associés
- fixtures : retire les users client-liot / client-acme
- migration Version20260522110000 (drop client_ticket, user_allowed_projects,
  colonnes liées ; task_document.task_id -> NOT NULL)
- tests : retire les cas obsolètes testant le blocage des clients sur le mail

Module gestion des absences (WIP) :
- entités / migrations (Version20260521160000, Version20260522090000)
- pages absences.vue / team-absences.vue, composants frontend/components/absence/
- services front, AccrueLeaveCommand, PublicHolidayController

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 11:31:31 +02:00

747 lines
32 KiB
PHP

<?php
declare(strict_types=1);
namespace App\DataFixtures;
use App\Entity\AbsenceBalance;
use App\Entity\AbsencePolicy;
use App\Entity\AbsenceRequest;
use App\Entity\Client;
use App\Entity\MailConfiguration;
use App\Entity\Project;
use App\Entity\Task;
use App\Entity\TaskEffort;
use App\Entity\TaskGroup;
use App\Entity\TaskPriority;
use App\Entity\TaskRecurrence;
use App\Entity\TaskStatus;
use App\Entity\TaskTag;
use App\Entity\TimeEntry;
use App\Entity\User;
use App\Entity\Workflow;
use App\Entity\ZimbraConfiguration;
use App\Enum\AbsenceStatus;
use App\Enum\AbsenceType;
use App\Enum\ContractType;
use App\Enum\FamilySituation;
use App\Enum\RecurrenceType;
use App\Enum\StatusCategory;
use DateTimeImmutable;
use DateTimeZone;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
class AppFixtures extends Fixture
{
public function __construct(
private readonly UserPasswordHasherInterface $passwordHasher,
) {}
public function load(ObjectManager $manager): void
{
// Users
$admin = new User();
$admin->setUsername('admin');
$admin->setRoles(['ROLE_ADMIN']);
$admin->setPassword($this->passwordHasher->hashPassword($admin, 'admin'));
$admin->setApiToken('dev-mcp-token-for-testing-only-do-not-use-in-production');
$manager->persist($admin);
$userAlice = new User();
$userAlice->setUsername('alice');
$userAlice->setRoles(['ROLE_USER']);
$userAlice->setPassword($this->passwordHasher->hashPassword($userAlice, 'alice'));
$manager->persist($userAlice);
$userBob = new User();
$userBob->setUsername('bob');
$userBob->setRoles(['ROLE_USER']);
$userBob->setPassword($this->passwordHasher->hashPassword($userBob, 'bob'));
$manager->persist($userBob);
$userCharlie = new User();
$userCharlie->setUsername('charlie');
$userCharlie->setRoles(['ROLE_USER']);
$userCharlie->setPassword($this->passwordHasher->hashPassword($userCharlie, 'charlie'));
$manager->persist($userCharlie);
// Clients
$clientLiot = new Client();
$clientLiot->setName('LIOT');
$clientLiot->setEmail('contact@liot.fr');
$clientLiot->setPhone('05 50 50 50 50');
$clientLiot->setStreet('14 allée d\'argenson');
$clientLiot->setCity('Poitiers');
$clientLiot->setPostalCode('86100');
$manager->persist($clientLiot);
$clientAcme = new Client();
$clientAcme->setName('ACME Corp');
$clientAcme->setEmail('contact@acme.com');
$clientAcme->setPhone('01 23 45 67 89');
$clientAcme->setStreet('10 rue de la Paix');
$clientAcme->setCity('Paris');
$clientAcme->setPostalCode('75002');
$manager->persist($clientAcme);
$clientNova = new Client();
$clientNova->setName('Nova Tech');
$clientNova->setEmail('info@novatech.io');
$clientNova->setPhone('04 56 78 90 12');
$clientNova->setStreet('5 avenue Jean Jaurès');
$clientNova->setCity('Lyon');
$clientNova->setPostalCode('69007');
$manager->persist($clientNova);
// Workflow par défaut
$standardWorkflow = new Workflow();
$standardWorkflow->setName('Standard');
$standardWorkflow->setIsDefault(true);
$standardWorkflow->setPosition(0);
$manager->persist($standardWorkflow);
// Task Statuses (rattachés au workflow Standard)
$defaultStatuses = [
['A faire', '#222783', 0, StatusCategory::Todo, false],
['En cours', '#4A90D9', 1, StatusCategory::InProgress, false],
['Bloqué', '#C62828', 2, StatusCategory::Blocked, false],
['En attente de validation', '#FF8F00', 3, StatusCategory::Review, false],
['Terminé', '#26A69A', 4, StatusCategory::Done, true],
];
$statusObjects = [];
foreach ($defaultStatuses as [$label, $color, $position, $category, $isFinal]) {
$status = new TaskStatus();
$status->setLabel($label);
$status->setColor($color);
$status->setPosition($position);
$status->setCategory($category);
$status->setIsFinal($isFinal);
$standardWorkflow->addStatus($status);
$manager->persist($status);
$statusObjects[$label] = $status;
}
$statusTodo = $statusObjects['A faire'];
$statusInProgress = $statusObjects['En cours'];
$statusBlocked = $statusObjects['Bloqué'];
$statusReview = $statusObjects['En attente de validation'];
$statusDone = $statusObjects['Terminé'];
// Projets
$projectSirh = new Project();
$projectSirh->setCode('SIRH');
$projectSirh->setName('SIRH');
$projectSirh->setDescription('Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer ac blandit turpis.');
$projectSirh->setColor('#222783');
$projectSirh->setClient($clientLiot);
$projectSirh->setWorkflow($standardWorkflow);
$manager->persist($projectSirh);
$projectCrm = new Project();
$projectCrm->setCode('CRM');
$projectCrm->setName('CRM');
$projectCrm->setDescription('Gestion de la relation client et suivi commercial.');
$projectCrm->setColor('#E91E63');
$projectCrm->setClient($clientAcme);
$projectCrm->setWorkflow($standardWorkflow);
$manager->persist($projectCrm);
$projectErp = new Project();
$projectErp->setCode('ERP');
$projectErp->setName('ERP');
$projectErp->setDescription('Planification des ressources et gestion des stocks.');
$projectErp->setColor('#4A90D9');
$projectErp->setClient($clientNova);
$projectErp->setWorkflow($standardWorkflow);
$manager->persist($projectErp);
$projectInterne = new Project();
$projectInterne->setCode('SITE');
$projectInterne->setName('Site vitrine');
$projectInterne->setDescription('Refonte du site web corporate.');
$projectInterne->setColor('#26A69A');
$projectInterne->setClient(null);
$projectInterne->setWorkflow($standardWorkflow);
$manager->persist($projectInterne);
// Task Efforts
$effortS = new TaskEffort();
$effortS->setLabel('S');
$manager->persist($effortS);
$effortM = new TaskEffort();
$effortM->setLabel('M');
$manager->persist($effortM);
$effortL = new TaskEffort();
$effortL->setLabel('L');
$manager->persist($effortL);
$effortXL = new TaskEffort();
$effortXL->setLabel('XL');
$manager->persist($effortXL);
$effortXXL = new TaskEffort();
$effortXXL->setLabel('XXL');
$manager->persist($effortXXL);
// Task Priorities
$priorityLow = new TaskPriority();
$priorityLow->setLabel('Basse');
$priorityLow->setColor('#222783');
$manager->persist($priorityLow);
$priorityMedium = new TaskPriority();
$priorityMedium->setLabel('Moyen');
$priorityMedium->setColor('#FF8F00');
$manager->persist($priorityMedium);
$priorityHigh = new TaskPriority();
$priorityHigh->setLabel('Haute');
$priorityHigh->setColor('#C62828');
$manager->persist($priorityHigh);
// Task Tags
$tagPassword = new TaskTag();
$tagPassword->setLabel('Gestion mdp');
$tagPassword->setColor('#C62828');
$manager->persist($tagPassword);
$tagAuth = new TaskTag();
$tagAuth->setLabel('Connexion');
$tagAuth->setColor('#FF8F00');
$manager->persist($tagAuth);
$tagCalendar = new TaskTag();
$tagCalendar->setLabel('Calendrier');
$tagCalendar->setColor('#222783');
$manager->persist($tagCalendar);
// Task Groups — SIRH
$groupFrontend = new TaskGroup();
$groupFrontend->setTitle('Frontend');
$groupFrontend->setColor('#4A90D9');
$groupFrontend->setProject($projectSirh);
$manager->persist($groupFrontend);
$groupBackend = new TaskGroup();
$groupBackend->setTitle('Backend');
$groupBackend->setColor('#26A69A');
$groupBackend->setProject($projectSirh);
$manager->persist($groupBackend);
// Task Groups — CRM
$groupCrmUi = new TaskGroup();
$groupCrmUi->setTitle('Interface');
$groupCrmUi->setColor('#E91E63');
$groupCrmUi->setProject($projectCrm);
$manager->persist($groupCrmUi);
$groupCrmApi = new TaskGroup();
$groupCrmApi->setTitle('API');
$groupCrmApi->setColor('#9C27B0');
$groupCrmApi->setProject($projectCrm);
$manager->persist($groupCrmApi);
// Task Groups — ERP
$groupErpStock = new TaskGroup();
$groupErpStock->setTitle('Stocks');
$groupErpStock->setColor('#4A90D9');
$groupErpStock->setProject($projectErp);
$manager->persist($groupErpStock);
$groupErpFacturation = new TaskGroup();
$groupErpFacturation->setTitle('Facturation');
$groupErpFacturation->setColor('#FF8F00');
$groupErpFacturation->setProject($projectErp);
$manager->persist($groupErpFacturation);
// Task Groups — Site vitrine
$groupSiteDesign = new TaskGroup();
$groupSiteDesign->setTitle('Design');
$groupSiteDesign->setColor('#26A69A');
$groupSiteDesign->setProject($projectInterne);
$manager->persist($groupSiteDesign);
$groupSiteContenu = new TaskGroup();
$groupSiteContenu->setTitle('Contenu');
$groupSiteContenu->setColor('#795548');
$groupSiteContenu->setProject($projectInterne);
$manager->persist($groupSiteContenu);
// =============================================
// Tasks — SIRH
// =============================================
$task1 = new Task();
$task1->setNumber(1);
$task1->setTitle('Création d\'une page de login');
$task1->setStatus($statusTodo);
$task1->setEffort($effortXXL);
$task1->setPriority($priorityLow);
$task1->setAssignee($admin);
$task1->setGroup($groupFrontend);
$task1->setProject($projectSirh);
$task1->addTag($tagPassword);
$manager->persist($task1);
$task2 = new Task();
$task2->setNumber(2);
$task2->setTitle('Intégration SSO');
$task2->setStatus($statusTodo);
$task2->setEffort($effortL);
$task2->setPriority($priorityHigh);
$task2->setAssignee($userAlice);
$task2->setGroup($groupFrontend);
$task2->setProject($projectSirh);
$task2->addTag($tagAuth);
$task2->setScheduledStart(new DateTimeImmutable('next monday 09:00'));
$task2->setScheduledEnd(new DateTimeImmutable('next monday 17:00'));
$task2->setSyncToCalendar(false);
$manager->persist($task2);
$task3 = new Task();
$task3->setNumber(3);
$task3->setTitle('API d\'authentification');
$task3->setStatus($statusInProgress);
$task3->setEffort($effortXXL);
$task3->setPriority($priorityLow);
$task3->setAssignee($admin);
$task3->setGroup($groupBackend);
$task3->setProject($projectSirh);
$task3->addTag($tagPassword);
$manager->persist($task3);
$task4 = new Task();
$task4->setNumber(4);
$task4->setTitle('Gestion des tokens JWT');
$task4->setStatus($statusBlocked);
$task4->setEffort($effortXXL);
$task4->setPriority($priorityLow);
$task4->setAssignee($userBob);
$task4->setProject($projectSirh);
$task4->addTag($tagPassword);
$manager->persist($task4);
$task5 = new Task();
$task5->setNumber(5);
$task5->setTitle('Calendrier des congés');
$task5->setStatus($statusReview);
$task5->setEffort($effortXXL);
$task5->setPriority($priorityMedium);
$task5->setAssignee($userCharlie);
$task5->setProject($projectSirh);
$task5->addTag($tagCalendar);
$task5->setDeadline(new DateTimeImmutable('+2 weeks'));
$task5->setSyncToCalendar(false);
$manager->persist($task5);
$task6 = new Task();
$task6->setNumber(6);
$task6->setTitle('Page de réinitialisation mdp');
$task6->setStatus($statusDone);
$task6->setEffort($effortXXL);
$task6->setPriority($priorityHigh);
$task6->setAssignee($admin);
$task6->setProject($projectSirh);
$task6->addTag($tagAuth);
$manager->persist($task6);
// =============================================
// Tasks — CRM
// =============================================
$taskCrm1 = new Task();
$taskCrm1->setNumber(1);
$taskCrm1->setTitle('Liste des contacts');
$taskCrm1->setStatus($statusDone);
$taskCrm1->setEffort($effortL);
$taskCrm1->setPriority($priorityHigh);
$taskCrm1->setAssignee($admin);
$taskCrm1->setGroup($groupCrmUi);
$taskCrm1->setProject($projectCrm);
$manager->persist($taskCrm1);
$taskCrm2 = new Task();
$taskCrm2->setNumber(2);
$taskCrm2->setTitle('Fiche contact détaillée');
$taskCrm2->setStatus($statusInProgress);
$taskCrm2->setEffort($effortM);
$taskCrm2->setPriority($priorityMedium);
$taskCrm2->setAssignee($userAlice);
$taskCrm2->setGroup($groupCrmUi);
$taskCrm2->setProject($projectCrm);
$manager->persist($taskCrm2);
$taskCrm3 = new Task();
$taskCrm3->setNumber(3);
$taskCrm3->setTitle('Import CSV contacts');
$taskCrm3->setStatus($statusTodo);
$taskCrm3->setEffort($effortXL);
$taskCrm3->setPriority($priorityLow);
$taskCrm3->setAssignee($admin);
$taskCrm3->setGroup($groupCrmApi);
$taskCrm3->setProject($projectCrm);
$manager->persist($taskCrm3);
$taskCrm4 = new Task();
$taskCrm4->setNumber(4);
$taskCrm4->setTitle('Pipeline de vente');
$taskCrm4->setStatus($statusInProgress);
$taskCrm4->setEffort($effortXXL);
$taskCrm4->setPriority($priorityHigh);
$taskCrm4->setAssignee($userBob);
$taskCrm4->setGroup($groupCrmUi);
$taskCrm4->setProject($projectCrm);
$taskCrm4->addTag($tagCalendar);
$manager->persist($taskCrm4);
$taskCrm5 = new Task();
$taskCrm5->setNumber(5);
$taskCrm5->setTitle('API recherche contacts');
$taskCrm5->setStatus($statusReview);
$taskCrm5->setEffort($effortM);
$taskCrm5->setPriority($priorityMedium);
$taskCrm5->setAssignee($admin);
$taskCrm5->setGroup($groupCrmApi);
$taskCrm5->setProject($projectCrm);
$manager->persist($taskCrm5);
// =============================================
// Tasks — ERP
// =============================================
$taskErp1 = new Task();
$taskErp1->setNumber(1);
$taskErp1->setTitle('Tableau de bord stocks');
$taskErp1->setStatus($statusDone);
$taskErp1->setEffort($effortL);
$taskErp1->setPriority($priorityHigh);
$taskErp1->setAssignee($admin);
$taskErp1->setGroup($groupErpStock);
$taskErp1->setProject($projectErp);
$manager->persist($taskErp1);
$taskErp2 = new Task();
$taskErp2->setNumber(2);
$taskErp2->setTitle('Alertes stock bas');
$taskErp2->setStatus($statusInProgress);
$taskErp2->setEffort($effortM);
$taskErp2->setPriority($priorityHigh);
$taskErp2->setAssignee($userCharlie);
$taskErp2->setGroup($groupErpStock);
$taskErp2->setProject($projectErp);
$manager->persist($taskErp2);
$taskErp3 = new Task();
$taskErp3->setNumber(3);
$taskErp3->setTitle('Génération factures PDF');
$taskErp3->setStatus($statusTodo);
$taskErp3->setEffort($effortXXL);
$taskErp3->setPriority($priorityMedium);
$taskErp3->setAssignee($admin);
$taskErp3->setGroup($groupErpFacturation);
$taskErp3->setProject($projectErp);
$taskErp3->setDeadline(new DateTimeImmutable('+1 month'));
$taskErp3->setSyncToCalendar(false);
$manager->persist($taskErp3);
$taskErp4 = new Task();
$taskErp4->setNumber(4);
$taskErp4->setTitle('Historique mouvements stock');
$taskErp4->setStatus($statusReview);
$taskErp4->setEffort($effortL);
$taskErp4->setPriority($priorityLow);
$taskErp4->setAssignee($admin);
$taskErp4->setGroup($groupErpStock);
$taskErp4->setProject($projectErp);
$manager->persist($taskErp4);
$taskErp5 = new Task();
$taskErp5->setNumber(5);
$taskErp5->setTitle('Export comptable');
$taskErp5->setStatus($statusBlocked);
$taskErp5->setEffort($effortXL);
$taskErp5->setPriority($priorityHigh);
$taskErp5->setAssignee($admin);
$taskErp5->setGroup($groupErpFacturation);
$taskErp5->setProject($projectErp);
$manager->persist($taskErp5);
$taskErp6 = new Task();
$taskErp6->setNumber(6);
$taskErp6->setTitle('Inventaire annuel');
$taskErp6->setStatus($statusTodo);
$taskErp6->setEffort($effortS);
$taskErp6->setPriority($priorityLow);
$taskErp6->setAssignee($admin);
$taskErp6->setGroup($groupErpStock);
$taskErp6->setProject($projectErp);
$taskErp6->addTag($tagCalendar);
$manager->persist($taskErp6);
// =============================================
// Tasks — Site vitrine
// =============================================
$taskSite1 = new Task();
$taskSite1->setNumber(1);
$taskSite1->setTitle('Maquette page d\'accueil');
$taskSite1->setStatus($statusDone);
$taskSite1->setEffort($effortM);
$taskSite1->setPriority($priorityHigh);
$taskSite1->setAssignee($admin);
$taskSite1->setGroup($groupSiteDesign);
$taskSite1->setProject($projectInterne);
$manager->persist($taskSite1);
$taskSite2 = new Task();
$taskSite2->setNumber(2);
$taskSite2->setTitle('Intégration responsive');
$taskSite2->setStatus($statusInProgress);
$taskSite2->setEffort($effortL);
$taskSite2->setPriority($priorityMedium);
$taskSite2->setAssignee($userAlice);
$taskSite2->setGroup($groupSiteDesign);
$taskSite2->setProject($projectInterne);
$manager->persist($taskSite2);
$taskSite3 = new Task();
$taskSite3->setNumber(3);
$taskSite3->setTitle('Rédaction page "À propos"');
$taskSite3->setStatus($statusTodo);
$taskSite3->setEffort($effortS);
$taskSite3->setPriority($priorityLow);
$taskSite3->setAssignee($admin);
$taskSite3->setGroup($groupSiteContenu);
$taskSite3->setProject($projectInterne);
$manager->persist($taskSite3);
$taskSite4 = new Task();
$taskSite4->setNumber(4);
$taskSite4->setTitle('Formulaire de contact');
$taskSite4->setStatus($statusReview);
$taskSite4->setEffort($effortM);
$taskSite4->setPriority($priorityMedium);
$taskSite4->setAssignee($admin);
$taskSite4->setGroup($groupSiteDesign);
$taskSite4->setProject($projectInterne);
$taskSite4->addTag($tagAuth);
$manager->persist($taskSite4);
$taskSite5 = new Task();
$taskSite5->setNumber(5);
$taskSite5->setTitle('SEO et métadonnées');
$taskSite5->setStatus($statusTodo);
$taskSite5->setEffort($effortS);
$taskSite5->setPriority($priorityHigh);
$taskSite5->setAssignee($admin);
$taskSite5->setGroup($groupSiteContenu);
$taskSite5->setProject($projectInterne);
$manager->persist($taskSite5);
// =============================================
// Time Entries — tous les projets
// =============================================
$timeEntryData = [
// SIRH — lundi à vendredi
['title' => 'Réunion', 'project' => $projectSirh, 'tag' => $tagAuth, 'start' => '09:00', 'stop' => '09:45', 'day' => 1],
['title' => 'Page accueil', 'project' => $projectSirh, 'tag' => $tagPassword, 'start' => '10:00', 'stop' => '12:00', 'day' => 0],
['title' => 'Design admin', 'project' => $projectSirh, 'tag' => $tagAuth, 'start' => '09:30', 'stop' => '11:00', 'day' => 2],
['title' => 'Page accueil', 'project' => $projectSirh, 'tag' => $tagPassword, 'start' => '10:30', 'stop' => '12:15', 'day' => 1],
['title' => 'System os', 'project' => $projectSirh, 'tag' => $tagCalendar, 'start' => '13:00', 'stop' => '15:30', 'day' => 0],
['title' => 'Login', 'project' => $projectSirh, 'tag' => $tagPassword, 'start' => '13:00', 'stop' => '15:00', 'day' => 1],
['title' => 'Script vault', 'project' => $projectSirh, 'tag' => $tagCalendar, 'start' => '10:00', 'stop' => '12:00', 'day' => 3],
['title' => 'Script backup BDD', 'project' => $projectSirh, 'tag' => $tagAuth, 'start' => '13:30', 'stop' => '15:00', 'day' => 3],
['title' => 'Maquette', 'project' => $projectSirh, 'tag' => null, 'start' => '09:00', 'stop' => '11:00', 'day' => 4],
['title' => 'PC compta', 'project' => $projectSirh, 'tag' => null, 'start' => '13:30', 'stop' => '15:30', 'day' => 4],
// CRM — lundi à vendredi
['title' => 'Liste contacts UI', 'project' => $projectCrm, 'tag' => null, 'start' => '08:30', 'stop' => '10:00', 'day' => 0],
['title' => 'Fiche contact', 'project' => $projectCrm, 'tag' => null, 'start' => '15:30', 'stop' => '17:00', 'day' => 0],
['title' => 'Pipeline vente', 'project' => $projectCrm, 'tag' => $tagCalendar, 'start' => '08:30', 'stop' => '09:30', 'day' => 1],
['title' => 'Import CSV', 'project' => $projectCrm, 'tag' => null, 'start' => '15:30', 'stop' => '17:30', 'day' => 2],
['title' => 'API recherche', 'project' => $projectCrm, 'tag' => null, 'start' => '08:30', 'stop' => '10:00', 'day' => 3],
['title' => 'Tests unitaires CRM', 'project' => $projectCrm, 'tag' => null, 'start' => '15:30', 'stop' => '17:00', 'day' => 3],
['title' => 'Revue pipeline', 'project' => $projectCrm, 'tag' => $tagCalendar, 'start' => '08:00', 'stop' => '09:00', 'day' => 4],
// ERP — lundi à vendredi
['title' => 'Dashboard stocks', 'project' => $projectErp, 'tag' => null, 'start' => '16:00', 'stop' => '17:30', 'day' => 1],
['title' => 'Alertes stock bas', 'project' => $projectErp, 'tag' => null, 'start' => '11:30', 'stop' => '12:30', 'day' => 2],
['title' => 'Factures PDF', 'project' => $projectErp, 'tag' => null, 'start' => '15:30', 'stop' => '17:30', 'day' => 4],
['title' => 'Mouvement stock', 'project' => $projectErp, 'tag' => null, 'start' => '09:00', 'stop' => '10:30', 'day' => 0],
['title' => 'Export comptable', 'project' => $projectErp, 'tag' => $tagCalendar, 'start' => '13:00', 'stop' => '14:30', 'day' => 2],
['title' => 'Inventaire', 'project' => $projectErp, 'tag' => null, 'start' => '13:30', 'stop' => '15:00', 'day' => 4],
// Site vitrine — lundi à jeudi
['title' => 'Maquette accueil', 'project' => $projectInterne, 'tag' => null, 'start' => '16:00', 'stop' => '17:30', 'day' => 0],
['title' => 'Responsive mobile', 'project' => $projectInterne, 'tag' => null, 'start' => '16:00', 'stop' => '17:30', 'day' => 2],
['title' => 'Rédaction contenu', 'project' => $projectInterne, 'tag' => null, 'start' => '15:30', 'stop' => '17:00', 'day' => 1],
['title' => 'Formulaire contact', 'project' => $projectInterne, 'tag' => $tagAuth, 'start' => '16:00', 'stop' => '17:30', 'day' => 3],
['title' => 'SEO meta tags', 'project' => $projectInterne, 'tag' => null, 'start' => '11:00', 'stop' => '12:00', 'day' => 4],
];
$monday = new DateTimeImmutable('monday this week', new DateTimeZone('UTC'));
foreach ($timeEntryData as $data) {
$entry = new TimeEntry();
$entry->setTitle($data['title']);
$entry->setUser($admin);
$entry->setProject($data['project']);
$entry->setStartedAt($monday->modify("+{$data['day']} days")->modify($data['start']));
$entry->setStoppedAt($monday->modify("+{$data['day']} days")->modify($data['stop']));
if ($data['tag']) {
$entry->addTag($data['tag']);
}
$manager->persist($entry);
}
// =============================================
// Zimbra Configuration
// =============================================
$zimbraConfig = new ZimbraConfiguration();
$zimbraConfig->setServerUrl('https://mail.ovh.com');
$zimbraConfig->setUsername('lesstime@ovh.fr');
$zimbraConfig->setCalendarPath('/dav/lesstime@ovh.fr/Calendar/');
$zimbraConfig->setEnabled(false);
$manager->persist($zimbraConfig);
// =============================================
// Task Recurrence — exemple hebdomadaire
// =============================================
$recurrence = new TaskRecurrence();
$recurrence->setType(RecurrenceType::Weekly);
$recurrence->setInterval(1);
$recurrence->setDaysOfWeek(['monday', 'wednesday', 'friday']);
$manager->persist($recurrence);
$taskRecurring = new Task();
$taskRecurring->setNumber(7);
$taskRecurring->setTitle('Réunion de suivi hebdomadaire');
$taskRecurring->setStatus($statusTodo);
$taskRecurring->setEffort($effortS);
$taskRecurring->setPriority($priorityMedium);
$taskRecurring->setAssignee($admin);
$taskRecurring->setProject($projectSirh);
$taskRecurring->setScheduledStart(new DateTimeImmutable('next monday 10:00'));
$taskRecurring->setScheduledEnd(new DateTimeImmutable('next monday 10:30'));
$taskRecurring->setSyncToCalendar(false);
$taskRecurring->setRecurrence($recurrence);
$manager->persist($taskRecurring);
// =============================================
// Mail Configuration
// =============================================
$mailConfig = new MailConfiguration();
$mailConfig->setImapHost('ssl0.ovh.net');
$mailConfig->setImapPort(993);
$mailConfig->setImapEncryption('ssl');
$mailConfig->setSmtpHost('ssl0.ovh.net');
$mailConfig->setSmtpPort(465);
$mailConfig->setSmtpEncryption('ssl');
$mailConfig->setUsername('lesstime@ovh.fr');
$mailConfig->setSentFolderPath('Sent');
$mailConfig->setEnabled(false);
$manager->persist($mailConfig);
// =============================================
// Absence management — policies, employees, balances, requests
// =============================================
// Default policies for the 5 absence types (legal defaults, editable by admin)
$policyData = [
// [type, daysPerYear, daysPerEvent, justifRequired, noticeDays, workingDaysOnly]
[AbsenceType::PaidLeave, 25.0, null, false, 30, true],
[AbsenceType::MarriagePacs, null, 4.0, true, 0, true],
[AbsenceType::ParentalLeave, null, null, true, 30, true],
[AbsenceType::Bereavement, null, 3.0, true, 0, true],
[AbsenceType::SickLeave, null, null, true, 0, true],
];
foreach ($policyData as [$type, $daysPerYear, $daysPerEvent, $justif, $notice, $workingDaysOnly]) {
$policy = new AbsencePolicy();
$policy->setType($type);
$policy->setDaysPerYear($daysPerYear);
$policy->setDaysPerEvent($daysPerEvent);
$policy->setJustificationRequired($justif);
$policy->setNoticeDays($notice);
$policy->setCountWorkingDaysOnly($workingDaysOnly);
$policy->setActive(true);
$manager->persist($policy);
}
// Mark internal users as employees
$admin->setIsEmployee(true);
$admin->setHireDate(new DateTimeImmutable('2020-01-15'));
$admin->setContractType(ContractType::Cdi);
$admin->setFamilySituation(FamilySituation::Married);
$admin->setNbChildren(2);
$userAlice->setIsEmployee(true);
$userAlice->setHireDate(new DateTimeImmutable('2022-09-01'));
$userAlice->setContractType(ContractType::Cdi);
$userAlice->setFamilySituation(FamilySituation::Single);
$userBob->setIsEmployee(true);
$userBob->setHireDate(new DateTimeImmutable('2023-03-10'));
$userBob->setContractType(ContractType::Cdd);
$userBob->setWorkTimeRatio(0.8);
$userBob->setFamilySituation(FamilySituation::Pacsed);
$userBob->setNbChildren(1);
// Paid-leave balances for the current reference period (June 1st → May 31st)
$cpPeriod = '2025-2026';
$balanceData = [
// [user, acquired (N-1), acquiring (N, en cours), taken, pending]
[$admin, 10.0, 22.5, 5.0, 0.0],
[$userAlice, 8.0, 18.0, 2.0, 5.0],
[$userBob, 0.0, 14.0, 0.0, 0.0],
];
foreach ($balanceData as [$bUser, $acquired, $acquiring, $taken, $pending]) {
$balance = new AbsenceBalance();
$balance->setUser($bUser);
$balance->setType(AbsenceType::PaidLeave);
$balance->setPeriod($cpPeriod);
$balance->setAcquired($acquired);
$balance->setAcquiring($acquiring);
$balance->setTaken($taken);
$balance->setPending($pending);
$manager->persist($balance);
}
// Demo requests
$approvedCp = new AbsenceRequest();
$approvedCp->setUser($admin);
$approvedCp->setType(AbsenceType::PaidLeave);
$approvedCp->setStartDate(new DateTimeImmutable('2026-04-13'));
$approvedCp->setEndDate(new DateTimeImmutable('2026-04-17'));
$approvedCp->setCountedDays(5.0);
$approvedCp->setReason('Vacances de printemps');
$approvedCp->setStatus(AbsenceStatus::Approved);
$approvedCp->setCreatedAt(new DateTimeImmutable('2026-03-10'));
$approvedCp->setReviewedAt(new DateTimeImmutable('2026-03-11'));
$approvedCp->setReviewedBy($admin);
$manager->persist($approvedCp);
$pendingCp = new AbsenceRequest();
$pendingCp->setUser($userAlice);
$pendingCp->setType(AbsenceType::PaidLeave);
$pendingCp->setStartDate(new DateTimeImmutable('2026-06-15'));
$pendingCp->setEndDate(new DateTimeImmutable('2026-06-19'));
$pendingCp->setCountedDays(5.0);
$pendingCp->setStatus(AbsenceStatus::Pending);
$pendingCp->setCreatedAt(new DateTimeImmutable('-2 days'));
$manager->persist($pendingCp);
$pendingMarriage = new AbsenceRequest();
$pendingMarriage->setUser($userBob);
$pendingMarriage->setType(AbsenceType::MarriagePacs);
$pendingMarriage->setStartDate(new DateTimeImmutable('2026-07-06'));
$pendingMarriage->setEndDate(new DateTimeImmutable('2026-07-09'));
$pendingMarriage->setCountedDays(4.0);
$pendingMarriage->setReason('Mariage');
$pendingMarriage->setStatus(AbsenceStatus::Pending);
$pendingMarriage->setCreatedAt(new DateTimeImmutable('-1 day'));
$manager->persist($pendingMarriage);
$manager->flush();
}
}