Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion config/routes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ afup_barometre_homepage:
methods: GET
controller: Symfony\Bundle\FrameworkBundle\Controller\RedirectController
defaults:
path: /about
path: /report/2025
permanent: false

afup_barometre_form:
Expand Down
8 changes: 8 additions & 0 deletions config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,14 @@ services:
parent: App\Report\AbstractReport
tags: ['barometre.report']

App\Report\UseGenerativeAiReport:
parent: App\Report\AbstractReport
tags: ['barometre.report']

App\Report\IncludeAiInProjectReport:
parent: App\Report\AbstractReport
tags: [ 'barometre.report' ]

NumberFormatter:
class: \NumberFormatter
arguments: ['fr', '1']
26 changes: 26 additions & 0 deletions migrations/Version20250906084617.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace Application\Migrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

final class Version20250906084617 extends AbstractMigration
{
public function getDescription(): string
{
return 'Add new column for 2025 answers';
}

public function up(Schema $schema): void
{
$this->addSql('ALTER TABLE response ADD useGenerativeAI TINYINT(1) DEFAULT NULL, ADD includeAiInProject TINYINT(1) DEFAULT NULL');
}

public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE response DROP useGenerativeAI, DROP includeAiInProject');
}
}
30 changes: 30 additions & 0 deletions migrations/Version20251002080532.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace Application\Migrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

final class Version20251002080532 extends AbstractMigration
{
public function getDescription(): string
{
return 'Add new specialities';
}

public function up(Schema $schema): void
{
$specialities = [
'API Platform',
'Sylius',
'Laminas (ex Zend Framework)',
'Ibexa (ex EzPublish)',
];

foreach ($specialities as $speciality) {
$this->addSql('INSERT INTO speciality (name) VALUES(:name)', ['name' => $speciality]);
}
}
}
Binary file added public/reports/2025/comparatif_avec_inflation.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/reports/2025/evolution_salaire.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/reports/2025/ia_usage_in_project.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/reports/2025/nombre_reponse_genre.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/reports/2025/use_generative_ai.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions src/Campaign/Format/Formats/Format2019.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ public function alterData(array $data)
}

