diff --git a/.changes/unreleased/Feature-20231212-154841.yaml b/.changes/unreleased/Feature-20231212-154841.yaml
deleted file mode 100644
index 14e19345b..000000000
--- a/.changes/unreleased/Feature-20231212-154841.yaml
+++ /dev/null
@@ -1,5 +0,0 @@
-kind: Feature
-body: '[DX] move async-upload-bundle features into chill-bundles'
-time: 2023-12-12T15:48:41.954970271+01:00
-custom:
- Issue: "221"
diff --git a/.changes/unreleased/Feature-20240530-160003.yaml b/.changes/unreleased/Feature-20240530-160003.yaml
deleted file mode 100644
index 6b6baedc5..000000000
--- a/.changes/unreleased/Feature-20240530-160003.yaml
+++ /dev/null
@@ -1,6 +0,0 @@
-kind: Feature
-body: |
- Upgrade import of address list to the last version of compiled addresses of belgian-best-address
-time: 2024-05-30T16:00:03.440767606+02:00
-custom:
- Issue: ""
diff --git a/.changes/unreleased/Feature-20240531-190242.yaml b/.changes/unreleased/Feature-20240531-190242.yaml
deleted file mode 100644
index 083298a26..000000000
--- a/.changes/unreleased/Feature-20240531-190242.yaml
+++ /dev/null
@@ -1,6 +0,0 @@
-kind: Feature
-body: |
- Upgrade CKEditor and refactor configuration with use of typescript
-time: 2024-05-31T19:02:42.776662753+02:00
-custom:
- Issue: ""
diff --git a/.changes/unreleased/Fixed-20240410-103736.yaml b/.changes/unreleased/Fixed-20240410-103736.yaml
deleted file mode 100644
index 355d24b1e..000000000
--- a/.changes/unreleased/Fixed-20240410-103736.yaml
+++ /dev/null
@@ -1,6 +0,0 @@
-kind: Fixed
-body: Fix resolving of centers for an household, which will fix in turn the access
- control
-time: 2024-04-10T10:37:36.462484988+02:00
-custom:
- Issue: ""
diff --git a/.changes/v2.22.0.md b/.changes/v2.22.0.md
new file mode 100644
index 000000000..fef006fd0
--- /dev/null
+++ b/.changes/v2.22.0.md
@@ -0,0 +1,6 @@
+## v2.22.0 - 2024-06-25
+### Feature
+* ([#216](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/216)) [event bundle] exports added for the event module
+
+### Traduction francophone
+* Exports sont ajoutés pour la module événement.
diff --git a/.changes/v2.22.1.md b/.changes/v2.22.1.md
new file mode 100644
index 000000000..b856cc95b
--- /dev/null
+++ b/.changes/v2.22.1.md
@@ -0,0 +1,5 @@
+## v2.22.1 - 2024-07-01
+### Fixed
+* Remove debug word
+### DX
+* Add a command for reading official address DB from Luxembourg and update chill addresses
diff --git a/.changes/v2.22.2.md b/.changes/v2.22.2.md
new file mode 100644
index 000000000..51b3c75da
--- /dev/null
+++ b/.changes/v2.22.2.md
@@ -0,0 +1,3 @@
+## v2.22.2 - 2024-07-03
+### Fixed
+* Remove scope required for event participation stats
diff --git a/.changes/v2.23.0.md b/.changes/v2.23.0.md
new file mode 100644
index 000000000..6b2aea37a
--- /dev/null
+++ b/.changes/v2.23.0.md
@@ -0,0 +1,11 @@
+## v2.23.0 - 2024-07-23
+### Feature
+* ([#221](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/221)) [DX] move async-upload-bundle features into chill-bundles
+* Add job bundle (module emploi)
+* Upgrade import of address list to the last version of compiled addresses of belgian-best-address
+
+* Upgrade CKEditor and refactor configuration with use of typescript
+
+### Fixed
+* Fix resolving of centers for an household, which will fix in turn the access control
+* Resolved type hinting error in activity list export
diff --git a/.changes/v3.0.0.md b/.changes/v3.0.0.md
new file mode 100644
index 000000000..586e648da
--- /dev/null
+++ b/.changes/v3.0.0.md
@@ -0,0 +1,5 @@
+## v3.0.0 - 2024-08-26
+### Fixed
+* Fix delete action for accompanying periods in draft state
+* Fix connection to azure when making an calendar event in chill
+* CollectionType js fixes for remove button and adding multiple entries
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index e355d95de..bb5c8dd5d 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -138,4 +138,4 @@ release:
- echo "running release_job"
release:
tag_name: '$CI_COMMIT_TAG'
- description: "./.changes/v$CI_COMMIT_TAG.md"
+ description: "./.changes/$CI_COMMIT_TAG.md"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index dc8f2305a..3aa0c490d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,41 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html),
and is generated by [Changie](https://github.com/miniscruff/changie).
+## v3.0.0 - 2024-08-26
+### Fixed
+* Fix delete action for accompanying periods in draft state
+* Fix connection to azure when making an calendar event in chill
+* CollectionType js fixes for remove button and adding multiple entries
+
+## v2.23.0 - 2024-07-23
+### Feature
+* ([#221](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/221)) [DX] move async-upload-bundle features into chill-bundles
+* Add job bundle (module emploi)
+* Upgrade import of address list to the last version of compiled addresses of belgian-best-address
+
+* Upgrade CKEditor and refactor configuration with use of typescript
+
+### Fixed
+* Fix resolving of centers for an household, which will fix in turn the access control
+* Resolved type hinting error in activity list export
+
+## v2.22.2 - 2024-07-03
+### Fixed
+* Remove scope required for event participation stats
+
+## v2.22.1 - 2024-07-01
+### Fixed
+* Remove debug word
+### DX
+* Add a command for reading official address DB from Luxembourg and update chill addresses
+
+## v2.22.0 - 2024-06-25
+### Feature
+* ([#216](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/216)) [event bundle] exports added for the event module
+
+### Traduction francophone
+* Exports sont ajoutés pour la module événement.
+
## v2.21.0 - 2024-06-18
### Feature
* Add flash menu buttons in search results, to open directly a new calendar, or a new activity in an accompanying period
diff --git a/composer.json b/composer.json
index 984e0db60..c65217c13 100644
--- a/composer.json
+++ b/composer.json
@@ -115,6 +115,8 @@
"Chill\\DocGeneratorBundle\\": "src/Bundle/ChillDocGeneratorBundle",
"Chill\\DocStoreBundle\\": "src/Bundle/ChillDocStoreBundle",
"Chill\\EventBundle\\": "src/Bundle/ChillEventBundle",
+ "Chill\\FranceTravailApiBundle\\": "src/Bundle/ChillFranceTravailApiBundle/src",
+ "Chill\\JobBundle\\": "src/Bundle/ChillJobBundle/src",
"Chill\\MainBundle\\": "src/Bundle/ChillMainBundle",
"Chill\\PersonBundle\\": "src/Bundle/ChillPersonBundle",
"Chill\\ReportBundle\\": "src/Bundle/ChillReportBundle",
diff --git a/docs/source/_static/code/exports/BirthdateFilter.php b/docs/source/_static/code/exports/BirthdateFilter.php
index e25d8b42f..fca768ab3 100644
--- a/docs/source/_static/code/exports/BirthdateFilter.php
+++ b/docs/source/_static/code/exports/BirthdateFilter.php
@@ -21,7 +21,7 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface;
class BirthdateFilter implements ExportElementValidatedInterface, FilterInterface
{
// add specific role for this filter
- public function addRole()
+ public function addRole(): ?string
{
// we do not need any new role for this filter, so we return null
return null;
diff --git a/docs/source/installation/index.rst b/docs/source/installation/index.rst
index 072a32ffb..a9a4ea0c6 100644
--- a/docs/source/installation/index.rst
+++ b/docs/source/installation/index.rst
@@ -56,7 +56,7 @@ We strongly encourage you to initialize a git repository at this step, to track
cat <<< "$(jq '.extra.symfony += {"endpoint": ["flex://defaults", "https://gitlab.com/api/v4/projects/57371968/repository/files/index.json/raw?ref=main"]}' composer.json)" > composer.json
# install chill and some dependencies
# TODO fix the suffix "alpha1" and replace by ^3.0.0 when version 3.0.0 will be released
- symfony composer require chill-project/chill-bundles v3.0.0-alpha1 champs-libres/wopi-lib dev-master@dev champs-libres/wopi-bundle dev-master@dev
+ symfony composer require chill-project/chill-bundles v3.0.0-RC3 champs-libres/wopi-lib dev-master@dev champs-libres/wopi-bundle dev-master@dev
We encourage you to accept the inclusion of the "Docker configuration from recipes": this is the documented way to run the database.
You must also accept to configure recipes from the contrib repository, unless you want to configure the bundles manually).
@@ -110,15 +110,14 @@ you can either:
.. code-block:: env
ADMIN_PASSWORD=\$2y\$13\$iyvJLuT4YEa6iWXyQV4/N.hNHpNG8kXlYDkkt5MkYy4FXcSwYAwmm
+ # note: if you copy-paste the line above, the password will be "admin".
- add the generated password to the secrets manager (**note**: you must add the generated hashed password to the secrets env,
not the password in clear text).
- set up the jwt authentication bundle
-Some environment variables are available for the JWT authentication bundle in the :code:`.env` file. You must also run the command
-:code:`symfony console lexik:jwt:generate-keypair` to generate some keys that will be stored in the paths set up in the :code:`JWT_SECRET_KEY`
-and the :code:`JWT_PUBLIC_KEY` env variables. This is only required for using the stored documents in Chill.
+Some environment variables are available for the JWT authentication bundle in the :code:`.env` file.
Prepare migrations and other tools
**********************************
@@ -136,6 +135,8 @@ To continue the installation process, you will have to run migrations:
symfony console messenger:setup-transports
# prepare some views
symfony console chill:db:sync-views
+ # generate jwt token, required for some api features (webdav access, ...)
+ symfony console lexik:jwt:generate-keypair
.. warning::
diff --git a/package.json b/package.json
index 09438fe84..e0417cd4f 100644
--- a/package.json
+++ b/package.json
@@ -27,7 +27,7 @@
"popper.js": "^1.16.1",
"postcss-loader": "^7.0.2",
"raw-loader": "^4.0.2",
- "sass-loader": "^13.0.0",
+ "sass-loader": "^14.0.0",
"select2": "^4.0.13",
"select2-bootstrap-theme": "0.1.0-beta.10",
"style-loader": "^3.3.1",
diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon
index 8af07174d..641bb5dcd 100644
--- a/phpstan-baseline.neon
+++ b/phpstan-baseline.neon
@@ -1,34 +1,29 @@
parameters:
ignoreErrors:
+ -
+ message: "#^Foreach overwrites \\$key with its key variable\\.$#"
+ count: 1
+ path: src/Bundle/ChillCustomFieldsBundle/Controller/CustomFieldsGroupController.php
+
-
message: "#^Only booleans are allowed in an if condition, mixed given\\.$#"
count: 1
path: src/Bundle/ChillCustomFieldsBundle/Entity/CustomField.php
-
- message: "#^Only booleans are allowed in an if condition, mixed given\\.$#"
+ message: "#^Property Chill\\\\CustomFieldsBundle\\\\Entity\\\\CustomField\\:\\:\\$required \\(false\\) does not accept bool\\.$#"
count: 1
- path: src/Bundle/ChillPersonBundle/Form/PersonType.php
+ path: src/Bundle/ChillCustomFieldsBundle/Entity/CustomField.php
-
- message: "#^Only booleans are allowed in an if condition, mixed given\\.$#"
- count: 1
- path: src/Bundle/ChillMainBundle/Templating/ChillTwigRoutingHelper.php
-
- -
- message: "#^Only booleans are allowed in an if condition, mixed given\\.$#"
- count: 1
- path: src/Bundle/ChillCustomFieldsBundle/Entity/CustomFieldsGroup.php
-
- -
- message: "#^Only booleans are allowed in an if condition, mixed given\\.$#"
+ message: "#^Parameter \\#1 \\$user of method Chill\\\\DocStoreBundle\\\\Entity\\\\Document\\:\\:setUser\\(\\) expects Chill\\\\MainBundle\\\\Entity\\\\User\\|null, Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\|null given\\.$#"
count: 2
- path: src/Bundle/ChillMainBundle/Repository/NotificationRepository.php
+ path: src/Bundle/ChillDocStoreBundle/Controller/DocumentAccompanyingCourseController.php
-
- message: "#^Foreach overwrites \\$key with its key variable\\.$#"
- count: 1
- path: src/Bundle/ChillCustomFieldsBundle/Controller/CustomFieldsGroupController.php
+ message: "#^Parameter \\#1 \\$user of method Chill\\\\DocStoreBundle\\\\Entity\\\\Document\\:\\:setUser\\(\\) expects Chill\\\\MainBundle\\\\Entity\\\\User\\|null, Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface\\|null given\\.$#"
+ count: 2
+ path: src/Bundle/ChillDocStoreBundle/Controller/DocumentPersonController.php
-
message: "#^Variable \\$participation might not be defined\\.$#"
@@ -40,6 +35,106 @@ parameters:
count: 1
path: src/Bundle/ChillEventBundle/Form/ChoiceLoader/EventChoiceLoader.php
+ -
+ message: "#^Comparison operation \"\\>\" between \\(bool\\|int\\|Redis\\) and 0 results in an error\\.$#"
+ count: 1
+ path: src/Bundle/ChillFranceTravailApiBundle/src/ApiHelper/ApiWrapper.php
+
+ -
+ message: "#^Variable \\$response might not be defined\\.$#"
+ count: 1
+ path: src/Bundle/ChillFranceTravailApiBundle/src/ApiHelper/ApiWrapper.php
+
+ -
+ message: "#^Function GuzzleHttp\\\\Psr7\\\\get not found\\.$#"
+ count: 1
+ path: src/Bundle/ChillFranceTravailApiBundle/src/ApiHelper/PartenaireRomeAppellation.php
+
+ -
+ message: "#^Function GuzzleHttp\\\\Psr7\\\\str not found\\.$#"
+ count: 2
+ path: src/Bundle/ChillFranceTravailApiBundle/src/ApiHelper/PartenaireRomeAppellation.php
+
+ -
+ message: "#^Parameter \\#1 \\$seconds of function sleep expects int, string given\\.$#"
+ count: 1
+ path: src/Bundle/ChillFranceTravailApiBundle/src/ApiHelper/PartenaireRomeAppellation.php
+
+ -
+ message: "#^Unreachable statement \\- code above always terminates\\.$#"
+ count: 1
+ path: src/Bundle/ChillJobBundle/src/Controller/CSPersonController.php
+
+ -
+ message: "#^Parameter \\#1 \\$interval of method DateTimeImmutable\\:\\:add\\(\\) expects DateInterval, string\\|null given\\.$#"
+ count: 1
+ path: src/Bundle/ChillJobBundle/src/Entity/Immersion.php
+
+ -
+ message: "#^Parameter \\#1 \\$object of static method DateTimeImmutable\\:\\:createFromMutable\\(\\) expects DateTime, DateTimeInterface given\\.$#"
+ count: 1
+ path: src/Bundle/ChillJobBundle/src/Entity/Immersion.php
+
+ -
+ message: "#^Property Chill\\\\JobBundle\\\\Entity\\\\Rome\\\\Metier\\:\\:\\$appellations is never read, only written\\.$#"
+ count: 1
+ path: src/Bundle/ChillJobBundle/src/Entity/Rome/Metier.php
+
+ -
+ message: "#^Method Chill\\\\JobBundle\\\\Export\\\\ListCSPerson\\:\\:splitArrayToColumns\\(\\) never returns Closure so it can be removed from the return type\\.$#"
+ count: 1
+ path: src/Bundle/ChillJobBundle/src/Export/ListCSPerson.php
+
+ -
+ message: "#^Variable \\$f might not be defined\\.$#"
+ count: 1
+ path: src/Bundle/ChillJobBundle/src/Export/ListCSPerson.php
+
+ -
+ message: "#^Method Chill\\\\JobBundle\\\\Export\\\\ListFrein\\:\\:splitArrayToColumns\\(\\) never returns Closure so it can be removed from the return type\\.$#"
+ count: 1
+ path: src/Bundle/ChillJobBundle/src/Export/ListFrein.php
+
+ -
+ message: "#^Method Chill\\\\JobBundle\\\\Export\\\\ListProjetProfessionnel\\:\\:splitArrayToColumns\\(\\) never returns Closure so it can be removed from the return type\\.$#"
+ count: 1
+ path: src/Bundle/ChillJobBundle/src/Export/ListProjetProfessionnel.php
+
+ -
+ message: "#^Property Chill\\\\JobBundle\\\\Form\\\\ChoiceLoader\\\\RomeAppellationChoiceLoader\\:\\:\\$appellationRepository \\(Chill\\\\JobBundle\\\\Repository\\\\Rome\\\\AppellationRepository\\) does not accept Doctrine\\\\ORM\\\\EntityRepository\\\\.$#"
+ count: 1
+ path: src/Bundle/ChillJobBundle/src/Form/ChoiceLoader/RomeAppellationChoiceLoader.php
+
+ -
+ message: "#^Result of && is always false\\.$#"
+ count: 1
+ path: src/Bundle/ChillJobBundle/src/Form/ChoiceLoader/RomeAppellationChoiceLoader.php
+
+ -
+ message: "#^Strict comparison using \\=\\=\\= between array\\{\\} and Symfony\\\\Component\\\\Validator\\\\ConstraintViolationListInterface will always evaluate to false\\.$#"
+ count: 2
+ path: src/Bundle/ChillJobBundle/src/Form/ChoiceLoader/RomeAppellationChoiceLoader.php
+
+ -
+ message: "#^Strict comparison using \\=\\=\\= between null and string will always evaluate to false\\.$#"
+ count: 1
+ path: src/Bundle/ChillJobBundle/src/Form/ChoiceLoader/RomeAppellationChoiceLoader.php
+
+ -
+ message: "#^Variable \\$metier might not be defined\\.$#"
+ count: 1
+ path: src/Bundle/ChillJobBundle/src/Form/ChoiceLoader/RomeAppellationChoiceLoader.php
+
+ -
+ message: "#^Parameter \\#1 \\$interval of method DateTimeImmutable\\:\\:add\\(\\) expects DateInterval, string\\|null given\\.$#"
+ count: 1
+ path: src/Bundle/ChillJobBundle/src/Security/Authorization/CSConnectesVoter.php
+
+ -
+ message: "#^Parameter \\#1 \\$object of static method DateTimeImmutable\\:\\:createFromMutable\\(\\) expects DateTime, DateTimeInterface given\\.$#"
+ count: 1
+ path: src/Bundle/ChillJobBundle/src/Security/Authorization/CSConnectesVoter.php
+
-
message: "#^Cannot unset offset '_token' on array\\{formatter\\: mixed, export\\: mixed, centers\\: mixed, alias\\: string\\}\\.$#"
count: 1
@@ -65,11 +160,31 @@ parameters:
count: 1
path: src/Bundle/ChillMainBundle/Form/ChoiceLoader/PostalCodeChoiceLoader.php
+ -
+ message: "#^Only booleans are allowed in an if condition, mixed given\\.$#"
+ count: 2
+ path: src/Bundle/ChillMainBundle/Repository/NotificationRepository.php
+
+ -
+ message: "#^Parameter \\#1 \\$user of method Chill\\\\MainBundle\\\\Security\\\\Authorization\\\\AuthorizationHelper\\:\\:userHasAccessForCenter\\(\\) expects Chill\\\\MainBundle\\\\Entity\\\\User, Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface given\\.$#"
+ count: 1
+ path: src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php
+
+ -
+ message: "#^Only booleans are allowed in an if condition, mixed given\\.$#"
+ count: 1
+ path: src/Bundle/ChillMainBundle/Templating/ChillTwigRoutingHelper.php
+
-
message: "#^Foreach overwrites \\$value with its value variable\\.$#"
count: 1
path: src/Bundle/ChillPersonBundle/Form/ChoiceLoader/PersonChoiceLoader.php
+ -
+ message: "#^Only booleans are allowed in an if condition, mixed given\\.$#"
+ count: 1
+ path: src/Bundle/ChillPersonBundle/Form/PersonType.php
+
-
message: "#^Foreach overwrites \\$value with its value variable\\.$#"
count: 1
diff --git a/rector.php b/rector.php
index 7604667ea..126c814e9 100644
--- a/rector.php
+++ b/rector.php
@@ -28,6 +28,9 @@ return static function (RectorConfig $rectorConfig): void {
// register a single rule
$rectorConfig->rule(InlineConstructorDefaultToPropertyRector::class);
+ $rectorConfig->rule(Rector\TypeDeclaration\Rector\ClassMethod\AddParamTypeFromPropertyTypeRector::class);
+ $rectorConfig->rule(Rector\TypeDeclaration\Rector\Class_\MergeDateTimePropertyTypeDeclarationRector::class);
+ $rectorConfig->rule(Rector\TypeDeclaration\Rector\ClassMethod\AddReturnTypeDeclarationBasedOnParentClassMethodRector::class);
// part of the symfony 54 rules
$rectorConfig->rule(\Rector\Symfony\Symfony53\Rector\StaticPropertyFetch\KernelTestCaseContainerPropertyDeprecationRector::class);
@@ -36,14 +39,14 @@ return static function (RectorConfig $rectorConfig): void {
//define sets of rules
$rectorConfig->sets([
- \Rector\Symfony\Set\SymfonySetList::SYMFONY_50,
- \Rector\Symfony\Set\SymfonySetList::SYMFONY_50_TYPES,
- \Rector\Symfony\Set\SymfonySetList::SYMFONY_51,
- \Rector\Symfony\Set\SymfonySetList::SYMFONY_52,
- \Rector\Symfony\Set\SymfonySetList::SYMFONY_53,
- \Rector\Symfony\Set\SymfonySetList::SYMFONY_54,
+ LevelSetList::UP_TO_PHP_82,
+ \Rector\Symfony\Set\SymfonySetList::SYMFONY_40,
+ \Rector\Symfony\Set\SymfonySetList::SYMFONY_41,
+ \Rector\Symfony\Set\SymfonySetList::SYMFONY_42,
+ \Rector\Symfony\Set\SymfonySetList::SYMFONY_43,
+ \Rector\Symfony\Set\SymfonySetList::SYMFONY_44,
\Rector\Doctrine\Set\DoctrineSetList::DOCTRINE_CODE_QUALITY,
- \Rector\Doctrine\Set\DoctrineSetList::ANNOTATIONS_TO_ATTRIBUTES,
+ \Rector\PHPUnit\Set\PHPUnitSetList::PHPUNIT_90,
]);
$rectorConfig->ruleWithConfiguration(\Rector\Php80\Rector\Class_\AnnotationToAttributeRector::class, [
@@ -66,9 +69,8 @@ return static function (RectorConfig $rectorConfig): void {
// skip some path...
$rectorConfig->skip([
- // we must adapt service definition
- \Rector\Symfony\Symfony28\Rector\MethodCall\GetToConstructorInjectionRector::class,
- \Rector\Symfony\Symfony34\Rector\Closure\ContainerGetNameToTypeInTestsRector::class,
+ // waiting for fixing this bug: https://github.com/rectorphp/rector-doctrine/issues/342
+ \Rector\Doctrine\CodeQuality\Rector\Property\ImproveDoctrineCollectionDocTypeInEntityRector::class,
]);
$rectorConfig->ruleWithConfiguration(AnnotationToAttributeRector::class, [
diff --git a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php
index 2248c54d3..cbfb93400 100644
--- a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php
+++ b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php
@@ -99,10 +99,10 @@ final class ActivityController extends AbstractController
$form = $this->createDeleteForm($activity->getId(), $person, $accompanyingPeriod);
- if (Request::METHOD_DELETE === $request->getMethod()) {
+ if (Request::METHOD_POST === $request->getMethod()) {
$form->handleRequest($request);
- if ($form->isValid()) {
+ if ($form->isSubmitted() && $form->isValid()) {
$this->logger->notice('An activity has been removed', [
'by_user' => $this->getUser()->getUsername(),
'activity_id' => $activity->getId(),
@@ -640,7 +640,6 @@ final class ActivityController extends AbstractController
return $this->createFormBuilder()
->setAction($this->generateUrl('chill_activity_activity_delete', $params))
- ->setMethod('DELETE')
->add('submit', SubmitType::class, ['label' => 'Delete'])
->getForm();
}
diff --git a/src/Bundle/ChillActivityBundle/Entity/Activity.php b/src/Bundle/ChillActivityBundle/Entity/Activity.php
index 2e7bede57..9f557f9b5 100644
--- a/src/Bundle/ChillActivityBundle/Entity/Activity.php
+++ b/src/Bundle/ChillActivityBundle/Entity/Activity.php
@@ -80,7 +80,7 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac
private \DateTime $date;
/**
- * @var Collection
+ * @var Collection
*/
#[Assert\Valid(traverse: true)]
#[ORM\ManyToMany(targetEntity: StoredObject::class, cascade: ['persist'])]
@@ -107,7 +107,7 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac
private ?Person $person = null;
/**
- * @var Collection
+ * @var Collection
*/
#[Groups(['read', 'docgen:read'])]
#[ORM\ManyToMany(targetEntity: Person::class)]
@@ -117,7 +117,7 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac
private PrivateCommentEmbeddable $privateComment;
/**
- * @var Collection
+ * @var Collection
*/
#[Groups(['docgen:read'])]
#[ORM\ManyToMany(targetEntity: ActivityReason::class)]
@@ -132,7 +132,7 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac
private string $sentReceived = '';
/**
- * @var Collection
+ * @var Collection
*/
#[Groups(['read', 'docgen:read'])]
#[ORM\ManyToMany(targetEntity: SocialAction::class)]
@@ -140,7 +140,7 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac
private Collection $socialActions;
/**
- * @var Collection
+ * @var Collection
*/
#[Groups(['read', 'docgen:read'])]
#[ORM\ManyToMany(targetEntity: SocialIssue::class)]
@@ -148,7 +148,7 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac
private Collection $socialIssues;
/**
- * @var Collection
+ * @var Collection
*/
#[Groups(['read', 'docgen:read'])]
#[ORM\ManyToMany(targetEntity: ThirdParty::class)]
@@ -162,7 +162,7 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac
private ?User $user = null;
/**
- * @var Collection
+ * @var Collection
*/
#[Groups(['read', 'docgen:read'])]
#[ORM\ManyToMany(targetEntity: User::class)]
diff --git a/src/Bundle/ChillActivityBundle/Entity/ActivityReason.php b/src/Bundle/ChillActivityBundle/Entity/ActivityReason.php
index 5c6576497..bf36ead6c 100644
--- a/src/Bundle/ChillActivityBundle/Entity/ActivityReason.php
+++ b/src/Bundle/ChillActivityBundle/Entity/ActivityReason.php
@@ -79,11 +79,9 @@ class ActivityReason
/**
* Set active.
*
- * @param bool $active
- *
* @return ActivityReason
*/
- public function setActive($active)
+ public function setActive(bool $active)
{
$this->active = $active;
@@ -110,11 +108,9 @@ class ActivityReason
/**
* Set name.
*
- * @param array $name
- *
* @return ActivityReason
*/
- public function setName($name)
+ public function setName(array $name)
{
$this->name = $name;
diff --git a/src/Bundle/ChillActivityBundle/Entity/ActivityReasonCategory.php b/src/Bundle/ChillActivityBundle/Entity/ActivityReasonCategory.php
index 9346d12a0..b31bb8731 100644
--- a/src/Bundle/ChillActivityBundle/Entity/ActivityReasonCategory.php
+++ b/src/Bundle/ChillActivityBundle/Entity/ActivityReasonCategory.php
@@ -40,9 +40,9 @@ class ActivityReasonCategory implements \Stringable
/**
* Array of ActivityReason.
*
- * @var Collection
+ * @var Collection
*/
- #[ORM\OneToMany(targetEntity: ActivityReason::class, mappedBy: 'category')]
+ #[ORM\OneToMany(mappedBy: 'category', targetEntity: ActivityReason::class)]
private Collection $reasons;
/**
diff --git a/src/Bundle/ChillActivityBundle/Export/Export/ListActivityHelper.php b/src/Bundle/ChillActivityBundle/Export/Export/ListActivityHelper.php
index 75d2c3fd0..15137b013 100644
--- a/src/Bundle/ChillActivityBundle/Export/Export/ListActivityHelper.php
+++ b/src/Bundle/ChillActivityBundle/Export/Export/ListActivityHelper.php
@@ -152,7 +152,7 @@ class ListActivityHelper
return '';
}
- return $this->translator->trans($value);
+ return $this->translator->trans((string) $value);
},
};
}
diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/PeriodHavingActivityBetweenDatesFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/PeriodHavingActivityBetweenDatesFilter.php
index 2d3282ad1..1a006ba97 100644
--- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/PeriodHavingActivityBetweenDatesFilter.php
+++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/PeriodHavingActivityBetweenDatesFilter.php
@@ -73,7 +73,7 @@ final readonly class PeriodHavingActivityBetweenDatesFilter implements FilterInt
$qb->andWhere(
$qb->expr()->exists(
- 'SELECT 1 FROM '.Activity::class." {$alias} WHERE {$alias}.date >= :{$from} AND {$alias}.date < :{$to} AND {$alias}.accompanyingPeriod = acp"
+ 'SELECT 1 FROM '.Activity::class." {$alias} WHERE {$alias}.date >= :{$from} AND {$alias}.date < :{$to} AND {$alias}.accompanyingPeriod = activity.accompanyingPeriod"
)
);
diff --git a/src/Bundle/ChillActivityBundle/Repository/ActivityTypeRepository.php b/src/Bundle/ChillActivityBundle/Repository/ActivityTypeRepository.php
index 99adf4fe0..698c8b370 100644
--- a/src/Bundle/ChillActivityBundle/Repository/ActivityTypeRepository.php
+++ b/src/Bundle/ChillActivityBundle/Repository/ActivityTypeRepository.php
@@ -15,9 +15,9 @@ use Chill\ActivityBundle\Entity\ActivityType;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
-final class ActivityTypeRepository implements ActivityTypeRepositoryInterface
+final readonly class ActivityTypeRepository implements ActivityTypeRepositoryInterface
{
- private readonly EntityRepository $repository;
+ private EntityRepository $repository;
public function __construct(EntityManagerInterface $em)
{
diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/concernedGroups.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/concernedGroups.html.twig
index 76db92d42..5528ab233 100644
--- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/concernedGroups.html.twig
+++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/concernedGroups.html.twig
@@ -87,7 +87,6 @@
{% if bloc.type == 'user' %}
- hello
{{ item|chill_entity_render_box({'render': 'raw', 'addAltNames': false, 'at_date': entity.date }) }}
{% else %}
diff --git a/src/Bundle/ChillAsideActivityBundle/src/Entity/AsideActivityCategory.php b/src/Bundle/ChillAsideActivityBundle/src/Entity/AsideActivityCategory.php
index 1758cdd3d..712039c5b 100644
--- a/src/Bundle/ChillAsideActivityBundle/src/Entity/AsideActivityCategory.php
+++ b/src/Bundle/ChillAsideActivityBundle/src/Entity/AsideActivityCategory.php
@@ -22,9 +22,9 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface;
class AsideActivityCategory
{
/**
- * @var Collection
+ * @var Collection
*/
- #[ORM\OneToMany(targetEntity: AsideActivityCategory::class, mappedBy: 'parent')]
+ #[ORM\OneToMany(mappedBy: 'parent', targetEntity: AsideActivityCategory::class)]
private Collection $children;
#[ORM\Id]
diff --git a/src/Bundle/ChillBudgetBundle/Controller/AbstractElementController.php b/src/Bundle/ChillBudgetBundle/Controller/AbstractElementController.php
index d293907f5..bb204c557 100644
--- a/src/Bundle/ChillBudgetBundle/Controller/AbstractElementController.php
+++ b/src/Bundle/ChillBudgetBundle/Controller/AbstractElementController.php
@@ -54,7 +54,7 @@ abstract class AbstractElementController extends AbstractController
$indexPage = 'chill_budget_elements_household_index';
}
- if (Request::METHOD_DELETE === $request->getMethod()) {
+ if (Request::METHOD_POST === $request->getMethod()) {
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
@@ -198,10 +198,9 @@ abstract class AbstractElementController extends AbstractController
/**
* Creates a form to delete a help request entity by id.
*/
- private function createDeleteForm(): Form
+ private function createDeleteForm(): \Symfony\Component\Form\FormInterface
{
return $this->createFormBuilder()
- ->setMethod(Request::METHOD_DELETE)
->add('submit', SubmitType::class, ['label' => 'Delete'])
->getForm();
}
diff --git a/src/Bundle/ChillBudgetBundle/Entity/Charge.php b/src/Bundle/ChillBudgetBundle/Entity/Charge.php
index 5857b8b67..b4b2918c9 100644
--- a/src/Bundle/ChillBudgetBundle/Entity/Charge.php
+++ b/src/Bundle/ChillBudgetBundle/Entity/Charge.php
@@ -100,7 +100,7 @@ class Charge extends AbstractElement implements HasCentersInterface
return $this;
}
- public function setHelp($help)
+ public function setHelp(?string $help)
{
$this->help = $help;
diff --git a/src/Bundle/ChillBudgetBundle/Repository/ChargeKindRepository.php b/src/Bundle/ChillBudgetBundle/Repository/ChargeKindRepository.php
index a0c23a4ad..b2bb9e82e 100644
--- a/src/Bundle/ChillBudgetBundle/Repository/ChargeKindRepository.php
+++ b/src/Bundle/ChillBudgetBundle/Repository/ChargeKindRepository.php
@@ -15,9 +15,9 @@ use Chill\BudgetBundle\Entity\ChargeKind;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
-final class ChargeKindRepository implements ChargeKindRepositoryInterface
+final readonly class ChargeKindRepository implements ChargeKindRepositoryInterface
{
- private readonly EntityRepository $repository;
+ private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager)
{
diff --git a/src/Bundle/ChillBudgetBundle/Repository/ResourceKindRepository.php b/src/Bundle/ChillBudgetBundle/Repository/ResourceKindRepository.php
index 723f26748..18051f120 100644
--- a/src/Bundle/ChillBudgetBundle/Repository/ResourceKindRepository.php
+++ b/src/Bundle/ChillBudgetBundle/Repository/ResourceKindRepository.php
@@ -15,9 +15,9 @@ use Chill\BudgetBundle\Entity\ResourceKind;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
-final class ResourceKindRepository implements ResourceKindRepositoryInterface
+final readonly class ResourceKindRepository implements ResourceKindRepositoryInterface
{
- private readonly EntityRepository $repository;
+ private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager)
{
diff --git a/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php b/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php
index 328b8788f..e57d2743d 100644
--- a/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php
+++ b/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php
@@ -84,7 +84,7 @@ class CalendarController extends AbstractController
$form = $this->createDeleteForm($entity);
- if (Request::METHOD_DELETE === $request->getMethod()) {
+ if (Request::METHOD_POST === $request->getMethod()) {
$form->handleRequest($request);
if ($form->isValid()) {
@@ -512,7 +512,6 @@ class CalendarController extends AbstractController
{
return $this->createFormBuilder()
->setAction($this->generateUrl('chill_calendar_calendar_delete', ['id' => $calendar->getId()]))
- ->setMethod('DELETE')
->add('submit', SubmitType::class, ['label' => 'Delete'])
->getForm();
}
diff --git a/src/Bundle/ChillCalendarBundle/Entity/Calendar.php b/src/Bundle/ChillCalendarBundle/Entity/Calendar.php
index 53949d1f0..05d75a9bc 100644
--- a/src/Bundle/ChillCalendarBundle/Entity/Calendar.php
+++ b/src/Bundle/ChillCalendarBundle/Entity/Calendar.php
@@ -103,7 +103,7 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface, HasCente
private int $dateTimeVersion = 0;
/**
- * @var Collection
+ * @var Collection
*/
#[ORM\OneToMany(mappedBy: 'calendar', targetEntity: CalendarDoc::class, orphanRemoval: true)]
private Collection $documents;
@@ -120,7 +120,7 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface, HasCente
private ?int $id = null;
/**
- * @var Collection&Selectable
+ * @var \Doctrine\Common\Collections\Collection&Selectable
*/
#[Serializer\Groups(['read', 'docgen:read'])]
#[ORM\OneToMany(mappedBy: 'calendar', targetEntity: Invite::class, cascade: ['persist', 'remove', 'merge', 'detach'], orphanRemoval: true)]
@@ -143,7 +143,7 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface, HasCente
private ?Person $person = null;
/**
- * @var Collection
+ * @var Collection
*/
#[Serializer\Groups(['calendar:read', 'read', 'calendar:light', 'docgen:read'])]
#[Assert\Count(min: 1, minMessage: 'calendar.At least {{ limit }} person is required.')]
@@ -157,7 +157,7 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface, HasCente
private PrivateCommentEmbeddable $privateComment;
/**
- * @var Collection
+ * @var Collection
*/
#[Serializer\Groups(['calendar:read', 'read', 'calendar:light', 'docgen:read'])]
#[ORM\ManyToMany(targetEntity: ThirdParty::class)]
diff --git a/src/Bundle/ChillCalendarBundle/Tests/Service/DocGenerator/CalendarContextTest.php b/src/Bundle/ChillCalendarBundle/Tests/Service/DocGenerator/CalendarContextTest.php
index 4a4b4f7d4..c06872a66 100644
--- a/src/Bundle/ChillCalendarBundle/Tests/Service/DocGenerator/CalendarContextTest.php
+++ b/src/Bundle/ChillCalendarBundle/Tests/Service/DocGenerator/CalendarContextTest.php
@@ -47,7 +47,7 @@ final class CalendarContextTest extends TestCase
{
$expected =
[
- 'track_datetime' => true,
+ 'trackDatetime' => true,
'askMainPerson' => true,
'mainPersonLabel' => 'docgen.calendar.Destinee',
'askThirdParty' => false,
@@ -61,7 +61,7 @@ final class CalendarContextTest extends TestCase
{
$expected =
[
- 'track_datetime' => true,
+ 'trackDatetime' => true,
'askMainPerson' => true,
'mainPersonLabel' => 'docgen.calendar.Destinee',
'askThirdParty' => false,
diff --git a/src/Bundle/ChillCustomFieldsBundle/Entity/CustomField.php b/src/Bundle/ChillCustomFieldsBundle/Entity/CustomField.php
index 9fddc10b3..06ff658c7 100644
--- a/src/Bundle/ChillCustomFieldsBundle/Entity/CustomField.php
+++ b/src/Bundle/ChillCustomFieldsBundle/Entity/CustomField.php
@@ -172,11 +172,9 @@ class CustomField
/**
* Set active.
*
- * @param bool $active
- *
* @return CustomField
*/
- public function setActive($active)
+ public function setActive(bool $active)
{
$this->active = $active;
@@ -224,18 +222,16 @@ class CustomField
/**
* Set order.
*
- * @param float $order
- *
* @return CustomField
*/
- public function setOrdering($order)
+ public function setOrdering(?float $order)
{
$this->ordering = $order;
return $this;
}
- public function setRequired($required)
+ public function setRequired(bool $required)
{
$this->required = $required;
@@ -245,7 +241,7 @@ class CustomField
/**
* @return $this
*/
- public function setSlug($slug)
+ public function setSlug(?string $slug)
{
$this->slug = $slug;
@@ -255,11 +251,9 @@ class CustomField
/**
* Set type.
*
- * @param string $type
- *
* @return CustomField
*/
- public function setType($type)
+ public function setType(?string $type)
{
$this->type = $type;
diff --git a/src/Bundle/ChillCustomFieldsBundle/Entity/CustomFieldLongChoice/Option.php b/src/Bundle/ChillCustomFieldsBundle/Entity/CustomFieldLongChoice/Option.php
index 497cf7150..c8bdc6031 100644
--- a/src/Bundle/ChillCustomFieldsBundle/Entity/CustomFieldLongChoice/Option.php
+++ b/src/Bundle/ChillCustomFieldsBundle/Entity/CustomFieldLongChoice/Option.php
@@ -23,9 +23,9 @@ class Option
private bool $active = true;
/**
- * @var Collection
+ * @var Collection
*/
- #[ORM\OneToMany(targetEntity: Option::class, mappedBy: 'parent')]
+ #[ORM\OneToMany(mappedBy: 'parent', targetEntity: Option::class)]
private Collection $children;
#[ORM\Id]
@@ -129,7 +129,7 @@ class Option
/**
* @return $this
*/
- public function setActive($active)
+ public function setActive(bool $active)
{
$this->active = $active;
@@ -139,7 +139,7 @@ class Option
/**
* @return $this
*/
- public function setInternalKey($internal_key)
+ public function setInternalKey(string $internal_key)
{
$this->internalKey = $internal_key;
@@ -149,7 +149,7 @@ class Option
/**
* @return $this
*/
- public function setKey($key)
+ public function setKey(?string $key)
{
$this->key = $key;
diff --git a/src/Bundle/ChillCustomFieldsBundle/Entity/CustomFieldsDefaultGroup.php b/src/Bundle/ChillCustomFieldsBundle/Entity/CustomFieldsDefaultGroup.php
index 918872860..c0022d530 100644
--- a/src/Bundle/ChillCustomFieldsBundle/Entity/CustomFieldsDefaultGroup.php
+++ b/src/Bundle/ChillCustomFieldsBundle/Entity/CustomFieldsDefaultGroup.php
@@ -69,7 +69,7 @@ class CustomFieldsDefaultGroup
*
* @return CustomFieldsDefaultGroup
*/
- public function setCustomFieldsGroup($customFieldsGroup)
+ public function setCustomFieldsGroup(?CustomFieldsGroup $customFieldsGroup)
{
$this->customFieldsGroup = $customFieldsGroup;
@@ -79,11 +79,9 @@ class CustomFieldsDefaultGroup
/**
* Set entity.
*
- * @param string $entity
- *
* @return CustomFieldsDefaultGroup
*/
- public function setEntity($entity)
+ public function setEntity(?string $entity)
{
$this->entity = $entity;
diff --git a/src/Bundle/ChillCustomFieldsBundle/Entity/CustomFieldsGroup.php b/src/Bundle/ChillCustomFieldsBundle/Entity/CustomFieldsGroup.php
index 25040ec5f..55f09597c 100644
--- a/src/Bundle/ChillCustomFieldsBundle/Entity/CustomFieldsGroup.php
+++ b/src/Bundle/ChillCustomFieldsBundle/Entity/CustomFieldsGroup.php
@@ -32,9 +32,9 @@ class CustomFieldsGroup
* The custom fields of the group.
* The custom fields are asc-ordered regarding to their property "ordering".
*
- * @var Collection
+ * @var Collection
*/
- #[ORM\OneToMany(targetEntity: CustomField::class, mappedBy: 'customFieldGroup')]
+ #[ORM\OneToMany(mappedBy: 'customFieldGroup', targetEntity: CustomField::class)]
#[ORM\OrderBy(['ordering' => \Doctrine\Common\Collections\Criteria::ASC])]
private Collection $customFields;
@@ -165,11 +165,9 @@ class CustomFieldsGroup
/**
* Set entity.
*
- * @param string $entity
- *
* @return CustomFieldsGroup
*/
- public function setEntity($entity)
+ public function setEntity(?string $entity)
{
$this->entity = $entity;
diff --git a/src/Bundle/ChillDocGeneratorBundle/GeneratorDriver/RelatorioDriver.php b/src/Bundle/ChillDocGeneratorBundle/GeneratorDriver/RelatorioDriver.php
index b46ee09b2..1ee3f0ba1 100644
--- a/src/Bundle/ChillDocGeneratorBundle/GeneratorDriver/RelatorioDriver.php
+++ b/src/Bundle/ChillDocGeneratorBundle/GeneratorDriver/RelatorioDriver.php
@@ -21,14 +21,14 @@ use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
-final class RelatorioDriver implements DriverInterface
+final readonly class RelatorioDriver implements DriverInterface
{
- private readonly string $url;
+ private string $url;
public function __construct(
- private readonly HttpClientInterface $client,
+ private HttpClientInterface $client,
ParameterBagInterface $parameterBag,
- private readonly LoggerInterface $logger
+ private LoggerInterface $logger
) {
$this->url = $parameterBag->get('chill_doc_generator')['driver']['relatorio']['url'];
}
diff --git a/src/Bundle/ChillDocGeneratorBundle/Repository/DocGeneratorTemplateRepository.php b/src/Bundle/ChillDocGeneratorBundle/Repository/DocGeneratorTemplateRepository.php
index b5f409032..498daf7ba 100644
--- a/src/Bundle/ChillDocGeneratorBundle/Repository/DocGeneratorTemplateRepository.php
+++ b/src/Bundle/ChillDocGeneratorBundle/Repository/DocGeneratorTemplateRepository.php
@@ -16,11 +16,11 @@ use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Symfony\Component\HttpFoundation\RequestStack;
-final class DocGeneratorTemplateRepository implements DocGeneratorTemplateRepositoryInterface
+final readonly class DocGeneratorTemplateRepository implements DocGeneratorTemplateRepositoryInterface
{
- private readonly EntityRepository $repository;
+ private EntityRepository $repository;
- public function __construct(EntityManagerInterface $entityManager, private readonly RequestStack $requestStack)
+ public function __construct(EntityManagerInterface $entityManager, private RequestStack $requestStack)
{
$this->repository = $entityManager->getRepository(DocGeneratorTemplate::class);
}
diff --git a/src/Bundle/ChillDocStoreBundle/Entity/Document.php b/src/Bundle/ChillDocStoreBundle/Entity/Document.php
index b8c15c27c..1970d1127 100644
--- a/src/Bundle/ChillDocStoreBundle/Entity/Document.php
+++ b/src/Bundle/ChillDocStoreBundle/Entity/Document.php
@@ -129,7 +129,7 @@ class Document implements TrackCreationInterface, TrackUpdateInterface
return $this;
}
- public function setUser($user): self
+ public function setUser(?\Chill\MainBundle\Entity\User $user): self
{
$this->user = $user;
diff --git a/src/Bundle/ChillDocStoreBundle/Entity/DocumentCategory.php b/src/Bundle/ChillDocStoreBundle/Entity/DocumentCategory.php
index 452f463f8..bac09414a 100644
--- a/src/Bundle/ChillDocStoreBundle/Entity/DocumentCategory.php
+++ b/src/Bundle/ChillDocStoreBundle/Entity/DocumentCategory.php
@@ -86,7 +86,7 @@ class DocumentCategory
return $this;
}
- public function setDocumentClass($documentClass): self
+ public function setDocumentClass(?string $documentClass): self
{
$this->documentClass = $documentClass;
diff --git a/src/Bundle/ChillDocStoreBundle/Entity/PersonDocument.php b/src/Bundle/ChillDocStoreBundle/Entity/PersonDocument.php
index dfc5b72a9..b6eefc733 100644
--- a/src/Bundle/ChillDocStoreBundle/Entity/PersonDocument.php
+++ b/src/Bundle/ChillDocStoreBundle/Entity/PersonDocument.php
@@ -55,14 +55,14 @@ class PersonDocument extends Document implements HasCenterInterface, HasScopeInt
return $this->scope;
}
- public function setPerson($person): self
+ public function setPerson(Person $person): self
{
$this->person = $person;
return $this;
}
- public function setScope($scope): self
+ public function setScope(?Scope $scope): self
{
$this->scope = $scope;
diff --git a/src/Bundle/ChillEventBundle/Controller/EventController.php b/src/Bundle/ChillEventBundle/Controller/EventController.php
index ad67728d7..dc7da134c 100644
--- a/src/Bundle/ChillEventBundle/Controller/EventController.php
+++ b/src/Bundle/ChillEventBundle/Controller/EventController.php
@@ -15,7 +15,7 @@ use Chill\EventBundle\Entity\Event;
use Chill\EventBundle\Entity\Participation;
use Chill\EventBundle\Form\EventType;
use Chill\EventBundle\Form\Type\PickEventType;
-use Chill\EventBundle\Security\Authorization\EventVoter;
+use Chill\EventBundle\Security\EventVoter;
use Chill\MainBundle\Entity\Center;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Pagination\PaginatorFactory;
@@ -61,7 +61,7 @@ final class EventController extends AbstractController
private readonly \Doctrine\Persistence\ManagerRegistry $managerRegistry
) {}
- #[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/event/event/{event_id}/delete', name: 'chill_event__event_delete', requirements: ['event_id' => '\d+'], methods: ['GET', 'DELETE'])]
+ #[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/event/event/{event_id}/delete', name: 'chill_event__event_delete', requirements: ['event_id' => '\d+'], methods: ['GET', 'POST', 'DELETE'])]
public function deleteAction($event_id, Request $request): \Symfony\Component\HttpFoundation\RedirectResponse|Response
{
$em = $this->managerRegistry->getManager();
@@ -78,10 +78,10 @@ final class EventController extends AbstractController
$form = $this->createDeleteForm($event_id);
- if (Request::METHOD_DELETE === $request->getMethod()) {
+ if (Request::METHOD_POST === $request->getMethod()) {
$form->handleRequest($request);
- if ($form->isValid()) {
+ if ($form->isSubmitted() && $form->isValid()) {
foreach ($participations as $participation) {
$em->remove($participation);
}
@@ -108,28 +108,6 @@ final class EventController extends AbstractController
]);
}
- /**
- * Displays a form to edit an existing Event entity.
- */
- #[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/event/event/{event_id}/edit', name: 'chill_event__event_edit')]
- public function editAction($event_id): Response
- {
- $em = $this->managerRegistry->getManager();
-
- $entity = $em->getRepository(Event::class)->find($event_id);
-
- if (!$entity) {
- throw $this->createNotFoundException('Unable to find Event entity.');
- }
-
- $editForm = $this->createEditForm($entity);
-
- return $this->render('@ChillEvent/Event/edit.html.twig', [
- 'entity' => $entity,
- 'edit_form' => $editForm->createView(),
- ]);
- }
-
/**
* List events subscriptions for a person.
*
@@ -313,7 +291,7 @@ final class EventController extends AbstractController
/**
* Edits an existing Event entity.
*/
- #[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/event/event/{event_id}/update', name: 'chill_event__event_update', methods: ['POST', 'PUT'])]
+ #[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/event/event/{event_id}/edit', name: 'chill_event__event_edit', methods: ['GET', 'POST', 'PUT'])]
public function updateAction(Request $request, $event_id): \Symfony\Component\HttpFoundation\RedirectResponse|Response
{
$em = $this->managerRegistry->getManager();
@@ -324,14 +302,20 @@ final class EventController extends AbstractController
throw $this->createNotFoundException('Unable to find Event entity.');
}
- $editForm = $this->createEditForm($entity);
+ $editForm = $this->createForm(EventType::class, $entity, [
+ 'center' => $entity->getCenter(),
+ 'role' => EventVoter::UPDATE,
+ ]);
+
+ $editForm->add('submit', SubmitType::class, ['label' => 'Update']);
+
$editForm->handleRequest($request);
- if ($editForm->isValid()) {
+ if ($editForm->isSubmitted() && $editForm->isValid()) {
+ $em->persist($entity);
$em->flush();
- $this->addFlash('success', $this->translator
- ->trans('The event was updated'));
+ $this->addFlash('success', $this->translator->trans('The event was updated'));
return $this->redirectToRoute('chill_event__event_show', ['event_id' => $event_id]);
}
@@ -418,7 +402,6 @@ final class EventController extends AbstractController
$builder->add('event_id', HiddenType::class, [
'data' => $event->getId(),
]);
- dump($event->getId());
return $builder->getForm();
}
@@ -600,29 +583,7 @@ final class EventController extends AbstractController
->setAction($this->generateUrl('chill_event__event_delete', [
'event_id' => $event_id,
]))
- ->setMethod('DELETE')
->add('submit', SubmitType::class, ['label' => 'Delete'])
->getForm();
}
-
- /**
- * Creates a form to edit a Event entity.
- *
- * @return \Symfony\Component\Form\FormInterface
- */
- private function createEditForm(Event $entity)
- {
- $form = $this->createForm(EventType::class, $entity, [
- 'action' => $this->generateUrl('chill_event__event_update', ['event_id' => $entity->getId()]),
- 'method' => 'PUT',
- 'center' => $entity->getCenter(),
- 'role' => 'CHILL_EVENT_CREATE',
- ]);
-
- $form->remove('center');
-
- $form->add('submit', SubmitType::class, ['label' => 'Update']);
-
- return $form;
- }
}
diff --git a/src/Bundle/ChillEventBundle/Controller/EventTypeController.php b/src/Bundle/ChillEventBundle/Controller/EventTypeController.php
index 5706dbe19..f7b1b205c 100644
--- a/src/Bundle/ChillEventBundle/Controller/EventTypeController.php
+++ b/src/Bundle/ChillEventBundle/Controller/EventTypeController.php
@@ -201,7 +201,7 @@ class EventTypeController extends AbstractController
/**
* Creates a form to delete a EventType entity by id.
*
- * @return \Symfony\Component\Form\Form The form
+ * @return \Symfony\Component\Form\FormInterface The form
*/
private function createDeleteForm(mixed $id)
{
@@ -210,7 +210,6 @@ class EventTypeController extends AbstractController
'chill_eventtype_admin_delete',
['id' => $id]
))
- ->setMethod('DELETE')
->add('submit', SubmitType::class, ['label' => 'Delete'])
->getForm();
}
diff --git a/src/Bundle/ChillEventBundle/Controller/ParticipationController.php b/src/Bundle/ChillEventBundle/Controller/ParticipationController.php
index 8030a7878..59501acd7 100644
--- a/src/Bundle/ChillEventBundle/Controller/ParticipationController.php
+++ b/src/Bundle/ChillEventBundle/Controller/ParticipationController.php
@@ -15,7 +15,7 @@ use Chill\EventBundle\Entity\Event;
use Chill\EventBundle\Entity\Participation;
use Chill\EventBundle\Form\ParticipationType;
use Chill\EventBundle\Repository\EventRepository;
-use Chill\EventBundle\Security\Authorization\ParticipationVoter;
+use Chill\EventBundle\Security\ParticipationVoter;
use Chill\PersonBundle\Repository\PersonRepository;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use Doctrine\Common\Collections\Collection;
@@ -259,10 +259,10 @@ final class ParticipationController extends AbstractController
$form = $this->createDeleteForm($participation_id);
- if (Request::METHOD_DELETE === $request->getMethod()) {
+ if (Request::METHOD_POST === $request->getMethod()) {
$form->handleRequest($request);
- if ($form->isValid()) {
+ if ($form->isSubmitted() && $form->isValid()) {
$em->remove($participation);
$em->flush();
@@ -753,7 +753,6 @@ final class ParticipationController extends AbstractController
->setAction($this->generateUrl('chill_event_participation_delete', [
'participation_id' => $participation_id,
]))
- ->setMethod('DELETE')
->add('submit', SubmitType::class, ['label' => 'Delete'])
->getForm();
}
diff --git a/src/Bundle/ChillEventBundle/Controller/RoleController.php b/src/Bundle/ChillEventBundle/Controller/RoleController.php
index 24e4f2121..1ff205dfc 100644
--- a/src/Bundle/ChillEventBundle/Controller/RoleController.php
+++ b/src/Bundle/ChillEventBundle/Controller/RoleController.php
@@ -201,7 +201,7 @@ class RoleController extends AbstractController
/**
* Creates a form to delete a Role entity by id.
*
- * @return \Symfony\Component\Form\Form The form
+ * @return \Symfony\Component\Form\FormInterface The form
*/
private function createDeleteForm(mixed $id)
{
diff --git a/src/Bundle/ChillEventBundle/Controller/StatusController.php b/src/Bundle/ChillEventBundle/Controller/StatusController.php
index 286408b0b..3b302500d 100644
--- a/src/Bundle/ChillEventBundle/Controller/StatusController.php
+++ b/src/Bundle/ChillEventBundle/Controller/StatusController.php
@@ -201,13 +201,12 @@ class StatusController extends AbstractController
/**
* Creates a form to delete a Status entity by id.
*
- * @return \Symfony\Component\Form\Form The form
+ * @return \Symfony\Component\Form\FormInterface The form
*/
private function createDeleteForm(mixed $id)
{
return $this->createFormBuilder()
->setAction($this->generateUrl('chill_event_admin_status_delete', ['id' => $id]))
- ->setMethod('DELETE')
->add('submit', SubmitType::class, ['label' => 'Delete'])
->getForm();
}
diff --git a/src/Bundle/ChillEventBundle/DependencyInjection/ChillEventExtension.php b/src/Bundle/ChillEventBundle/DependencyInjection/ChillEventExtension.php
index 8ddcab58c..0b30ca6c5 100644
--- a/src/Bundle/ChillEventBundle/DependencyInjection/ChillEventExtension.php
+++ b/src/Bundle/ChillEventBundle/DependencyInjection/ChillEventExtension.php
@@ -11,8 +11,8 @@ declare(strict_types=1);
namespace Chill\EventBundle\DependencyInjection;
-use Chill\EventBundle\Security\Authorization\EventVoter;
-use Chill\EventBundle\Security\Authorization\ParticipationVoter;
+use Chill\EventBundle\Security\EventVoter;
+use Chill\EventBundle\Security\ParticipationVoter;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
@@ -33,12 +33,13 @@ class ChillEventExtension extends Extension implements PrependExtensionInterface
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../config'));
$loader->load('services.yaml');
- $loader->load('services/authorization.yaml');
+ $loader->load('services/security.yaml');
$loader->load('services/fixtures.yaml');
$loader->load('services/forms.yaml');
$loader->load('services/repositories.yaml');
$loader->load('services/search.yaml');
$loader->load('services/timeline.yaml');
+ $loader->load('services/export.yaml');
}
/** (non-PHPdoc).
diff --git a/src/Bundle/ChillEventBundle/Entity/Event.php b/src/Bundle/ChillEventBundle/Entity/Event.php
index be5969363..2c2105b55 100644
--- a/src/Bundle/ChillEventBundle/Entity/Event.php
+++ b/src/Bundle/ChillEventBundle/Entity/Event.php
@@ -47,7 +47,7 @@ class Event implements HasCenterInterface, HasScopeInterface, TrackCreationInter
private ?Scope $circle = null;
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::DATETIME_MUTABLE)]
- private ?\DateTime $date;
+ private ?\DateTime $date = null;
#[ORM\Id]
#[ORM\Column(name: 'id', type: \Doctrine\DBAL\Types\Types::INTEGER)]
@@ -62,9 +62,9 @@ class Event implements HasCenterInterface, HasScopeInterface, TrackCreationInter
private ?string $name = null;
/**
- * @var Collection
+ * @var Collection
*/
- #[ORM\OneToMany(targetEntity: Participation::class, mappedBy: 'event')]
+ #[ORM\OneToMany(mappedBy: 'event', targetEntity: Participation::class)]
private Collection $participations;
#[Assert\NotNull]
@@ -79,7 +79,7 @@ class Event implements HasCenterInterface, HasScopeInterface, TrackCreationInter
private ?Location $location = null;
/**
- * @var Collection
+ * @var Collection
*/
#[ORM\ManyToMany(targetEntity: StoredObject::class, cascade: ['persist', 'refresh'])]
#[ORM\JoinTable('chill_event_event_documents')]
@@ -192,7 +192,7 @@ class Event implements HasCenterInterface, HasScopeInterface, TrackCreationInter
{
$iterator = iterator_to_array($this->participations->getIterator());
- uasort($iterator, static fn ($first, $second) => strnatcasecmp((string) $first->getPerson()->getFirstName(), (string) $second->getPerson()->getFirstName()));
+ uasort($iterator, static fn ($first, $second) => strnatcasecmp($first->getPerson()->getFirstName(), $second->getPerson()->getFirstName()));
return new \ArrayIterator($iterator);
}
@@ -265,11 +265,9 @@ class Event implements HasCenterInterface, HasScopeInterface, TrackCreationInter
/**
* Set label.
*
- * @param string $label
- *
* @return Event
*/
- public function setName($label)
+ public function setName(?string $label)
{
$this->name = $label;
diff --git a/src/Bundle/ChillEventBundle/Entity/EventType.php b/src/Bundle/ChillEventBundle/Entity/EventType.php
index 5aa257ee9..b0f81f906 100644
--- a/src/Bundle/ChillEventBundle/Entity/EventType.php
+++ b/src/Bundle/ChillEventBundle/Entity/EventType.php
@@ -38,13 +38,13 @@ class EventType
private $name;
/**
- * @var Collection
+ * @var Collection
*/
- #[ORM\OneToMany(targetEntity: Role::class, mappedBy: 'type')]
+ #[ORM\OneToMany(mappedBy: 'type', targetEntity: Role::class)]
private Collection $roles;
/**
- * @var Collection
+ * @var Collection
*/
#[ORM\OneToMany(targetEntity: Status::class, mappedBy: 'type')]
private Collection $statuses;
@@ -146,11 +146,9 @@ class EventType
/**
* Set active.
*
- * @param bool $active
- *
* @return EventType
*/
- public function setActive($active)
+ public function setActive(bool $active)
{
$this->active = $active;
diff --git a/src/Bundle/ChillEventBundle/Entity/Role.php b/src/Bundle/ChillEventBundle/Entity/Role.php
index 90f3c43e6..7dbd8700c 100644
--- a/src/Bundle/ChillEventBundle/Entity/Role.php
+++ b/src/Bundle/ChillEventBundle/Entity/Role.php
@@ -81,11 +81,9 @@ class Role
/**
* Set active.
*
- * @param bool $active
- *
* @return Role
*/
- public function setActive($active)
+ public function setActive(bool $active)
{
$this->active = $active;
diff --git a/src/Bundle/ChillEventBundle/Entity/Status.php b/src/Bundle/ChillEventBundle/Entity/Status.php
index 4153967af..38c07879c 100644
--- a/src/Bundle/ChillEventBundle/Entity/Status.php
+++ b/src/Bundle/ChillEventBundle/Entity/Status.php
@@ -81,11 +81,9 @@ class Status
/**
* Set active.
*
- * @param bool $active
- *
* @return Status
*/
- public function setActive($active)
+ public function setActive(bool $active)
{
$this->active = $active;
diff --git a/src/Bundle/ChillEventBundle/Export/Aggregator/EventDateAggregator.php b/src/Bundle/ChillEventBundle/Export/Aggregator/EventDateAggregator.php
new file mode 100644
index 000000000..1e519997a
--- /dev/null
+++ b/src/Bundle/ChillEventBundle/Export/Aggregator/EventDateAggregator.php
@@ -0,0 +1,110 @@
+ 'month',
+ 'by week' => 'week',
+ 'by year' => 'year',
+ ];
+
+ private const DEFAULT_CHOICE = 'year';
+
+ public function addRole(): ?string
+ {
+ return null;
+ }
+
+ public function alterQuery(QueryBuilder $qb, $data)
+ {
+ $order = null;
+
+ switch ($data['frequency']) {
+ case 'month':
+ $fmt = 'YYYY-MM';
+
+ break;
+
+ case 'week':
+ $fmt = 'YYYY-IW';
+
+ break;
+
+ case 'year':
+ $fmt = 'YYYY';
+ $order = 'DESC';
+
+ break;
+
+ default:
+ throw new \RuntimeException(sprintf("The frequency data '%s' is invalid.", $data['frequency']));
+ }
+
+ $qb->addSelect(sprintf("TO_CHAR(event.date, '%s') AS date_aggregator", $fmt));
+ $qb->addGroupBy('date_aggregator');
+ $qb->addOrderBy('date_aggregator', $order);
+ }
+
+ public function applyOn(): string
+ {
+ return Declarations::EVENT;
+ }
+
+ public function buildForm(FormBuilderInterface $builder)
+ {
+ $builder->add('frequency', ChoiceType::class, [
+ 'choices' => self::CHOICES,
+ 'multiple' => false,
+ 'expanded' => true,
+ ]);
+ }
+
+ public function getFormDefaultData(): array
+ {
+ return ['frequency' => self::DEFAULT_CHOICE];
+ }
+
+ public function getLabels($key, array $values, $data)
+ {
+ return static function ($value) use ($data): string {
+ if ('_header' === $value) {
+ return 'by '.$data['frequency'];
+ }
+
+ if (null === $value) {
+ return '';
+ }
+
+ return match ($data['frequency']) {
+ default => $value,
+ };
+ };
+ }
+
+ public function getQueryKeys($data): array
+ {
+ return ['date_aggregator'];
+ }
+
+ public function getTitle(): string
+ {
+ return 'Group event by date';
+ }
+}
diff --git a/src/Bundle/ChillEventBundle/Export/Aggregator/EventTypeAggregator.php b/src/Bundle/ChillEventBundle/Export/Aggregator/EventTypeAggregator.php
new file mode 100644
index 000000000..db757cac9
--- /dev/null
+++ b/src/Bundle/ChillEventBundle/Export/Aggregator/EventTypeAggregator.php
@@ -0,0 +1,81 @@
+getAllAliases(), true)) {
+ $qb->leftJoin('event.type', 'eventtype');
+ }
+
+ $qb->addSelect(sprintf('IDENTITY(event.type) AS %s', self::KEY));
+ $qb->addGroupBy(self::KEY);
+ }
+
+ public function applyOn(): string
+ {
+ return Declarations::EVENT;
+ }
+
+ public function buildForm(FormBuilderInterface $builder)
+ {
+ // no form required for this aggregator
+ }
+
+ public function getFormDefaultData(): array
+ {
+ return [];
+ }
+
+ public function getLabels($key, array $values, $data): \Closure
+ {
+ return function (int|string|null $value): string {
+ if ('_header' === $value) {
+ return 'Event type';
+ }
+
+ if (null === $value || '' === $value || null === $t = $this->eventTypeRepository->find($value)) {
+ return '';
+ }
+
+ return $this->translatableStringHelper->localize($t->getName());
+ };
+ }
+
+ public function getQueryKeys($data): array
+ {
+ return [self::KEY];
+ }
+
+ public function getTitle()
+ {
+ return 'Group by event type';
+ }
+}
diff --git a/src/Bundle/ChillEventBundle/Export/Aggregator/RoleAggregator.php b/src/Bundle/ChillEventBundle/Export/Aggregator/RoleAggregator.php
new file mode 100644
index 000000000..c02483db2
--- /dev/null
+++ b/src/Bundle/ChillEventBundle/Export/Aggregator/RoleAggregator.php
@@ -0,0 +1,81 @@
+getAllAliases(), true)) {
+ $qb->leftJoin('event_part.role', 'role');
+ }
+
+ $qb->addSelect(sprintf('IDENTITY(event_part.role) AS %s', self::KEY));
+ $qb->addGroupBy(self::KEY);
+ }
+
+ public function applyOn(): string
+ {
+ return Declarations::EVENT_PARTICIPANTS;
+ }
+
+ public function buildForm(FormBuilderInterface $builder)
+ {
+ // no form required for this aggregator
+ }
+
+ public function getFormDefaultData(): array
+ {
+ return [];
+ }
+
+ public function getLabels($key, array $values, $data): \Closure
+ {
+ return function (int|string|null $value): string {
+ if ('_header' === $value) {
+ return 'Participant role';
+ }
+
+ if (null === $value || '' === $value || null === $r = $this->roleRepository->find($value)) {
+ return '';
+ }
+
+ return $this->translatableStringHelper->localize($r->getName());
+ };
+ }
+
+ public function getQueryKeys($data): array
+ {
+ return [self::KEY];
+ }
+
+ public function getTitle()
+ {
+ return 'Group by participant role';
+ }
+}
diff --git a/src/Bundle/ChillEventBundle/Export/Declarations.php b/src/Bundle/ChillEventBundle/Export/Declarations.php
new file mode 100644
index 000000000..8a873a673
--- /dev/null
+++ b/src/Bundle/ChillEventBundle/Export/Declarations.php
@@ -0,0 +1,22 @@
+filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
+ }
+
+ public function buildForm(FormBuilderInterface $builder) {}
+
+ public function getFormDefaultData(): array
+ {
+ return [];
+ }
+
+ public function getAllowedFormattersTypes()
+ {
+ return [FormatterInterface::TYPE_TABULAR];
+ }
+
+ public function getDescription()
+ {
+ return 'Count participants to an event by various parameters.';
+ }
+
+ public function getGroup(): string
+ {
+ return 'Exports of events';
+ }
+
+ public function getLabels($key, array $values, $data)
+ {
+ if ('export_count_event_participants' !== $key) {
+ throw new \LogicException("the key {$key} is not used by this export");
+ }
+
+ return static fn ($value) => '_header' === $value ? 'Count event participants' : $value;
+ }
+
+ public function getQueryKeys($data)
+ {
+ return ['export_count_event_participants'];
+ }
+
+ public function getResult($query, $data)
+ {
+ return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
+ }
+
+ public function getTitle()
+ {
+ return 'Count event participants';
+ }
+
+ public function getType(): string
+ {
+ return Declarations::EVENT_PARTICIPANTS;
+ }
+
+ public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
+ {
+ $centers = array_map(static fn ($el) => $el['center'], $acl);
+
+ $qb = $this->participationRepository
+ ->createQueryBuilder('event_part')
+ ->join('event_part.person', 'person');
+
+ $qb->select('COUNT(event_part.id) as export_count_event_participants');
+
+ if ($this->filterStatsByCenters) {
+ $qb
+ ->andWhere(
+ $qb->expr()->exists(
+ 'SELECT 1 FROM '.PersonCenterHistory::class.' acl_count_person_history WHERE acl_count_person_history.person = person
+ AND acl_count_person_history.center IN (:authorized_centers)
+ '
+ )
+ )
+ ->setParameter('authorized_centers', $centers);
+ }
+
+ return $qb;
+ }
+
+ public function requiredRole(): string
+ {
+ return ParticipationVoter::STATS;
+ }
+
+ public function supportsModifiers()
+ {
+ return [
+ Declarations::EVENT_PARTICIPANTS,
+ PersonDeclarations::PERSON_TYPE,
+ ];
+ }
+}
diff --git a/src/Bundle/ChillEventBundle/Export/Export/CountEvents.php b/src/Bundle/ChillEventBundle/Export/Export/CountEvents.php
new file mode 100644
index 000000000..7cb98b5a6
--- /dev/null
+++ b/src/Bundle/ChillEventBundle/Export/Export/CountEvents.php
@@ -0,0 +1,126 @@
+filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
+ }
+
+ public function buildForm(FormBuilderInterface $builder) {}
+
+ public function getFormDefaultData(): array
+ {
+ return [];
+ }
+
+ public function getAllowedFormattersTypes()
+ {
+ return [FormatterInterface::TYPE_TABULAR];
+ }
+
+ public function getDescription()
+ {
+ return 'Count events by various parameters.';
+ }
+
+ public function getGroup(): string
+ {
+ return 'Exports of events';
+ }
+
+ public function getLabels($key, array $values, $data)
+ {
+ if ('export_count_event' !== $key) {
+ throw new \LogicException("the key {$key} is not used by this export");
+ }
+
+ return static fn ($value) => '_header' === $value ? 'Number of events' : $value;
+ }
+
+ public function getQueryKeys($data)
+ {
+ return ['export_count_event'];
+ }
+
+ public function getResult($query, $data)
+ {
+ return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
+ }
+
+ public function getTitle()
+ {
+ return 'Count events';
+ }
+
+ public function getType(): string
+ {
+ return Declarations::EVENT;
+ }
+
+ public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
+ {
+ $centers = array_map(static fn ($el) => $el['center'], $acl);
+
+ $qb = $this->eventRepository
+ ->createQueryBuilder('event')
+ ->leftJoin('event.participations', 'epart')
+ ->leftJoin('epart.person', 'person');
+
+ $qb->select('COUNT(DISTINCT event.id) as export_count_event');
+
+ if ($this->filterStatsByCenters) {
+ $qb
+ ->andWhere(
+ $qb->expr()->exists(
+ 'SELECT 1 FROM '.PersonCenterHistory::class.' acl_count_person_history WHERE acl_count_person_history.person = person
+ AND acl_count_person_history.center IN (:authorized_centers)
+ '
+ )
+ )
+ ->setParameter('authorized_centers', $centers);
+ }
+
+ return $qb;
+ }
+
+ public function requiredRole(): string
+ {
+ return EventVoter::STATS;
+ }
+
+ public function supportsModifiers()
+ {
+ return [
+ Declarations::EVENT,
+ PersonDeclarations::PERSON_TYPE,
+ ];
+ }
+}
diff --git a/src/Bundle/ChillEventBundle/Export/Filter/EventDateFilter.php b/src/Bundle/ChillEventBundle/Export/Filter/EventDateFilter.php
new file mode 100644
index 000000000..10f1dbd81
--- /dev/null
+++ b/src/Bundle/ChillEventBundle/Export/Filter/EventDateFilter.php
@@ -0,0 +1,95 @@
+getDQLPart('where');
+ $clause = $qb->expr()->between(
+ 'event.date',
+ ':date_from',
+ ':date_to'
+ );
+
+ if ($where instanceof Expr\Andx) {
+ $where->add($clause);
+ } else {
+ $where = $qb->expr()->andX($clause);
+ }
+
+ $qb->add('where', $where);
+ $qb->setParameter(
+ 'date_from',
+ $this->rollingDateConverter->convert($data['date_from'])
+ );
+ $qb->setParameter(
+ 'date_to',
+ $this->rollingDateConverter->convert($data['date_to'])
+ );
+ }
+
+ public function applyOn(): string
+ {
+ return Declarations::EVENT;
+ }
+
+ public function buildForm(FormBuilderInterface $builder)
+ {
+ $builder
+ ->add('date_from', PickRollingDateType::class, [
+ 'label' => 'Events after this date',
+ ])
+ ->add('date_to', PickRollingDateType::class, [
+ 'label' => 'Events before this date',
+ ]);
+ }
+
+ public function getFormDefaultData(): array
+ {
+ return ['date_from' => new RollingDate(RollingDate::T_YEAR_PREVIOUS_START), 'date_to' => new RollingDate(RollingDate::T_TODAY)];
+ }
+
+ public function describeAction($data, $format = 'string')
+ {
+ return [
+ 'Filtered by date of event: only between %date_from% and %date_to%',
+ [
+ '%date_from%' => $this->rollingDateConverter->convert($data['date_from'])->format('d-m-Y'),
+ '%date_to%' => $this->rollingDateConverter->convert($data['date_to'])->format('d-m-Y'),
+ ],
+ ];
+ }
+
+ public function getTitle()
+ {
+ return 'Filtered by event date';
+ }
+}
diff --git a/src/Bundle/ChillEventBundle/Export/Filter/EventTypeFilter.php b/src/Bundle/ChillEventBundle/Export/Filter/EventTypeFilter.php
new file mode 100644
index 000000000..9e8855adf
--- /dev/null
+++ b/src/Bundle/ChillEventBundle/Export/Filter/EventTypeFilter.php
@@ -0,0 +1,94 @@
+expr()->in('event.type', ':selected_event_types');
+
+ $qb->andWhere($clause);
+ $qb->setParameter('selected_event_types', $data['types']);
+ }
+
+ public function applyOn(): string
+ {
+ return Declarations::EVENT;
+ }
+
+ public function buildForm(FormBuilderInterface $builder)
+ {
+ $builder->add('types', EntityType::class, [
+ 'choices' => $this->eventTypeRepository->findAllActive(),
+ 'class' => EventType::class,
+ 'choice_label' => fn (EventType $ety) => $this->translatableStringHelper->localize($ety->getName()),
+ 'multiple' => true,
+ 'expanded' => false,
+ 'attr' => [
+ 'class' => 'select2',
+ ],
+ ]);
+ }
+
+ public function getFormDefaultData(): array
+ {
+ return [];
+ }
+
+ public function describeAction($data, $format = 'string')
+ {
+ $typeNames = array_map(
+ fn (EventType $t): string => $this->translatableStringHelper->localize($t->getName()),
+ $this->eventTypeRepository->findBy(['id' => $data['types'] instanceof \Doctrine\Common\Collections\Collection ? $data['types']->toArray() : $data['types']])
+ );
+
+ return ['Filtered by event type: only %list%', [
+ '%list%' => implode(', ', $typeNames),
+ ]];
+ }
+
+ public function getTitle()
+ {
+ return 'Filtered by event type';
+ }
+
+ public function validateForm($data, ExecutionContextInterface $context)
+ {
+ if (null === $data['types'] || 0 === \count($data['types'])) {
+ $context
+ ->buildViolation('At least one type must be chosen')
+ ->addViolation();
+ }
+ }
+}
diff --git a/src/Bundle/ChillEventBundle/Export/Filter/RoleFilter.php b/src/Bundle/ChillEventBundle/Export/Filter/RoleFilter.php
new file mode 100644
index 000000000..791f07f7a
--- /dev/null
+++ b/src/Bundle/ChillEventBundle/Export/Filter/RoleFilter.php
@@ -0,0 +1,94 @@
+expr()->in('event_part.role', ':selected_part_roles');
+
+ $qb->andWhere($clause);
+ $qb->setParameter('selected_part_roles', $data['part_roles']);
+ }
+
+ public function applyOn(): string
+ {
+ return Declarations::EVENT_PARTICIPANTS;
+ }
+
+ public function buildForm(FormBuilderInterface $builder)
+ {
+ $builder->add('part_roles', EntityType::class, [
+ 'choices' => $this->roleRepository->findAllActive(),
+ 'class' => Role::class,
+ 'choice_label' => fn (Role $r) => $this->translatableStringHelper->localize($r->getName()),
+ 'multiple' => true,
+ 'expanded' => false,
+ 'attr' => [
+ 'class' => 'select2',
+ ],
+ ]);
+ }
+
+ public function getFormDefaultData(): array
+ {
+ return [];
+ }
+
+ public function describeAction($data, $format = 'string')
+ {
+ $roleNames = array_map(
+ fn (Role $r): string => $this->translatableStringHelper->localize($r->getName()),
+ $this->roleRepository->findBy(['id' => $data['part_roles'] instanceof \Doctrine\Common\Collections\Collection ? $data['part_roles']->toArray() : $data['part_roles']])
+ );
+
+ return ['Filtered by participant roles: only %list%', [
+ '%list%' => implode(', ', $roleNames),
+ ]];
+ }
+
+ public function getTitle()
+ {
+ return 'Filter by participant roles';
+ }
+
+ public function validateForm($data, ExecutionContextInterface $context)
+ {
+ if (null === $data['part_roles'] || 0 === \count($data['part_roles'])) {
+ $context
+ ->buildViolation('At least one role must be chosen')
+ ->addViolation();
+ }
+ }
+}
diff --git a/src/Bundle/ChillEventBundle/Form/EventType.php b/src/Bundle/ChillEventBundle/Form/EventType.php
index 98cb5ea5e..ebdf66010 100644
--- a/src/Bundle/ChillEventBundle/Form/EventType.php
+++ b/src/Bundle/ChillEventBundle/Form/EventType.php
@@ -13,6 +13,7 @@ namespace Chill\EventBundle\Form;
use Chill\DocStoreBundle\Entity\StoredObject;
use Chill\DocStoreBundle\Form\StoredObjectType;
+use Chill\EventBundle\Entity\Event;
use Chill\EventBundle\Form\Type\PickEventTypeType;
use Chill\MainBundle\Entity\Center;
use Chill\MainBundle\Form\Type\ChillCollectionType;
@@ -23,6 +24,7 @@ use Chill\MainBundle\Form\Type\PickUserLocationType;
use Chill\MainBundle\Form\Type\ScopePickerType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\MoneyType;
+use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
@@ -31,7 +33,9 @@ class EventType extends AbstractType
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
- ->add('name')
+ ->add('name', TextType::class, [
+ 'required' => true,
+ ])
->add('date', ChillDateTimeType::class, [
'required' => true,
])
@@ -75,7 +79,7 @@ class EventType extends AbstractType
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
- 'data_class' => \Chill\EventBundle\Entity\Event::class,
+ 'data_class' => Event::class,
]);
$resolver
->setRequired(['center', 'role'])
diff --git a/src/Bundle/ChillEventBundle/Menu/PersonMenuBuilder.php b/src/Bundle/ChillEventBundle/Menu/PersonMenuBuilder.php
index 8abfc7cd6..e14e4c979 100644
--- a/src/Bundle/ChillEventBundle/Menu/PersonMenuBuilder.php
+++ b/src/Bundle/ChillEventBundle/Menu/PersonMenuBuilder.php
@@ -11,7 +11,7 @@ declare(strict_types=1);
namespace Chill\EventBundle\Menu;
-use Chill\EventBundle\Security\Authorization\EventVoter;
+use Chill\EventBundle\Security\EventVoter;
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
use Knp\Menu\MenuItem;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
diff --git a/src/Bundle/ChillEventBundle/Menu/SectionMenuBuilder.php b/src/Bundle/ChillEventBundle/Menu/SectionMenuBuilder.php
index 341848e42..276324938 100644
--- a/src/Bundle/ChillEventBundle/Menu/SectionMenuBuilder.php
+++ b/src/Bundle/ChillEventBundle/Menu/SectionMenuBuilder.php
@@ -11,7 +11,7 @@ declare(strict_types=1);
namespace Chill\EventBundle\Menu;
-use Chill\EventBundle\Security\Authorization\EventVoter;
+use Chill\EventBundle\Security\EventVoter;
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
use Knp\Menu\MenuItem;
use Symfony\Component\Security\Core\Security;
diff --git a/src/Bundle/ChillEventBundle/Repository/EventACLAwareRepository.php b/src/Bundle/ChillEventBundle/Repository/EventACLAwareRepository.php
index 7b9b027f9..22141b536 100644
--- a/src/Bundle/ChillEventBundle/Repository/EventACLAwareRepository.php
+++ b/src/Bundle/ChillEventBundle/Repository/EventACLAwareRepository.php
@@ -13,7 +13,7 @@ namespace Chill\EventBundle\Repository;
use Chill\EventBundle\Entity\Event;
use Chill\EventBundle\Entity\Participation;
-use Chill\EventBundle\Security\Authorization\EventVoter;
+use Chill\EventBundle\Security\EventVoter;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Security\Authorization\AuthorizationHelperForCurrentUserInterface;
use Chill\PersonBundle\Entity\Person;
diff --git a/src/Bundle/ChillEventBundle/Repository/RoleRepository.php b/src/Bundle/ChillEventBundle/Repository/RoleRepository.php
index fa0524a6d..b5444a85b 100644
--- a/src/Bundle/ChillEventBundle/Repository/RoleRepository.php
+++ b/src/Bundle/ChillEventBundle/Repository/RoleRepository.php
@@ -12,13 +12,57 @@ declare(strict_types=1);
namespace Chill\EventBundle\Repository;
use Chill\EventBundle\Entity\Role;
-use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
-use Doctrine\Persistence\ManagerRegistry;
+use Chill\MainBundle\Templating\TranslatableStringHelper;
+use Doctrine\ORM\EntityManagerInterface;
+use Doctrine\ORM\EntityRepository;
+use Doctrine\ORM\QueryBuilder;
+use Doctrine\Persistence\ObjectRepository;
-class RoleRepository extends ServiceEntityRepository
+readonly class RoleRepository implements ObjectRepository
{
- public function __construct(ManagerRegistry $registry)
+ private EntityRepository $repository;
+
+ public function __construct(EntityManagerInterface $entityManager, private TranslatableStringHelper $translatableStringHelper)
{
- parent::__construct($registry, Role::class);
+ $this->repository = $entityManager->getRepository(Role::class);
+ }
+
+ public function createQueryBuilder(string $alias, ?string $indexBy = null): QueryBuilder
+ {
+ return $this->repository->createQueryBuilder($alias, $indexBy);
+ }
+
+ public function find($id)
+ {
+ return $this->repository->find($id);
+ }
+
+ public function findAll(): array
+ {
+ return $this->repository->findAll();
+ }
+
+ public function findAllActive(): array
+ {
+ $roles = $this->repository->findBy(['active' => true]);
+
+ usort($roles, fn (Role $a, Role $b) => $this->translatableStringHelper->localize($a->getName()) <=> $this->translatableStringHelper->localize($b->getName()));
+
+ return $roles;
+ }
+
+ public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array
+ {
+ return $this->repository->findBy($criteria, $orderBy, $limit, $offset);
+ }
+
+ public function findOneBy(array $criteria)
+ {
+ return $this->repository->findOneBy($criteria);
+ }
+
+ public function getClassName(): string
+ {
+ return Role::class;
}
}
diff --git a/src/Bundle/ChillEventBundle/Resources/views/Participation/_ignored_participations.html.twig b/src/Bundle/ChillEventBundle/Resources/views/Participation/_ignored_participations.html.twig
index 9451f3c2b..f43c94f72 100644
--- a/src/Bundle/ChillEventBundle/Resources/views/Participation/_ignored_participations.html.twig
+++ b/src/Bundle/ChillEventBundle/Resources/views/Participation/_ignored_participations.html.twig
@@ -1,7 +1,7 @@
{% import '@ChillPerson/Person/macro.html.twig' as person_macro %}
{% if ignored_participations|length > 0 %}
- {% transchoice ignored_participations|length %}The following people have been ignored because they are already participating on the event{% endtranschoice %} :
+ {{ 'ignored_participations'|trans({'count': ignored_participations|length}) }}:
{% for p in ignored_participations %}
{{ person_macro.render(p.person) }}
diff --git a/src/Bundle/ChillEventBundle/Security/Authorization/EventVoter.php b/src/Bundle/ChillEventBundle/Security/EventVoter.php
similarity index 60%
rename from src/Bundle/ChillEventBundle/Security/Authorization/EventVoter.php
rename to src/Bundle/ChillEventBundle/Security/EventVoter.php
index c88f2804a..e490e0518 100644
--- a/src/Bundle/ChillEventBundle/Security/Authorization/EventVoter.php
+++ b/src/Bundle/ChillEventBundle/Security/EventVoter.php
@@ -9,18 +9,19 @@ declare(strict_types=1);
* the LICENSE file that was distributed with this source code.
*/
-namespace Chill\EventBundle\Security\Authorization;
+namespace Chill\EventBundle\Security;
use Chill\EventBundle\Entity\Event;
+use Chill\MainBundle\Entity\Center;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Security\Authorization\AbstractChillVoter;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
+use Chill\MainBundle\Security\Authorization\VoterHelperFactoryInterface;
+use Chill\MainBundle\Security\Authorization\VoterHelperInterface;
use Chill\MainBundle\Security\ProvideRoleHierarchyInterface;
use Chill\PersonBundle\Entity\Person;
-use Chill\PersonBundle\Security\Authorization\PersonVoter;
use Psr\Log\LoggerInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
-use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
/**
* Description of EventVoter.
@@ -42,61 +43,46 @@ class EventVoter extends AbstractChillVoter implements ProvideRoleHierarchyInter
final public const UPDATE = 'CHILL_EVENT_UPDATE';
- /**
- * @var AccessDecisionManagerInterface
- */
- protected $accessDecisionManager;
+ final public const STATS = 'CHILL_EVENT_STATS';
- /**
- * @var AuthorizationHelper
- */
- protected $authorizationHelper;
-
- /**
- * @var LoggerInterface
- */
- protected $logger;
+ private readonly VoterHelperInterface $voterHelper;
public function __construct(
- AccessDecisionManagerInterface $accessDecisionManager,
- AuthorizationHelper $authorizationHelper,
- LoggerInterface $logger
+ private readonly AuthorizationHelper $authorizationHelper,
+ private readonly LoggerInterface $logger,
+ VoterHelperFactoryInterface $voterHelperFactory
) {
- $this->accessDecisionManager = $accessDecisionManager;
- $this->authorizationHelper = $authorizationHelper;
- $this->logger = $logger;
+ $this->voterHelper = $voterHelperFactory
+ ->generate(self::class)
+ ->addCheckFor(null, [self::SEE])
+ ->addCheckFor(Event::class, [...self::ROLES])
+ ->addCheckFor(Person::class, [self::SEE, self::CREATE])
+ ->addCheckFor(Center::class, [self::STATS])
+ ->build();
}
public function getRoles(): array
{
- return self::ROLES;
+ return [...self::ROLES, self::STATS];
}
public function getRolesWithHierarchy(): array
{
return [
- 'Event' => self::ROLES,
+ 'Event' => $this->getRoles(),
];
}
public function getRolesWithoutScope(): array
{
- return [];
+ return [self::ROLES, self::STATS];
}
public function supports($attribute, $subject)
{
- return ($subject instanceof Event && \in_array($attribute, self::ROLES, true))
- || ($subject instanceof Person && \in_array($attribute, [self::CREATE, self::SEE], true))
- || (null === $subject && self::SEE === $attribute);
+ return $this->voterHelper->supports($attribute, $subject);
}
- /**
- * @param string $attribute
- * @param Event $subject
- *
- * @return bool
- */
protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
{
$this->logger->debug(sprintf('Voting from %s class', self::class));
@@ -118,15 +104,5 @@ class EventVoter extends AbstractChillVoter implements ProvideRoleHierarchyInter
->getReachableCenters($token->getUser(), $attribute);
return \count($centers) > 0;
-
- if (!$this->accessDecisionManager->decide($token, [PersonVoter::SEE], $person)) {
- return false;
- }
-
- return $this->authorizationHelper->userHasAccess(
- $token->getUser(),
- $subject,
- $attribute
- );
}
}
diff --git a/src/Bundle/ChillEventBundle/Security/Authorization/ParticipationVoter.php b/src/Bundle/ChillEventBundle/Security/ParticipationVoter.php
similarity index 61%
rename from src/Bundle/ChillEventBundle/Security/Authorization/ParticipationVoter.php
rename to src/Bundle/ChillEventBundle/Security/ParticipationVoter.php
index ad2e90377..368a47cab 100644
--- a/src/Bundle/ChillEventBundle/Security/Authorization/ParticipationVoter.php
+++ b/src/Bundle/ChillEventBundle/Security/ParticipationVoter.php
@@ -9,18 +9,19 @@ declare(strict_types=1);
* the LICENSE file that was distributed with this source code.
*/
-namespace Chill\EventBundle\Security\Authorization;
+namespace Chill\EventBundle\Security;
use Chill\EventBundle\Entity\Participation;
+use Chill\MainBundle\Entity\Center;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Security\Authorization\AbstractChillVoter;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
+use Chill\MainBundle\Security\Authorization\VoterHelperFactoryInterface;
+use Chill\MainBundle\Security\Authorization\VoterHelperInterface;
use Chill\MainBundle\Security\ProvideRoleHierarchyInterface;
use Chill\PersonBundle\Entity\Person;
-use Chill\PersonBundle\Security\Authorization\PersonVoter;
use Psr\Log\LoggerInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
-use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
class ParticipationVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterface
{
@@ -39,58 +40,48 @@ class ParticipationVoter extends AbstractChillVoter implements ProvideRoleHierar
final public const UPDATE = 'CHILL_EVENT_PARTICIPATION_UPDATE';
- /**
- * @var AccessDecisionManagerInterface
- */
- protected $accessDecisionManager;
+ final public const STATS = 'CHILL_EVENT_PARTICIPATION_STATS';
- /**
- * @var AuthorizationHelper
- */
- protected $authorizationHelper;
-
- /**
- * @var LoggerInterface
- */
- protected $logger;
+ private readonly VoterHelperInterface $voterHelper;
public function __construct(
- AccessDecisionManagerInterface $accessDecisionManager,
- AuthorizationHelper $authorizationHelper,
- LoggerInterface $logger
+ private readonly AuthorizationHelper $authorizationHelper,
+ private readonly LoggerInterface $logger,
+ VoterHelperFactoryInterface $voterHelperFactory
) {
- $this->accessDecisionManager = $accessDecisionManager;
- $this->authorizationHelper = $authorizationHelper;
- $this->logger = $logger;
+ $this->voterHelper = $voterHelperFactory
+ ->generate(self::class)
+ ->addCheckFor(null, [self::SEE])
+ ->addCheckFor(Participation::class, [...self::ROLES])
+ ->addCheckFor(Person::class, [self::SEE, self::CREATE])
+ ->addCheckFor(Center::class, [self::STATS])
+ ->build();
}
public function getRoles(): array
{
- return self::ROLES;
+ return [...self::ROLES, self::STATS];
}
public function getRolesWithHierarchy(): array
{
return [
- 'Event' => self::ROLES,
+ 'Participation' => $this->getRoles(),
];
}
public function getRolesWithoutScope(): array
{
- return [];
+ return [self::ROLES, self::STATS];
}
public function supports($attribute, $subject)
{
- return ($subject instanceof Participation && \in_array($attribute, self::ROLES, true))
- || ($subject instanceof Person && \in_array($attribute, [self::CREATE, self::SEE], true))
- || (null === $subject && self::SEE === $attribute);
+ return $this->voterHelper->supports($attribute, $subject);
}
/**
- * @param string $attribute
- * @param Participation $subject
+ * @param string $attribute
*
* @return bool
*/
@@ -115,15 +106,5 @@ class ParticipationVoter extends AbstractChillVoter implements ProvideRoleHierar
->getReachableCenters($token->getUser(), $attribute);
return \count($centers) > 0;
-
- if (!$this->accessDecisionManager->decide($token, [PersonVoter::SEE], $person)) {
- return false;
- }
-
- return $this->authorizationHelper->userHasAccess(
- $token->getUser(),
- $subject,
- $attribute
- );
}
}
diff --git a/src/Bundle/ChillEventBundle/Tests/Export/CountEventParticipationsTest.php b/src/Bundle/ChillEventBundle/Tests/Export/CountEventParticipationsTest.php
new file mode 100644
index 000000000..2c7886ed7
--- /dev/null
+++ b/src/Bundle/ChillEventBundle/Tests/Export/CountEventParticipationsTest.php
@@ -0,0 +1,43 @@
+countEventParticipations = self::getContainer()->get(CountEventParticipations::class);
+ }
+
+ public function testExecuteQuery(): void
+ {
+ $qb = $this->countEventParticipations->initiateQuery([], [], [])
+ ->setMaxResults(1);
+
+ $results = $qb->getQuery()->getResult(AbstractQuery::HYDRATE_ARRAY);
+
+ self::assertIsArray($results, 'smoke test: test that the result is an array');
+ }
+}
diff --git a/src/Bundle/ChillEventBundle/Tests/Export/CountEventTest.php b/src/Bundle/ChillEventBundle/Tests/Export/CountEventTest.php
new file mode 100644
index 000000000..15884edec
--- /dev/null
+++ b/src/Bundle/ChillEventBundle/Tests/Export/CountEventTest.php
@@ -0,0 +1,43 @@
+countEvents = self::getContainer()->get(CountEvents::class);
+ }
+
+ public function testExecuteQuery(): void
+ {
+ $qb = $this->countEvents->initiateQuery([], [], [])
+ ->setMaxResults(1);
+
+ $results = $qb->getQuery()->getResult(AbstractQuery::HYDRATE_ARRAY);
+
+ self::assertIsArray($results, 'smoke test: test that the result is an array');
+ }
+}
diff --git a/src/Bundle/ChillEventBundle/Tests/Export/aggregators/EventDateAggregatorTest.php b/src/Bundle/ChillEventBundle/Tests/Export/aggregators/EventDateAggregatorTest.php
new file mode 100644
index 000000000..4adf4fa2c
--- /dev/null
+++ b/src/Bundle/ChillEventBundle/Tests/Export/aggregators/EventDateAggregatorTest.php
@@ -0,0 +1,59 @@
+aggregator = self::getContainer()->get(EventDateAggregator::class);
+ }
+
+ public function getAggregator()
+ {
+ return $this->aggregator;
+ }
+
+ public function getFormData(): array|\Generator
+ {
+ yield ['frequency' => 'YYYY'];
+ yield ['frequency' => 'YYYY-MM'];
+ yield ['frequency' => 'YYYY-IV'];
+ }
+
+ public function getQueryBuilders(): array
+ {
+ self::bootKernel();
+
+ $em = self::getContainer()->get(EntityManagerInterface::class);
+
+ return [
+ $em->createQueryBuilder()
+ ->select('event.id')
+ ->from(Event::class, 'event'),
+ ];
+ }
+}
diff --git a/src/Bundle/ChillEventBundle/Tests/Export/aggregators/EventTypeAggregatorTest.php b/src/Bundle/ChillEventBundle/Tests/Export/aggregators/EventTypeAggregatorTest.php
new file mode 100644
index 000000000..33e3182c4
--- /dev/null
+++ b/src/Bundle/ChillEventBundle/Tests/Export/aggregators/EventTypeAggregatorTest.php
@@ -0,0 +1,59 @@
+aggregator = self::getContainer()->get(EventTypeAggregator::class);
+ }
+
+ public function getAggregator()
+ {
+ return $this->aggregator;
+ }
+
+ public function getFormData(): array
+ {
+ return [
+ [],
+ ];
+ }
+
+ public function getQueryBuilders(): array
+ {
+ self::bootKernel();
+
+ $em = self::getContainer()->get(EntityManagerInterface::class);
+
+ return [
+ $em->createQueryBuilder()
+ ->select('event.id')
+ ->from(Event::class, 'event'),
+ ];
+ }
+}
diff --git a/src/Bundle/ChillEventBundle/Tests/Export/aggregators/RoleAggregatorTest.php b/src/Bundle/ChillEventBundle/Tests/Export/aggregators/RoleAggregatorTest.php
new file mode 100644
index 000000000..c9cdb92be
--- /dev/null
+++ b/src/Bundle/ChillEventBundle/Tests/Export/aggregators/RoleAggregatorTest.php
@@ -0,0 +1,63 @@
+aggregator = self::getContainer()->get(RoleAggregator::class);
+ }
+
+ public function getAggregator()
+ {
+ return $this->aggregator;
+ }
+
+ public function getFormData(): array
+ {
+ return [
+ [],
+ ];
+ }
+
+ public function getQueryBuilders(): array
+ {
+ self::bootKernel();
+
+ $em = self::getContainer()->get(EntityManagerInterface::class);
+
+ return [
+ $em->createQueryBuilder()
+ ->select('event.id')
+ ->from(Event::class, 'event'),
+ $em->createQueryBuilder()
+ ->select('event_part')
+ ->from(Participation::class, 'event_part'),
+ ];
+ }
+}
diff --git a/src/Bundle/ChillEventBundle/Tests/Export/filters/EventDateFilterTest.php b/src/Bundle/ChillEventBundle/Tests/Export/filters/EventDateFilterTest.php
new file mode 100644
index 000000000..369ceee59
--- /dev/null
+++ b/src/Bundle/ChillEventBundle/Tests/Export/filters/EventDateFilterTest.php
@@ -0,0 +1,65 @@
+rollingDateConverter = self::getContainer()->get(RollingDateConverterInterface::class);
+ }
+
+ public function getFilter()
+ {
+ return new EventDateFilter($this->rollingDateConverter);
+ }
+
+ public function getFormData()
+ {
+ return [
+ [
+ 'date_from' => new RollingDate(RollingDate::T_YEAR_CURRENT_START),
+ 'date_to' => new RollingDate(RollingDate::T_TODAY),
+ ],
+ ];
+ }
+
+ public function getQueryBuilders(): array
+ {
+ self::bootKernel();
+
+ $em = self::getContainer()->get(EntityManagerInterface::class);
+
+ return [
+ $em->createQueryBuilder()
+ ->select('event.id')
+ ->from(Event::class, 'event'),
+ ];
+ }
+}
diff --git a/src/Bundle/ChillEventBundle/Tests/Export/filters/EventTypeFilterTest.php b/src/Bundle/ChillEventBundle/Tests/Export/filters/EventTypeFilterTest.php
new file mode 100644
index 000000000..4e41b624e
--- /dev/null
+++ b/src/Bundle/ChillEventBundle/Tests/Export/filters/EventTypeFilterTest.php
@@ -0,0 +1,76 @@
+filter = self::getContainer()->get(EventTypeFilter::class);
+ }
+
+ public function getFilter(): EventTypeFilter|\Chill\MainBundle\Export\FilterInterface
+ {
+ return $this->filter;
+ }
+
+ public function getFormData()
+ {
+ self::bootKernel();
+
+ $em = self::getContainer()->get(EntityManagerInterface::class);
+
+ $array = $em->createQueryBuilder()
+ ->from(EventType::class, 'et')
+ ->select('et')
+ ->getQuery()
+ ->getResult();
+
+ $data = [];
+
+ foreach ($array as $a) {
+ $data[] = [
+ 'types' => new ArrayCollection([$a]),
+ ];
+ }
+
+ return $data;
+ }
+
+ public function getQueryBuilders()
+ {
+ self::bootKernel();
+
+ $em = self::getContainer()->get(EntityManagerInterface::class);
+
+ return [
+ $em->createQueryBuilder()
+ ->select('event.id')
+ ->from(Event::class, 'event'),
+ ];
+ }
+}
diff --git a/src/Bundle/ChillEventBundle/Tests/Export/filters/RoleFilterTest.php b/src/Bundle/ChillEventBundle/Tests/Export/filters/RoleFilterTest.php
new file mode 100644
index 000000000..714098956
--- /dev/null
+++ b/src/Bundle/ChillEventBundle/Tests/Export/filters/RoleFilterTest.php
@@ -0,0 +1,81 @@
+filter = self::getContainer()->get(RoleFilter::class);
+ }
+
+ public function getFilter()
+ {
+ return $this->filter;
+ }
+
+ public function getFormData(): array
+ {
+ self::bootKernel();
+ $em = self::getContainer()->get(EntityManagerInterface::class);
+
+ $array = $em->createQueryBuilder()
+ ->from(Role::class, 'r')
+ ->select('r')
+ ->getQuery()
+ ->setMaxResults(1)
+ ->getResult();
+
+ $data = [];
+
+ foreach ($array as $a) {
+ $data[] = [
+ 'roles' => new ArrayCollection([$a]),
+ ];
+ }
+
+ return $data;
+ }
+
+ public function getQueryBuilders()
+ {
+ self::bootKernel();
+
+ $em = self::getContainer()->get(EntityManagerInterface::class);
+
+ return [
+ $em->createQueryBuilder()
+ ->select('event.id')
+ ->from(Event::class, 'event'),
+ $em->createQueryBuilder()
+ ->select('event_part')
+ ->from(Participation::class, 'event_part'),
+ ];
+ }
+}
diff --git a/src/Bundle/ChillEventBundle/Tests/Repository/EventACLAwareRepositoryTest.php b/src/Bundle/ChillEventBundle/Tests/Repository/EventACLAwareRepositoryTest.php
index 4bcaac1f6..758e50d56 100644
--- a/src/Bundle/ChillEventBundle/Tests/Repository/EventACLAwareRepositoryTest.php
+++ b/src/Bundle/ChillEventBundle/Tests/Repository/EventACLAwareRepositoryTest.php
@@ -12,7 +12,7 @@ declare(strict_types=1);
namespace Chill\EventBundle\Tests\Repository;
use Chill\EventBundle\Repository\EventACLAwareRepository;
-use Chill\EventBundle\Security\Authorization\EventVoter;
+use Chill\EventBundle\Security\EventVoter;
use Chill\MainBundle\Entity\Center;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Entity\User;
diff --git a/src/Bundle/ChillEventBundle/config/services/authorization.yaml b/src/Bundle/ChillEventBundle/config/services/authorization.yaml
deleted file mode 100644
index 6f382b72e..000000000
--- a/src/Bundle/ChillEventBundle/config/services/authorization.yaml
+++ /dev/null
@@ -1,18 +0,0 @@
-services:
- chill_event.event_voter:
- class: Chill\EventBundle\Security\Authorization\EventVoter
- arguments:
- - "@security.access.decision_manager"
- - "@chill.main.security.authorization.helper"
- - "@logger"
- tags:
- - { name: security.voter }
-
- chill_event.event_participation:
- class: Chill\EventBundle\Security\Authorization\ParticipationVoter
- arguments:
- - "@security.access.decision_manager"
- - "@chill.main.security.authorization.helper"
- - "@logger"
- tags:
- - { name: security.voter }
diff --git a/src/Bundle/ChillEventBundle/config/services/export.yaml b/src/Bundle/ChillEventBundle/config/services/export.yaml
new file mode 100644
index 000000000..8f8399e31
--- /dev/null
+++ b/src/Bundle/ChillEventBundle/config/services/export.yaml
@@ -0,0 +1,41 @@
+services:
+ _defaults:
+ autowire: true
+ autoconfigure: true
+
+ # indicators
+
+ Chill\EventBundle\Export\Export\CountEvents:
+ tags:
+ - { name: chill.export, alias: 'count_events' }
+ Chill\EventBundle\Export\Export\CountEventParticipations:
+ tags:
+ - { name: chill.export, alias: 'count_event_participants' }
+
+ # filters
+
+ Chill\EventBundle\Export\Filter\EventDateFilter:
+ tags:
+ - { name: chill.export_filter, alias: 'event_date_filter' }
+
+ Chill\EventBundle\Export\Filter\EventTypeFilter:
+ tags:
+ - { name: chill.export_filter, alias: 'event_type_filter' }
+
+ Chill\EventBundle\Export\Filter\RoleFilter:
+ tags:
+ - { name: chill.export_filter, alias: 'role_filter' }
+
+ # aggregators
+
+ Chill\EventBundle\Export\Aggregator\EventTypeAggregator:
+ tags:
+ - { name: chill.export_aggregator, alias: event_type_aggregator }
+
+ Chill\EventBundle\Export\Aggregator\EventDateAggregator:
+ tags:
+ - { name: chill.export_aggregator, alias: event_date_aggregator }
+
+ Chill\EventBundle\Export\Aggregator\RoleAggregator:
+ tags:
+ - { name: chill.export_aggregator, alias: role_aggregator }
diff --git a/src/Bundle/ChillEventBundle/config/services/security.yaml b/src/Bundle/ChillEventBundle/config/services/security.yaml
new file mode 100644
index 000000000..13198d55f
--- /dev/null
+++ b/src/Bundle/ChillEventBundle/config/services/security.yaml
@@ -0,0 +1,14 @@
+services:
+ Chill\EventBundle\Security\EventVoter:
+ autowire: true
+ autoconfigure: true
+ tags:
+ - { name: security.voter }
+ - { name: chill.role }
+
+ Chill\EventBundle\Security\ParticipationVoter:
+ autowire: true
+ autoconfigure: true
+ tags:
+ - { name: security.voter }
+ - { name: chill.role }
diff --git a/src/Bundle/ChillEventBundle/translations/messages+intl-icu.fr.yml b/src/Bundle/ChillEventBundle/translations/messages+intl-icu.fr.yml
index 5c2a5b7c9..ed2568d06 100644
--- a/src/Bundle/ChillEventBundle/translations/messages+intl-icu.fr.yml
+++ b/src/Bundle/ChillEventBundle/translations/messages+intl-icu.fr.yml
@@ -19,3 +19,9 @@ events:
one {et un autre participant}
other {et # autres participants}
}
+
+ignored_participations: >-
+ { count, plural,
+ one {La personne suivante a été ignorée parce qu''elle participe déjà à l''événement}
+ other {Les personnes suivantes ont été ignorées parce qu''elles participent déjà à l'événement}
+ }
diff --git a/src/Bundle/ChillEventBundle/translations/messages.fr.yml b/src/Bundle/ChillEventBundle/translations/messages.fr.yml
index 60d888f07..6046881ff 100644
--- a/src/Bundle/ChillEventBundle/translations/messages.fr.yml
+++ b/src/Bundle/ChillEventBundle/translations/messages.fr.yml
@@ -41,7 +41,6 @@ Back to the event: Retour à l'événement
The participation was created: La participation a été créée
The participation was updated: La participation a été mise à jour
'None of the requested people may participate the event: they are maybe already participating.': 'Aucune des personnes indiquées ne peut être ajoutée à l''événement: elles sont peut-être déjà inscrites comme participantes.'
-'The following people have been ignored because they are already participating on the event': '{1} La personne suivante a été ignorée parce qu''elle participe déjà à l''événement | ]1,Inf] Les personnes suivantes ont été ignorées parce qu''elles participent déjà à l''événement'
There are no participation to edit for this event: Il n'y a pas de participation pour cet événement
The participations have been successfully updated.: Les participations ont été mises à jour.
The participation has been sucessfully removed: La participation a été correctement supprimée.
@@ -81,9 +80,31 @@ Pick an event: Choisir un événement
Pick a type of event: Choisir un type d'événement
Pick a moderator: Choisir un animateur
+# exports
Select a format: Choisir un format
Export: Exporter
+Count events: Nombre d'événements
+Count events by various parameters.: Compte le nombre d'événements selon divers critères
+Exports of events: Exports d'événements
+
+Filtered by event date: Filtrer par date d'événement
+'Filtered by date of event: only between %date_from% and %date_to%': "Filtré par date d'événement: uniquement entre le %date_from% et le %date_to%"
+Events after this date: Événements après cette date
+Events before this date: Événements avant cette date
+Filtered by event type: Filtrer par type d'événement
+'Filtered by event type: only %list%': "Filtré par type: uniquement %list%"
+Group event by date: Grouper par date d'événement
+Group by event type: Grouper par type d'événement
+
+Count event participants: Nombre de participations
+Count participants to an event by various parameters.: Compte le nombre de participations selon divers critères
+Exports of event participants: Exports de participations
+'Filtered by participant roles: only %list%': "Filtré par rôles de participation: uniquement %list%"
+Filter by participant roles: Filtrer par rôles de participation
+Part roles: Rôles de participation
+Group by participant role: Grouper par rôle de participation
+
Events configuration: Configuration des événements
Events configuration menu: Menu des événements
diff --git a/src/Bundle/ChillFranceTravailApiBundle/src/ApiHelper/ApiWrapper.php b/src/Bundle/ChillFranceTravailApiBundle/src/ApiHelper/ApiWrapper.php
new file mode 100644
index 000000000..513050a2a
--- /dev/null
+++ b/src/Bundle/ChillFranceTravailApiBundle/src/ApiHelper/ApiWrapper.php
@@ -0,0 +1,84 @@
+client = new Client([
+ 'base_uri' => 'https://entreprise.francetravail.fr/connexion/oauth2/access_token',
+ ]);
+ }
+
+ public function getPublicBearer($scopes): string
+ {
+ $cacheKey = $this->getCacheKey($scopes);
+
+ if ($this->redis->exists($cacheKey) > 0) {
+ $data = \unserialize($this->redis->get($cacheKey));
+
+ return $data->access_token;
+ }
+
+ try {
+ $response = $this->client->post('', [
+ 'query' => ['realm' => '/partenaire'],
+ 'headers' => [
+ 'Content-Type' => 'application/x-www-form-urlencoded',
+ ],
+ 'form_params' => [
+ 'grant_type' => 'client_credentials',
+ 'client_id' => $this->clientId,
+ 'client_secret' => $this->clientSecret,
+ 'scope' => \implode(' ', \array_merge($scopes, ['application_'.$this->clientId])),
+ ],
+ ]);
+ } catch (ClientException $e) {
+ dump($e->getResponse());
+ }
+ $data = \json_decode((string) $response->getBody());
+
+ // set the key with an expiry time
+ $this->redis->setex(
+ $cacheKey,
+ $data->expires_in - 2,
+ \serialize($data)
+ );
+
+ return $data->access_token;
+ }
+
+ protected function getCacheKey($scopes)
+ {
+ return self::UNPERSONAL_BEARER.implode('', $scopes);
+ }
+}
diff --git a/src/Bundle/ChillFranceTravailApiBundle/src/ApiHelper/PartenaireRomeAppellation.php b/src/Bundle/ChillFranceTravailApiBundle/src/ApiHelper/PartenaireRomeAppellation.php
new file mode 100644
index 000000000..66a8ee05b
--- /dev/null
+++ b/src/Bundle/ChillFranceTravailApiBundle/src/ApiHelper/PartenaireRomeAppellation.php
@@ -0,0 +1,113 @@
+wrapper = $wrapper;
+ $this->logger = $logger;
+ $this->client = new Client([
+ 'base_uri' => 'https://api.pole-emploi.io/partenaire/rome-metiers/v1/metiers/',
+ ]);
+ }
+
+ private function getBearer()
+ {
+ return $this->wrapper->getPublicBearer([
+ 'api_rome-metiersv1',
+ 'nomenclatureRome',
+ ]);
+ }
+
+ public function getListeAppellation(string $search): array
+ {
+ $bearer = $this->getBearer();
+
+ try {
+ $response = $this->httpClient->request(
+ 'GET',
+ self::BASE.'appellation/requete',
+ [
+ 'headers' => [
+ 'Authorization' => 'Bearer '.$bearer,
+ 'Accept' => 'application/json',
+ ],
+ 'query' => [
+ 'q' => $search,
+ ],
+ ]
+ );
+
+ return $response->toArray()['resultats'];
+ } catch (HttpExceptionInterface $exception) {
+ throw $exception;
+ }
+ }
+
+ public function getAppellation(string $code): array
+ {
+ $bearer = $this->getBearer();
+
+ while (true) {
+ try {
+ $response = $this->httpClient->request('GET', sprintf(self::BASE.'appellation/%s', $code), [
+ 'headers' => [
+ 'Authorization' => 'Bearer '.$bearer,
+ 'Accept' => 'application/json',
+ ],
+ 'query' => [
+ 'champs' => 'code,libelle,metier(code,libelle)',
+ ],
+ ]);
+
+ return $response->toArray();
+ } catch (HttpExceptionInterface $exception) {
+ if (429 === $exception->getResponse()->getStatusCode()) {
+ $retryAfter = $exception->getResponse()->getHeaders(false)['retry-after'][0] ?? 1;
+ sleep((int) $retryAfter);
+ } else {
+ throw $exception;
+ }
+ }
+ }
+ }
+}
diff --git a/src/Bundle/ChillFranceTravailApiBundle/src/ApiHelper/ProcessRequestTrait.php b/src/Bundle/ChillFranceTravailApiBundle/src/ApiHelper/ProcessRequestTrait.php
new file mode 100644
index 000000000..01ead1109
--- /dev/null
+++ b/src/Bundle/ChillFranceTravailApiBundle/src/ApiHelper/ProcessRequestTrait.php
@@ -0,0 +1,100 @@
+handleRequestRecursive(
+ $request,
+ $parameters,
+ $client,
+ $logger
+ );
+ }
+
+ /**
+ * internal method to handle recursive requests.
+ *
+ * @throws BadResponseException
+ */
+ private function handleRequestRecursive(
+ Request $request,
+ array $parameters,
+ Client $client,
+ LoggerInterface $logger,
+ $counter = 0
+ ) {
+ try {
+ return $client->send($request, $parameters);
+ } catch (BadResponseException $e) {
+ if (
+ // get 429 exceptions
+ $e instanceof ClientException
+ && 429 === $e->getResponse()->getStatusCode()
+ && count($e->getResponse()->getHeader('Retry-After')) > 0) {
+ if ($counter > 5) {
+ $logger->error('too much 429 response', [
+ 'request' => Psr7\get($e->getRequest()),
+ ]);
+
+ throw $e;
+ }
+
+ $delays = $e->getResponse()->getHeader('Retry-After');
+ $delay = \end($delays);
+
+ sleep($delay);
+
+ return $this->handleRequestRecursive(
+ $request,
+ $parameters,
+ $client,
+ $logger,
+ $counter + 1
+ );
+ }
+
+ // handling other errors
+ $logger->error('Error while querying ROME api', [
+ 'status_code' => $e->getResponse()->getStatusCode(),
+ 'part' => 'appellation',
+ 'request' => $e->getRequest()->getBody()->getContents(),
+ 'response' => $e->getResponse()->getBody()->getContents(),
+ ]);
+
+ throw $e;
+ }
+ }
+}
diff --git a/src/Bundle/ChillFranceTravailApiBundle/src/ChillFranceTravailApiBundle.php b/src/Bundle/ChillFranceTravailApiBundle/src/ChillFranceTravailApiBundle.php
new file mode 100644
index 000000000..c235fc2c5
--- /dev/null
+++ b/src/Bundle/ChillFranceTravailApiBundle/src/ChillFranceTravailApiBundle.php
@@ -0,0 +1,16 @@
+apiAppellation = $apiAppellation;
+ }
+
+ #[Route(path: '/{_locale}/france-travail/appellation/search.{_format}', name: 'chill_france_travail_api_appellation_search')]
+ public function appellationSearchAction(Request $request)
+ {
+ if (false === $request->query->has('q')) {
+ return new JsonResponse([]);
+ }
+
+ $appellations = $this->apiAppellation
+ ->getListeAppellation($request->query->get('q'));
+ $results = [];
+
+ foreach ($appellations as $appellation) {
+ $appellation['id'] = 'original-'.$appellation['code'];
+ $appellation['text'] = $appellation['libelle'];
+ $results[] = $appellation;
+ }
+
+ $computed = new \stdClass();
+ $computed->pagination = (new \stdClass());
+ $computed->pagination->more = false;
+ $computed->results = $results;
+
+ return new JsonResponse($computed);
+ }
+}
diff --git a/src/Bundle/ChillFranceTravailApiBundle/src/DependencyInjection/ChillFranceTravailApiExtension.php b/src/Bundle/ChillFranceTravailApiBundle/src/DependencyInjection/ChillFranceTravailApiExtension.php
new file mode 100644
index 000000000..1f69b80c2
--- /dev/null
+++ b/src/Bundle/ChillFranceTravailApiBundle/src/DependencyInjection/ChillFranceTravailApiExtension.php
@@ -0,0 +1,52 @@
+processConfiguration($configuration, $configs);
+
+ $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
+ $loader->load('services.yml');
+ }
+
+ public function prepend(ContainerBuilder $container): void
+ {
+ $this->prependRoute($container);
+ }
+
+ protected function prependRoute(ContainerBuilder $container): void
+ {
+ // declare routes for france travail api bundle
+ $container->prependExtensionConfig('chill_main', [
+ 'routing' => [
+ 'resources' => [
+ '@ChillFranceTravailApiBundle/Resources/config/routing.yml',
+ ],
+ ],
+ ]);
+ }
+}
diff --git a/src/Bundle/ChillFranceTravailApiBundle/src/DependencyInjection/Configuration.php b/src/Bundle/ChillFranceTravailApiBundle/src/DependencyInjection/Configuration.php
new file mode 100644
index 000000000..2d94678d4
--- /dev/null
+++ b/src/Bundle/ChillFranceTravailApiBundle/src/DependencyInjection/Configuration.php
@@ -0,0 +1,34 @@
+getRootNode();
+ // Here you should define the parameters that are allowed to
+ // configure your bundle. See the documentation linked above for
+ // more information on that topic.
+
+ return $treeBuilder;
+ }
+}
diff --git a/src/Bundle/ChillFranceTravailApiBundle/src/Resources/config/routing.yml b/src/Bundle/ChillFranceTravailApiBundle/src/Resources/config/routing.yml
new file mode 100644
index 000000000..fdb34eb87
--- /dev/null
+++ b/src/Bundle/ChillFranceTravailApiBundle/src/Resources/config/routing.yml
@@ -0,0 +1,3 @@
+chill_france_travail_api_controllers:
+ resource: "@ChillFranceTravailApiBundle/Controller"
+ type: annotation
diff --git a/src/Bundle/ChillFranceTravailApiBundle/src/Resources/config/services.yml b/src/Bundle/ChillFranceTravailApiBundle/src/Resources/config/services.yml
new file mode 100644
index 000000000..658a152dc
--- /dev/null
+++ b/src/Bundle/ChillFranceTravailApiBundle/src/Resources/config/services.yml
@@ -0,0 +1,16 @@
+services:
+ _defaults:
+ autowire: true
+ autoconfigure: true
+
+ Chill\FranceTravailApiBundle\ApiHelper\ApiWrapper:
+ $clientId: '%env(FRANCE_TRAVAIL_CLIENT_ID)%'
+ $clientSecret: '%env(FRANCE_TRAVAIL_CLIENT_SECRET)%'
+ $redis: '@Chill\MainBundle\Redis\ChillRedis'
+
+ Chill\FranceTravailApiBundle\ApiHelper\PartenaireRomeAppellation: ~
+
+ Chill\FranceTravailApiBundle\Controller\RomeController:
+ autowire: true
+ autoconfigure: true
+ tags: ['controller.service_arguments']
diff --git a/src/Bundle/ChillFranceTravailApiBundle/src/Resources/views/.gitkeep b/src/Bundle/ChillFranceTravailApiBundle/src/Resources/views/.gitkeep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/src/Bundle/ChillFranceTravailApiBundle/src/Resources/views/.gitkeep
@@ -0,0 +1 @@
+
diff --git a/src/Bundle/ChillFranceTravailApiBundle/src/Tests/ApiHelper/PartenaireRomeAppellationTest.php b/src/Bundle/ChillFranceTravailApiBundle/src/Tests/ApiHelper/PartenaireRomeAppellationTest.php
new file mode 100644
index 000000000..4096d5e94
--- /dev/null
+++ b/src/Bundle/ChillFranceTravailApiBundle/src/Tests/ApiHelper/PartenaireRomeAppellationTest.php
@@ -0,0 +1,93 @@
+
+ *
+ * @internal
+ *
+ * @coversNothing
+ */
+class PartenaireRomeAppellationTest extends KernelTestCase
+{
+ protected function setUp(): void
+ {
+ parent::setUp();
+
+ self::bootKernel();
+ }
+
+ public function testGetListeMetiersSimple()
+ {
+ /** @var PartenaireRomeAppellation $appellations */
+ $appellations = self::$kernel
+ ->getContainer()
+ ->get(PartenaireRomeAppellation::class)
+ ;
+
+ $data = $appellations->getListeAppellation('arb');
+
+ $this->assertTrue(\is_array($data));
+ $this->assertNotNull($data[0]->libelle);
+ $this->assertNotNull($data[0]->code);
+ }
+
+ public function testGetListeMetiersTooMuchRequests()
+ {
+ /** @var PartenaireRomeMetier $appellations */
+ $appellations = self::$kernel
+ ->getContainer()
+ ->get(PartenaireRomeAppellation::class)
+ ;
+
+ $appellations->getListeAppellation('arb');
+ $appellations->getListeAppellation('ing');
+ $appellations->getListeAppellation('rob');
+ $appellations->getListeAppellation('chori');
+ $data = $appellations->getListeAppellation('camion');
+
+ $this->assertTrue(
+ $data[0] instanceof \stdClass,
+ 'assert that first index of data is an instance of stdClass'
+ );
+ }
+
+ public function testGetAppellation()
+ {
+ /** @var PartenaireRomeMetier $appellations */
+ $appellations = self::$kernel
+ ->getContainer()
+ ->get(PartenaireRomeAppellation::class)
+ ;
+
+ $a = $appellations->getListeAppellation('arb');
+
+ $full = $appellations->getAppellation($a[0]->code);
+
+ $this->assertNotNull(
+ $full->libelle,
+ 'assert that libelle is not null'
+ );
+ $this->assertTrue(
+ $full->metier instanceof \stdClass,
+ 'assert that metier is returned'
+ );
+ $this->assertNotNull(
+ $full->metier->libelle,
+ 'assert that metier->libelle is not null'
+ );
+ }
+}
diff --git a/src/Bundle/ChillFranceTravailApiBundle/src/Tests/Controller/RomeControllerTest.php b/src/Bundle/ChillFranceTravailApiBundle/src/Tests/Controller/RomeControllerTest.php
new file mode 100644
index 000000000..ef88ccf75
--- /dev/null
+++ b/src/Bundle/ChillFranceTravailApiBundle/src/Tests/Controller/RomeControllerTest.php
@@ -0,0 +1,29 @@
+request('GET', '/{_locale}/pole-emploi/appellation/search');
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/ChillJobBundle.php b/src/Bundle/ChillJobBundle/src/ChillJobBundle.php
new file mode 100644
index 000000000..b8b4a2146
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/ChillJobBundle.php
@@ -0,0 +1,16 @@
+request->get('submit', 'save-and-close');
+
+ return match ($next) {
+ 'save-and-close', 'delete-and-close' => $this->redirectToRoute('chill_job_report_index', [
+ 'person' => $entity->getPerson()->getId(),
+ ]),
+ default => parent::onBeforeRedirectAfterSubmission($action, $entity, $form, $request),
+ };
+ }
+
+ protected function duplicateEntity(string $action, Request $request)
+ {
+ if ('cscv' === $this->getCrudName()) {
+ $id = $request->query->get('duplicate_id', 0);
+ /** @var \Chill\JobBundle\Entity\CV $cv */
+ $cv = $this->getEntity($action, $id, $request);
+ $em = $this->managerRegistry->getManager();
+
+ $em->detach($cv);
+
+ foreach ($cv->getExperiences() as $experience) {
+ $cv->removeExperience($experience);
+ $em->detach($experience);
+ $cv->addExperience($experience);
+ }
+ foreach ($cv->getFormations() as $formation) {
+ $cv->removeFormation($formation);
+ $em->detach($formation);
+ $cv->addFormation($formation);
+ }
+
+ return $cv;
+ }
+ if ('projet_prof' === $this->getCrudName()) {
+ $id = $request->query->get('duplicate_id', 0);
+ /** @var \Chill\JobBundle\Entity\ProjetProfessionnel $original */
+ $original = $this->getEntity($action, $id, $request);
+
+ $new = parent::duplicateEntity($action, $request);
+
+ foreach ($original->getSouhait() as $s) {
+ $new->addSouhait($s);
+ }
+ foreach ($original->getValide() as $s) {
+ $new->addValide($s);
+ }
+
+ return $new;
+ }
+
+ return parent::duplicateEntity($action, $request);
+ }
+
+ protected function createFormFor(string $action, $entity, ?string $formClass = null, array $formOptions = []): FormInterface
+ {
+ if ($entity instanceof Immersion) {
+ if ('edit' === $action || 'new' === $action) {
+ return parent::createFormFor($action, $entity, $formClass, [
+ 'center' => $entity->getPerson()->getCenter(),
+ ]);
+ }
+ if ('bilan' === $action) {
+ return parent::createFormFor($action, $entity, $formClass, [
+ 'center' => $entity->getPerson()->getCenter(),
+ 'step' => 'bilan',
+ ]);
+ }
+ if ('delete' === $action) {
+ return parent::createFormFor($action, $entity, $formClass, $formOptions);
+ }
+ throw new \LogicException("this step {$action} is not supported");
+ }
+
+ return parent::createFormFor($action, $entity, $formClass, $formOptions);
+ }
+
+ protected function onPreFlush(string $action, $entity, FormInterface $form, Request $request)
+ {
+ // for immersion / edit-bilan action
+ if ('bilan' === $action) {
+ /* @var $entity Immersion */
+ $entity->setIsBilanFullfilled(true);
+ }
+
+ parent::onPreFlush($action, $entity, $form, $request);
+ }
+
+ /**
+ * Edit immersion bilan.
+ *
+ * @param int $id
+ */
+ public function editBilan(Request $request, $id): Response
+ {
+ return $this->formEditAction('bilan', $request, $id);
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/Controller/CSPersonController.php b/src/Bundle/ChillJobBundle/src/Controller/CSPersonController.php
new file mode 100644
index 000000000..d5ddf329d
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Controller/CSPersonController.php
@@ -0,0 +1,150 @@
+formEditAction(
+ 'ps_situation_edit',
+ $request,
+ $id,
+ CSPersonPersonalSituationType::class
+ );
+ }
+
+ #[Route(path: '{_locale}/person/job/dispositifs/{id}/edit', name: 'chill_crud_job_dispositifs_edit')]
+ public function dispositifsEdit(Request $request, $id)
+ {
+ return $this->formEditAction(
+ 'dispositifs_edit',
+ $request,
+ $id,
+ CSPersonDispositifsType::class
+ );
+ }
+
+ #[Route(path: '{_locale}/person/job/{person}/personal_situation', name: 'chill_crud_job_personal_situation_view')]
+ public function personalSituationView(Request $request, $person): Response
+ {
+ return $this->viewAction('ps_situation_view', $request, $person);
+ }
+
+ #[Route(path: '{_locale}/person/job/{person}/dispositifs', name: 'chill_crud_job_dispositifs_view')]
+ public function dispositifsView(Request $request, $person): Response
+ {
+ return $this->viewAction('dispositifs_view', $request, $person);
+ }
+
+ protected function generateRedirectOnCreateRoute($action, Request $request, $entity): string
+ {
+ $route = '';
+
+ switch ($action) {
+ case 'ps_situation_view':
+ $route = 'chill_crud_job_personal_situation_edit';
+ break;
+ case 'dispositifs_view':
+ $route = 'chill_crud_job_dispositifs_edit';
+ break;
+ default:
+ parent::generateRedirectOnCreateRoute($action, $request, $entity);
+ }
+
+ return $this->generateUrl($route, ['id' => $entity->getPerson()->getId()]);
+ }
+
+ protected function checkACL($action, $entity): void
+ {
+ match ($action) {
+ 'ps_situation_edit', 'dispositifs_edit' => $this->denyAccessUnlessGranted(
+ PersonVoter::UPDATE,
+ $entity->getPerson()
+ ),
+ 'ps_situation_view', 'dispositifs_view' => $this->denyAccessUnlessGranted(
+ PersonVoter::SEE,
+ $entity->getPerson()
+ ),
+ default => parent::checkACL($action, $entity),
+ };
+ }
+
+ protected function onBeforeRedirectAfterSubmission(string $action, $entity, FormInterface $form, Request $request): ?Response
+ {
+ return match ($action) {
+ 'ps_situation_edit' => $this->redirectToRoute(
+ 'chill_crud_'.$this->getCrudName().'_personal_situation_view',
+ ['person' => $entity->getId()]
+ ),
+ 'dispositifs_edit' => $this->redirectToRoute(
+ 'chill_crud_'.$this->getCrudName().'_dispositifs_view',
+ ['person' => $entity->getId()]
+ ),
+ default => null,
+ };
+ }
+
+ protected function getTemplateFor($action, $entity, Request $request): string
+ {
+ return match ($action) {
+ 'ps_situation_edit' => '@ChillJob/CSPerson/personal_situation_edit.html.twig',
+ 'dispositifs_edit' => '@ChillJob/CSPerson/dispositifs_edit.html.twig',
+ 'ps_situation_view' => '@ChillJob/CSPerson/personal_situation_view.html.twig',
+ 'dispositifs_view' => '@ChillJob/CSPerson/dispositifs_view.html.twig',
+ default => parent::getTemplateFor($action, $entity, $request),
+ };
+ }
+
+ protected function createFormFor(string $action, $entity, ?string $formClass = null, array $formOptions = []): FormInterface
+ {
+ switch ($action) {
+ case 'ps_situation_edit':
+ case 'dispositifs_edit':
+ $form = $this->createForm($formClass, $entity, \array_merge(
+ $formOptions,
+ ['center' => $entity->getPerson()->getCenter()]
+ ));
+ $this->customizeForm($action, $form);
+
+ return $form;
+
+ default:
+ return parent::createFormFor($action, $entity, $formClass, $formOptions);
+ }
+ }
+
+ protected function generateLabelForButton($action, $formName, $form): string
+ {
+ switch ($action) {
+ case 'ps_situation_edit':
+ case 'dispositifs_edit':
+ if ('submit' === $formName) {
+ return 'Enregistrer';
+ }
+ throw new \LogicException("this formName is not supported: {$formName}");
+ break;
+ default:
+ return 'Enregistrer';
+ }
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/Controller/CSReportController.php b/src/Bundle/ChillJobBundle/src/Controller/CSReportController.php
new file mode 100644
index 000000000..0fb85f89c
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Controller/CSReportController.php
@@ -0,0 +1,73 @@
+denyAccessUnlessGranted(PersonVoter::SEE, $person, 'The access to '
+ .'person is denied');
+
+ $reports = $this->getReports($person);
+
+ return $this->render('@ChillJob/Report/index.html.twig', \array_merge([
+ 'person' => $person,
+ ], $reports));
+ }
+
+ protected function getReports(Person $person): array
+ {
+ $results = [];
+
+ $kinds = [];
+
+ if ($this->isGranted(JobVoter::REPORT_CV, $person)) {
+ $kinds['cvs'] = CV::class;
+ }
+
+ if ($this->isGranted(JobVoter::REPORT_NEW, $person)) {
+ $kinds = \array_merge($kinds, [
+ 'cvs' => CV::class,
+ 'freins' => Frein::class,
+ 'immersions' => Immersion::class,
+ 'projet_professionnels' => ProjetProfessionnel::class,
+ ]);
+ }
+
+ foreach ($kinds as $key => $className) {
+ $ordering = match ($key) {
+ 'immersions' => ['debutDate' => 'DESC'],
+ default => ['reportDate' => 'DESC'],
+ };
+ $results[$key] = $this->managerRegistry->getManager()
+ ->getRepository($className)
+ ->findBy(['person' => $person], $ordering);
+ }
+
+ return $results;
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/Controller/CVCrudController.php b/src/Bundle/ChillJobBundle/src/Controller/CVCrudController.php
new file mode 100644
index 000000000..bd78498cb
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Controller/CVCrudController.php
@@ -0,0 +1,62 @@
+request->get('submit', 'save-and-close');
+
+ return match ($next) {
+ 'save-and-close', 'delete-and-close' => $this->redirectToRoute('chill_job_report_index', [
+ 'person' => $entity->getPerson()->getId(),
+ ]),
+ default => parent::onBeforeRedirectAfterSubmission($action, $entity, $form, $request),
+ };
+ }
+
+ protected function duplicateEntity(string $action, Request $request)
+ {
+ if ('cv' === $this->getCrudName()) {
+ $id = $request->query->get('duplicate_id', 0);
+ /** @var \Chill\JobBundle\Entity\CV $cv */
+ $cv = $this->getEntity($action, $id, $request);
+ $em = $this->managerRegistry->getManager();
+
+ $em->detach($cv);
+
+ foreach ($cv->getExperiences() as $experience) {
+ $cv->removeExperience($experience);
+ $em->detach($experience);
+ $cv->addExperience($experience);
+ }
+ foreach ($cv->getFormations() as $formation) {
+ $cv->removeFormation($formation);
+ $em->detach($formation);
+ $cv->addFormation($formation);
+ }
+
+ return $cv;
+ }
+
+ return parent::duplicateEntity($action, $request);
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/Controller/FreinCrudController.php b/src/Bundle/ChillJobBundle/src/Controller/FreinCrudController.php
new file mode 100644
index 000000000..d3b8ee6ef
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Controller/FreinCrudController.php
@@ -0,0 +1,35 @@
+request->get('submit', 'save-and-close');
+
+ return match ($next) {
+ 'save-and-close', 'delete-and-close' => $this->redirectToRoute('chill_job_report_index', [
+ 'person' => $entity->getPerson()->getId(),
+ ]),
+ default => parent::onBeforeRedirectAfterSubmission($action, $entity, $form, $request),
+ };
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/Controller/ImmersionCrudController.php b/src/Bundle/ChillJobBundle/src/Controller/ImmersionCrudController.php
new file mode 100644
index 000000000..c4880c3f3
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Controller/ImmersionCrudController.php
@@ -0,0 +1,80 @@
+request->get('submit', 'save-and-close');
+
+ return match ($next) {
+ 'save-and-close', 'delete-and-close' => $this->redirectToRoute('chill_job_report_index', [
+ 'person' => $entity->getPerson()->getId(),
+ ]),
+ default => parent::onBeforeRedirectAfterSubmission($action, $entity, $form, $request),
+ };
+ }
+
+ protected function createFormFor(string $action, $entity, ?string $formClass = null, array $formOptions = []): FormInterface
+ {
+ if ($entity instanceof Immersion) {
+ if ('edit' === $action || 'new' === $action) {
+ return parent::createFormFor($action, $entity, $formClass, [
+ 'center' => $entity->getPerson()->getCenter(),
+ ]);
+ }
+ if ('bilan' === $action) {
+ return parent::createFormFor($action, $entity, $formClass, [
+ 'center' => $entity->getPerson()->getCenter(),
+ 'step' => 'bilan',
+ ]);
+ }
+ if ('delete' === $action) {
+ return parent::createFormFor($action, $entity, $formClass, $formOptions);
+ }
+ throw new \LogicException("this step {$action} is not supported");
+ }
+
+ return parent::createFormFor($action, $entity, $formClass, $formOptions);
+ }
+
+ protected function onPreFlush(string $action, $entity, FormInterface $form, Request $request)
+ {
+ // for immersion / edit-bilan action
+ if ('bilan' === $action) {
+ /* @var $entity Immersion */
+ $entity->setIsBilanFullfilled(true);
+ }
+
+ parent::onPreFlush($action, $entity, $form, $request);
+ }
+
+ /**
+ * Edit immersion bilan.
+ *
+ * @param int $id
+ */
+ public function bilan(Request $request, $id): Response
+ {
+ return $this->formEditAction('bilan', $request, $id);
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/Controller/ProjetProfessionnelCrudController.php b/src/Bundle/ChillJobBundle/src/Controller/ProjetProfessionnelCrudController.php
new file mode 100644
index 000000000..80c953699
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Controller/ProjetProfessionnelCrudController.php
@@ -0,0 +1,57 @@
+request->get('submit', 'save-and-close');
+
+ return match ($next) {
+ 'save-and-close', 'delete-and-close' => $this->redirectToRoute('chill_job_report_index', [
+ 'person' => $entity->getPerson()->getId(),
+ ]),
+ default => parent::onBeforeRedirectAfterSubmission($action, $entity, $form, $request),
+ };
+ }
+
+ protected function duplicateEntity(string $action, Request $request)
+ {
+ if ('projet_prof' === $this->getCrudName()) {
+ $id = $request->query->get('duplicate_id', 0);
+ /** @var \Chill\JobBundle\Entity\ProjetProfessionnel $original */
+ $original = $this->getEntity($action, $id, $request);
+
+ $new = parent::duplicateEntity($action, $request);
+
+ foreach ($original->getSouhait() as $s) {
+ $new->addSouhait($s);
+ }
+ foreach ($original->getValide() as $s) {
+ $new->addValide($s);
+ }
+
+ return $new;
+ }
+
+ return parent::duplicateEntity($action, $request);
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/DependencyInjection/ChillJobExtension.php b/src/Bundle/ChillJobBundle/src/DependencyInjection/ChillJobExtension.php
new file mode 100644
index 000000000..110e5d8df
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/DependencyInjection/ChillJobExtension.php
@@ -0,0 +1,196 @@
+processConfiguration($configuration, $configs);
+
+ $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
+ $loader->load('services.yml');
+ $loader->load('services/3party_type.yml');
+ $loader->load('services/controller.yml');
+ $loader->load('services/form.yml');
+ $loader->load('services/export.yml');
+ $loader->load('services/menu.yml');
+ $loader->load('services/security.yml');
+ }
+
+ public function prepend(ContainerBuilder $container): void
+ {
+ $this->prependRoute($container);
+ $this->prependCruds($container);
+ }
+
+ protected function prependCruds(ContainerBuilder $container)
+ {
+ $container->prependExtensionConfig('chill_main', [
+ 'cruds' => [
+ [
+ 'class' => CSPerson::class,
+ 'controller' => CSPersonController::class,
+ 'name' => 'job',
+ 'base_role' => 'ROLE_USER',
+ 'base_path' => '/person/job/',
+ ],
+ [
+ 'class' => CV::class,
+ 'controller' => CVCrudController::class,
+ 'name' => 'cscv',
+ 'base_role' => 'ROLE_USER',
+ 'base_path' => '/person/report/cv',
+ 'form_class' => CVType::class,
+ 'actions' => [
+ 'view' => [
+ 'role' => 'ROLE_USER',
+ 'template' => '@ChillJob/CV/view.html.twig',
+ ],
+ 'new' => [
+ 'role' => 'ROLE_USER',
+ 'template' => '@ChillJob/CV/new.html.twig',
+ ],
+ 'edit' => [
+ 'role' => 'ROLE_USER',
+ 'template' => '@ChillJob/CV/edit.html.twig',
+ ],
+ 'delete' => [
+ 'role' => 'ROLE_USER',
+ 'template' => '@ChillJob/Report/delete.html.twig',
+ ],
+ ],
+ ],
+ [
+ 'class' => ProjetProfessionnel::class,
+ 'controller' => ProjetProfessionnelCrudController::class,
+ 'name' => 'projet_prof',
+ 'base_role' => 'ROLE_USER',
+ 'base_path' => '/person/report/projet-professionnel',
+ 'form_class' => ProjetProfessionnelType::class,
+ 'actions' => [
+ 'view' => [
+ 'role' => 'ROLE_USER',
+ 'template' => '@ChillJob/ProjetProfessionnel/view.html.twig',
+ ],
+ 'new' => [
+ 'role' => 'ROLE_USER',
+ 'template' => '@ChillJob/ProjetProfessionnel/new.html.twig',
+ ],
+ 'edit' => [
+ 'role' => 'ROLE_USER',
+ 'template' => '@ChillJob/ProjetProfessionnel/edit.html.twig',
+ ],
+ 'delete' => [
+ 'role' => 'ROLE_USER',
+ 'template' => '@ChillJob/Report/delete.html.twig',
+ ],
+ ],
+ ],
+ [
+ 'class' => Frein::class,
+ 'controller' => FreinCrudController::class,
+ 'name' => 'csfrein',
+ 'base_role' => 'ROLE_USER',
+ 'base_path' => '/person/report/frein',
+ 'form_class' => FreinType::class,
+ 'actions' => [
+ 'view' => [
+ 'role' => 'ROLE_USER',
+ 'template' => '@ChillJob/Frein/view.html.twig',
+ ],
+ 'new' => [
+ 'role' => 'ROLE_USER',
+ 'template' => '@ChillJob/Frein/new.html.twig',
+ ],
+ 'edit' => [
+ 'role' => 'ROLE_USER',
+ 'template' => '@ChillJob/Frein/edit.html.twig',
+ ],
+ 'delete' => [
+ 'role' => 'ROLE_USER',
+ 'template' => '@ChillJob/Report/delete.html.twig',
+ ],
+ ],
+ ],
+ [
+ 'class' => Immersion::class,
+ 'controller' => ImmersionCrudController::class,
+ 'name' => 'immersion',
+ 'base_role' => 'ROLE_USER',
+ 'base_path' => '/person/report/immersion',
+ 'form_class' => ImmersionType::class,
+ 'actions' => [
+ 'view' => [
+ 'role' => 'ROLE_USER',
+ 'template' => '@ChillJob/Immersion/view.html.twig',
+ ],
+ 'new' => [
+ 'role' => 'ROLE_USER',
+ 'template' => '@ChillJob/Immersion/new.html.twig',
+ ],
+ 'bilan' => [
+ 'role' => 'ROLE_USER',
+ 'template' => '@ChillJob/Immersion/edit-bilan.html.twig',
+ ],
+ 'edit' => [
+ 'role' => 'ROLE_USER',
+ 'template' => '@ChillJob/Immersion/edit.html.twig',
+ ],
+ 'delete' => [
+ 'role' => 'ROLE_USER',
+ 'template' => '@ChillJob/Report/delete.html.twig',
+ ],
+ ],
+ ],
+ ],
+ ]);
+ }
+
+ protected function prependRoute(ContainerBuilder $container): void
+ {
+ // declare routes for job bundle
+ $container->prependExtensionConfig('chill_main', [
+ 'routing' => [
+ 'resources' => [
+ '@ChillJobBundle/Resources/config/routing.yml',
+ ],
+ ],
+ ]);
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/DependencyInjection/Configuration.php b/src/Bundle/ChillJobBundle/src/DependencyInjection/Configuration.php
new file mode 100644
index 000000000..f4140defa
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/DependencyInjection/Configuration.php
@@ -0,0 +1,35 @@
+getRootNode();
+
+ // Here you should define the parameters that are allowed to
+ // configure your bundle. See the documentation linked above for
+ // more information on that topic.
+
+ return $treeBuilder;
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/Entity/CSPerson.php b/src/Bundle/ChillJobBundle/src/Entity/CSPerson.php
new file mode 100644
index 000000000..1a2608388
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Entity/CSPerson.php
@@ -0,0 +1,1224 @@
+id;
+ }
+
+ /**
+ * Set situationLogement.
+ *
+ * @return CSPerson
+ */
+ public function setSituationLogement(?string $situationLogement = null)
+ {
+ $this->situationLogement = $situationLogement;
+
+ return $this;
+ }
+
+ /**
+ * Get situationLogement.
+ *
+ * @return string|null
+ */
+ public function getSituationLogement()
+ {
+ return $this->situationLogement;
+ }
+
+ /**
+ * Set enfantACharge.
+ *
+ * @return CSPerson
+ */
+ public function setEnfantACharge(?int $enfantACharge = null)
+ {
+ $this->enfantACharge = $enfantACharge;
+
+ return $this;
+ }
+
+ /**
+ * Get enfantACharge.
+ *
+ * @return int|null
+ */
+ public function getEnfantACharge()
+ {
+ return $this->enfantACharge;
+ }
+
+ /**
+ * Set niveauMaitriseLangue.
+ *
+ * @return CSPerson
+ */
+ public function setNiveauMaitriseLangue($niveauMaitriseLangue)
+ {
+ if (null === $niveauMaitriseLangue) {
+ $this->niveauMaitriseLangue = null;
+
+ return $this;
+ }
+
+ $this->niveauMaitriseLangue = count($niveauMaitriseLangue) > 0 ?
+ $niveauMaitriseLangue : null;
+
+ return $this;
+ }
+
+ /**
+ * Get niveauMaitriseLangue.
+ */
+ public function getNiveauMaitriseLangue()
+ {
+ return $this->niveauMaitriseLangue;
+ }
+
+ /**
+ * Valide niveauMaitriseLangue.
+ *
+ * @Assert\Callback()
+ */
+ public function validateNiveauMatriseLangue(ExecutionContextInterface $context)
+ {
+ if (null === $this->getNiveauMaitriseLangue()) {
+ return;
+ }
+
+ if (\in_array('aucun', $this->getNiveauMaitriseLangue(), true)) {
+ if (count($this->getNiveauMaitriseLangue()) > 1) {
+ $context->buildViolation("Si \"Aucun\" est choisi dans la liste, il n'est "
+ ."pas possible de cocher d'autres indications")
+ ->atPath('niveauMaitriseLangue')
+ ->addViolation();
+ }
+ }
+ }
+
+ /**
+ * Set vehiculePersonnel.
+ *
+ * @return CSPerson
+ */
+ public function setVehiculePersonnel(?bool $vehiculePersonnel)
+ {
+ $this->vehiculePersonnel = $vehiculePersonnel;
+
+ return $this;
+ }
+
+ /**
+ * Get vehiculePersonnel.
+ *
+ * @return bool
+ */
+ public function getVehiculePersonnel()
+ {
+ return $this->vehiculePersonnel;
+ }
+
+ /**
+ * Set permisConduire.
+ *
+ * @return CSPerson
+ */
+ public function setPermisConduire($permisConduire)
+ {
+ $this->permisConduire = $permisConduire;
+
+ return $this;
+ }
+
+ /**
+ * Get permisConduire.
+ */
+ public function getPermisConduire()
+ {
+ return $this->permisConduire;
+ }
+
+ /**
+ * Set situationProfessionnelle.
+ *
+ * @return CSPerson
+ */
+ public function setSituationProfessionnelle(?string $situationProfessionnelle)
+ {
+ $this->situationProfessionnelle = $situationProfessionnelle;
+
+ return $this;
+ }
+
+ /**
+ * Get situationProfessionnelle.
+ *
+ * @return string
+ */
+ public function getSituationProfessionnelle()
+ {
+ return $this->situationProfessionnelle;
+ }
+
+ /**
+ * Set dateFinDernierEmploi.
+ *
+ * @param \DateTime $dateFinDernierEmploi
+ *
+ * @return CSPerson
+ */
+ public function setDateFinDernierEmploi(?\DateTimeInterface $dateFinDernierEmploi)
+ {
+ $this->dateFinDernierEmploi = $dateFinDernierEmploi;
+
+ return $this;
+ }
+
+ /**
+ * Get dateFinDernierEmploi.
+ *
+ * @return \DateTimeInterface
+ */
+ public function getDateFinDernierEmploi()
+ {
+ return $this->dateFinDernierEmploi;
+ }
+
+ /**
+ * Set typeContrat.
+ *
+ * @return CSPerson
+ */
+ public function setTypeContrat($typeContrat)
+ {
+ $this->typeContrat = $typeContrat;
+
+ return $this;
+ }
+
+ /**
+ * Get typeContrat.
+ */
+ public function getTypeContrat()
+ {
+ return $this->typeContrat;
+ }
+
+ /**
+ * Set ressources.
+ *
+ * @return CSPerson
+ */
+ public function setRessources($ressources)
+ {
+ $this->ressources = $ressources;
+
+ return $this;
+ }
+
+ /**
+ * Get ressources.
+ */
+ public function getRessources()
+ {
+ return $this->ressources;
+ }
+
+ /**
+ * Set ressourcesComment.
+ *
+ * @return CSPerson
+ */
+ public function setRessourcesComment(?string $ressourcesComment)
+ {
+ $this->ressourcesComment = $ressourcesComment;
+
+ return $this;
+ }
+
+ /**
+ * Get ressourcesComment.
+ *
+ * @return string
+ */
+ public function getRessourcesComment()
+ {
+ return $this->ressourcesComment;
+ }
+
+ /**
+ * Set ressourceDate1Versement.
+ *
+ * @param \DateTime $ressourceDate1Versement
+ *
+ * @return CSPerson
+ */
+ public function setRessourceDate1Versement(?\DateTimeInterface $ressourceDate1Versement)
+ {
+ $this->ressourceDate1Versement = $ressourceDate1Versement;
+
+ return $this;
+ }
+
+ /**
+ * Get ressourceDate1Versement.
+ *
+ * @return \DateTimeInterface
+ */
+ public function getRessourceDate1Versement()
+ {
+ return $this->ressourceDate1Versement;
+ }
+
+ public function getCPFMontant()
+ {
+ return $this->cPFMontant;
+ }
+
+ public function setCPFMontant(?float $cPFMontant)
+ {
+ $this->cPFMontant = $cPFMontant;
+
+ return $this;
+ }
+
+ /**
+ * Set accompagnement.
+ *
+ * @return CSPerson
+ */
+ public function setAccompagnement($accompagnement)
+ {
+ $this->accompagnement = $accompagnement;
+
+ return $this;
+ }
+
+ /**
+ * Get accompagnement.
+ */
+ public function getAccompagnement()
+ {
+ return $this->accompagnement;
+ }
+
+ /**
+ * Set accompagnementRQTHDate.
+ *
+ * @param \DateTime $accompagnementRQTHDate
+ *
+ * @return CSPerson
+ */
+ public function setAccompagnementRQTHDate(?\DateTimeInterface $accompagnementRQTHDate)
+ {
+ $this->accompagnementRQTHDate = $accompagnementRQTHDate;
+
+ return $this;
+ }
+
+ /**
+ * Get accompagnementRQTHDate.
+ *
+ * @return \DateTimeInterface
+ */
+ public function getAccompagnementRQTHDate()
+ {
+ return $this->accompagnementRQTHDate;
+ }
+
+ /**
+ * Set accompagnementComment.
+ *
+ * @return CSPerson
+ */
+ public function setAccompagnementComment(?string $accompagnementComment)
+ {
+ $this->accompagnementComment = $accompagnementComment;
+
+ return $this;
+ }
+
+ /**
+ * Get accompagnementComment.
+ *
+ * @return string
+ */
+ public function getAccompagnementComment()
+ {
+ return $this->accompagnementComment;
+ }
+
+ /**
+ * Set poleEmploiId.
+ *
+ * @return CSPerson
+ */
+ public function setPoleEmploiId(?string $poleEmploiId)
+ {
+ $this->poleEmploiId = $poleEmploiId;
+
+ return $this;
+ }
+
+ /**
+ * Get poleEmploiId.
+ *
+ * @return string
+ */
+ public function getPoleEmploiId()
+ {
+ return $this->poleEmploiId;
+ }
+
+ /**
+ * Set poleEmploiInscriptionDate.
+ *
+ * @param \DateTime $poleEmploiInscriptionDate
+ *
+ * @return CSPerson
+ */
+ public function setPoleEmploiInscriptionDate(?\DateTimeInterface $poleEmploiInscriptionDate)
+ {
+ $this->poleEmploiInscriptionDate = $poleEmploiInscriptionDate;
+
+ return $this;
+ }
+
+ /**
+ * Get poleEmploiInscriptionDate.
+ *
+ * @return \DateTimeInterface
+ */
+ public function getPoleEmploiInscriptionDate()
+ {
+ return $this->poleEmploiInscriptionDate;
+ }
+
+ /**
+ * Set cafId.
+ *
+ * @return CSPerson
+ */
+ public function setCafId(?string $cafId)
+ {
+ $this->cafId = $cafId;
+
+ return $this;
+ }
+
+ /**
+ * Get cafId.
+ *
+ * @return string
+ */
+ public function getCafId()
+ {
+ return $this->cafId;
+ }
+
+ /**
+ * Set cafInscriptionDate.
+ *
+ * @param \DateTime $cafInscriptionDate
+ *
+ * @return CSPerson
+ */
+ public function setCafInscriptionDate(?\DateTimeInterface $cafInscriptionDate)
+ {
+ $this->cafInscriptionDate = $cafInscriptionDate;
+
+ return $this;
+ }
+
+ /**
+ * Get cafInscriptionDate.
+ *
+ * @return \DateTimeInterface
+ */
+ public function getCafInscriptionDate()
+ {
+ return $this->cafInscriptionDate;
+ }
+
+ /**
+ * Set cERInscriptionDate.
+ *
+ * @param \DateTime $cERInscriptionDate
+ *
+ * @return CSPerson
+ */
+ public function setCERInscriptionDate(?\DateTimeInterface $cERInscriptionDate)
+ {
+ $this->cERInscriptionDate = $cERInscriptionDate;
+
+ return $this;
+ }
+
+ /**
+ * Get cERInscriptionDate.
+ *
+ * @return \DateTimeInterface
+ */
+ public function getCERInscriptionDate()
+ {
+ return $this->cERInscriptionDate;
+ }
+
+ /**
+ * Set pPAEInscriptionDate.
+ *
+ * @param \DateTime $pPAEInscriptionDate
+ *
+ * @return CSPerson
+ */
+ public function setPPAEInscriptionDate(?\DateTimeInterface $pPAEInscriptionDate)
+ {
+ $this->pPAEInscriptionDate = $pPAEInscriptionDate;
+
+ return $this;
+ }
+
+ /**
+ * Get pPAEInscriptionDate.
+ *
+ * @return \DateTimeInterface
+ */
+ public function getPPAEInscriptionDate()
+ {
+ return $this->pPAEInscriptionDate;
+ }
+
+ public function getCERSignataire(): ?string
+ {
+ return $this->cERSignataire;
+ }
+
+ public function getPPAESignataire(): ?string
+ {
+ return $this->pPAESignataire;
+ }
+
+ public function setCERSignataire(?string $cERSignataire)
+ {
+ $this->cERSignataire = $cERSignataire;
+ }
+
+ public function setPPAESignataire(?string $pPAESignataire)
+ {
+ $this->pPAESignataire = $pPAESignataire;
+ }
+
+ /**
+ * Set nEETEligibilite.
+ *
+ * @return CSPerson
+ */
+ public function setNEETEligibilite(?bool $nEETEligibilite)
+ {
+ $this->nEETEligibilite = $nEETEligibilite;
+
+ return $this;
+ }
+
+ /**
+ * Get nEETEligibilite.
+ *
+ * @return bool
+ */
+ public function getNEETEligibilite()
+ {
+ return $this->nEETEligibilite;
+ }
+
+ /**
+ * Set nEETCommissionDate.
+ *
+ * @param \DateTime $nEETCommissionDate
+ *
+ * @return CSPerson
+ */
+ public function setNEETCommissionDate(?\DateTimeInterface $nEETCommissionDate)
+ {
+ $this->nEETCommissionDate = $nEETCommissionDate;
+
+ return $this;
+ }
+
+ /**
+ * Get nEETCommissionDate.
+ *
+ * @return \DateTimeInterface
+ */
+ public function getNEETCommissionDate()
+ {
+ return $this->nEETCommissionDate;
+ }
+
+ /**
+ * Set fSEMaDemarcheCode.
+ *
+ * @return CSPerson
+ */
+ public function setFSEMaDemarcheCode(?string $fSEMaDemarcheCode)
+ {
+ $this->fSEMaDemarcheCode = $fSEMaDemarcheCode;
+
+ return $this;
+ }
+
+ /**
+ * Get fSEMaDemarcheCode.
+ *
+ * @return string
+ */
+ public function getFSEMaDemarcheCode()
+ {
+ return $this->fSEMaDemarcheCode;
+ }
+
+ public function getDispositifsNotes()
+ {
+ return $this->dispositifsNotes;
+ }
+
+ public function setDispositifsNotes(?string $dispositifsNotes)
+ {
+ $this->dispositifsNotes = $dispositifsNotes;
+ }
+
+ public function setPerson(Person $person)
+ {
+ $this->person = $person;
+ $this->id = $person->getId();
+ }
+
+ public function getPerson(): ?Person
+ {
+ return $this->person;
+ }
+
+ // quick and dirty way to handle marital status from a form in this bundle
+ // (CSPersonalSituationType)
+
+ public function getPersonMaritalStatus()
+ {
+ return $this->getPerson()->getMaritalStatus();
+ }
+
+ public function setPersonMaritalStatus(MaritalStatus $maritalStatus)
+ {
+ return $this->getPerson()->setMaritalStatus($maritalStatus);
+ }
+
+ public function getDocumentCV(): ?StoredObject
+ {
+ return $this->documentCV;
+ }
+
+ public function getDocumentAgrementIAE(): ?StoredObject
+ {
+ return $this->documentAgrementIAE;
+ }
+
+ public function getDocumentRQTH(): ?StoredObject
+ {
+ return $this->documentRQTH;
+ }
+
+ public function getDocumentAttestationNEET(): ?StoredObject
+ {
+ return $this->documentAttestationNEET;
+ }
+
+ public function getDocumentCI(): ?StoredObject
+ {
+ return $this->documentCI;
+ }
+
+ public function getDocumentTitreSejour(): ?StoredObject
+ {
+ return $this->documentTitreSejour;
+ }
+
+ public function getDocumentAttestationFiscale(): ?StoredObject
+ {
+ return $this->documentAttestationFiscale;
+ }
+
+ public function getDocumentPermis(): ?StoredObject
+ {
+ return $this->documentPermis;
+ }
+
+ public function getDocumentAttestationCAAF(): ?StoredObject
+ {
+ return $this->documentAttestationCAAF;
+ }
+
+ public function getDocumentContraTravail(): ?StoredObject
+ {
+ return $this->documentContraTravail;
+ }
+
+ public function getDocumentAttestationFormation(): ?StoredObject
+ {
+ return $this->documentAttestationFormation;
+ }
+
+ public function getDocumentQuittanceLoyer(): ?StoredObject
+ {
+ return $this->documentQuittanceLoyer;
+ }
+
+ public function getDocumentFactureElectricite(): ?StoredObject
+ {
+ return $this->documentFactureElectricite;
+ }
+
+ public function getPrescripteur(): ?ThirdParty
+ {
+ return $this->prescripteur;
+ }
+
+ public function setDocumentCV(?StoredObject $documentCV = null)
+ {
+ $this->documentCV = $documentCV;
+ }
+
+ public function setDocumentAgrementIAE(?StoredObject $documentAgrementIAE = null)
+ {
+ $this->documentAgrementIAE = $documentAgrementIAE;
+ }
+
+ public function setDocumentRQTH(?StoredObject $documentRQTH = null)
+ {
+ $this->documentRQTH = $documentRQTH;
+ }
+
+ public function setDocumentAttestationNEET(?StoredObject $documentAttestationNEET = null)
+ {
+ $this->documentAttestationNEET = $documentAttestationNEET;
+ }
+
+ public function setDocumentCI(?StoredObject $documentCI = null)
+ {
+ $this->documentCI = $documentCI;
+ }
+
+ public function setDocumentTitreSejour(?StoredObject $documentTitreSejour = null)
+ {
+ $this->documentTitreSejour = $documentTitreSejour;
+ }
+
+ public function setDocumentAttestationFiscale(?StoredObject $documentAttestationFiscale = null)
+ {
+ $this->documentAttestationFiscale = $documentAttestationFiscale;
+ }
+
+ public function setDocumentPermis(?StoredObject $documentPermis = null)
+ {
+ $this->documentPermis = $documentPermis;
+ }
+
+ public function setDocumentAttestationCAAF(?StoredObject $documentAttestationCAAF = null)
+ {
+ $this->documentAttestationCAAF = $documentAttestationCAAF;
+ }
+
+ public function setDocumentContraTravail(?StoredObject $documentContraTravail = null)
+ {
+ $this->documentContraTravail = $documentContraTravail;
+ }
+
+ public function setDocumentAttestationFormation(?StoredObject $documentAttestationFormation = null)
+ {
+ $this->documentAttestationFormation = $documentAttestationFormation;
+ }
+
+ public function setDocumentQuittanceLoyer(?StoredObject $documentQuittanceLoyer = null)
+ {
+ $this->documentQuittanceLoyer = $documentQuittanceLoyer;
+ }
+
+ public function setDocumentFactureElectricite(?StoredObject $documentFactureElectricite = null)
+ {
+ $this->documentFactureElectricite = $documentFactureElectricite;
+ }
+
+ public function setPrescripteur(?ThirdParty $prescripteur = null)
+ {
+ $this->prescripteur = $prescripteur;
+ }
+
+ public function getSituationLogementPrecision()
+ {
+ return $this->situationLogementPrecision;
+ }
+
+ public function getAcompteDIF()
+ {
+ return $this->acompteDIF;
+ }
+
+ public function getHandicapIs()
+ {
+ return $this->handicapIs;
+ }
+
+ public function getHandicapNotes()
+ {
+ return $this->handicapNotes;
+ }
+
+ public function getHandicapRecommandation()
+ {
+ return $this->handicapRecommandation;
+ }
+
+ public function getMobiliteMoyenDeTransport()
+ {
+ return $this->mobiliteMoyenDeTransport;
+ }
+
+ public function getMobiliteNotes()
+ {
+ return $this->mobiliteNotes;
+ }
+
+ public function setMobiliteMoyenDeTransport($mobiliteMoyenDeTransport)
+ {
+ $this->mobiliteMoyenDeTransport = $mobiliteMoyenDeTransport;
+
+ return $this;
+ }
+
+ public function setMobiliteNotes(?string $mobiliteNotes)
+ {
+ $this->mobiliteNotes = $mobiliteNotes;
+
+ return $this;
+ }
+
+ public function getHandicapAccompagnement(): ?ThirdParty
+ {
+ return $this->handicapAccompagnement;
+ }
+
+ public function getDocumentAttestationSecuriteSociale(): ?StoredObject
+ {
+ return $this->documentAttestationSecuriteSociale;
+ }
+
+ public function setSituationLogementPrecision(?string $situationLogementPrecision)
+ {
+ $this->situationLogementPrecision = $situationLogementPrecision;
+
+ return $this;
+ }
+
+ public function setAcompteDIF(?float $acompteDIF)
+ {
+ $this->acompteDIF = $acompteDIF;
+
+ return $this;
+ }
+
+ public function setHandicapIs(?bool $handicapIs)
+ {
+ $this->handicapIs = $handicapIs;
+
+ return $this;
+ }
+
+ public function setHandicapNotes(?string $handicapNotes)
+ {
+ $this->handicapNotes = $handicapNotes;
+
+ return $this;
+ }
+
+ public function setHandicapRecommandation(?string $handicapRecommandation)
+ {
+ $this->handicapRecommandation = $handicapRecommandation;
+
+ return $this;
+ }
+
+ public function setHandicapAccompagnement(?ThirdParty $handicapAccompagnement = null)
+ {
+ $this->handicapAccompagnement = $handicapAccompagnement;
+
+ return $this;
+ }
+
+ public function setDocumentAttestationSecuriteSociale(?StoredObject $documentAttestationSecuriteSociale = null)
+ {
+ $this->documentAttestationSecuriteSociale = $documentAttestationSecuriteSociale;
+
+ return $this;
+ }
+
+ public function getDateContratIEJ(): ?\DateTimeInterface
+ {
+ return $this->dateContratIEJ;
+ }
+
+ public function setDateContratIEJ(?\DateTime $dateContratIEJ = null)
+ {
+ $this->dateContratIEJ = $dateContratIEJ;
+
+ return $this;
+ }
+
+ public function getTypeContratAide()
+ {
+ return $this->typeContratAide;
+ }
+
+ public function setTypeContratAide(?string $typeContratAide)
+ {
+ $this->typeContratAide = $typeContratAide;
+
+ return $this;
+ }
+
+ public function getDateAvenantIEJ(): ?\DateTimeInterface
+ {
+ return $this->dateAvenantIEJ;
+ }
+
+ public function setDateAvenantIEJ(?\DateTime $dateAvenantIEJ = null)
+ {
+ $this->dateAvenantIEJ = $dateAvenantIEJ;
+
+ return $this;
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/Entity/CV.php b/src/Bundle/ChillJobBundle/src/Entity/CV.php
new file mode 100644
index 000000000..257e4a0d0
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Entity/CV.php
@@ -0,0 +1,303 @@
+
+ */
+ #[ORM\OneToMany(targetEntity: CV\Formation::class, mappedBy: 'CV', cascade: ['persist', 'remove', 'detach'], orphanRemoval: true)]
+ // #[ORM\OrderBy(['startDate' => Order::Descending, 'endDate' => 'DESC'])]
+ private Collection $formations;
+
+ /**
+ * @Assert\Valid(traverse=true)
+ *
+ * @var \Doctrine\Common\Collections\Collection
+ */
+ #[ORM\OneToMany(targetEntity: CV\Experience::class, mappedBy: 'CV', cascade: ['persist', 'remove', 'detach'], orphanRemoval: true)]
+ // #[ORM\OrderBy(['startDate' => Order::Descending, 'endDate' => 'DESC'])]
+ private Collection $experiences;
+
+ #[ORM\ManyToOne(targetEntity: Person::class)]
+ private ?Person $person = null;
+
+ public function __construct()
+ {
+ $this->formations = new ArrayCollection();
+ $this->experiences = new ArrayCollection();
+ $this->reportDate = new \DateTime('now');
+ }
+
+ /**
+ * Get id.
+ *
+ * @return int
+ */
+ public function getId()
+ {
+ return $this->id;
+ }
+
+ /**
+ * Set reportDate.
+ */
+ public function setReportDate(\DateTime $reportDate): self
+ {
+ $this->reportDate = $reportDate;
+
+ return $this;
+ }
+
+ /**
+ * Get reportDate.
+ */
+ public function getReportDate(): ?\DateTimeInterface
+ {
+ return $this->reportDate;
+ }
+
+ /**
+ * Set formationLevel.
+ */
+ public function setFormationLevel(?string $formationLevel = null): self
+ {
+ $this->formationLevel = $formationLevel;
+
+ return $this;
+ }
+
+ /**
+ * Get formationLevel.
+ *
+ * @return string|null
+ */
+ public function getFormationLevel()
+ {
+ return $this->formationLevel;
+ }
+
+ /**
+ * Set formationType.
+ */
+ public function setFormationType(string $formationType): self
+ {
+ $this->formationType = $formationType;
+
+ return $this;
+ }
+
+ /**
+ * Get formationType.
+ */
+ public function getFormationType(): ?string
+ {
+ return $this->formationType;
+ }
+
+ /**
+ * Set spokenLanguages.
+ *
+ * @param mixed|null $spokenLanguages
+ */
+ public function setSpokenLanguages($spokenLanguages = null): self
+ {
+ $this->spokenLanguages = $spokenLanguages;
+
+ return $this;
+ }
+
+ /**
+ * Get spokenLanguages.
+ */
+ public function getSpokenLanguages(): array
+ {
+ return $this->spokenLanguages ?? [];
+ }
+
+ /**
+ * Set notes.
+ */
+ public function setNotes(?string $notes = null): self
+ {
+ $this->notes = $notes;
+
+ return $this;
+ }
+
+ /**
+ * Get notes.
+ */
+ public function getNotes(): ?string
+ {
+ return $this->notes;
+ }
+
+ public function getFormations(): Collection
+ {
+ return $this->formations;
+ }
+
+ public function getExperiences(): Collection
+ {
+ return $this->experiences;
+ }
+
+ public function setFormations(Collection $formations): self
+ {
+ foreach ($formations as $formation) {
+ /* @var CV\Formation $formation */
+ $formation->setCV($this);
+ }
+ $this->formations = $formations;
+
+ return $this;
+ }
+
+ public function addFormation(CV\Formation $formation): self
+ {
+ if ($this->formations->contains($formation)) {
+ return $this;
+ }
+
+ $this->formations->add($formation);
+ $formation->setCV($this);
+
+ return $this;
+ }
+
+ public function removeFormation(CV\Formation $formation): self
+ {
+ if (false === $this->formations->contains($formation)) {
+ return $this;
+ }
+
+ $formation->setCV(null);
+ $this->formations->removeElement($formation);
+
+ return $this;
+ }
+
+ public function setExperiences(Collection $experiences): self
+ {
+ foreach ($experiences as $experience) {
+ /* @var CV\Experience $experience */
+ $experience->setCV($this);
+ }
+
+ $this->experiences = $experiences;
+
+ return $this;
+ }
+
+ public function addExperience(CV\Experience $experience): self
+ {
+ if ($this->experiences->contains($experience)) {
+ return $this;
+ }
+
+ $experience->setCV($this);
+ $this->experiences->add($experience);
+
+ return $this;
+ }
+
+ public function removeExperience(CV\Experience $experience): self
+ {
+ if (false === $this->experiences->contains($experience)) {
+ return $this;
+ }
+
+ $this->experiences->removeElement($experience);
+ $experience->setCV(null);
+
+ return $this;
+ }
+
+ public function getPerson(): Person
+ {
+ return $this->person;
+ }
+
+ public function setPerson(Person $person)
+ {
+ $this->person = $person;
+
+ return $this;
+ }
+
+ public function __toString(): string
+ {
+ return 'CV de '.$this->getPerson().' daté du '.
+ $this->getReportDate()->format('d-m-Y');
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/Entity/CV/Experience.php b/src/Bundle/ChillJobBundle/src/Entity/CV/Experience.php
new file mode 100644
index 000000000..521cc82f6
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Entity/CV/Experience.php
@@ -0,0 +1,205 @@
+id;
+ }
+
+ /**
+ * Set poste.
+ */
+ public function setPoste(?string $poste = null): self
+ {
+ $this->poste = $poste;
+
+ return $this;
+ }
+
+ /**
+ * Get poste.
+ */
+ public function getPoste(): ?string
+ {
+ return $this->poste;
+ }
+
+ /**
+ * Set structure.
+ */
+ public function setStructure(?string $structure = null): self
+ {
+ $this->structure = $structure;
+
+ return $this;
+ }
+
+ /**
+ * Get structure.
+ */
+ public function getStructure(): ?string
+ {
+ return $this->structure;
+ }
+
+ /**
+ * Set startDate.
+ *
+ * @param \DateTime|null $startDate
+ */
+ public function setStartDate(?\DateTimeInterface $startDate = null): self
+ {
+ $this->startDate = $startDate;
+
+ return $this;
+ }
+
+ /**
+ * Get startDate.
+ *
+ * @return \DateTimeInterface
+ */
+ public function getStartDate()
+ {
+ return $this->startDate;
+ }
+
+ /**
+ * Set endDate.
+ *
+ * @param \DateTime|null $endDate
+ */
+ public function setEndDate(?\DateTimeInterface $endDate = null): self
+ {
+ $this->endDate = $endDate;
+
+ return $this;
+ }
+
+ /**
+ * Get endDate.
+ *
+ * @return \DateTimeInterface
+ */
+ public function getEndDate()
+ {
+ return $this->endDate;
+ }
+
+ /**
+ * Set contratType.
+ */
+ public function setContratType(?string $contratType): self
+ {
+ $this->contratType = $contratType;
+
+ return $this;
+ }
+
+ /**
+ * Get contratType.
+ */
+ public function getContratType(): ?string
+ {
+ return $this->contratType;
+ }
+
+ /**
+ * Set notes.
+ */
+ public function setNotes(?string $notes): self
+ {
+ $this->notes = $notes;
+
+ return $this;
+ }
+
+ /**
+ * Get notes.
+ */
+ public function getNotes(): ?string
+ {
+ return $this->notes;
+ }
+
+ public function getCV(): CV
+ {
+ return $this->CV;
+ }
+
+ public function setCV(?CV $CV = null): self
+ {
+ $this->CV = $CV;
+
+ return $this;
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/Entity/CV/Formation.php b/src/Bundle/ChillJobBundle/src/Entity/CV/Formation.php
new file mode 100644
index 000000000..3394fa795
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Entity/CV/Formation.php
@@ -0,0 +1,214 @@
+id;
+ }
+
+ /**
+ * Set title.
+ *
+ * @return Formation
+ */
+ public function setTitle(?string $title)
+ {
+ $this->title = $title;
+
+ return $this;
+ }
+
+ /**
+ * Get title.
+ *
+ * @return string
+ */
+ public function getTitle()
+ {
+ return $this->title;
+ }
+
+ /**
+ * Set startDate.
+ *
+ * @param \DateTime|null $startDate
+ *
+ * @return Formation
+ */
+ public function setStartDate(?\DateTimeInterface $startDate = null)
+ {
+ $this->startDate = $startDate;
+
+ return $this;
+ }
+
+ /**
+ * Get startDate.
+ *
+ * @return \DateTimeInterface
+ */
+ public function getStartDate()
+ {
+ return $this->startDate;
+ }
+
+ /**
+ * Set endDate.
+ *
+ * @param \DateTime|null $endDate
+ *
+ * @return Formation
+ */
+ public function setEndDate(?\DateTimeInterface $endDate = null)
+ {
+ $this->endDate = $endDate;
+
+ return $this;
+ }
+
+ /**
+ * Get endDate.
+ *
+ * @return \DateTimeInterface
+ */
+ public function getEndDate()
+ {
+ return $this->endDate;
+ }
+
+ /**
+ * Set diplomaObtained.
+ *
+ * @return Formation
+ */
+ public function setDiplomaObtained(?string $diplomaObtained = null)
+ {
+ $this->diplomaObtained = $diplomaObtained;
+
+ return $this;
+ }
+
+ /**
+ * Get diplomaObtained.
+ */
+ public function getDiplomaObtained()
+ {
+ return $this->diplomaObtained;
+ }
+
+ /**
+ * Set diplomaReconnue.
+ */
+ public function setDiplomaReconnue(?string $diplomaReconnue = null): self
+ {
+ $this->diplomaReconnue = $diplomaReconnue;
+
+ return $this;
+ }
+
+ /**
+ * Get diplomaReconnue.
+ */
+ public function getDiplomaReconnue(): ?string
+ {
+ return $this->diplomaReconnue;
+ }
+
+ /**
+ * Set organisme.
+ */
+ public function setOrganisme(?string $organisme): self
+ {
+ $this->organisme = $organisme;
+
+ return $this;
+ }
+
+ /**
+ * Get organisme.
+ */
+ public function getOrganisme(): ?string
+ {
+ return $this->organisme;
+ }
+
+ public function getCV(): ?CV
+ {
+ return $this->CV;
+ }
+
+ public function setCV(?CV $CV = null): self
+ {
+ $this->CV = $CV;
+
+ return $this;
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/Entity/Frein.php b/src/Bundle/ChillJobBundle/src/Entity/Frein.php
new file mode 100644
index 000000000..b60a342fd
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Entity/Frein.php
@@ -0,0 +1,192 @@
+reportDate = new \DateTime('today');
+ }
+
+ public function getId(): ?int
+ {
+ return $this->id;
+ }
+
+ public function setReportDate(?\DateTimeInterface $reportDate): self
+ {
+ $this->reportDate = $reportDate;
+
+ return $this;
+ }
+
+ public function getReportDate(): ?\DateTimeInterface
+ {
+ return $this->reportDate;
+ }
+
+ public function setFreinsPerso(array $freinsPerso = []): self
+ {
+ $this->freinsPerso = $freinsPerso;
+
+ return $this;
+ }
+
+ public function getFreinsPerso(): array
+ {
+ return $this->freinsPerso;
+ }
+
+ public function setNotesPerso(?string $notesPerso = null): self
+ {
+ $this->notesPerso = (string) $notesPerso;
+
+ return $this;
+ }
+
+ public function getNotesPerso(): ?string
+ {
+ return $this->notesPerso;
+ }
+
+ public function setFreinsEmploi(array $freinsEmploi = []): self
+ {
+ $this->freinsEmploi = $freinsEmploi;
+
+ return $this;
+ }
+
+ public function getFreinsEmploi(): array
+ {
+ return $this->freinsEmploi;
+ }
+
+ public function setNotesEmploi(?string $notesEmploi = null): self
+ {
+ $this->notesEmploi = (string) $notesEmploi;
+
+ return $this;
+ }
+
+ public function getNotesEmploi(): ?string
+ {
+ return $this->notesEmploi;
+ }
+
+ public function getPerson(): ?Person
+ {
+ return $this->person;
+ }
+
+ public function setPerson(?Person $person = null): HasPerson
+ {
+ $this->person = $person;
+
+ return $this;
+ }
+
+ /**
+ * @Assert\Callback()
+ */
+ public function validateFreinsCount(ExecutionContextInterface $context, $payload): void
+ {
+ $nb = count($this->getFreinsEmploi()) + count($this->getFreinsPerso());
+
+ if (0 === $nb) {
+ $msg = 'Indiquez au moins un frein parmi les freins '
+ ."liés à l'emploi et les freins liés à la situation personnelle.";
+ $context->buildViolation($msg)
+ ->atPath('freinsEmploi')
+ ->addViolation();
+
+ $context->buildViolation($msg)
+ ->atPath('freinsPerso')
+ ->addViolation();
+ }
+ }
+
+ public function __toString(): string
+ {
+ return 'Rapport "frein" de '.$this->getPerson().' daté du '.
+ $this->getReportDate()->format('d-m-Y');
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/Entity/Immersion.php b/src/Bundle/ChillJobBundle/src/Entity/Immersion.php
new file mode 100644
index 000000000..5ae19a365
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Entity/Immersion.php
@@ -0,0 +1,1083 @@
+ false])]
+ private ?bool $isBilanFullfilled = false;
+
+ public const SAVOIR_ETRE = [
+ 'assiduite',
+ 'ponctualite',
+ 'respect_consigne_securite',
+ 'relation_hierarchie',
+ 'capacite_adaptation',
+ 'motivation_travail',
+ ];
+
+ /**
+ * @var array|null
+ */
+ #[ORM\Column(name: 'savoirEtre', type: \Doctrine\DBAL\Types\Types::JSON, nullable: true)]
+ private $savoirEtre;
+
+ #[ORM\Column(name: 'savoirEtreNote', type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)]
+ private ?string $savoirEtreNote = null;
+
+ #[ORM\Column(name: 'noteimmersion', type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)]
+ private ?string $noteImmersion = null;
+
+ #[ORM\Column(name: 'principalesActivites', type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)]
+ private ?string $principalesActivites = null;
+
+ #[ORM\Column(name: 'competencesAcquises', type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)]
+ private ?string $competencesAcquises = null;
+
+ #[ORM\Column(name: 'competencesADevelopper', type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)]
+ private ?string $competencesADevelopper = null;
+
+ #[ORM\Column(name: 'noteBilan', type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)]
+ private ?string $noteBilan = null;
+
+ public const PONCTUALITE_SALARIE = [
+ 'aucun',
+ 'un',
+ 'plusieurs',
+ ];
+
+ #[ORM\Column(name: 'ponctualite_salarie', type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)]
+ private ?string $ponctualiteSalarie = null;
+
+ #[ORM\Column(name: 'ponctualite_salarie_note', type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)]
+ private ?string $ponctualiteSalarieNote = null;
+
+ public const ASSIDUITE = [
+ 'aucun',
+ 'un',
+ 'plusieurs',
+ ];
+
+ #[ORM\Column(name: 'assiduite', type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)]
+ private ?string $assiduite = null;
+
+ #[ORM\Column(name: 'assiduite_note', type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)]
+ private ?string $assiduiteNote = null;
+
+ #[ORM\Column(name: 'interet_activite', type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)]
+ private ?string $interetActivite = null;
+
+ #[ORM\Column(name: 'interet_activite_note', type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)]
+ private ?string $interetActiviteNote = null;
+
+ public const INTEGRE_REGLE = [
+ '1_temps',
+ 'rapidement',
+ 'pas_encore',
+ ];
+
+ #[ORM\Column(name: 'integre_regle', type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)]
+ private ?string $integreRegle = null;
+
+ #[ORM\Column(name: 'integre_regle_note', type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)]
+ private ?string $integreRegleNote = null;
+
+ #[ORM\Column(name: 'esprit_initiative', type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)]
+ private ?string $espritInitiative = null;
+
+ #[ORM\Column(name: 'esprit_initiative_note', type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)]
+ private ?string $espritInitiativeNote = null;
+
+ #[ORM\Column(name: 'organisation', type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)]
+ private ?string $organisation = null;
+
+ #[ORM\Column(name: 'organisation_note', type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)]
+ private ?string $organisationNote = null;
+
+ #[ORM\Column(name: 'capacite_travail_equipe', type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)]
+ private ?string $capaciteTravailEquipe = null;
+
+ #[ORM\Column(name: 'capacite_travail_equipe_note', type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)]
+ private ?string $capaciteTravailEquipeNote = null;
+
+ #[ORM\Column(name: 'style_vestimentaire', type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)]
+ private ?string $styleVestimentaire = null;
+
+ #[ORM\Column(name: 'style_vestimentaire_note', type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)]
+ private ?string $styleVestimentaireNote = null;
+
+ #[ORM\Column(name: 'langage_prof', type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)]
+ private ?string $langageProf = null;
+
+ #[ORM\Column(name: 'langage_prof_note', type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)]
+ private ?string $langageProfNote = null;
+
+ #[ORM\Column(name: 'applique_consigne', type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)]
+ private ?string $appliqueConsigne = null;
+
+ #[ORM\Column(name: 'applique_consigne_note', type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)]
+ private ?string $appliqueConsigneNote = null;
+
+ #[ORM\Column(name: 'respect_hierarchie', type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)]
+ private ?string $respectHierarchie = null;
+
+ #[ORM\Column(name: 'respect_hierarchie_note', type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)]
+ private ?string $respectHierarchieNote = null;
+
+ /**
+ * Get id.
+ *
+ * @return int
+ */
+ public function getId()
+ {
+ return $this->id;
+ }
+
+ /**
+ * Set domaineActivite.
+ *
+ * @return Immersion
+ */
+ public function setDomaineActivite(?string $domaineActivite = null)
+ {
+ $this->domaineActivite = $domaineActivite;
+
+ return $this;
+ }
+
+ /**
+ * Get domaineActivite.
+ *
+ * @return string|null
+ */
+ public function getDomaineActivite()
+ {
+ return $this->domaineActivite;
+ }
+
+ /**
+ * Set tuteurName.
+ *
+ * @return Immersion
+ */
+ public function setTuteurName(?string $tuteurName = null)
+ {
+ $this->tuteurName = $tuteurName;
+
+ return $this;
+ }
+
+ /**
+ * Get tuteurName.
+ *
+ * @return string|null
+ */
+ public function getTuteurName()
+ {
+ return $this->tuteurName;
+ }
+
+ /**
+ * Set tuteurFonction.
+ *
+ * @return Immersion
+ */
+ public function setTuteurFonction(?string $tuteurFonction = null)
+ {
+ $this->tuteurFonction = $tuteurFonction;
+
+ return $this;
+ }
+
+ /**
+ * Get tuteurFonction.
+ *
+ * @return string|null
+ */
+ public function getTuteurFonction()
+ {
+ return $this->tuteurFonction;
+ }
+
+ /**
+ * Set tuteurPhoneNumber.
+ *
+ * @return Immersion
+ */
+ public function setTuteurPhoneNumber(?PhoneNumber $tuteurPhoneNumber = null)
+ {
+ $this->tuteurPhoneNumber = $tuteurPhoneNumber;
+
+ return $this;
+ }
+
+ /**
+ * Get tuteurPhoneNumber.
+ */
+ public function getTuteurPhoneNumber(): ?PhoneNumber
+ {
+ return $this->tuteurPhoneNumber;
+ }
+
+ /**
+ * Set structureAccName.
+ *
+ * @return Immersion
+ */
+ public function setStructureAccName(?string $structureAccName = null)
+ {
+ $this->structureAccName = $structureAccName;
+
+ return $this;
+ }
+
+ /**
+ * Get structureAccName.
+ *
+ * @return string|null
+ */
+ public function getStructureAccName()
+ {
+ return $this->structureAccName;
+ }
+
+ /**
+ * Set structureAccPhonenumber.
+ *
+ * @return Immersion
+ */
+ public function setStructureAccPhonenumber(?PhoneNumber $structureAccPhonenumber)
+ {
+ $this->structureAccPhonenumber = $structureAccPhonenumber;
+
+ return $this;
+ }
+
+ /**
+ * Get structureAccPhonenumber.
+ */
+ public function getStructureAccPhonenumber(): ?PhoneNumber
+ {
+ return $this->structureAccPhonenumber;
+ }
+
+ /**
+ * Set posteDescriptif.
+ *
+ * @return Immersion
+ */
+ public function setPosteDescriptif(?string $posteDescriptif = null)
+ {
+ $this->posteDescriptif = $posteDescriptif;
+
+ return $this;
+ }
+
+ /**
+ * Get posteDescriptif.
+ *
+ * @return string|null
+ */
+ public function getPosteDescriptif()
+ {
+ return $this->posteDescriptif;
+ }
+
+ /**
+ * Set posteTitle.
+ *
+ * @return Immersion
+ */
+ public function setPosteTitle(?string $posteTitle = null)
+ {
+ $this->posteTitle = $posteTitle;
+
+ return $this;
+ }
+
+ /**
+ * Get posteTitle.
+ *
+ * @return string|null
+ */
+ public function getPosteTitle()
+ {
+ return $this->posteTitle;
+ }
+
+ /**
+ * Set posteLieu.
+ *
+ * @return Immersion
+ */
+ public function setPosteLieu(?string $posteLieu = null)
+ {
+ $this->posteLieu = $posteLieu;
+
+ return $this;
+ }
+
+ /**
+ * Get posteLieu.
+ *
+ * @return string|null
+ */
+ public function getPosteLieu()
+ {
+ return $this->posteLieu;
+ }
+
+ /**
+ * Set debutDate.
+ *
+ * @return Immersion
+ */
+ public function setDebutDate(?\DateTime $debutDate = null)
+ {
+ $this->debutDate = $debutDate;
+
+ return $this;
+ }
+
+ /**
+ * Get debutDate.
+ *
+ * @return \DateTime
+ */
+ public function getDebutDate()
+ {
+ return $this->debutDate;
+ }
+
+ /**
+ * Set duration.
+ *
+ * @param string|null $duration
+ *
+ * @return Immersion
+ */
+ public function setDuration($duration = null)
+ {
+ $this->duration = $duration;
+
+ return $this;
+ }
+
+ /**
+ * Get duration.
+ */
+ public function getDuration()
+ {
+ return $this->duration;
+ }
+
+ public function getDateEndComputed()
+ {
+ $startDate = \DateTimeImmutable::createFromMutable($this->getDebutDate());
+
+ return $startDate->add($this->getDuration());
+ }
+
+ /**
+ * Set horaire.
+ *
+ * @return Immersion
+ */
+ public function setHoraire(?string $horaire = null)
+ {
+ $this->horaire = $horaire;
+
+ return $this;
+ }
+
+ /**
+ * Get horaire.
+ *
+ * @return string|null
+ */
+ public function getHoraire()
+ {
+ return $this->horaire;
+ }
+
+ /**
+ * Set objectifs.
+ *
+ * @param array|null $objectifs
+ *
+ * @return Immersion
+ */
+ public function setObjectifs($objectifs = null)
+ {
+ $this->objectifs = $objectifs;
+
+ return $this;
+ }
+
+ /**
+ * Get objectifs.
+ *
+ * @return array|null
+ */
+ public function getObjectifs()
+ {
+ return $this->objectifs;
+ }
+
+ public function getObjectifsAutre()
+ {
+ return $this->objectifsAutre;
+ }
+
+ public function setObjectifsAutre(?string $objectifsAutre)
+ {
+ $this->objectifsAutre = $objectifsAutre;
+
+ return $this;
+ }
+
+ /**
+ * Set savoirEtre.
+ *
+ * @param array|null $savoirEtre
+ *
+ * @return Immersion
+ */
+ public function setSavoirEtre($savoirEtre = null)
+ {
+ $this->savoirEtre = $savoirEtre;
+
+ return $this;
+ }
+
+ /**
+ * Get savoirEtre.
+ *
+ * @return array|null
+ */
+ public function getSavoirEtre()
+ {
+ return $this->savoirEtre;
+ }
+
+ /**
+ * Set note.
+ *
+ * @return Immersion
+ */
+ public function setNoteImmersion(?string $note)
+ {
+ $this->noteImmersion = $note;
+
+ return $this;
+ }
+
+ /**
+ * Get note.
+ *
+ * @return string
+ */
+ public function getNoteImmersion()
+ {
+ return $this->noteImmersion;
+ }
+
+ /**
+ * Set principalesActivites.
+ *
+ * @return Immersion
+ */
+ public function setPrincipalesActivites(?string $principalesActivites = null)
+ {
+ $this->principalesActivites = $principalesActivites;
+
+ return $this;
+ }
+
+ /**
+ * Get principalesActivites.
+ *
+ * @return string|null
+ */
+ public function getPrincipalesActivites()
+ {
+ return $this->principalesActivites;
+ }
+
+ /**
+ * Set competencesAcquises.
+ *
+ * @return Immersion
+ */
+ public function setCompetencesAcquises(?string $competencesAcquises = null)
+ {
+ $this->competencesAcquises = $competencesAcquises;
+
+ return $this;
+ }
+
+ /**
+ * Get competencesAcquises.
+ *
+ * @return string|null
+ */
+ public function getCompetencesAcquises()
+ {
+ return $this->competencesAcquises;
+ }
+
+ /**
+ * Set competencesADevelopper.
+ *
+ * @return Immersion
+ */
+ public function setCompetencesADevelopper(?string $competencesADevelopper = null)
+ {
+ $this->competencesADevelopper = $competencesADevelopper;
+
+ return $this;
+ }
+
+ /**
+ * Get competencesADevelopper.
+ *
+ * @return string|null
+ */
+ public function getCompetencesADevelopper()
+ {
+ return $this->competencesADevelopper;
+ }
+
+ /**
+ * Set noteBilan.
+ *
+ * @return Immersion
+ */
+ public function setNoteBilan(?string $noteBilan = null)
+ {
+ $this->noteBilan = $noteBilan;
+
+ return $this;
+ }
+
+ /**
+ * Get noteBilan.
+ *
+ * @return string|null
+ */
+ public function getNoteBilan()
+ {
+ return $this->noteBilan;
+ }
+
+ public function getPerson(): ?Person
+ {
+ return $this->person;
+ }
+
+ public function getEntreprise(): ?ThirdParty
+ {
+ return $this->entreprise;
+ }
+
+ public function getReferent(): ?User
+ {
+ return $this->referent;
+ }
+
+ public function setPerson(Person $person)
+ {
+ $this->person = $person;
+
+ return $this;
+ }
+
+ public function setEntreprise(ThirdParty $entreprise)
+ {
+ $this->entreprise = $entreprise;
+
+ return $this;
+ }
+
+ public function setReferent(User $referent)
+ {
+ $this->referent = $referent;
+
+ return $this;
+ }
+
+ public function getStructureAccEmail()
+ {
+ return $this->structureAccEmail;
+ }
+
+ public function getStructureAccAddress(): ?Address
+ {
+ return $this->structureAccAddress;
+ }
+
+ public function setStructureAccEmail(?string $structureAccEmail)
+ {
+ $this->structureAccEmail = $structureAccEmail;
+
+ return $this;
+ }
+
+ public function setStructureAccAddress(Address $structureAccAddress)
+ {
+ $this->structureAccAddress = $structureAccAddress;
+
+ return $this;
+ }
+
+ public function getIsBilanFullfilled()
+ {
+ return $this->isBilanFullfilled;
+ }
+
+ public function getSavoirEtreNote()
+ {
+ return $this->savoirEtreNote;
+ }
+
+ public function setIsBilanFullfilled(?bool $isBilanFullfilled)
+ {
+ $this->isBilanFullfilled = $isBilanFullfilled;
+
+ return $this;
+ }
+
+ public function setSavoirEtreNote(?string $savoirEtreNote)
+ {
+ $this->savoirEtreNote = $savoirEtreNote;
+
+ return $this;
+ }
+
+ public function getPonctualiteSalarie()
+ {
+ return $this->ponctualiteSalarie;
+ }
+
+ public function getPonctualiteSalarieNote()
+ {
+ return $this->ponctualiteSalarieNote;
+ }
+
+ public function getAssiduite()
+ {
+ return $this->assiduite;
+ }
+
+ public function getAssiduiteNote()
+ {
+ return $this->assiduiteNote;
+ }
+
+ public function getInteretActivite()
+ {
+ return $this->interetActivite;
+ }
+
+ public function getInteretActiviteNote()
+ {
+ return $this->interetActiviteNote;
+ }
+
+ public function getIntegreRegle()
+ {
+ return $this->integreRegle;
+ }
+
+ public function getIntegreRegleNote()
+ {
+ return $this->integreRegleNote;
+ }
+
+ public function getEspritInitiative()
+ {
+ return $this->espritInitiative;
+ }
+
+ public function getEspritInitiativeNote()
+ {
+ return $this->espritInitiativeNote;
+ }
+
+ public function getOrganisation()
+ {
+ return $this->organisation;
+ }
+
+ public function getOrganisationNote()
+ {
+ return $this->organisationNote;
+ }
+
+ public function getCapaciteTravailEquipe()
+ {
+ return $this->capaciteTravailEquipe;
+ }
+
+ public function getCapaciteTravailEquipeNote()
+ {
+ return $this->capaciteTravailEquipeNote;
+ }
+
+ public function getStyleVestimentaire()
+ {
+ return $this->styleVestimentaire;
+ }
+
+ public function getStyleVestimentaireNote()
+ {
+ return $this->styleVestimentaireNote;
+ }
+
+ public function getLangageProf()
+ {
+ return $this->langageProf;
+ }
+
+ public function getLangageProfNote()
+ {
+ return $this->langageProfNote;
+ }
+
+ public function getAppliqueConsigne()
+ {
+ return $this->appliqueConsigne;
+ }
+
+ public function getAppliqueConsigneNote()
+ {
+ return $this->appliqueConsigneNote;
+ }
+
+ public function getRespectHierarchie()
+ {
+ return $this->respectHierarchie;
+ }
+
+ public function getRespectHierarchieNote()
+ {
+ return $this->respectHierarchieNote;
+ }
+
+ public function setPonctualiteSalarie(?string $ponctualiteSalarie)
+ {
+ $this->ponctualiteSalarie = $ponctualiteSalarie;
+
+ return $this;
+ }
+
+ public function setPonctualiteSalarieNote(?string $ponctualiteSalarieNote)
+ {
+ $this->ponctualiteSalarieNote = $ponctualiteSalarieNote;
+
+ return $this;
+ }
+
+ public function setAssiduite(?string $assiduite)
+ {
+ $this->assiduite = $assiduite;
+
+ return $this;
+ }
+
+ public function setAssiduiteNote(?string $assiduiteNote)
+ {
+ $this->assiduiteNote = $assiduiteNote;
+
+ return $this;
+ }
+
+ public function setInteretActivite(?string $interetActivite)
+ {
+ $this->interetActivite = $interetActivite;
+
+ return $this;
+ }
+
+ public function setInteretActiviteNote(?string $interetActiviteNote)
+ {
+ $this->interetActiviteNote = $interetActiviteNote;
+
+ return $this;
+ }
+
+ public function setIntegreRegle(?string $integreRegle)
+ {
+ $this->integreRegle = $integreRegle;
+
+ return $this;
+ }
+
+ public function setIntegreRegleNote(?string $integreRegleNote)
+ {
+ $this->integreRegleNote = $integreRegleNote;
+
+ return $this;
+ }
+
+ public function setEspritInitiative(?string $espritInitiative)
+ {
+ $this->espritInitiative = $espritInitiative;
+
+ return $this;
+ }
+
+ public function setEspritInitiativeNote(?string $espritInitiativeNote)
+ {
+ $this->espritInitiativeNote = $espritInitiativeNote;
+
+ return $this;
+ }
+
+ public function setOrganisation(?string $organisation)
+ {
+ $this->organisation = $organisation;
+
+ return $this;
+ }
+
+ public function setOrganisationNote(?string $organisationNote)
+ {
+ $this->organisationNote = $organisationNote;
+
+ return $this;
+ }
+
+ public function setCapaciteTravailEquipe(?string $capaciteTravailEquipe)
+ {
+ $this->capaciteTravailEquipe = $capaciteTravailEquipe;
+
+ return $this;
+ }
+
+ public function setCapaciteTravailEquipeNote(?string $capaciteTravailEquipeNote)
+ {
+ $this->capaciteTravailEquipeNote = $capaciteTravailEquipeNote;
+
+ return $this;
+ }
+
+ public function setStyleVestimentaire(?string $styleVestimentaire)
+ {
+ $this->styleVestimentaire = $styleVestimentaire;
+
+ return $this;
+ }
+
+ public function setStyleVestimentaireNote(?string $styleVestimentaireNote)
+ {
+ $this->styleVestimentaireNote = $styleVestimentaireNote;
+
+ return $this;
+ }
+
+ public function setLangageProf(?string $langageProf)
+ {
+ $this->langageProf = $langageProf;
+
+ return $this;
+ }
+
+ public function setLangageProfNote(?string $langageProfNote)
+ {
+ $this->langageProfNote = $langageProfNote;
+
+ return $this;
+ }
+
+ public function setAppliqueConsigne(?string $appliqueConsigne)
+ {
+ $this->appliqueConsigne = $appliqueConsigne;
+
+ return $this;
+ }
+
+ public function setAppliqueConsigneNote(?string $appliqueConsigneNote)
+ {
+ $this->appliqueConsigneNote = $appliqueConsigneNote;
+
+ return $this;
+ }
+
+ public function setRespectHierarchie(?string $respectHierarchie)
+ {
+ $this->respectHierarchie = $respectHierarchie;
+
+ return $this;
+ }
+
+ public function setRespectHierarchieNote(?string $respectHierarchieNote)
+ {
+ $this->respectHierarchieNote = $respectHierarchieNote;
+
+ return $this;
+ }
+
+ public function __toString(): string
+ {
+ return 'Rapport "immersion" de '.$this->getPerson();
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/Entity/ProjetProfessionnel.php b/src/Bundle/ChillJobBundle/src/Entity/ProjetProfessionnel.php
new file mode 100644
index 000000000..58a1fca41
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Entity/ProjetProfessionnel.php
@@ -0,0 +1,407 @@
+
+ */
+ #[ORM\JoinTable(name: 'chill_job.projetprofessionnel_souhait')]
+ #[ORM\ManyToMany(targetEntity: Appellation::class, cascade: ['persist'])]
+ private Collection $souhait;
+
+ #[ORM\Column(name: 'domaineActiviteSouhait', type: Types::TEXT, nullable: true)]
+ private ?string $domaineActiviteSouhait = null;
+
+ public const TYPE_CONTRAT = [
+ 'cdd', 'cdi', 'contrat_insertion',
+ 'interim', 'indifferent', 'apprentissage',
+ 'personnalisation', 'creation_entreprise',
+ ];
+
+ /**
+ * @var array|null
+ *
+ * @Assert\Count(min=1, minMessage="Indiquez au moins un type de contrat")
+ */
+ #[ORM\Column(name: 'typeContrat', type: Types::JSON, nullable: true)]
+ private $typeContrat;
+
+ #[ORM\Column(name: 'typeContratNotes', type: Types::TEXT, nullable: true)]
+ private ?string $typeContratNotes = null;
+
+ public const VOLUME_HORAIRES = [
+ 'temps_plein',
+ 'temps_partiel',
+ ];
+
+ /**
+ * @var array|null
+ *
+ * @Assert\Count(min=1, minMessage="Indiquez un volume horaire souhaité")
+ */
+ #[ORM\Column(name: 'volumeHoraire', type: Types::JSON, nullable: true)]
+ private $volumeHoraire;
+
+ #[ORM\Column(name: 'volumeHoraireNotes', type: Types::TEXT, nullable: true)]
+ private ?string $volumeHoraireNotes = null;
+
+ #[ORM\Column(name: 'idee', type: Types::TEXT, nullable: true)]
+ private ?string $idee = null;
+
+ #[ORM\Column(name: 'enCoursConstruction', type: Types::TEXT, nullable: true)]
+ private ?string $enCoursConstruction = null;
+
+ /**
+ * @var \Doctrine\Common\Collections\Collection
+ */
+ #[ORM\JoinTable(name: 'chill_job.projetprofessionnel_valide')]
+ #[ORM\ManyToMany(targetEntity: Appellation::class)]
+ private Collection $valide;
+
+ #[ORM\Column(name: 'domaineActiviteValide', type: Types::TEXT, nullable: true)]
+ private ?string $domaineActiviteValide = null;
+
+ #[ORM\Column(name: 'valideNotes', type: Types::TEXT, nullable: true)]
+ private ?string $valideNotes = null;
+
+ #[ORM\Column(name: 'projetProfessionnelNote', type: Types::TEXT, nullable: true)]
+ private ?string $projetProfessionnelNote = null;
+
+ public function __construct()
+ {
+ $this->valide = new ArrayCollection();
+ $this->souhait = new ArrayCollection();
+ }
+
+ /**
+ * Get id.
+ *
+ * @return int
+ */
+ public function getId()
+ {
+ return $this->id;
+ }
+
+ /**
+ * Set reportDate.
+ *
+ * @param \DateTime $reportDate
+ *
+ * @return ProjetProfessionnel
+ */
+ public function setReportDate(?\DateTimeInterface $reportDate)
+ {
+ $this->reportDate = $reportDate;
+
+ return $this;
+ }
+
+ /**
+ * Get reportDate.
+ *
+ * @return \DateTimeInterface
+ */
+ public function getReportDate()
+ {
+ return $this->reportDate;
+ }
+
+ /**
+ * Set typeContrat.
+ *
+ * @param mixed|null $typeContrat
+ *
+ * @return ProjetProfessionnel
+ */
+ public function setTypeContrat($typeContrat = null)
+ {
+ $this->typeContrat = $typeContrat;
+
+ return $this;
+ }
+
+ /**
+ * Get typeContrat.
+ */
+ public function getTypeContrat()
+ {
+ return $this->typeContrat;
+ }
+
+ /**
+ * Set typeContratNotes.
+ *
+ * @return ProjetProfessionnel
+ */
+ public function setTypeContratNotes(?string $typeContratNotes = null)
+ {
+ $this->typeContratNotes = $typeContratNotes;
+
+ return $this;
+ }
+
+ /**
+ * Get typeContratNotes.
+ *
+ * @return string|null
+ */
+ public function getTypeContratNotes()
+ {
+ return $this->typeContratNotes;
+ }
+
+ /**
+ * Set volumeHoraire.
+ *
+ * @param mixed|null $volumeHoraire
+ *
+ * @return ProjetProfessionnel
+ */
+ public function setVolumeHoraire($volumeHoraire = null)
+ {
+ $this->volumeHoraire = $volumeHoraire;
+
+ return $this;
+ }
+
+ /**
+ * Get volumeHoraire.
+ */
+ public function getVolumeHoraire()
+ {
+ return $this->volumeHoraire;
+ }
+
+ /**
+ * Set volumeHoraireNotes.
+ *
+ * @return ProjetProfessionnel
+ */
+ public function setVolumeHoraireNotes(?string $volumeHoraireNotes = null)
+ {
+ $this->volumeHoraireNotes = $volumeHoraireNotes;
+
+ return $this;
+ }
+
+ /**
+ * Get volumeHoraireNotes.
+ *
+ * @return string|null
+ */
+ public function getVolumeHoraireNotes()
+ {
+ return $this->volumeHoraireNotes;
+ }
+
+ /**
+ * Set idee.
+ *
+ * @return ProjetProfessionnel
+ */
+ public function setIdee(?string $idee = null)
+ {
+ $this->idee = $idee;
+
+ return $this;
+ }
+
+ /**
+ * Get idee.
+ *
+ * @return string|null
+ */
+ public function getIdee()
+ {
+ return $this->idee;
+ }
+
+ /**
+ * Set enCoursConstruction.
+ *
+ * @return ProjetProfessionnel
+ */
+ public function setEnCoursConstruction(?string $enCoursConstruction = null)
+ {
+ $this->enCoursConstruction = $enCoursConstruction;
+
+ return $this;
+ }
+
+ /**
+ * Get enCoursConstruction.
+ *
+ * @return string|null
+ */
+ public function getEnCoursConstruction()
+ {
+ return $this->enCoursConstruction;
+ }
+
+ /**
+ * Set valideNotes.
+ *
+ * @return ProjetProfessionnel
+ */
+ public function setValideNotes(?string $valideNotes = null)
+ {
+ $this->valideNotes = $valideNotes;
+
+ return $this;
+ }
+
+ /**
+ * Get valideNotes.
+ *
+ * @return string|null
+ */
+ public function getValideNotes()
+ {
+ return $this->valideNotes;
+ }
+
+ /**
+ * Set projetProfessionnelNote.
+ *
+ * @return ProjetProfessionnel
+ */
+ public function setProjetProfessionnelNote(?string $projetProfessionnelNote = null)
+ {
+ $this->projetProfessionnelNote = $projetProfessionnelNote;
+
+ return $this;
+ }
+
+ /**
+ * Get projetProfessionnelNote.
+ *
+ * @return string|null
+ */
+ public function getProjetProfessionnelNote()
+ {
+ return $this->projetProfessionnelNote;
+ }
+
+ public function getPerson(): Person
+ {
+ return $this->person;
+ }
+
+ public function getSouhait(): Collection
+ {
+ return $this->souhait;
+ }
+
+ public function getValide(): Collection
+ {
+ return $this->valide;
+ }
+
+ public function setPerson(Person $person)
+ {
+ $this->person = $person;
+
+ return $this;
+ }
+
+ public function setSouhait(Collection $souhait)
+ {
+ $this->souhait = $souhait;
+
+ return $this;
+ }
+
+ public function addSouhait(Appellation $souhait)
+ {
+ $this->souhait->add($souhait);
+
+ return $this;
+ }
+
+ public function setValide(Collection $valide)
+ {
+ $this->valide = $valide;
+
+ return $this;
+ }
+
+ public function addValide(Appellation $valide)
+ {
+ $this->valide->add($valide);
+
+ return $this;
+ }
+
+ public function getDomaineActiviteSouhait(): ?string
+ {
+ return $this->domaineActiviteSouhait;
+ }
+
+ public function getDomaineActiviteValide(): ?string
+ {
+ return $this->domaineActiviteValide;
+ }
+
+ public function setDomaineActiviteSouhait(?string $domaineActiviteSouhait = null)
+ {
+ $this->domaineActiviteSouhait = $domaineActiviteSouhait;
+
+ return $this;
+ }
+
+ public function setDomaineActiviteValide(?string $domaineActiviteValide = null)
+ {
+ $this->domaineActiviteValide = $domaineActiviteValide;
+
+ return $this;
+ }
+
+ public function __toString(): string
+ {
+ return 'Rapport "projet professionnel" de '.$this->getPerson().' daté du '.
+ $this->getReportDate()->format('d-m-Y');
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/Entity/Rome/Appellation.php b/src/Bundle/ChillJobBundle/src/Entity/Rome/Appellation.php
new file mode 100644
index 000000000..1d2c3b026
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Entity/Rome/Appellation.php
@@ -0,0 +1,107 @@
+id;
+ }
+
+ /**
+ * Set code.
+ *
+ * @return Appellation
+ */
+ public function setCode(?string $code)
+ {
+ $this->code = $code;
+
+ return $this;
+ }
+
+ /**
+ * Get code.
+ *
+ * @return string
+ */
+ public function getCode()
+ {
+ return $this->code;
+ }
+
+ /**
+ * Set libelle.
+ *
+ * @return Appellation
+ */
+ public function setLibelle(?string $libelle)
+ {
+ $this->libelle = $libelle;
+
+ return $this;
+ }
+
+ /**
+ * Get libelle.
+ *
+ * @return string
+ */
+ public function getLibelle()
+ {
+ return $this->libelle;
+ }
+
+ public function getMetier(): Metier
+ {
+ return $this->metier;
+ }
+
+ public function setMetier(Metier $metier)
+ {
+ $this->metier = $metier;
+
+ return $this;
+ }
+
+ public function __toString(): string
+ {
+ return (string) $this->libelle;
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/Entity/Rome/Metier.php b/src/Bundle/ChillJobBundle/src/Entity/Rome/Metier.php
new file mode 100644
index 000000000..ce44a6acf
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Entity/Rome/Metier.php
@@ -0,0 +1,100 @@
+
+ */
+ #[ORM\OneToMany(targetEntity: Appellation::class, mappedBy: 'metier')]
+ private \Doctrine\Common\Collections\Collection $appellations;
+
+ public function __construct()
+ {
+ $this->appellations = new ArrayCollection();
+ // $this->appellation = new ArrayCollection();
+ }
+
+ /**
+ * Get id.
+ *
+ * @return int
+ */
+ public function getId()
+ {
+ return $this->id;
+ }
+
+ /**
+ * Set libelle.
+ *
+ * @return Metier
+ */
+ public function setLibelle(?string $libelle)
+ {
+ $this->libelle = $libelle;
+
+ return $this;
+ }
+
+ /**
+ * Get libelle.
+ *
+ * @return string
+ */
+ public function getLibelle()
+ {
+ return $this->libelle;
+ }
+
+ /**
+ * Set code.
+ *
+ * @return Metier
+ */
+ public function setCode(?string $code)
+ {
+ $this->code = $code;
+
+ return $this;
+ }
+
+ /**
+ * Get code.
+ *
+ * @return string
+ */
+ public function getCode()
+ {
+ return $this->code;
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/Export/AddCSPersonToPersonListHelper.php b/src/Bundle/ChillJobBundle/src/Export/AddCSPersonToPersonListHelper.php
new file mode 100644
index 000000000..0c27bdb32
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Export/AddCSPersonToPersonListHelper.php
@@ -0,0 +1,188 @@
+ 'ressources__'.$key, CSPerson::RESSOURCES);
+ $moyenTransport = array_map(static fn ($key) => 'moyen_transport__'.$key, CSPerson::MOBILITE_MOYEN_TRANSPORT);
+ $accompagnements = array_map(static fn ($key) => 'accompagnements__'.$key, CSPerson::ACCOMPAGNEMENTS);
+ $permisConduire = array_map(static fn ($key) => 'permis_conduire__'.$key, CSPerson::PERMIS_CONDUIRE);
+ $typeContrat = array_map(static fn ($key) => 'type_contrat__'.$key, CSPerson::TYPE_CONTRAT);
+
+ return [
+ ...$existing,
+ ...self::CSPERSON_FIELDS,
+ ...$ressources,
+ ...$moyenTransport,
+ ...$accompagnements,
+ ...$permisConduire,
+ ...$typeContrat,
+ ];
+ }
+
+ public function alterSelect(QueryBuilder $qb, \DateTimeImmutable $computedDate): void
+ {
+ $qb
+ ->leftJoin(CSPerson::class, 'cs_person', Query\Expr\Join::WITH, 'cs_person.person = person');
+
+ foreach (self::CSPERSON_FIELDS as $f) {
+ $qb->addSelect(sprintf('cs_person.%s as %s', $f, $f));
+ }
+
+ /* $qb->addSelect('cs_person.situationProfessionnelle as situation_prof');
+
+ $qb->addSelect('cs_person.nEETEligibilite as nEETEligibilite');*/
+
+ $i = 0;
+
+ foreach (CSPerson::RESSOURCES as $key) {
+ $qb->addSelect("JSONB_EXISTS_IN_ARRAY(cs_person.ressources, :param_{$i}) AS ressources__".$key)
+ ->setParameter('param_'.$i, $key);
+ ++$i;
+ }
+
+ foreach (CSPerson::MOBILITE_MOYEN_TRANSPORT as $key) {
+ $qb->addSelect("JSONB_EXISTS_IN_ARRAY(cs_person.mobiliteMoyenDeTransport, :param_{$i}) AS moyen_transport__".$key)
+ ->setParameter('param_'.$i, $key);
+ ++$i;
+ }
+
+ foreach (CSPerson::TYPE_CONTRAT as $key) {
+ $qb->addSelect("JSONB_EXISTS_IN_ARRAY(cs_person.typeContrat, :param_{$i}) AS type_contrat__".$key)
+ ->setParameter('param_'.$i, $key);
+ ++$i;
+ }
+
+ foreach (CSPerson::ACCOMPAGNEMENTS as $key) {
+ $qb->addSelect("JSONB_EXISTS_IN_ARRAY(cs_person.accompagnement, :param_{$i}) AS accompagnements__".$key)
+ ->setParameter('param_'.$i, $key);
+ ++$i;
+ }
+
+ foreach (CSPerson::PERMIS_CONDUIRE as $key) {
+ $qb->addSelect("JSONB_EXISTS_IN_ARRAY(cs_person.permisConduire, :param_{$i}) AS permis_conduire__".$key)
+ ->setParameter('param_'.$i, $key);
+ ++$i;
+ }
+ }
+
+ public function getLabels(string $key, array $values, array $data): ?callable
+ {
+ if (str_contains($key, '__')) {
+ return function (string|bool|null $value) use ($key): string {
+ if ('_header' === $value) {
+ [$domain, $v] = explode('__', $key);
+
+ return 'export.list.cs_person.'.$domain.'.'.$v;
+ }
+
+ if ('1' === $value || true === $value || 't' === $value) {
+ return 'x';
+ }
+
+ return '';
+ };
+ }
+
+ return match ($key) {
+ 'nEETEligibilite' => function (string|bool|null $value): string {
+ if ('_header' === $value) {
+ return 'export.list.cs_person.neet_eligibility';
+ }
+
+ if ('1' === $value || true === $value || 't' === $value) {
+ return 'x';
+ }
+
+ return '';
+ },
+ 'situationProfessionnelle' => function ($value) {
+ if ('_header' === $value) {
+ return 'export.list.cs_person.situation_professionelle';
+ }
+
+ return $value;
+ },
+ 'cerinscriptiondate', 'ppaeinscriptiondate', 'neetcommissiondate', 'findernieremploidate', 'cafinscriptiondate', 'contratiejdate' => function ($value) use ($key) {
+ if ('_header' === $value) {
+ return $this->translator->trans($key);
+ }
+
+ if (null === $value) {
+ return '';
+ }
+ // warning: won't work with DateTimeImmutable as we reset time a few lines later
+ $date = \DateTime::createFromFormat('Y-m-d', $value);
+ $hasTime = false;
+
+ if (false === $date) {
+ $date = \DateTime::createFromFormat('Y-m-d H:i:s', $value);
+ $hasTime = true;
+ }
+
+ // check that the creation could occur.
+ if (false === $date) {
+ throw new \Exception(sprintf('The value %s could not be converted to %s', $value, \DateTime::class));
+ }
+
+ if (!$hasTime) {
+ $date->setTime(0, 0, 0);
+ }
+
+ return $date;
+ },
+ default => function ($value) use ($key) {
+ if ('_header' === $value) {
+ return $this->translator->trans($key);
+ }
+
+ return $value;
+ },
+ };
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/Export/ListCV.php b/src/Bundle/ChillJobBundle/src/Export/ListCV.php
new file mode 100644
index 000000000..896c7db01
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Export/ListCV.php
@@ -0,0 +1,395 @@
+ 'integer',
+ 'firstname' => 'string',
+ 'lastname' => 'string',
+ 'gender' => 'string',
+ 'birthdate' => 'date',
+ 'placeofbirth' => 'string',
+ 'countryofbirth' => 'json',
+ 'formationlevel' => 'string',
+ ];
+
+ /**
+ * @var array
+ */
+ protected $personIds = [];
+
+ /**
+ * @var EntityManagerInterface
+ */
+ protected $entityManager;
+
+ /**
+ * ListAcquisition constructor.
+ */
+ public function __construct(EntityManagerInterface $em)
+ {
+ $this->entityManager = $em;
+ }
+
+ /**
+ * validate the form's data and, if required, build a contraint
+ * violation on the data.
+ *
+ * @param mixed $data the data, as returned by the user
+ */
+ public function validateForm($data, ExecutionContextInterface $context) {}
+
+ /**
+ * get a title, which will be used in UI (and translated).
+ *
+ * @return string
+ */
+ public function getTitle()
+ {
+ return 'Liste des CVs par personne';
+ }
+
+ /**
+ * Add a form to collect data from the user.
+ */
+ public function buildForm(FormBuilderInterface $builder)
+ {
+ $builder
+ ->add('fields', ChoiceType::class, [
+ 'multiple' => true,
+ 'expanded' => true,
+ // 'choices_as_values' => true,
+ 'label' => 'Fields to include in export',
+ 'choices' => array_combine($this->getFields(), $this->getFields()),
+ 'data' => array_combine($this->getFields(), $this->getFields()),
+ 'choice_attr' => [],
+ 'attr' => ['class' => ''],
+ 'constraints' => [new Callback([
+ 'callback' => function ($selected, ExecutionContextInterface $context) {
+ if (0 === count($selected)) {
+ $context
+ ->buildViolation('You must select at least one element')
+ ->atPath('fields')
+ ->addViolation();
+ }
+ },
+ ])],
+ ])
+ ->add('reportdate_min', ChillDateType::class, [
+ 'label' => 'Date du rapport après le',
+ 'required' => false,
+ 'label_attr' => [
+ 'class' => 'reportdate_range',
+ ],
+ 'attr' => [
+ 'class' => 'reportdate_range',
+ ],
+ ])
+ ->add('reportdate_max', ChillDateType::class, [
+ 'label' => 'Date du rapport avant le',
+ 'required' => false,
+ 'label_attr' => [
+ 'class' => 'report_date_range',
+ ],
+ 'attr' => [
+ 'class' => 'report_date_range',
+ ],
+ ])
+ ;
+ }
+
+ /**
+ * Return the Export's type. This will inform _on what_ export will apply.
+ * Most of the type, it will be a string which references an entity.
+ *
+ * Example of types : Chill\PersonBundle\Export\Declarations::PERSON_TYPE
+ *
+ * @return string
+ */
+ public function getType()
+ {
+ return Person::class;
+ }
+
+ /**
+ * A description, which will be used in the UI to explain what the export does.
+ * This description will be translated.
+ *
+ * @return string
+ */
+ public function getDescription()
+ {
+ return 'Crée une liste des CVs en fonction de différents paramètres.';
+ }
+
+ /**
+ * The initial query, which will be modified by ModifiersInterface
+ * (i.e. AggregatorInterface, FilterInterface).
+ *
+ * This query should take into account the `$acl` and restrict result only to
+ * what the user is allowed to see. (Do not show personal data the user
+ * is not allowed to see).
+ *
+ * The returned object should be an instance of QueryBuilder or NativeQuery.
+ *
+ * @param array $acl an array where each row has a `center` key containing the Chill\MainBundle\Entity\Center, and `circles` keys containing the reachable circles. Example: `array( array('center' => $centerA, 'circles' => array($circleA, $circleB) ) )`
+ * @param array $data the data from the form, if any
+ *
+ * @return QueryBuilder|\Doctrine\ORM\NativeQuery the query to execute
+ */
+ public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
+ {
+ return $this->entityManager->createQueryBuilder()
+ ->from('ChillPersonBundle:Person', 'person');
+ }
+
+ /**
+ * Inform which ModifiersInterface (i.e. AggregatorInterface, FilterInterface)
+ * are allowed. The modifiers should be an array of types the _modifier_ apply on
+ * (@see ModifiersInterface::applyOn()).
+ *
+ * @return string[]
+ */
+ public function supportsModifiers()
+ {
+ return ['cv', 'person'];
+ }
+
+ /**
+ * Return the required Role to execute the Export.
+ */
+ public function requiredRole(): string
+ {
+ return ExportsJobVoter::EXPORT;
+ }
+
+ /**
+ * Return which formatter type is allowed for this report.
+ *
+ * @return string[]
+ */
+ public function getAllowedFormattersTypes()
+ {
+ return [FormatterInterface::TYPE_LIST];
+ }
+
+ /**
+ * give the list of keys the current export added to the queryBuilder in
+ * self::initiateQuery.
+ *
+ * Example: if your query builder will contains `SELECT count(id) AS count_id ...`,
+ * this function will return `array('count_id')`.
+ *
+ * @param mixed[] $data the data from the export's form (added by self::buildForm)
+ *
+ * @return array
+ */
+ public function getQueryKeys($data)
+ {
+ return array_keys($data['fields']);
+ }
+
+ /**
+ * Return array FIELDS keys only.
+ *
+ * @return array
+ */
+ private function getFields()
+ {
+ return array_keys(self::FIELDS);
+ }
+
+ /**
+ * Return the results of the query builder.
+ *
+ * @param QueryBuilder|\Doctrine\ORM\NativeQuery $qb
+ * @param mixed[] $data the data from the export's form (added by self::buildForm)
+ */
+ public function getResult($qb, $data)
+ {
+ $qb->select('person.id');
+
+ $ids = $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
+ $this->personIds = array_map(fn ($e) => $e['id'], $ids);
+ $personIdsParameters = '?'.\str_repeat(', ?', count($this->personIds) - 1);
+ $query = \str_replace('%person_ids%', $personIdsParameters, self::QUERY);
+
+ $rsm = new Query\ResultSetMapping();
+
+ foreach (self::FIELDS as $name => $type) {
+ if (null !== $data['fields'][$name]) {
+ $rsm->addScalarResult($name, $name, $type);
+ }
+ }
+
+ $nq = $this->entityManager->createNativeQuery($query, $rsm);
+
+ $idx = 1;
+ for ($i = 1; $i <= count($this->personIds); ++$i) {
+ ++$idx;
+ $nq->setParameter($i, $this->personIds[$i - 1]);
+ }
+ $nq->setParameter($idx++, $data['reportdate_min'], 'date');
+ $nq->setParameter($idx, $data['reportdate_max'], 'date');
+
+ return $nq->getResult();
+ }
+
+ /**
+ * transform the results to viewable and understable string.
+ *
+ * The callable will have only one argument: the `value` to translate.
+ *
+ * The callable should also be able to return a key `_header`, which
+ * will contains the header of the column.
+ *
+ * The string returned **must** be already translated if necessary,
+ * **with an exception** for the string returned for `_header`.
+ *
+ * Example :
+ *
+ * ```
+ * protected $translator;
+ *
+ * public function getLabels($key, array $values, $data)
+ * {
+ * return function($value) {
+ * case $value
+ * {
+ * case '_header' :
+ * return 'my header not translated';
+ * case true:
+ * return $this->translator->trans('true');
+ * case false:
+ * return $this->translator->trans('false');
+ * default:
+ * // this should not happens !
+ * throw new \LogicException();
+ * }
+ * }
+ * ```
+ *
+ * **Note:** Why each string must be translated with an exception for
+ * the `_header` ? For performance reasons: most of the value will be number
+ * which do not need to be translated, or value already translated in
+ * database. But the header must be, in every case, translated.
+ *
+ * @param string $key The column key, as added in the query
+ * @param mixed[] $values The values from the result. if there are duplicates, those might be given twice. Example: array('FR', 'BE', 'CZ', 'FR', 'BE', 'FR')
+ * @param mixed $data The data from the export's form (as defined in `buildForm`
+ */
+ public function getLabels($key, array $values, $data)
+ {
+ return match ($key) {
+ 'birthdate' => function ($value) use ($key) {
+ if ('_header' === $value) {
+ return $key;
+ }
+ if (null === $value || '' === $value) {
+ return '';
+ }
+
+ return $value->format('d-m-Y');
+ },
+ 'countryofbirth' => function ($value) use ($key) {
+ if ('_header' === $value) {
+ return $key;
+ }
+
+ return $value['fr'];
+ },
+ 'gender' => function ($value) use ($key) {
+ $gend_array = ['man' => 'Homme', 'woman' => 'Femme', 'both' => 'Indéterminé'];
+ if ('_header' === $value) {
+ return $key;
+ }
+ if (null === $value || '' === $value) {
+ return '';
+ }
+
+ return $gend_array[$value];
+ },
+ default => function ($value) use ($key) {
+ if ('_header' === $value) {
+ return $key;
+ }
+
+ return $value;
+ },
+ };
+ }
+
+ /**
+ * Native Query SQL.
+ */
+ public const QUERY = <<<'SQL'
+
+SELECT
+ p.id as id,
+ p.firstname as firstname,
+ p.lastname as lastname,
+ p.gender as gender,
+ p.birthdate as birthdate,
+ p.place_of_birth as placeofbirth,
+ cn.name as countryofbirth,
+ cv.formationlevel as formationlevel
+FROM
+ public.chill_person_person AS p
+LEFT JOIN chill_job.cv AS cv
+ ON p.id = cv.person_id
+LEFT JOIN public.country AS cn
+ ON p.countryofbirth_id = cn.id
+
+-- condition 1
+WHERE p.id IN (%person_ids%)
+
+-- condition 2
+AND (
+ cv.reportdate
+ BETWEEN COALESCE(?::date, '1900-01-01')
+ AND COALESCE(?::date, '2100-01-01')
+)
+
+ORDER BY cv.reportdate DESC
+
+SQL;
+
+ public function getFormDefaultData(): array
+ {
+ return [];
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/Export/ListFrein.php b/src/Bundle/ChillJobBundle/src/Export/ListFrein.php
new file mode 100644
index 000000000..8e3a64294
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Export/ListFrein.php
@@ -0,0 +1,497 @@
+ Frein::FREINS_PERSO,
+ 'freinsemploi' => Frein::FREINS_EMPLOI,
+ ];
+
+ /**
+ * @var array
+ */
+ public const FIELDS = [
+ 'id' => 'integer',
+ 'firstname' => 'string',
+ 'lastname' => 'string',
+ 'gender' => 'string',
+ 'birthdate' => 'date',
+ 'placeofbirth' => 'string',
+ 'countryofbirth' => 'json',
+ 'reportdate' => 'date',
+ 'freinsperso' => 'json',
+ 'notesperso' => 'string',
+ 'freinsemploi' => 'json',
+ 'notesemploi' => 'string',
+ ];
+
+ /**
+ * @var array
+ */
+ protected $personIds = [];
+
+ /**
+ * @var EntityManagerInterface
+ */
+ protected $entityManager;
+
+ /**
+ * ListAcquisition constructor.
+ */
+ public function __construct(EntityManagerInterface $em)
+ {
+ $this->entityManager = $em;
+ }
+
+ /**
+ * validate the form's data and, if required, build a contraint
+ * violation on the data.
+ *
+ * @param mixed $data the data, as returned by the user
+ */
+ public function validateForm($data, ExecutionContextInterface $context) {}
+
+ /**
+ * get a title, which will be used in UI (and translated).
+ *
+ * @return string
+ */
+ public function getTitle()
+ {
+ return 'Liste des freins identifiés par personne';
+ }
+
+ /**
+ * Add a form to collect data from the user.
+ */
+ public function buildForm(FormBuilderInterface $builder)
+ {
+ $builder
+ ->add('fields', ChoiceType::class, [
+ 'multiple' => true,
+ 'expanded' => true,
+ // 'choices_as_values' => true,
+ 'label' => 'Fields to include in export',
+ 'choices' => array_combine($this->getFields(), $this->getFields()),
+ 'data' => array_combine($this->getFields(), $this->getFields()),
+ 'choice_attr' => [],
+ 'attr' => ['class' => ''],
+ 'constraints' => [new Callback([
+ 'callback' => function ($selected, ExecutionContextInterface $context) {
+ if (0 === count($selected)) {
+ $context
+ ->buildViolation('You must select at least one element')
+ ->atPath('fields')
+ ->addViolation();
+ }
+ },
+ ])],
+ ])
+ ->add('reportdate_min', ChillDateType::class, [
+ 'label' => 'Date du rapport après le',
+ 'required' => false,
+ 'label_attr' => [
+ 'class' => 'reportdate_range',
+ ],
+ 'attr' => [
+ 'class' => 'reportdate_range',
+ ],
+ ])
+ ->add('reportdate_max', ChillDateType::class, [
+ 'label' => 'Date du rapport avant le',
+ 'required' => false,
+ 'label_attr' => [
+ 'class' => 'report_date_range',
+ ],
+ 'attr' => [
+ 'class' => 'report_date_range',
+ ],
+ ])
+ ;
+ }
+
+ /**
+ * Return the Export's type. This will inform _on what_ export will apply.
+ * Most of the type, it will be a string which references an entity.
+ *
+ * Example of types : Chill\PersonBundle\Export\Declarations::PERSON_TYPE
+ *
+ * @return string
+ */
+ public function getType()
+ {
+ return Person::class;
+ }
+
+ /**
+ * A description, which will be used in the UI to explain what the export does.
+ * This description will be translated.
+ *
+ * @return string
+ */
+ public function getDescription()
+ {
+ return 'Crée une liste des personnes et de leurs freins identifiés en fonction de différents paramètres.';
+ }
+
+ /**
+ * The initial query, which will be modified by ModifiersInterface
+ * (i.e. AggregatorInterface, FilterInterface).
+ *
+ * This query should take into account the `$acl` and restrict result only to
+ * what the user is allowed to see. (Do not show personal data the user
+ * is not allowed to see).
+ *
+ * The returned object should be an instance of QueryBuilder or NativeQuery.
+ *
+ * @param array $acl an array where each row has a `center` key containing the Chill\MainBundle\Entity\Center, and `circles` keys containing the reachable circles. Example: `array( array('center' => $centerA, 'circles' => array($circleA, $circleB) ) )`
+ * @param array $data the data from the form, if any
+ *
+ * @return QueryBuilder|\Doctrine\ORM\NativeQuery the query to execute
+ */
+ public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
+ {
+ return $this->entityManager->createQueryBuilder()
+ ->from(Person::class, 'person');
+ }
+
+ /**
+ * Inform which ModifiersInterface (i.e. AggregatorInterface, FilterInterface)
+ * are allowed. The modifiers should be an array of types the _modifier_ apply on
+ * (@see ModifiersInterface::applyOn()).
+ *
+ * @return string[]
+ */
+ public function supportsModifiers()
+ {
+ return ['frein', 'person'];
+ }
+
+ /**
+ * Return the required Role to execute the Export.
+ */
+ public function requiredRole(): string
+ {
+ return ExportsJobVoter::EXPORT;
+ }
+
+ /**
+ * Return which formatter type is allowed for this report.
+ *
+ * @return string[]
+ */
+ public function getAllowedFormattersTypes()
+ {
+ return [FormatterInterface::TYPE_LIST];
+ }
+
+ /**
+ * Return array FIELDS keys only.
+ *
+ * @return array
+ */
+ private function getFields()
+ {
+ return array_keys(self::FIELDS);
+ }
+
+ /**
+ * give the list of keys the current export added to the queryBuilder in
+ * self::initiateQuery.
+ *
+ * Example: if your query builder will contains `SELECT count(id) AS count_id ...`,
+ * this function will return `array('count_id')`.
+ *
+ * @param mixed[] $data the data from the export's form (added by self::buildForm)
+ *
+ * @return array
+ */
+ public function getQueryKeys($data)
+ {
+ $freins = self::FREINS;
+ $fields = [];
+ foreach ($data['fields'] as $key) {
+ switch ($key) {
+ case 'freinsperso':
+ case 'freinsemploi':
+ foreach ($freins[$key] as $item) {
+ $this->translationCompatKey($item, $key);
+ $fields[] = $item;
+ }
+ break;
+
+ default:
+ $fields[] = $key;
+ }
+ }
+
+ return $fields;
+ }
+
+ /**
+ * Make key compatible with YAML messages ids
+ * for fields that are splitted in columns.
+ *
+ * @param string $item (&) passed by reference
+ * @param string $key
+ */
+ private function translationCompatKey(&$item, $key)
+ {
+ $prefix = substr_replace($key, 'freins_', 0, 6);
+ $item = $prefix.'.'.$item;
+ }
+
+ /**
+ * Some fields values are arrays that have to be splitted in columns.
+ * This function split theses fields.
+ *
+ * @param array $rows
+ *
+ * @return array|\Closure
+ */
+ private function splitArrayToColumns($rows)
+ {
+ $freins = self::FREINS;
+
+ $results = [];
+ foreach ($rows as $row) {
+ /**
+ * @var string $key
+ */
+ $res = [];
+ foreach ($row as $key => $value) {
+ switch ($key) {
+ case 'freinsperso':
+ case 'freinsemploi':
+ foreach ($freins[$key] as $item) {
+ $this->translationCompatKey($item, $key);
+
+ if (0 === count($value)) {
+ $res[$item] = '';
+ } else {
+ foreach ($value as $v) {
+ $this->translationCompatKey($v, $key);
+ if ($item === $v) {
+ $res[$item] = 'x';
+ break;
+ }
+ $res[$item] = '';
+ }
+ }
+ }
+ break;
+
+ default:
+ $res[$key] = $value;
+ }
+ }
+ $results[] = $res;
+ }
+
+ return $results;
+ }
+
+ /**
+ * Return the results of the query builder.
+ *
+ * @param QueryBuilder|\Doctrine\ORM\NativeQuery $qb
+ * @param mixed[] $data the data from the export's form (added by self::buildForm)
+ */
+ public function getResult($qb, $data)
+ {
+ $qb->select('person.id');
+
+ $ids = $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
+ $this->personIds = array_map(fn ($e) => $e['id'], $ids);
+ $personIdsParameters = '?'.\str_repeat(', ?', count($this->personIds) - 1);
+ $query = \str_replace('%person_ids%', $personIdsParameters, self::QUERY);
+
+ $rsm = new Query\ResultSetMapping();
+
+ foreach (self::FIELDS as $name => $type) {
+ if (null !== $data['fields'][$name]) {
+ $rsm->addScalarResult($name, $name, $type);
+ }
+ }
+
+ $nq = $this->entityManager->createNativeQuery($query, $rsm);
+
+ $idx = 1;
+ for ($i = 1; $i <= count($this->personIds); ++$i) {
+ ++$idx;
+ $nq->setParameter($i, $this->personIds[$i - 1]);
+ }
+ $nq->setParameter($idx++, $data['reportdate_min'], 'date');
+ $nq->setParameter($idx, $data['reportdate_max'], 'date');
+
+ return $this->splitArrayToColumns(
+ $nq->getResult()
+ );
+ }
+
+ /**
+ * transform the results to viewable and understable string.
+ *
+ * The callable will have only one argument: the `value` to translate.
+ *
+ * The callable should also be able to return a key `_header`, which
+ * will contains the header of the column.
+ *
+ * The string returned **must** be already translated if necessary,
+ * **with an exception** for the string returned for `_header`.
+ *
+ * Example :
+ *
+ * ```
+ * protected $translator;
+ *
+ * public function getLabels($key, array $values, $data)
+ * {
+ * return function($value) {
+ * case $value
+ * {
+ * case '_header' :
+ * return 'my header not translated';
+ * case true:
+ * return $this->translator->trans('true');
+ * case false:
+ * return $this->translator->trans('false');
+ * default:
+ * // this should not happens !
+ * throw new \LogicException();
+ * }
+ * }
+ * ```
+ *
+ * **Note:** Why each string must be translated with an exception for
+ * the `_header` ? For performance reasons: most of the value will be number
+ * which do not need to be translated, or value already translated in
+ * database. But the header must be, in every case, translated.
+ *
+ * @param string $key The column key, as added in the query
+ * @param mixed[] $values The values from the result. if there are duplicates, those might be given twice. Example: array('FR', 'BE', 'CZ', 'FR', 'BE', 'FR')
+ * @param mixed $data The data from the export's form (as defined in `buildForm`
+ */
+ public function getLabels($key, array $values, $data)
+ {
+ return match ($key) {
+ 'reportdate', 'birthdate' => function ($value) use ($key) {
+ if ('_header' === $value) {
+ return $key;
+ }
+ if (null === $value || '' === $value) {
+ return '';
+ }
+
+ return $value->format('d-m-Y');
+ },
+ 'countryofbirth' => function ($value) use ($key) {
+ if ('_header' === $value) {
+ return $key;
+ }
+
+ return $value['fr'];
+ },
+ 'gender' => function ($value) use ($key) {
+ $gend_array = ['man' => 'Homme', 'woman' => 'Femme', 'both' => 'Indéterminé'];
+ if ('_header' === $value) {
+ return $key;
+ }
+ if (null === $value || '' === $value) {
+ return '';
+ }
+
+ return $gend_array[$value];
+ },
+ default => function ($value) use ($key) {
+ if ('_header' === $value) {
+ return $key;
+ }
+ if (null === $value || '' === $value) {
+ return '';
+ }
+
+ return $value;
+ },
+ };
+ }
+
+ /**
+ * Native Query SQL.
+ */
+ public const QUERY = <<<'SQL'
+
+SELECT
+ p.id as id,
+ p.firstname as firstname,
+ p.lastname as lastname,
+ p.gender as gender,
+ p.birthdate as birthdate,
+ p.place_of_birth as placeofbirth,
+ cn.name as countryofbirth,
+ fr.reportdate as reportdate,
+ fr.freinsperso as freinsperso,
+ fr.notesperso as notesperso,
+ fr.freinsemploi as freinsemploi,
+ fr.notesemploi as notesemploi
+FROM
+ public.chill_person_person AS p
+LEFT JOIN chill_job.frein AS fr
+ ON p.id = fr.person_id
+LEFT JOIN public.country AS cn
+ ON p.countryofbirth_id = cn.id
+
+-- condition 1
+WHERE p.id IN (%person_ids%)
+
+-- condition 2
+AND (
+ fr.reportdate
+ BETWEEN COALESCE(?::date, '1900-01-01')
+ AND COALESCE(?::date, '2100-01-01')
+)
+
+ORDER BY fr.reportdate DESC
+
+SQL;
+
+ public function getFormDefaultData(): array
+ {
+ return [];
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/Export/ListProjetProfessionnel.php b/src/Bundle/ChillJobBundle/src/Export/ListProjetProfessionnel.php
new file mode 100644
index 000000000..0a1eeb753
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Export/ListProjetProfessionnel.php
@@ -0,0 +1,586 @@
+ ProjetProfessionnel::TYPE_CONTRAT,
+ 'projet_prof__volume_horaire__label' => ProjetProfessionnel::VOLUME_HORAIRES,
+ ];
+
+ /**
+ * @var array
+ */
+ public const FIELDS = [
+ 'id' => 'integer',
+ 'firstname' => 'string',
+ 'lastname' => 'string',
+ 'gender' => 'string',
+ 'birthdate' => 'date',
+ 'placeofbirth' => 'string',
+ 'countryofbirth' => 'json',
+ 'projet_prof__souhait__code' => 'string',
+ 'projet_prof__type_contrat__label' => 'json',
+ 'projet_prof__type_contrat__note' => 'string',
+ 'projet_prof__volume_horaire__label' => 'json',
+ 'projet_prof__volume_horaire__note' => 'string',
+ 'projet_prof__idee' => 'string',
+ 'projet_prof__encoursdeconstruction' => 'string',
+ 'projet_prof__valide__note' => 'string',
+ 'projet_prof__valide__code' => 'string',
+ 'projet_prof__note' => 'string',
+ ];
+
+ /**
+ * @var array
+ */
+ protected $personIds = [];
+
+ /**
+ * @var EntityManagerInterface
+ */
+ protected $entityManager;
+
+ /**
+ * ListAcquisition constructor.
+ */
+ public function __construct(EntityManagerInterface $em)
+ {
+ $this->entityManager = $em;
+ }
+
+ /**
+ * validate the form's data and, if required, build a contraint
+ * violation on the data.
+ *
+ * @param mixed $data the data, as returned by the user
+ */
+ public function validateForm($data, ExecutionContextInterface $context) {}
+
+ /**
+ * get a title, which will be used in UI (and translated).
+ *
+ * @return string
+ */
+ public function getTitle()
+ {
+ return 'Liste des projets professionnels par personne';
+ }
+
+ /**
+ * Add a form to collect data from the user.
+ */
+ public function buildForm(FormBuilderInterface $builder)
+ {
+ $builder
+ ->add('fields', ChoiceType::class, [
+ 'multiple' => true,
+ 'expanded' => true,
+ // 'choices_as_values' => true,
+ 'label' => 'Fields to include in export',
+ 'choice_label' => fn ($key) => str_replace('__', '.', (string) $key),
+ 'choices' => array_combine($this->getFields(), $this->getFields()),
+ 'data' => array_combine($this->getFields(), $this->getFields()),
+ 'choice_attr' => [],
+ 'attr' => ['class' => ''],
+ 'constraints' => [new Callback([
+ 'callback' => function ($selected, ExecutionContextInterface $context) {
+ if (0 === count($selected)) {
+ $context
+ ->buildViolation('You must select at least one element')
+ ->atPath('fields')
+ ->addViolation();
+ }
+ },
+ ])],
+ ])
+ ->add('reportdate_min', ChillDateType::class, [
+ 'label' => 'Date du rapport après le',
+ 'required' => false,
+ 'label_attr' => [
+ 'class' => 'reportdate_range',
+ ],
+ 'attr' => [
+ 'class' => 'reportdate_range',
+ ],
+ ])
+ ->add('reportdate_max', ChillDateType::class, [
+ 'label' => 'Date du rapport avant le',
+ 'required' => false,
+ 'label_attr' => [
+ 'class' => 'report_date_range',
+ ],
+ 'attr' => [
+ 'class' => 'report_date_range',
+ ],
+ ])
+ ;
+ }
+
+ /**
+ * Return the Export's type. This will inform _on what_ export will apply.
+ * Most of the type, it will be a string which references an entity.
+ *
+ * Example of types : Chill\PersonBundle\Export\Declarations::PERSON_TYPE
+ *
+ * @return string
+ */
+ public function getType()
+ {
+ return Person::class;
+ }
+
+ /**
+ * A description, which will be used in the UI to explain what the export does.
+ * This description will be translated.
+ *
+ * @return string
+ */
+ public function getDescription()
+ {
+ return 'Crée une liste des personnes et de leur projet professionnel en fonction de différents paramètres.';
+ }
+
+ /**
+ * The initial query, which will be modified by ModifiersInterface
+ * (i.e. AggregatorInterface, FilterInterface).
+ *
+ * This query should take into account the `$acl` and restrict result only to
+ * what the user is allowed to see. (Do not show personal data the user
+ * is not allowed to see).
+ *
+ * The returned object should be an instance of QueryBuilder or NativeQuery.
+ *
+ * @param array $acl an array where each row has a `center` key containing the Chill\MainBundle\Entity\Center, and `circles` keys containing the reachable circles. Example: `array( array('center' => $centerA, 'circles' => array($circleA, $circleB) ) )`
+ * @param array $data the data from the form, if any
+ *
+ * @return QueryBuilder|\Doctrine\ORM\NativeQuery the query to execute
+ */
+ public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
+ {
+ return $this->entityManager->createQueryBuilder()
+ ->from('ChillPersonBundle:Person', 'person');
+ }
+
+ /**
+ * Inform which ModifiersInterface (i.e. AggregatorInterface, FilterInterface)
+ * are allowed. The modifiers should be an array of types the _modifier_ apply on
+ * (@see ModifiersInterface::applyOn()).
+ *
+ * @return string[]
+ */
+ public function supportsModifiers()
+ {
+ return ['projetprofessionnel', 'person'];
+ }
+
+ /**
+ * Return the required Role to execute the Export.
+ */
+ public function requiredRole(): string
+ {
+ return ExportsJobVoter::EXPORT;
+ }
+
+ /**
+ * Return which formatter type is allowed for this report.
+ *
+ * @return string[]
+ */
+ public function getAllowedFormattersTypes()
+ {
+ return [FormatterInterface::TYPE_LIST];
+ }
+
+ /**
+ * Return array FIELDS keys only.
+ *
+ * @return array
+ */
+ private function getFields()
+ {
+ return array_keys(self::FIELDS);
+ }
+
+ /**
+ * give the list of keys the current export added to the queryBuilder in
+ * self::initiateQuery.
+ *
+ * Example: if your query builder will contains `SELECT count(id) AS count_id ...`,
+ * this function will return `array('count_id')`.
+ *
+ * @param mixed[] $data the data from the export's form (added by self::buildForm)
+ *
+ * @return array
+ */
+ public function getQueryKeys($data)
+ {
+ $projet_professionnel = self::PPROF;
+
+ $fields = [];
+ foreach ($data['fields'] as $key) {
+ switch ($key) {
+ case 'projet_prof__type_contrat__label':
+ case 'projet_prof__volume_horaire__label':
+ foreach ($projet_professionnel[$key] as $item) {
+ $this->translationCompatKey($item, $key);
+ $fields[] = $item;
+ }
+ break;
+
+ case 'projet_prof__souhait__code':
+ case 'projet_prof__type_contrat__note':
+ case 'projet_prof__volume_horaire__note':
+ case 'projet_prof__idee':
+ case 'projet_prof__encoursdeconstruction':
+ case 'projet_prof__valide__note':
+ case 'projet_prof__valide__code':
+ case 'projet_prof__note':
+ $key = str_replace('__', '.', (string) $key);
+
+ // no break
+ default:
+ $fields[] = $key;
+ }
+ }
+
+ return $fields;
+ }
+
+ /**
+ * Make item compatible with YAML messages ids
+ * for fields that are splitted in columns (with field key to replace).
+ *
+ * AVANT
+ * key: projet_prof__volume_horaire__label
+ * item: temps_plein
+ * APRES
+ * item: projet_prof.volume_horaire.temps_plein
+ *
+ * @param string $item (&) passed by reference
+ * @param string $key
+ */
+ private function translationCompatKey(&$item, $key)
+ {
+ $key = str_replace('label', $item, $key);
+ $key = str_replace('__', '.', $key);
+ $item = $key;
+ }
+
+ /**
+ * Some fields values are arrays that have to be splitted in columns.
+ * This function split theses fields.
+ *
+ * @param array $rows
+ *
+ * @return array|\Closure
+ */
+ private function splitArrayToColumns($rows)
+ {
+ $projet_professionnel = self::PPROF;
+
+ $results = [];
+
+ foreach ($rows as $row) {
+ /**
+ * @var string $key
+ */
+ $res = [];
+ foreach ($row as $key => $value) {
+ switch ($key) {
+ case 'projet_prof__type_contrat__label':
+ case 'projet_prof__volume_horaire__label':
+ foreach ($projet_professionnel[$key] as $item) {
+ $this->translationCompatKey($item, $key);
+
+ if (0 === count($value)) {
+ $res[$item] = '';
+ } else {
+ foreach ($value as $v) {
+ $this->translationCompatKey($v, $key);
+
+ if ($item === $v) {
+ $res[$item] = 'x';
+ break;
+ }
+ $res[$item] = '';
+ }
+ }
+ }
+ break;
+
+ case 'projet_prof__souhait__code':
+ case 'projet_prof__type_contrat__note':
+ case 'projet_prof__volume_horaire__note':
+ case 'projet_prof__idee':
+ case 'projet_prof__encoursdeconstruction':
+ case 'projet_prof__valide__note':
+ case 'projet_prof__valide__code':
+ case 'projet_prof__note':
+ $key = str_replace('__', '.', (string) $key);
+
+ // no break
+ default:
+ $res[$key] = $value;
+ }
+ }
+ $results[] = $res;
+ }
+
+ return $results;
+ }
+
+ /**
+ * Return the results of the query builder.
+ *
+ * @param QueryBuilder|\Doctrine\ORM\NativeQuery $qb
+ * @param mixed[] $data the data from the export's form (added by self::buildForm)
+ */
+ public function getResult($qb, $data)
+ {
+ $qb->select('person.id');
+
+ $ids = $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
+ $this->personIds = array_map(fn ($e) => $e['id'], $ids);
+ $personIdsParameters = '?'.\str_repeat(', ?', count($this->personIds) - 1);
+ $query = \str_replace('%person_ids%', $personIdsParameters, self::QUERY);
+
+ $rsm = new Query\ResultSetMapping();
+
+ foreach (self::FIELDS as $name => $type) {
+ if (null !== $data['fields'][$name]) {
+ $rsm->addScalarResult($name, $name, $type);
+ }
+ }
+
+ $nq = $this->entityManager->createNativeQuery($query, $rsm);
+
+ $idx = 1;
+ for ($i = 1; $i <= count($this->personIds); ++$i) {
+ ++$idx;
+ $nq->setParameter($i, $this->personIds[$i - 1]);
+ }
+ $nq->setParameter($idx++, $data['reportdate_min'], 'date');
+ $nq->setParameter($idx, $data['reportdate_max'], 'date');
+
+ return $this->splitArrayToColumns(
+ $nq->getResult()
+ );
+ }
+
+ /**
+ * transform the results to viewable and understable string.
+ *
+ * The callable will have only one argument: the `value` to translate.
+ *
+ * The callable should also be able to return a key `_header`, which
+ * will contains the header of the column.
+ *
+ * The string returned **must** be already translated if necessary,
+ * **with an exception** for the string returned for `_header`.
+ *
+ * Example :
+ *
+ * ```
+ * protected $translator;
+ *
+ * public function getLabels($key, array $values, $data)
+ * {
+ * return function($value) {
+ * case $value
+ * {
+ * case '_header' :
+ * return 'my header not translated';
+ * case true:
+ * return $this->translator->trans('true');
+ * case false:
+ * return $this->translator->trans('false');
+ * default:
+ * // this should not happens !
+ * throw new \LogicException();
+ * }
+ * }
+ * ```
+ *
+ * **Note:** Why each string must be translated with an exception for
+ * the `_header` ? For performance reasons: most of the value will be number
+ * which do not need to be translated, or value already translated in
+ * database. But the header must be, in every case, translated.
+ *
+ * @param string $key The column key, as added in the query
+ * @param mixed[] $values The values from the result. if there are duplicates, those might be given twice. Example: array('FR', 'BE', 'CZ', 'FR', 'BE', 'FR')
+ * @param mixed $data The data from the export's form (as defined in `buildForm`
+ */
+ public function getLabels($key, array $values, $data)
+ {
+ return match ($key) {
+ 'birthdate' => function ($value) use ($key) {
+ if ('_header' === $value) {
+ return $key;
+ }
+ if (null === $value || '' === $value) {
+ return '';
+ }
+
+ return $value->format('d-m-Y');
+ },
+ 'countryofbirth' => function ($value) use ($key) {
+ if ('_header' === $value) {
+ return $key;
+ }
+
+ return $value['fr'];
+ },
+ 'projet_prof.valide.code', 'projet_prof.souhait.code' => function ($value) use ($key) {
+ if ('_header' === $value) {
+ return $key;
+ }
+ if ('{NULL}' === $value) {
+ return '';
+ }
+
+ return str_replace(['{', '}'], '', $value);
+ },
+ 'gender' => function ($value) use ($key) {
+ $gend_array = ['man' => 'Homme', 'woman' => 'Femme', 'both' => 'Indéterminé'];
+ if ('_header' === $value) {
+ return $key;
+ }
+ if (null === $value || '' === $value) {
+ return '';
+ }
+
+ return $gend_array[$value];
+ },
+ default => function ($value) use ($key) {
+ if ('_header' === $value) {
+ return $key;
+ }
+ if (null === $value || '' === $value) {
+ return '';
+ }
+
+ return $value;
+ },
+ };
+ }
+
+ /**
+ * Native Query SQL.
+ */
+ public const QUERY = <<<'SQL'
+
+WITH projet_professionnel AS (
+
+ SELECT
+ pp.id,
+ pp.reportdate,
+ pp.typecontrat,
+ pp.typecontratnotes,
+ pp.volumehoraire,
+ pp.volumehorairenotes,
+ pp.idee,
+ pp.encoursconstruction,
+ pp.validenotes,
+ pp.projetprofessionnelnote,
+ ARRAY_AGG (DISTINCT rms.code) as rms_codes,
+ ARRAY_AGG (DISTINCT rmv.code) as rmv_codes
+
+ FROM chill_job.projet_professionnel AS pp
+
+ LEFT OUTER JOIN chill_job.projetprofessionnel_souhait AS pps
+ ON pp.id = pps.projetprofessionnel_id
+ LEFT OUTER JOIN chill_job.rome_appellation AS ras
+ ON pps.appellation_id = ras.id
+ LEFT OUTER JOIN chill_job.rome_metier AS rms
+ ON ras.metier_id = rms.id
+ LEFT OUTER JOIN chill_job.projetprofessionnel_valide AS ppv
+ ON pp.id = ppv.projetprofessionnel_id
+ LEFT OUTER JOIN chill_job.rome_appellation AS rav
+ ON ppv.appellation_id = rav.id
+ LEFT OUTER JOIN chill_job.rome_metier AS rmv
+ ON rav.metier_id = rmv.id
+
+ GROUP BY pp.id
+)
+
+SELECT
+ p.id,
+ p.firstname,
+ p.lastname,
+ p.gender as gender,
+ p.birthdate as birthdate,
+ p.place_of_birth as placeofbirth,
+ cn.name as countryofbirth,
+ pp.rms_codes as projet_prof__souhait__code,
+ pp.typecontrat as projet_prof__type_contrat__label,
+ pp.typecontratnotes as projet_prof__type_contrat__note,
+ pp.volumehoraire as projet_prof__volume_horaire__label,
+ pp.volumehorairenotes as projet_prof__volume_horaire__note,
+ pp.idee as projet_prof__idee,
+ pp.encoursconstruction as projet_prof__encoursdeconstruction,
+ pp.validenotes as projet_prof__valide__note,
+ pp.rmv_codes as projet_prof__valide__code,
+ pp.projetprofessionnelnote as projet_prof__note
+
+FROM public.chill_person_person AS p
+
+ LEFT JOIN projet_professionnel AS pp
+ ON p.id = pp.id
+
+ LEFT OUTER JOIN public.country AS cn
+ ON p.countryofbirth_id = cn.id
+
+-- condition 1
+WHERE p.id IN (%person_ids%)
+
+-- condition 2
+AND (
+ pp.reportdate
+ BETWEEN COALESCE(?::date, '1900-01-01')
+ AND COALESCE(?::date, '2100-01-01')
+)
+
+ORDER BY pp.reportdate DESC
+
+SQL;
+
+ public function getFormDefaultData(): array
+ {
+ return [];
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/Form/CSPersonDispositifsType.php b/src/Bundle/ChillJobBundle/src/Form/CSPersonDispositifsType.php
new file mode 100644
index 000000000..187c5f656
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Form/CSPersonDispositifsType.php
@@ -0,0 +1,125 @@
+add('accompagnement', ChoiceType::class, [
+ 'choices' => \array_combine(CSPerson::ACCOMPAGNEMENTS, CSPerson::ACCOMPAGNEMENTS),
+ 'required' => false,
+ 'label' => 'Accompagnement',
+ 'multiple' => true,
+ 'expanded' => true,
+ 'choice_label' => fn ($k) => 'accompagnement.'.$k,
+ ])
+ ->add('accompagnementRQTHDate', ChillDateType::class, [
+ 'label' => "Date d'accompagnement RQTH",
+ 'required' => false,
+ ])
+ ->add('accompagnementComment', TextareaType::class, [
+ 'label' => 'Accompagnement autre: précisions',
+ 'required' => false,
+ ])
+ ->add('poleEmploiId', TextType::class, [
+ 'label' => 'Identifiant pôle emploi',
+ 'required' => false,
+ ])
+ ->add('poleEmploiInscriptionDate', ChillDateType::class, [
+ 'label' => "Date d'inscription Pôle emploi",
+ 'required' => false,
+ ])
+ ->add('cafId', TextType::class, [
+ 'label' => 'Numéro allocataire CAF',
+ 'required' => false,
+ ])
+ ->add('cafInscriptionDate', ChillDateType::class, [
+ 'label' => "Date d'inscription à la CAF",
+ 'required' => false,
+ ])
+ ->add('cERInscriptionDate', ChillDateType::class, [
+ 'label' => 'Date CER',
+ 'required' => false,
+ ])
+ ->add('pPAEInscriptionDate', ChillDateType::class, [
+ 'label' => 'Date PPAE',
+ 'required' => false,
+ ])
+ ->add('nEETEligibilite', ChoiceType::class, [
+ 'label' => 'Éligibilité NEET',
+ 'choices' => \array_combine(CSPerson::NEET_ELIGIBILITY, CSPerson::NEET_ELIGIBILITY),
+ 'choice_label' => fn ($k) => 'neet_eligibility.'.$k,
+ 'multiple' => false,
+ 'expanded' => true,
+ 'required' => false,
+ ])
+ ->add('cERSignataire', TextType::class, [
+ 'label' => 'Signataire CER',
+ 'required' => false,
+ ])
+ ->add('pPAESignataire', TextType::class, [
+ 'label' => 'Signataire PPAE',
+ 'required' => false,
+ ])
+ ->add('nEETCommissionDate', ChillDateType::class, [
+ 'label' => 'Date commission NEET',
+ 'required' => false,
+ ])
+ ->add('fSEMaDemarcheCode', TextType::class, [
+ 'label' => 'Code "Ma démarche FSE"',
+ 'required' => false,
+ ])
+ ->add('prescripteur', PickThirdpartyDynamicType::class, [
+ 'required' => false,
+ 'label' => 'Prescripteur',
+ ])
+ ->add('dispositifsNotes', TextareaType::class, [
+ 'required' => false,
+ 'label' => 'Notes',
+ ])
+ ->add('dateContratIEJ', ChillDateType::class, [
+ 'required' => false,
+ 'label' => ' Date du contrat d’engagement IEJ',
+ ])
+ ->add('dateAvenantIEJ', ChillDateType::class, [
+ 'required' => false,
+ 'label' => " Date de l'avenant IEJ",
+ ]);
+ }
+
+ public function configureOptions(OptionsResolver $resolver)
+ {
+ $resolver->setDefaults(['data_class' => CSPerson::class]);
+
+ $resolver
+ ->setDefined('center')
+ ->setAllowedTypes('center', [\Chill\MainBundle\Entity\Center::class])
+ ;
+ }
+
+ public function getBlockPrefix()
+ {
+ return 'job_bundle_csperson';
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/Form/CSPersonPersonalSituationType.php b/src/Bundle/ChillJobBundle/src/Form/CSPersonPersonalSituationType.php
new file mode 100644
index 000000000..ba04d8b0f
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Form/CSPersonPersonalSituationType.php
@@ -0,0 +1,256 @@
+add('personMaritalStatus', Select2MaritalStatusType::class, ['required' => false, 'label' => 'État civil'])
+ ->add('situationLogement', ChoiceType::class, [
+ 'choices' => \array_combine(
+ CSPerson::SITUATIONS_LOGEMENTS,
+ CSPerson::SITUATIONS_LOGEMENTS
+ ),
+ 'choice_label' => fn ($k) => 'situation_logement.'.$k,
+ 'required' => false,
+ 'label' => 'Situation de logement',
+ 'multiple' => false,
+ 'expanded' => true,
+ ])
+ ->add('situationLogementPrecision', TextareaType::class, [
+ 'label' => 'Précisions',
+ 'required' => false,
+ ])
+ ->add('enfantACharge', IntegerType::class, [
+ 'label' => 'Enfants à charge',
+ 'required' => false,
+ ])
+ ->add('niveauMaitriseLangue', ChoiceType::class, [
+ 'choices' => \array_combine(
+ CSPerson::NIVEAU_MAITRISE_LANGUE,
+ CSPerson::NIVEAU_MAITRISE_LANGUE
+ ),
+ 'choice_label' => fn ($k) => 'niveau_maitrise_langue.'.$k,
+ 'multiple' => true,
+ 'required' => false,
+ 'expanded' => true,
+ 'label' => 'Maitrise de la langue française',
+ ])
+ ->add('vehiculePersonnel', ChoiceType::class, [
+ 'choices' => [
+ 'Oui' => true,
+ 'Non' => false,
+ ],
+ 'required' => false,
+ 'multiple' => false,
+ ])
+ ->add('permisConduire', ChoiceType::class, [
+ 'choices' => [
+ \array_combine(CSPerson::PERMIS_CONDUIRE, CSPerson::PERMIS_CONDUIRE),
+ ],
+ 'label' => 'Permis de conduire',
+ 'required' => false,
+ 'multiple' => true,
+ 'expanded' => true,
+ 'choice_label' => fn ($k) => 'permis_conduire.'.$k,
+ ])
+ ->add('situationProfessionnelle', ChoiceType::class, [
+ 'choices' => \array_combine(CSPerson::SITUATION_PROFESSIONNELLE, CSPerson::SITUATION_PROFESSIONNELLE),
+ 'required' => false,
+ 'multiple' => false,
+ 'expanded' => true,
+ 'choice_label' => fn ($k) => 'situation_professionnelle.'.$k,
+ ])
+ ->add('dateFinDernierEmploi', ChillDateType::class, [
+ 'label' => 'Date de la fin du dernier emploi',
+ 'required' => false,
+ ])
+ ->add('typeContrat', ChoiceType::class, [
+ 'choices' => \array_combine(CSPerson::TYPE_CONTRAT, CSPerson::TYPE_CONTRAT),
+ 'label' => 'Type de contrat',
+ 'required' => false,
+ 'multiple' => true,
+ 'expanded' => true,
+ 'choice_label' => fn ($k) => 'type_contrat.'.$k,
+ ])
+ ->add('typeContratAide', TextType::class, [
+ 'label' => 'Type de contrat aidé',
+ 'required' => false,
+ ])
+ ->add('ressources', ChoiceType::class, [
+ 'choices' => \array_combine(CSPerson::RESSOURCES, CSPerson::RESSOURCES),
+ 'choice_label' => fn ($k) => 'ressource.'.$k,
+ 'required' => false,
+ 'multiple' => true,
+ 'expanded' => true,
+ ])
+ ->add('ressourcesComment', TextareaType::class, [
+ 'label' => 'Information autre ressource',
+ 'required' => false,
+ ])
+ ->add('ressourceDate1Versement', ChillDateType::class, [
+ 'label' => "Date du premier versement (si bénéficiaire d'une aide)",
+ 'required' => false,
+ ])
+ ->add('cPFMontant', MoneyType::class, [
+ 'label' => 'Montant CPF',
+ 'required' => false,
+ ])
+ ->add('acompteDIF', MoneyType::class, [
+ 'label' => 'Compte DIF',
+ 'required' => false,
+ ])
+ ->add('handicapIs', ChoiceType::class, [
+ 'label' => 'Handicap',
+ 'required' => false,
+ 'choices' => [
+ 'Oui' => true,
+ 'Non' => false,
+ ],
+ 'multiple' => false,
+ 'expanded' => true,
+ ])
+ ->add('handicapNotes', TextareaType::class, [
+ 'label' => 'Type de handicap',
+ 'required' => false,
+ ])
+ ->add('handicapRecommandation', ChoiceType::class, [
+ 'label' => 'Recommandation',
+ 'required' => false,
+ 'multiple' => false,
+ 'expanded' => true,
+ 'choices' => \array_combine(CSPerson::HANDICAP_RECOMMANDATIONS, CSPerson::HANDICAP_RECOMMANDATIONS),
+ 'choice_label' => fn ($k) => 'handicap_recommandation.'.$k,
+ ])
+ ->add('handicapAccompagnement', PickThirdpartyDynamicType::class, [
+ 'required' => false,
+ 'multiple' => false,
+ ])
+ ->add('mobiliteMoyenDeTransport', ChoiceType::class, [
+ 'required' => false,
+ 'multiple' => true,
+ 'expanded' => true,
+ 'label' => 'Moyens de transports accessibles',
+ 'choices' => \array_combine(
+ CSPerson::MOBILITE_MOYEN_TRANSPORT,
+ CSPerson::MOBILITE_MOYEN_TRANSPORT
+ ),
+ 'choice_label' => fn ($k) => 'moyen_transport.'.$k,
+ ])
+ ->add('mobiliteNotes', TextareaType::class, [
+ 'required' => false,
+ 'label' => 'Notes concernant la mobilité',
+ ])
+ ->add('documentCV', StoredObjectType::class, [
+ 'label' => 'CV',
+ 'required' => false,
+ 'error_bubbling' => false,
+ ])
+ ->add('documentAgrementIAE', StoredObjectType::class, [
+ 'label' => 'Document Agrément IAE',
+ 'required' => false,
+ 'error_bubbling' => false,
+ ])
+ ->add('documentRQTH', StoredObjectType::class, [
+ 'label' => 'Document RQTH',
+ 'required' => false,
+ 'error_bubbling' => false,
+ ])
+ ->add('documentAttestationNEET', StoredObjectType::class, [
+ 'label' => 'Attestation NEET',
+ 'required' => false,
+ 'error_bubbling' => false,
+ ])
+ ->add('documentCI', StoredObjectType::class, [
+ 'label' => 'Carte d\'identité',
+ 'required' => false,
+ 'error_bubbling' => false,
+ ])
+ ->add('documentTitreSejour', StoredObjectType::class, [
+ 'label' => 'Titre de séjour',
+ 'required' => false,
+ 'error_bubbling' => false,
+ ])
+ ->add('documentAttestationFiscale', StoredObjectType::class, [
+ 'label' => 'Attestation fiscale',
+ 'required' => false,
+ 'error_bubbling' => false,
+ ])
+ ->add('documentPermis', StoredObjectType::class, [
+ 'label' => 'Permis',
+ 'required' => false,
+ 'error_bubbling' => false,
+ ])
+ ->add('documentAttestationCAAF', StoredObjectType::class, [
+ 'label' => 'Attestation CAF',
+ 'required' => false,
+ 'error_bubbling' => false,
+ ])
+ ->add('documentContraTravail', StoredObjectType::class, [
+ 'label' => 'Contrat de travail',
+ 'required' => false,
+ 'error_bubbling' => false,
+ ])
+ ->add('documentAttestationFormation', StoredObjectType::class, [
+ 'label' => 'Attestation formation',
+ 'required' => false,
+ 'error_bubbling' => false,
+ ])
+ ->add('documentQuittanceLoyer', StoredObjectType::class, [
+ 'label' => 'Quittance de loyer',
+ 'required' => false,
+ 'error_bubbling' => false,
+ ])
+ ->add('documentFactureElectricite', StoredObjectType::class, [
+ 'label' => 'Facture d\'électricité',
+ 'required' => false,
+ 'error_bubbling' => false,
+ ])
+ ->add('documentAttestationSecuriteSociale', StoredObjectType::class, [
+ 'label' => 'Attestation de sécurité sociale',
+ 'required' => false,
+ 'error_bubbling' => false,
+ ])
+ ;
+ }
+
+ public function configureOptions(OptionsResolver $resolver)
+ {
+ $resolver->setDefaults(['data_class' => CSPerson::class]);
+
+ $resolver->setRequired('center')
+ ->setAllowedTypes('center', [\Chill\MainBundle\Entity\Center::class])
+ ;
+ }
+
+ public function getBlockPrefix()
+ {
+ return 'job_bundle_csperson';
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/Form/CV/ExperienceType.php b/src/Bundle/ChillJobBundle/src/Form/CV/ExperienceType.php
new file mode 100644
index 000000000..de74f2a22
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Form/CV/ExperienceType.php
@@ -0,0 +1,70 @@
+add('poste', TextType::class, [
+ 'required' => true,
+ 'label' => 'Poste',
+ 'label_attr' => [
+ 'class' => 'required ',
+ ],
+ ])
+ ->add('structure', TextType::class, [
+ 'required' => false,
+ 'label' => 'Nom de la structure',
+ ])
+ ->add('startDate', ChillDateType::class, [
+ 'required' => false,
+ 'label' => 'Date de début',
+ ])
+ ->add('endDate', ChillDateType::class, [
+ 'required' => false,
+ 'label' => 'Date de fin',
+ ])
+ ->add('contratType', ChoiceType::class, [
+ 'required' => false,
+ 'expanded' => true,
+ 'multiple' => false,
+ 'choices' => \array_combine(Experience::CONTRAT_TYPE, Experience::CONTRAT_TYPE),
+ 'choice_label' => fn ($k) => 'xp_contrat_type.'.$k,
+ ])
+ ->add('notes', TextareaType::class, [
+ 'label' => 'Notes',
+ 'required' => false,
+ ])
+ ;
+ }
+
+ public function configureOptions(OptionsResolver $resolver)
+ {
+ $resolver->setDefaults(['data_class' => Experience::class]);
+ }
+
+ public function getBlockPrefix()
+ {
+ return 'job_bundle_cv_experience';
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/Form/CV/FormationType.php b/src/Bundle/ChillJobBundle/src/Form/CV/FormationType.php
new file mode 100644
index 000000000..83093d95b
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Form/CV/FormationType.php
@@ -0,0 +1,75 @@
+add('title', TextType::class, [
+ 'required' => true,
+ 'label' => 'Nom de la formation',
+ 'label_attr' => [
+ 'class' => 'required ',
+ ],
+ ])
+ ->add('organisme', TextType::class, [
+ 'label' => 'Organisme',
+ 'required' => false,
+ ])
+ ->add('startDate', ChillDateType::class, [
+ 'required' => false,
+ 'label' => 'Date de début',
+ ])
+ ->add('endDate', ChillDateType::class, [
+ 'required' => false,
+ 'label' => 'Date de fin',
+ ])
+ ->add('diplomaObtained', ChoiceType::class, [
+ 'label' => 'Diplôme obtenu ?',
+ 'required' => false,
+ 'multiple' => false,
+ 'expanded' => true,
+ 'choices' => \array_combine(F::DIPLOMA_OBTAINED, F::DIPLOMA_OBTAINED),
+ 'choice_label' => fn ($k) => 'diploma_obtained.'.$k,
+ ])
+ ->add('diplomaReconnue', ChoiceType::class, [
+ 'label' => 'Diplôme reconnu en France ?',
+ 'required' => false,
+ 'multiple' => false,
+ 'expanded' => true,
+ 'choices' => \array_combine(F::DIPLOMA_RECONNU, F::DIPLOMA_RECONNU),
+ 'choice_label' => fn ($k) => 'diploma_reconnu.'.$k,
+ ])
+
+ ;
+ }
+
+ public function configureOptions(OptionsResolver $resolver)
+ {
+ $resolver->setDefaults(['data_class' => F::class]);
+ }
+
+ public function getBlockPrefix()
+ {
+ return 'job_bundle_cv_formation';
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/Form/CVType.php b/src/Bundle/ChillJobBundle/src/Form/CVType.php
new file mode 100644
index 000000000..c6fb6614d
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Form/CVType.php
@@ -0,0 +1,91 @@
+add('reportDate', ChillDateType::class, [
+ 'label' => 'Date de rédaction du CV',
+ ])
+ ->add('formationLevel', ChoiceType::class, [
+ 'label' => 'Niveau de formation',
+ 'required' => true,
+ 'multiple' => false,
+ 'expanded' => true,
+ 'choices' => \array_combine(CV::FORMATION_LEVEL, CV::FORMATION_LEVEL),
+ 'choice_label' => fn ($k) => 'formation_level.'.$k,
+ ])
+ ->add('formationType', ChoiceType::class, [
+ 'label' => 'Type de formation',
+ 'required' => false,
+ 'multiple' => false,
+ 'expanded' => true,
+ 'choices' => \array_combine(CV::FORMATION_TYPE, CV::FORMATION_TYPE),
+ 'choice_label' => fn ($k) => 'formation_type.'.$k,
+ ])
+ ->add('spokenLanguages', Select2LanguageType::class, [
+ 'required' => false,
+ 'multiple' => true,
+ ])
+ ->add('notes', TextareaType::class, [
+ 'label' => 'Note',
+ 'required' => false,
+ ])
+ ->add('formations', ChillCollectionType::class, [
+ 'label' => 'Formations',
+ 'entry_type' => FormationType::class,
+ 'allow_add' => true,
+ 'allow_delete' => true,
+ 'button_add_label' => 'Ajouter une formation',
+ 'button_remove_label' => 'Retirer cette formation',
+ 'required' => false,
+ 'by_reference' => false,
+ 'block_name' => 'formation_list',
+ ])
+ ->add('experiences', ChillCollectionType::class, [
+ 'label' => 'Expériences',
+ 'entry_type' => ExperienceType::class,
+ 'allow_add' => true,
+ 'allow_delete' => true,
+ 'button_add_label' => 'Ajouter une expérience',
+ 'button_remove_label' => 'Retirer cette expérience',
+ 'required' => false,
+ 'by_reference' => false,
+ ])
+ ;
+ }
+
+ public function configureOptions(OptionsResolver $resolver)
+ {
+ $resolver->setDefaults(['data_class' => CV::class]);
+ }
+
+ public function getBlockPrefix()
+ {
+ return 'job_bundle_cv';
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/Form/ChoiceLoader/RomeAppellationChoiceLoader.php b/src/Bundle/ChillJobBundle/src/Form/ChoiceLoader/RomeAppellationChoiceLoader.php
new file mode 100644
index 000000000..39ab23ae1
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Form/ChoiceLoader/RomeAppellationChoiceLoader.php
@@ -0,0 +1,155 @@
+
+ */
+ private $toBeCreated = [];
+
+ public function __construct(
+ EntityManagerInterface $em,
+ PartenaireRomeAppellation $apiAppellation,
+ ValidatorInterface $validator
+ ) {
+ $this->em = $em;
+ $this->apiAppellation = $apiAppellation;
+ $this->appellationRepository = $em->getRepository(Appellation::class);
+ $this->validator = $validator;
+ }
+
+ public function loadChoiceList($value = null): ChoiceListInterface
+ {
+ return new ArrayChoiceList($this->lazyLoadedAppellations, $value);
+ }
+
+ public function loadChoicesForValues($values, $value = null)
+ {
+ $choices = [];
+ $code = '';
+
+ foreach ($values as $v) {
+ if (null === $v || '' === $v) {
+ continue;
+ }
+
+ // start with "original-" ? then we load from api
+ if (str_starts_with($v, 'original-')) {
+ $code = \substr($v, \strlen('original-'));
+ $appellation = $this->appellationRepository->findOneBy(['code' => $code]);
+
+ if ($appellation) {
+ $metier = $appellation->getMetier();
+ }
+
+ if (null === $appellation) {
+ if (array_key_exists($v, $this->toBeCreated)) {
+ [$appellation, $metier] = $this->toBeCreated[$v];
+ }
+ }
+ } else {
+ $id = $v;
+ $appellation = $this->appellationRepository->find($id);
+ $metier = $appellation->getMetier();
+ }
+
+ if (null === $appellation && '' !== $code) {
+ $def = $this->apiAppellation->getAppellation($code);
+
+ $metier ??= $this->em->getRepository(Metier::class)
+ ->findOneBy(['code' => $def['metier']['code']])
+ ?? (new Metier())
+ ->setCode($def['metier']['code'])
+ ->setLibelle($def['metier']['libelle']);
+
+ $appellation = new Appellation();
+
+ $appellation
+ ->setCode($def['code'])
+ ->setLibelle($def['libelle'])
+ ->setMetier($metier)
+ ;
+
+ $errorsAppellation = $this->validator->validate($appellation);
+ $errorsMetier = $this->validator->validate($metier);
+
+ if (0 === $errorsAppellation->count() && 0 === $errorsMetier->count()) {
+ $this->toBeCreated[$v] = [$appellation, $metier];
+ $this->em->persist($appellation);
+ }
+ }
+
+ if ($this->em->contains($metier) and $this->em->contains($appellation)) {
+ $choices[] = $appellation;
+ }
+ }
+
+ return $choices;
+ }
+
+ public function loadValuesForChoices(array $choices, $value = null)
+ {
+ $values = [];
+
+ foreach ($choices as $choice) {
+ if (null === $choice) {
+ $values[] = null;
+ continue;
+ }
+
+ $id = \call_user_func($value, $choice);
+
+ $this->lazyLoadedAppellations[$id] = $choice;
+ }
+
+ return $this->loadChoiceList($value)->getValuesForChoices($choices);
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/Form/FreinType.php b/src/Bundle/ChillJobBundle/src/Form/FreinType.php
new file mode 100644
index 000000000..43c28ddeb
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Form/FreinType.php
@@ -0,0 +1,66 @@
+add('reportDate', ChillDateType::class, [
+ 'label' => 'Date du rapport',
+ ])
+ ->add('freinsPerso', ChoiceType::class, [
+ 'label' => 'Freins identifiés liés à la situation personnelle',
+ 'choices' => \array_combine(Frein::FREINS_PERSO, Frein::FREINS_PERSO),
+ 'choice_label' => fn ($k) => 'freins_perso.'.$k,
+ 'required' => false,
+ 'expanded' => true,
+ 'multiple' => true,
+ ])
+ ->add('freinsEmploi', ChoiceType::class, [
+ 'label' => 'Freins identifiés liés à la situation professionnelle',
+ 'choices' => \array_combine(Frein::FREINS_EMPLOI, Frein::FREINS_EMPLOI),
+ 'choice_label' => fn ($k) => 'freins_emploi.'.$k,
+ 'required' => false,
+ 'expanded' => true,
+ 'multiple' => true,
+ ])
+ ->add('notesPerso', TextareaType::class, [
+ 'label' => 'Notes concernant la situation personnelle',
+ 'required' => false,
+ ])
+ ->add('notesEmploi', TextareaType::class, [
+ 'label' => 'Notes concernant l\'accès à l\'emploi',
+ 'required' => false,
+ ])
+ ;
+ }
+
+ public function configureOptions(OptionsResolver $resolver)
+ {
+ $resolver->setDefaults(['data_class' => Frein::class]);
+ }
+
+ public function getBlockPrefix()
+ {
+ return 'job_bundle_frein';
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/Form/ImmersionType.php b/src/Bundle/ChillJobBundle/src/Form/ImmersionType.php
new file mode 100644
index 000000000..ed5e2276e
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Form/ImmersionType.php
@@ -0,0 +1,197 @@
+add('entreprise', PickThirdpartyDynamicType::class, [
+ 'label' => "Identité de l'entreprise",
+ 'required' => true,
+ 'multiple' => false,
+ ])
+ ->add('domaineActivite', TextType::class, [
+ 'label' => "Domaine d'activité",
+ 'required' => true,
+ ])
+ ->add('tuteurName', TextType::class, [
+ 'label' => 'Nom du tuteur',
+ 'required' => true,
+ ])
+ ->add('tuteurFonction', TextType::class, [
+ 'label' => 'Fonction du tuteur',
+ 'required' => true,
+ ])
+ ->add('tuteurPhoneNumber', ChillPhoneNumberType::class, [
+ 'label' => 'Téléphone du tuteur',
+ 'required' => true,
+ ])
+ ->add('structureAccName', TextType::class, [
+ 'label' => 'Nom de la structure',
+ 'required' => false,
+ ])
+ ->add('structureAccPhonenumber', ChillPhoneNumberType::class, [
+ 'label' => 'Téléphone de la structure',
+ 'required' => false,
+ ])
+ ->add('structureAccEmail', EmailType::class, [
+ 'label' => 'Email de la structure',
+ 'required' => false,
+ ])
+ ->add('structureAccAddress', PickAddressType::class, [
+ 'label' => 'Addresse de la structure d\'accompagnement',
+ 'required' => false,
+ ])
+ ->add('posteTitle', TextType::class, [
+ 'label' => 'Intitulé du poste',
+ 'required' => true,
+ ])
+ ->add('posteLieu', TextType::class, [
+ 'label' => "Lieu d'exercice",
+ 'required' => true,
+ ])
+ ->add('debutDate', ChillDateType::class, [
+ 'label' => "Date de début de l'immersion",
+ 'required' => true,
+ ])
+ ->add('duration', DateIntervalType::class, [
+ 'unit_choices' => [
+ 'Weeks' => 'W',
+ 'Months' => 'M',
+ 'Days' => 'D',
+ ],
+ 'label' => "Durée de l'immersion",
+ 'required' => true,
+ ])
+ ->add('horaire', TextareaType::class, [
+ 'label' => 'Horaire du stagiaire',
+ 'required' => true,
+ ])
+ ->add('objectifs', ChoiceType::class, [
+ 'label' => 'Objectifs',
+ 'required' => false,
+ 'multiple' => true,
+ 'expanded' => true,
+ 'choices' => \array_combine(Immersion::OBJECTIFS, Immersion::OBJECTIFS),
+ 'choice_label' => fn ($k) => 'immersion_objectif.'.$k,
+ ])
+ ->add('objectifsAutre', TextareaType::class, [
+ 'label' => 'Précision sur les objectifs',
+ 'required' => false,
+ ])
+ ->add('noteImmersion', TextareaType::class, [
+ 'label' => 'Note',
+ 'required' => false,
+ ])
+ ;
+ } elseif ('bilan' === $options['step']) {
+ $builder
+ ->add('savoirEtre', ChoiceType::class, [
+ 'label' => 'Savoir-être du jeune',
+ 'required' => false,
+ 'multiple' => true,
+ 'expanded' => true,
+ 'choices' => \array_combine(Immersion::SAVOIR_ETRE, Immersion::SAVOIR_ETRE),
+ 'choice_label' => fn ($k) => 'immersion_savoir_etre.'.$k,
+ ])
+ ->add('savoirEtreNote', TextareaType::class, [
+ 'label' => 'Note',
+ 'required' => false,
+ ])
+ ->add('principalesActivites', TextareaType::class, [
+ 'label' => 'Principales activités',
+ 'required' => false,
+ ])
+ ->add('competencesAcquises', TextareaType::class, [
+ 'label' => 'Compétences acquises',
+ 'required' => false,
+ ])
+ ->add('competencesADevelopper', TextareaType::class, [
+ 'label' => 'Compétences à développer',
+ 'required' => false,
+ ])
+ ->add('noteBilan', TextareaType::class, [
+ 'label' => 'Notes sur le bilan',
+ 'required' => false,
+ ])
+
+ ;
+
+ foreach ([
+ ['ponctualiteSalarie', Immersion::PONCTUALITE_SALARIE, 'Ponctualité du salarié'],
+ ['assiduite', Immersion::ASSIDUITE, 'Assiduité'],
+ ['interetActivite', Immersion::YES_NO_NSP, 'La personne s’intéresse à l’ensemble des activités et membres de l’entreprise'],
+ ['integreRegle', Immersion::INTEGRE_REGLE, 'La personne a intégré les règles (les principes) de l’entreprise'],
+ ['espritInitiative', Immersion::YES_NO_NSP, 'La personne fait preuve d’esprit d’initiative'],
+ ['organisation', Immersion::YES_NO_NSP, 'La personne a fait preuve d’organisation'],
+ ['capaciteTravailEquipe', Immersion::YES_NO_NSP, 'Sa capacité à travailler en équipe'],
+ ['styleVestimentaire', Immersion::YES_NO_NSP, 'Style vestimentaire adapté'],
+ ['langageProf', Immersion::YES_NO_NSP, 'Langage professionnel'],
+ ['appliqueConsigne', Immersion::YES_NO_NSP, 'Applique les consignes'],
+ ['respectHierarchie', Immersion::YES_NO_NSP, 'Respecte les niveaux hiérarchiques'],
+ ] as [$name, $choices, $label]) {
+ $builder
+ ->add($name, ChoiceType::class, [
+ 'label' => $label,
+ 'multiple' => false,
+ 'required' => false,
+ 'expanded' => true,
+ 'choices' => $choices,
+ 'choice_label' => function ($el) use ($choices, $name) {
+ if (Immersion::YES_NO_NSP === $choices) {
+ return 'immersion_nsp.'.$el;
+ }
+
+ return 'immersion_'.$name.'.'.$el;
+ },
+ ])
+ ->add($name.'Note', TextareaType::class, [
+ 'label' => 'Notes',
+ 'required' => false,
+ ]);
+ }
+ }
+ }
+
+ public function configureOptions(OptionsResolver $resolver)
+ {
+ $resolver->setDefaults(['data_class' => Immersion::class, 'step' => 'immersion']);
+
+ $resolver
+ ->setAllowedValues('step', ['immersion', 'bilan'])
+ ->setRequired('center')
+ ->setAllowedTypes('center', \Chill\MainBundle\Entity\Center::class)
+ ;
+ }
+
+ public function getBlockPrefix()
+ {
+ return 'job_bundle_immersion';
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/Form/ProjetProfessionnelType.php b/src/Bundle/ChillJobBundle/src/Form/ProjetProfessionnelType.php
new file mode 100644
index 000000000..4817dfcc3
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Form/ProjetProfessionnelType.php
@@ -0,0 +1,108 @@
+add('souhait', PickRomeAppellationType::class, [
+ 'label' => 'Souhait',
+ 'multiple' => true,
+ 'required' => false,
+ ])
+ ->add('domaineActiviteSouhait', TextareaType::class, [
+ 'label' => "Domaine d'activité souhaité",
+ 'required' => false,
+ ])
+ ->add('reportDate', ChillDateType::class, [
+ 'label' => 'Date',
+ 'required' => true,
+ ])
+ ->add('typeContrat', ChoiceType::class, [
+ 'label' => 'Type de contrat recherché',
+ 'multiple' => true,
+ 'expanded' => true,
+ 'choices' => \array_combine(
+ ProjetProfessionnel::TYPE_CONTRAT,
+ ProjetProfessionnel::TYPE_CONTRAT
+ ),
+ 'choice_label' => fn ($k) => 'projet_prof.type_contrat.'.$k,
+ ])
+ ->add('typeContratNotes', TextareaType::class, [
+ 'label' => 'Notes concernant le contrat recherché',
+ 'required' => false,
+ ])
+ ->add('volumeHoraire', ChoiceType::class, [
+ 'label' => 'Volume horaire',
+ 'multiple' => true,
+ 'expanded' => true,
+ 'required' => true,
+ 'choices' => \array_combine(
+ ProjetProfessionnel::VOLUME_HORAIRES,
+ ProjetProfessionnel::VOLUME_HORAIRES
+ ),
+ 'choice_label' => fn ($k) => 'projet_prof.volume_horaire.'.$k,
+ ])
+ ->add('volumeHoraireNotes', TextareaType::class, [
+ 'label' => 'Notes concernant le volume horaire',
+ 'required' => false,
+ ])
+ ->add('idee', TextareaType::class, [
+ 'label' => 'Idée',
+ 'required' => false,
+ ])
+ ->add('enCoursConstruction', TextareaType::class, [
+ 'label' => 'En cours de construction',
+ 'required' => false,
+ ])
+ ->add('valide', PickRomeAppellationType::class, [
+ 'label' => 'Validé',
+ 'multiple' => true,
+ 'by_reference' => false,
+ 'required' => false,
+ ])
+ ->add('domaineActiviteValide', TextareaType::class, [
+ 'label' => "Domaine d'activité validé",
+ 'required' => false,
+ ])
+ ->add('valideNotes', TextareaType::class, [
+ 'label' => 'Validé (notes)',
+ 'required' => false,
+ ])
+ ->add('projetProfessionnelNote', TextareaType::class, [
+ 'label' => 'Notes concernant le projet professionnel',
+ 'required' => false,
+ ])
+ ;
+ }
+
+ public function configureOptions(OptionsResolver $resolver)
+ {
+ $resolver->setDefaults(['data_class' => ProjetProfessionnel::class]);
+ }
+
+ public function getBlockPrefix()
+ {
+ return 'job_bundle_projetprofessionnel';
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/Form/Type/PickRomeAppellationType.php b/src/Bundle/ChillJobBundle/src/Form/Type/PickRomeAppellationType.php
new file mode 100644
index 000000000..174a25c18
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Form/Type/PickRomeAppellationType.php
@@ -0,0 +1,116 @@
+translator = $translator;
+ $this->urlGenerator = $urlGenerator;
+ $this->em = $em;
+ $this->apiPartenaire = $apiPartenaire;
+ $this->validator = $validator;
+ }
+
+ public function buildForm(FormBuilderInterface $builder, array $options)
+ {
+ // ->addModelTransformer($this->romeAppellationTransformer)
+ }
+
+ public function configureOptions(OptionsResolver $resolver)
+ {
+ $resolver
+ ->setDefault('class', Appellation::class)
+ ->setDefault('choice_label', fn (Appellation $a) => $a->getLibelle())
+ ->setDefault('placeholder', 'Choisir une appellation')
+ ->setDefault('attr', ['class' => 'select2 '])
+ ->setDefault('choice_loader', fn (Options $o) => new RomeAppellationChoiceLoader(
+ $this->em,
+ $this->apiPartenaire,
+ $this->validator
+ ))
+ ;
+ }
+
+ public function getParent()
+ {
+ return EntityType::class;
+ }
+
+ public function buildView(\Symfony\Component\Form\FormView $view, \Symfony\Component\Form\FormInterface $form, array $options)
+ {
+ $view->vars['attr']['data-rome-appellation-picker'] = true;
+ $view->vars['attr']['data-select-interactive-loading'] = true;
+ $view->vars['attr']['data-search-url'] = $this->urlGenerator
+ ->generate('chill_france_travail_api_appellation_search', ['_format' => 'json']);
+ $view->vars['attr']['data-placeholder'] = 'Choisir une appellation';
+ $view->vars['attr']['data-no-results-label'] = $this->translator->trans('select2.no_results');
+ $view->vars['attr']['data-error-load-label'] = $this->translator->trans('select2.error_loading');
+ $view->vars['attr']['data-searching-label'] = $this->translator->trans('select2.searching');
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/Menu/MenuBuilder.php b/src/Bundle/ChillJobBundle/src/Menu/MenuBuilder.php
new file mode 100644
index 000000000..c838a4b1a
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Menu/MenuBuilder.php
@@ -0,0 +1,72 @@
+authorizationChecker = $authorizationChecker;
+ }
+
+ public function buildMenu($menuId, MenuItem $menu, array $parameters)
+ {
+ /** @var \Chill\PersonBundle\Entity\Person $person */
+ $person = $parameters['person'];
+
+ if ($this->authorizationChecker->isGranted(JobVoter::REPORT_NEW, $person)) {
+ $menu->addChild('Situation personnelle', [
+ 'route' => 'chill_crud_job_personal_situation_view',
+ 'routeParameters' => [
+ 'person' => $person->getId(),
+ ],
+ ])
+ ->setExtras([
+ 'order' => 50,
+ ]);
+ $menu->addChild('Dispositifs', [
+ 'route' => 'chill_crud_job_dispositifs_view',
+ 'routeParameters' => [
+ 'person' => $person->getId(),
+ ],
+ ])
+ ->setExtras([
+ 'order' => 51,
+ ]);
+ }
+
+ $menu->addChild('Emploi', [
+ 'route' => 'chill_job_report_index',
+ 'routeParameters' => [
+ 'person' => $person->getId(),
+ ],
+ ])
+ ->setExtras([
+ 'order' => 52,
+ ]);
+ }
+
+ public static function getMenuIds(): array
+ {
+ return ['person'];
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/Repository/CSPersonRepository.php b/src/Bundle/ChillJobBundle/src/Repository/CSPersonRepository.php
new file mode 100644
index 000000000..ac833113e
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Repository/CSPersonRepository.php
@@ -0,0 +1,20 @@
+Dispositifs
+ {% endblock %}
+
+ {# surcharge le block "retour" par un lien vers la page vue #}
+ {% block content_form_actions_back %}
+
+
+ {{ 'Cancel'|trans }}
+
+
+ {% endblock %}
+
+ {% block content_form_actions_view %}
+ {# no view acceptable #}
+ {% endblock %}
+
+ {% block content_form_actions_save_and_close %}
+ {# save and close does not makes sens #}
+ {% endblock %}
+
+ {% block crud_content_form_rows %}
+ Accompagnement
+
+
+ {{ form_row(form.accompagnement) }}
+
+
+
+ {{ form_row(form.accompagnementRQTHDate) }}
+
+
+
+ {{ form_row(form.prescripteur) }}
+
+ {{ form_row(form.dispositifsNotes) }}
+
+ Pôle emploi
+
+ {{ form_row(form.poleEmploiId) }}
+ {{ form_row(form.poleEmploiInscriptionDate) }}
+
+
+ CAF
+
+
+ {{ form_row(form.cafId) }}
+
+
+ {{ form_row(form.cafInscriptionDate) }}
+
+
+
+ Autres informations
+
+
+ {{ form_row(form.cERInscriptionDate) }}
+ {{ form_row(form.cERSignataire) }}
+ {{ form_row(form.pPAEInscriptionDate) }}
+ {{ form_row(form.pPAESignataire) }}
+
+
+ {{ form_row(form.nEETEligibilite) }}
+
+
+
+ {{ form_row(form.nEETCommissionDate) }}
+
+
+ {{ form_row(form.fSEMaDemarcheCode) }}
+ {{ form_row(form.dateContratIEJ) }}
+ {{ form_row(form.dateAvenantIEJ) }}
+ {% endblock %}
+{% endembed %}
+{% endblock %}
+
+{% block js %}
+ {{ parent() }}
+ {{ encore_entry_script_tags('mod_pickentity_type') }}
+
+
+{% endblock js %}
diff --git a/src/Bundle/ChillJobBundle/src/Resources/views/CSPerson/dispositifs_view.html.twig b/src/Bundle/ChillJobBundle/src/Resources/views/CSPerson/dispositifs_view.html.twig
new file mode 100644
index 000000000..976f36e5b
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Resources/views/CSPerson/dispositifs_view.html.twig
@@ -0,0 +1,128 @@
+{% extends "@ChillPerson/Person/layout.html.twig" %}
+
+{% set person = entity.getPerson() %}
+
+{% set activeRouteKey = '' %}
+{% set accompagnements = constant('Chill\\JobBundle\\Entity\\CSPerson::ACCOMPAGNEMENTS') %}
+
+
+{% import '@ChillDocStore/Macro/macro.html.twig' as doc %}
+
+{% block title 'Dispositifs d\'accompagnement de %name%'|trans( { '%name%': person.firstName ~ ' ' ~ person.lastName } ) %}
+
+{% block content %}
+ {{ 'Dispositifs d\'accompagnement de %name%'|trans( { '%name%': person.firstName ~ ' ' ~ person.lastName } ) }}
+
+ Accompagnement
+
+
+
+ Accompagnements
+ {% if entity.accompagnement is null or entity.accompagnement|length == 0 %}
+ {{ null|chill_print_or_message }}
+ {% else %}
+
+
+ {% for e in accompagnements %}
+ {% if e in entity.accompagnement %}
+ {% if e == 'autre' %}
+ Autre: {{ entity.accompagnementComment|chill_print_or_message(null, 'blockquote') }}
+ {% elseif e == 'rqth' %}
+ {{ ('accompagnement.' ~ e)|trans }} - Date de l'accompagnement: {{ entity.accompagnementRQTHDate|chill_print_or_message }}
+ {% else %}
+ {{ ('accompagnement.' ~ e)|trans }}
+ {% endif %}
+ {% endif %}
+ {% endfor %}
+
+
+ {% endif %}
+
+ Prescripteur
+
+ {% if entity.prescripteur is not null %}
+ {{ entity.prescripteur|chill_entity_render_box({'with_valid_from': false}) }}
+ {% else %}
+ {{ null|chill_print_or_message }}
+ {% endif %}
+
+ Notes
+ {{ entity.dispositifsNotes|chill_print_or_message("Aucune note", 'blockquote') }}
+
+
+ Pôle emploi
+
+
+ Identifiant pôle emploi
+ {{ entity.poleEmploiId|chill_print_or_message }}
+
+ Date d'inscription pôle emploi
+ {{ entity.poleEmploiInscriptionDate|chill_print_or_message }}
+
+
+
+ CAF
+
+
+ Identifiant CAF
+ {{ entity.cafId|chill_print_or_message }}
+
+ Date d'inscription CAF
+ {{ entity.cafInscriptionDate|chill_print_or_message }}
+
+
+
+ Autres informations
+
+
+ {% for item in [
+ ['cERInscriptionDate', 'Date CER'],
+ ['cERSignataire', 'Signataire CER'],
+ ['pPAEInscriptionDate', 'Date PPAE'],
+ ['pPAESignataire', 'Signataire PPAE'],
+ ] %}
+ {{ item[1] }}
+ {{ attribute(entity, item[0])|chill_print_or_message }}
+ {% endfor %}
+
+ Éligibilite NEET
+
+ {% if entity.nEETEligibilite is null %}
+ {{ null|chill_print_or_message }}
+ {% elseif entity.nEETEligibilite == 'oui' %}
+ Oui Date de commission : {{ entity.nEETCommissionDate|chill_print_or_message }}
+ {% elseif entity.nEETEligibilite == 'non' %}
+ Non
+ {% else %}
+ {{ ('neet_eligibility.' ~ entity.nEETEligibilite)|trans }}
+ {% endif %}
+
+
+ Code "Ma démarche FSE"
+ {{ entity.fSEMaDemarcheCode|chill_print_or_message }}
+
+ {% if entity.dateContratIEJ != null or entity.dateAvenantIEJ != null %}
+ IEJ
+
+ {% if entity.dateContratIEJ != null %}
+ Date du contrat IEJ : {{ entity.dateContratIEJ|format_date('short') }}
+ {% endif %}
+ {% if entity.dateAvenantIEJ != null %}
+ Date de l'avenant IEJ : {{ entity.dateAvenantIEJ|format_date('short') }}
+ {% endif %}
+
+ {% endif %}
+
+
+
+
+
+{% endblock content %}
+
+{% block css %}
+
+{% endblock %}
diff --git a/src/Bundle/ChillJobBundle/src/Resources/views/CSPerson/personal_situation_edit.html.twig b/src/Bundle/ChillJobBundle/src/Resources/views/CSPerson/personal_situation_edit.html.twig
new file mode 100644
index 000000000..3265679dc
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Resources/views/CSPerson/personal_situation_edit.html.twig
@@ -0,0 +1,126 @@
+{% extends '@ChillPerson/CRUD/edit.html.twig' %}
+
+{% block title 'Situation personnelle de ' ~ entity.person.firstName ~ ' ' ~ entity.person.lastName %}
+
+{% block content %}
+{% embed '@ChillMain/CRUD/_edit_content.html.twig' %}
+ {% block crud_content_header %}
+ Situation personnelle
+ {% endblock %}
+
+ {# surcharge le block "retour" par un lien vers la page vue #}
+ {% block content_form_actions_back %}
+
+
+ {{ 'Cancel'|trans }}
+
+
+ {% endblock %}
+
+ {% block content_form_actions_view %}
+ {# no view acceptable #}
+ {% endblock %}
+
+ {% block content_form_actions_save_and_close %}
+ {# save and close does not makes sens #}
+ {% endblock %}
+
+ {% block crud_content_form_rows %}
+ Logement
+
+
+ {{ form_row(form.situationLogement) }}
+
+
+
+ {{ form_row(form.situationLogementPrecision) }}
+
+
+ Situation familiale
+
+ {{ form_row(form.enfantACharge) }}
+ {{ form_row(form.personMaritalStatus) }}
+
+ Maitrise de la langue
+
+ {{ form_row(form.niveauMaitriseLangue) }}
+
+ Mobilité
+
+ {{ form_row(form.mobiliteMoyenDeTransport) }}
+ {{ form_row(form.vehiculePersonnel) }}
+ {{ form_row(form.permisConduire) }}
+ {{ form_row(form.mobiliteNotes) }}
+
+ Situation professionnelle et économique
+
+
+ {{ form_row(form.situationProfessionnelle) }}
+
+
+ {{ form_row(form.dateFinDernierEmploi) }}
+
+
+ {{ form_row(form.typeContrat) }}
+
+
+
+ {{ form_row(form.typeContratAide) }}
+
+
+
+ {{ form_row(form.ressources) }}
+
+
+
+
+ {{ form_row(form.ressourceDate1Versement) }}
+ {{ form_row(form.cPFMontant) }}
+ {{ form_row(form.acompteDIF) }}
+
+ Situation de handicap
+
+
+ {{ form_row(form.handicapIs) }}
+
+
+
+ {{ form_row(form.handicapNotes) }}
+ {{ form_row(form.handicapRecommandation) }}
+ {{ form_row(form.handicapAccompagnement) }}
+
+
+ Documents
+
+ {{ form_row(form.documentCV) }}
+ {{ form_row(form.documentAgrementIAE) }}
+ {{ form_row(form.documentRQTH) }}
+ {{ form_row(form.documentAttestationNEET) }}
+ {{ form_row(form.documentCI) }}
+ {{ form_row(form.documentTitreSejour) }}
+ {{ form_row(form.documentAttestationFiscale) }}
+ {{ form_row(form.documentPermis) }}
+ {{ form_row(form.documentAttestationCAAF) }}
+ {{ form_row(form.documentContraTravail) }}
+ {{ form_row(form.documentAttestationFormation) }}
+ {{ form_row(form.documentQuittanceLoyer) }}
+ {{ form_row(form.documentFactureElectricite) }}
+ {{ form_row(form.documentAttestationSecuriteSociale) }}
+ {% endblock %}
+{% endembed %}
+{% endblock %}
+
+{% block css %}
+ {{ parent() }}
+ {{ encore_entry_link_tags('mod_async_upload') }}
+ {{ encore_entry_link_tags('mod_pickentity_type') }}
+{% endblock css %}
+
+{% block js %}
+ {{ parent() }}
+ {{ encore_entry_script_tags('mod_async_upload') }}
+ {{ encore_entry_script_tags('mod_pickentity_type') }}
+
+{% endblock js %}
diff --git a/src/Bundle/ChillJobBundle/src/Resources/views/CSPerson/personal_situation_view.html.twig b/src/Bundle/ChillJobBundle/src/Resources/views/CSPerson/personal_situation_view.html.twig
new file mode 100644
index 000000000..3ce2bd98d
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Resources/views/CSPerson/personal_situation_view.html.twig
@@ -0,0 +1,285 @@
+{% extends "@ChillPerson/Person/layout.html.twig" %}
+
+{% set person = entity.getPerson() %}
+
+{% set activeRouteKey = '' %}
+{% set niveaux_maitrise_langue = constant('Chill\\JobBundle\\Entity\\CSPerson::NIVEAU_MAITRISE_LANGUE') %}
+{% set permis_conduire = constant('Chill\\JobBundle\\Entity\\CSPerson::PERMIS_CONDUIRE') %}
+{% set types_contrat = constant('Chill\\JobBundle\\Entity\\CSPerson::TYPE_CONTRAT') %}
+{% set ressources = constant('Chill\\JobBundle\\Entity\\CSPerson::RESSOURCES') %}
+
+{% import '@ChillDocStore/Macro/macro.html.twig' as doc %}
+
+{% block title 'Situation personnelle de %name%'|trans( { '%name%': person.firstName ~ ' ' ~ person.lastName } ) %}
+
+{% block content %}
+ {{ 'Situation personnelle de %name%'|trans( { '%name%': person.firstName ~ ' ' ~ person.lastName } ) }}
+
+ Logement
+
+
+
+ Situation de logement
+ {% if entity.situationLogement is not null %}
+ {{ ('situation_logement.' ~ entity.situationLogement)|trans }}
+ {% else %}
+ {{ null|chill_print_or_message("Aucune information") }}
+ {% endif %}
+
+
+
+ Situation familiale
+
+
+
+ Enfants à charge
+ {% if entity.enfantACharge is not null %}
+
+ {% if entity.enfantACharge == 0 %}Aucun enfant{% elseif entity.enfantACharge == 1 %}Un enfant{% else %}{{ entity.enfantACharge }} enfants{% endif %} à charge
+ {% else %}
+ {{ null|chill_print_or_message }}
+ {% endif %}
+
+ {{'Marital status'|trans}} :
+
+ {% if entity.person.maritalStatus is not null %}
+ {{ entity.person.maritalStatus.name|localize_translatable_string }}
+ {% else %}
+ {{ 'No data given'|trans }}
+ {% endif %}
+
+
+
+
+ Maitrise de la langue
+
+
+
+ Niveau de maitrise de la langue française
+ {% if entity.niveauMaitriseLangue is null or entity.niveauMaitriseLangue|length == 0 %}
+ {{ null|chill_print_or_message }}
+ {% else %}
+
+
+ {% for niveau in niveaux_maitrise_langue %}
+ {% if niveau in entity.niveauMaitriseLangue %}
+ {{ ('niveau_maitrise_langue.' ~ niveau)|trans }}
+ {% endif %}
+ {% endfor %}
+
+
+ {% endif %}
+
+
+ Mobilité
+
+
+
+
+ Moyens de transports accessibles
+
+ {% if entity.mobiliteMoyenDeTransport is null or entity.mobiliteMoyenDeTransport|length == 0 %}
+ {{ null|chill_print_or_message("Aucun moyen de transport renseigné") }}
+ {% else %}
+
+ {% for e in entity.mobiliteMoyenDeTransport %}
+ {{ ('moyen_transport.' ~ e)|trans }}
+ {% endfor %}
+
+ {% endif %}
+
+
+ Véhicule Personnel
+ {% if entity.vehiculePersonnel is null %}
+ {{ null|chill_print_or_message }}
+ {% elseif entity.vehiculePersonnel == true %}
+ A un véhicule personnel
+ {% else %}
+ N'a pas de véhicule personnel
+ {% endif %}
+
+ Permis de conduire
+ {% if entity.permisConduire is null or entity.permisConduire|length == 0 %}
+ {{ null|chill_print_or_message }}
+ {% else %}
+
+
+ {% for e in permis_conduire %}
+ {% if e in entity.permisConduire %}
+ {{ ('permis_conduire.' ~ e)|trans }}
+ {% endif %}
+ {% endfor %}
+
+
+ {% endif %}
+
+ Notes concernant la mobilité
+
+ {{ entity.mobiliteNotes|chill_print_or_message("Aucune note", 'blockquote') }}
+
+
+
+ Situation professionnelle et économique
+
+
+
+ Situation professionnelle
+ {% if entity.situationProfessionnelle is not null %}
+ {{ ('situation_professionnelle.' ~ entity.situationProfessionnelle)|trans }}
+ {% else %}
+ {{ null|chill_print_or_message }}
+ {% endif %}
+
+ Date de fin du dernier emploi
+ {% if entity.dateFinDernierEmploi is not null %}
+ {{ entity.dateFinDernierEmploi|format_date('short') }}
+ {% else %}
+ {{ null|chill_print_or_message }}
+ {% endif %}
+
+ {% if entity.situationProfessionnelle == 'en_activite' %}
+ Type de contrat
+ {% if entity.typeContrat is null or entity.typeContrat|length == 0 %}
+ {{ null|chill_print_or_message }}
+ {% else %}
+
+
+ {% for e in types_contrat %}
+ {% if e in entity.typeContrat %}
+ {{ ('type_contrat.' ~ e)|trans }}
+ {% endif %}
+ {% endfor %}
+
+
+ {% endif %}
+ {% endif %}
+
+ Ressources
+ {% if entity.ressources is null or entity.ressources|length == 0 %}
+ {{ null|chill_print_or_message }}
+ {% else %}
+
+
+ {% for e in ressources %}
+ {% if e in entity.ressources %}
+ {% if e == 'autre' %}
+ Autre: {{ entity.ressourcesComment|chill_print_or_message }}
+ {% else %}
+ {{ ('ressource.' ~ e)|trans }}
+ {% endif %}
+ {% endif %}
+ {% endfor %}
+
+
+ {% endif %}
+
+ Date du premier versement
+ {% if entity.ressourceDate1Versement is not null %}
+ {{ entity.ressourceDate1Versement|format_date('short') }}
+ {% else %}
+ {{ null|chill_print_or_message }}
+ {% endif %}
+
+ Montant CPF
+ {% if entity.cPFMontant is not null %}
+ {{ entity.cPFMontant|format_currency('EUR') }}
+ {% else %}
+ {{ null|chill_print_or_message }}
+ {% endif %}
+
+
+ Montant acompte DIF
+ {% if entity.acompteDIF is not null %}
+ {{ entity.acompteDIF|format_currency('EUR') }}
+ {% else %}
+ {{ null|chill_print_or_message }}
+ {% endif %}
+
+
+
+ Handicap
+
+
+ Handicap ?
+
+ {% if entity.handicapIs is null %}
+ {{ null|chill_print_or_message }}
+ {% elseif entity.handicapIs %}
+ Oui
+
+ Type de handicap : {{ entity.handicapNotes|chill_print_or_message("Aucune précision", 'blockquote') }}
+ {% else %}
+ Non
+ {% endif %}
+
+
+ {% if entity.handicapIs %}
+ Recommandation
+
+ {% if entity.handicapRecommandation is null %}
+ {{ null|chill_print_or_message("Aucune recommandation renseignée") }}
+ {% else %}
+ {{ ('handicap_recommandation.' ~ entity.handicapRecommandation)|trans }}
+ {% endif %}
+
+
+ Accompagnement
+ {% if entity.handicapAccompagnement is not null %}
+ {{ entity.handicapAccompagnement.name }}
+ {% else %}
+ {{ null|chill_print_or_message }}
+ {% endif %}
+ {% endif %}
+
+
+ Documents
+
+
+
+ {% for r in [
+ ['documentCV', 'CV'],
+ ['documentAgrementIAE', 'Document Agrément AIE'],
+ ['documentRQTH', 'Document RQTH'],
+ ['documentAttestationNEET', 'Attestation NEET'],
+ ['documentCI', "Carte d'identité"],
+ ['documentTitreSejour', 'Titre de séjour'],
+ ['documentAttestationFiscale', 'Attestation fiscale'],
+ ['documentPermis', 'Permis'],
+ ['documentAttestationCAAF', 'Attestation CAAF'],
+ ['documentContraTravail', 'Contrat de travail'],
+ ['documentAttestationFormation', 'Attestation formation'],
+ ['documentQuittanceLoyer', 'Quittance de loyer'],
+ ['documentFactureElectricite', "Facture d'électricité"],
+ ['documentAttestationSecuriteSociale', "Attestation sécurité sociale"],
+ ] %}
+
+ {{ r[1] }}
+ {% set d = attribute(entity, r[0]) %}
+ {% if d is null %}
+ {{ null|chill_print_or_message("Aucun document") }}
+ {% else %}
+ {% set title = person.lastname ~ ' ' ~ person.firstname ~ ', ' ~ r[1]|replace({"Document ": ""}) %}
+ {{ d|chill_document_button_group(title, is_granted('CHILL_PERSON_UPDATE', person), {small: true}) }}
+ {% endif %}
+
+ {% endfor %}
+
+
+
+
+
+{% endblock %}
+
+{% block css %}
+ {{ parent() }}
+ {{ encore_entry_link_tags('mod_async_upload') }}
+ {{ encore_entry_script_tags('mod_document_action_buttons_group') }}
+{% endblock css %}
+
+{% block js %}
+ {{ parent() }}
+ {{ encore_entry_script_tags('mod_async_upload') }}
+ {{ encore_entry_link_tags('mod_document_action_buttons_group') }}
+{% endblock js %}
diff --git a/src/Bundle/ChillJobBundle/src/Resources/views/CV/edit.html.twig b/src/Bundle/ChillJobBundle/src/Resources/views/CV/edit.html.twig
new file mode 100644
index 000000000..2ebb37e3d
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Resources/views/CV/edit.html.twig
@@ -0,0 +1,61 @@
+{% extends "@ChillPerson/Person/layout.html.twig" %}
+
+{% set person = entity.person %}
+{% set activeRouteKey = '' %}
+
+{% block title %}
+{% include('@ChillMain/CRUD/_edit_title.html.twig') %}
+{% endblock title %}
+
+{% form_theme form _self %}
+{% block job_bundle_cv_formation_widget %}
+
+ {{ form_row(form.title) }}
+ {{ form_row(form.organisme) }}
+ {{ form_row(form.startDate) }}
+ {{ form_row(form.endDate) }}
+
+ {{ form_row(form.diplomaObtained) }}
+
+
+ {{ form_row(form.diplomaReconnue) }}
+
+
+
+{% endblock %}
+
+{% block content %}
+{% embed '@ChillMain/CRUD/_edit_content.html.twig' %}
+ {% block crud_content_form_rows %}
+
+
+
+
+ {{ form_row(form.reportDate) }}
+ {{ form_row(form.formationLevel) }}
+ {{ form_row(form.formationType) }}
+ {{ form_row(form.spokenLanguages) }}
+
+ Formations
+ {{ form_widget(form.formations) }}
+
+ Expériences
+ {{ form_widget(form.experiences) }}
+
+ Notes
+ {{ form_widget(form.notes) }}
+ {% endblock crud_content_form_rows %}
+
+ {% block content_form_actions_back %}
+
+
+ {{ 'Cancel'|trans }}
+
+
+ {% endblock %}
+{% endembed %}
+{% endblock %}
+
+{% block css %}
+
+{% endblock css %}
diff --git a/src/Bundle/ChillJobBundle/src/Resources/views/CV/new.html.twig b/src/Bundle/ChillJobBundle/src/Resources/views/CV/new.html.twig
new file mode 100644
index 000000000..756c5a699
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Resources/views/CV/new.html.twig
@@ -0,0 +1,61 @@
+{% extends "@ChillPerson/Person/layout.html.twig" %}
+
+{% set person = entity.person %}
+{% set activeRouteKey = '' %}
+
+{% block title %}
+{% embed('@ChillPerson/CRUD/_new_title.html.twig') %}{% endembed %}
+{% endblock %}
+
+{% form_theme form _self %}
+{% block job_bundle_cv_formation_widget %}
+
+ {{ form_row(form.title) }}
+ {{ form_row(form.organisme) }}
+ {{ form_row(form.startDate) }}
+ {{ form_row(form.endDate) }}
+
+ {{ form_row(form.diplomaObtained) }}
+
+
+ {{ form_row(form.diplomaReconnue) }}
+
+
+
+{% endblock %}
+
+{% block content %}
+{% embed '@ChillMain/CRUD/_new_content.html.twig' %}
+ {% block crud_content_header %}
+ {{ ('crud.'~crud_name~'.title_new')|trans({'%person%': person|chill_entity_render_string }) }}
+ {% endblock crud_content_header %}
+
+ {% block crud_content_form_rows %}
+ {{ form_row(form.reportDate) }}
+ {{ form_row(form.formationLevel) }}
+ {{ form_row(form.formationType) }}
+ {{ form_row(form.spokenLanguages) }}
+
+ Formations
+ {{ form_widget(form.formations) }}
+
+ Expériences
+ {{ form_widget(form.experiences) }}
+
+ Notes
+ {{ form_widget(form.notes) }}
+ {% endblock crud_content_form_rows %}
+
+ {% block content_form_actions_back %}
+
+
+ {{ 'Cancel'|trans }}
+
+
+ {% endblock %}
+{% endembed %}
+{% endblock %}
+
+{% block css %}
+
+{% endblock css %}
diff --git a/src/Bundle/ChillJobBundle/src/Resources/views/CV/view.html.twig b/src/Bundle/ChillJobBundle/src/Resources/views/CV/view.html.twig
new file mode 100644
index 000000000..7caa8c709
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Resources/views/CV/view.html.twig
@@ -0,0 +1,144 @@
+{% extends '@ChillPerson/CRUD/view.html.twig' %}
+
+{% block content %}
+{% embed '@ChillPerson/CRUD/_view_content.html.twig' %}
+ {% block crud_content_header %}
+ {{ ('crud.' ~ crud_name ~ '.title_view')|trans({'%person%': person|chill_entity_render_string }) }}
+ {% endblock crud_content_header %}
+
+ {% block crud_content_view_details %}
+
+ Date du rapport
+ {{ entity.reportDate|format_date('short') }}
+
+ Compétences
+
+ Langues parlées
+
+ {% if entity.spokenLanguages is null or entity.spokenLanguages|length == 0 %}
+ {{ null|chill_print_or_message }}
+ {% else %}
+ {% for lang in entity.spokenLanguages %}
+ {{ lang.name|localize_translatable_string }}{% if not loop.last %},{% endif %}
+ {% endfor %}
+ {% endif %}
+
+
+ Formation
+
+ Niveau de formation
+
+ {{ (entity.formationLevel is null ? null : ('formation_level.' ~ entity.formationLevel))|chill_print_or_message("Aucune information") }}
+
+
+ Type de formation
+
+ {{ (entity.formationType is null ? null : ('formation_type.' ~ entity.formationType))|chill_print_or_message("Aucune information") }}
+
+
+
+ Formations suivies
+
+ {% if entity.formations|length > 0 %}
+ {% for f in entity.formations %}
+
+ {% endfor %}
+ {% else %}
+ {{ 'No education'|trans }}
+ {% endif %}
+
+ Expériences
+
+ {% if entity.formations|length > 0 %}
+ {% for f in entity.experiences %}
+
+
+
{{ f.poste }} {% if f.structure is not empty %}auprès de {{ f.structure }} {% endif %}
+
+
+ Dates de l'expérience
+
+ {% if f.startDate is null and f.endDate is null %}
+ {{ null|chill_print_or_message("Aucune date indiquée") }}
+ {% elseif f.startDate is null %}
+ Jusqu'au {{ f.endDate|format_date('short') }} (date de début inconnue)
+ {% elseif f.endDate is null %}
+ Depuis le {{ f.startDate|format_date('short') }} (date de fin inconnue)
+ {% else %}
+ Du {{ f.startDate|format_date('short') }} au {{ f.endDate|format_date('short') }}
+ {% endif %}
+
+
+ Type de contrat
+
+ {{ (f.contratType is null ? null : ('xp_contrat_type.'~f.contratType))|chill_print_or_message }}
+
+
+ {% if f.notes is not empty %}
+ Notes
+
+ {{ f.notes|chill_print_or_message(null, 'blockquote') }}
+
+ {% endif %}
+
+
+
+ {% endfor %}
+ {% else %}
+ Aucune formation renseignée
+ {% endif %}
+
+ Note
+
+ {{ entity.notes|chill_print_or_message("Aucune note", 'blockquote') }}
+ {% endblock crud_content_view_details %}
+
+ {% block content_view_actions_back %}
+
+
+ {{ 'Cancel'|trans }}
+
+
+ {% endblock %}
+{% endembed %}
+{% endblock %}
+
+{% block css %}
+
+{% endblock %}
diff --git a/src/Bundle/ChillJobBundle/src/Resources/views/Frein/edit.html.twig b/src/Bundle/ChillJobBundle/src/Resources/views/Frein/edit.html.twig
new file mode 100644
index 000000000..a7feeeca5
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Resources/views/Frein/edit.html.twig
@@ -0,0 +1,20 @@
+{% extends "@ChillPerson/Person/layout.html.twig" %}
+
+{% set person = entity.person %}
+{% set activeRouteKey = '' %}
+
+{% block title %}
+{% include('@ChillMain/CRUD/_edit_title.html.twig') %}
+{% endblock title %}
+
+{% block content %}
+{% embed '@ChillMain/CRUD/_edit_content.html.twig' %}
+ {% block content_form_actions_back %}
+
+
+ {{ 'Cancel'|trans }}
+
+
+ {% endblock %}
+{% endembed %}
+{% endblock %}
diff --git a/src/Bundle/ChillJobBundle/src/Resources/views/Frein/new.html.twig b/src/Bundle/ChillJobBundle/src/Resources/views/Frein/new.html.twig
new file mode 100644
index 000000000..153f669be
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Resources/views/Frein/new.html.twig
@@ -0,0 +1,23 @@
+{% extends "@ChillPerson/Person/layout.html.twig" %}
+
+{% set person = entity.person %}
+{% set activeRouteKey = '' %}
+
+{% block title %}
+{% embed('@ChillPerson/CRUD/_new_title.html.twig') %}{% endembed %}
+{% endblock %}
+
+{% block content %}
+{% embed '@ChillMain/CRUD/_new_content.html.twig' %}
+ {% block crud_content_header %}
+ {{ ('crud.'~crud_name~'.title_new')|trans({'%person%': person|chill_entity_render_string }) }}
+ {% endblock crud_content_header %}
+ {% block content_form_actions_back %}
+
+
+ {{ 'Cancel'|trans }}
+
+
+ {% endblock %}
+{% endembed %}
+{% endblock %}
diff --git a/src/Bundle/ChillJobBundle/src/Resources/views/Frein/view.html.twig b/src/Bundle/ChillJobBundle/src/Resources/views/Frein/view.html.twig
new file mode 100644
index 000000000..a5ef2b350
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Resources/views/Frein/view.html.twig
@@ -0,0 +1,58 @@
+{% extends '@ChillPerson/CRUD/view.html.twig' %}
+
+{% block content %}
+{% embed '@ChillPerson/CRUD/_view_content.html.twig' %}
+ {% block crud_content_header %}
+ {{ ('crud.' ~ crud_name ~ '.title_view')|trans({'%person%': person|chill_entity_render_string }) }}
+ {% endblock crud_content_header %}
+
+ {% block crud_content_view_details %}
+
+ Date du rapport
+ {{ entity.reportDate|format_date('long') }}
+
+ Freins identifiés
+
+ {% if entity.freinsPerso|length > 0 %}
+
+ {% for e in entity.freinsPerso %}
+ {{ ('freins_perso.' ~ e)|trans }}
+ {% endfor %}
+
+ {% else %}
+ {{ null|chill_print_or_message("Aucun frein personnel renseigné") }}
+ {% endif %}
+
+ {% if entity.notesPerso is not empty %}
+ {{ entity.notesPerso|chill_print_or_message(null, 'blockquote') }}
+ {% endif %}
+
+
+ Freins d'accès à l'emploi
+
+ {% if entity.freinsEmploi|length > 0 %}
+
+ {% for e in entity.freinsEmploi %}
+ {{ ('freins_emploi.' ~ e)|trans }}
+ {% endfor %}
+
+ {% else %}
+ {{ null|chill_print_or_message("Aucun frein à l'emploi renseigné") }}
+ {% endif %}
+
+ {% if entity.notesEmploi is not empty %}
+ {{ entity.notesEmploi|chill_print_or_message(null, 'blockquote') }}
+ {% endif %}
+
+
+ {% endblock crud_content_view_details %}
+
+ {% block content_view_actions_back %}
+
+
+ {{ 'Cancel'|trans }}
+
+
+ {% endblock %}
+{% endembed %}
+{% endblock %}
diff --git a/src/Bundle/ChillJobBundle/src/Resources/views/Immersion/edit-bilan.html.twig b/src/Bundle/ChillJobBundle/src/Resources/views/Immersion/edit-bilan.html.twig
new file mode 100644
index 000000000..f126bcf40
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Resources/views/Immersion/edit-bilan.html.twig
@@ -0,0 +1,92 @@
+{% extends "@ChillPerson/Person/layout.html.twig" %}
+
+{% set person = entity.person %}
+{% set activeRouteKey = '' %}
+
+{% block title %}
+Bilan d'immersion
+{% endblock title %}
+
+{% block content %}
+{% embed '@ChillMain/CRUD/_edit_content.html.twig' %}
+ {% block crud_content_header %}
+ Bilan d'immersion
+ {% endblock crud_content_header %}
+
+ {% block content_form_actions_back %}
+
+
+ {{ 'Cancel'|trans }}
+
+
+ {% endblock %}
+
+ {% block crud_content_form_rows %}
+
+ Immersion du {{ entity.debutDate|format_date('long') }} au {{ entity.getDateEndComputed|format_date('long') }},
+ auprès de
{{ entity.entreprise.name }}
+ Domaine d'activité: {{ entity.domaineActivite }}
+
+ Modifier
+
+
+ Savoir-être du jeune
+
+ {{ form_widget(form.savoirEtre) }}
+
+ {{ form_row(form.savoirEtreNote) }}
+
+ Ponctualité
+
+ {{ form_row(form.ponctualiteSalarie) }}
+ {{ form_row(form.ponctualiteSalarieNote) }}
+
+ Assiduité
+ {{ form_row(form.assiduite) }}
+ {{ form_row(form.assiduiteNote) }}
+
+ Intégration
+ {{ form_row(form.interetActivite) }}
+ {{ form_row(form.interetActiviteNote) }}
+
+ {{ form_row(form.integreRegle) }}
+ {{ form_row(form.integreRegleNote) }}
+
+ Autonomie
+ {{ form_row(form.espritInitiative) }}
+ {{ form_row(form.espritInitiativeNote) }}
+
+ {{ form_row(form.organisation) }}
+ {{ form_row(form.organisationNote) }}
+
+ Attitude
+ {{ form_row(form.capaciteTravailEquipe) }}
+ {{ form_row(form.capaciteTravailEquipeNote) }}
+
+ Posture professionnelle
+ {{ form_row(form.styleVestimentaire) }}
+ {{ form_row(form.styleVestimentaireNote) }}
+
+ {{ form_row(form.langageProf) }}
+ {{ form_row(form.langageProfNote) }}
+
+ Relation avec la hiérarchie
+ {{ form_row(form.appliqueConsigne) }}
+ {{ form_row(form.appliqueConsigneNote) }}
+
+ {{ form_row(form.respectHierarchie) }}
+ {{ form_row(form.respectHierarchieNote) }}
+
+ Savoir-faire développés
+
+ {{ form_row(form.principalesActivites) }}
+ {{ form_row(form.competencesAcquises) }}
+ {{ form_row(form.competencesADevelopper) }}
+
+ Notes
+
+ {{ form_widget(form.noteBilan) }}
+
+ {% endblock %}
+{% endembed %}
+{% endblock %}
diff --git a/src/Bundle/ChillJobBundle/src/Resources/views/Immersion/edit.html.twig b/src/Bundle/ChillJobBundle/src/Resources/views/Immersion/edit.html.twig
new file mode 100644
index 000000000..e327ddad3
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Resources/views/Immersion/edit.html.twig
@@ -0,0 +1,71 @@
+{% extends "@ChillPerson/Person/layout.html.twig" %}
+
+{% set person = entity.person %}
+{% set activeRouteKey = '' %}
+
+{% block css %}
+ {{ encore_entry_link_tags('mod_pickentity_type') }}
+{% endblock %}
+
+{% block title %}
+{% include('@ChillMain/CRUD/_edit_title.html.twig') %}
+{% endblock title %}
+
+{% block content %}
+{% embed '@ChillMain/CRUD/_edit_content.html.twig' %}
+ {% block content_form_actions_back %}
+
+
+ {{ 'Cancel'|trans }}
+
+
+ {% endblock %}
+
+ {% block crud_content_form_rows %}
+ {{ form_row(form.entreprise) }}
+ {{ form_row(form.domaineActivite) }}
+
+ Tuteur
+
+ {{ form_row(form.tuteurName) }}
+ {{ form_row(form.tuteurFonction) }}
+ {{ form_row(form.tuteurPhoneNumber) }}
+
+ Structure d'accompagnement
+
+ {{ form_row(form.structureAccName) }}
+ {{ form_row(form.structureAccPhonenumber) }}
+ {{ form_row(form.structureAccEmail) }}
+ {{ form_widget(form.structureAccAddress) }}
+
+ Descriptif du poste occupé
+
+ {{ form_row(form.posteTitle) }}
+ {{ form_row(form.posteLieu) }}
+ {{ form_row(form.debutDate) }}
+ {{ form_row(form.duration) }}
+ {{ form_row(form.horaire) }}
+
+ Objectifs
+
+
+ {{ form_widget(form.objectifs) }}
+
+
+
+ {{ form_row(form.objectifsAutre) }}
+
+
+ Notes
+
+ {{ form_widget(form.noteImmersion) }}
+
+ {% endblock %}
+{% endembed %}
+{% endblock %}
+
+{% block js %}
+ {{ parent() }}
+ {{ encore_entry_script_tags('mod_pickentity_type') }}
+
+{% endblock %}
diff --git a/src/Bundle/ChillJobBundle/src/Resources/views/Immersion/new.html.twig b/src/Bundle/ChillJobBundle/src/Resources/views/Immersion/new.html.twig
new file mode 100644
index 000000000..e10722fed
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Resources/views/Immersion/new.html.twig
@@ -0,0 +1,75 @@
+{% extends "@ChillPerson/Person/layout.html.twig" %}
+
+{% set person = entity.person %}
+{% set activeRouteKey = '' %}
+
+{% block css %}
+ {{ encore_entry_link_tags('mod_pickentity_type') }}
+{% endblock %}
+
+{% block title %}
+{% embed('@ChillPerson/CRUD/_new_title.html.twig') %}{% endembed %}
+{% endblock %}
+
+{% block content %}
+{% embed '@ChillMain/CRUD/_new_content.html.twig' %}
+ {% block crud_content_header %}
+ {{ ('crud.'~crud_name~'.title_new')|trans({'%person%': person|chill_entity_render_string }) }}
+ {% endblock crud_content_header %}
+ {% block content_form_actions_back %}
+
+
+ {{ 'Cancel'|trans }}
+
+
+ {% endblock %}
+
+ {% block crud_content_form_rows %}
+ {{ form_row(form.entreprise) }}
+ {{ form_row(form.domaineActivite) }}
+
+ Tuteur
+
+ {{ form_row(form.tuteurName) }}
+ {{ form_row(form.tuteurFonction) }}
+ {{ form_row(form.tuteurPhoneNumber) }}
+
+ Structure d'accompagnement
+
+ {{ form_row(form.structureAccName) }}
+ {{ form_row(form.structureAccPhonenumber) }}
+ {{ form_row(form.structureAccEmail) }}
+ {{ form_widget(form.structureAccAddress) }}
+
+ Descriptif du poste occupé
+
+ {{ form_row(form.posteTitle) }}
+ {{ form_row(form.posteLieu) }}
+ {{ form_row(form.debutDate) }}
+ {{ form_row(form.duration) }}
+ {{ form_row(form.horaire) }}
+
+ Objectifs
+
+
+ {{ form_widget(form.objectifs) }}
+
+
+
+ {{ form_row(form.objectifsAutre) }}
+
+
+ Notes
+
+ {{ form_widget(form.noteImmersion) }}
+
+ {% endblock %}
+{% endembed %}
+{% endblock %}
+
+{% block js %}
+ {{ parent() }}
+ {{ encore_entry_script_tags('mod_pickentity_type') }}
+
+
+{% endblock %}
diff --git a/src/Bundle/ChillJobBundle/src/Resources/views/Immersion/view.html.twig b/src/Bundle/ChillJobBundle/src/Resources/views/Immersion/view.html.twig
new file mode 100644
index 000000000..3dda01fbd
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Resources/views/Immersion/view.html.twig
@@ -0,0 +1,222 @@
+{% extends '@ChillPerson/CRUD/view.html.twig' %}
+
+{% block content %}
+{% embed '@ChillPerson/CRUD/_view_content.html.twig' %}
+ {% block crud_content_header %}
+ {{ ('crud.' ~ crud_name ~ '.title_view')|trans({'%person%': person|chill_entity_render_string }) }}
+ {% endblock crud_content_header %}
+
+ {% block crud_content_view_details %}
+{# {% import 'ChillMainBundle:Address:macro.html.twig' as macro_address %}#}
+
+
+ Entreprise
+
+ Entreprise
+ {{ entity.entreprise|chill_entity_render_box({'with_valid_from': false}) }}
+
+ Domaine d'activité
+ {{ entity.domaineActivite }}
+
+ Tuteur
+
+ Nom du tuteur
+ {{ entity.tuteurName }}
+
+ Fonction du tuteur
+ {{ entity.tuteurFonction }}
+
+ {% if entity.tuteurPhoneNumber is not empty %}
+ Téléphone du tuteur
+
+ {{ entity.tuteurPhoneNumber|chill_format_phonenumber }}
+
+ {% endif %}
+
+ Structure d'accompagnement
+
+ Nom de la structure
+ {{ entity.structureAccName }}
+
+ Addresse mail de la structure
+ {{ entity.structureAccEmail }}
+
+ {% if entity.structureAccPhonenumber is not empty %}
+ Téléphone de la structure
+
+ {{ entity.structureAccPhonenumber|chill_format_phonenumber }}
+
+ {% endif %}
+
+{# #}
+{# {% for el in ['structureAccName', 'structureAccPhonenumber', 'structureAccEmail'] %}#}
+{# {% set el_data = attribute(entity, el) %}#}
+{# {% if el_data is not empty %}{{ el_data }} {% endif %}#}
+{# {% endfor %}#}
+{# {% if entity.structureAccAddress is not empty %}#}
+{# {{ macro_address._render(entity.structureAccAddress, { 'with_valid_from': false }) }}#}
+{# {% endif %}#}
+{# #}
+
+ Poste occupé
+
+ Titre
+ {{ entity.posteTitle|chill_print_or_message }}
+
+ Lieu du poste
+ {{ entity.posteLieu|chill_print_or_message }}
+
+ Dates
+ Du {{ entity.debutDate|format_date('long') }}
+ au {{ entity.getDateEndComputed|format_date('long') }}
+
+
+ Horaire
+ {{ entity.horaire|nl2br }}
+
+ Objectifs
+
+ Objectifs
+
+ {% for el in entity.objectifs %}
+ {% if loop.first %}{% endif %}
+ {{ ('immersion_objectif.' ~ el)|trans }}
+ {% if loop.last %} {% endif %}
+ {% else %}
+ Aucun objectif renseigné
+ {% endfor %}
+
+ {% if 'autre' in entity.objectifs and entity.objectifsAutre is not empty %}
+ Précisions:
+
+ {{ entity.objectifsAutre|nl2br }}
+
+ {% endif %}
+
+
+ Note
+
+
+ {{ entity.noteImmersion|chill_print_or_message('Aucune note') }}
+
+
+ {% if entity.isBilanFullfilled %}
+ Bilan
+
+ Savoir-êtres du jeune
+
+ Savoir-être du jeune
+
+ {% for el in entity.savoirEtre %}
+ {% if loop.first %}{% endif %}
+ {{ ('immersion_savoir_etre.' ~ el)|trans }}
+ {% if loop.last %} {% endif %}
+ {% else %}
+ Aucun élément indiqué
+ {% endfor %}
+
+ {% if entity.savoirEtreNote is not empty %}
+ {{ entity.savoirEtreNote|chill_print_or_message(null, 'blockquote') }}
+ {% endif %}
+
+
+ {% for line in [
+ ['Ponctualité'],
+ ['ponctualiteSalarie', "Ponctualité du salarié"],
+ ['Assiduité'],
+ ['assiduite', "Assiduité"],
+ ['Intégration'],
+ ['interetActivite', "La personne s’intéresse à l’ensemble des activités et membres de l’entreprise"],
+ ['integreRegle', "La personne a intégré les règles (les principes) de l’entreprise"],
+ ['Autonomie'],
+ ['espritInitiative', "La personne fait preuve d’esprit d’initiative"],
+ ['organisation', "La personne a fait preuve d’organisation"],
+ ['Attitude'],
+ ['capaciteTravailEquipe', "Capacité à travailler à en équipe"],
+ ['Posture professionnelle'],
+ ['styleVestimentaire', 'Style vestimentaire adapté'],
+ ['langageProf', "Langage professionnel"],
+ ['Relation avec la hiérarchie'],
+ ['appliqueConsigne', "Applique les consignes"],
+ ['respectHierarchie', "Respecte les niveaux hiérarchiques"],
+ ] %}
+ {% if line|length == 1 %}
+ {{ line[0] }}
+ {% else %}
+
+ {{ line[1] }}
+
+ {% set attr = attribute(entity, line[0]) %}
+ {% if attr != null %}
+ {% if attr in constant('Chill\\JobBundle\\Entity\\Immersion::YES_NO_NSP') %}
+ {{ ('immersion_nsp.'~attr)|trans }}
+ {% else %}
+ {{ ('immersion_' ~ line[0] ~ '.' ~ attr)|trans }}
+ {% endif %}
+ {% else %}
+ {{ null|chill_print_or_message("Aucune information") }}
+ {% endif %}
+ {% set note = attribute(entity, (line[0] ~ 'Note')) %}
+ {% if note != null %}
+ {{ note|chill_print_or_message(null, 'blockquote') }}
+ {% endif %}
+
+ {% endif %}
+ {% endfor %}
+
+ {% if entity.principalesActivites is not empty
+ or entity.competencesAcquises is not empty
+ or entity.competencesADevelopper is not empty %}
+ Savoir-faire développés
+
+ {% for el in ['principalesActivites', 'competencesAcquises','competencesADevelopper'] %}
+ {% set data = attribute(entity, el) %}
+ {% if data is not empty %}
+ {% if el == 'principalesActivites' %}
+ Principales activités
+ {% elseif el == 'competencesAcquises' %}
+ Compétences acquises
+ {% else %}
+ Compétences à développer
+ {% endif %}
+
+ {{ data|chill_print_or_message(null, 'blockquote') }}
+
+ {% endif %}
+ {% endfor %}
+
+ {% endif %}
+
+ {% if entity.noteBilan is not empty %}
+ Note
+
+
+ {{ entity.noteBilan|chill_print_or_message(null, 'blockquote') }}
+
+
+ {% endif %}
+ {% endif %}
+
+ {% endblock crud_content_view_details %}
+
+ {% block content_view_actions_back %}
+
+
+ {{ 'Cancel'|trans }}
+
+
+ {% endblock %}
+ {% block content_view_actions_after %}
+
+
+
+ Bilan
+
+
+ {% endblock %}
+{% endembed %}
+{% endblock %}
+
+{% block css %}
+
+{% endblock %}
diff --git a/src/Bundle/ChillJobBundle/src/Resources/views/ProjetProfessionnel/edit.html.twig b/src/Bundle/ChillJobBundle/src/Resources/views/ProjetProfessionnel/edit.html.twig
new file mode 100644
index 000000000..ec58011b2
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Resources/views/ProjetProfessionnel/edit.html.twig
@@ -0,0 +1,52 @@
+{% extends "@ChillPerson/Person/layout.html.twig" %}
+
+{% set person = entity.person %}
+{% set activeRouteKey = '' %}
+
+{% block title %}
+{% include('@ChillMain/CRUD/_edit_title.html.twig') %}
+{% endblock title %}
+
+{% block content %}
+{% embed '@ChillMain/CRUD/_edit_content.html.twig' %}
+ {% block crud_content_header %}
+ {{ ('crud.'~crud_name~'.title_edit')|trans({'%person%': person|chill_entity_render_string }) }}
+ {% endblock crud_content_header %}
+
+ {% block crud_content_form_rows %}
+ {{ form_row(form.reportDate) }}
+
+ Orientation souhaitée
+
+ {{ form_row(form.souhait) }}
+ {{ form_row(form.domaineActiviteSouhait) }}
+
+ {{ form_row(form.typeContrat) }}
+ {{ form_row(form.typeContratNotes) }}
+
+ {{ form_row(form.volumeHoraire) }}
+ {{ form_row(form.volumeHoraireNotes) }}
+
+ Projet professionnel
+
+ {{ form_row(form.idee) }}
+ {{ form_row(form.enCoursConstruction) }}
+
+ {{ form_row(form.valide) }}
+ {{ form_row(form.domaineActiviteValide) }}
+ {{ form_row(form.valideNotes) }}
+
+ Notes
+
+ {{ form_widget(form.projetProfessionnelNote) }}
+ {% endblock %}
+
+ {% block content_form_actions_back %}
+
+
+ {{ 'Cancel'|trans }}
+
+
+ {% endblock %}
+{% endembed %}
+{% endblock %}
diff --git a/src/Bundle/ChillJobBundle/src/Resources/views/ProjetProfessionnel/new.html.twig b/src/Bundle/ChillJobBundle/src/Resources/views/ProjetProfessionnel/new.html.twig
new file mode 100644
index 000000000..34d5b9b39
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Resources/views/ProjetProfessionnel/new.html.twig
@@ -0,0 +1,52 @@
+{% extends "@ChillPerson/Person/layout.html.twig" %}
+
+{% set person = entity.person %}
+{% set activeRouteKey = '' %}
+
+{% block title %}
+{% embed('@ChillPerson/CRUD/_new_title.html.twig') %}{% endembed %}
+{% endblock %}
+
+{% block content %}
+{% embed '@ChillMain/CRUD/_new_content.html.twig' %}
+ {% block crud_content_header %}
+ {{ ('crud.'~crud_name~'.title_new')|trans({'%person%': person|chill_entity_render_string }) }}
+ {% endblock crud_content_header %}
+
+ {% block crud_content_form_rows %}
+ {{ form_row(form.reportDate) }}
+
+ Orientation souhaitée
+
+ {{ form_row(form.souhait) }}
+ {{ form_row(form.domaineActiviteSouhait) }}
+
+ {{ form_row(form.typeContrat) }}
+ {{ form_row(form.typeContratNotes) }}
+
+ {{ form_row(form.volumeHoraire) }}
+ {{ form_row(form.volumeHoraireNotes) }}
+
+ Projet professionnel
+
+ {{ form_row(form.idee) }}
+ {{ form_row(form.enCoursConstruction) }}
+
+ {{ form_row(form.valide) }}
+ {{ form_row(form.domaineActiviteValide) }}
+ {{ form_row(form.valideNotes) }}
+
+ Notes
+
+ {{ form_widget(form.projetProfessionnelNote) }}
+ {% endblock %}
+
+ {% block content_form_actions_back %}
+
+
+ {{ 'Cancel'|trans }}
+
+
+ {% endblock %}
+{% endembed %}
+{% endblock %}
diff --git a/src/Bundle/ChillJobBundle/src/Resources/views/ProjetProfessionnel/view.html.twig b/src/Bundle/ChillJobBundle/src/Resources/views/ProjetProfessionnel/view.html.twig
new file mode 100644
index 000000000..535a77a20
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Resources/views/ProjetProfessionnel/view.html.twig
@@ -0,0 +1,108 @@
+{% extends '@ChillPerson/CRUD/view.html.twig' %}
+
+{% block content %}
+{% embed '@ChillPerson/CRUD/_view_content.html.twig' %}
+ {% block crud_content_header %}
+ {{ ('crud.' ~ crud_name ~ '.title_view')|trans({'%person%': person|chill_entity_render_string }) }}
+ {% endblock crud_content_header %}
+
+ {% block crud_content_view_details %}
+
+ Date
+ {{ entity.reportDate|format_date('long') }}
+
+ Souhaits
+
+ Orientation souhaitée
+
+ {% for r in entity.souhait %}
+ {% if loop.first %}{% endif %}
+ {{ r.libelle }} ({{ r.metier.code }} - {{ r.metier.libelle }})
+ {% if loop.last %} {% endif %}
+ {% else %}
+ Aucune orientation indiquée
+ {% endfor %}
+ {% if entity.domaineActiviteSouhait is not empty %}
+ Domaine d'activité souhaité :
+ {{ entity.domaineActiviteSouhait|nl2br }}
+ {% endif %}
+
+
+ Type de contrat recherché
+
+ {% for type in entity.typeContrat %}
+ {% if loop.first %}{% endif %}
+ {{ ('projet_prof.type_contrat.' ~ type)|trans }}
+ {% if loop.last %} {% endif %}
+ {% endfor %}
+
+ {% if entity.typeContratNotes is not empty %}
+ {{ entity.typeContratNotes|nl2br }}
+ {% endif %}
+
+
+ Volume horaire souhaité
+
+ {% for type in entity.volumeHoraire %}
+ {% if loop.first %}{% endif %}
+ {{ ('projet_prof.volume_horaire.' ~ type)|trans }}
+ {% if loop.last %} {% endif %}
+ {% endfor %}
+
+ {% if entity.volumeHoraireNotes is not empty %}
+ {{ entity.volumeHoraireNotes|nl2br }}
+ {% endif %}
+
+
+ Projet professionnel
+
+ Idée
+
+ {{ entity.idee|chill_print_or_message('Aucune information', 'blockquote') }}
+
+
+ En cours de construction
+
+ {{ entity.enCoursConstruction|chill_print_or_message('Aucune information', 'blockquote') }}
+
+
+ Validé
+
+ {% for r in entity.valide %}
+ {% if loop.first %}{% endif %}
+ {{ r.libelle }} ({{ r.metier.code }} - {{ r.metier.libelle }})
+ {% if loop.last %} {% endif %}
+ {% else %}
+ Aucune orientation indiquée
+ {% endfor %}
+
+ {% if entity.valideNotes is not empty %}
+
+ {{ entity.valideNotes|nl2br }}
+
+ {% endif %}
+ {% if entity.domaineActiviteValide is not empty %}
+ Domaine d'activité validé :
+ {{ entity.domaineActiviteValide|nl2br }}
+ {% endif %}
+
+
+
+ Notes
+
+ {{ entity.projetProfessionnelNote|chill_print_or_message('Aucune note', 'blockquote') }}
+
+
+ {% endblock crud_content_view_details %}
+
+ {% block content_view_actions_back %}
+
+
+ {{ 'Cancel'|trans }}
+
+
+ {% endblock %}
+ {% block content_view_actions_after %}
+ {% endblock %}
+{% endembed %}
+{% endblock %}
diff --git a/src/Bundle/ChillJobBundle/src/Resources/views/Report/delete.html.twig b/src/Bundle/ChillJobBundle/src/Resources/views/Report/delete.html.twig
new file mode 100644
index 000000000..9b98e174d
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Resources/views/Report/delete.html.twig
@@ -0,0 +1,16 @@
+{% extends '@ChillMain/layout.html.twig' %}
+
+{% set person = entity.person %}
+{% set activeRouteKey = '' %}
+
+{% block content %}
+{% embed '@ChillMain/CRUD/_delete_content.html.twig' %}
+ {% block content_form_actions_back %}
+
+
+ {{ 'Cancel'|trans }}
+
+
+ {% endblock %}
+{% endembed %}
+{% endblock %}
diff --git a/src/Bundle/ChillJobBundle/src/Resources/views/Report/index.html.twig b/src/Bundle/ChillJobBundle/src/Resources/views/Report/index.html.twig
new file mode 100644
index 000000000..cc6cca86e
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Resources/views/Report/index.html.twig
@@ -0,0 +1,253 @@
+{% extends '@ChillPerson/Person/layout.html.twig' %}
+
+{% set activeRouteKey = '' %}
+
+{% block content %}
+
+
Rapports pour {{ person|chill_entity_render_string }}
+
+ {% if cvs is defined %}
+
CV
+
+ {% if cvs|length == 0 %}
+
{{ null|chill_print_or_message("Aucun CV enregistré") }}
+ {% else %}
+
+
+
+ Date
+
+
+
+
+ {% for cv in cvs %}
+
+ {{ cv.reportDate|format_date('short') }}
+
+
+
+
+
+
+
+
+ {% if is_granted('CHILL_JOB_REPORT_DELETE', cv) %}
+
+
+
+ {% endif %}
+
+
+
+ {% endfor %}
+
+
+ {% endif %}
+
+
+ {% endif %}
+
+ {% if freins is defined %}
+
Freins
+
+ {% if freins|length == 0 %}
+
{{ null|chill_print_or_message("Aucun rapport enregistré") }}
+ {% else %}
+
+
+
+ Date
+ Freins identifiés
+
+
+
+
+ {% for frein in freins %}
+
+ {{ frein.reportDate|format_date('short') }}
+
+ {% if frein.freinsPerso|merge(frein.freinsEmploi)|length > 0 %}
+
+ {% for e in frein.freinsPerso %}
+ {{ ('freins_perso.' ~ e)|trans }}
+ {% endfor %}
+ {% for e in frein.freinsEmploi %}
+ {{ ('freins_emploi.' ~ e)|trans }}
+ {% endfor %}
+
+ {% else %}
+ {{ null|chill_print_or_message("Aucun frein renseigné") }}
+ {% endif %}
+
+
+
+
+
+
+
+
+
+ {% if is_granted('CHILL_JOB_REPORT_DELETE', frein) %}
+
+
+
+ {% endif %}
+
+
+
+ {% endfor %}
+
+
+ {% endif %}
+
+
+
+ {% endif %}
+
+ {% if immersions is defined %}
+
Immersions
+
+ {% if immersions|length == 0 %}
+
{{ null|chill_print_or_message("Aucun rapport enregistré") }}
+ {% else %}
+
+
+
+ Date de début de l'immersion
+ Entreprise
+
+
+
+
+ {% for im in immersions %}
+
+ {{ im.debutDate|format_date('short') }}
+
+ {{ im.entreprise.name }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {% if is_granted('CHILL_JOB_REPORT_DELETE', im) %}
+
+
+
+ {% endif %}
+
+
+
+
+ {% endfor %}
+
+
+ {% endif %}
+
+
+ {% endif %}
+
+ {% if projet_professionnels is defined %}
+
+
Projets professionnels
+
+ {% if projet_professionnels|length == 0 %}
+
{{ null|chill_print_or_message("Aucun rapport enregistré") }}
+ {% else %}
+
+
+
+ Date de création
+ Projet validé ou souhaité
+ Type de contrat
+
+
+
+
+ {% for pr in projet_professionnels %}
+
+ {{ pr.reportDate|format_date('short') }}
+
+ {% set romes = [] %}
+ {% if pr.valide|length > 0 %}
+ Projet validé :
+ {% set romes = pr.valide %}
+ {% elseif pr.souhait|length > 0 %}
+ Projet souhaité :
+ {% set romes = pr.souhait %}
+ {% else %}
+ Aucun souhait rempli
+ {% endif %}
+
+
+ {% for a in romes %}
+ {{ a.libelle }} ({{ a.metier.code }} - {{ a.metier.libelle }})
+ {% endfor %}
+
+
+
+
+ {% for type in pr.typeContrat %}
+ {{ ('projet_prof.type_contrat.' ~ type)|trans }}
+ {% endfor %}
+
+
+
+
+
+
+
+
+
+
+ {% if is_granted('CHILL_JOB_REPORT_DELETE', pr) %}
+
+
+
+ {% endif %}
+
+
+
+
+ {% endfor %}
+
+
+ {% endif %}
+
+
+ {% endif %}
+
+
+{% endblock %}
diff --git a/src/Bundle/ChillJobBundle/src/Security/Authorization/ExportsJobVoter.php b/src/Bundle/ChillJobBundle/src/Security/Authorization/ExportsJobVoter.php
new file mode 100644
index 000000000..af4935893
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Security/Authorization/ExportsJobVoter.php
@@ -0,0 +1,122 @@
+authorizationHelper = $authorizationHelper;
+ }
+
+ /**
+ * @return bool
+ */
+ protected function supports($attribute, $subject)
+ {
+ if ($subject instanceof Center) {
+ return self::EXPORT === $attribute;
+ }
+ if (null === $subject) {
+ return self::EXPORT === $attribute;
+ }
+
+ return false;
+ }
+
+ /**
+ * @return bool
+ */
+ protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
+ {
+ $user = $token->getUser();
+
+ if (!$user instanceof User) {
+ return false;
+ }
+
+ $centers = $this->authorizationHelper->getReachableCenters($user, $attribute);
+
+ if (null === $subject) {
+ return count($centers) > 0;
+ }
+
+ return $this->authorizationHelper->userHasAccess($user, $subject, $attribute);
+ }
+
+ /**
+ * Return an array of roles, where keys are the hierarchy, and values
+ * an array of roles.
+ *
+ * Example:
+ *
+ * ```
+ * [ 'Title' => [ 'CHILL_FOO_SEE', 'CHILL_FOO_UPDATE' ] ]
+ * ```
+ */
+ public function getRolesWithHierarchy(): array
+ {
+ return ['JobBundle' => $this->getRoles()];
+ }
+
+ /**
+ * return an array of role provided by the object.
+ *
+ * @return string[] array of roles (as string)
+ */
+ public function getRoles(): array
+ {
+ return $this->getAttributes();
+ }
+
+ /**
+ * return roles which doesn't need.
+ *
+ * @return string[] array of roles without scopes
+ */
+ public function getRolesWithoutScope(): array
+ {
+ return $this->getAttributes();
+ }
+
+ /**
+ * @return array
+ */
+ private function getAttributes()
+ {
+ return [self::EXPORT];
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/Security/Authorization/JobVoter.php b/src/Bundle/ChillJobBundle/src/Security/Authorization/JobVoter.php
new file mode 100644
index 000000000..54de180f5
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Security/Authorization/JobVoter.php
@@ -0,0 +1,119 @@
+date15DaysAgo = new \DateTime('-15 days');
+ $this->authorizationHelper = $authorizationHelper;
+ }
+
+ protected function supports($attribute, $subject)
+ {
+ if (!\in_array($attribute, self::ALL, true)) {
+ return false;
+ }
+
+ if ($subject instanceof Frein
+ || $subject instanceof CV
+ || $subject instanceof Immersion
+ || $subject instanceof ProjetProfessionnel
+ || $subject instanceof Person) {
+ return true;
+ }
+
+ return false;
+ }
+
+ protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
+ {
+ if ($subject instanceof Person) {
+ $center = $subject->getCenter();
+ } else {
+ $center = $subject->getPerson()->getCenter();
+ }
+
+ switch ($attribute) {
+ case self::REPORT_NEW:
+ return $this->authorizationHelper->userHasAccess($token->getUser(), $center, $attribute);
+
+ case self::REPORT_CV:
+ if (! ($subject instanceof CV || $subject instanceof Person)) {
+ return false;
+ }
+
+ return $this->authorizationHelper->userHasAccess($token->getUser(), $center, $attribute);
+
+ case self::REPORT_DELETE:
+ if ($subject instanceof Immersion) {
+ $date = \DateTimeImmutable::createFromMutable($subject->getDebutDate())->add($subject->getDuration());
+ } else {
+ $date = $subject->getReportDate();
+ }
+
+ if (!$this->authorizationHelper->userHasAccess($token->getUser(), $center, $attribute)) {
+ return false;
+ }
+
+ return $this->date15DaysAgo < $date;
+ }
+
+ return true;
+ }
+
+ public function getRoles(): array
+ {
+ return self::ALL;
+ }
+
+ public function getRolesWithHierarchy(): array
+ {
+ return ['JobBundle' => $this->getRoles()];
+ }
+
+ public function getRolesWithoutScope(): array
+ {
+ return $this->getRoles();
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/Tests/Controller/CSPersonControllerTest.php b/src/Bundle/ChillJobBundle/src/Tests/Controller/CSPersonControllerTest.php
new file mode 100644
index 000000000..a6b19e648
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/Tests/Controller/CSPersonControllerTest.php
@@ -0,0 +1,21 @@
+addSql('CREATE SCHEMA chill_job');
+ $this->addSql('CREATE SEQUENCE chill_job.cv_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
+ $this->addSql('CREATE SEQUENCE chill_job.cv_experience_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
+ $this->addSql('CREATE SEQUENCE chill_job.cv_formation_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
+ $this->addSql('CREATE SEQUENCE chill_job.frein_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
+ $this->addSql('CREATE SEQUENCE chill_job.immersion_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
+ $this->addSql('CREATE SEQUENCE chill_job.projet_professionnel_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
+ $this->addSql('CREATE SEQUENCE chill_job.rome_appellation_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
+ $this->addSql('CREATE SEQUENCE chill_job.rome_metier_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
+ $this->addSql('CREATE TABLE chill_job.cs_person (id INT NOT NULL, person_id INT DEFAULT NULL, prescripteur_id INT DEFAULT NULL, situationLogement VARCHAR(255) DEFAULT NULL, situationLogementPrecision TEXT DEFAULT NULL, enfantACharge INT DEFAULT NULL, niveauMaitriseLangue JSONB DEFAULT NULL, vehiculePersonnel BOOLEAN DEFAULT NULL, permisConduire JSONB DEFAULT NULL, situationProfessionnelle VARCHAR(255) DEFAULT NULL, dateFinDernierEmploi DATE DEFAULT NULL, typeContrat JSONB DEFAULT NULL, typeContratAide TEXT DEFAULT NULL, ressources JSONB DEFAULT NULL, ressourcesComment TEXT DEFAULT NULL, ressourceDate1Versement DATE DEFAULT NULL, CPFMontant NUMERIC(10, 2) DEFAULT NULL, acomptedif NUMERIC(10, 2) DEFAULT NULL, accompagnement JSONB DEFAULT NULL, accompagnementRQTHDate DATE DEFAULT NULL, accompagnementComment VARCHAR(255) DEFAULT NULL, poleEmploiId VARCHAR(255) DEFAULT NULL, poleEmploiInscriptionDate DATE DEFAULT NULL, cafId VARCHAR(255) DEFAULT NULL, cafInscriptionDate DATE DEFAULT NULL, CERInscriptionDate DATE DEFAULT NULL, PPAEInscriptionDate DATE DEFAULT NULL, CERSignataire TEXT DEFAULT NULL, PPAESignataire TEXT DEFAULT NULL, NEETEligibilite VARCHAR(255) DEFAULT NULL, NEETCommissionDate DATE DEFAULT NULL, FSEMaDemarcheCode TEXT DEFAULT NULL, datecontratIEJ DATE DEFAULT NULL, dateavenantIEJ DATE DEFAULT NULL, dispositifs_notes TEXT DEFAULT NULL, handicap BOOLEAN DEFAULT NULL, handicapnotes TEXT DEFAULT NULL, handicapRecommandation VARCHAR(50) DEFAULT NULL, mobilitemoyentransport JSONB DEFAULT NULL, mobilitenotes TEXT DEFAULT NULL, handicapAccompagnement_id INT DEFAULT NULL, documentCV_id INT DEFAULT NULL, documentAgrementIAE_id INT DEFAULT NULL, documentRQTH_id INT DEFAULT NULL, documentAttestationNEET_id INT DEFAULT NULL, documentCI_id INT DEFAULT NULL, documentTitreSejour_id INT DEFAULT NULL, documentAttestationFiscale_id INT DEFAULT NULL, documentPermis_id INT DEFAULT NULL, documentAttestationCAAF_id INT DEFAULT NULL, documentContraTravail_id INT DEFAULT NULL, documentAttestationFormation_id INT DEFAULT NULL, documentQuittanceLoyer_id INT DEFAULT NULL, documentFactureElectricite_id INT DEFAULT NULL, documentAttestationSecuriteSociale_id INT DEFAULT NULL, PRIMARY KEY(id))');
+ $this->addSql('CREATE UNIQUE INDEX UNIQ_10864F31217BBB47 ON chill_job.cs_person (person_id)');
+ $this->addSql('CREATE INDEX IDX_10864F312654B57D ON chill_job.cs_person (handicapAccompagnement_id)');
+ $this->addSql('CREATE INDEX IDX_10864F3154866550 ON chill_job.cs_person (documentCV_id)');
+ $this->addSql('CREATE INDEX IDX_10864F318825E118 ON chill_job.cs_person (documentAgrementIAE_id)');
+ $this->addSql('CREATE INDEX IDX_10864F31A396AFAC ON chill_job.cs_person (documentRQTH_id)');
+ $this->addSql('CREATE INDEX IDX_10864F3187541764 ON chill_job.cs_person (documentAttestationNEET_id)');
+ $this->addSql('CREATE INDEX IDX_10864F315CFC2299 ON chill_job.cs_person (documentCI_id)');
+ $this->addSql('CREATE INDEX IDX_10864F3134FDF11D ON chill_job.cs_person (documentTitreSejour_id)');
+ $this->addSql('CREATE INDEX IDX_10864F315742C99D ON chill_job.cs_person (documentAttestationFiscale_id)');
+ $this->addSql('CREATE INDEX IDX_10864F31166494D4 ON chill_job.cs_person (documentPermis_id)');
+ $this->addSql('CREATE INDEX IDX_10864F3172820D66 ON chill_job.cs_person (documentAttestationCAAF_id)');
+ $this->addSql('CREATE INDEX IDX_10864F31AFA5E636 ON chill_job.cs_person (documentContraTravail_id)');
+ $this->addSql('CREATE INDEX IDX_10864F3161E05C22 ON chill_job.cs_person (documentAttestationFormation_id)');
+ $this->addSql('CREATE INDEX IDX_10864F316F744BB0 ON chill_job.cs_person (documentQuittanceLoyer_id)');
+ $this->addSql('CREATE INDEX IDX_10864F31AC39B1B ON chill_job.cs_person (documentFactureElectricite_id)');
+ $this->addSql('CREATE INDEX IDX_10864F3172A75B6D ON chill_job.cs_person (documentAttestationSecuriteSociale_id)');
+ $this->addSql('CREATE INDEX IDX_10864F31D486E642 ON chill_job.cs_person (prescripteur_id)');
+ $this->addSql('CREATE TABLE chill_job.cv (id INT NOT NULL, person_id INT DEFAULT NULL, reportDate DATE NOT NULL, formationLevel VARCHAR(255) DEFAULT NULL, formationType VARCHAR(255) DEFAULT NULL, spokenLanguages JSONB DEFAULT NULL, notes TEXT DEFAULT NULL, PRIMARY KEY(id))');
+ $this->addSql('CREATE INDEX IDX_3F24F812217BBB47 ON chill_job.cv (person_id)');
+ $this->addSql('CREATE TABLE chill_job.cv_experience (id INT NOT NULL, poste TEXT DEFAULT NULL, structure TEXT DEFAULT NULL, startDate DATE DEFAULT NULL, endDate DATE DEFAULT NULL, contratType VARCHAR(100) NOT NULL, notes TEXT DEFAULT NULL, CV_id INT DEFAULT NULL, PRIMARY KEY(id))');
+ $this->addSql('CREATE INDEX IDX_102A1262AE1799D8 ON chill_job.cv_experience (CV_id)');
+ $this->addSql('CREATE TABLE chill_job.cv_formation (id INT NOT NULL, title TEXT NOT NULL, startDate DATE DEFAULT NULL, endDate DATE DEFAULT NULL, diplomaObtained VARCHAR(255) DEFAULT NULL, diplomaReconnue VARCHAR(50) DEFAULT NULL, organisme TEXT DEFAULT NULL, CV_id INT DEFAULT NULL, PRIMARY KEY(id))');
+ $this->addSql('CREATE INDEX IDX_20BE09E2AE1799D8 ON chill_job.cv_formation (CV_id)');
+ $this->addSql('CREATE TABLE chill_job.frein (id INT NOT NULL, reportDate DATE NOT NULL, freinsPerso JSONB NOT NULL, notesPerso TEXT NOT NULL, freinsEmploi JSONB NOT NULL, notesEmploi TEXT NOT NULL, PRIMARY KEY(id))');
+ $this->addSql('CREATE TABLE chill_job.immersion (id INT NOT NULL, entreprise_id INT DEFAULT NULL, referent_id INT DEFAULT NULL, domaineActivite TEXT DEFAULT NULL, tuteurName TEXT DEFAULT NULL, tuteurFonction TEXT DEFAULT NULL, tuteurPhoneNumber TEXT DEFAULT NULL, structureAccName TEXT DEFAULT NULL, structureAccPhonenumber TEXT DEFAULT NULL, structureAccEmail TEXT DEFAULT NULL, posteDescriptif TEXT DEFAULT NULL, posteTitle TEXT DEFAULT NULL, posteLieu TEXT DEFAULT NULL, debutDate DATE DEFAULT NULL, duration INTERVAL DEFAULT NULL, horaire TEXT DEFAULT NULL, objectifs JSONB DEFAULT NULL, objectifsAutre TEXT DEFAULT NULL, is_bilan_fullfilled BOOLEAN DEFAULT false NOT NULL, savoirEtre JSONB DEFAULT NULL, savoirEtreNote TEXT DEFAULT NULL, noteimmersion TEXT, principalesActivites TEXT DEFAULT NULL, competencesAcquises TEXT DEFAULT NULL, competencesADevelopper TEXT DEFAULT NULL, noteBilan TEXT DEFAULT NULL, ponctualite_salarie TEXT DEFAULT NULL, ponctualite_salarie_note TEXT DEFAULT NULL, assiduite TEXT DEFAULT NULL, assiduite_note TEXT DEFAULT NULL, interet_activite TEXT DEFAULT NULL, interet_activite_note TEXT DEFAULT NULL, integre_regle TEXT DEFAULT NULL, integre_regle_note TEXT DEFAULT NULL, esprit_initiative TEXT DEFAULT NULL, esprit_initiative_note TEXT DEFAULT NULL, organisation TEXT DEFAULT NULL, organisation_note TEXT DEFAULT NULL, capacite_travail_equipe TEXT DEFAULT NULL, capacite_travail_equipe_note TEXT DEFAULT NULL, style_vestimentaire TEXT DEFAULT NULL, style_vestimentaire_note TEXT DEFAULT NULL, langage_prof TEXT DEFAULT NULL, langage_prof_note TEXT DEFAULT NULL, applique_consigne TEXT DEFAULT NULL, applique_consigne_note TEXT DEFAULT NULL, respect_hierarchie TEXT DEFAULT NULL, respect_hierarchie_note TEXT DEFAULT NULL, structureAccAddress_id INT DEFAULT NULL, PRIMARY KEY(id))');
+ $this->addSql('CREATE INDEX IDX_FBB3CBB4A4AEAFEA ON chill_job.immersion (entreprise_id)');
+ $this->addSql('CREATE INDEX IDX_FBB3CBB435E47E35 ON chill_job.immersion (referent_id)');
+ $this->addSql('CREATE INDEX IDX_FBB3CBB4B5E04267 ON chill_job.immersion (structureAccAddress_id)');
+ $this->addSql('COMMENT ON COLUMN chill_job.immersion.duration IS \'(DC2Type:dateinterval)\'');
+ $this->addSql('CREATE TABLE chill_job.projet_professionnel (id INT NOT NULL, reportDate DATE NOT NULL, domaineActiviteSouhait TEXT DEFAULT NULL, typeContrat JSONB DEFAULT NULL, typeContratNotes TEXT DEFAULT NULL, volumeHoraire JSONB DEFAULT NULL, volumeHoraireNotes TEXT DEFAULT NULL, idee TEXT DEFAULT NULL, enCoursConstruction TEXT DEFAULT NULL, domaineActiviteValide TEXT DEFAULT NULL, valideNotes TEXT DEFAULT NULL, projetProfessionnelNote TEXT DEFAULT NULL, PRIMARY KEY(id))');
+ $this->addSql('CREATE TABLE chill_job.projetprofessionnel_souhait (projetprofessionnel_id INT NOT NULL, appellation_id INT NOT NULL, PRIMARY KEY(projetprofessionnel_id, appellation_id))');
+ $this->addSql('CREATE INDEX IDX_3280B96DB87BF7B5 ON chill_job.projetprofessionnel_souhait (projetprofessionnel_id)');
+ $this->addSql('CREATE INDEX IDX_3280B96D7CDE30DD ON chill_job.projetprofessionnel_souhait (appellation_id)');
+ $this->addSql('CREATE TABLE chill_job.projetprofessionnel_valide (projetprofessionnel_id INT NOT NULL, appellation_id INT NOT NULL, PRIMARY KEY(projetprofessionnel_id, appellation_id))');
+ $this->addSql('CREATE INDEX IDX_E0501BE0B87BF7B5 ON chill_job.projetprofessionnel_valide (projetprofessionnel_id)');
+ $this->addSql('CREATE INDEX IDX_E0501BE07CDE30DD ON chill_job.projetprofessionnel_valide (appellation_id)');
+ $this->addSql('CREATE TABLE chill_job.rome_appellation (id INT NOT NULL, metier_id INT DEFAULT NULL, code VARCHAR(40) NOT NULL, libelle TEXT NOT NULL, PRIMARY KEY(id))');
+ $this->addSql('CREATE UNIQUE INDEX UNIQ_D9E9CABC77153098 ON chill_job.rome_appellation (code)');
+ $this->addSql('CREATE INDEX IDX_D9E9CABCED16FA20 ON chill_job.rome_appellation (metier_id)');
+ $this->addSql('CREATE TABLE chill_job.rome_metier (id INT NOT NULL, libelle TEXT NOT NULL, code VARCHAR(20) NOT NULL, PRIMARY KEY(id))');
+ $this->addSql('CREATE UNIQUE INDEX UNIQ_3274952577153098 ON chill_job.rome_metier (code)');
+ $this->addSql('ALTER TABLE chill_job.cs_person ADD CONSTRAINT FK_10864F31217BBB47 FOREIGN KEY (person_id) REFERENCES chill_person_person (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_job.cs_person ADD CONSTRAINT FK_10864F312654B57D FOREIGN KEY (handicapAccompagnement_id) REFERENCES chill_3party.third_party (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_job.cs_person ADD CONSTRAINT FK_10864F3154866550 FOREIGN KEY (documentCV_id) REFERENCES chill_doc.stored_object (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_job.cs_person ADD CONSTRAINT FK_10864F318825E118 FOREIGN KEY (documentAgrementIAE_id) REFERENCES chill_doc.stored_object (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_job.cs_person ADD CONSTRAINT FK_10864F31A396AFAC FOREIGN KEY (documentRQTH_id) REFERENCES chill_doc.stored_object (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_job.cs_person ADD CONSTRAINT FK_10864F3187541764 FOREIGN KEY (documentAttestationNEET_id) REFERENCES chill_doc.stored_object (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_job.cs_person ADD CONSTRAINT FK_10864F315CFC2299 FOREIGN KEY (documentCI_id) REFERENCES chill_doc.stored_object (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_job.cs_person ADD CONSTRAINT FK_10864F3134FDF11D FOREIGN KEY (documentTitreSejour_id) REFERENCES chill_doc.stored_object (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_job.cs_person ADD CONSTRAINT FK_10864F315742C99D FOREIGN KEY (documentAttestationFiscale_id) REFERENCES chill_doc.stored_object (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_job.cs_person ADD CONSTRAINT FK_10864F31166494D4 FOREIGN KEY (documentPermis_id) REFERENCES chill_doc.stored_object (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_job.cs_person ADD CONSTRAINT FK_10864F3172820D66 FOREIGN KEY (documentAttestationCAAF_id) REFERENCES chill_doc.stored_object (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_job.cs_person ADD CONSTRAINT FK_10864F31AFA5E636 FOREIGN KEY (documentContraTravail_id) REFERENCES chill_doc.stored_object (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_job.cs_person ADD CONSTRAINT FK_10864F3161E05C22 FOREIGN KEY (documentAttestationFormation_id) REFERENCES chill_doc.stored_object (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_job.cs_person ADD CONSTRAINT FK_10864F316F744BB0 FOREIGN KEY (documentQuittanceLoyer_id) REFERENCES chill_doc.stored_object (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_job.cs_person ADD CONSTRAINT FK_10864F31AC39B1B FOREIGN KEY (documentFactureElectricite_id) REFERENCES chill_doc.stored_object (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_job.cs_person ADD CONSTRAINT FK_10864F3172A75B6D FOREIGN KEY (documentAttestationSecuriteSociale_id) REFERENCES chill_doc.stored_object (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_job.cs_person ADD CONSTRAINT FK_10864F31D486E642 FOREIGN KEY (prescripteur_id) REFERENCES chill_3party.third_party (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_job.cv ADD CONSTRAINT FK_3F24F812217BBB47 FOREIGN KEY (person_id) REFERENCES chill_person_person (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_job.cv_experience ADD CONSTRAINT FK_102A1262AE1799D8 FOREIGN KEY (CV_id) REFERENCES chill_job.cv (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_job.cv_formation ADD CONSTRAINT FK_20BE09E2AE1799D8 FOREIGN KEY (CV_id) REFERENCES chill_job.cv (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_job.immersion ADD CONSTRAINT FK_FBB3CBB4A4AEAFEA FOREIGN KEY (entreprise_id) REFERENCES chill_3party.third_party (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_job.immersion ADD CONSTRAINT FK_FBB3CBB435E47E35 FOREIGN KEY (referent_id) REFERENCES users (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_job.immersion ADD CONSTRAINT FK_FBB3CBB4B5E04267 FOREIGN KEY (structureAccAddress_id) REFERENCES chill_main_address (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_job.projetprofessionnel_souhait ADD CONSTRAINT FK_3280B96DB87BF7B5 FOREIGN KEY (projetprofessionnel_id) REFERENCES chill_job.projet_professionnel (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_job.projetprofessionnel_souhait ADD CONSTRAINT FK_3280B96D7CDE30DD FOREIGN KEY (appellation_id) REFERENCES chill_job.rome_appellation (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_job.projetprofessionnel_valide ADD CONSTRAINT FK_E0501BE0B87BF7B5 FOREIGN KEY (projetprofessionnel_id) REFERENCES chill_job.projet_professionnel (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_job.projetprofessionnel_valide ADD CONSTRAINT FK_E0501BE07CDE30DD FOREIGN KEY (appellation_id) REFERENCES chill_job.rome_appellation (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_job.rome_appellation ADD CONSTRAINT FK_D9E9CABCED16FA20 FOREIGN KEY (metier_id) REFERENCES chill_job.rome_metier (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ }
+
+ public function down(Schema $schema): void
+ {
+ $this->addSql('DROP SEQUENCE chill_job.cv_id_seq CASCADE');
+ $this->addSql('DROP SEQUENCE chill_job.cv_experience_id_seq CASCADE');
+ $this->addSql('DROP SEQUENCE chill_job.cv_formation_id_seq CASCADE');
+ $this->addSql('DROP SEQUENCE chill_job.frein_id_seq CASCADE');
+ $this->addSql('DROP SEQUENCE chill_job.immersion_id_seq CASCADE');
+ $this->addSql('DROP SEQUENCE chill_job.projet_professionnel_id_seq CASCADE');
+ $this->addSql('DROP SEQUENCE chill_job.rome_appellation_id_seq CASCADE');
+ $this->addSql('DROP SEQUENCE chill_job.rome_metier_id_seq CASCADE');
+ $this->addSql('ALTER TABLE chill_job.cs_person DROP CONSTRAINT FK_10864F31217BBB47');
+ $this->addSql('ALTER TABLE chill_job.cs_person DROP CONSTRAINT FK_10864F312654B57D');
+ $this->addSql('ALTER TABLE chill_job.cs_person DROP CONSTRAINT FK_10864F3154866550');
+ $this->addSql('ALTER TABLE chill_job.cs_person DROP CONSTRAINT FK_10864F318825E118');
+ $this->addSql('ALTER TABLE chill_job.cs_person DROP CONSTRAINT FK_10864F31A396AFAC');
+ $this->addSql('ALTER TABLE chill_job.cs_person DROP CONSTRAINT FK_10864F3187541764');
+ $this->addSql('ALTER TABLE chill_job.cs_person DROP CONSTRAINT FK_10864F315CFC2299');
+ $this->addSql('ALTER TABLE chill_job.cs_person DROP CONSTRAINT FK_10864F3134FDF11D');
+ $this->addSql('ALTER TABLE chill_job.cs_person DROP CONSTRAINT FK_10864F315742C99D');
+ $this->addSql('ALTER TABLE chill_job.cs_person DROP CONSTRAINT FK_10864F31166494D4');
+ $this->addSql('ALTER TABLE chill_job.cs_person DROP CONSTRAINT FK_10864F3172820D66');
+ $this->addSql('ALTER TABLE chill_job.cs_person DROP CONSTRAINT FK_10864F31AFA5E636');
+ $this->addSql('ALTER TABLE chill_job.cs_person DROP CONSTRAINT FK_10864F3161E05C22');
+ $this->addSql('ALTER TABLE chill_job.cs_person DROP CONSTRAINT FK_10864F316F744BB0');
+ $this->addSql('ALTER TABLE chill_job.cs_person DROP CONSTRAINT FK_10864F31AC39B1B');
+ $this->addSql('ALTER TABLE chill_job.cs_person DROP CONSTRAINT FK_10864F3172A75B6D');
+ $this->addSql('ALTER TABLE chill_job.cs_person DROP CONSTRAINT FK_10864F31D486E642');
+ $this->addSql('ALTER TABLE chill_job.cv DROP CONSTRAINT FK_3F24F812217BBB47');
+ $this->addSql('ALTER TABLE chill_job.cv_experience DROP CONSTRAINT FK_102A1262AE1799D8');
+ $this->addSql('ALTER TABLE chill_job.cv_formation DROP CONSTRAINT FK_20BE09E2AE1799D8');
+ $this->addSql('ALTER TABLE chill_job.immersion DROP CONSTRAINT FK_FBB3CBB4A4AEAFEA');
+ $this->addSql('ALTER TABLE chill_job.immersion DROP CONSTRAINT FK_FBB3CBB435E47E35');
+ $this->addSql('ALTER TABLE chill_job.immersion DROP CONSTRAINT FK_FBB3CBB4B5E04267');
+ $this->addSql('ALTER TABLE chill_job.projetprofessionnel_souhait DROP CONSTRAINT FK_3280B96DB87BF7B5');
+ $this->addSql('ALTER TABLE chill_job.projetprofessionnel_souhait DROP CONSTRAINT FK_3280B96D7CDE30DD');
+ $this->addSql('ALTER TABLE chill_job.projetprofessionnel_valide DROP CONSTRAINT FK_E0501BE0B87BF7B5');
+ $this->addSql('ALTER TABLE chill_job.projetprofessionnel_valide DROP CONSTRAINT FK_E0501BE07CDE30DD');
+ $this->addSql('ALTER TABLE chill_job.rome_appellation DROP CONSTRAINT FK_D9E9CABCED16FA20');
+ $this->addSql('DROP TABLE chill_job.cs_person');
+ $this->addSql('DROP TABLE chill_job.cv');
+ $this->addSql('DROP TABLE chill_job.cv_experience');
+ $this->addSql('DROP TABLE chill_job.cv_formation');
+ $this->addSql('DROP TABLE chill_job.frein');
+ $this->addSql('DROP TABLE chill_job.immersion');
+ $this->addSql('DROP TABLE chill_job.projet_professionnel');
+ $this->addSql('DROP TABLE chill_job.projetprofessionnel_souhait');
+ $this->addSql('DROP TABLE chill_job.projetprofessionnel_valide');
+ $this->addSql('DROP TABLE chill_job.rome_appellation');
+ $this->addSql('DROP TABLE chill_job.rome_metier');
+ $this->addSql('DROP SCHEMA chill_job');
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/migrations/Version20240424140641.php b/src/Bundle/ChillJobBundle/src/migrations/Version20240424140641.php
new file mode 100644
index 000000000..87c9d3623
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/migrations/Version20240424140641.php
@@ -0,0 +1,46 @@
+addSql('ALTER TABLE chill_job.frein ADD person_id INT DEFAULT NULL');
+ $this->addSql('ALTER TABLE chill_job.frein ADD CONSTRAINT FK_172EAC0A217BBB47 FOREIGN KEY (person_id) REFERENCES chill_person_person (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('CREATE INDEX IDX_172EAC0A217BBB47 ON chill_job.frein (person_id)');
+ $this->addSql('ALTER TABLE chill_job.immersion ADD person_id INT DEFAULT NULL');
+ $this->addSql('ALTER TABLE chill_job.immersion ADD CONSTRAINT FK_FBB3CBB4217BBB47 FOREIGN KEY (person_id) REFERENCES chill_person_person (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('CREATE INDEX IDX_FBB3CBB4217BBB47 ON chill_job.immersion (person_id)');
+ $this->addSql('ALTER TABLE chill_job.projet_professionnel ADD person_id INT DEFAULT NULL');
+ $this->addSql('ALTER TABLE chill_job.projet_professionnel ADD CONSTRAINT FK_12E4FFBF217BBB47 FOREIGN KEY (person_id) REFERENCES chill_person_person (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('CREATE INDEX IDX_12E4FFBF217BBB47 ON chill_job.projet_professionnel (person_id)');
+ }
+
+ public function down(Schema $schema): void
+ {
+ $this->addSql('ALTER TABLE chill_job.projet_professionnel DROP CONSTRAINT FK_12E4FFBF217BBB47');
+ $this->addSql('ALTER TABLE chill_job.projet_professionnel DROP person_id');
+ $this->addSql('ALTER TABLE chill_job.immersion DROP CONSTRAINT FK_FBB3CBB4217BBB47');
+ $this->addSql('ALTER TABLE chill_job.immersion DROP person_id');
+ $this->addSql('ALTER TABLE chill_job.frein DROP CONSTRAINT FK_172EAC0A217BBB47');
+ $this->addSql('ALTER TABLE chill_job.frein DROP person_id');
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/migrations/Version20240429111628.php b/src/Bundle/ChillJobBundle/src/migrations/Version20240429111628.php
new file mode 100644
index 000000000..e12318d7c
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/migrations/Version20240429111628.php
@@ -0,0 +1,41 @@
+addSql('ALTER TABLE chill_job.immersion ALTER tuteurphonenumber TYPE VARCHAR(35)');
+ $this->addSql('COMMENT ON COLUMN chill_job.immersion.tuteurPhoneNumber IS \'(DC2Type:phone_number)\'');
+
+ $this->addSql('ALTER TABLE chill_job.immersion ALTER structureAccPhonenumber TYPE VARCHAR(35)');
+ $this->addSql('COMMENT ON COLUMN chill_job.immersion.structureAccPhonenumber IS \'(DC2Type:phone_number)\'');
+ }
+
+ public function down(Schema $schema): void
+ {
+ $this->addSql('ALTER TABLE chill_job.immersion ALTER tuteurPhoneNumber TYPE TEXT');
+ $this->addSql('COMMENT ON COLUMN chill_job.immersion.tuteurphonenumber IS NULL');
+
+ $this->addSql('ALTER TABLE chill_job.immersion ALTER structureAccPhonenumber TYPE TEXT');
+ $this->addSql('COMMENT ON COLUMN chill_job.immersion.structureAccPhonenumber IS NULL');
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/migrations/old/Version20191119172511.php b/src/Bundle/ChillJobBundle/src/migrations/old/Version20191119172511.php
new file mode 100644
index 000000000..6dccbec42
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/migrations/old/Version20191119172511.php
@@ -0,0 +1,114 @@
+skipIf(true, 'Skipping this old migration. Replaced by migration Version20240424095147');
+ $this->abortIf('postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.');
+
+ $this->addSql('CREATE SCHEMA chill_csconnectes');
+ $this->addSql('CREATE TABLE chill_csconnectes.cs_person (
+ id INT NOT NULL,
+ person_id INT NOT NULL,
+ prescripteur_id INT DEFAULT NULL,
+ situationLogement VARCHAR(255) DEFAULT NULL,
+ enfantACharge INT DEFAULT NULL,
+ niveauMaitriseLangue JSONB DEFAULT NULL,
+ vehiculePersonnel BOOLEAN DEFAULT NULL,
+ permisConduire JSONB DEFAULT NULL,
+ situationProfessionnelle VARCHAR(255) DEFAULT NULL,
+ dateFinDernierEmploi DATE DEFAULT NULL,
+ typeContrat JSONB DEFAULT NULL,
+ ressources JSONB DEFAULT NULL,
+ ressourcesComment TEXT DEFAULT NULL,
+ ressourceDate1Versement DATE DEFAULT NULL,
+ CPFNombreHeures INT DEFAULT NULL,
+ accompagnement JSONB DEFAULT NULL,
+ accompagnementRQTHDate DATE DEFAULT NULL,
+ accompagnementComment VARCHAR(255) DEFAULT NULL,
+ poleEmploiId VARCHAR(255) DEFAULT NULL,
+ poleEmploiInscriptionDate DATE DEFAULT NULL,
+ cafId VARCHAR(255) DEFAULT NULL,
+ cafInscriptionDate DATE DEFAULT NULL,
+ CERInscriptionDate DATE DEFAULT NULL,
+ PPAEInscriptionDate DATE DEFAULT NULL,
+ NEETEligibilite BOOLEAN DEFAULT NULL,
+ NEETCommissionDate DATE DEFAULT NULL,
+ FSEMaDemarcheCode TEXT DEFAULT NULL,
+ documentCV_id INT DEFAULT NULL,
+ documentAgrementIAE_id INT DEFAULT NULL,
+ documentRQTH_id INT DEFAULT NULL,
+ documentAttestationNEET_id INT DEFAULT NULL,
+ documentCI_id INT DEFAULT NULL,
+ documentTitreSejour_id INT DEFAULT NULL,
+ documentAttestationFiscale_id INT DEFAULT NULL,
+ documentPermis_id INT DEFAULT NULL,
+ documentAttestationCAAF_id INT DEFAULT NULL,
+ documentContraTravail_id INT DEFAULT NULL,
+ documentAttestationFormation_id INT DEFAULT NULL,
+ documentQuittanceLoyer_id INT DEFAULT NULL,
+ documentFactureElectricite_id INT DEFAULT NULL,
+ PRIMARY KEY(id, person_id))');
+ $this->addSql('CREATE INDEX IDX_10864F31217BBB47 ON chill_csconnectes.cs_person (person_id)');
+ $this->addSql('CREATE INDEX IDX_10864F3154866550 ON chill_csconnectes.cs_person (documentCV_id)');
+ $this->addSql('CREATE INDEX IDX_10864F318825E118 ON chill_csconnectes.cs_person (documentAgrementIAE_id)');
+ $this->addSql('CREATE INDEX IDX_10864F31A396AFAC ON chill_csconnectes.cs_person (documentRQTH_id)');
+ $this->addSql('CREATE INDEX IDX_10864F3187541764 ON chill_csconnectes.cs_person (documentAttestationNEET_id)');
+ $this->addSql('CREATE INDEX IDX_10864F315CFC2299 ON chill_csconnectes.cs_person (documentCI_id)');
+ $this->addSql('CREATE INDEX IDX_10864F3134FDF11D ON chill_csconnectes.cs_person (documentTitreSejour_id)');
+ $this->addSql('CREATE INDEX IDX_10864F315742C99D ON chill_csconnectes.cs_person (documentAttestationFiscale_id)');
+ $this->addSql('CREATE INDEX IDX_10864F31166494D4 ON chill_csconnectes.cs_person (documentPermis_id)');
+ $this->addSql('CREATE INDEX IDX_10864F3172820D66 ON chill_csconnectes.cs_person (documentAttestationCAAF_id)');
+ $this->addSql('CREATE INDEX IDX_10864F31AFA5E636 ON chill_csconnectes.cs_person (documentContraTravail_id)');
+ $this->addSql('CREATE INDEX IDX_10864F3161E05C22 ON chill_csconnectes.cs_person (documentAttestationFormation_id)');
+ $this->addSql('CREATE INDEX IDX_10864F316F744BB0 ON chill_csconnectes.cs_person (documentQuittanceLoyer_id)');
+ $this->addSql('CREATE INDEX IDX_10864F31AC39B1B ON chill_csconnectes.cs_person (documentFactureElectricite_id)');
+ $this->addSql('CREATE INDEX IDX_10864F31D486E642 ON chill_csconnectes.cs_person (prescripteur_id)');
+ $this->addSql('ALTER TABLE chill_csconnectes.cs_person ADD CONSTRAINT FK_10864F31217BBB47 FOREIGN KEY (person_id) REFERENCES chill_person_person (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_csconnectes.cs_person ADD CONSTRAINT FK_10864F3154866550 FOREIGN KEY (documentCV_id) REFERENCES chill_doc.stored_object (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_csconnectes.cs_person ADD CONSTRAINT FK_10864F318825E118 FOREIGN KEY (documentAgrementIAE_id) REFERENCES chill_doc.stored_object (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_csconnectes.cs_person ADD CONSTRAINT FK_10864F31A396AFAC FOREIGN KEY (documentRQTH_id) REFERENCES chill_doc.stored_object (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_csconnectes.cs_person ADD CONSTRAINT FK_10864F3187541764 FOREIGN KEY (documentAttestationNEET_id) REFERENCES chill_doc.stored_object (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_csconnectes.cs_person ADD CONSTRAINT FK_10864F315CFC2299 FOREIGN KEY (documentCI_id) REFERENCES chill_doc.stored_object (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_csconnectes.cs_person ADD CONSTRAINT FK_10864F3134FDF11D FOREIGN KEY (documentTitreSejour_id) REFERENCES chill_doc.stored_object (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_csconnectes.cs_person ADD CONSTRAINT FK_10864F315742C99D FOREIGN KEY (documentAttestationFiscale_id) REFERENCES chill_doc.stored_object (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_csconnectes.cs_person ADD CONSTRAINT FK_10864F31166494D4 FOREIGN KEY (documentPermis_id) REFERENCES chill_doc.stored_object (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_csconnectes.cs_person ADD CONSTRAINT FK_10864F3172820D66 FOREIGN KEY (documentAttestationCAAF_id) REFERENCES chill_doc.stored_object (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_csconnectes.cs_person ADD CONSTRAINT FK_10864F31AFA5E636 FOREIGN KEY (documentContraTravail_id) REFERENCES chill_doc.stored_object (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_csconnectes.cs_person ADD CONSTRAINT FK_10864F3161E05C22 FOREIGN KEY (documentAttestationFormation_id) REFERENCES chill_doc.stored_object (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_csconnectes.cs_person ADD CONSTRAINT FK_10864F316F744BB0 FOREIGN KEY (documentQuittanceLoyer_id) REFERENCES chill_doc.stored_object (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_csconnectes.cs_person ADD CONSTRAINT FK_10864F31AC39B1B FOREIGN KEY (documentFactureElectricite_id) REFERENCES chill_doc.stored_object (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_csconnectes.cs_person ADD CONSTRAINT FK_10864F31D486E642 FOREIGN KEY (prescripteur_id) REFERENCES chill_3party.third_party (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('COMMENT ON COLUMN chill_csconnectes.cs_person.niveauMaitriseLangue IS NULL');
+ $this->addSql('COMMENT ON COLUMN chill_csconnectes.cs_person.permisConduire IS NULL');
+ $this->addSql('COMMENT ON COLUMN chill_csconnectes.cs_person.typeContrat IS NULL');
+ $this->addSql('COMMENT ON COLUMN chill_csconnectes.cs_person.ressources IS NULL');
+ $this->addSql('COMMENT ON COLUMN chill_csconnectes.cs_person.accompagnement IS NULL');
+ }
+
+ public function down(Schema $schema): void
+ {
+ $this->abortIf('postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.');
+
+ $this->addSql('DROP TABLE chill_csconnectes.cs_person');
+ $this->addSql('DROP SCHEMA chill_csconnectes CASCADE');
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/migrations/old/Version20191129112321.php b/src/Bundle/ChillJobBundle/src/migrations/old/Version20191129112321.php
new file mode 100644
index 000000000..85ca4e137
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/migrations/old/Version20191129112321.php
@@ -0,0 +1,60 @@
+skipIf(true, 'Skipping this old migration. Replaced by migration Version20240424095147');
+ $this->abortIf('postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.');
+
+ $this->addSql('DROP INDEX chill_csconnectes.IDX_10864f31217bbb47');
+ $this->addSql('ALTER TABLE chill_csconnectes.cs_person ADD CERSignataire TEXT DEFAULT NULL');
+ $this->addSql('ALTER TABLE chill_csconnectes.cs_person ADD PPAESignataire TEXT DEFAULT NULL');
+ $this->addSql('COMMENT ON COLUMN chill_csconnectes.cs_person.niveauMaitriseLangue IS NULL');
+ $this->addSql('COMMENT ON COLUMN chill_csconnectes.cs_person.permisConduire IS NULL');
+ $this->addSql('COMMENT ON COLUMN chill_csconnectes.cs_person.typeContrat IS NULL');
+ $this->addSql('COMMENT ON COLUMN chill_csconnectes.cs_person.ressources IS NULL');
+ $this->addSql('COMMENT ON COLUMN chill_csconnectes.cs_person.accompagnement IS NULL');
+ $this->addSql('CREATE UNIQUE INDEX UNIQ_10864F31217BBB47 ON chill_csconnectes.cs_person (person_id)');
+ $this->addSql('ALTER TABLE chill_csconnectes.cs_person DROP CONSTRAINT cs_person_pkey');
+ $this->addSql('ALTER TABLE chill_csconnectes.cs_person ADD PRIMARY KEY (id)');
+ $this->addSql('ALTER TABLE chill_csconnectes.cs_person ALTER person_id DROP NOT NULL');
+ }
+
+ public function down(Schema $schema): void
+ {
+ $this->throwIrreversibleMigrationException('this migration is not reversible ('
+ .'actions on primary keys)');
+ $this->abortIf('postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.');
+
+ $this->addSql('DROP INDEX UNIQ_10864F31217BBB47');
+ $this->addSql('DROP INDEX cs_person_pkey');
+ $this->addSql('ALTER TABLE chill_csconnectes.cs_person DROP CERSignataire');
+ $this->addSql('ALTER TABLE chill_csconnectes.cs_person DROP PPAESignataire');
+ $this->addSql('ALTER TABLE chill_csconnectes.cs_person ALTER person_id SET NOT NULL');
+ $this->addSql('COMMENT ON COLUMN chill_csconnectes.cs_person.niveaumaitriselangue IS \'(DC2Type:json_array)\'');
+ $this->addSql('COMMENT ON COLUMN chill_csconnectes.cs_person.permisconduire IS \'(DC2Type:json_array)\'');
+ $this->addSql('COMMENT ON COLUMN chill_csconnectes.cs_person.typecontrat IS \'(DC2Type:json_array)\'');
+ $this->addSql('COMMENT ON COLUMN chill_csconnectes.cs_person.ressources IS \'(DC2Type:json_array)\'');
+ $this->addSql('COMMENT ON COLUMN chill_csconnectes.cs_person.accompagnement IS \'(DC2Type:json_array)\'');
+ $this->addSql('CREATE INDEX idx_10864f31217bbb47 ON chill_csconnectes.cs_person (person_id)');
+ $this->addSql('ALTER TABLE chill_csconnectes.cs_person ADD PRIMARY KEY (id, person_id)');
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/migrations/old/Version20200113104411.php b/src/Bundle/ChillJobBundle/src/migrations/old/Version20200113104411.php
new file mode 100644
index 000000000..1fb74f5f0
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/migrations/old/Version20200113104411.php
@@ -0,0 +1,53 @@
+skipIf(true, 'Skipping this old migration. Replaced by migration Version20240424095147');
+ $this->abortIf('postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.');
+
+ $this->addSql('CREATE SEQUENCE chill_csconnectes.immersion_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
+ $this->addSql('CREATE TABLE chill_csconnectes.immersion (id INT NOT NULL, person_id INT DEFAULT NULL, entreprise_id INT DEFAULT NULL, referent_id INT DEFAULT NULL, domaineActivite TEXT DEFAULT NULL, tuteurName TEXT DEFAULT NULL, tuteurFonction TEXT DEFAULT NULL, tuteurPhoneNumber TEXT DEFAULT NULL, structureAccName TEXT DEFAULT NULL, structureAccPhonenumber TEXT DEFAULT NULL, posteDescriptif TEXT DEFAULT NULL, posteTitle TEXT DEFAULT NULL, posteLieu TEXT DEFAULT NULL, debutDate DATE DEFAULT NULL, duration INTERVAL DEFAULT NULL, horaire TEXT DEFAULT NULL, objectifs JSONB DEFAULT NULL, savoirEtre JSONB DEFAULT NULL, noteimmersion TEXT NOT NULL, principalesActivites TEXT DEFAULT NULL, competencesAcquises TEXT DEFAULT NULL, competencesADevelopper TEXT DEFAULT NULL, noteBilan TEXT DEFAULT NULL, PRIMARY KEY(id))');
+ $this->addSql('CREATE INDEX IDX_FBB3CBB4217BBB47 ON chill_csconnectes.immersion (person_id)');
+ $this->addSql('CREATE INDEX IDX_FBB3CBB4A4AEAFEA ON chill_csconnectes.immersion (entreprise_id)');
+ $this->addSql('CREATE INDEX IDX_FBB3CBB435E47E35 ON chill_csconnectes.immersion (referent_id)');
+ $this->addSql('COMMENT ON COLUMN chill_csconnectes.immersion.duration IS \'(DC2Type:dateinterval)\'');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion ADD CONSTRAINT FK_FBB3CBB4217BBB47 FOREIGN KEY (person_id) REFERENCES chill_person_person (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion ADD CONSTRAINT FK_FBB3CBB4A4AEAFEA FOREIGN KEY (entreprise_id) REFERENCES chill_3party.third_party (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion ADD CONSTRAINT FK_FBB3CBB435E47E35 FOREIGN KEY (referent_id) REFERENCES users (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+
+ $this->addSql('CREATE TABLE chill_csconnectes.cv_formation (id INT NOT NULL, title TEXT NOT NULL, startDate DATE DEFAULT NULL, endDate DATE DEFAULT NULL, diplomaObtained VARCHAR(255) DEFAULT NULL, diplomaReconnue VARCHAR(50) DEFAULT NULL, organisme TEXT DEFAULT NULL, CV_id INT DEFAULT NULL, PRIMARY KEY(id))');
+ $this->addSql('CREATE INDEX IDX_20BE09E2AE1799D8 ON chill_csconnectes.cv_formation (CV_id)');
+ $this->addSql('ALTER TABLE chill_csconnectes.cv_formation ADD CONSTRAINT FK_20BE09E2AE1799D8 FOREIGN KEY (CV_id) REFERENCES chill_csconnectes.cv (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ }
+
+ public function down(Schema $schema): void
+ {
+ $this->abortIf('postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.');
+
+ $this->addSql('DROP SEQUENCE chill_csconnectes.immersion_id_seq CASCADE');
+ $this->addSql('DROP TABLE chill_csconnectes.immersion');
+
+ $this->addSql('DROP SEQUENCE chill_csconnectes.cv_formation_id_seq CASCADE');
+ $this->addSql('ALTER TABLE chill_csconnectes.cv_formation DROP CONSTRAINT FK_20BE09E2AE1799D8');
+ $this->addSql('DROP TABLE chill_csconnectes.cv_formation');
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/migrations/old/Version20200113142525.php b/src/Bundle/ChillJobBundle/src/migrations/old/Version20200113142525.php
new file mode 100644
index 000000000..cabc97d59
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/migrations/old/Version20200113142525.php
@@ -0,0 +1,43 @@
+skipIf(true, 'Skipping this old migration. Replaced by migration Version20240424095147');
+ $this->abortIf('postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.');
+
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion ADD structureAccEmail TEXT DEFAULT NULL');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion ADD structureAccAddress_id INT DEFAULT NULL');
+ $this->addSql('CREATE INDEX IDX_FBB3CBB4B5E04267 ON chill_csconnectes.immersion (structureAccAddress_id)');
+ }
+
+ public function down(Schema $schema): void
+ {
+ $this->abortIf('postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.');
+
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion DROP structureAccEmail');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion DROP structureAccAddress_id');
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/migrations/old/Version20200114081435.php b/src/Bundle/ChillJobBundle/src/migrations/old/Version20200114081435.php
new file mode 100644
index 000000000..a03263bf3
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/migrations/old/Version20200114081435.php
@@ -0,0 +1,44 @@
+skipIf(true, 'Skipping this old migration. Replaced by migration Version20240424095147');
+ $this->abortIf('postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.');
+
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion ADD is_bilan_fullfilled BOOLEAN DEFAULT \'false\' NOT NULL');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion ADD savoirEtreNote TEXT DEFAULT NULL');
+ $this->addSql('COMMENT ON COLUMN chill_csconnectes.immersion.savoirEtre IS NULL');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion ADD CONSTRAINT FK_FBB3CBB4B5E04267 FOREIGN KEY (structureAccAddress_id) REFERENCES chill_main_address (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ }
+
+ public function down(Schema $schema): void
+ {
+ $this->abortIf('postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.');
+
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion DROP CONSTRAINT FK_FBB3CBB4B5E04267');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion DROP is_bilan_fullfilled');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion DROP savoirEtreNote');
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/migrations/old/Version20200124130244.php b/src/Bundle/ChillJobBundle/src/migrations/old/Version20200124130244.php
new file mode 100644
index 000000000..dd1e669ae
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/migrations/old/Version20200124130244.php
@@ -0,0 +1,36 @@
+skipIf(true, 'Skipping this old migration. Replaced by migration Version20240424095147');
+ $this->abortIf('postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.');
+
+ $this->addSql('ALTER TABLE chill_csconnectes.cs_person ADD datecontratIEJ DATE DEFAULT NULL');
+ }
+
+ public function down(Schema $schema): void
+ {
+ $this->abortIf('postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.');
+
+ $this->addSql('ALTER TABLE chill_csconnectes.cs_person DROP datecontratIEJ');
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/migrations/old/Version20200124132321.php b/src/Bundle/ChillJobBundle/src/migrations/old/Version20200124132321.php
new file mode 100644
index 000000000..3cf1b3019
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/migrations/old/Version20200124132321.php
@@ -0,0 +1,36 @@
+skipIf(true, 'Skipping this old migration. Replaced by migration Version20240424095147');
+ $this->abortIf('postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.');
+
+ $this->addSql('ALTER TABLE chill_csconnectes.cs_person ADD typeContratAide TEXT DEFAULT NULL');
+ }
+
+ public function down(Schema $schema): void
+ {
+ $this->abortIf('postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.');
+
+ $this->addSql('ALTER TABLE chill_csconnectes.cs_person DROP typeContratAide');
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/migrations/old/Version20200127132932.php b/src/Bundle/ChillJobBundle/src/migrations/old/Version20200127132932.php
new file mode 100644
index 000000000..2907c2155
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/migrations/old/Version20200127132932.php
@@ -0,0 +1,36 @@
+skipIf(true, 'Skipping this old migration. Replaced by migration Version20240424095147');
+ $this->abortIf('postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.');
+
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion ADD objectifsAutre TEXT DEFAULT NULL');
+ }
+
+ public function down(Schema $schema): void
+ {
+ $this->abortIf('postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.');
+
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion DROP objectifsAutre');
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/migrations/old/Version20200205132532.php b/src/Bundle/ChillJobBundle/src/migrations/old/Version20200205132532.php
new file mode 100644
index 000000000..1372aa308
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/migrations/old/Version20200205132532.php
@@ -0,0 +1,83 @@
+skipIf(true, 'Skipping this old migration. Replaced by migration Version20240424095147');
+ $this->abortIf('postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.');
+
+ // $this->addSql('DROP SEQUENCE report_id_seq CASCADE');
+ $this->addSql('CREATE SEQUENCE chill_csconnectes.rome_appellation_id_seq '
+ .'INCREMENT BY 1 MINVALUE 1 START 1');
+ $this->addSql('CREATE SEQUENCE chill_csconnectes.rome_metier_id_seq '
+ .'INCREMENT BY 1 MINVALUE 1 START 1');
+ $this->addSql('CREATE SEQUENCE chill_csconnectes.projet_professionnel_id_seq '
+ .'INCREMENT BY 1 MINVALUE 1 START 1');
+ $this->addSql('CREATE SEQUENCE chill_csconnectes.cv_formation_id_seq '
+ .'INCREMENT BY 1 MINVALUE 1 START 1');
+ $this->addSql('CREATE TABLE chill_csconnectes.rome_appellation ('
+ .'id INT NOT NULL, metier_id INT DEFAULT NULL, code VARCHAR(40) NOT NULL, '
+ .'libelle TEXT NOT NULL, PRIMARY KEY(id))');
+ $this->addSql('CREATE INDEX IDX_D9E9CABCED16FA20 ON chill_csconnectes.rome_appellation (metier_id)');
+ $this->addSql('CREATE TABLE chill_csconnectes.rome_metier (id INT NOT NULL, '
+ .'libelle TEXT NOT NULL, code VARCHAR(20) NOT NULL, PRIMARY KEY(id))');
+ $this->addSql('CREATE TABLE chill_csconnectes.projet_professionnel (id INT NOT NULL, '
+ .'person_id INT DEFAULT NULL, reportDate DATE NOT NULL, '
+ .'typeContrat JSONB DEFAULT NULL, typeContratNotes TEXT DEFAULT NULL, '
+ .'volumeHoraire JSONB DEFAULT NULL, volumeHoraireNotes TEXT DEFAULT NULL, '
+ .'idee TEXT DEFAULT NULL, enCoursConstruction TEXT DEFAULT NULL, '
+ .'valideNotes TEXT DEFAULT NULL, projetProfessionnelNote TEXT DEFAULT NULL, '
+ .'PRIMARY KEY(id))');
+ $this->addSql('CREATE INDEX IDX_12E4FFBF217BBB47 ON chill_csconnectes.projet_professionnel (person_id)');
+ $this->addSql('CREATE TABLE chill_csconnectes.projetprofessionnel_souhait (projetprofessionnel_id INT NOT NULL, appellation_id INT NOT NULL, PRIMARY KEY(projetprofessionnel_id, appellation_id))');
+ $this->addSql('CREATE INDEX IDX_3280B96DB87BF7B5 ON chill_csconnectes.projetprofessionnel_souhait (projetprofessionnel_id)');
+ $this->addSql('CREATE INDEX IDX_3280B96D7CDE30DD ON chill_csconnectes.projetprofessionnel_souhait (appellation_id)');
+ $this->addSql('CREATE TABLE chill_csconnectes.projetprofessionnel_valide (projetprofessionnel_id INT NOT NULL, appellation_id INT NOT NULL, PRIMARY KEY(projetprofessionnel_id, appellation_id))');
+ $this->addSql('CREATE INDEX IDX_E0501BE0B87BF7B5 ON chill_csconnectes.projetprofessionnel_valide (projetprofessionnel_id)');
+ $this->addSql('CREATE INDEX IDX_E0501BE07CDE30DD ON chill_csconnectes.projetprofessionnel_valide (appellation_id)');
+ $this->addSql('ALTER TABLE chill_csconnectes.rome_appellation ADD CONSTRAINT FK_D9E9CABCED16FA20 FOREIGN KEY (metier_id) REFERENCES chill_csconnectes.rome_metier (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_csconnectes.projet_professionnel ADD CONSTRAINT FK_12E4FFBF217BBB47 FOREIGN KEY (person_id) REFERENCES chill_person_person (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_csconnectes.projetprofessionnel_souhait ADD CONSTRAINT FK_3280B96DB87BF7B5 FOREIGN KEY (projetprofessionnel_id) REFERENCES chill_csconnectes.projet_professionnel (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_csconnectes.projetprofessionnel_souhait ADD CONSTRAINT FK_3280B96D7CDE30DD FOREIGN KEY (appellation_id) REFERENCES chill_csconnectes.rome_appellation (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_csconnectes.projetprofessionnel_valide ADD CONSTRAINT FK_E0501BE0B87BF7B5 FOREIGN KEY (projetprofessionnel_id) REFERENCES chill_csconnectes.projet_professionnel (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_csconnectes.projetprofessionnel_valide ADD CONSTRAINT FK_E0501BE07CDE30DD FOREIGN KEY (appellation_id) REFERENCES chill_csconnectes.rome_appellation (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
+ }
+
+ public function down(Schema $schema): void
+ {
+ $this->abortIf('postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.');
+
+ $this->addSql('ALTER TABLE chill_csconnectes.projetprofessionnel_souhait DROP CONSTRAINT FK_3280B96D7CDE30DD');
+ $this->addSql('ALTER TABLE chill_csconnectes.projetprofessionnel_valide DROP CONSTRAINT FK_E0501BE07CDE30DD');
+ $this->addSql('ALTER TABLE chill_csconnectes.rome_appellation DROP CONSTRAINT FK_D9E9CABCED16FA20');
+ $this->addSql('ALTER TABLE chill_csconnectes.projetprofessionnel_souhait DROP CONSTRAINT FK_3280B96DB87BF7B5');
+ $this->addSql('ALTER TABLE chill_csconnectes.projetprofessionnel_valide DROP CONSTRAINT FK_E0501BE0B87BF7B5');
+ $this->addSql('DROP SEQUENCE chill_csconnectes.rome_appellation_id_seq CASCADE');
+ $this->addSql('DROP SEQUENCE chill_csconnectes.rome_metier_id_seq CASCADE');
+ $this->addSql('DROP SEQUENCE chill_csconnectes.projet_professionnel_id_seq CASCADE');
+
+ $this->addSql('DROP TABLE chill_csconnectes.rome_appellation');
+ $this->addSql('DROP TABLE chill_csconnectes.rome_metier');
+ $this->addSql('DROP TABLE chill_csconnectes.projet_professionnel');
+ $this->addSql('DROP TABLE chill_csconnectes.projetprofessionnel_souhait');
+ $this->addSql('DROP TABLE chill_csconnectes.projetprofessionnel_valide');
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/migrations/old/Version20200207224152.php b/src/Bundle/ChillJobBundle/src/migrations/old/Version20200207224152.php
new file mode 100644
index 000000000..6fecfda82
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/migrations/old/Version20200207224152.php
@@ -0,0 +1,38 @@
+skipIf(true, 'Skipping this old migration. Replaced by migration Version20240424095147');
+ $this->abortIf('postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.');
+
+ $this->addSql('CREATE INDEX code_appellation_idx ON chill_csconnectes.rome_appellation (code)');
+ $this->addSql('CREATE INDEX code_metier_idx ON chill_csconnectes.rome_metier (code)');
+ }
+
+ public function down(Schema $schema): void
+ {
+ $this->abortIf('postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.');
+
+ $this->addSql('DROP INDEX code_appellation_idx ON chill_csconnectes.rome_appellation');
+ $this->addSql('DROP INDEX code_metier_idx ON chill_csconnectes.rome_metier');
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/migrations/old/Version20200210105342.php b/src/Bundle/ChillJobBundle/src/migrations/old/Version20200210105342.php
new file mode 100644
index 000000000..53d88ec2b
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/migrations/old/Version20200210105342.php
@@ -0,0 +1,36 @@
+skipIf(true, 'Skipping this old migration. Replaced by migration Version20240424095147');
+ $this->addSql('CREATE UNIQUE INDEX UNIQ_D9E9CABC77153098 ON chill_csconnectes.rome_appellation (code);');
+ $this->addSql('CREATE UNIQUE INDEX UNIQ_3274952577153098 ON chill_csconnectes.rome_metier (code);');
+ $this->addSql('DROP INDEX IF EXISTS chill_csconnectes.code_metier_idx ');
+ $this->addSql('DROP INDEX IF EXISTS chill_csconnectes.code_appellation_idx ');
+ }
+
+ public function down(Schema $schema): void
+ {
+ $this->addSql('DROP INDEX chill_csconnectes.UNIQ_D9E9CABC77153098');
+ $this->addSql('DROP INDEX chill_csconnectes.UNIQ_3274952577153098');
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/migrations/old/Version20200313124323.php b/src/Bundle/ChillJobBundle/src/migrations/old/Version20200313124323.php
new file mode 100644
index 000000000..1c3ef3be4
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/migrations/old/Version20200313124323.php
@@ -0,0 +1,87 @@
+skipIf(true, 'Skipping this old migration. Replaced by migration Version20240424095147');
+ $this->abortIf('postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.');
+ $this->addSql('ALTER TABLE chill_csconnectes.cv_formation ALTER diplomaobtained TYPE VARCHAR(255)');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion ADD ponctualite_salarie TEXT DEFAULT NULL');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion ADD ponctualite_salarie_note TEXT DEFAULT NULL');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion ADD assiduite TEXT DEFAULT NULL');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion ADD assiduite_note TEXT DEFAULT NULL');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion ADD interet_activite TEXT DEFAULT NULL');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion ADD interet_activite_note TEXT DEFAULT NULL');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion ADD integre_regle TEXT DEFAULT NULL');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion ADD integre_regle_note TEXT DEFAULT NULL');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion ADD esprit_initiative TEXT DEFAULT NULL');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion ADD esprit_initiative_note TEXT DEFAULT NULL');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion ADD organisation TEXT DEFAULT NULL');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion ADD organisation_note TEXT DEFAULT NULL');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion ADD capacite_travail_equipe TEXT DEFAULT NULL');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion ADD capacite_travail_equipe_note TEXT DEFAULT NULL');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion ADD style_vestimentaire TEXT DEFAULT NULL');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion ADD style_vestimentaire_note TEXT DEFAULT NULL');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion ADD langage_prof TEXT DEFAULT NULL');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion ADD langage_prof_note TEXT DEFAULT NULL');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion ADD applique_consigne TEXT DEFAULT NULL');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion ADD applique_consigne_note TEXT DEFAULT NULL');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion ADD respect_hierarchie TEXT DEFAULT NULL');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion ADD respect_hierarchie_note TEXT DEFAULT NULL');
+ $this->addSql('COMMENT ON COLUMN chill_csconnectes.immersion.objectifs IS NULL');
+ $this->addSql('COMMENT ON COLUMN chill_csconnectes.immersion.savoirEtre IS NULL');
+ $this->addSql('COMMENT ON COLUMN chill_csconnectes.frein.freinsPerso IS NULL');
+ $this->addSql('COMMENT ON COLUMN chill_csconnectes.frein.freinsEmploi IS NULL');
+ $this->addSql('COMMENT ON COLUMN chill_csconnectes.projet_professionnel.typeContrat IS NULL');
+ $this->addSql('COMMENT ON COLUMN chill_csconnectes.projet_professionnel.volumeHoraire IS NULL');
+ $this->addSql('COMMENT ON COLUMN chill_3party.third_party.types IS NULL');
+ }
+
+ public function down(Schema $schema): void
+ {
+ $this->abortIf('postgresql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'postgresql\'.');
+
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion DROP ponctualite_salarie');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion DROP ponctualite_salarie_note');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion DROP assiduite');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion DROP assiduite_note');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion DROP interet_activite');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion DROP interet_activite_note');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion DROP integre_regle');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion DROP integre_regle_note');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion DROP esprit_initiative');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion DROP esprit_initiative_note');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion DROP organisation');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion DROP organisation_note');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion DROP capacite_travail_equipe');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion DROP capacite_travail_equipe_note');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion DROP style_vestimentaire');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion DROP style_vestimentaire_note');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion DROP langage_prof');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion DROP langage_prof_note');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion DROP applique_consigne');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion DROP applique_consigne_note');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion DROP respect_hierarchie');
+ $this->addSql('ALTER TABLE chill_csconnectes.immersion DROP respect_hierarchie_note');
+ $this->addSql('COMMENT ON COLUMN chill_csconnectes.immersion.objectifs IS \'(DC2Type:json_array)\'');
+ $this->addSql('COMMENT ON COLUMN chill_csconnectes.immersion.savoiretre IS \'(DC2Type:json_array)\'');
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/migrations/old/Version20200403114520.php b/src/Bundle/ChillJobBundle/src/migrations/old/Version20200403114520.php
new file mode 100644
index 000000000..ab80c48d7
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/migrations/old/Version20200403114520.php
@@ -0,0 +1,35 @@
+skipIf(true, 'Skipping this old migration. Replaced by migration Version20240424095147');
+ $this->addSql('ALTER TABLE chill_csconnectes.projet_professionnel ADD domaineActiviteSouhait TEXT DEFAULT NULL;');
+ $this->addSql('ALTER TABLE chill_csconnectes.projet_professionnel ADD domaineActiviteValide TEXT DEFAULT NULL;');
+ }
+
+ public function down(Schema $schema): void
+ {
+ $this->addSql('ALTER TABLE chill_csconnectes.projet_professionnel DROP domaineActiviteSouhait');
+ $this->addSql('ALTER TABLE chill_csconnectes.projet_professionnel DROP domaineActiviteValide');
+ }
+}
diff --git a/src/Bundle/ChillJobBundle/src/migrations/old/Version20200403123148.php b/src/Bundle/ChillJobBundle/src/migrations/old/Version20200403123148.php
new file mode 100644
index 000000000..307cd14c7
--- /dev/null
+++ b/src/Bundle/ChillJobBundle/src/migrations/old/Version20200403123148.php
@@ -0,0 +1,32 @@
+skipIf(true, 'Skipping this old migration. Replaced by migration Version20240424095147');
+ $this->addSql('ALTER TABLE chill_csconnectes.cs_person ADD dateavenantIEJ DATE DEFAULT NULL;');
+ }
+
+ public function down(Schema $schema): void
+ {
+ $this->addSql('ALTER TABLE chill_csconnectes.cs_person DROP dateavenantIEJ');
+ }
+}
diff --git a/src/Bundle/ChillMainBundle/Command/LoadAddressesLUFromBDAddressCommand.php b/src/Bundle/ChillMainBundle/Command/LoadAddressesLUFromBDAddressCommand.php
new file mode 100644
index 000000000..2477a486d
--- /dev/null
+++ b/src/Bundle/ChillMainBundle/Command/LoadAddressesLUFromBDAddressCommand.php
@@ -0,0 +1,40 @@
+setName('chill:main:address-ref-lux');
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output): int
+ {
+ $this->addressImporter->import();
+
+ return Command::SUCCESS;
+ }
+}
diff --git a/src/Bundle/ChillMainBundle/Controller/PermissionsGroupController.php b/src/Bundle/ChillMainBundle/Controller/PermissionsGroupController.php
index e3327648a..a326e0ff5 100644
--- a/src/Bundle/ChillMainBundle/Controller/PermissionsGroupController.php
+++ b/src/Bundle/ChillMainBundle/Controller/PermissionsGroupController.php
@@ -151,7 +151,7 @@ final class PermissionsGroupController extends AbstractController
/**
* remove an association between permissionsGroup and roleScope.
*/
- #[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/admin/permissionsgroup/{pgid}/delete_link_role_scope/{rsid}', name: 'admin_permissionsgroup_delete_role_scope', methods: ['DELETE'])]
+ #[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/admin/permissionsgroup/{pgid}/delete_link_role_scope/{rsid}', name: 'admin_permissionsgroup_delete_role_scope', methods: ['POST'])]
public function deleteLinkRoleScopeAction(int $pgid, int $rsid): Response
{
$permissionsGroup = $this->permissionsGroupRepository->find($pgid);
diff --git a/src/Bundle/ChillMainBundle/Entity/Address.php b/src/Bundle/ChillMainBundle/Entity/Address.php
index cd2917798..38b309a76 100644
--- a/src/Bundle/ChillMainBundle/Entity/Address.php
+++ b/src/Bundle/ChillMainBundle/Entity/Address.php
@@ -92,7 +92,7 @@ class Address implements TrackCreationInterface, TrackUpdateInterface
* This list is computed by a materialized view. It won't be populated until a refresh is done
* on the materialized view.
*
- * @var Collection
+ * @var Collection
*
* @readonly
*/
@@ -446,7 +446,7 @@ class Address implements TrackCreationInterface, TrackUpdateInterface
return $this;
}
- public function setLinkedToThirdParty($linkedToThirdParty): self
+ public function setLinkedToThirdParty(?ThirdParty $linkedToThirdParty): self
{
$this->linkedToThirdParty = $linkedToThirdParty;
diff --git a/src/Bundle/ChillMainBundle/Entity/Center.php b/src/Bundle/ChillMainBundle/Entity/Center.php
index 61a026b5e..0d0858a6e 100644
--- a/src/Bundle/ChillMainBundle/Entity/Center.php
+++ b/src/Bundle/ChillMainBundle/Entity/Center.php
@@ -21,9 +21,9 @@ use Symfony\Component\Serializer\Annotation as Serializer;
class Center implements HasCenterInterface, \Stringable
{
/**
- * @var Collection
+ * @var Collection
*/
- #[ORM\OneToMany(targetEntity: GroupCenter::class, mappedBy: 'center')]
+ #[ORM\OneToMany(mappedBy: 'center', targetEntity: GroupCenter::class)]
private Collection $groupCenters;
#[Serializer\Groups(['docgen:read'])]
@@ -40,7 +40,7 @@ class Center implements HasCenterInterface, \Stringable
private bool $isActive = true;
/**
- * @var Collection
+ * @var Collection
*/
#[ORM\ManyToMany(targetEntity: Regroupment::class, mappedBy: 'centers')]
private Collection $regroupments;
@@ -111,7 +111,7 @@ class Center implements HasCenterInterface, \Stringable
/**
* @return $this
*/
- public function setName($name)
+ public function setName(string $name)
{
$this->name = $name;
diff --git a/src/Bundle/ChillMainBundle/Entity/Embeddable/CommentEmbeddable.php b/src/Bundle/ChillMainBundle/Entity/Embeddable/CommentEmbeddable.php
index aec4e3dde..ea0d4ec29 100644
--- a/src/Bundle/ChillMainBundle/Entity/Embeddable/CommentEmbeddable.php
+++ b/src/Bundle/ChillMainBundle/Entity/Embeddable/CommentEmbeddable.php
@@ -61,10 +61,7 @@ class CommentEmbeddable
$this->date = $date;
}
- /**
- * @param int $userId
- */
- public function setUserId($userId)
+ public function setUserId(?int $userId)
{
$this->userId = $userId;
}
diff --git a/src/Bundle/ChillMainBundle/Entity/Embeddable/PrivateCommentEmbeddable.php b/src/Bundle/ChillMainBundle/Entity/Embeddable/PrivateCommentEmbeddable.php
index 6e5168c63..0c2af22f7 100644
--- a/src/Bundle/ChillMainBundle/Entity/Embeddable/PrivateCommentEmbeddable.php
+++ b/src/Bundle/ChillMainBundle/Entity/Embeddable/PrivateCommentEmbeddable.php
@@ -57,7 +57,7 @@ class PrivateCommentEmbeddable
return $this;
}
- public function setComments($comments)
+ public function setComments(array $comments)
{
$this->comments = $comments;
diff --git a/src/Bundle/ChillMainBundle/Entity/GeographicalUnitLayer.php b/src/Bundle/ChillMainBundle/Entity/GeographicalUnitLayer.php
index e528ab860..5b311b465 100644
--- a/src/Bundle/ChillMainBundle/Entity/GeographicalUnitLayer.php
+++ b/src/Bundle/ChillMainBundle/Entity/GeographicalUnitLayer.php
@@ -36,9 +36,9 @@ class GeographicalUnitLayer
private string $refId = '';
/**
- * @var Collection
+ * @var Collection
*/
- #[ORM\OneToMany(targetEntity: GeographicalUnit::class, mappedBy: 'layer')]
+ #[ORM\OneToMany(mappedBy: 'layer', targetEntity: GeographicalUnit::class)]
private Collection $units;
public function __construct()
diff --git a/src/Bundle/ChillMainBundle/Entity/GroupCenter.php b/src/Bundle/ChillMainBundle/Entity/GroupCenter.php
index e93b6d19b..5a1349bcc 100644
--- a/src/Bundle/ChillMainBundle/Entity/GroupCenter.php
+++ b/src/Bundle/ChillMainBundle/Entity/GroupCenter.php
@@ -34,7 +34,7 @@ class GroupCenter
private ?PermissionsGroup $permissionsGroup = null;
/**
- * @var Collection
+ * @var Collection
*/
#[ORM\ManyToMany(targetEntity: User::class, mappedBy: 'groupCenters')]
private Collection $users;
diff --git a/src/Bundle/ChillMainBundle/Entity/Language.php b/src/Bundle/ChillMainBundle/Entity/Language.php
index ae7cb865f..894b929ac 100644
--- a/src/Bundle/ChillMainBundle/Entity/Language.php
+++ b/src/Bundle/ChillMainBundle/Entity/Language.php
@@ -59,11 +59,9 @@ class Language
/**
* Set id.
*
- * @param string $id
- *
* @return Language
*/
- public function setId($id)
+ public function setId(?string $id)
{
$this->id = $id;
@@ -77,7 +75,7 @@ class Language
*
* @return Language
*/
- public function setName($name)
+ public function setName(array $name)
{
$this->name = $name;
diff --git a/src/Bundle/ChillMainBundle/Entity/Notification.php b/src/Bundle/ChillMainBundle/Entity/Notification.php
index 4165da3d0..d85a144b0 100644
--- a/src/Bundle/ChillMainBundle/Entity/Notification.php
+++ b/src/Bundle/ChillMainBundle/Entity/Notification.php
@@ -30,7 +30,7 @@ class Notification implements TrackUpdateInterface
private array $addedAddresses = [];
/**
- * @var Collection
+ * @var Collection
*/
#[ORM\ManyToMany(targetEntity: User::class)]
#[ORM\JoinTable(name: 'chill_main_notification_addresses_user')]
@@ -54,9 +54,9 @@ class Notification implements TrackUpdateInterface
private ?ArrayCollection $addressesOnLoad = null;
/**
- * @var Collection
+ * @var Collection
*/
- #[ORM\OneToMany(targetEntity: NotificationComment::class, mappedBy: 'notification', orphanRemoval: true)]
+ #[ORM\OneToMany(mappedBy: 'notification', targetEntity: NotificationComment::class, orphanRemoval: true)]
#[ORM\OrderBy(['createdAt' => \Doctrine\Common\Collections\Criteria::ASC])]
private Collection $comments;
@@ -88,7 +88,7 @@ class Notification implements TrackUpdateInterface
private string $title = '';
/**
- * @var Collection
+ * @var Collection
*/
#[ORM\ManyToMany(targetEntity: User::class)]
#[ORM\JoinTable(name: 'chill_main_notification_addresses_unread')]
diff --git a/src/Bundle/ChillMainBundle/Entity/PermissionsGroup.php b/src/Bundle/ChillMainBundle/Entity/PermissionsGroup.php
index 480270e74..4902fca95 100644
--- a/src/Bundle/ChillMainBundle/Entity/PermissionsGroup.php
+++ b/src/Bundle/ChillMainBundle/Entity/PermissionsGroup.php
@@ -28,9 +28,9 @@ class PermissionsGroup
private array $flags = [];
/**
- * @var Collection
+ * @var Collection
*/
- #[ORM\OneToMany(targetEntity: GroupCenter::class, mappedBy: 'permissionsGroup')]
+ #[ORM\OneToMany(mappedBy: 'permissionsGroup', targetEntity: GroupCenter::class)]
private Collection $groupCenters;
#[ORM\Id]
@@ -42,7 +42,7 @@ class PermissionsGroup
private string $name = '';
/**
- * @var Collection
+ * @var Collection
*/
#[ORM\ManyToMany(targetEntity: RoleScope::class, inversedBy: 'permissionsGroups', cascade: ['persist'])]
#[ORM\Cache(usage: 'NONSTRICT_READ_WRITE')]
@@ -137,7 +137,7 @@ class PermissionsGroup
/**
* @return $this
*/
- public function setName($name)
+ public function setName(string $name)
{
$this->name = $name;
diff --git a/src/Bundle/ChillMainBundle/Entity/PostalCode.php b/src/Bundle/ChillMainBundle/Entity/PostalCode.php
index 3449e0184..ecab19a5f 100644
--- a/src/Bundle/ChillMainBundle/Entity/PostalCode.php
+++ b/src/Bundle/ChillMainBundle/Entity/PostalCode.php
@@ -157,11 +157,9 @@ class PostalCode implements TrackUpdateInterface, TrackCreationInterface
/**
* Set code.
*
- * @param string $code
- *
* @return PostalCode
*/
- public function setCode($code)
+ public function setCode(?string $code)
{
$this->code = $code;
@@ -183,11 +181,9 @@ class PostalCode implements TrackUpdateInterface, TrackCreationInterface
/**
* Set name.
*
- * @param string $name
- *
* @return PostalCode
*/
- public function setName($name)
+ public function setName(?string $name)
{
$this->name = $name;
@@ -197,11 +193,9 @@ class PostalCode implements TrackUpdateInterface, TrackCreationInterface
/**
* Set origin.
*
- * @param int $origin
- *
* @return PostalCode
*/
- public function setOrigin($origin)
+ public function setOrigin(int $origin)
{
$this->origin = $origin;
diff --git a/src/Bundle/ChillMainBundle/Entity/Regroupment.php b/src/Bundle/ChillMainBundle/Entity/Regroupment.php
index b2d61e34d..389eceb31 100644
--- a/src/Bundle/ChillMainBundle/Entity/Regroupment.php
+++ b/src/Bundle/ChillMainBundle/Entity/Regroupment.php
@@ -20,7 +20,7 @@ use Doctrine\ORM\Mapping as ORM;
class Regroupment
{
/**
- * @var Collection
+ * @var Collection
*/
#[ORM\ManyToMany(targetEntity: Center::class, inversedBy: 'regroupments')]
#[ORM\Id]
diff --git a/src/Bundle/ChillMainBundle/Entity/RoleScope.php b/src/Bundle/ChillMainBundle/Entity/RoleScope.php
index 3f4047dc8..4048debb1 100644
--- a/src/Bundle/ChillMainBundle/Entity/RoleScope.php
+++ b/src/Bundle/ChillMainBundle/Entity/RoleScope.php
@@ -26,7 +26,7 @@ class RoleScope
private ?int $id = null;
/**
- * @var Collection
+ * @var Collection
*/
#[ORM\ManyToMany(targetEntity: PermissionsGroup::class, mappedBy: 'roleScopes')]
private Collection $permissionsGroups;
diff --git a/src/Bundle/ChillMainBundle/Entity/Scope.php b/src/Bundle/ChillMainBundle/Entity/Scope.php
index 3e891062b..dd04f8a47 100644
--- a/src/Bundle/ChillMainBundle/Entity/Scope.php
+++ b/src/Bundle/ChillMainBundle/Entity/Scope.php
@@ -42,9 +42,9 @@ class Scope
private array $name = [];
/**
- * @var Collection
+ * @var Collection
*/
- #[ORM\OneToMany(targetEntity: RoleScope::class, mappedBy: 'scope')]
+ #[ORM\OneToMany(mappedBy: 'scope', targetEntity: RoleScope::class)]
#[ORM\Cache(usage: 'NONSTRICT_READ_WRITE')]
private Collection $roleScopes;
diff --git a/src/Bundle/ChillMainBundle/Entity/User.php b/src/Bundle/ChillMainBundle/Entity/User.php
index 508d12df7..0c8c87553 100644
--- a/src/Bundle/ChillMainBundle/Entity/User.php
+++ b/src/Bundle/ChillMainBundle/Entity/User.php
@@ -64,7 +64,7 @@ class User implements UserInterface, \Stringable, PasswordAuthenticatedUserInter
private bool $enabled = true;
/**
- * @var Collection
+ * @var Collection
*/
#[ORM\ManyToMany(targetEntity: GroupCenter::class, inversedBy: 'users')]
#[ORM\Cache(usage: 'NONSTRICT_READ_WRITE')]
@@ -83,9 +83,9 @@ class User implements UserInterface, \Stringable, PasswordAuthenticatedUserInter
private ?Location $mainLocation = null;
/**
- * @var Collection&Selectable
+ * @var \Doctrine\Common\Collections\Collection&Selectable
*/
- #[ORM\OneToMany(targetEntity: UserScopeHistory::class, mappedBy: 'user', cascade: ['persist', 'remove'], orphanRemoval: true)]
+ #[ORM\OneToMany(mappedBy: 'user', targetEntity: UserScopeHistory::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
private Collection&Selectable $scopeHistories;
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 255)]
@@ -98,9 +98,9 @@ class User implements UserInterface, \Stringable, PasswordAuthenticatedUserInter
private ?string $salt = null;
/**
- * @var Collection&Selectable
+ * @var \Doctrine\Common\Collections\Collection&Selectable
*/
- #[ORM\OneToMany(targetEntity: UserJobHistory::class, mappedBy: 'user', cascade: ['persist', 'remove'], orphanRemoval: true)]
+ #[ORM\OneToMany(mappedBy: 'user', targetEntity: UserJobHistory::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
private Collection&Selectable $jobHistories;
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 80)]
@@ -437,7 +437,7 @@ class User implements UserInterface, \Stringable, PasswordAuthenticatedUserInter
/**
* @return $this
*/
- public function setEmail($email)
+ public function setEmail(?string $email)
{
$this->email = $email;
@@ -447,7 +447,7 @@ class User implements UserInterface, \Stringable, PasswordAuthenticatedUserInter
/**
* @return $this
*/
- public function setEmailCanonical($emailCanonical)
+ public function setEmailCanonical(?string $emailCanonical)
{
$this->emailCanonical = $emailCanonical;
@@ -521,7 +521,7 @@ class User implements UserInterface, \Stringable, PasswordAuthenticatedUserInter
/**
* @return $this
*/
- public function setPassword($password)
+ public function setPassword(string $password)
{
$this->password = $password;
@@ -531,7 +531,7 @@ class User implements UserInterface, \Stringable, PasswordAuthenticatedUserInter
/**
* @return $this
*/
- public function setSalt($salt)
+ public function setSalt(?string $salt)
{
$this->salt = $salt;
@@ -593,7 +593,7 @@ class User implements UserInterface, \Stringable, PasswordAuthenticatedUserInter
/**
* @return $this
*/
- public function setUsernameCanonical($usernameCanonical)
+ public function setUsernameCanonical(?string $usernameCanonical)
{
$this->usernameCanonical = $usernameCanonical;
diff --git a/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflow.php b/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflow.php
index eb187cd39..4ab1ee30e 100644
--- a/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflow.php
+++ b/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflow.php
@@ -35,7 +35,7 @@ class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface
use TrackUpdateTrait;
/**
- * @var Collection
+ * @var Collection
*/
#[ORM\OneToMany(targetEntity: EntityWorkflowComment::class, mappedBy: 'entityWorkflow', orphanRemoval: true)]
private Collection $comments;
@@ -52,10 +52,10 @@ class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface
private int $relatedEntityId;
/**
- * @var Collection
+ * @var Collection
*/
#[Assert\Valid(traverse: true)]
- #[ORM\OneToMany(targetEntity: EntityWorkflowStep::class, mappedBy: 'entityWorkflow', orphanRemoval: true, cascade: ['persist'])]
+ #[ORM\OneToMany(mappedBy: 'entityWorkflow', targetEntity: EntityWorkflowStep::class, cascade: ['persist'], orphanRemoval: true)]
#[ORM\OrderBy(['transitionAt' => \Doctrine\Common\Collections\Criteria::ASC, 'id' => 'ASC'])]
private Collection $steps;
@@ -65,14 +65,14 @@ class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface
private ?array $stepsChainedCache = null;
/**
- * @var Collection
+ * @var Collection
*/
#[ORM\ManyToMany(targetEntity: User::class)]
#[ORM\JoinTable(name: 'chill_main_workflow_entity_subscriber_to_final')]
private Collection $subscriberToFinal;
/**
- * @var Collection
+ * @var Collection
*/
#[ORM\ManyToMany(targetEntity: User::class)]
#[ORM\JoinTable(name: 'chill_main_workflow_entity_subscriber_to_step')]
@@ -247,12 +247,16 @@ class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface
return $this->steps;
}
+ /**
+ * @throws \Exception
+ */
public function getStepsChained(): array
{
if (\is_array($this->stepsChainedCache)) {
return $this->stepsChainedCache;
}
+ /** @var \ArrayIterator $iterator */
$iterator = $this->steps->getIterator();
$current = null;
$steps = [];
diff --git a/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflowStep.php b/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflowStep.php
index a97e810b4..dde204a85 100644
--- a/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflowStep.php
+++ b/src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflowStep.php
@@ -26,7 +26,7 @@ class EntityWorkflowStep
private string $accessKey;
/**
- * @var Collection
+ * @var Collection
*/
#[ORM\ManyToMany(targetEntity: User::class)]
#[ORM\JoinTable(name: 'chill_main_workflow_entity_step_cc_user')]
diff --git a/src/Bundle/ChillMainBundle/Repository/AddressReferenceRepository.php b/src/Bundle/ChillMainBundle/Repository/AddressReferenceRepository.php
index 86faf6ea1..3e8d060c3 100644
--- a/src/Bundle/ChillMainBundle/Repository/AddressReferenceRepository.php
+++ b/src/Bundle/ChillMainBundle/Repository/AddressReferenceRepository.php
@@ -20,11 +20,11 @@ use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\ORM\Query\ResultSetMappingBuilder;
use Doctrine\Persistence\ObjectRepository;
-final class AddressReferenceRepository implements ObjectRepository
+final readonly class AddressReferenceRepository implements ObjectRepository
{
- private readonly EntityManagerInterface $entityManager;
+ private EntityManagerInterface $entityManager;
- private readonly EntityRepository $repository;
+ private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager)
{
diff --git a/src/Bundle/ChillMainBundle/Repository/AddressRepository.php b/src/Bundle/ChillMainBundle/Repository/AddressRepository.php
index 074b1fc32..4dbd09cab 100644
--- a/src/Bundle/ChillMainBundle/Repository/AddressRepository.php
+++ b/src/Bundle/ChillMainBundle/Repository/AddressRepository.php
@@ -17,9 +17,9 @@ use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder;
use Doctrine\Persistence\ObjectRepository;
-final class AddressRepository implements ObjectRepository
+final readonly class AddressRepository implements ObjectRepository
{
- private readonly EntityRepository $repository;
+ private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager)
{
diff --git a/src/Bundle/ChillMainBundle/Repository/CenterRepository.php b/src/Bundle/ChillMainBundle/Repository/CenterRepository.php
index 0b507faa1..1bc5a7405 100644
--- a/src/Bundle/ChillMainBundle/Repository/CenterRepository.php
+++ b/src/Bundle/ChillMainBundle/Repository/CenterRepository.php
@@ -15,9 +15,9 @@ use Chill\MainBundle\Entity\Center;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
-final class CenterRepository implements CenterRepositoryInterface
+final readonly class CenterRepository implements CenterRepositoryInterface
{
- private readonly EntityRepository $repository;
+ private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager)
{
diff --git a/src/Bundle/ChillMainBundle/Repository/CountryRepository.php b/src/Bundle/ChillMainBundle/Repository/CountryRepository.php
index 701019dba..ae318e35e 100644
--- a/src/Bundle/ChillMainBundle/Repository/CountryRepository.php
+++ b/src/Bundle/ChillMainBundle/Repository/CountryRepository.php
@@ -17,9 +17,9 @@ use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder;
use Doctrine\Persistence\ObjectRepository;
-final class CountryRepository implements ObjectRepository
+final readonly class CountryRepository implements ObjectRepository
{
- private readonly EntityRepository $repository;
+ private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager)
{
diff --git a/src/Bundle/ChillMainBundle/Repository/GeographicalUnitLayerLayerRepository.php b/src/Bundle/ChillMainBundle/Repository/GeographicalUnitLayerLayerRepository.php
index 11a03c209..1135b889d 100644
--- a/src/Bundle/ChillMainBundle/Repository/GeographicalUnitLayerLayerRepository.php
+++ b/src/Bundle/ChillMainBundle/Repository/GeographicalUnitLayerLayerRepository.php
@@ -15,9 +15,9 @@ use Chill\MainBundle\Entity\GeographicalUnitLayer;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
-final class GeographicalUnitLayerLayerRepository implements GeographicalUnitLayerRepositoryInterface
+final readonly class GeographicalUnitLayerLayerRepository implements GeographicalUnitLayerRepositoryInterface
{
- private readonly EntityRepository $repository;
+ private EntityRepository $repository;
public function __construct(EntityManagerInterface $em)
{
diff --git a/src/Bundle/ChillMainBundle/Repository/GeographicalUnitRepository.php b/src/Bundle/ChillMainBundle/Repository/GeographicalUnitRepository.php
index 608609a11..35ec31ff3 100644
--- a/src/Bundle/ChillMainBundle/Repository/GeographicalUnitRepository.php
+++ b/src/Bundle/ChillMainBundle/Repository/GeographicalUnitRepository.php
@@ -18,9 +18,9 @@ use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query\Expr\Join;
use Doctrine\ORM\QueryBuilder;
-final class GeographicalUnitRepository implements GeographicalUnitRepositoryInterface
+final readonly class GeographicalUnitRepository implements GeographicalUnitRepositoryInterface
{
- private readonly EntityRepository $repository;
+ private EntityRepository $repository;
public function __construct(EntityManagerInterface $em)
{
diff --git a/src/Bundle/ChillMainBundle/Repository/GroupCenterRepository.php b/src/Bundle/ChillMainBundle/Repository/GroupCenterRepository.php
index 2d9ad8c5a..d0f5d8561 100644
--- a/src/Bundle/ChillMainBundle/Repository/GroupCenterRepository.php
+++ b/src/Bundle/ChillMainBundle/Repository/GroupCenterRepository.php
@@ -16,9 +16,9 @@ use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Doctrine\Persistence\ObjectRepository;
-final class GroupCenterRepository implements ObjectRepository
+final readonly class GroupCenterRepository implements ObjectRepository
{
- private readonly EntityRepository $repository;
+ private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager)
{
diff --git a/src/Bundle/ChillMainBundle/Repository/LanguageRepository.php b/src/Bundle/ChillMainBundle/Repository/LanguageRepository.php
index d8c5d54f8..28d21d2c1 100644
--- a/src/Bundle/ChillMainBundle/Repository/LanguageRepository.php
+++ b/src/Bundle/ChillMainBundle/Repository/LanguageRepository.php
@@ -15,9 +15,9 @@ use Chill\MainBundle\Entity\Language;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
-final class LanguageRepository implements LanguageRepositoryInterface
+final readonly class LanguageRepository implements LanguageRepositoryInterface
{
- private readonly EntityRepository $repository;
+ private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager)
{
diff --git a/src/Bundle/ChillMainBundle/Repository/PermissionsGroupRepository.php b/src/Bundle/ChillMainBundle/Repository/PermissionsGroupRepository.php
index 910d924db..598894b61 100644
--- a/src/Bundle/ChillMainBundle/Repository/PermissionsGroupRepository.php
+++ b/src/Bundle/ChillMainBundle/Repository/PermissionsGroupRepository.php
@@ -16,9 +16,9 @@ use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Doctrine\Persistence\ObjectRepository;
-final class PermissionsGroupRepository implements ObjectRepository
+final readonly class PermissionsGroupRepository implements ObjectRepository
{
- private readonly EntityRepository $repository;
+ private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager)
{
diff --git a/src/Bundle/ChillMainBundle/Repository/PostalCodeRepository.php b/src/Bundle/ChillMainBundle/Repository/PostalCodeRepository.php
index 0949f52ba..0779ea90a 100644
--- a/src/Bundle/ChillMainBundle/Repository/PostalCodeRepository.php
+++ b/src/Bundle/ChillMainBundle/Repository/PostalCodeRepository.php
@@ -19,11 +19,11 @@ use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\ORM\Query\ResultSetMappingBuilder;
-final class PostalCodeRepository implements PostalCodeRepositoryInterface
+final readonly class PostalCodeRepository implements PostalCodeRepositoryInterface
{
- private readonly EntityManagerInterface $entityManager;
+ private EntityManagerInterface $entityManager;
- private readonly EntityRepository $repository;
+ private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager)
{
diff --git a/src/Bundle/ChillMainBundle/Repository/RegroupmentRepository.php b/src/Bundle/ChillMainBundle/Repository/RegroupmentRepository.php
index e18279944..793015f5b 100644
--- a/src/Bundle/ChillMainBundle/Repository/RegroupmentRepository.php
+++ b/src/Bundle/ChillMainBundle/Repository/RegroupmentRepository.php
@@ -18,9 +18,9 @@ use Doctrine\ORM\NonUniqueResultException;
use Doctrine\ORM\NoResultException;
use Doctrine\Persistence\ObjectRepository;
-final class RegroupmentRepository implements ObjectRepository
+final readonly class RegroupmentRepository implements ObjectRepository
{
- private readonly EntityRepository $repository;
+ private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager)
{
diff --git a/src/Bundle/ChillMainBundle/Repository/RoleScopeRepository.php b/src/Bundle/ChillMainBundle/Repository/RoleScopeRepository.php
index ddf52af5b..a00d2ce35 100644
--- a/src/Bundle/ChillMainBundle/Repository/RoleScopeRepository.php
+++ b/src/Bundle/ChillMainBundle/Repository/RoleScopeRepository.php
@@ -16,9 +16,9 @@ use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Doctrine\Persistence\ObjectRepository;
-final class RoleScopeRepository implements ObjectRepository
+final readonly class RoleScopeRepository implements ObjectRepository
{
- private readonly EntityRepository $repository;
+ private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager)
{
diff --git a/src/Bundle/ChillMainBundle/Repository/ScopeRepository.php b/src/Bundle/ChillMainBundle/Repository/ScopeRepository.php
index aa3c78270..4f752bce0 100644
--- a/src/Bundle/ChillMainBundle/Repository/ScopeRepository.php
+++ b/src/Bundle/ChillMainBundle/Repository/ScopeRepository.php
@@ -17,11 +17,11 @@ use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder;
-final class ScopeRepository implements ScopeRepositoryInterface
+final readonly class ScopeRepository implements ScopeRepositoryInterface
{
- private readonly EntityRepository $repository;
+ private EntityRepository $repository;
- public function __construct(EntityManagerInterface $entityManager, private readonly TranslatableStringHelperInterface $translatableStringHelper)
+ public function __construct(EntityManagerInterface $entityManager, private TranslatableStringHelperInterface $translatableStringHelper)
{
$this->repository = $entityManager->getRepository(Scope::class);
}
diff --git a/src/Bundle/ChillMainBundle/Resources/public/module/collection/index.ts b/src/Bundle/ChillMainBundle/Resources/public/module/collection/index.ts
index de428335d..875e99fad 100644
--- a/src/Bundle/ChillMainBundle/Resources/public/module/collection/index.ts
+++ b/src/Bundle/ChillMainBundle/Resources/public/module/collection/index.ts
@@ -53,14 +53,17 @@ export const handleAdd = (button: any): void => {
let
empty_explain: HTMLLIElement | null = collection.querySelector('li[data-collection-empty-explain]'),
entry = document.createElement('li'),
- counter = collection.childNodes.length + 1,
- content = prototype.replace(new RegExp('__name__', 'g'), counter.toString()),
+ counter = collection.querySelectorAll('li.entry').length, // Updated counter logic
+ content = prototype.replace(/__name__/g, counter.toString()),
event = new CustomEvent('collection-add-entry', {detail: new CollectionEventPayload(collection, entry)});
+ console.log(counter)
+ console.log(content)
+
entry.innerHTML = content;
entry.classList.add('entry');
- if ("dataCollectionRegular" in collection.dataset) {
+ if ("collectionRegular" in collection.dataset) {
initializeRemove(collection, entry);
if (empty_explain !== null) {
empty_explain.remove();
diff --git a/src/Bundle/ChillMainBundle/Resources/public/module/pick-entity/index.js b/src/Bundle/ChillMainBundle/Resources/public/module/pick-entity/index.js
index 6b33c0f52..03220630f 100644
--- a/src/Bundle/ChillMainBundle/Resources/public/module/pick-entity/index.js
+++ b/src/Bundle/ChillMainBundle/Resources/public/module/pick-entity/index.js
@@ -159,3 +159,5 @@ document.addEventListener('DOMContentLoaded', function(e) {
loadDynamicPicker(document)
})
+window.loadDynamicPicker = loadDynamicPicker;
+
diff --git a/src/Bundle/ChillMainBundle/Resources/views/CRUD/_edit_content.html.twig b/src/Bundle/ChillMainBundle/Resources/views/CRUD/_edit_content.html.twig
index 0bfa5d54b..a6f139fd7 100644
--- a/src/Bundle/ChillMainBundle/Resources/views/CRUD/_edit_content.html.twig
+++ b/src/Bundle/ChillMainBundle/Resources/views/CRUD/_edit_content.html.twig
@@ -1,5 +1,5 @@
{% set formId = crudMainFormId|default('crud_main_form') %}
-
+
{% block crud_content_header %}
{{ ('crud.'~crud_name~'.title_edit')|trans }}
{% endblock crud_content_header %}
@@ -21,9 +21,9 @@