From 2c68224e9ce90755d3105371a66e6e8ee6e7d155 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Fri, 19 Apr 2024 10:21:17 +0200 Subject: [PATCH] Add jobBundle and FranceTravailApiBundle --- composer.json | 2 + .../src/ApiHelper/ApiWrapper.php | 95 ++ .../ApiHelper/PartenaireRomeAppellation.php | 101 ++ .../src/ApiHelper/ProcessRequestTrait.php | 97 ++ .../src/ChillFranceTravailApiBundle.php | 9 + .../src/Controller/RomeController.php | 54 + .../ChillFranceTravailApiExtension.php | 28 + .../src/DependencyInjection/Configuration.php | 29 + .../src/Resources/config/routing.yml | 3 + .../src/Resources/config/services.yml | 14 + .../src/Resources/views/.gitkeep | 1 + .../PartenaireRomeAppellationTest.php | 75 + .../Tests/Controller/RomeControllerTest.php | 16 + .../ChillJobBundle/src/ChillJobBundle.php | 9 + .../src/Controller/CSCrudReportController.php | 124 ++ .../src/Controller/CSPersonController.php | 151 ++ .../src/Controller/CSReportController.php | 72 + .../DependencyInjection/ChillJobExtension.php | 31 + .../src/DependencyInjection/Configuration.php | 29 + .../ChillJobBundle/src/Entity/CSPerson.php | 1482 +++++++++++++++++ src/Bundle/ChillJobBundle/src/Entity/CV.php | 353 ++++ .../src/Entity/CV/Experience.php | 263 +++ .../src/Entity/CV/Formation.php | 258 +++ .../ChillJobBundle/src/Entity/Frein.php | 272 +++ .../ChillJobBundle/src/Entity/Immersion.php | 1256 ++++++++++++++ .../src/Entity/ProjetProfessionnel.php | 468 ++++++ .../src/Entity/Rome/Appellation.php | 125 ++ .../ChillJobBundle/src/Entity/Rome/Metier.php | 112 ++ .../src/Export/ListCSPerson.php | 653 ++++++++ .../ChillJobBundle/src/Export/ListCV.php | 392 +++++ .../ChillJobBundle/src/Export/ListFrein.php | 506 ++++++ .../src/Export/ListProjetProfessionnel.php | 584 +++++++ .../src/Form/CSPersonDispositifsType.php | 132 ++ .../Form/CSPersonPersonalSituationType.php | 263 +++ .../src/Form/CV/ExperienceType.php | 72 + .../src/Form/CV/FormationType.php | 77 + src/Bundle/ChillJobBundle/src/Form/CVType.php | 94 ++ .../RomeAppellationChoiceLoader.php | 144 ++ .../ChillJobBundle/src/Form/FreinType.php | 68 + .../ChillJobBundle/src/Form/ImmersionType.php | 209 +++ .../src/Form/ProjetProfessionnelType.php | 109 ++ .../src/Form/Type/PickRomeAppellationType.php | 125 ++ .../ChillJobBundle/src/Menu/MenuBuilder.php | 68 + .../src/Repository/CSPersonRepository.php | 13 + .../Repository/CV/ExperienceRepository.php | 13 + .../src/Repository/CV/FormationRepository.php | 13 + .../src/Repository/CVRepository.php | 13 + .../src/Repository/FreinRepository.php | 13 + .../src/Repository/ImmersionRepository.php | 13 + .../ProjetProfessionnelRepository.php | 13 + .../Repository/Rome/AppellationRepository.php | 13 + .../src/Repository/Rome/MetierRepository.php | 13 + .../src/Resources/config/routing.yml | 3 + .../src/Resources/config/services.yml | 12 + .../Resources/config/services/3party_type.yml | 9 + .../Resources/config/services/controller.yml | 3 + .../src/Resources/config/services/export.yml | 28 + .../src/Resources/config/services/form.yml | 8 + .../src/Resources/config/services/menu.yml | 6 + .../Resources/config/services/security.yml | 15 + .../migrations/Version20191119172511.php | 105 ++ .../migrations/Version20191129112321.php | 50 + .../migrations/Version20200113104411.php | 35 + .../migrations/Version20200113142525.php | 33 + .../migrations/Version20200114081435.php | 34 + .../migrations/Version20200124130244.php | 27 + .../migrations/Version20200124132321.php | 26 + .../migrations/Version20200127132932.php | 27 + .../migrations/Version20200205132532.php | 76 + .../migrations/Version20200207224152.php | 28 + .../migrations/Version20200210105342.php | 27 + .../migrations/Version20200313124323.php | 78 + .../migrations/Version20200403114520.php | 25 + .../migrations/Version20200403123148.php | 22 + .../public/images/footer_bandeau.jpg | Bin 0 -> 39797 bytes .../src/Resources/public/images/index.js | 1 + .../Resources/public/module/cv_edit/index.js | 43 + .../public/module/dispositif_edit/index.js | 72 + .../public/module/immersion_edit/index.js | 20 + .../public/module/personal_situation/index.js | 103 ++ .../Resources/public/sass/csconnectes.scss | 19 + .../src/Resources/public/sass/index.js | 1 + .../Resources/translations/messages.fr.yml | 250 +++ .../views/CSPerson/dispositifs_edit.html.twig | 91 + .../views/CSPerson/dispositifs_view.html.twig | 126 ++ .../personal_situation_edit.html.twig | 124 ++ .../personal_situation_view.html.twig | 282 ++++ .../src/Resources/views/CV/edit.html.twig | 61 + .../src/Resources/views/CV/new.html.twig | 61 + .../src/Resources/views/CV/view.html.twig | 142 ++ .../src/Resources/views/Frein/edit.html.twig | 20 + .../src/Resources/views/Frein/new.html.twig | 23 + .../src/Resources/views/Frein/view.html.twig | 58 + .../views/Immersion/edit-bilan.html.twig | 92 + .../Resources/views/Immersion/edit.html.twig | 65 + .../Resources/views/Immersion/new.html.twig | 68 + .../Resources/views/Immersion/view.html.twig | 209 +++ .../views/ProjetProfessionnel/edit.html.twig | 52 + .../views/ProjetProfessionnel/new.html.twig | 52 + .../views/ProjetProfessionnel/view.html.twig | 108 ++ .../Resources/views/Report/delete.html.twig | 16 + .../Resources/views/Report/index.html.twig | 253 +++ .../Authorization/CSConnectesVoter.php | 120 ++ .../Security/Authorization/ExportsVoter.php | 121 ++ .../Controller/CSPersonControllerTest.php | 9 + .../Controller/CSReportControllerTest.php | 9 + .../src/ThirdParty/EntrepriseType.php | 17 + .../src/ThirdParty/PrescripteurType.php | 17 + .../src/chill.webpack.config.js | 20 + 109 files changed, 12544 insertions(+) create mode 100644 src/Bundle/ChillFranceTravailApiBundle/src/ApiHelper/ApiWrapper.php create mode 100644 src/Bundle/ChillFranceTravailApiBundle/src/ApiHelper/PartenaireRomeAppellation.php create mode 100644 src/Bundle/ChillFranceTravailApiBundle/src/ApiHelper/ProcessRequestTrait.php create mode 100644 src/Bundle/ChillFranceTravailApiBundle/src/ChillFranceTravailApiBundle.php create mode 100644 src/Bundle/ChillFranceTravailApiBundle/src/Controller/RomeController.php create mode 100644 src/Bundle/ChillFranceTravailApiBundle/src/DependencyInjection/ChillFranceTravailApiExtension.php create mode 100644 src/Bundle/ChillFranceTravailApiBundle/src/DependencyInjection/Configuration.php create mode 100644 src/Bundle/ChillFranceTravailApiBundle/src/Resources/config/routing.yml create mode 100644 src/Bundle/ChillFranceTravailApiBundle/src/Resources/config/services.yml create mode 100644 src/Bundle/ChillFranceTravailApiBundle/src/Resources/views/.gitkeep create mode 100644 src/Bundle/ChillFranceTravailApiBundle/src/Tests/ApiHelper/PartenaireRomeAppellationTest.php create mode 100644 src/Bundle/ChillFranceTravailApiBundle/src/Tests/Controller/RomeControllerTest.php create mode 100644 src/Bundle/ChillJobBundle/src/ChillJobBundle.php create mode 100644 src/Bundle/ChillJobBundle/src/Controller/CSCrudReportController.php create mode 100644 src/Bundle/ChillJobBundle/src/Controller/CSPersonController.php create mode 100644 src/Bundle/ChillJobBundle/src/Controller/CSReportController.php create mode 100644 src/Bundle/ChillJobBundle/src/DependencyInjection/ChillJobExtension.php create mode 100644 src/Bundle/ChillJobBundle/src/DependencyInjection/Configuration.php create mode 100644 src/Bundle/ChillJobBundle/src/Entity/CSPerson.php create mode 100644 src/Bundle/ChillJobBundle/src/Entity/CV.php create mode 100644 src/Bundle/ChillJobBundle/src/Entity/CV/Experience.php create mode 100644 src/Bundle/ChillJobBundle/src/Entity/CV/Formation.php create mode 100644 src/Bundle/ChillJobBundle/src/Entity/Frein.php create mode 100644 src/Bundle/ChillJobBundle/src/Entity/Immersion.php create mode 100644 src/Bundle/ChillJobBundle/src/Entity/ProjetProfessionnel.php create mode 100644 src/Bundle/ChillJobBundle/src/Entity/Rome/Appellation.php create mode 100644 src/Bundle/ChillJobBundle/src/Entity/Rome/Metier.php create mode 100644 src/Bundle/ChillJobBundle/src/Export/ListCSPerson.php create mode 100644 src/Bundle/ChillJobBundle/src/Export/ListCV.php create mode 100644 src/Bundle/ChillJobBundle/src/Export/ListFrein.php create mode 100644 src/Bundle/ChillJobBundle/src/Export/ListProjetProfessionnel.php create mode 100644 src/Bundle/ChillJobBundle/src/Form/CSPersonDispositifsType.php create mode 100644 src/Bundle/ChillJobBundle/src/Form/CSPersonPersonalSituationType.php create mode 100644 src/Bundle/ChillJobBundle/src/Form/CV/ExperienceType.php create mode 100644 src/Bundle/ChillJobBundle/src/Form/CV/FormationType.php create mode 100644 src/Bundle/ChillJobBundle/src/Form/CVType.php create mode 100644 src/Bundle/ChillJobBundle/src/Form/ChoiceLoader/RomeAppellationChoiceLoader.php create mode 100644 src/Bundle/ChillJobBundle/src/Form/FreinType.php create mode 100644 src/Bundle/ChillJobBundle/src/Form/ImmersionType.php create mode 100644 src/Bundle/ChillJobBundle/src/Form/ProjetProfessionnelType.php create mode 100644 src/Bundle/ChillJobBundle/src/Form/Type/PickRomeAppellationType.php create mode 100644 src/Bundle/ChillJobBundle/src/Menu/MenuBuilder.php create mode 100644 src/Bundle/ChillJobBundle/src/Repository/CSPersonRepository.php create mode 100644 src/Bundle/ChillJobBundle/src/Repository/CV/ExperienceRepository.php create mode 100644 src/Bundle/ChillJobBundle/src/Repository/CV/FormationRepository.php create mode 100644 src/Bundle/ChillJobBundle/src/Repository/CVRepository.php create mode 100644 src/Bundle/ChillJobBundle/src/Repository/FreinRepository.php create mode 100644 src/Bundle/ChillJobBundle/src/Repository/ImmersionRepository.php create mode 100644 src/Bundle/ChillJobBundle/src/Repository/ProjetProfessionnelRepository.php create mode 100644 src/Bundle/ChillJobBundle/src/Repository/Rome/AppellationRepository.php create mode 100644 src/Bundle/ChillJobBundle/src/Repository/Rome/MetierRepository.php create mode 100644 src/Bundle/ChillJobBundle/src/Resources/config/routing.yml create mode 100644 src/Bundle/ChillJobBundle/src/Resources/config/services.yml create mode 100644 src/Bundle/ChillJobBundle/src/Resources/config/services/3party_type.yml create mode 100644 src/Bundle/ChillJobBundle/src/Resources/config/services/controller.yml create mode 100644 src/Bundle/ChillJobBundle/src/Resources/config/services/export.yml create mode 100644 src/Bundle/ChillJobBundle/src/Resources/config/services/form.yml create mode 100644 src/Bundle/ChillJobBundle/src/Resources/config/services/menu.yml create mode 100644 src/Bundle/ChillJobBundle/src/Resources/config/services/security.yml create mode 100644 src/Bundle/ChillJobBundle/src/Resources/migrations/Version20191119172511.php create mode 100644 src/Bundle/ChillJobBundle/src/Resources/migrations/Version20191129112321.php create mode 100644 src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200113104411.php create mode 100644 src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200113142525.php create mode 100644 src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200114081435.php create mode 100644 src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200124130244.php create mode 100644 src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200124132321.php create mode 100644 src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200127132932.php create mode 100644 src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200205132532.php create mode 100644 src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200207224152.php create mode 100644 src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200210105342.php create mode 100644 src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200313124323.php create mode 100644 src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200403114520.php create mode 100644 src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200403123148.php create mode 100644 src/Bundle/ChillJobBundle/src/Resources/public/images/footer_bandeau.jpg create mode 100644 src/Bundle/ChillJobBundle/src/Resources/public/images/index.js create mode 100644 src/Bundle/ChillJobBundle/src/Resources/public/module/cv_edit/index.js create mode 100644 src/Bundle/ChillJobBundle/src/Resources/public/module/dispositif_edit/index.js create mode 100644 src/Bundle/ChillJobBundle/src/Resources/public/module/immersion_edit/index.js create mode 100644 src/Bundle/ChillJobBundle/src/Resources/public/module/personal_situation/index.js create mode 100644 src/Bundle/ChillJobBundle/src/Resources/public/sass/csconnectes.scss create mode 100644 src/Bundle/ChillJobBundle/src/Resources/public/sass/index.js create mode 100644 src/Bundle/ChillJobBundle/src/Resources/translations/messages.fr.yml create mode 100644 src/Bundle/ChillJobBundle/src/Resources/views/CSPerson/dispositifs_edit.html.twig create mode 100644 src/Bundle/ChillJobBundle/src/Resources/views/CSPerson/dispositifs_view.html.twig create mode 100644 src/Bundle/ChillJobBundle/src/Resources/views/CSPerson/personal_situation_edit.html.twig create mode 100644 src/Bundle/ChillJobBundle/src/Resources/views/CSPerson/personal_situation_view.html.twig create mode 100644 src/Bundle/ChillJobBundle/src/Resources/views/CV/edit.html.twig create mode 100644 src/Bundle/ChillJobBundle/src/Resources/views/CV/new.html.twig create mode 100644 src/Bundle/ChillJobBundle/src/Resources/views/CV/view.html.twig create mode 100644 src/Bundle/ChillJobBundle/src/Resources/views/Frein/edit.html.twig create mode 100644 src/Bundle/ChillJobBundle/src/Resources/views/Frein/new.html.twig create mode 100644 src/Bundle/ChillJobBundle/src/Resources/views/Frein/view.html.twig create mode 100644 src/Bundle/ChillJobBundle/src/Resources/views/Immersion/edit-bilan.html.twig create mode 100644 src/Bundle/ChillJobBundle/src/Resources/views/Immersion/edit.html.twig create mode 100644 src/Bundle/ChillJobBundle/src/Resources/views/Immersion/new.html.twig create mode 100644 src/Bundle/ChillJobBundle/src/Resources/views/Immersion/view.html.twig create mode 100644 src/Bundle/ChillJobBundle/src/Resources/views/ProjetProfessionnel/edit.html.twig create mode 100644 src/Bundle/ChillJobBundle/src/Resources/views/ProjetProfessionnel/new.html.twig create mode 100644 src/Bundle/ChillJobBundle/src/Resources/views/ProjetProfessionnel/view.html.twig create mode 100644 src/Bundle/ChillJobBundle/src/Resources/views/Report/delete.html.twig create mode 100644 src/Bundle/ChillJobBundle/src/Resources/views/Report/index.html.twig create mode 100644 src/Bundle/ChillJobBundle/src/Security/Authorization/CSConnectesVoter.php create mode 100644 src/Bundle/ChillJobBundle/src/Security/Authorization/ExportsVoter.php create mode 100644 src/Bundle/ChillJobBundle/src/Tests/Controller/CSPersonControllerTest.php create mode 100644 src/Bundle/ChillJobBundle/src/Tests/Controller/CSReportControllerTest.php create mode 100644 src/Bundle/ChillJobBundle/src/ThirdParty/EntrepriseType.php create mode 100644 src/Bundle/ChillJobBundle/src/ThirdParty/PrescripteurType.php create mode 100644 src/Bundle/ChillJobBundle/src/chill.webpack.config.js diff --git a/composer.json b/composer.json index a000d5b3c..9953aeacf 100644 --- a/composer.json +++ b/composer.json @@ -114,6 +114,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/src/Bundle/ChillFranceTravailApiBundle/src/ApiHelper/ApiWrapper.php b/src/Bundle/ChillFranceTravailApiBundle/src/ApiHelper/ApiWrapper.php new file mode 100644 index 000000000..15e51c1f2 --- /dev/null +++ b/src/Bundle/ChillFranceTravailApiBundle/src/ApiHelper/ApiWrapper.php @@ -0,0 +1,95 @@ +clientId = $clientId; + $this->clientSecret = $clientSecret; + $this->redis = $redis; + $this->client = new Client([ + 'base_uri' => 'https://entreprise.pole-emploi.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' + ], + //'body' => 'grant_type=client_credentials&client_id=PAR_chillcsconnectesdev_0e20082886f1bc5d8ff4f8b34868603e2bcc7ed6bc5963e648e3709c639aced9&client_secret=4e626fa3123bcf4d299591c09731fa3242a7e75bbc003955f903aebc33cdd022&scope=api_romev1%20nomenclatureRome%20application_PAR_chillcsconnectesdev_0e20082886f1bc5d8ff4f8b34868603e2bcc7ed6bc5963e648e3709c639aced9' + '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(Psr7\str($e->getRequest())); + dump( Psr7\str($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..9f05834d6 --- /dev/null +++ b/src/Bundle/ChillFranceTravailApiBundle/src/ApiHelper/PartenaireRomeAppellation.php @@ -0,0 +1,101 @@ +wrapper = $wrapper; + $this->logger = $logger; + $this->client = new Client([ + 'base_uri' => 'https://api.emploi-store.fr/partenaire/rome/v1/' + ]); + } + + private function getBearer() + { + return $this->wrapper->getPublicBearer([ + 'api_romev1', + 'nomenclatureRome', + ]); + } + + /** + * + * @param string $search + */ + public function getListeAppellation($search) + { + $bearer = $this->getBearer(); + + $request = new Request('GET', 'appellation'); + $parameters = [ + 'query' => [ + 'q' => $search, + 'qf' => 'libelle' + ], + 'headers' => [ + 'Authorization' => 'Bearer '.$bearer + ] + ]; + $response = $this->handleRequest($request, $parameters, $this->client, + $this->logger); + + return \GuzzleHttp\json_decode((string) $response->getBody()); + } + + public function getAppellation($code) + { + $bearer = $this->getBearer(); + + $request = new Request('GET', sprintf('appellation/%s', $code)); + $parameters = [ + 'headers' => [ + 'Authorization' => 'Bearer '.$bearer + ], + 'query' => [ + 'champs' => 'code,libelle,metier(code,libelle)' + ] + ]; + + $response = $this->handleRequest($request, $parameters, $this->client, + $this->logger); + + return \GuzzleHttp\json_decode((string) $response->getBody()); + } +} diff --git a/src/Bundle/ChillFranceTravailApiBundle/src/ApiHelper/ProcessRequestTrait.php b/src/Bundle/ChillFranceTravailApiBundle/src/ApiHelper/ProcessRequestTrait.php new file mode 100644 index 000000000..7561c3b40 --- /dev/null +++ b/src/Bundle/ChillFranceTravailApiBundle/src/ApiHelper/ProcessRequestTrait.php @@ -0,0 +1,97 @@ +handleRequestRecursive($request, $parameters, + $client, $logger); + } + + /** + * internal method to handle recursive requests + * + * @param Request $request + * @param array $parameters + * @param Client $client + * @param LoggerInterface $logger + * @param type $counter + * @return type + * @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 + && + $e->getResponse()->getStatusCode() === 429 + && + count($e->getResponse()->getHeader('Retry-After')) > 0) { + + if ($counter > 5) { + $logger->error("too much 429 response", [ + 'request' => Psr7\str($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' => Psr7\str($e->getRequest()), + 'response' => Psr7\str($e->getResponse()), + ]); + + throw $e; + } + } +} diff --git a/src/Bundle/ChillFranceTravailApiBundle/src/ChillFranceTravailApiBundle.php b/src/Bundle/ChillFranceTravailApiBundle/src/ChillFranceTravailApiBundle.php new file mode 100644 index 000000000..9f428c6a2 --- /dev/null +++ b/src/Bundle/ChillFranceTravailApiBundle/src/ChillFranceTravailApiBundle.php @@ -0,0 +1,9 @@ +apiAppellation = $apiAppellation; + } + + /** + * @Route("/{_locale}/pole-emploi/appellation/search.{_format}", + * name="chill_pole_emploi_api_appellation_search", + * requirements={ "_format" = "json" } + * ) + */ + public function appellationSearchAction(Request $request) + { + if ($request->query->has('q') === FALSE) { + 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..15bbf3d30 --- /dev/null +++ b/src/Bundle/ChillFranceTravailApiBundle/src/DependencyInjection/ChillFranceTravailApiExtension.php @@ -0,0 +1,28 @@ +processConfiguration($configuration, $configs); + + $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + $loader->load('services.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..b013b4e46 --- /dev/null +++ b/src/Bundle/ChillFranceTravailApiBundle/src/DependencyInjection/Configuration.php @@ -0,0 +1,29 @@ +root('chill_pole_emploi_api'); + + // 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..6d0204b6e --- /dev/null +++ b/src/Bundle/ChillFranceTravailApiBundle/src/Resources/config/routing.yml @@ -0,0 +1,3 @@ +chill_poleemploi_api_controllers: + resource: "@ChillPoleEmploiApiBundle/Controller" + type: annotation \ No newline at end of file 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..ff2352d7a --- /dev/null +++ b/src/Bundle/ChillFranceTravailApiBundle/src/Resources/config/services.yml @@ -0,0 +1,14 @@ +services: + Chill\ChillFranceTravailApiBundle\ApiHelper\ApiWrapper: + $clientId: '%pole_emploi_dev_client_id%' + $clientSecret: '%pole_emploi_dev_client_secret%' + $redis: '@Chill\MainBundle\Redis\ChillRedis' + + Chill\ChillFranceTravailApiBundle\ApiHelper\PartenaireRomeAppellation: + $wrapper: '@Chill\ChillFranceTravailApiBundle\ApiHelper\ApiWrapper' + $logger: '@Psr\Log\LoggerInterface' + + Chill\ChillFranceTravailApiBundle\Controller\RomeController: + arguments: + $apiAppellation: '@Chill\ChillFranceTravailApiBundle\ApiHelper\PartenaireRomeAppellation' + 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..897bc7cb0 --- /dev/null +++ b/src/Bundle/ChillFranceTravailApiBundle/src/Tests/ApiHelper/PartenaireRomeAppellationTest.php @@ -0,0 +1,75 @@ + + */ +class PartenaireRomeAppellationTest extends KernelTestCase +{ + protected function setUp() + { + 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..b0127a85d --- /dev/null +++ b/src/Bundle/ChillFranceTravailApiBundle/src/Tests/Controller/RomeControllerTest.php @@ -0,0 +1,16 @@ +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..5120f4a79 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/ChillJobBundle.php @@ -0,0 +1,9 @@ +request->get("submit", "save-and-close"); + + switch ($next) { + case "save-and-close": + case "delete-and-close": + return $this->redirectToRoute('chill_csconnectes_csreport_index', [ + 'person' => $entity->getPerson()->getId() + ]); + default: + return parent::onBeforeRedirectAfterSubmission($action, $entity, $form, $request); + } + } + + protected function duplicateEntity(string $action, Request $request) + { + + if ($this->getCrudName() === 'cscv') { + $id = $request->query->get('duplicate_id', 0); + /** @var \Chill\ChillJobBundle\Entity\CV $cv */ + $cv = $this->getEntity($action, $id, $request); + $em = $this->getDoctrine()->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; + } elseif ($this->getCrudName() === 'projet_prof') { + $id = $request->query->get('duplicate_id', 0); + /** @var \Chill\ChillJobBundle\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() + ]); + } elseif ('bilan' === $action) { + return parent::createFormFor($action, $entity, $formClass, [ + 'center' => $entity->getPerson()->getCenter(), + 'step' => 'bilan' + ]); + } elseif ($action === 'delete') { + return parent::createFormFor($action, $entity, $formClass, $formOptions); + } else { + 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 Request $request + * @param type $id + * @return \Symfony\Component\HttpFoundation\Response + */ + public function editBilan(Request $request, $id): \Symfony\Component\HttpFoundation\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..fb1ed69a9 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Controller/CSPersonController.php @@ -0,0 +1,151 @@ +formEditAction( + 'ps_situation_edit', + $request, + $id, + CSPersonPersonalSituationType::class + ); + } + + public function dispositifsEdit(Request $request, $id) + { + return $this->formEditAction( + 'dispositifs_edit', + $request, + $id, + CSPersonDispositifsType::class + ); + } + + public function personalSituationView(Request $request, $id): Response + { + return $this->viewAction('ps_situation_view', $request, $id); + } + + public function dispositifsView(Request $request, $id): Response + { + return $this->viewAction('dispositifs_view', $request, $id); + } + + protected function generateRedirectOnCreateRoute($action, Request $request, $entity) + { + switch($action) { + case 'ps_situation_view': + $route = 'chill_crud_csperson_personal_situation_edit'; + break; + case 'dispositifs_view': + $route = 'chill_crud_csperson_dispositifs_edit'; + break; + default: + parent::generateRedirectOnCreateRoute($action, $request, $entity); + } + + return $this->generateUrl($route, ['id' => $entity->getPerson()->getId()]); + } + + protected function checkACL($action, $entity) + { + switch($action) { + case 'ps_situation_edit': + case 'dispositifs_edit': + $this->denyAccessUnlessGranted(PersonVoter::UPDATE, + $entity->getPerson()); + break; + case 'ps_situation_view': + case 'dispositifs_view': + $this->denyAccessUnlessGranted(PersonVoter::SEE, + $entity->getPerson()); + break; + default: + parent::checkACL($action, $entity); + } + } + + protected function onBeforeRedirectAfterSubmission(string $action, $entity, FormInterface $form, Request $request) + { + switch($action) { + case 'ps_situation_edit': + return $this->redirectToRoute('chill_crud_'.$this->getCrudName().'_personal_situation_view', + ['id' => $entity->getId()]); + + case 'dispositifs_edit': + return $this->redirectToRoute('chill_crud_'.$this->getCrudName().'_dispositifs_view', + ['id' => $entity->getId()]); + + default: + return null; + } + } + + protected function getTemplateFor($action, $entity, Request $request) + { + switch ($action) { + case 'ps_situation_edit': + return '@CSConnectesSP/CSPerson/personal_situation_edit.html.twig'; + case 'dispositifs_edit': + return '@CSConnectesSP/CSPerson/dispositifs_edit.html.twig'; + case 'ps_situation_view': + return '@CSConnectesSP/CSPerson/personal_situation_view.html.twig'; + case 'dispositifs_view': + return '@CSConnectesSP/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 'dispositifs_edit': + $form = $this->createForm($formClass, $entity, \array_merge( + $formOptions, [ 'center' => $entity->getPerson()->getCenter() ])); + $this->customizeForm($action, $form); + + return $form; + + case 'ps_situation_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) + { + switch($action): + case 'ps_situation_edit': + case 'dispositifs_edit': + if ($formName === 'submit') { + return 'Enregistrer'; + } else { + throw new \LogicException("this formName is not supported: $formName"); + } + break; + default: + return parent::generateLabelForButton($action, $formName, $form); + endswitch; + } + +} diff --git a/src/Bundle/ChillJobBundle/src/Controller/CSReportController.php b/src/Bundle/ChillJobBundle/src/Controller/CSReportController.php new file mode 100644 index 000000000..353474be8 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Controller/CSReportController.php @@ -0,0 +1,72 @@ +denyAccessUnlessGranted(PersonVoter::SEE, $person, "The access to " + . "person is denied"); + + $reports = $this->getReports($person); + + return $this->render('@CSConnectesSP/Report/index.html.twig', \array_merge([ + 'person' => $person, + ], $reports)); + } + + protected function getReports(Person $person) + { + $results = []; + + $kinds = []; + + if ($this->isGranted(CSConnectesVoter::REPORT_CV, $person)) { + $kinds['cvs'] = CV::class; + } + + if ($this->isGranted(CSConnectesVoter::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) { + switch ($key) { + case 'immersions': + $ordering = [ 'debutDate' => 'DESC' ]; + break; + default: + $ordering = [ 'reportDate' => 'DESC' ]; + break; + } + $results[$key] = $this->getDoctrine()->getManager() + ->getRepository($className) + ->findByPerson($person, $ordering); + } + + return $results; + } +} diff --git a/src/Bundle/ChillJobBundle/src/DependencyInjection/ChillJobExtension.php b/src/Bundle/ChillJobBundle/src/DependencyInjection/ChillJobExtension.php new file mode 100644 index 000000000..9284b1af0 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/DependencyInjection/ChillJobExtension.php @@ -0,0 +1,31 @@ +processConfiguration($configuration, $configs); + + $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + $loader->load('services.yml'); + + // exports: list_CSperson override list_person + $container->setAlias('chill.person.export.list_person','Chill\ChillJobBundle\Export\ListCSPerson'); + } +} diff --git a/src/Bundle/ChillJobBundle/src/DependencyInjection/Configuration.php b/src/Bundle/ChillJobBundle/src/DependencyInjection/Configuration.php new file mode 100644 index 000000000..b20154466 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/DependencyInjection/Configuration.php @@ -0,0 +1,29 @@ +root('cs_connectes_sp'); + + // 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..1e902d0d5 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Entity/CSPerson.php @@ -0,0 +1,1482 @@ +id; + } + + /** + * Set situationLogement. + * + * @param string|null $situationLogement + * + * @return CSPerson + */ + public function setSituationLogement($situationLogement = null) + { + $this->situationLogement = $situationLogement; + + return $this; + } + + /** + * Get situationLogement. + * + * @return string|null + */ + public function getSituationLogement() + { + return $this->situationLogement; + } + + /** + * Set enfantACharge. + * + * @param int|null $enfantACharge + * + * @return CSPerson + */ + public function setEnfantACharge($enfantACharge = null) + { + $this->enfantACharge = $enfantACharge; + + return $this; + } + + /** + * Get enfantACharge. + * + * @return int|null + */ + public function getEnfantACharge() + { + return $this->enfantACharge; + } + + /** + * Set niveauMaitriseLangue. + * + * @param json $niveauMaitriseLangue + * + * @return CSPerson + */ + public function setNiveauMaitriseLangue($niveauMaitriseLangue) + { + if ($niveauMaitriseLangue === null) { + $this->niveauMaitriseLangue = null; + + return $this; + } + + $this->niveauMaitriseLangue = count($niveauMaitriseLangue) > 0 ? + $niveauMaitriseLangue : null; + + return $this; + } + + /** + * Get niveauMaitriseLangue. + * + * @return json + */ + public function getNiveauMaitriseLangue() + { + return $this->niveauMaitriseLangue; + } + + /** + * Valide niveauMaitriseLangue + * + * @param ExecutionContextInterface $context + * @Assert\Callback() + */ + public function validateNiveauMatriseLangue(ExecutionContextInterface $context) + { + if (NULL === $this->getNiveauMaitriseLangue()) { + return; + } + + if (\in_array('aucun', $this->getNiveauMaitriseLangue())) { + 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. + * + * @param bool $vehiculePersonnel + * + * @return CSPerson + */ + public function setVehiculePersonnel($vehiculePersonnel) + { + $this->vehiculePersonnel = $vehiculePersonnel; + + return $this; + } + + /** + * Get vehiculePersonnel. + * + * @return bool + */ + public function getVehiculePersonnel() + { + return $this->vehiculePersonnel; + } + + /** + * Set permisConduire. + * + * @param json $permisConduire + * + * @return CSPerson + */ + public function setPermisConduire($permisConduire) + { + $this->permisConduire = $permisConduire; + + return $this; + } + + /** + * Get permisConduire. + * + * @return json + */ + public function getPermisConduire() + { + return $this->permisConduire; + } + + /** + * Set situationProfessionnelle. + * + * @param string $situationProfessionnelle + * + * @return CSPerson + */ + public function setSituationProfessionnelle($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($dateFinDernierEmploi) + { + $this->dateFinDernierEmploi = $dateFinDernierEmploi; + + return $this; + } + + /** + * Get dateFinDernierEmploi. + * + * @return \DateTime + */ + public function getDateFinDernierEmploi() + { + return $this->dateFinDernierEmploi; + } + + /** + * Set typeContrat. + * + * @param json $typeContrat + * + * @return CSPerson + */ + public function setTypeContrat($typeContrat) + { + $this->typeContrat = $typeContrat; + + return $this; + } + + /** + * Get typeContrat. + * + * @return json + */ + public function getTypeContrat() + { + return $this->typeContrat; + } + + /** + * Set ressources. + * + * @param json $ressources + * + * @return CSPerson + */ + public function setRessources($ressources) + { + $this->ressources = $ressources; + + return $this; + } + + /** + * Get ressources. + * + * @return json + */ + public function getRessources() + { + return $this->ressources; + } + + /** + * Set ressourcesComment. + * + * @param string $ressourcesComment + * + * @return CSPerson + */ + public function setRessourcesComment($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($ressourceDate1Versement) + { + $this->ressourceDate1Versement = $ressourceDate1Versement; + + return $this; + } + + /** + * Get ressourceDate1Versement. + * + * @return \DateTime + */ + public function getRessourceDate1Versement() + { + return $this->ressourceDate1Versement; + } + + function getCPFMontant() + { + return $this->cPFMontant; + } + + function setCPFMontant($cPFMontant) + { + $this->cPFMontant = $cPFMontant; + + return $this; + } + + /** + * Set accompagnement. + * + * @param json $accompagnement + * + * @return CSPerson + */ + public function setAccompagnement($accompagnement) + { + $this->accompagnement = $accompagnement; + + return $this; + } + + /** + * Get accompagnement. + * + * @return json + */ + public function getAccompagnement() + { + return $this->accompagnement; + } + + /** + * Set accompagnementRQTHDate. + * + * @param \DateTime $accompagnementRQTHDate + * + * @return CSPerson + */ + public function setAccompagnementRQTHDate($accompagnementRQTHDate) + { + $this->accompagnementRQTHDate = $accompagnementRQTHDate; + + return $this; + } + + /** + * Get accompagnementRQTHDate. + * + * @return \DateTime + */ + public function getAccompagnementRQTHDate() + { + return $this->accompagnementRQTHDate; + } + + /** + * Set accompagnementComment. + * + * @param string $accompagnementComment + * + * @return CSPerson + */ + public function setAccompagnementComment($accompagnementComment) + { + $this->accompagnementComment = $accompagnementComment; + + return $this; + } + + /** + * Get accompagnementComment. + * + * @return string + */ + public function getAccompagnementComment() + { + return $this->accompagnementComment; + } + + /** + * Set poleEmploiId. + * + * @param string $poleEmploiId + * + * @return CSPerson + */ + public function setPoleEmploiId($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($poleEmploiInscriptionDate) + { + $this->poleEmploiInscriptionDate = $poleEmploiInscriptionDate; + + return $this; + } + + /** + * Get poleEmploiInscriptionDate. + * + * @return \DateTime + */ + public function getPoleEmploiInscriptionDate() + { + return $this->poleEmploiInscriptionDate; + } + + /** + * Set cafId. + * + * @param string $cafId + * + * @return CSPerson + */ + public function setCafId($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($cafInscriptionDate) + { + $this->cafInscriptionDate = $cafInscriptionDate; + + return $this; + } + + /** + * Get cafInscriptionDate. + * + * @return \DateTime + */ + public function getCafInscriptionDate() + { + return $this->cafInscriptionDate; + } + + /** + * Set cERInscriptionDate. + * + * @param \DateTime $cERInscriptionDate + * + * @return CSPerson + */ + public function setCERInscriptionDate($cERInscriptionDate) + { + $this->cERInscriptionDate = $cERInscriptionDate; + + return $this; + } + + /** + * Get cERInscriptionDate. + * + * @return \DateTime + */ + public function getCERInscriptionDate() + { + return $this->cERInscriptionDate; + } + + /** + * Set pPAEInscriptionDate. + * + * @param \DateTime $pPAEInscriptionDate + * + * @return CSPerson + */ + public function setPPAEInscriptionDate($pPAEInscriptionDate) + { + $this->pPAEInscriptionDate = $pPAEInscriptionDate; + + return $this; + } + + /** + * Get pPAEInscriptionDate. + * + * @return \DateTime + */ + public function getPPAEInscriptionDate() + { + return $this->pPAEInscriptionDate; + } + + public function getCERSignataire(): ?string + { + return $this->cERSignataire; + } + + public function getPPAESignataire(): ?string + { + return $this->pPAESignataire; + } + + public function setCERSignataire($cERSignataire) + { + $this->cERSignataire = $cERSignataire; + } + + public function setPPAESignataire($pPAESignataire) + { + $this->pPAESignataire = $pPAESignataire; + } + + + /** + * Set nEETEligibilite. + * + * @param bool $nEETEligibilite + * + * @return CSPerson + */ + public function setNEETEligibilite($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($nEETCommissionDate) + { + $this->nEETCommissionDate = $nEETCommissionDate; + + return $this; + } + + /** + * Get nEETCommissionDate. + * + * @return \DateTime + */ + public function getNEETCommissionDate() + { + return $this->nEETCommissionDate; + } + + /** + * Set fSEMaDemarcheCode. + * + * @param string $fSEMaDemarcheCode + * + * @return CSPerson + */ + public function setFSEMaDemarcheCode($fSEMaDemarcheCode) + { + $this->fSEMaDemarcheCode = $fSEMaDemarcheCode; + + return $this; + } + + /** + * Get fSEMaDemarcheCode. + * + * @return string + */ + public function getFSEMaDemarcheCode() + { + return $this->fSEMaDemarcheCode; + } + + function getDispositifsNotes() + { + return $this->dispositifsNotes; + } + + function setDispositifsNotes($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); + } + + function getDocumentCV(): ?StoredObject + { + return $this->documentCV; + } + + function getDocumentAgrementIAE(): ?StoredObject + { + return $this->documentAgrementIAE; + } + + function getDocumentRQTH(): ?StoredObject + { + return $this->documentRQTH; + } + + function getDocumentAttestationNEET(): ?StoredObject + { + return $this->documentAttestationNEET; + } + + function getDocumentCI(): ?StoredObject + { + return $this->documentCI; + } + + function getDocumentTitreSejour(): ?StoredObject + { + return $this->documentTitreSejour; + } + + function getDocumentAttestationFiscale(): ?StoredObject + { + return $this->documentAttestationFiscale; + } + + function getDocumentPermis(): ?StoredObject + { + return $this->documentPermis; + } + + function getDocumentAttestationCAAF(): ?StoredObject + { + return $this->documentAttestationCAAF; + } + + function getDocumentContraTravail(): ?StoredObject + { + return $this->documentContraTravail; + } + + function getDocumentAttestationFormation(): ?StoredObject + { + return $this->documentAttestationFormation; + } + + function getDocumentQuittanceLoyer(): ?StoredObject + { + return $this->documentQuittanceLoyer; + } + + function getDocumentFactureElectricite(): ?StoredObject + { + return $this->documentFactureElectricite; + } + + function getPrescripteur(): ?ThirdParty + { + return $this->prescripteur; + } + + function setDocumentCV(StoredObject $documentCV = null) + { + $this->documentCV = $documentCV; + } + + function setDocumentAgrementIAE(StoredObject $documentAgrementIAE = null) + { + $this->documentAgrementIAE = $documentAgrementIAE; + } + + function setDocumentRQTH(StoredObject $documentRQTH = null) + { + $this->documentRQTH = $documentRQTH; + } + + function setDocumentAttestationNEET(StoredObject $documentAttestationNEET = null) + { + $this->documentAttestationNEET = $documentAttestationNEET; + } + + function setDocumentCI(StoredObject $documentCI = null) + { + $this->documentCI = $documentCI; + } + + function setDocumentTitreSejour(StoredObject $documentTitreSejour = null) + { + $this->documentTitreSejour = $documentTitreSejour; + } + + function setDocumentAttestationFiscale(StoredObject $documentAttestationFiscale = null) + { + $this->documentAttestationFiscale = $documentAttestationFiscale; + } + + function setDocumentPermis(StoredObject $documentPermis = null) + { + $this->documentPermis = $documentPermis; + } + + function setDocumentAttestationCAAF(StoredObject $documentAttestationCAAF = null) + { + $this->documentAttestationCAAF = $documentAttestationCAAF; + } + + function setDocumentContraTravail(StoredObject $documentContraTravail = null) + { + $this->documentContraTravail = $documentContraTravail; + } + + function setDocumentAttestationFormation(StoredObject $documentAttestationFormation = null) + { + $this->documentAttestationFormation = $documentAttestationFormation; + } + + function setDocumentQuittanceLoyer(StoredObject $documentQuittanceLoyer = null) + { + $this->documentQuittanceLoyer = $documentQuittanceLoyer; + } + + function setDocumentFactureElectricite(StoredObject $documentFactureElectricite = null) + { + $this->documentFactureElectricite = $documentFactureElectricite; + } + + 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($mobiliteNotes) + { + $this->mobiliteNotes = $mobiliteNotes; + + return $this; + } + + public function getHandicapAccompagnement(): ?ThirdParty + { + return $this->handicapAccompagnement; + } + + public function getDocumentAttestationSecuriteSociale(): ?StoredObject + { + return $this->documentAttestationSecuriteSociale; + } + + public function setSituationLogementPrecision($situationLogementPrecision) + { + $this->situationLogementPrecision = $situationLogementPrecision; + return $this; + } + + public function setAcompteDIF($acompteDIF) + { + $this->acompteDIF = $acompteDIF; + return $this; + } + + public function setHandicapIs($handicapIs) + { + $this->handicapIs = $handicapIs; + return $this; + } + + public function setHandicapNotes($handicapNotes) + { + $this->handicapNotes = $handicapNotes; + return $this; + } + + public function setHandicapRecommandation($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(): ?\DateTime + { + return $this->dateContratIEJ; + } + + public function setDateContratIEJ(\DateTime $dateContratIEJ = null) + { + $this->dateContratIEJ = $dateContratIEJ; + return $this; + } + + public function getTypeContratAide() + { + return $this->typeContratAide; + } + + public function setTypeContratAide($typeContratAide) + { + $this->typeContratAide = $typeContratAide; + return $this; + } + + public function getDateAvenantIEJ(): ?\DateTime + { + 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..4240bb637 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Entity/CV.php @@ -0,0 +1,353 @@ +formations = new ArrayCollection(); + $this->experiences = new ArrayCollection(); + $this->reportDate = new \DateTime('now'); + } + + /** + * Get id. + * + * @return int + */ + public function getId() + { + return $this->id; + } + + /** + * Set reportDate. + * + * @param \DateTime $reportDate + * + * @return CV + */ + public function setReportDate($reportDate) + { + $this->reportDate = $reportDate; + + return $this; + } + + /** + * Get reportDate. + * + * @return \DateTime + */ + public function getReportDate() + { + return $this->reportDate; + } + + /** + * Set formationLevel. + * + * @param string|null $formationLevel + * + * @return CV + */ + public function setFormationLevel($formationLevel = null) + { + $this->formationLevel = $formationLevel; + + return $this; + } + + /** + * Get formationLevel. + * + * @return string|null + */ + public function getFormationLevel() + { + return $this->formationLevel; + } + + /** + * Set formationType. + * + * @param string $formationType + * + * @return CV + */ + public function setFormationType($formationType) + { + $this->formationType = $formationType; + + return $this; + } + + /** + * Get formationType. + * + * @return string + */ + public function getFormationType() + { + return $this->formationType; + } + + /** + * Set spokenLanguages. + * + * @param json|null $spokenLanguages + * + * @return CV + */ + public function setSpokenLanguages($spokenLanguages = null) + { + $this->spokenLanguages = $spokenLanguages; + + return $this; + } + + /** + * Get spokenLanguages. + * + * @return json|null + */ + public function getSpokenLanguages() + { + return $this->spokenLanguages ?? []; + } + + /** + * Set notes. + * + * @param string|null $notes + * + * @return CV + */ + public function setNotes($notes = null) + { + $this->notes = $notes; + + return $this; + } + + /** + * Get notes. + * + * @return string|null + */ + public function getNotes() + { + return $this->notes; + } + + public function getFormations(): Collection + { + return $this->formations; + } + + public function getExperiences(): Collection + { + return $this->experiences; + } + + public function setFormations(Collection $formations) + { + foreach ($formations as $formation) { + /** @var CV\Formation $formation */ + $formation->setCV($this); + } + $this->formations = $formations; + + return $this; + } + + public function addFormation(CV\Formation $formation) + { + if ($this->formations->contains($formation)) { + return $this; + } + + $this->formations->add($formation); + $formation->setCV($this); + + return $this; + } + + public function removeFormation(CV\Formation $formation) + { + if (FALSE === $this->formations->contains($formation)) { + return $this; + } + + $formation->setCV(null); + $this->formations->removeElement($formation); + + return $this; + } + + public function setExperiences(Collection $experiences) + { + foreach ($experiences as $experience) { + /** @var CV\Experience $experience */ + $experience->setCV($this); + } + + $this->experiences = $experiences; + + return $this; + } + + public function addExperience(CV\Experience $experience) + { + if ($this->experiences->contains($experience)) { + return $this; + } + + $experience->setCV($this); + $this->experiences->add($experience); + + return $this; + } + + public function removeExperience(CV\Experience $experience) + { + 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() + { + 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..aed41e9da --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Entity/CV/Experience.php @@ -0,0 +1,263 @@ +id; + } + + /** + * Set poste. + * + * @param string|null $poste + * + * @return Experience + */ + public function setPoste($poste = null) + { + $this->poste = $poste; + + return $this; + } + + /** + * Get poste. + * + * @return string|null + */ + public function getPoste() + { + return $this->poste; + } + + /** + * Set structure. + * + * @param string|null $structure + * + * @return Experience + */ + public function setStructure($structure = null) + { + $this->structure = $structure; + + return $this; + } + + /** + * Get structure. + * + * @return string|null + */ + public function getStructure() + { + return $this->structure; + } + + /** + * Set startDate. + * + * @param \DateTime|null $startDate + * + * @return Experience + */ + public function setStartDate($startDate = null) + { + $this->startDate = $startDate; + + return $this; + } + + /** + * Get startDate. + * + * @return \DateTime|null + */ + public function getStartDate() + { + return $this->startDate; + } + + /** + * Set endDate. + * + * @param \DateTime|null $endDate + * + * @return Experience + */ + public function setEndDate($endDate = null) + { + $this->endDate = $endDate; + + return $this; + } + + /** + * Get endDate. + * + * @return \DateTime|null + */ + public function getEndDate() + { + return $this->endDate; + } + + /** + * Set contratType. + * + * @param string $contratType + * + * @return Experience + */ + public function setContratType($contratType) + { + $this->contratType = $contratType; + + return $this; + } + + /** + * Get contratType. + * + * @return string + */ + public function getContratType() + { + return $this->contratType; + } + + /** + * Set notes. + * + * @param string $notes + * + * @return Experience + */ + public function setNotes($notes) + { + $this->notes = $notes; + + return $this; + } + + /** + * Get notes. + * + * @return string + */ + public function getNotes() + { + return $this->notes; + } + + public function getCV(): CV + { + return $this->CV; + } + + public function setCV(?CV $CV = null) + { + $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..63749d5d7 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Entity/CV/Formation.php @@ -0,0 +1,258 @@ +id; + } + + /** + * Set title. + * + * @param string $title + * + * @return Formation + */ + public function setTitle($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($startDate = null) + { + $this->startDate = $startDate; + + return $this; + } + + /** + * Get startDate. + * + * @return \DateTime|null + */ + public function getStartDate() + { + return $this->startDate; + } + + /** + * Set endDate. + * + * @param \DateTime|null $endDate + * + * @return Formation + */ + public function setEndDate($endDate = null) + { + $this->endDate = $endDate; + + return $this; + } + + /** + * Get endDate. + * + * @return \DateTime|null + */ + public function getEndDate() + { + return $this->endDate; + } + + /** + * Set diplomaObtained. + * + * @param json|null $diplomaObtained + * + * @return Formation + */ + public function setDiplomaObtained($diplomaObtained = null) + { + $this->diplomaObtained = $diplomaObtained; + + return $this; + } + + /** + * Get diplomaObtained. + * + * @return json|null + */ + public function getDiplomaObtained() + { + return $this->diplomaObtained; + } + + /** + * Set diplomaReconnue. + * + * @param string|null $diplomaReconnue + * + * @return Formation + */ + public function setDiplomaReconnue($diplomaReconnue = null) + { + $this->diplomaReconnue = $diplomaReconnue; + + return $this; + } + + /** + * Get diplomaReconnue. + * + * @return string|null + */ + public function getDiplomaReconnue() + { + return $this->diplomaReconnue; + } + + /** + * Set organisme. + * + * @param string $organisme + * + * @return Formation + */ + public function setOrganisme($organisme) + { + $this->organisme = $organisme; + + return $this; + } + + /** + * Get organisme. + * + * @return string + */ + public function getOrganisme() + { + return $this->organisme; + } + + public function getCV(): ?CV + { + return $this->CV; + } + + public function setCV(?CV $CV = null) + { + $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..891dd0a2c --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Entity/Frein.php @@ -0,0 +1,272 @@ +reportDate = new \DateTime('today'); + } + + /** + * Get id. + * + * @return int + */ + public function getId() + { + return $this->id; + } + + /** + * Set reportDate. + * + * @param \DateTime $reportDate + * + * @return Frein + */ + public function setReportDate($reportDate) + { + $this->reportDate = $reportDate; + + return $this; + } + + /** + * Get reportDate. + * + * @return \DateTime + */ + public function getReportDate() + { + return $this->reportDate; + } + + /** + * Set freinsPerso. + * + * @param string[] $freinsPerso + * + * @return Frein + */ + public function setFreinsPerso(array $freinsPerso = []) + { + $this->freinsPerso = $freinsPerso; + + return $this; + } + + /** + * Get freinsPerso. + * + * @return json + */ + public function getFreinsPerso() + { + return $this->freinsPerso; + } + + /** + * Set notesPerso. + * + * @param string $notesPerso + * + * @return Frein + */ + public function setNotesPerso(string $notesPerso = null) + { + $this->notesPerso = (string) $notesPerso; + + return $this; + } + + /** + * Get notesPerso. + * + * @return string + */ + public function getNotesPerso() + { + return $this->notesPerso; + } + + /** + * Set freinsEmploi. + * + * @param json $freinsEmploi + * + * @return Frein + */ + public function setFreinsEmploi(array $freinsEmploi = []) + { + $this->freinsEmploi = $freinsEmploi; + + return $this; + } + + /** + * Get freinsEmploi. + * + * @return json + */ + public function getFreinsEmploi() + { + return $this->freinsEmploi; + } + + /** + * Set notesEmploi. + * + * @param string $notesEmploi + * + * @return Frein + */ + public function setNotesEmploi(string $notesEmploi = null) + { + $this->notesEmploi = (string) $notesEmploi; + + return $this; + } + + /** + * Get notesEmploi. + * + * @return string + */ + public function getNotesEmploi() + { + return $this->notesEmploi; + } + + public function getPerson(): ?\Chill\PersonBundle\Entity\Person + { + return $this->person; + } + + public function setPerson(\Chill\PersonBundle\Entity\Person $person = null): HasPerson + { + $this->person = $person; + + return $this; + } + + /** + * Vérifie qu'au moins un frein a été coché parmi les freins perso + emploi + * + * @param ExecutionContextInterface $context + * @param array $payload + * @Assert\Callback() + */ + public function validateFreinsCount(ExecutionContextInterface $context, $payload) + { + $nb = count($this->getFreinsEmploi()) + count($this->getFreinsPerso()); + + if ($nb === 0) { + $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() + { + 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..69bf513ad --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Entity/Immersion.php @@ -0,0 +1,1256 @@ +id; + } + + /** + * Set domaineActivite. + * + * @param string|null $domaineActivite + * + * @return Immersion + */ + public function setDomaineActivite($domaineActivite = null) + { + $this->domaineActivite = $domaineActivite; + + return $this; + } + + /** + * Get domaineActivite. + * + * @return string|null + */ + public function getDomaineActivite() + { + return $this->domaineActivite; + } + + /** + * Set tuteurName. + * + * @param string|null $tuteurName + * + * @return Immersion + */ + public function setTuteurName($tuteurName = null) + { + $this->tuteurName = $tuteurName; + + return $this; + } + + /** + * Get tuteurName. + * + * @return string|null + */ + public function getTuteurName() + { + return $this->tuteurName; + } + + /** + * Set tuteurFonction. + * + * @param string|null $tuteurFonction + * + * @return Immersion + */ + public function setTuteurFonction($tuteurFonction = null) + { + $this->tuteurFonction = $tuteurFonction; + + return $this; + } + + /** + * Get tuteurFonction. + * + * @return string|null + */ + public function getTuteurFonction() + { + return $this->tuteurFonction; + } + + /** + * Set tuteurPhoneNumber. + * + * @param string|null $tuteurPhoneNumber + * + * @return Immersion + */ + public function setTuteurPhoneNumber($tuteurPhoneNumber = null) + { + $this->tuteurPhoneNumber = $tuteurPhoneNumber; + + return $this; + } + + /** + * Get tuteurPhoneNumber. + * + * @return string|null + */ + public function getTuteurPhoneNumber() + { + return $this->tuteurPhoneNumber; + } + + /** + * Set structureAccName. + * + * @param string|null $structureAccName + * + * @return Immersion + */ + public function setStructureAccName($structureAccName = null) + { + $this->structureAccName = $structureAccName; + + return $this; + } + + /** + * Get structureAccName. + * + * @return string|null + */ + public function getStructureAccName() + { + return $this->structureAccName; + } + + /** + * Set structureAccPhonenumber. + * + * @param string $structureAccPhonenumber + * + * @return Immersion + */ + public function setStructureAccPhonenumber($structureAccPhonenumber) + { + $this->structureAccPhonenumber = $structureAccPhonenumber; + + return $this; + } + + /** + * Get structureAccPhonenumber. + * + * @return string + */ + public function getStructureAccPhonenumber() + { + return $this->structureAccPhonenumber; + } + + /** + * Set posteDescriptif. + * + * @param string|null $posteDescriptif + * + * @return Immersion + */ + public function setPosteDescriptif($posteDescriptif = null) + { + $this->posteDescriptif = $posteDescriptif; + + return $this; + } + + /** + * Get posteDescriptif. + * + * @return string|null + */ + public function getPosteDescriptif() + { + return $this->posteDescriptif; + } + + /** + * Set posteTitle. + * + * @param string|null $posteTitle + * + * @return Immersion + */ + public function setPosteTitle($posteTitle = null) + { + $this->posteTitle = $posteTitle; + + return $this; + } + + /** + * Get posteTitle. + * + * @return string|null + */ + public function getPosteTitle() + { + return $this->posteTitle; + } + + /** + * Set posteLieu. + * + * @param string|null $posteLieu + * + * @return Immersion + */ + public function setPosteLieu($posteLieu = null) + { + $this->posteLieu = $posteLieu; + + return $this; + } + + /** + * Get posteLieu. + * + * @return string|null + */ + public function getPosteLieu() + { + return $this->posteLieu; + } + + /** + * Set debutDate. + * + * @param \DateTime|null $debutDate + * + * @return Immersion + */ + public function setDebutDate($debutDate = null) + { + $this->debutDate = $debutDate; + + return $this; + } + + /** + * Get debutDate. + * + * @return \DateTime|null + */ + 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. + * + * @return string|null + */ + public function getDuration() + { + return $this->duration; + } + + public function getDateEndComputed() + { + $startDate = \DateTimeImmutable::createFromMutable($this->getDebutDate()); + + return $startDate->add($this->getDuration()); + } + + /** + * Set horaire. + * + * @param string|null $horaire + * + * @return Immersion + */ + public function setHoraire($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($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. + * + * @param string $note + * + * @return Immersion + */ + public function setNoteImmersion($note) + { + $this->noteImmersion = (string) $note; + + return $this; + } + + /** + * Get note. + * + * @return string + */ + public function getNoteImmersion() + { + return $this->noteImmersion; + } + + /** + * Set principalesActivites. + * + * @param string|null $principalesActivites + * + * @return Immersion + */ + public function setPrincipalesActivites($principalesActivites = null) + { + $this->principalesActivites = $principalesActivites; + + return $this; + } + + /** + * Get principalesActivites. + * + * @return string|null + */ + public function getPrincipalesActivites() + { + return $this->principalesActivites; + } + + /** + * Set competencesAcquises. + * + * @param string|null $competencesAcquises + * + * @return Immersion + */ + public function setCompetencesAcquises($competencesAcquises = null) + { + $this->competencesAcquises = $competencesAcquises; + + return $this; + } + + /** + * Get competencesAcquises. + * + * @return string|null + */ + public function getCompetencesAcquises() + { + return $this->competencesAcquises; + } + + /** + * Set competencesADevelopper. + * + * @param string|null $competencesADevelopper + * + * @return Immersion + */ + public function setCompetencesADevelopper($competencesADevelopper = null) + { + $this->competencesADevelopper = $competencesADevelopper; + + return $this; + } + + /** + * Get competencesADevelopper. + * + * @return string|null + */ + public function getCompetencesADevelopper() + { + return $this->competencesADevelopper; + } + + /** + * Set noteBilan. + * + * @param string|null $noteBilan + * + * @return Immersion + */ + public function setNoteBilan($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($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($isBilanFullfilled) + { + $this->isBilanFullfilled = $isBilanFullfilled; + return $this; + } + + public function setSavoirEtreNote($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($ponctualiteSalarie) + { + $this->ponctualiteSalarie = $ponctualiteSalarie; + return $this; + } + + public function setPonctualiteSalarieNote($ponctualiteSalarieNote) + { + $this->ponctualiteSalarieNote = $ponctualiteSalarieNote; + return $this; + } + + public function setAssiduite($assiduite) + { + $this->assiduite = $assiduite; + return $this; + } + + public function setAssiduiteNote($assiduiteNote) + { + $this->assiduiteNote = $assiduiteNote; + return $this; + } + + public function setInteretActivite($interetActivite) + { + $this->interetActivite = $interetActivite; + return $this; + } + + public function setInteretActiviteNote($interetActiviteNote) + { + $this->interetActiviteNote = $interetActiviteNote; + return $this; + } + + public function setIntegreRegle($integreRegle) + { + $this->integreRegle = $integreRegle; + return $this; + } + + public function setIntegreRegleNote($integreRegleNote) + { + $this->integreRegleNote = $integreRegleNote; + return $this; + } + + public function setEspritInitiative($espritInitiative) + { + $this->espritInitiative = $espritInitiative; + return $this; + } + + public function setEspritInitiativeNote($espritInitiativeNote) + { + $this->espritInitiativeNote = $espritInitiativeNote; + return $this; + } + + public function setOrganisation($organisation) + { + $this->organisation = $organisation; + return $this; + } + + public function setOrganisationNote($organisationNote) + { + $this->organisationNote = $organisationNote; + return $this; + } + + public function setCapaciteTravailEquipe($capaciteTravailEquipe) + { + $this->capaciteTravailEquipe = $capaciteTravailEquipe; + return $this; + } + + public function setCapaciteTravailEquipeNote($capaciteTravailEquipeNote) + { + $this->capaciteTravailEquipeNote = $capaciteTravailEquipeNote; + return $this; + } + + public function setStyleVestimentaire($styleVestimentaire) + { + $this->styleVestimentaire = $styleVestimentaire; + return $this; + } + + public function setStyleVestimentaireNote($styleVestimentaireNote) + { + $this->styleVestimentaireNote = $styleVestimentaireNote; + return $this; + } + + public function setLangageProf($langageProf) + { + $this->langageProf = $langageProf; + return $this; + } + + public function setLangageProfNote($langageProfNote) + { + $this->langageProfNote = $langageProfNote; + return $this; + } + + public function setAppliqueConsigne($appliqueConsigne) + { + $this->appliqueConsigne = $appliqueConsigne; + return $this; + } + + public function setAppliqueConsigneNote($appliqueConsigneNote) + { + $this->appliqueConsigneNote = $appliqueConsigneNote; + return $this; + } + + public function setRespectHierarchie($respectHierarchie) + { + $this->respectHierarchie = $respectHierarchie; + return $this; + } + + public function setRespectHierarchieNote($respectHierarchieNote) + { + $this->respectHierarchieNote = $respectHierarchieNote; + return $this; + } + + public function __toString() + { + 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..95e0fc136 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Entity/ProjetProfessionnel.php @@ -0,0 +1,468 @@ +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($reportDate) + { + $this->reportDate = $reportDate; + + return $this; + } + + /** + * Get reportDate. + * + * @return \DateTime + */ + public function getReportDate() + { + return $this->reportDate; + } + + /** + * Set typeContrat. + * + * @param json|null $typeContrat + * + * @return ProjetProfessionnel + */ + public function setTypeContrat($typeContrat = null) + { + $this->typeContrat = $typeContrat; + + return $this; + } + + /** + * Get typeContrat. + * + * @return json|null + */ + public function getTypeContrat() + { + return $this->typeContrat; + } + + /** + * Set typeContratNotes. + * + * @param string|null $typeContratNotes + * + * @return ProjetProfessionnel + */ + public function setTypeContratNotes($typeContratNotes = null) + { + $this->typeContratNotes = $typeContratNotes; + + return $this; + } + + /** + * Get typeContratNotes. + * + * @return string|null + */ + public function getTypeContratNotes() + { + return $this->typeContratNotes; + } + + /** + * Set volumeHoraire. + * + * @param json|null $volumeHoraire + * + * @return ProjetProfessionnel + */ + public function setVolumeHoraire($volumeHoraire = null) + { + $this->volumeHoraire = $volumeHoraire; + + return $this; + } + + /** + * Get volumeHoraire. + * + * @return json|null + */ + public function getVolumeHoraire() + { + return $this->volumeHoraire; + } + + /** + * Set volumeHoraireNotes. + * + * @param string|null $volumeHoraireNotes + * + * @return ProjetProfessionnel + */ + public function setVolumeHoraireNotes($volumeHoraireNotes = null) + { + $this->volumeHoraireNotes = $volumeHoraireNotes; + + return $this; + } + + /** + * Get volumeHoraireNotes. + * + * @return string|null + */ + public function getVolumeHoraireNotes() + { + return $this->volumeHoraireNotes; + } + + /** + * Set idee. + * + * @param string|null $idee + * + * @return ProjetProfessionnel + */ + public function setIdee($idee = null) + { + $this->idee = $idee; + + return $this; + } + + /** + * Get idee. + * + * @return string|null + */ + public function getIdee() + { + return $this->idee; + } + + /** + * Set enCoursConstruction. + * + * @param string|null $enCoursConstruction + * + * @return ProjetProfessionnel + */ + public function setEnCoursConstruction($enCoursConstruction = null) + { + $this->enCoursConstruction = $enCoursConstruction; + + return $this; + } + + /** + * Get enCoursConstruction. + * + * @return string|null + */ + public function getEnCoursConstruction() + { + return $this->enCoursConstruction; + } + + /** + * Set valideNotes. + * + * @param string|null $valideNotes + * + * @return ProjetProfessionnel + */ + public function setValideNotes($valideNotes = null) + { + $this->valideNotes = $valideNotes; + + return $this; + } + + /** + * Get valideNotes. + * + * @return string|null + */ + public function getValideNotes() + { + return $this->valideNotes; + } + + /** + * Set projetProfessionnelNote. + * + * @param string|null $projetProfessionnelNote + * + * @return ProjetProfessionnel + */ + public function setProjetProfessionnelNote($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() + { + 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..e3e2dedb4 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Entity/Rome/Appellation.php @@ -0,0 +1,125 @@ +id; + } + + /** + * Set code. + * + * @param string $code + * + * @return Appellation + */ + public function setCode($code) + { + $this->code = $code; + + return $this; + } + + /** + * Get code. + * + * @return string + */ + public function getCode() + { + return $this->code; + } + + /** + * Set libelle. + * + * @param string $libelle + * + * @return Appellation + */ + public function setLibelle($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() + { + return $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..d6ab5a751 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Entity/Rome/Metier.php @@ -0,0 +1,112 @@ +appellation = new ArrayCollection(); + } + + + /** + * Get id. + * + * @return int + */ + public function getId() + { + return $this->id; + } + + /** + * Set libelle. + * + * @param string $libelle + * + * @return Metier + */ + public function setLibelle($libelle) + { + $this->libelle = $libelle; + + return $this; + } + + /** + * Get libelle. + * + * @return string + */ + public function getLibelle() + { + return $this->libelle; + } + + /** + * Set code. + * + * @param string $code + * + * @return Metier + */ + public function setCode($code) + { + $this->code = $code; + + return $this; + } + + /** + * Get code. + * + * @return string + */ + public function getCode() + { + return $this->code; + } +} diff --git a/src/Bundle/ChillJobBundle/src/Export/ListCSPerson.php b/src/Bundle/ChillJobBundle/src/Export/ListCSPerson.php new file mode 100644 index 000000000..bc69b70fd --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Export/ListCSPerson.php @@ -0,0 +1,653 @@ + CSPerson::RESSOURCES, + 'moyen_transport__label' => CSPerson::MOBILITE_MOYEN_TRANSPORT, + 'type_contrat__label' => CSPerson::TYPE_CONTRAT, + 'permis_conduire__label' => CSPerson::PERMIS_CONDUIRE, + 'accompagnement__label' => CSPerson::ACCOMPAGNEMENTS, + 'situation_professionnelle__label' => CSPerson::SITUATION_PROFESSIONNELLE, + 'neet_eligibility__label' => CSPerson::NEET_ELIGIBILITY + ]; + + /** + * @var array + */ + protected $personIds = []; + + /** EntityManagerInterface $em */ + protected $em; + /** TranslatorInterface $translator */ + protected $translator; + /** TranslatableStringHelper $translatableStringHelper */ + protected $translatableStringHelper; + /** CustomFieldProvider $customFieldProvider */ + protected $customFieldProvider; + + public function __construct( + EntityManagerInterface $em, + TranslatorInterface $translator, + TranslatableStringHelper $translatableStringHelper, + CustomFieldProvider $customFieldProvider + ) { + parent::__construct($em, $translator, $translatableStringHelper, $customFieldProvider); + } + + /** + * Rebuild fields array, combining parent ListPerson and ListCSPerson, + * adding query type as value + * + * @return array + */ + protected function allFields() + { + $fields = [ + 'id' => 'integer', + 'firstName' => 'string', + 'lastName' => 'string', + 'gender' => 'string', + 'birthdate' => 'date', + 'placeOfBirth' => 'string', + 'countryOfBirth' => 'json', + 'nationality' => 'json', + 'email' => 'string', + 'phonenumber' => 'string', + 'mobilenumber' => 'string', + 'contactInfo' => 'string', + 'memo' => 'string', + 'address_valid_from' => 'date', + 'address_street_address_1' => 'string', + 'address_street_address_2' => 'string', + 'address_postcode_code' => 'string', + 'address_postcode_label' => 'string', + 'address_country_name' => 'string', + 'address_country_code' => 'string', + 'address_isnoaddress' => 'boolean' + ]; + + $CSfields = [ + 'recentopeningdate' => 'date', + 'recentclosingdate' => 'date', + 'closingmotive' => 'json', + 'situation_familiale' => 'json', + 'enfantacharge' => 'integer', + 'accompagnement__label' => 'json', + 'findernieremploidate' => 'date', + 'prescripteur__name' => 'string', + 'prescripteur__email' => 'string', + 'prescripteur__phone' => 'string', + 'poleemploiid' => 'string', + 'cafid' => 'string', + 'cafinscriptiondate' => 'date', + 'contratiejdate' => 'date', + 'cerinscriptiondate' => 'date', + 'ppaeinscriptiondate' => 'date', + 'ppaesignataire' => 'string', + 'cersignataire' => 'string', + 'neet_eligibility__label' => 'string', + 'neetcommissiondate' => 'date', + 'fsemademarchecode' => 'string', + 'permis_conduire__label' => 'json', + 'situation_professionnelle__label' => 'string', + 'datefindernieremploi' => 'date', + 'type_contrat__label' => 'json', + 'ressource__label' => 'json', + 'moyen_transport__label' => 'json' + ]; + + return array_merge($fields, $CSfields); + } + + /** + * Return array FIELDS keys only + * + * @return array + */ + private function getFields() + { + return array_keys($this->allFields()); + } + + /** + * 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) + { + $csperson = self::CSPERSON; + + $fields = []; + foreach ($data['fields'] as $key) { + switch ($key) { + + case 'ressource__label': + case 'moyen_transport__label': + foreach ($csperson[$key] as $item) { + $this->translationCompatKey($item, $key); + $fields[] = $item; + } + break; + + case 'prescripteur__name': + case 'prescripteur__email': + case 'prescripteur__phone': + $key = str_replace('__', '.', $key); + + case 'situation_professionnelle__label': + case 'neet_eligibility__label': + + case 'accompagnement__label': + case 'permis_conduire__label': + case 'type_contrat__label': + + default: + $fields[] = $key; + } + } + return $fields; + } + + /** + * 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) + { + $csperson = self::CSPERSON; + + /** + * @var array $row each row exported + */ + $results = []; + foreach ($rows as $row) { + + /** + * @var string $key + * @var mixed $value + */ + $res = []; + foreach ($row as $key => $value) { + + switch ($key) { + case 'ressource__label': + case 'moyen_transport__label': + + foreach ($csperson[$key] as $item) { + $this->translationCompatKey($item, $key); + if (($value === null)||(count($value) === 0)) { + $res[$item] = ''; + } else { + foreach ($value as $v) { + $this->translationCompatKey($v, $key); + + if ($item === $v) { + $res[$item] = 'x'; + break; + } else { + $res[$item] = ''; + } + } + } + } + break; + + case 'situation_professionnelle__label': + + $f = false; + if ($value === 'en_activite') { + $f = true; + } + $res[$key] = $value; + break; + + case 'type_contrat__label': + + if (! empty($value)) { + $res[$key] = ($f) ? $value : null; + } else { + $res[$key] = null; + } + break; + + case 'prescripteur__name': + case 'prescripteur__email': + case 'prescripteur__phone': + + $key = str_replace('__', '.', $key); + + case 'neet_eligibility__label': + case 'accompagnement__label': + case 'permis_conduire__label': + + default: + $res[$key] = $value; + } + } + $results[] = $res; + } + return $results; + } + + /** + * 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; + } + + /** + * @param FormBuilderInterface $builder + */ + public function buildForm(FormBuilderInterface $builder) + { + parent::buildForm($builder); // ajouter un '?' dans la query + + $choices = array_combine($this->getFields(), $this->getFields()); + + $builder->add('fields', ChoiceType::class, array( + 'multiple' => true, + 'expanded' => true, + 'choices' => $choices, + 'data' => $choices, //les checkbox cochés !! + 'choices_as_values' => true, + 'label' => 'Fields to include in export', + 'choice_label' => function ($key) { + return str_replace('__', '.', $key); + }, + 'choice_attr' => function($val) { + if (substr($val, 0, 8) === 'address_') { + return ['data-display-target' => 'address_date']; + } else { + return []; + } + }, + 'constraints' => [new Callback(array( + 'callback' => function($selected, ExecutionContextInterface $context) { + if (count($selected) === 0) { + $context->buildViolation('You must select at least one element') + ->atPath('fields') + ->addViolation(); + } + } + ))] + )); + } + + /** + * @param array $requiredModifiers + * @param array $acl + * @param array $data + * @return \Doctrine\ORM\NativeQuery|\Doctrine\ORM\QueryBuilder + * @throws \Doctrine\DBAL\Exception\InvalidArgumentException + */ + public function initiateQuery(array $requiredModifiers, array $acl, array $data = array()) + { + $centers = array_map(function($el) { return $el['center']; }, $acl); + + // throw an error if any fields are present + if (!\array_key_exists('fields', $data)) { + throw new \Doctrine\DBAL\Exception\InvalidArgumentException("any fields " + . "have been checked"); + } + + $qb = $this->entityManager->createQueryBuilder() + ->from('ChillPersonBundle:Person', 'person') + ->join('person.center', 'center') + ->andWhere('center IN (:authorized_centers)') + ->setParameter('authorized_centers', $centers) + ; + return $qb; + } + + /** + * @param \Doctrine\ORM\NativeQuery|\Doctrine\ORM\QueryBuilder $qb + * @param mixed[] $data + * @return mixed|mixed[] + */ + public function getResult($qb, $data) + { + $qb->select('person.id'); + + $ids = $qb->getQuery()->getResult(Query::HYDRATE_SCALAR); + $this->personIds = array_map(function ($e) { return $e['id']; }, $ids); + + $personIdsParameters = '?'. \str_repeat(', ?', count($this->personIds) -1); + $query = \str_replace('%person_ids%', $personIdsParameters, self::QUERY); + + $rsm = new Query\ResultSetMapping(); + + + foreach ($this->allFields() as $name => $type) { + if ($data['fields'][$name]) { + $rsm->addScalarResult(strtolower($name), $name, $type); + } + } + + $nq = $this->entityManager->createNativeQuery($query, $rsm); + + $idx = 0; + for ($i=1; $i<=8; $i++) { + $idx++; + $nq->setParameter($idx, $data['address_date'], 'date'); + } + for ($i=1; $i<=(count($this->personIds)); $i++) { + $idx++; + $nq->setParameter($idx, $this->personIds[$i-1]); + } + + return $this->splitArrayToColumns( + $nq->getResult() + ); + } + + /** + * @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` + * + * @return \Closure where the first argument is the value, and the function should return the label to show in the formatted file. Example : `function($countryCode) use ($countries) { return $countries[$countryCode]->getName(); }` + */ + public function getLabels($key, array $values, $data) + { + $csperson = self::CSPERSON; + + switch ($key) { + case 'countryOfBirth': + case 'situation_familiale': + case 'closingmotive': + case 'nationality': + return function ($value) use ($key) { + if ($value === '_header') { return $key; } + return $value['fr']; + }; + case 'accompagnement__label': + case 'permis_conduire__label': + case 'type_contrat__label': + return function ($value) use ($key, $csperson) { + if ($value === '_header') { + return $this->translator->trans( + str_replace('__', '.', $key) + ); + } + if (empty($value)) { return ''; } + $arr = []; + foreach ($value as $v) { + $this->translationCompatKey($v, $key); + $arr[] = $this->translator->trans($v); + } + return implode(', ', $arr); + }; + case 'situation_professionnelle__label': + case 'neet_eligibility__label': + return function ($value) use ($key) { + if ($value === '_header') { + return $this->translator->trans( + str_replace('__', '.', $key) + ); + } + if (empty($value)) { return ''; } + $this->translationCompatKey($value, $key); + return $this->translator->trans($value); + }; + case 'birthdate': + case 'address_valid_from': + case 'recentopeningdate': + case 'recentclosingdate': + case 'findernieremploidate': + case 'cafinscriptiondate': + case 'contratiejdate': + case 'cerinscriptiondate': + case 'ppaeinscriptiondate': + case 'neetcommissiondate': + case 'datefindernieremploi': + /** @var \DateTime $value */ + return function($value) use ($key) { + if ($value === '_header') { return $key; } + if (empty($value)) { return ''; } + return $value->format('d-m-Y'); + }; + + // remplace les getLabels de ListPerson + // (pas possible d'utiliser parent qui appelle une méthode private pour les customfields) + case 'gender' : + return function ($value) { + if ($value === '_header') { return 'gender'; } + return $this->translator->trans($value); + }; + case 'address_country_name': + return function ($value) use ($key) { + if ($value === '_header') { return \strtolower($key); } + if ($value === null) { return ''; } + return $this->translatableStringHelper->localize(json_decode($value, true)); + }; + case 'address_isnoaddress': + return parent::getLabels($key, $values, $data); + default: + return function ($value) use ($key) { + if ($value === '_header') { + return $key; + } + if (empty($value)) { return ''; } + return $value; + }; + } + } + + /** + * Native Query SQL + */ + const QUERY = << '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. + * + * @param EntityManagerInterface $em + */ + 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 + * @param ExecutionContextInterface $context + */ + 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. + * + * @param FormBuilderInterface $builder + */ + 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 (count($selected) === 0) { + $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 $requiredModifiers + * @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 = array()) + { + 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. + * + * @return \Symfony\Component\Security\Core\Role\Role + * + */ + public function requiredRole() + { + return new Role(ExportsVoter::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) + * @return mixed[] an array of results + */ + public function getResult($qb, $data) + { + $qb->select('person.id'); + + $ids = $qb->getQuery()->getResult(Query::HYDRATE_SCALAR); + $this->personIds = array_map(function ($e) { return $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 ($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` + * @return \Closure where the first argument is the value, and the function should return the label to show in the formatted file. Example : `function($countryCode) use ($countries) { return $countries[$countryCode]->getName(); }` + */ + public function getLabels($key, array $values, $data) + { + + switch ($key) { + case 'birthdate': + /** @var \DateTime $value */ + return function($value) use ($key) { + if ($value === '_header') { return $key; } + if (empty($value)) { return ''; } + return $value->format('d-m-Y'); + }; + case 'countryofbirth': + return function ($value) use ($key) { + if ($value === '_header') { + return $key; + } + return $value['fr']; + }; + case 'gender': + return function ($value) use ($key) { + $gend_array = [ 'man' => 'Homme', 'woman' => 'Femme', 'both' => 'Indéterminé' ]; + if ($value === '_header') { return $key; } + if (empty($value)) { return ''; } + return $gend_array[$value]; + }; + case 'id': + case 'firstname': + case 'lastname': + case 'placeofbirth': + case 'formationlevel': + default: + return function ($value) use ($key) { + if ($value === '_header') { + return $key; + } + return $value; + }; + } + } + + /** + * Native Query SQL + */ + const QUERY = << Frein::FREINS_PERSO, + 'freinsemploi' => Frein::FREINS_EMPLOI, + ]; + + /** + * @var array + */ + 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. + * + * @param EntityManagerInterface $em + */ + 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 + * @param ExecutionContextInterface $context + */ + 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. + * + * @param FormBuilderInterface $builder + */ + 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 (count($selected) === 0) { + $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 $requiredModifiers + * @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 = array()) + { + 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 [ 'frein', 'person' ]; + } + + /** + * Return the required Role to execute the Export. + * + * @return \Symfony\Component\Security\Core\Role\Role + * + */ + public function requiredRole() + { + return new Role(ExportsVoter::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; + + /** + * @var array $row each row exported + */ + $results = []; + foreach ($rows as $row) { + + /** + * @var string $key + * @var mixed $value + */ + $res = []; + foreach ($row as $key => $value) { + + switch ($key) { + case 'freinsperso': + case 'freinsemploi': + + foreach ($freins[$key] as $item) { + $this->translationCompatKey($item, $key); + + if (count($value) === 0) { + $res[$item] = ''; + + } else { + foreach ($value as $v) { + + $this->translationCompatKey($v, $key); + if ($item === $v) { + $res[$item] = 'x'; + break; + } else { + $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) + * @return mixed[]|\closure an array of results + */ + public function getResult($qb, $data) + { + $qb->select('person.id'); + + $ids = $qb->getQuery()->getResult(Query::HYDRATE_SCALAR); + $this->personIds = array_map(function ($e) { return $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 ($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` + * @return \Closure where the first argument is the value, and the function should return the label to show in the formatted file. Example : `function($countryCode) use ($countries) { return $countries[$countryCode]->getName(); }` + */ + public function getLabels($key, array $values, $data) + { + + switch ($key) { + case 'reportdate': + case 'birthdate': + /** @var \DateTime $value */ + return function($value) use ($key) { + if ($value === '_header') { return $key; } + if (empty($value)) { return ''; } + return $value->format('d-m-Y'); + }; + case 'countryofbirth': + return function ($value) use ($key) { + if ($value === '_header') { + return $key; + } + return $value['fr']; + }; + case 'gender': + return function ($value) use ($key) { + $gend_array = [ 'man' => 'Homme', 'woman' => 'Femme', 'both' => 'Indéterminé' ]; + if ($value === '_header') { return $key; } + if (empty($value)) { return ''; } + return $gend_array[$value]; + }; + case 'id': + case 'firstname': + case 'lastname': + case 'placeofbirth': + case 'notesperso': + case 'notesemploi': + default: + return function ($value) use ($key) { + if ($value === '_header') { + return $key; + } + if (empty($value)) { return ''; } + return $value; + }; + } + } + + + /** + * Native Query SQL + */ + const QUERY = << ProjetProfessionnel::TYPE_CONTRAT, + 'projet_prof__volume_horaire__label' => ProjetProfessionnel::VOLUME_HORAIRES + ]; + + /** + * @var array + */ + 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. + * + * @param EntityManagerInterface $em + */ + 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 + * @param ExecutionContextInterface $context + */ + 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. + * + * @param FormBuilderInterface $builder + */ + 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' => function ($key) { + return str_replace('__', '.', $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 (count($selected) === 0) { + $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 $requiredModifiers + * @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 = array()) + { + 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. + * + * @return \Symfony\Component\Security\Core\Role\Role + * + */ + public function requiredRole() + { + return new Role(ExportsVoter::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('__', '.', $key); + + 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; + + /** + * @var array $row each row exported + */ + $results = []; + foreach ($rows as $row) { + + /** + * @var string $key + * @var mixed $value + */ + $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 (count($value) === 0) { + $res[$item] = ''; + + } else { + foreach ($value as $v) { + $this->translationCompatKey($v, $key); + + if ($item === $v) { + $res[$item] = 'x'; + break; + } else { + $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('__', '.', $key); + + 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) + * @return mixed[] an array of results + */ + public function getResult($qb, $data) + { + $qb->select('person.id'); + + $ids = $qb->getQuery()->getResult(Query::HYDRATE_SCALAR); + $this->personIds = array_map(function ($e) { return $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 ($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` + * @return \Closure where the first argument is the value, and the function should return the label to show in the formatted file. Example : `function($countryCode) use ($countries) { return $countries[$countryCode]->getName(); }` + */ + public function getLabels($key, array $values, $data) + { + switch ($key) { + case 'birthdate': + /** @var \DateTime $value */ + return function($value) use ($key) { + if ($value === '_header') { return $key; } + if (empty($value)) { return ''; } + return $value->format('d-m-Y'); + }; + case 'countryofbirth': + return function ($value) use ($key) { + if ($value === '_header') { + return $key; + } + return $value['fr']; + }; + case 'projet_prof.valide.code': + case 'projet_prof.souhait.code': + return function ($value) use ($key) { + if ($value === '_header') { return $key; } + if ($value === '{NULL}') { return ''; } + return str_replace(['{','}'], '', $value); + }; + case 'gender': + return function ($value) use ($key) { + $gend_array = [ 'man' => 'Homme', 'woman' => 'Femme', 'both' => 'Indéterminé' ]; + if ($value === '_header') { return $key; } + if (empty($value)) { return ''; } + return $gend_array[$value]; + }; + case 'id': + case 'firstname': + case 'lastname': + case 'placeofbirth': + + default: + return function ($value) use ($key) { + if ($value === '_header') { + return $key; + } + if (empty($value)) { return ''; } + return $value; + }; + } + } + + /** + * Native Query SQL + */ + const QUERY = <<add('accompagnement', ChoiceType::class, [ + 'choices' => \array_combine(CSPerson::ACCOMPAGNEMENTS, CSPerson::ACCOMPAGNEMENTS), + 'required' => false, + 'label' => 'Accompagnement', + 'multiple' => true, + 'expanded' => true, + 'choice_label' => function($k) { return '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' => function($k) { return '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', PickThirdPartyType::class, [ + 'required' => false, + 'types' => ['prescripteur'], + 'label' => 'Prescripteur', + 'center' => $options['center'] + ]) + ->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" + ]); + } + + /** + * {@inheritdoc} + */ + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults(array( + 'data_class' => 'Chill\ChillJobBundle\Entity\CSPerson' + )); + + $resolver + ->setDefined('center') + ->setAllowedTypes('center', [\Chill\MainBundle\Entity\Center::class]) + ; + } + + /** + * {@inheritdoc} + */ + public function getBlockPrefix() + { + return 'csconnectes_spbundle_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..2b2a8fa23 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Form/CSPersonPersonalSituationType.php @@ -0,0 +1,263 @@ +add('personMaritalStatus', Select2MaritalStatusType::class, array( + 'required' => false, + 'label' => 'État civil' + )) + ->add('situationLogement', ChoiceType::class, [ + 'choices' => \array_combine( + CSPerson::SITUATIONS_LOGEMENTS, + CSPerson::SITUATIONS_LOGEMENTS), + 'choice_label' => function($k) { return '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' => function($k) { return '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' => function($k) { return 'permis_conduire.'.$k; } + ]) + ->add('situationProfessionnelle', ChoiceType::class, [ + 'choices' => \array_combine(CSPerson::SITUATION_PROFESSIONNELLE, CSPerson::SITUATION_PROFESSIONNELLE), + 'required' => false, + 'multiple' => false, + 'expanded' => true, + 'choice_label' => function($k) { return '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' => function($k) { return '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' => function($k) { return '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' => function($k) { return 'handicap_recommandation.'.$k; } + ]) + ->add('handicapAccompagnement', PickThirdPartyType::class, [ + 'center' => $options['center'], + 'types' => [ 'prescripteur' ], + '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' => function($k) { + return '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 + ]) + ; + + }/** + * {@inheritdoc} + */ + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults(array( + 'data_class' => 'Chill\ChillJobBundle\Entity\CSPerson' + )); + + $resolver->setRequired('center') + ->setAllowedTypes('center', [ \Chill\MainBundle\Entity\Center::class ]) + ; + } + + /** + * {@inheritdoc} + */ + public function getBlockPrefix() + { + return 'csconnectes_spbundle_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..9950d2b87 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Form/CV/ExperienceType.php @@ -0,0 +1,72 @@ +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' => function($k) { return 'xp_contrat_type.'.$k; } + ]) + ->add('notes', TextareaType::class, [ + 'label' => 'Notes', + 'required' => false + ]) + ; + }/** + * {@inheritdoc} + */ + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults(array( + 'data_class' => 'Chill\ChillJobBundle\Entity\CV\Experience' + )); + } + + /** + * {@inheritdoc} + */ + public function getBlockPrefix() + { + return 'csconnectes_spbundle_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..ec1792713 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Form/CV/FormationType.php @@ -0,0 +1,77 @@ +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' => function($k) { return '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' => function($k) { return 'diploma_reconnu.'.$k; } + ]) + + ; + }/** + * {@inheritdoc} + */ + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults(array( + 'data_class' => 'Chill\ChillJobBundle\Entity\CV\Formation' + )); + } + + /** + * {@inheritdoc} + */ + public function getBlockPrefix() + { + return 'csconnectes_spbundle_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..a4265de2c --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Form/CVType.php @@ -0,0 +1,94 @@ +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' => function($k) { return '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' => function($k) { return '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 + ]) + ; + }/** + * {@inheritdoc} + */ + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults(array( + 'data_class' => 'Chill\ChillJobBundle\Entity\CV' + )); + } + + /** + * {@inheritdoc} + */ + public function getBlockPrefix() + { + return 'csconnectes_spbundle_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..aab8fae7a --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Form/ChoiceLoader/RomeAppellationChoiceLoader.php @@ -0,0 +1,144 @@ +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 = []; + + foreach($values as $v) { + if (empty($v)) { + continue; + } + + // start with "original-" ? then we load from api + if (\substr($v, 0, \strlen('original-')) === 'original-') { + $code = \substr($v, \strlen('original-')); + $appellation = $this->appellationRepository->findOneByCode($code); + } else { + $id = $v; + $appellation = $this->appellationRepository->find($id); + } + + if (NULL === $appellation) { + $def = $this->apiAppellation->getAppellation($code); + $metier = $this->em->getRepository(Metier::class) + ->findOneByCode($def->metier->code) + ; + + if ($metier === NULL) { + $metier = (new Metier()) + ->setCode($def->metier->code) + ->setLibelle($def->metier->libelle) + ; + } + + $appellation = new Appellation(); + + $appellation + ->setCode($def->code) + ->setLibelle($def->libelle) + ->setMetier($metier) + ; + + if ($this->validator->validate($appellation) && $this->validator->validate($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) + { + 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..8f9afdbb8 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Form/FreinType.php @@ -0,0 +1,68 @@ +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' => function($k) { return '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' => function($k) { return '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 + ]) + ; + }/** + * {@inheritdoc} + */ + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults(array( + 'data_class' => 'Chill\ChillJobBundle\Entity\Frein' + )); + } + + /** + * {@inheritdoc} + */ + public function getBlockPrefix() + { + return 'csconnectes_spbundle_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..e237ba33c --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Form/ImmersionType.php @@ -0,0 +1,209 @@ +add('entreprise', PickThirdPartyType::class, [ + 'center' => $options['center'], + 'types' => [ 'entreprise' ], + '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', TextType::class, [ + 'label' => "Téléphone du tuteur", + 'required' => true + ]) + ->add('structureAccName', TextType::class, [ + 'label' => "Nom de la structure", + "required" => false + ]) + ->add('structureAccPhonenumber', TextType::class, [ + 'label' => "Téléphone de la structure", + 'required' => false + ]) + ->add('structureAccEmail', EmailType::class, [ + 'label' => 'Email de la structure', + 'required' => false + ]) + ->add('structureAccAddress', AddressType::class, [ + 'label' => 'Addresse de la structure d\'accompagnement', + 'required' => false, + 'has_valid_from' => false, + 'null_if_empty' => true + ]) + ->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' => function($k) { return 'immersion_objectif.'.$k; } + ]) + ->add('objectifsAutre', TextareaType::class, [ + 'label' => 'Précision sur les objectifs', + 'required' => false + ]) + ->add('noteImmersion', TextareaType::class, [ + 'label' => "Note", + 'required' => false + ]) + ; + } elseif ($options['step'] === 'bilan') { + $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' => function($k) { return '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 list($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 ($choices === Immersion::YES_NO_NSP) { + return 'immersion_nsp.'.$el; + } + + return 'immersion_'.$name.'.'.$el; + } + ]) + ->add($name.'Note', TextareaType::class, [ + 'label' => "Notes", + 'required' => false + ]); + + } + } + } + + /** + * {@inheritdoc} + */ + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults(array( + 'data_class' => 'Chill\ChillJobBundle\Entity\Immersion', + 'step' => 'immersion' + )); + + $resolver + ->setAllowedValues('step', ['immersion', 'bilan']) + ->setRequired('center') + ->setAllowedTypes('center', \Chill\MainBundle\Entity\Center::class) + ; + } + + /** + * {@inheritdoc} + */ + public function getBlockPrefix() + { + return 'csconnectes_spbundle_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..a03573d7c --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Form/ProjetProfessionnelType.php @@ -0,0 +1,109 @@ +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' => function($k) { return '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' => function($k) { return '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 + ]) + ; + + + }/** + * {@inheritdoc} + */ + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults(array( + 'data_class' => 'Chill\ChillJobBundle\Entity\ProjetProfessionnel' + )); + } + + /** + * {@inheritdoc} + */ + public function getBlockPrefix() + { + return 'csconnectes_spbundle_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..a7f761df6 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Form/Type/PickRomeAppellationType.php @@ -0,0 +1,125 @@ +translator = $translator; + $this->urlGenerator = $urlGenerator; + $this->em = $em; + $this->apiPartenaire = $apiPartenaire; + $this->validator = $validator; + } + + public function buildForm(FormBuilderInterface $builder, array $options) + { + $builder + //->addModelTransformer($this->romeAppellationTransformer) + ; + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver + ->setDefault('class', Appellation::class) + ->setDefault('choice_label', function(Appellation $a) { + return $a->getLibelle(); + }) + ->setDefault('placeholder', 'Choisir une appellation') + //->setDefault('attr', ['class' => 'select2 ']) + ->setDefault('choice_loader', function(Options $o) { + return 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_pole_emploi_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..3f40d11ba --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Menu/MenuBuilder.php @@ -0,0 +1,68 @@ +authorizationChecker = $authorizationChecker; + } + + public function buildMenu($menuId, MenuItem $menu, array $parameters) + { + /** @var \Chill\PersonBundle\Entity\Person $person */ + $person = $parameters['person']; + + if ($this->authorizationChecker->isGranted(CSConnectesVoter::REPORT_NEW, $person)) { + $menu->addChild('Situation personnelle', [ + 'route' => 'chill_crud_csperson_personal_situation_view', + 'routeParameters' => [ + 'id' => $person->getId() + ] + ]) + ->setExtras([ + 'order'=> 50 + ]); + $menu->addChild('Dispositifs', [ + 'route' => 'chill_crud_csperson_dispositifs_view', + 'routeParameters' => [ + 'id' => $person->getId() + ] + ]) + ->setExtras([ + 'order'=> 51 + ]); + } + + $menu->addChild('Parcours d\'accompagnement', [ + 'route' => 'chill_csconnectes_csreport_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..1b7fdee2e --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Repository/CSPersonRepository.php @@ -0,0 +1,13 @@ +abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', '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($this->connection->getDatabasePlatform()->getName() !== 'postgresql', '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/Resources/migrations/Version20191129112321.php b/src/Bundle/ChillJobBundle/src/Resources/migrations/Version20191129112321.php new file mode 100644 index 000000000..a27acc50f --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/migrations/Version20191129112321.php @@ -0,0 +1,50 @@ +abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', '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($this->connection->getDatabasePlatform()->getName() !== 'postgresql', '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/Resources/migrations/Version20200113104411.php b/src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200113104411.php new file mode 100644 index 000000000..3784c8657 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200113104411.php @@ -0,0 +1,35 @@ +abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', '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'); + } + + public function down(Schema $schema) : void + { + $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', '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'); + } +} diff --git a/src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200113142525.php b/src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200113142525.php new file mode 100644 index 000000000..422547759 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200113142525.php @@ -0,0 +1,33 @@ +abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', '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($this->connection->getDatabasePlatform()->getName() !== 'postgresql', '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/Resources/migrations/Version20200114081435.php b/src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200114081435.php new file mode 100644 index 000000000..3761e700e --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200114081435.php @@ -0,0 +1,34 @@ +abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', '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($this->connection->getDatabasePlatform()->getName() !== 'postgresql', '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/Resources/migrations/Version20200124130244.php b/src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200124130244.php new file mode 100644 index 000000000..9c5bc73ad --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200124130244.php @@ -0,0 +1,27 @@ +abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', '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($this->connection->getDatabasePlatform()->getName() !== 'postgresql', '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/Resources/migrations/Version20200124132321.php b/src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200124132321.php new file mode 100644 index 000000000..143e62cec --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200124132321.php @@ -0,0 +1,26 @@ +abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', '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($this->connection->getDatabasePlatform()->getName() !== 'postgresql', '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/Resources/migrations/Version20200127132932.php b/src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200127132932.php new file mode 100644 index 000000000..e81ab2d3b --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200127132932.php @@ -0,0 +1,27 @@ +abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', '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($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.'); + + $this->addSql('ALTER TABLE chill_csconnectes.immersion DROP objectifsAutre'); + + } +} diff --git a/src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200205132532.php b/src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200205132532.php new file mode 100644 index 000000000..9111382ba --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200205132532.php @@ -0,0 +1,76 @@ +abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', '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 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($this->connection->getDatabasePlatform()->getName() !== 'postgresql', '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/Resources/migrations/Version20200207224152.php b/src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200207224152.php new file mode 100644 index 000000000..4cac2715e --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200207224152.php @@ -0,0 +1,28 @@ +abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', '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($this->connection->getDatabasePlatform()->getName() !== 'postgresql', '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/Resources/migrations/Version20200210105342.php b/src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200210105342.php new file mode 100644 index 000000000..e49d01087 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200210105342.php @@ -0,0 +1,27 @@ +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/Resources/migrations/Version20200313124323.php b/src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200313124323.php new file mode 100644 index 000000000..a82b10520 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200313124323.php @@ -0,0 +1,78 @@ +abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', '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($this->connection->getDatabasePlatform()->getName() !== 'postgresql', '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/Resources/migrations/Version20200403114520.php b/src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200403114520.php new file mode 100644 index 000000000..7e5971f8e --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200403114520.php @@ -0,0 +1,25 @@ +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/Resources/migrations/Version20200403123148.php b/src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200403123148.php new file mode 100644 index 000000000..63106ee14 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/migrations/Version20200403123148.php @@ -0,0 +1,22 @@ +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/ChillJobBundle/src/Resources/public/images/footer_bandeau.jpg b/src/Bundle/ChillJobBundle/src/Resources/public/images/footer_bandeau.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3e0347d3be8a18d629cb94ad3934998f8898d308 GIT binary patch literal 39797 zcmbrk1yo$kvM4-wfIx5vZoyrH2Z!M9&fxA&5&{I5po6;&?jGDNxCeK4f0NJdIrsf< zt#j7jdsgr2vff?2tGa7?zs$Y-0-$}Akd^>IK|uk2KrX<`8X!sB!_o`@kdp(@0RVtk z0C*@201O0zf?NP7d;r`ZFaV$qMeq--4@L7A4>SM(jrl+P!Il8nzxW|K|0q8oHAK_z z-XM3FXaE2K0>QGdv9e_T4YRVaWI|}aIbL2MHKe?(!L(brxH#}KGut^c8JXG}1DQ|SeOC)LLLrACe}a~Qe&XGrJVrvNpm|jsimm^wFajgi=2Zf(85y6%L%CB zC9i7YWo^P^N-ZRa#P7lDVe4QEbTK0Ju(h#s=JgPu{zEx01pbX?riL&%nVRt`i%I;& z0%-|Q|Me{H?(R(P>`eAf=FF@-JUq-SY|LzIj1Ue+XHPp9BM(M9X9|c0B+@^0hyk5V zoGcw&EbZ<7(glPV`yXZhHn886KSl--Cne?o-Q<G8jCuqxElX4U`so5K~@G**1u%_FWSFLDcU<*{vN?^DN%?W zfKEWuf0g`K`ahE5kcm?VIywI~*lN9pu|Md)ilm2G?M~A4rjlGi!#5;h3;!aLLS0_@--w$sGB&BgPviY-Z zVsB^X3MA#?hX=$JT!xR_Y@*y!kZWO(>Q zL?k36n7HJW2!w`XSv5z`MDUUL8dkX3MvKR}u=gDffAko)g~v1jjS;SQh+ALS~-Y5ouy zjW%rAVcg^)1we`|g#^<-3&pU`p8(vhz7zleN2c{R1pp9qy|;TUe+i(c4aJUrdu%KC z<*w})0ATErFC>*B9bs|xhOL&h`eL8;UPba~r>Mq*?{3S~>&U(FB4ff+|I?p};BUGn zy;^l|#xr5E?`HP}%>s0Wrq>DEvjBpT$B*T44o~upQP}`!)tzNug`mGXM-bQ@(wgL% zu$V;OX2VW$#@U3JjH$X7=*#SLg!c*c~JpZyHVn>t@~xnp(}WpvCA5N z%-yE?=|?r?KXkoTyLVa1(8zT1NL+_J(cSD`11sOS@>_p`d}=e7q{N;w>V@q>_N4`1 zxC`Gdlv0keVa`a4;S1}@Bk)|(%(sLvXKcogL?z!x=XH-cn4WF>!hD(Q(>XV+Hy6hO zcnqvod7j?Hvn5npVA1I${m~_N8*$3?{!UvU#w)jWT)pyyPFS6t6_RQG+&4MR?etsx zLMmk@yPp8@Hq8YEr|WRs$u`Csx_Z1v-CG>n6bk~wGO3O(`vV3bIQK*zbtQUm(Ey!T zPXth2nK1)m78EbnHu-S5l0mQ2!zEwBz5+t=12^jKzSunEO0ImS?oDd}l|(=0`H^Om za{e1XKR@l`bpK3_a?!E5JFg~$#6zo_t6#TzJfr1&*q5u+2zF92lkCKi0b5?5UMmGs zU<;rP{E9Yp+20{be%`(80c8*Y(3hF`cb-1 z07funf;Uogv6r~TvD_p$+w+P2qK2<0OdPpl_GV0Pulu(x|1qTifjd$8blv%)(?&y9 zXG6P0hsFfV?(xasX|kL1vw^?u>Oikb31Pao%jGknV-)vcxtxHkG5f*1 z+l5i@Pjd!6-XhHScE$tcDIMeto8-aG8L`QQX0B&btAo6Y2Z1-`JJ)HCZQc_J_?HL# zX=vLVg5gahf-RE;M3X4*x>rNSo7fhdTJ}dmjLP+@2|8*_5A6Q1bXm&5?fi;gcs_wa zX^p+i*!&%Dojv!iXK%Y&tB^6{#_+YMUJa%V?zE6E@ce zOm1M6=2P=qw~I#(jFm&(v<$@6fQCVf@6sxomAiXN#Jn}8q%K%BLFr}y0Ln>l{*hPX zNsdhP*u|(d;sQ@;y_0?q*EHL8qY(FkcFI@5$dkvi!=LXsn>lBlF70SbP4;Y3?pnIS z_8uVb_D0Oz3qYspXnTL|J_&qZ=leL^mipZ`C}ik(A?$F`GilIes7~{B^SzM4=gHx{3|CtEFn;fDpBC77aMe}B(a=gRsrOHVmnYpA8)-hf-h!^0a z-iaseEiIn;joK~}d7d=>GQRGzUO%2`x;lyVou!OyEyuA{=nW&)|K_#aprE! zpiPT&DEOuU@H6aPPDiXf5dm2M<#+eXM((W37r+Nk5_IF)jg_dWp)wWP#EZ8bcv?b*IHI^?>1qD?`|4)r~^i#8%&Zb!?u$ZLllqzQt=yLMMvp+?xNQ zImKaXLC*Heq7Ww0L-!>-fz2=dMtf?hxnBFpc7aPCcR!}6)aT%#-4%D)!9~5@p(S~t zk2a}`BCW2GV0S;_Z;9bU3j3QO- zT35Ki__xf^6N&ZwyhlT~ei^o_gLTQ*T?iR=)9s0<%{Jbio!H!oHYOTkV@cj0PU~y! z7vE3M98RH2fn=9KT44|34fT!SF!M1lwl4iN>+d;X*B7pKa_6q~+`E0*&Ih^n={;#@ zb>O*Ffs#D?43({wK?WJq(MN;o6t_M-%!Sk3oq`6B8j(qX`mp-!JHN8{3m(b+!$r#i zvWJtT((?;UcjENvb+2D2STo@rzfO(5SCY?@jvlS{J&_dMzv;jAz*$Up^KLp`oeFm=nD{KoN?d%XePVo=I9Y`C17n54G zA}m^wC)h9Aeb2mmljp}OE)HTxe>sndCVH&z-i_`0v}U9zW$et1WWPJuf6H)^>vnOx zq=(L^>sEUnj&rx|IBC1N2s4ou5_XkZrm@o&%(by|<>Jp>jw8h!$7-7GXmP3~K#Y>P z=|iGbwy`@78!cM`T=o?T!XxxWOz0$X!`+T!kVublvsRUepfht_?*cCFQ!thjYAz7D zCEM7{T-bjt0YXeXdzs&pcBSV$yknDQTY4akHn!t2i9b^_y5mueS2Ck#4jjELnI+S) zYT9XDD@$2DZz%ON)i7YkF&B6N1TU}LJ~jAEPd{qQoz%Tq?tMD2=i6eRv>B7r@t5rM z$!Dy&4((Ppd$Pn>co6e!vlkQ|e((z*lXYEguGTttDPztU-Rk{2utPBiYj^c*Oq-F| zsYQ=DTVCRh+@Q!5F!?TzF;$zH3|E3w1cDj_s$(#@5^i2;fcJGO@ALu`4t7F3=I&~z znof)M_}XzLNBu>&y#81R0RV#4H}cb)H@Y;Q%s63N$mX$@SXH(=RKM;=oJqt0un?08 z2nAz>kXK;^0)?TpkVL9-;eb*Aj3S6-eyn^qc2qBON~~mcqMGUp7%uOc*gRJZu!v%T zKMQI~)adJIdn@|@k82?0vw2Unk+Ooe&B@3X%sDVv(Qb95`=l+YP;SeSoTBSkzk2~Y za+@2vom^2zFJD^!h8^VggwPO?Lc*7QcKZQ#lSgG z`WnVnjE;_YqkdqcSKw`W`_?rS($x&Fl;A1e+cv%HldMcnKbaSXwc&p({_l*C z%`h_>01C1tZ7P1+J1HfZpqoHGBaBz~cvf+@iuzw)ua-e(%*&x4yFhRjV zzX1BT>Pkc9%}RKR!P~{vpyE-h{{;s9Y_jwZjAcE3)}Z5T=`nN0P99b_XVpsm??5Dn zK>i#!Y)`ADtrF*i(oyYt9;+qs<0NUc$QAWw9__;|>+1Nj?x%^1&OSSdk^cEc0&WVk zO`D~NZ&Lg1yRjA~dgF~vxZEP!ySmHBDOt`gOm=}I{|^*J0*_Ew`-5GZ$*#h(UmD*< zMu+2>df`kje-Xig&-n&wyc5N?8tU{b>b%d6unaQ37LiQrS^KJatj3j5(C=OurH=@% zZcZ3bls?T)h$AKOSeS)xGP4GAPtrLCj7U z`qgw7nOVUtM!3%kJF-LG@r9LlZ#8vSEB1r$OqPGbfeVj|%KU8ySsrqr$k*2&%0ajx z^c99WFv$jct`<=~#-V4+lj^MJL;M>d$Tp!h9G`~s(#xhq7shUvk`E`3(7Hd)X;u6O~c=id1j3b{{gBlR_oSer0t;dFMS zXlJLFt_G(3I_v#5E2j9f(a}a&@;+s6H84g7tB9epyI&sFT#iAp?yX63wcKmkc4RWp z+wYvrtz|cNR$RN{{X*Frn`aa;j!N3CK2C1kk>Vetz8h4xGcw;U`_!c-a3zxqnrQ7? z-hav;R1bXwdK*W9%*)OeldTRwbmBqlu4hdeXHi@@cm1S+QS_IciEg?u@7 zo8I*0RJOA9PLhP&?H8prqyuG{(V(sTcqhbAc(27-^6ai8Vp zUV)!8W$MqPauSxfdzW&CS#}PG&bW1%%2=;{+1QoVAPm!M6WXIz5PhxH;_!Z$yyklu z(mWP&nJ;6Up=~_m<@NCaldsm-Lf@Nob(VcCy2(b?0W!ur`4+2T%3~uVw<-M)9Ee8b zz>H*g9gQYIb?HI&{mw&66$Ac%_CJ~3c zo3O4=fmAjtro-|)SG)wDEd;qC5l+xrMn^jl1`+tan27eQsd=#j4>e3)j1PW9=ES=7 zq226@2nOSA8+7pXb*aXp#*7HN`Fr8jIj6OT@&(>N%y5sGmLb~pxe1Nx9)_6C-U<=m zpECyf^>ZPRemk9t!3+jQUv^TpO^$5$YN>Lpd~kJ6n98d^)_*{0e)sadlmSu3M9IVH z>FUhKTXXCjmse9KO=xH+FqL1ZeW zQf_Zn;qBU#I6?eGf|y9;$Va5y@^cx;9QJ}KbCs)9v!1(P%cBFxaFB^)&d46xg8k=| z(<%vskHuo&XQ&!J29;em>8uY#P&JdILRF^%^IrWq)k||9#Eo*$BLqfw$ht^6fbGI@P%CxXFXZLgduw6KIEiHJ`Zk zSUa*b^L9j%FNXv{Op23WX`^suTZ?&qH6iiQPDy>4fJ%9;t&N-Pjeo>lb~|BZiM>~k z>W|4rwALcFI*$a2=PV>`a^v}o_-Xfn(KNHwwfm+d_MJ7psH->52PO{L|CtWt|^61 zgoYS?e0@$4*?4Yya2Af+sgjAOX^hV9j2pA^c1G%hDOxWq_!KI|fxXXQPoX9c1@jJ3 z0`w^>8=Oz+v6)PpAAMOGY8g_N9B#{9o|8%^)Wqa}(HCxbB4O+6)P{N-i$}0za{`-` zp0M)`*f)gf#MKi4qGl)$CXa;A&LN%(cO4_tynfvs+_U&c&^)+);H^j-PtslVo?Ds6 z(_?6}%B)k|#{f<23bL!Z6p+0_nrVDJxG)p6^}u)j^92x*I`-wDCUUgfYi`~Lh{@+H z?#JW2zw-J-H$Z$h=KF2IicHGzC);@@wX++fUL}*8PDt!YJ5PHTuTxf59y?EyrWyB1Q;ciPApB6t<<1Aw_rhsD ze0QjX*Nrz+=;^MkCXsRd{#Jzluo?RbHBa=E0Wcm8Vp zblJXPPk=MlLrjwfT8janNrI$HtsS!FM5)UXxB_`-V>PBcRgq}U@%A)eY(@J!Q8{g- z1b-;GU!#48iwAGy6@3@54GFB$(n6gQ>~&)7uQudjPo@{)G9=KI3qPJ}f1}8TwHd}cKS}L{kd=t+!?N}X@DQ*Y(WJ; zEJ!!6R;a(@(CFW1mqJne=`K8vO`mMdn^YHN@m=dXs)7+8Vr6Rn{2Qwq^kJqsc5^DJ zqn6UGSC{o?QyI)x2*>wsvWIEj)bayq-**qw_^90E)4oG$2-20g73C;A6ZnN&sH(+s zEt2;xGm`hp#1Kb#LDi{;aD4dN8xX1>2D#x#oS!&V;F~2@ly|;juD`vad_a^S&)esK z@`xsJJMO`Sr>!EN7?C)eeSqJgm%S&H6Yg7|X;nY=axw-XI;^yzEx!|2DCn)WZQ;eB zE(+Rraq^GnNAEmq>!q%>pwJlcEOh!IzL8HBK&)q^I8d-p80+iilHjcQoKZJ6c|Cvc zwkedHfnYw(cd;#p%mPQZU(pG;-dH)|)bWk2rt~@F@3!1We>USWav^lfcr}tm)ChgorPI&=&wCcj7|_K*2ym z&OqQ0V4;4Wr9zG!AO{KP7?@el@|g8F%rpy;{;r32Upm$zSMz1>fnXXKP;YjH?!SzglbB zth#u_Tn#i@!kMQ2AEB)mj^d{~8#IvCbe)6JrAKmb^@qUE$@)Vj|5T8sm=+f;ArtiB z`D31&r=M~&e><&Sx*#5IJ&OjjMvEkE~+pE8`WY_Zd^Pk{2_ zbSeEX-KjyNGxG5T;C7PrD08!ATsqjd9HDMNGp)o^ra^~CMAj)6T2wGJ_uRjZkKKhD zxzoA#^{3trh=-z7^R-~vp1|RLDMiB z0k^5Qxo~>r~C`*8=ZQt_q81z97_g`)Tw3Ir(Nwr%gwu< zbs%%(pv<3gUtBrB7o5ry&Fn`Yn-bbZ|0*LWH=bvaX37@;tw;idDem4=lWF_>Pz|RI zx*}!%H!*`?;{usVVh;txl$)E*>dq-iu*qf7kBT>pr+mMuyRTQ_j6U{&ekT>cxU>o9+IDa12z#Z{av)zgA% z&03_HllEcH$t~;TC4&88w(@JAjSEzbcQZ&L+9PU&4QZbOl}~$(YbSxxX_z6v0F|)C zBAQseuVi6FA!0(s!|#O^dY1w71&#(XlPA)d^dvhQrOiE_U zEt2IE)3s0;Y_rx5ty~y;RqY9<3eMajZMf2tqLzWj!x}l9V~70y1$9J}hgi?SfNvu( zEZjhGO*-=Kquzaab|#7dphow*uk3FM_2&wou&L1#6wgnDT}8Xi(hd7)+xAxFT}WQ{ z5Fx)+G}DzlUc5pwmqM5ii`NnmHF|f5b6?CvwvZ|gF7Ze-_tPgRB-Z*kiyE4cHCeN6 z8&5=O6MsVFBENo!X;_!0fl**t)0P>i!Iv3DAU<`So|G6Rj;tjv7j~!WBc|F=5k_O# z%^8f^&BT850;u|x?oLahNc78sV!r_#%lm;6XY*-%HJV%D6}4S}O(mdS-u63}`tPeB} zOba`zqQIpTq8b`@ln$keI;CT$i~#n@=8kpiRDECcDb2zI0!jKTL7l=)(*R7AsVRrC zlFqWV(vaksn~ZJ#WrZNJcMq)@htABSLM)rxwS)5!xGJclHeF3oY&~s(Y%D!gYjRr( z6ZfQ(+q7AE^-eEpF~H)ndc74|$0CntjkLr^dw%uprFWKoyK(4f&B$o<>XCLeJRTk{PtweDIqFdize zkSvzY%$f%45_E%cr9MIo?u(0e8#OO>K}72RAv>|AE0o>j1rXR}#g@AJZoI&uFpbIl zR#&359eVc z%(###JdbHRRi$T4vpj;Q;s~Frn=^%$M2zIf%h?xW`aQ%9h^dK?I+d9I25IbQrvf3 zRE=Du_WokGy@5rCCN6D-9|TkaBjRb^^)7+2gZZ3HBg2>Thib@B#?G5{UjRJMo^0tFVYMZdY-SP$4Z8B_8dDfE#kZ6mkt3I~oD=oP_CQ&y^a0rV zc}X}~b4+cOG(B7UVJ>S+Z+f)0>3gfxJDo<_`8n6t?*#A4re*|{OSu!(EZ=5xyXBdE zSxPM7*gGc zLls6HHxic$vcpVqnORJ=a!-(#(!SECUvGk%S$%>W{l!Y6Fg2KsZaz&jY8kQ$4XTMX zER5&9C$8508YSzxwCdX>_^xP?SaEWIwHi9$YwyH0C?17D(dtLBN3P=@ah?o)o*TFQ zl7G@gkbBpbY{*HY#rEzhQP>xd`>@@y<6SUsM6~0)t`~#u75;gr`<4^vfWe)ApU7;U zwL!;jgC8Sin$KjQ94fFV3hFBvy~AghcX$Kx&M+*sJcrKWlR#^U1AiWmZ)mRVH z=_VfOV_Toy00`KHhRZ>zdjTv&RB_(;trR8%ac#jQ4Xg9r(=4ueR9@ca$M#`xOip{q z+By4+$(zpbEo+}0$`_cfnUl}MZl;xef@d}KRhrnhSfQj^DOPXnnDff-eMGgbo%qlR z^BLiZ&d8*aL|h|Frj9{>(3?nIxNbfx7*88p&PUO*QH}HGSljZ> zU6d0~8Xj3&F)n8mT*t@l#?2aw-1wiK&5-Q|5BDphnIV82j!+Zy<}PUbBMcg1N4>){8vE55k3tX+(W$%Wr8Sw9xiE1mdD{m=uMlKt{xf&OXtZlV30@P3D{ z?8u)Or)ae}c9e#`*t`H1leuuU&aNb~vIMhAr+KZtsAO-5bOyjSm!*adu&%0=T;-P6nyh8QE(Y7}Gk43H02qC^ibj6vhovXgEXP9)cy- z)m0KynivXPwB&cI(k6g>*@N!lamQh_%Qz}cR1&|AooX5^s`RUJwUn{r$@{$qWAOCV zWoA^v-W|~Hial?Dh?+PKMdj`0O@*@i{l%l7!^oa+MDH1bFSXw6R*_8nM`#)fXZf~g zR0@vQKb8|~_i_LIhuKgn8W^>%y9lmLsG89p(z0d*{yPX-q)W%lquTT%aq;^`UNMH$^$q7^U7LUec5ATL zyfJU~kxf8|=5Zx~o^cg(l_m93yg8$iC7I5IA(xybYWp?mC$%q~*k3Ayvy702UTKO{ ze9(Ddgk&PTzcUdicsOV{7$}5)G7)rG3{0%wsR)~}5~(sd3%ilyhtH=X6b>M3#7UR=dMi0r7To^_f}W7w;Gf?(voidi&UVMXHjH7 zNE(&aG$eDRW$9bO$XpA|y9U>^O(!HSRQ-HV*EX>FFGy3j>7$v+n5#c=^dWLXM_Qh~ zCCm_&Th|v%Fs|QL>CxNNDSW^ZcUvCxU4t#FbQeA)Bj@GZzroWdIYf<*O=>^O;$2Ge z^yv2fuLdpT6t?<_>REs?C^Wu3fA&)E-01$Zc%!_nl{%)lmC`rcWxSvt`x$T(qcp>j zP3S{iS=cm^uuu5dwmA6%!FW#-p^GHlL~5qB$fAC0l2bx*_PfZzml<+(UjAl0gLDF9 z3bO}x8&|BhgSQ_722bxy$JI=nlC?f{T4k!p&n7-F`YodsOOYIwYL(i{W-)frQ4$-!ud3MhzYFyi2gZ z)0(5z94$K}+n&E=x6N_yUj#bEM~t zR2Qd^)AezC@SLr3$l9FM*QR6!I&}&cBlQy>Rgh*-c zpKMptuJ1O9e`Zi+AVu`uhj!b?e_N${@X5SR*92b-p|>fL9)`fUP+HDqe^`b_?T_Zx zj5rVYycnlLZ95Q|wdpRqw`CybsU}pAIyiKxU0TY`%@>A~NTnh7+ieC0=NS5dB{Ywlt*K|E+pXlvwfH}Rfxnx4@8Rc$$b5kt4j zW0=rS`;83Tv5916-sjbk@78jj173U0O~39A+0$0qcgi1q8yB9#8sRHrg5Rqb14yX5 zs$KxaU_7)GRb`wzYz|Ic=)ngyu+|we{Jp!f!vUUQ+rqe|!S)Nl6%QkkXYUKGAOI7u zx9VZC%t+rtc>Kr}_#--?Ldl4KcUc90u^~#qgmCC^%P0#KmV$$kx00A;=$2u;;C;i? zd99IIjq>U(a**TAL|0OO`U%**$TYbpB%@`vX1x|%a@1D zXIUIc)l|aNLn&vA6)`B_9sRF zqW0Im6=hfY1tkvrB9b{$x?+jcZ6!n&9Y^gmZBE)=aMKR0zNp2d((?eg2C8Wt`_?L@ zok_sbH9qTbpO*=-hsx)c4K&SdbgR)E=ymlw%)1ZeCUoMdGXZBwEn{p%DBN=VdqF;HLZNNIZh!4q#{mnKI)vb zFs>e-y%rnEgXfzEV#!##o;<`ZL#EF&?JI3Ye>Mo@IF2jiHMmt*D9pyq<_;8bUd%OA zq;8UE+kg+#?Lc}kE}a1trXS+7J7h4F*)>CUw?-u@x{E4y%|$vkn(gLrrnRvSdHd?k zI)?VkS`3k89Lpd3e~bg&fj$F_8-oY-`o|T?Whpr@qB5FTT-LdX)FORIXcde3DO5Gw zc9P=lypLi2A9RIs&&i7|DqS2iHI?R{nf5v^KretZA|&Sk@sE90#gIZ+;{;z!yf;UpIY%!f;!v_1X2++-Zto+fdE6|H{6;wq0%x*!6=YK`FoKV=cc=o zO)kkBp7@mAT2*?vR9Rs-=pQuYaKGI!fz)1kqfWOcZqjYPfdaX-G&`#aTl=^l2afSa zCqh)3Ifp;F6=;1q&Iuuqy{3tqcE(U5WQ37J@DGnnozyzqeESMpX!|pQ(r`2<9b#sU zk5aV%hP+#Q_OXa1J`GY}($|7sDqF3rXS>v&lOmv>8y~=@OZb_+5ntfI(W?`J2P;h0 zgT916-IUwNmyyEZSumTtlYU9^@#JRdz`diJHN^~#%mY?7@Zs2%sYiXmsiCdE(4q1-%ymbDa{RYYtY?xmnAJIqt8ClKDdRmwqZ|f#CRa1)qrRS zVO*8oBjtQ`rM-c|RdPn%k8v*X^dUpe^Px$&5eq7=cU4bUwcBkVlkb0zrOTIz0Bp)s zeYN~b<&XJGSrqL@stPlGM>M(YDYk5tyRUfektORpb+a;=I*5btV_ZF;>Xt@F4xO=V zb!<(kx2qHvbGfCV^w3x1b-n+5BCylLPv2ATCQ}Y~0S8klB;+VZ?*jY+P^1_DGtILN zBPiS0nhnZ)AfSdsuX~2yi&mtMXyE+qCyOMTQk(f7H6bkCy+DKp>wb4}b-&oox~vK_q^D9S5!R@K$7ZL_yVZCc*Y_Z6K)g^gMU zm{!lVD4GLB5nzG2ZH>9*{G{%myV{pM+x4rqu`Eut9@w1;nlN{9XgY{;H4N3XIWiqB z33fGEJJl>V4Aoz~*sXoSb*?^q0d#V=;e$o>1oy^TX!ZMJ$5C9A1x8>e-X~y+u5q-W z6esH(3-|8MDuZ@}+D&J1)8x2>Ph1st(m>;QOhUkSQTI7hR6ouSY9t8wz4-U5DuuEJ zrIRsPHk7X3OzPYtjAfM1EWZF$aQY8Z-;g6YyyHQ$D0C6CRulC^FV1Qzv?$6$Tby8v z$|bj``B2+ZD$w{@Mf}qX;MIrq6ezclN{uETMwpUlsI$*%1foPm!dVf#MN-|$4SGWH z1fNhOE_AZwExg5%!gZa()MHf7?;}*wPE)#R1T&TEE?nf|bFB(es{O>c`gQPN!I#A9 zUT^3H5aQDV2FHZA%rnoc$33-n`Tr!)O;`t>;RKA1P-x0+rG%In;b&QXW#~rc!N5s^ z#wnEO*Iw63k`Lp=7#2|}MYrBHjWm}QS*8)2noU6=#IYlx=f;gs2^$>g*)m%{uXgm* zYG?s3>8sl@|7V0!=PHR$lNZaFx>o9XVN5-V#zU3BxvE1=lqVSy7Y4;jksf5M|L4uS zoJw|_rg9E)C9j#`=SK_KOVE$GdOQbl>$<8O2~NrR$xyT^G-^4vsv}#wH^l?Kd zvn#P#K4eW$8audrIX!zPs`!0P<*$#^;DsO`r+u|0OzMxHnhQHF^L-QHyz66~A-bV^ zPlCTQemg4|+}n65$T^mE_7~C8I1CrF*$x2tSAJR(BWRenJyk2>)6}d$Sa0K@KIfS6 zS(!I(g!5dBb$ZW+?lm+1PNm0xNwml(L5pRzjI53e{mIJEC4F-!fk6?PEp2$P@6E?aF8^;~%he=^ia@2d4r zX-XQ>SW!H(TKMak92v<3ovmuUz@}Rrbf&ciSI}Y~-5MEx`T_!xjXGYMu8T4k0&PSe zQ#In(wD@NFi1qwi^Xq4jec%n4yTSj>8Dh|l8^`vt>HHH{D)~(g-pDzn z^rj+Fl&96LU^kHiV;N zoiwA`&Go~{gpT9x^p|n}(cAA4M$20HG33ItB7|5-4gu1#0TNhq<tXn? zlLYqp$UmE=R$o6az0LljpMqJLdQqHGyGkEN{V@?=bJi);2|BEpy5Wd8Ep{Rz%CqwE_{FGH zGB+altmazGh?b7kR(1E8iyNm5)Ua)2KSXSB0wX=-a^E-J1DuYqP&zSg+rc4^l>~2hl}~H z^}7cA#@U7-yF+{0lA}#sDaYE|dY1#4ZTBHt`>wAy&r6uUPH%HN!2s{K$%QS)vBpt3 zT39-wFMzGr4ABzTxNqWgl`;&!quH>dOp$f9rb{$dRNP&w!=QXtv#uMXy{^gaRR|4L z9fgg7tpHqUoIYZOp^A-B2HKxvCCQqxCc%y-V*#En&%<5NV|*&VU7mqCCM4RNzuAHU z8i<=DQwDjm-I2*6S>AdV3sD*7LJJdHnmKyExiIKDt72%JtXGPtU6ax9Rf3QsZnfI9-E9`tB0#;1^)qiUl7zU-dSCUc^OX>U z`EaMkgwDg6@gkiE)R9<4OO(YVEPHhg1V@=wi;%p#@#pN zdm=K+7g@azBWV~b*lp51LWU6U1@L~)6-IdamWm}`*wJ`-YR&V`K0UHO%aQEPTaCd zcHZq9^=_$&()!|+XwlI43>_GvCOWQ#BX$BO3uCVN_ls3ms)fT?9NjqkGjZY}T3&W- zBSwa16dc02N2PUBh)COrwsg8=+>#OBh$QNirK@!7M?O|aCn2&ed5hF})-cB-e88$k zbS^z~sVx>L8a^9|OK+uZBP$fRhxZXHd?GVxm74R^7dN|3SVBB~-p;(~!Pk<69O*64 ztV@@V=G=&X3}uo5(6ATA>c?7B#(r8>^QJ7ckS4m8dn)4C6KZ`e`pKy@PW9Kv#D167 z*Rn%N=^q5JL6WNa3$kKBt?~23Pd8I90OnQ`{v)DRYFtLP9z;?!juBXv%m zSqs-;`$;QL>Hw3FE%UY(>pjUQ`b>O4d#ef8hp)qp_7??16Xk%!McB+kaJao!;yMUv zKIq&^EZW7zMU`3vHmrQDHDrkHyEKNpGdGr_l`I$aAYM2@?m3PsVW#zfqtRTApG}YS z9#}O+eA{hkQq$kZ@9I;!nZ-u`uLgn=+;9Fg>#SNv{f8T|`4x_Le1jgTQfzRn72}NJ z!6G69KFc+4J;2=PiYC#;>qw5DuS?ANfdqv!n(x-Hh{RuW(J+~9Ry=Bsg)h;DEo8lR z_g@`5O*NZl1kJ2WIEwT)!Y*SvzRLUH-&{1Vir>Z~O1 zEKD44^J9&f?(%A*)QaEYRrSZNP!XYkvUSb)5Gh|d0|OQXYDkEZg!$bxMhx+kIWWvp zp;c|29c<3f8NwDt(Syyt!)}iTXD3)h=IY_sVeZj9U(M_|l)vw`CR^eyW~N+gHC<}k z_u%wQGVkCvJrd4dwlNt4!Kco1!UK#qs8`BE%tVooK`L;<*vbW{R(!^u| zQg%=I`7Oh4E7ea^DH@D1PUVKb1~X&5;DCmzkpUfWKzp|! z{X*zpaKmQ^`bD75_iQ-HKN;`bVq2<-9u(KW=GaPQ^}R(^2;JWg^DH61+p-c#oAanh z5Juh7P%E&J!RlQU6qZfze1ILq6^QSO$f-JZC?00U(1|CoR#ua(7~HVTquxd87hm`k zIj{xq6*1m?32?$GJf*>_~Ge;@g9 z9%_AQ{Zt5IS{!IB%DHyoGeZsFL6~k>bb3EPd&qw~D7$c8@nrfebk(Cp&h3ape^5a9gg|Xn)l0VC)=3--b z3Q}sSvCD69``3Xa2rWjY#))bwGphty%sybe~0PnJvThwnq*7G;@tH=4?QWnc)B7G{geUjXM1p`o-{T11}* zKd#JV2cV#I2FEHvL4XHWO`95 zRz7r=7jsc__=0>pHO9FuJT{e&XGI!JVdO^V*2Staq4f@gpr38&EqP^SYcK9ckjs%{Ms0yv-o$;9F`%%IW z>gO6Op}(QE9?9AMF?0$ZJJ<16T{mReY9m*4OA?q^&kXG&)L1BR*5TN8S>>&h(*8OB zv9#Q^ke6@}@>eP!m54iWC~2L!ol-fMN}uo3m+vjlR|sRDIX9@W3wi6L;nS|_5*BsyoRph4F;*4v#5PW_CjL;n!_s`qspF9jb9neM#y6zwB zf;GIJZaJ52>G=D8X03A@JjhA;i4^dtwbDmeIJq2_Dc)PZ3UC0nYjMw>7AE#jnlQ9g zzPT>kmc>eldRwb$U#Q(Bbb42@hvuEkCr*X_7!%@5bUUP3l+z{iHU$>YZlLB_hTC7= z#SqBeFCR1wiL8_6-3(*NT6D%qJp4Q8>{tdve&40BK|X?{j&rDx?PO@mmdt8Lx+nCt z3*?_{*)V+n23-&`M_#Z9R31Y2J>Gq5j?8PBc-&JH$X>Pb>v;{w7@^BOz}gWwHxQQ#cA92z%=PaP}79aWmbTV4Inl9Wz7B3^7y8%#N9vnVH#+ znVFfHxy^QLC&ri=vz_n1_urY_dv|B%(Rri-b+x3DR7a=Y^PZx(uTRwrp2O7dNkBU` zuEWG8{EprJCZ=!doQTLTT}`a#Ts7rk@_C0-Wl-NGjh3~e!5pSi&a9%&dMBLhJl*$h zRe`!9^+c)2BqbX9AoOSCP;YeP0rlmFm3^4M9ilqYt*xnbZI+8V7yNT;vXc!TJsg4Y zHLiMaN_ltZuraPs_6)B4MwCDGkMEXjg4Xrr*jiN5KjLW=J29;KzV9FH>lmMv*zoTS z>ogk3suK|L%@AHin<5lcJ37;SiR41=E-CL`n&j??%HC0kJC#%5wWNR#weKzAlcbrJ zf&?NN&3F_|t`e<4ez-?QNVKv*&9A0n9>HJ^kChl2#j|FkFgY=n$xBD0?_;1&6`C&I zqb1`-4@yOwX|{3jrJHyB;=EO%M~F?|Ql2(VRgh~{>rJ(}brOxE{sTxYUGP|MR+vJL zx|NXd7;gd(k5!_wL^I(6NUqyeW|kyA9j$-)pozJ)g8k_Rwz97L`5eyKNrnX8hC*h3 zcsCJ=l|YPYNa|7Nm$Wl2Lb_=7Z^jj+m)TE!~`jxf}SYe+|Baq1Apg#Mpj$= zLx&CI⪙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 QoM?_HgwXc?0OH^O*{`R%s{jB1 literal 0 HcmV?d00001 diff --git a/src/Bundle/ChillJobBundle/src/Resources/public/images/index.js b/src/Bundle/ChillJobBundle/src/Resources/public/images/index.js new file mode 100644 index 000000000..f8435adf5 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/public/images/index.js @@ -0,0 +1 @@ +require('./footer_bandeau.jpg'); diff --git a/src/Bundle/ChillJobBundle/src/Resources/public/module/cv_edit/index.js b/src/Bundle/ChillJobBundle/src/Resources/public/module/cv_edit/index.js new file mode 100644 index 000000000..43917ddad --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/public/module/cv_edit/index.js @@ -0,0 +1,43 @@ +import { ShowHide } from 'ShowHide/show_hide.js'; +// listen to adding of formation and register a show hide + +var make_show_hide = function(entry) { + let + obtained = entry.querySelector('[data-diploma-obtained]'), + reconnue = entry.querySelector('[data-diploma-reconnue]') + ; + var a = new ShowHide({ + load_event: null, + froms: [ obtained ], + container: [ reconnue ], + test: function(froms, event) { + for (let f of froms.values()) { + for (let input of f.querySelectorAll('input').values()) { + if (input.value === 'non-fr') { + return input.checked; + } + } + } + + return false; + } + }); +}; + +window.addEventListener('collection-add-entry', function(e) { + if (e.detail.collection.dataset.collectionName === 'formations') { + make_show_hide(e.detail.entry); + } +}); + +// starting the formation on load +window.addEventListener('load', function(_e) { + let + formations = document.querySelectorAll('[data-formation-entry]') + ; + + for (let f of formations.values()) { + make_show_hide(f); + } +}); + diff --git a/src/Bundle/ChillJobBundle/src/Resources/public/module/dispositif_edit/index.js b/src/Bundle/ChillJobBundle/src/Resources/public/module/dispositif_edit/index.js new file mode 100644 index 000000000..c8dba4ff7 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/public/module/dispositif_edit/index.js @@ -0,0 +1,72 @@ +import { ShowHide } from 'ShowHide/show_hide.js'; + +var + div_accompagnement = document.getElementById("form_accompagnement"), + div_accompagnement_rqth = document.getElementById("form_accompagnement_rqth"), + div_accompagnement_comment = document.getElementById("form_accompagnement_comment"), + div_caf_id = document.getElementById("cafId"), + div_caf_inscription_date = document.getElementById("cafInscriptionDate"), + div_neet_eligibilite = document.getElementById("neetEligibilite"), + div_neet_commission_date = document.getElementById("neetCommissionDate") + ; + +// faire apparaitre / disparaitre RQTH si RQTH coché +new ShowHide({ + "froms": [div_accompagnement], + "test": function(froms, event) { + for (let el of froms.values()) { + for (let input of el.querySelectorAll('input').values()) { + if (input.value === 'rqth') { + return input.checked; + } + } + } + }, + "container": [div_accompagnement_rqth] +}); + +// faire apparaitre / disparaitre commetnaire si coché +new ShowHide({ + "froms": [div_accompagnement], + "test": function(froms, event) { + for (let el of froms.values()) { + for (let input of el.querySelectorAll('input').values()) { + if (input.value === 'autre') { + return input.checked; + } + } + } + + return false; + }, + "container": [div_accompagnement_comment] +}); + +// faire apparaitre cafInscriptionDate seulement si cafID est rempli +new ShowHide({ + froms: [ div_caf_id ], + test: function(froms, event) { + for (let el of froms.values()) { + return el.querySelector("input").value !== ""; + } + }, + container: [ div_caf_inscription_date ], + event_name: 'input' +}); + +// faire apparaitre date de commission neet seulement si eligible +new ShowHide({ + froms: [ div_neet_eligibilite ], + test: function(froms, event) { + for (let el of froms.values()) { + for (let input of el.querySelectorAll('input').values()) { + if (input.value === "oui") { + return input.checked; + } + } + } + + return false; + }, + container: [ div_neet_commission_date ] +}); \ No newline at end of file diff --git a/src/Bundle/ChillJobBundle/src/Resources/public/module/immersion_edit/index.js b/src/Bundle/ChillJobBundle/src/Resources/public/module/immersion_edit/index.js new file mode 100644 index 000000000..c934b0b32 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/public/module/immersion_edit/index.js @@ -0,0 +1,20 @@ +import { ShowHide } from 'ShowHide/show_hide.js'; + +var + div_objectifs = document.getElementById("objectifs"), + div_objectifs_autre = document.getElementById("objectifsAutre") + ; + +new ShowHide({ + froms: [div_objectifs], + container: [div_objectifs_autre], + test: function(froms, event) { + for (let el of froms.values()) { + for (let input of el.querySelectorAll('input').values()) { + if (input.value === 'autre') { + return input.checked; + } + } + } + } +}); \ No newline at end of file diff --git a/src/Bundle/ChillJobBundle/src/Resources/public/module/personal_situation/index.js b/src/Bundle/ChillJobBundle/src/Resources/public/module/personal_situation/index.js new file mode 100644 index 000000000..4cb4bb246 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/public/module/personal_situation/index.js @@ -0,0 +1,103 @@ +import { ShowHide } from 'ShowHide/show_hide.js'; +var + ressources = document.getElementById("ressources"), + ressources_comment = document.getElementById("ressourcesComment"), + handicap_is = document.getElementById('handicap_is'), + handicap_if = document.getElementById('handicap_if'), + situation_prof = document.getElementById('situation_prof'), + type_contrat = document.getElementById('type_contrat'), + type_contrat_aide = document.getElementById('type_contrat_aide'), + situation_logement = document.getElementById('situation_logement'), + situation_logement_precision = document.getElementById('situation_logement_precision') + ; + +new ShowHide({ + froms: [ressources], + container: [ressources_comment], + test: function(froms) { + for (let f of froms.values()) { + for (let input of f.querySelectorAll('input').values()) { + if (input.value === 'autre') { + return input.checked; + } + } + } + } +}); + +new ShowHide({ + froms: [handicap_is], + container: [handicap_if], + test: function(froms) { + for (let f of froms.values()) { + for (let input of f.querySelectorAll('input').values()) { + if (input.value === '1') { + return input.checked; + } + } + } + + return false; + } +}); + +var show_hide_contrat_aide = new ShowHide({ + froms: [type_contrat], + container: [type_contrat_aide], + test: function(froms) { + for (let f of froms.values()) { + for (let input of f.querySelectorAll('input').values()) { + if (input.value === 'contrat_aide') { + return input.checked; + } + } + } + + return false; + } +}); + +new ShowHide({ + id: 'situation_prof_type_contrat', + froms: [situation_prof], + container: [type_contrat], + test: function(froms) { + for (let f of froms.values()) { + for (let input of f.querySelectorAll('input').values()) { + if (input.value === 'en_activite') { + return input.checked; + } + } + } + + return false; + } +}); + +window.addEventListener('show-hide-hide', function (e) { + if (e.detail.id = 'situation_prof_type_contrat') { + show_hide_contrat_aide.forceHide(); + } +}); + +window.addEventListener('show-hide-show', function (e) { + if (e.detail.id = 'situation_prof_type_contrat') { + show_hide_contrat_aide.forceCompute(); + } +}); + +new ShowHide({ + froms: [situation_logement], + container: [situation_logement_precision], + test: function(froms) { + for (let f of froms.values()) { + for (let input of f.querySelectorAll('input')) { + if (input.value === 'heberge_chez_tiers') { + return input.checked; + } + } + } + + return false; + } +}); \ No newline at end of file diff --git a/src/Bundle/ChillJobBundle/src/Resources/public/sass/csconnectes.scss b/src/Bundle/ChillJobBundle/src/Resources/public/sass/csconnectes.scss new file mode 100644 index 000000000..6405c0f00 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/public/sass/csconnectes.scss @@ -0,0 +1,19 @@ +footer.footer { + padding: 0; + background-color: white; + border-top: 1px solid grey; + div.sponsors { + p { + padding-bottom: 10px; + color: #000; + font-size: 16px; + } + background-color: white; + padding: 2em 0; + img { + display: block; + margin: auto; + } + } +} + diff --git a/src/Bundle/ChillJobBundle/src/Resources/public/sass/index.js b/src/Bundle/ChillJobBundle/src/Resources/public/sass/index.js new file mode 100644 index 000000000..657c9677d --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/public/sass/index.js @@ -0,0 +1 @@ +require('./csconnectes.scss'); diff --git a/src/Bundle/ChillJobBundle/src/Resources/translations/messages.fr.yml b/src/Bundle/ChillJobBundle/src/Resources/translations/messages.fr.yml new file mode 100644 index 000000000..9f9e652bd --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/translations/messages.fr.yml @@ -0,0 +1,250 @@ +situation_logement: + proprietaire: Propriétaire + locataire: Locataire + heberge_chez_tiers: Hébergé chez un tiers + heberge_chez_parents: Hébergé chez un parent + hebergement_en_foyer: Hébergé en foyer + sans_domicile: Sans domicile +niveau_maitrise_langue: + lu: Lu + ecrit: Écrit + parle: Parlé + aucun: Aucun +permis_conduire: + a: Permis A + b: Permis B + c: Permis C + d: Permis D + e: Permis E + en_cours: En cours + pas_de_permis: Pas de permis + caces: CACES + label: "Permis de conduire" +situation_professionnelle: + sans_emploi: Sans emploi + en_activite: En activité + etudiant: Étudiant + etudiant_descolarise: Étudiant déscolarisé + label: "Situation professionnelle" +type_contrat: + cdd: CDD + cdi: CDI + contrat_interim: Contrat intérim + contrat_aide: Contrat aidé + cdd_insertion: CDD insertion + contrat_extra: Contrat extra + service_civique: Service civique + label: "Type de contrat" +ressource: + salaires: Salaire(s) + ARE: ARE + are: ARE + ASS: ASS + ass: ASS + RSA: RSA + rsa: RSA + AAH: AAH + aah: AAH + autre: Autre + label: "Ressource" +accompagnement: + plie: PLIE + pole_emploi: Pôle emploi + referent_RSA: Référent RSA + mission_locale: Mission locale + rqth: RQTH + autre: Autre + label: "Accompagnement" +freins_perso: + situation_administrative: Situation administrative + situation_personnelle_et_familiale: Situation personnelle et familiale + comportement: Comportement + etat_de_sante: État de santé + precarite_situation_materielle: Précarité de la situation matérielle + condition_ou_absence_logement: Condition ou absence de logement + autres: Autres +freins_emploi: + garde_d_enfants: Garde d'enfants + sante: Santé + famille: Famille + finances: Finances + maitrise_de_la_langue: Maitrise de la langue + autres: Autres +neet_eligibility: + oui: Oui + non: Non + en_attente: En attente + label: "Éligibilité NEET" +handicap_recommandation: + travail_esat: Travail en ESAT + milieu_ordinaire: Milieu ordinaire + entreprise_adaptee: Entreprise adaptée +moyen_transport: + transport_commun: Transport en commun + scooter: Scooter + velo: Vélo + voiture: Voiture + autre: Autre + label: "Moyen de transport" +formation_level: + sans_diplome: Sans diplôme + BEP_CAP: BEP CAP + BAC: BAC + BAC+2: BAC +2 + BAC+3: BAC +3 + BAC+4: BAC +4 + BAC+5: BAC +5 + BAC+8: BAC +8 +formation_type: + formation_initiale: Formation initiale + formation_continue: Formation continue +diploma_obtained: + fr: En France + non-fr: À l'étranger + aucun: Aucun +diploma_reconnu: + oui: Oui + non: Non + nsp: Ne sait pas +xp_contrat_type: + cddi: CDDI + cdd-6mois: CDD -6mois + cdd+6mois: CDD +6mois + interim: Intérim + apprentissage: Apprentissage + contrat_prof: Contrat professionnel + cui: CUI + cae: CAE + cdi: CDI + stage: Stage + volontariat: Volontariat + benevolat: Bénévolat + autres: Autres +immersion_objectif: + 'decouvrir_metier': "Découvrir un métier ou un secteur d'activité" + 'confirmer_projet_prof': "Confirmer un projet professionnel" + 'acquerir_experience': "Acquérir une expérience professionnelle" + 'acquerir_competences': "Acquérir de nouvelles compétences" + 'initier_demarche_recrutement': "Initier une démarche de recrutement" + 'autre': "Autre" +immersion_savoir_etre: + 'assiduite': "Assiduité" + 'ponctualite': "Ponctualité" + 'respect_consigne_securite': "Respect des consignes de sécurité" + 'relation_hierarchie': "Relation avec la hiérarchie" + 'capacite_adaptation': "Capacité d'adaptation" + 'motivation_travail': "Motivation au travail" +immersion_ponctualiteSalarie: + un: Un retard + aucun: Aucun retard + plusieurs: Plusieurs retards +immersion_assiduite: + aucun: Aucune absence + un: Une absence + plusieurs: Plusieurs absences +immersion_integreRegle: + 1_temps: Au bout d'un certain temps + rapidement: Rapidement + pas_encore: Ne les a pas encore intégrées +immersion_nsp: + oui: Oui + non: Non + nsp: Ne sait pas +projet_prof: + type_contrat: + cdd: "CDD" + cdi: "CDI" + contrat_insertion: "Contrat d'insertion" + interim: "Intérim" + indifferent: "Indifférent" + label: "Type de contrat recherché" + apprentissage: Contrat d'apprentissage + personnalisation: Personnalisation + creation_entreprise: Création d'entreprise + note: "Notes contrat recherché" + volume_horaire: + temps_plein: "Temps plein" + temps_partiel: "Temps partiel" + label: "Volume horaire" + note: "Notes volume horaire" + idee: "Idées" + encoursdeconstruction: "En cours de construction" + valide: + note: "Notes validés" + code: "Codes validés" + note: "Notes" + souhait: + code: "Codes souhaits" + + +chill_3party: + key_label: + prescripteur: Prescripteur + entreprise: Entreprise + +crud: + csfrein: + title_new: Nouveau rapport "frein" pour %person% + title_view: Rapport 'Frein' pour %person% + title_edit: Modifier un rapport "frein" + title_delete: Supprimer un Frein + button_delete: Supprimer + confirm_message_delete: Supprimer le %as_string% ? + cscv: + title_new: Nouveau CV pour %person% + title_view: CV pour %person% + title_edit: Modifier un CV + title_delete: Supprimer un CV + button_delete: Supprimer + confirm_message_delete: Supprimer le %as_string% ? + immersion: + title_new: Nouvelle immersion pour %person% + title_view: Immersion pour %person% + title_edit: Modifier immersion + title_delete: Supprimer immersion + button_delete: Supprimer + confirm_message_delete: Supprimer le %as_string% ? + projet_prof: + title_new: Nouveau projet professionnel pour %person% + title_view: Projet professionnel pour %person% + title_edit: Modifier un projet professionnel + title_delete: Supprimer le projet professionnel + button_delete: Supprimer + confirm_message_delete: Supprimer le %as_string% ? + +# +# Exports +# +placeofbirth: 'Lieu de naissance' +countryofbirth: 'Pays de naissance' +formationlevel: 'Niveau de formation' +reportdate: 'Date du rapport' +notesperso: 'Notes situation personnelle' +notesemploi: "Notes accès à l’emploi" + +prescripteur: + name: "Prescripteur" + email: "Email prescripteur" + phone: "Téléphone prescripteur" + +recentopeningdate: "Date récente d’ouverture du dossier" +recentclosingdate: "Date récente de fermeture du dossier" +closingmotive: "Motif de fermeture" +situation_familiale: "Situation familiale" +enfantacharge: "Enfants à charge" +poleemploiid: "Identifiant pôle emploi" +cafid: "Numéro allocataire CAF" +cafinscriptiondate: "Date de l’inscription CAF" +cerinscriptiondate: "Date de l’inscription CER" +contratiejdate: "Date de l’avenant du contrat" +ppaeinscriptiondate: "Date de l’inscription PPAE" +ppaesignataire: "Signataire PPAE" +cersignataire: "Signataire CER" +neetcommissiondate: "Date de commission NEET" +fsemademarchecode: "Code démarche FSE" +findernieremploidate: "Date de fin dernier emploi" + +CHILL_CSCONNECTES_REPORT_NEW: Création et modification des rapports CSConnectes +CHILL_CSCONNECTES_REPORT_DELETE: Suppression des rapports CSConnectes +CHILL_CSCONNECTES_REPORT_CV: Création et modification des rapports CSConnectes (CV uniquement) +CHILL_CSCONNECTES_EXPORTS: Exports CSConnectes \ No newline at end of file diff --git a/src/Bundle/ChillJobBundle/src/Resources/views/CSPerson/dispositifs_edit.html.twig b/src/Bundle/ChillJobBundle/src/Resources/views/CSPerson/dispositifs_edit.html.twig new file mode 100644 index 000000000..82a4682d9 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/views/CSPerson/dispositifs_edit.html.twig @@ -0,0 +1,91 @@ +{% extends '@ChillPerson/CRUD/edit.html.twig' %} + +{% block title 'Dispositifs de ' ~ entity.person.firstName ~ ' ' ~ entity.person.lastName %} + +{% block personcontent %} +{% embed '@ChillPerson/CRUD/_edit_content.html.twig' %} + {% block crud_content_header %} +

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.accompagnementComment) }} +
    + {{ 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() }} + + +{% endblock js %} \ No newline at end of file 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..569aa7078 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/views/CSPerson/dispositifs_view.html.twig @@ -0,0 +1,126 @@ +{% extends "ChillPersonBundle::layout.html.twig" %} + +{% set person = entity.getPerson() %} + +{% set activeRouteKey = '' %} +{% set accompagnements = constant('CSConnectes\\SPBundle\\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 personcontent %} +

    {{ '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|localizeddate('long', 'none') }}

    + {% endif %} + {% if entity.dateAvenantIEJ != null %} +

    Date de l'avenant IEJ : {{ entity.dateAvenantIEJ|localizeddate('long', 'none') }}

    + {% endif %} +
    + {% endif %} +
    + + + + +{% endblock personcontent %} + +{% block css %} + +{% endblock %} \ No newline at end of file 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..04f73a0ed --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/views/CSPerson/personal_situation_edit.html.twig @@ -0,0 +1,124 @@ +{% extends '@ChillPerson/CRUD/edit.html.twig' %} + +{% block title 'Situation personnelle de ' ~ entity.person.firstName ~ ' ' ~ entity.person.lastName %} + +{% block personcontent %} +{% embed '@ChillPerson/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.ressourcesComment) }} +
    + + {{ 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() }} + +{% endblock css %} + +{% block js %} + {{ parent() }} + + +{% 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..a0063cabd --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/views/CSPerson/personal_situation_view.html.twig @@ -0,0 +1,282 @@ +{% extends "ChillPersonBundle::layout.html.twig" %} + +{% set person = entity.getPerson() %} + +{% set activeRouteKey = '' %} +{% set niveaux_maitrise_langue = constant('CSConnectes\\SPBundle\\Entity\\CSPerson::NIVEAU_MAITRISE_LANGUE') %} +{% set permis_conduire = constant('CSConnectes\\SPBundle\\Entity\\CSPerson::PERMIS_CONDUIRE') %} +{% set types_contrat = constant('CSConnectes\\SPBundle\\Entity\\CSPerson::TYPE_CONTRAT') %} +{% set ressources = constant('CSConnectes\\SPBundle\\Entity\\CSPerson::RESSOURCES') %} + +{% import '@ChillDocStore/Macro/macro.html.twig' as doc %} + +{% block title 'Situation personnelle de %name%'|trans( { '%name%': person.firstName ~ ' ' ~ person.lastName } ) %} + +{% block personcontent %} +

    {{ '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|localizeddate('medium', 'none') }} + {% 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|localizeddate('medium', 'none') }} + {% else %} +
    {{ null|chill_print_or_message }}
    + {% endif %} + +
    Montant CPF
    + {% if entity.cPFMontant is not null %} +
    {{ entity.cPFMontant|localizedcurrency('EUR') }}
    + {% else %} +
    {{ null|chill_print_or_message }}
    + {% endif %} + + +
    Montant acompte DIF
    + {% if entity.acompteDIF is not null %} +
    {{ entity.acompteDIF|localizedcurrency('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 document = attribute(entity, r[0]) %} + {% if document is null %} +
    {{ null|chill_print_or_message("Aucun document") }}
    + {% else %} +
    {{ doc.download_button(document, r[1] ~ " de " ~ person.firstName ~ " " ~ person.lastName) }}
    + {% endif %} + + {% endfor %} + +
    + + + +{% endblock %} + +{% block css %} + {{ parent() }} + +{% endblock css %} + +{% block js %} + {{ parent() }} + +{% endblock js %} \ No newline at end of file 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..96b9428ce --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/views/CV/edit.html.twig @@ -0,0 +1,61 @@ +{% extends '@ChillPerson/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 csconnectes_spbundle_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 personcontent %} +{% embed '@ChillPerson/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 %} \ No newline at end of file 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..c7842f048 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/views/CV/new.html.twig @@ -0,0 +1,61 @@ +{% extends '@ChillPerson/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 csconnectes_spbundle_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 personcontent %} +{% 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 %} \ No newline at end of file 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..cf9c3a962 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/views/CV/view.html.twig @@ -0,0 +1,142 @@ +{% extends '@ChillPerson/CRUD/view.html.twig' %} + +{% block personcontent %} +{% 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|localizeddate('long', 'none') }}
    + +

    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

    + +
    + {% for f in entity.formations %} +
    +

    {{ f.title }}{% if f.organisme is not empty %} auprès de {{ f.organisme }}{% endif %}

    + +
    + +
    Dates de formation
    +
    + {% 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|localizeddate('long', 'none') }} (date de début inconnue) + {% elseif f.endDate is null %} + Depuis le {{ f.startDate|localizeddate('long', 'none') }} (date de fin inconnue) + {% else %} + Du {{ f.startDate|localizeddate('long', 'none') }} au {{ f.endDate|localizeddate('long', 'none') }} + {% endif %} +
    + +
    Diplôme
    +
    +

    Diplôme obtenu: {{ (f.diplomaObtained is null ? null : ('diploma_obtained.' ~ f.diplomaObtained))|chill_print_or_message("Aucune information") }}

    +

    Diplôme reconnu en France: {{ (f.diplomaReconnue is null ? null : ('diploma_reconnu.' ~ f.diplomaReconnue))|chill_print_or_message("Aucune information") }}

    +
    +
    +
    + {% else %} +

    Aucune formation renseignée

    + {% endfor %} +
    + +

    Expériences

    + +
    + {% 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|localizeddate('long', 'none') }} (date de début inconnue) + {% elseif f.endDate is null %} + Depuis le {{ f.startDate|localizeddate('long', 'none') }} (date de fin inconnue) + {% else %} + Du {{ f.startDate|localizeddate('long', 'none') }} au {{ f.endDate|localizeddate('long', 'none') }} + {% 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 %} +
    +
    + {% else %} +

    Aucune formation renseignée

    + {% endfor %} +
    + + +

    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 %} \ No newline at end of file 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..8e022d6b1 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/views/Frein/edit.html.twig @@ -0,0 +1,20 @@ +{% extends '@ChillPerson/layout.html.twig' %} + +{% set person = entity.person %} +{% set activeRouteKey = '' %} + +{% block title %} +{% include('@ChillMain/CRUD/_edit_title.html.twig') %} +{% endblock title %} + +{% block personcontent %} +{% embed '@ChillPerson/CRUD/_edit_content.html.twig' %} + {% block content_form_actions_back %} +
  • + + {{ 'Cancel'|trans }} + +
  • + {% endblock %} +{% endembed %} +{% endblock %} \ No newline at end of file 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..be8d2a84a --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/views/Frein/new.html.twig @@ -0,0 +1,23 @@ +{% extends '@ChillPerson/layout.html.twig' %} + +{% set person = entity.person %} +{% set activeRouteKey = '' %} + +{% block title %} +{% embed('@ChillPerson/CRUD/_new_title.html.twig') %}{% endembed %} +{% endblock %} + +{% block personcontent %} +{% 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..e32d4a453 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/views/Frein/view.html.twig @@ -0,0 +1,58 @@ +{% extends '@ChillPerson/CRUD/view.html.twig' %} + +{% block personcontent %} +{% 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|localizeddate('long', 'none') }}
    + +
    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 %} \ No newline at end of file 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..37ca1f40a --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/views/Immersion/edit-bilan.html.twig @@ -0,0 +1,92 @@ +{% extends '@ChillPerson/layout.html.twig' %} + +{% set person = entity.person %} +{% set activeRouteKey = '' %} + +{% block title %} +Bilan d'immersion +{% endblock title %} + +{% block personcontent %} +{% embed '@ChillPerson/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|localizeddate('long', 'none') }} au {{ entity.getDateEndComputed|localizeddate('long', 'none') }}, + 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 %} \ No newline at end of file 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..aacfc14fd --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/views/Immersion/edit.html.twig @@ -0,0 +1,65 @@ +{% extends '@ChillPerson/layout.html.twig' %} + +{% set person = entity.person %} +{% set activeRouteKey = '' %} + +{% block title %} +{% include('@ChillMain/CRUD/_edit_title.html.twig') %} +{% endblock title %} + +{% block personcontent %} +{% embed '@ChillPerson/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 %} + +{% endblock %} \ No newline at end of file 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..eeeb1b2c4 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/views/Immersion/new.html.twig @@ -0,0 +1,68 @@ +{% extends '@ChillPerson/layout.html.twig' %} + +{% set person = entity.person %} +{% set activeRouteKey = '' %} + +{% block title %} +{% embed('@ChillPerson/CRUD/_new_title.html.twig') %}{% endembed %} +{% endblock %} + +{% block personcontent %} +{% 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 %} + +{% 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..d5f789431 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/views/Immersion/view.html.twig @@ -0,0 +1,209 @@ +{% extends '@ChillPerson/CRUD/view.html.twig' %} + +{% block personcontent %} +{% 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

    + +
    + {% 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|localizeddate('long', 'none') }} + au {{ entity.getDateEndComputed|localizeddate('long', 'none') }} +
    + +
    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 %} + +
    + {{ 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('CSConnectes\\SPBundle\\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 %} \ No newline at end of file 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..335019564 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/views/ProjetProfessionnel/edit.html.twig @@ -0,0 +1,52 @@ +{% extends '@ChillPerson/layout.html.twig' %} + +{% set person = entity.person %} +{% set activeRouteKey = '' %} + +{% block title %} +{% include('@ChillMain/CRUD/_edit_title.html.twig') %} +{% endblock title %} + +{% block personcontent %} +{% embed '@ChillPerson/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..c27a45419 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/views/ProjetProfessionnel/new.html.twig @@ -0,0 +1,52 @@ +{% extends '@ChillPerson/layout.html.twig' %} + +{% set person = entity.person %} +{% set activeRouteKey = '' %} + +{% block title %} +{% embed('@ChillPerson/CRUD/_new_title.html.twig') %}{% endembed %} +{% endblock %} + +{% block personcontent %} +{% 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..ba221ef62 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/views/ProjetProfessionnel/view.html.twig @@ -0,0 +1,108 @@ +{% extends '@ChillPerson/CRUD/view.html.twig' %} + +{% block personcontent %} +{% 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|localizeddate('long', 'none') }}
    + +

    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 %} \ No newline at end of file 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..d805dfdac --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/views/Report/delete.html.twig @@ -0,0 +1,16 @@ +{% extends '@ChillPerson/layout.html.twig' %} + +{% set person = entity.person %} +{% set activeRouteKey = '' %} + +{% block personcontent %} +{% 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..a9d3fcba0 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Resources/views/Report/index.html.twig @@ -0,0 +1,253 @@ +{% extends '@ChillPerson/layout.html.twig' %} + +{% set activeRouteKey = '' %} + +{% block personcontent %} +
    +

    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 %} + + + + + + + + + {% for cv in cvs %} + + + + + {% endfor %} + +
    Date 
    {{ cv.reportDate|localizeddate('short', 'none') }} +
      +
    • + +
    • +
    • + +
    • + {% if is_granted('CHILL_CSCONNECTES_REPORT_DELETE', cv) %} +
    • + +
    • + {% endif %} +
    +
    + {% endif %} + + + {% endif %} + + {% if freins is defined %} +

    Freins

    + + {% if freins|length == 0 %} +

    {{ null|chill_print_or_message("Aucun rapport enregistré") }}

    + {% else %} + + + + + + + + + + {% for frein in freins %} + + + + + + {% endfor %} + +
    DateFreins identifiés 
    {{ frein.reportDate|localizeddate('short', 'none') }} + {% 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_CSCONNECTES_REPORT_DELETE', frein) %} +
    • + +
    • + {% endif %} +
    +
    + {% endif %} + + + + {% endif %} + + {% if immersions is defined %} +

    Immersions

    + + {% if immersions|length == 0 %} +

    {{ null|chill_print_or_message("Aucun rapport enregistré") }}

    + {% else %} + + + + + + + + + + {% for im in immersions %} + + + + + + + {% endfor %} + +
    Date de début de l'immersionEntreprise 
    {{ im.debutDate|localizeddate('short', 'none') }} + {{ im.entreprise.name }} + +
      +
    • + +
    • +
    • + +
    • +
    • + + + +
    • + {% if is_granted('CHILL_CSCONNECTES_REPORT_DELETE', im) %} +
    • + +
    • + {% endif %} +
    +
    + {% endif %} + + + {% endif %} + + {% if projet_professionnels is defined %} + +

    Projets professionnels

    + + {% if projet_professionnels|length == 0 %} +

    {{ null|chill_print_or_message("Aucun rapport enregistré") }}

    + {% else %} + + + + + + + + + + + {% for pr in projet_professionnels %} + + + + + + + + {% endfor %} + +
    Date de créationProjet validé ou souhaitéType de contrat 
    {{ pr.reportDate|localizeddate('short', 'none') }} + {% 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_CSCONNECTES_REPORT_DELETE', pr) %} +
    • + +
    • + {% endif %} +
    +
    + {% endif %} + + + {% endif %} +
    + +{% endblock %} \ No newline at end of file diff --git a/src/Bundle/ChillJobBundle/src/Security/Authorization/CSConnectesVoter.php b/src/Bundle/ChillJobBundle/src/Security/Authorization/CSConnectesVoter.php new file mode 100644 index 000000000..13d155a37 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Security/Authorization/CSConnectesVoter.php @@ -0,0 +1,120 @@ +date15DaysAgo = new \DateTime('-15 days'); + $this->authorizationHelper = $authorizationHelper; + } + + + protected function supports($attribute, $subject) + { + if (!\in_array($attribute, self::ALL)) { + 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() + { + return self::ALL; + } + + public function getRolesWithHierarchy(): array + { + return ['CSConnectes' => $this->getRoles()]; + } + + public function getRolesWithoutScope(): array + { + return $this->getRoles(); + } +} diff --git a/src/Bundle/ChillJobBundle/src/Security/Authorization/ExportsVoter.php b/src/Bundle/ChillJobBundle/src/Security/Authorization/ExportsVoter.php new file mode 100644 index 000000000..620dcbcf9 --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Security/Authorization/ExportsVoter.php @@ -0,0 +1,121 @@ +authorizationHelper = $authorizationHelper; + } + + /** + * @param $attribute + * @param $subject + * @return bool + */ + protected function supports($attribute, $subject) + { + if ($subject instanceof Center) { + return $attribute === self::EXPORT; + } elseif ($subject === NULL) { + return $attribute === self::EXPORT; + } + return false; + } + + /** + * @param $attribute + * @param $subject + * @param TokenInterface $token + * @return bool + */ + protected function voteOnAttribute($attribute, $subject, TokenInterface $token) + { + $user = $token->getUser(); + + if (!$user instanceof User) { + return false; + } + + $centers = $this->authorizationHelper->getReachableCenters($user, new Role($attribute)); + + if ($subject === null) { + 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' ] ] + * ``` + * + * @return array where keys are the hierarchy, and values an array of roles: `[ 'title' => [ 'CHILL_FOO_SEE', 'CHILL_FOO_UPDATE' ] ]` + */ + public function getRolesWithHierarchy() + { + return [ 'CSConnectes' => $this->getRoles() ]; + } + + /** + * return an array of role provided by the object + * + * @return string[] array of roles (as string) + */ + public function getRoles() + { + return $this->getAttributes(); + } + + /** + * return roles which doesn't need + * + * @return string[] array of roles without scopes + */ + public function getRolesWithoutScope() + { + return $this->getAttributes(); + } + + /** + * @return array + */ + private function getAttributes() { + return [ self::EXPORT ]; + } +} 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..e92f9fb0b --- /dev/null +++ b/src/Bundle/ChillJobBundle/src/Tests/Controller/CSPersonControllerTest.php @@ -0,0 +1,9 @@ +