if ('Freelance / entreprise individuelle' === $data['status']
&& '' !== trim($data['freelance_tjm'])
&& '' !== trim($data['freelance_average_work_day'])
&& '' !== mb_trim($data['freelance_tjm'])
&& '' !== mb_trim($data['freelance_average_work_day'])
) {
// calcul basic du brut d'un freelance
$freelanceAnnualSalary = $data['freelance_tjm'] * $data['freelance_average_work_day'];
Expand Down
87 changes: 87 additions & 0 deletions src/Campaign/Format/Formats/Format2025.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?php

declare(strict_types=1);

namespace App\Campaign\Format\Formats;

use App\Campaign\Format\FormatInterface;
use App\Enums\SalarySatisfactionEnums;

class Format2025 implements FormatInterface
{
public function getColumns()
{
return [
'', // Horodateur,
'gross_annual_salary', // Quelle est votre rémunération annuelle brute fixe en euro ?
'variable_annual_salary', // Quelle est votre rémunération annuelle brut variable (hors part fixe) en euro ?
'salary_satisfaction', // Estimez-vous votre rémunération satisfaisante ?
'salary_inflation', // Votre entreprise vous propose-t-elle à minima une réévaluation annuelle de votre rémunération du niveau de l’inflation ?
'initial_training', // Quelle est votre formation initiale ?
'retraining', // Venez-vous d'une reconversion ?
'status', // Quel est votre statut actuel ?
'job_title', // Quel est l'intitulé de votre poste actuel ?
'contract_work_duration', // Quelle est votre durée de travail contractuelle ?
'experience_in_year', // /Quel est votre nombre d'année d'expérience total ?
'experience_in_current_job', // Quel est votre nombre d'année d'expérience dans votre entreprise actuelle ?
'leave_job', // Si vous avez cherché à changer de poste en cette année, est-ce que vous avez ?
'freelance_tjm', // Quelle est votre TJM en euro ?
'freelance_average_work_day', // Quel est votre nombre de jours travaillé en moyenne dans l’année ?
'company_department', // Quel est votre département de travail ?
'company_type', // Dans quel type d'entreprise travaillez-vous ?
'company_size', // Taille de votre entreprise
'job_interest', // Quels sont les aspects les plus importants dans votre emploi actuel ?
'company_origin', // Si elle n'est pas française, quelle est l'origine de votre entreprise ou maison mère ?
'discrimination_during_hiring', // Avez-vous le sentiment d'avoir été victime de discrimination à l'embauche ?
'other_language', // "Développez-vous dans d'autres langages que PHP ? Si oui, quel est le principal ?"
'remote_usage', // Travaillez-vous en télétravail ?
'remote_pace', // Quel serait le rythme idéal en télétravail pour vous ? (en nombre de jour par semaine)
'technological_watch', // Faites-vous régulièrement de la veille technique ?,
'os_developpment', // Sous quel OS développez-vous principalement ?,
'number_meetup_participation', // À combien d'événement / meetup tech avez-vous participé sur la dernière année ?,
'community_inclusion', // Est-ce que vous pensez que l'AFUP, sa communauté et ses événements sont inclusifs ?
'speciality', // Quelle est votre plus grande spécialité ?,
'php_version', // Quelle version de PHP utilisez-vous au quotidien ?,
'php_strength', // "D'après vous, quelle est la plus grande force de PHP ?"
'has_formation', // Avez-vous suivi une formation au cours de ces deux dernières années ?,
'formation_subject', // Sur quel(s) sujet(s) avez-vous été formés ?,
'formation_impact', // Cela a-t-il eu une incidence sur votre emploi/rémunération ?,
'use_generative_ai', // Utilisez-vous l’IA générative pour développer vos projets ?
'include_ai_in_project', // Vos projets intègrent-ils des fonctionnalités liées à l'IA générative ?
'gender', // Vous êtes
'age', // Quel âge avez-vous ?
];
}

/**
* @return array
*/
public function alterData(array $data)
{
$data['annual_salary'] = $data['gross_annual_salary'] + $data['variable_annual_salary'];

if ('Un homme' === $data['gender'] || 'Homme' === $data['gender']) {
$data['gender'] = 'Hommes';
} elseif ('Une femme' === $data['gender'] || 'Femme' === $data['gender']) {
$data['gender'] = 'Femmes';
}

if (0 === $data['salary_satisfaction']) {
$data['salary_satisfaction'] = SalarySatisfactionEnums::SANS_OPINION;
}

$status = explode(',', $data['status']);

$data['status'] = isset($status[0]) ? ucfirst($status[0]) : 'Autre';

if ('Niveau Master2 ou ingénieur' === $data['initial_training']) {
$data['initial_training'] = 'Niveau Master2 ou ingénieur';
}

if ('Maitrise ou équivalent' === $data['initial_training']) {
$data['initial_training'] = 'Autre';
}

return $data;
}
}
16 changes: 12 additions & 4 deletions src/Campaign/ResponseFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,14 @@ public function createResponse(array $data, Campaign $campaign): Response
'oui' === mb_strtolower($data['formation_impact'] ?? null)
);

$response->setUseGenerativeAI(
'oui' === mb_strtolower($data['use_generative_ai'] ?? null)
);

$response->setIncludeAiInProject(
'oui' === mb_strtolower($data['include_ai_in_project'] ?? null)
);

return $response;
}

Expand All @@ -202,7 +210,7 @@ protected function addCertification(Response $response, array $certificationList
foreach ($certificationList as $certification) {
$certification = $this->certificationRepository->findOneBy(
[
'name' => trim($certification),
'name' => mb_trim($certification),
]
);

Expand All @@ -217,7 +225,7 @@ protected function addCertification(Response $response, array $certificationList
protected function addSpeciality(Response $response, array $specialityList)
{
foreach ($specialityList as $speciality) {
$speciality = $this->specialityRepository->findOneBy(['name' => trim($speciality)]);
$speciality = $this->specialityRepository->findOneBy(['name' => mb_trim($speciality)]);

if (!$speciality instanceof Speciality) {
continue;
Expand All @@ -230,7 +238,7 @@ protected function addSpeciality(Response $response, array $specialityList)
private function addHostingType(Response $response, array $hostingType)
{
foreach ($hostingType as $hostingTypeName) {
$hostingType = $this->hostingTypeRepository->findOneBy(['name' => trim($hostingTypeName)]);
$hostingType = $this->hostingTypeRepository->findOneBy(['name' => mb_trim($hostingTypeName)]);

if (!$hostingType instanceof HostingType) {
continue;
Expand All @@ -243,7 +251,7 @@ private function addHostingType(Response $response, array $hostingType)
private function addContainerEnvironmentUsage(Response $response, array $containerEnvironmentsUsage)
{
foreach ($containerEnvironmentsUsage as $name) {
$containerEnvironmentUsage = $this->containerEnvironmentUsageRepository->findOneBy(['name' => trim($name)]);
$containerEnvironmentUsage = $this->containerEnvironmentUsageRepository->findOneBy(['name' => mb_trim($name)]);

if (!$containerEnvironmentUsage instanceof ContainerEnvironmentUsage) {
continue;
Expand Down
30 changes: 30 additions & 0 deletions src/Entity/Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,12 @@ class Response
#[ORM\Column(type: 'integer', nullable: true)]
private ?int $age = null;

#[ORM\Column(type: 'boolean', nullable: true)]
private ?bool $useGenerativeAI = null;

#[ORM\Column(type: 'boolean', nullable: true)]
private ?bool $includeAiInProject = null;

public function __construct()
{
$this->certifications = new ArrayCollection();
Expand Down Expand Up @@ -896,4 +902,28 @@ public function setAge(?int $age): self

return $this;
}

public function getUseGenerativeAI(): ?bool
{
return $this->useGenerativeAI;
}

public function setUseGenerativeAI(?bool $useGenerativeAI): self
{
$this->useGenerativeAI = $useGenerativeAI;

return $this;
}

public function getIncludeAiInProject(): ?bool
{
return $this->includeAiInProject;
}

public function setIncludeAiInProject(?bool $includeAiInProject): self
{
$this->includeAiInProject = $includeAiInProject;

return $this;
}
}
2 changes: 1 addition & 1 deletion src/Enums/AbstractEnums.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public function getIds(): array

public function getIdByLabel(?string $label): ?int
{
$key = array_search(trim($label ?? ''), $this->choices, true);
$key = array_search(mb_trim($label ?? ''), $this->choices, true);

return false === $key ? $this->getDefaultValue() : $key;
}
Expand Down
16 changes: 16 additions & 0 deletions src/Enums/OuiNonEnums.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace App\Enums;

class OuiNonEnums extends AbstractEnums
{
public const YES = 1;
public const NO = 0;

protected array $choices = [
self::YES => 'Oui',
self::NO => 'Non',
];
}
69 changes: 69 additions & 0 deletions src/Filter/UseGenerativeAIFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

declare(strict_types=1);

namespace App\Filter;

use App\Enums\OuiNonEnums;
use App\Form\Type\Select2MultipleFilterType;
use Doctrine\DBAL\Query\QueryBuilder;
use Symfony\Component\Form\FormBuilderInterface;

class UseGenerativeAIFilter implements FilterInterface
{
public function __construct(private OuiNonEnums $enums)
{
}

/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder)
{
$builder->add($this->getName(), Select2MultipleFilterType::class, [
'label' => 'filter.use_generative_ai',
'choices' => array_flip($this->enums->getChoices()),
]);
}

/**
* {@inheritdoc}
*/
public function buildQuery(QueryBuilder $queryBuilder, array $values = [])
{
if (!\array_key_exists($this->getName(), $values) || 0 === \count($values[$this->getName()])) {
return;
}

$queryBuilder
->andWhere($queryBuilder->expr()->in('response.useGenerativeAI', $values[$this->getName()]));
}

/**
* {@inheritdoc}
*/
public function convertValuesToLabels($value)
{
return array_map(function ($value) {
return $this->enums->getLabelById($value);
}, $value);
}

/**
* {@inheritdoc}
*/
public function getName()
{
return 'use_generative_ai';
}

/**
* Filter weight.
*
* @return int
*/
public function getWeight()
{
return 160;
}
}
4 changes: 2 additions & 2 deletions src/Menu/MenuBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ protected function getBaseMenu()
$menu->setChildrenAttribute('class', 'nav navbar-nav');

$menu->addChild(
'menu.result2024',
'menu.result2025',
[
'route' => 'afup_barometre_campaign',
'routeParameters' => ['campaignName' => 2024],
'routeParameters' => ['campaignName' => 2025],
'routeAbsolute' => UrlGeneratorInterface::ABSOLUTE_URL,
]
);
Expand Down
Loading