Merge remote-tracking branch 'origin/fix-getParticipationsContainsPerson' into fix-person-tests

This commit is contained in:
Julien Fastré 2021-05-26 22:38:25 +02:00
commit 2b12e61fbd
84 changed files with 1954 additions and 668 deletions

View File

@ -18,7 +18,7 @@ before_script:
# Bring in any services we need http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service
# See http://docs.gitlab.com/ee/ci/services/README.html for examples.
services:
- name: postgres:12
- name: postgis/postgis:12-3.1-alpine
alias: db
- name: redis
alias: redis

View File

@ -590,7 +590,7 @@ class CRUDController extends AbstractController
if (NULL === $entity) {
throw $this->createNotFoundException(sprintf("The %s with id %s "
. "is not found"), $this->getCrudName(), $id);
. "is not found", $this->getCrudName(), $id));
}
$response = $this->checkACL($action, $entity);

View File

@ -28,7 +28,7 @@
// @import "bootstrap/scss/card";
// @import "bootstrap/scss/breadcrumb";
// @import "bootstrap/scss/pagination";
// @import "bootstrap/scss/badge";
@import "bootstrap/scss/badge";
// @import "bootstrap/scss/jumbotron";
// @import "bootstrap/scss/alert";
// @import "bootstrap/scss/progress";
@ -41,7 +41,7 @@
// @import "bootstrap/scss/popover";
// @import "bootstrap/scss/carousel";
// @import "bootstrap/scss/spinners";
// @import "bootstrap/scss/utilities";
@import "bootstrap/scss/utilities";
// @import "bootstrap/scss/print";
@import "custom";

View File

@ -5,7 +5,7 @@
@include button($green, $white);
}
&.bt-reset, &.bt-delete {
&.bt-reset, &.bt-delete, &.bt-remove {
@include button($red, $white);
}
@ -24,6 +24,7 @@
&.bt-save::before,
&.bt-new::before,
&.bt-delete::before,
&.bt-remove::before,
&.bt-update::before,
&.bt-edit::before,
&.bt-cancel::before,
@ -57,6 +58,11 @@
content: "";
}
&.bt-remove::before {
// add a times
content: "";
}
&.bt-edit::before, &.bt-update::before {
// add a pencil
content: "";
@ -94,6 +100,7 @@
&.bt-save::before,
&.bt-new::before,
&.bt-delete::before,
&.bt-remove::before,
&.bt-update::before,
&.bt-edit::before,
&.bt-cancel::before,
@ -123,6 +130,7 @@
&.bt-save::before,
&.bt-new::before,
&.bt-delete::before,
&.bt-remove::before,
&.bt-update::before,
&.bt-edit::before,
&.bt-cancel::before,

View File

@ -39,6 +39,8 @@ div.subheader {
height: 130px;
}
//// VUEJS ////
div.vue-component {
padding: 1.5em;
margin: 2em 0;
@ -55,3 +57,97 @@ div.vue-component {
}
dd { margin-left: 1em; }
}
//// MODAL ////
.modal-mask {
position: fixed;
z-index: 9998;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.75);
display: table;
transition: opacity 0.3s ease;
}
.modal-header .close { // bootstrap classes, override sc-button 0 radius
border-top-right-radius: 0.3rem;
}
/*
* The following styles are auto-applied to elements with
* transition="modal" when their visibility is toggled
* by Vue.js.
*
* You can easily play with the modal transition by editing
* these styles.
*/
.modal-enter {
opacity: 0;
}
.modal-leave-active {
opacity: 0;
}
.modal-enter .modal-container,
.modal-leave-active .modal-container {
-webkit-transform: scale(1.1);
transform: scale(1.1);
}
//// AddPersons modal
div.modal-body.up {
margin: auto 4em;
div.search {
position: relative;
input {
padding: 1.2em 1.5em 1.2em 2.5em;
margin: 1em 0;
}
i {
position: absolute;
top: 50%;
left: 0.5em;
padding: 0.65em 0;
opacity: 0.5;
}
}
}
div.results {
div.count {
margin: -0.5em 0 0.7em;
display: flex;
justify-content: space-between;
}
div.list-item {
line-height: 26pt;
padding: 0.3em 0.8em;
display: flex;
flex-direction: row;
&.checked {
background-color: #ececec;
border-bottom: 1px dotted #8b8b8b;
}
div.container {
& > input {
margin-right: 0.8em;
}
}
div.right_actions {
margin: 0 0 0 auto;
& > * {
margin-left: 0.5em;
}
a.sc-button {
border: 1px solid lightgrey;
font-size: 70%;
padding: 4px;
}
}
}
}
.discret {
color: grey;
margin-right: 1em;
}

View File

@ -0,0 +1,45 @@
<template>
<transition name="modal">
<div class="modal-mask">
<!-- :: styles bootstrap :: -->
<div class="modal-dialog" :class="modalDialogClass">
<div class="modal-content">
<div class="modal-header">
<slot name="header"></slot>
<button class="close sc-button grey" @click="$emit('close')">
<i class="fa fa-times" aria-hidden="true"></i></button>
</div>
<div class="modal-body up" style="overflow-y: unset;">
<slot name="body-fixed"></slot>
</div>
<div class="modal-body">
<slot name="body"></slot>
</div>
<div class="modal-footer">
<button class="sc-button cancel" @click="$emit('close')">{{ $t('action.close') }}</button>
<slot name="footer"></slot>
</div>
</div>
</div>
<!-- :: end styles bootstrap :: -->
</div>
</transition>
</template>
<script>
/*
* This Modal component is a mix between :
* - Vue3 modal implementation
* => with 'v-if:showModal' directive:parameter, html scope is added/removed not just shown/hidden
* => with slot we can pass content from parent component
* => some classes are passed from parent component
* - Bootstrap 4.6 _modal.scss module
* => using bootstrap css classes, the modal have a responsive behaviour,
* => modal design can be configured using css classes (size, scroll)
*/
export default {
name: 'Modal',
props: ['modalDialogClass'],
emits: ['close']
}
</script>

View File

@ -0,0 +1,55 @@
import { createI18n } from 'vue-i18n'
const datetimeFormats = {
fr: {
short: {
year: "numeric",
month: "numeric",
day: "numeric"
},
long: {
year: "numeric",
month: "short",
day: "numeric",
weekday: "short",
hour: "numeric",
minute: "numeric",
hour12: false
}
}
};
const messages = {
fr: {
action: {
actions: "Actions",
show: "Voir",
edit: "Modifier",
create: "Créer",
remove: "Enlever",
delete: "Supprimer",
save: "Enregistrer",
add: "Ajouter",
show_modal: "Ouvrir une modale",
ok: "OK",
cancel: "Annuler",
close: "Fermer",
next: "Suivant",
previous: "Précédent",
back: "Retour",
check_all: "cocher tout",
reset: "réinitialiser"
},
}
};
const _createI18n = (appMessages) => {
Object.assign(messages.fr, appMessages.fr);
return createI18n({
locale: 'fr',
fallbackLocale: 'fr',
datetimeFormats,
messages,
})
};
export { _createI18n }

View File

@ -121,7 +121,7 @@ class AccompanyingCourseController extends Controller
* @Route(
* "/{_locale}/person/api/1.0/accompanying-course/{accompanying_period_id}/participation.{_format}",
* name="chill_person_accompanying_course_api_add_participation",
* methods={"POST"},
* methods={"POST","DELETE"},
* format="json",
* requirements={
* "_format": "json",
@ -129,7 +129,7 @@ class AccompanyingCourseController extends Controller
* )
* @ParamConverter("accompanyingCourse", options={"id": "accompanying_period_id"})
*/
public function addParticipationAPI(Request $request, AccompanyingPeriod $accompanyingCourse, $_format): Response
public function participationAPI(Request $request, AccompanyingPeriod $accompanyingCourse, $_format): Response
{
switch ($_format) {
case 'json':
@ -146,7 +146,9 @@ class AccompanyingCourseController extends Controller
}
// TODO add acl
$accompanyingCourse->addPerson($person);
$participation = ($request->getMethod() === 'POST') ?
$accompanyingCourse->addPerson($person) : $accompanyingCourse->removePerson($person);
$errors = $this->validator->validate($accompanyingCourse);
if ($errors->count() > 0) {
@ -156,6 +158,6 @@ class AccompanyingCourseController extends Controller
$this->getDoctrine()->getManager()->flush();
return new JsonResponse();
return $this->json($participation);
}
}

View File

@ -38,6 +38,7 @@ use Symfony\Component\Translation\TranslatorInterface;
use Chill\MainBundle\Search\SearchProvider;
use Chill\PersonBundle\Repository\PersonRepository;
use Chill\PersonBundle\Config\ConfigPersonAltNamesHelper;
use Chill\PersonBundle\Repository\PersonNotDuplicateRepository;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Doctrine\ORM\EntityManagerInterface;
@ -290,7 +291,7 @@ final class PersonController extends AbstractController
return $errors;
}
public function reviewAction(Request $request)
public function reviewAction(Request $request, PersonNotDuplicateRepository $personNotDuplicateRepository)
{
if ($request->getMethod() !== 'POST') {
$r = new Response("You must send something to review the creation of a new Person");
@ -299,7 +300,6 @@ final class PersonController extends AbstractController
}
$form = $this->createForm(
//CreationPersonType::NAME,
CreationPersonType::class,
new Person(),
array(
@ -326,7 +326,7 @@ final class PersonController extends AbstractController
}
$form = $this->createForm(
CreationPersonType::NAME,
CreationPersonType::class,
$person,
array(
'action' => $this->generateUrl('chill_person_review'),
@ -342,8 +342,7 @@ final class PersonController extends AbstractController
$this->em->persist($person);
$alternatePersons = $this->similarPersonMatcher
->matchPerson($person);
$alternatePersons = $this->similarPersonMatcher->matchPerson($person, $personNotDuplicateRepository);
if (count($alternatePersons) === 0) {
return $this->forward('ChillPersonBundle:Person:create');

View File

@ -19,6 +19,7 @@ use Symfony\Component\Translation\TranslatorInterface;
use Chill\ActivityBundle\Entity\Activity;
use Chill\DocStoreBundle\Entity\PersonDocument;
use Chill\EventBundle\Entity\Participation;
use Chill\PersonBundle\Repository\PersonNotDuplicateRepository;
use Chill\TaskBundle\Entity\SingleTask;
class PersonDuplicateController extends Controller
@ -62,7 +63,7 @@ class PersonDuplicateController extends Controller
$this->eventDispatcher = $eventDispatcher;
}
public function viewAction($person_id)
public function viewAction($person_id, PersonNotDuplicateRepository $personNotDuplicateRepository)
{
$person = $this->_getPerson($person_id);
if ($person === null) {
@ -74,10 +75,9 @@ class PersonDuplicateController extends Controller
"You are not allowed to see this person.");
$duplicatePersons = $this->similarPersonMatcher->
matchPerson($person, 0.5, SimilarPersonMatcher::SIMILAR_SEARCH_ORDER_BY_ALPHABETICAL);
matchPerson($person, $personNotDuplicateRepository, 0.5, SimilarPersonMatcher::SIMILAR_SEARCH_ORDER_BY_ALPHABETICAL);
$notDuplicatePersons = $this->getDoctrine()->getRepository(PersonNotDuplicate::class)
->findNotDuplicatePerson($person);
$notDuplicatePersons = $personNotDuplicateRepository->findNotDuplicatePerson($person);
return $this->render('ChillPersonBundle:PersonDuplicate:view.html.twig', [
'person' => $person,

View File

@ -0,0 +1,88 @@
<?php
/*
* Chill is a software for social workers
*
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Chill\PersonBundle\DataFixtures\ORM;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Persistence\ObjectManager;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\Person;
/**
* Description of LoadAccompanyingPeriod
*
* @author Champs-Libres Coop
*/
class LoadAccompanyingPeriod extends AbstractFixture implements OrderedFixtureInterface, ContainerAwareInterface
{
use \Symfony\Component\DependencyInjection\ContainerAwareTrait;
public const ACCOMPANYING_PERIOD = 'parcours 1';
public function getOrder()
{
return 10004;
}
public static $references = array();
public function load(ObjectManager $manager)
{
$centerA = $this->getReference('centerA');
$centerAId = $centerA->getId();
$personIds = $this->container->get('doctrine.orm.entity_manager')
->createQueryBuilder()
->select('p.id')
->from('ChillPersonBundle:Person', 'p')
->where('p.center = :centerAId')
->orderBy('p.id', 'ASC')
->setParameter('centerAId', $centerAId)
->getQuery()
->getScalarResult();
$openingDate = new \DateTime('2020-04-01');
$person1 = $manager->getRepository(Person::class)->find($personIds[0]);
$person2 = $manager->getRepository(Person::class)->find($personIds[1]);
$socialScope = $this->getReference('scope_social');
$a = new AccompanyingPeriod($openingDate);
$a->addPerson($person1);
$a->addPerson($person2);
$a->addScope($socialScope);
$a->setStep(AccompanyingPeriod::STEP_CONFIRMED);
$manager->persist($a);
$this->addReference(self::ACCOMPANYING_PERIOD, $a);
echo "Adding one AccompanyingPeriod\n";
$manager->flush();
}
}

View File

@ -0,0 +1,62 @@
<?php
/*
* Chill is a software for social workers
*
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Chill\PersonBundle\DataFixtures\ORM;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Persistence\ObjectManager;
use Chill\PersonBundle\Entity\AccompanyingPeriod\Origin;
/**
* Description of LoadAccompanyingPeriodOrigin
*
* @author Champs-Libres Coop
*/
class LoadAccompanyingPeriodOrigin extends AbstractFixture implements OrderedFixtureInterface
{
public const ACCOMPANYING_PERIOD_ORIGIN = 'accompanying_period_origin';
public function getOrder()
{
return 10005;
}
private $phoneCall = ['en' => 'phone call', 'fr' => 'appel téléphonique'];
public static $references = array();
public function load(ObjectManager $manager)
{
$o = new Origin();
$o->setLabel(json_encode($this->phoneCall));
$manager->persist($o);
$this->addReference(self::ACCOMPANYING_PERIOD_ORIGIN, $o);
echo "Adding one AccompanyingPeriod Origin\n";
$manager->flush();
}
}

View File

@ -0,0 +1,82 @@
<?php
/*
* Chill is a suite of a modules, Chill is a software for social workers
* Copyright (C) 2021, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Chill\PersonBundle\DataFixtures\ORM;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Persistence\ObjectManager;
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
/**
* Create social actions
*
*/
class LoadSocialActions extends AbstractFixture implements OrderedFixtureInterface
{
public function getOrder()
{
return 10020;
}
public static $socialActions = [
'social_action_info_conseil' => [
'title' => [
'fr' => 'Informer, conseiller'
],
'issue' => 'social_issue_prev_prot'
],
'social_action_instruire' => [
'title' => [
'fr' => 'Instruire l\'imprime unique pour des impayés'
],
'issue' => 'social_issue_prev_prot'
],
'social_action_MASP' => [
'title' => [
'fr' => 'MASP'
],
'issue' => 'social_issue_diff_fin'
],
'social_action_protection_enfant' => [
'title' => [
'fr' => 'Protection Enfant confié dans le cadre judiciaire'
],
'issue' => 'social_issue_enfant_protection'
],
];
public function load(ObjectManager $manager)
{
foreach (static::$socialActions as $ref => $new) {
$socialAction = new SocialAction();
$socialAction->setTitle($new['title']);
$socialAction->setIssue($this->getReference($new['issue']));
$socialAction->setDefaultNotificationDelay(new \DateInterval('P5D'));
$manager->persist($socialAction);
$this->addReference($ref, $socialAction);
print("Adding SocialAction '".$new['title']['fr']."'\n");
}
$manager->flush();
}
}

View File

@ -0,0 +1,70 @@
<?php
/*
* Chill is a suite of a modules, Chill is a software for social workers
* Copyright (C) 2021, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Chill\PersonBundle\DataFixtures\ORM;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Persistence\ObjectManager;
use Chill\PersonBundle\Entity\SocialWork\Goal;
/**
* Create social goals
*
*/
class LoadSocialGoals extends AbstractFixture implements OrderedFixtureInterface
{
public function getOrder()
{
return 10030;
}
public static $socialGoals = [
'social_goal_instuire_dossier' => [
'title' => [
'fr' => 'Instruire le dossier de surendettement'
],
'action' => 'social_action_MASP'
],
'social_goal_proteger' => [
'title' => [
'fr' => 'Protéger via une assistance educative placement'
],
'action' => 'social_action_protection_enfant'
],
];
public function load(ObjectManager $manager)
{
foreach (static::$socialGoals as $ref => $new) {
$socialGoal = new Goal();
$socialGoal->setTitle($new['title']);
$socialGoal->addSocialAction($this->getReference($new['action']));
$manager->persist($socialGoal);
$this->addReference($ref, $socialGoal);
print("Adding SocialGoal '".$new['title']['fr']."'\n");
}
$manager->flush();
}
}

View File

@ -0,0 +1,90 @@
<?php
/*
* Chill is a suite of a modules, Chill is a software for social workers
* Copyright (C) 2021, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Chill\PersonBundle\DataFixtures\ORM;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Persistence\ObjectManager;
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
/**
* Create social issues
*
*/
class LoadSocialIssues extends AbstractFixture implements OrderedFixtureInterface
{
public function getOrder()
{
return 10010;
}
public static $socialIssues = [
'social_issue_diff_fin_or_admin' => [
'title' => [
'fr' => 'ADULTE - DIFFICULTES FINANCIERES ET/OU ADMINISTRATIVES'
]
],
'social_issue_prev_prot' => [
'title' => [
'fr' => 'ADULTE PREVENTION/PROTECTION'
],
'parent' => 'social_issue_diff_fin_or_admin'
],
'social_issue_diff_fin' => [
'title' => [
'fr' => 'Difficulté financière'
],
'parent' => 'social_issue_diff_fin_or_admin'
],
'social_issue_enfant_famille' => [
'title' => [
'fr' => 'Enfant / famille'
]
],
'social_issue_enfant_protection' => [
'title' => [
'fr' => 'enfant - protection'
],
'parent' => 'social_issue_enfant_famille'
],
];
public function load(ObjectManager $manager)
{
foreach (static::$socialIssues as $ref => $new) {
$socialIssue = new SocialIssue();
$socialIssue->setTitle($new['title']);
if ( array_key_exists('parent', $new)) {
$parentRef = $new['parent'];
$parent = $this->getReference($parentRef);
$socialIssue->setParent($parent);
}
$manager->persist($socialIssue);
$this->addReference($ref, $socialIssue);
print("Adding SocialIssue '".$new['title']['fr']."'\n");
}
$manager->flush();
}
}

View File

@ -0,0 +1,94 @@
<?php
/*
* Chill is a suite of a modules, Chill is a software for social workers
* Copyright (C) 2021, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Chill\PersonBundle\DataFixtures\ORM;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Persistence\ObjectManager;
use Chill\PersonBundle\Entity\SocialWork\Result;
/**
* Create social results
*
*/
class LoadSocialResults extends AbstractFixture implements OrderedFixtureInterface
{
public function getOrder()
{
return 10040;
}
public static $socialResults = [
'social_result_FSL_acces' => [
'title' => [
'fr' => 'FSL - accès cautionnement'
],
'action' => 'social_action_instruire'
],
'social_result_FSL_maintien' => [
'title' => [
'fr' => 'FSL maintien - impayés de loyer'
],
'action' => 'social_action_MASP'
],
'social_result_soutien_parental' => [
'title' => [
'fr' => 'Soutien parental'
],
// 'action' => 'social_action_protection_enfant', (via le goal)
'goal' => 'social_goal_proteger'
],
'social_result_accompagnement_mineur' => [
'title' => [
'fr' => 'Accompagnement du mineur'
],
// 'action' => 'social_action_protection_enfant', (via le goal)
'goal' => 'social_goal_proteger',
],
];
public function load(ObjectManager $manager)
{
foreach (static::$socialResults as $ref => $new) {
$socialResult = new Result();
$socialResult->setTitle($new['title']);
if ( array_key_exists('action', $new)) {
$action = $this->getReference($new['action']);
$socialResult->addSocialAction($action);
}
if ( array_key_exists('goal', $new)) {
$goal = $this->getReference($new['goal']);
$socialResult->addGoal($goal);
}
$manager->persist($socialResult);
$this->addReference($ref, $socialResult);
print("Adding SocialResult '".$new['title']['fr']."'\n");
}
$manager->flush();
}
}

View File

@ -73,9 +73,11 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
$loader->load('services/command.yaml');
$loader->load('services/actions.yaml');
$loader->load('services/form.yaml');
$loader->load('services/repository.yaml');
$loader->load('services/templating.yaml');
$loader->load('services/alt_names.yaml');
// We can get rid of this file when the service 'chill.person.repository.person' is no more used.
// We should use the PersonRepository service instead of a custom service name.
$loader->load('services/repository.yaml');
$loader->load('services/serializer.yaml');
$loader->load('services/security.yaml');

View File

@ -37,7 +37,7 @@ use Chill\MainBundle\Entity\User;
/**
* AccompanyingPeriod Class
*
* @ORM\Entity(repositoryClass="Chill\PersonBundle\Repository\AccompanyingPeriodRepository")
* @ORM\Entity
* @ORM\Table(name="chill_person_accompanying_period")
*/
class AccompanyingPeriod
@ -344,12 +344,13 @@ class AccompanyingPeriod
*/
public function getParticipationsContainsPerson(Person $person): Collection
{
return $this->getParticipations($person)->filter(
function(AccompanyingPeriodParticipation $participation) use ($person) {
if ($person === $participation->getPerson()) {
return $participation;
return $this
->getParticipations()
->filter(
static function(AccompanyingPeriodParticipation $participation) use ($person): bool {
return $person === $participation->getPerson();
}
});
);
}
/**
@ -359,12 +360,13 @@ class AccompanyingPeriod
*/
public function getOpenParticipationContainsPerson(Person $person): ?AccompanyingPeriodParticipation
{
$collection = $this->getParticipationsContainsPerson($person)->filter(
function(AccompanyingPeriodParticipation $participation) use ($person) {
if (NULL === $participation->getEndDate()) {
return $participation;
$collection = $this
->getParticipationsContainsPerson($person)
->filter(
static function(AccompanyingPeriodParticipation $participation): bool {
return null === $participation->getEndDate();
}
});
);
return $collection->count() > 0 ? $collection->first() : NULL;
}
@ -429,15 +431,16 @@ class AccompanyingPeriod
return false;
}
$participation = $this->participationsContainsPerson($person);
if (!null === $participation)
$participation = $this->getOpenParticipationContainsPerson($person);
if (null === $participation)
{
$person = $participation->getPerson();
$periods = $person->getAccompanyingPeriodsOrdered();
return end($periods) === $this;
return false;
}
return false;
$periods = $participation->getPerson()->getAccompanyingPeriodsOrdered();
return end($periods) === $this;
}
/**
@ -646,11 +649,15 @@ class AccompanyingPeriod
/**
* Get a list of all persons which are participating to this course
*
* @psalm-return Collection<int, Person>
*/
public function getPersons(): Collection
{
return $this->participations->map(
function(AccompanyingPeriodParticipation $participation) {
return $this
->participations
->map(
static function(AccompanyingPeriodParticipation $participation): Person {
return $participation->getPerson();
}
);

View File

@ -4,7 +4,6 @@ namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\SocialWork\Result;
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkRepository;
use Chill\MainBundle\Entity\User;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
@ -13,7 +12,7 @@ use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=AccompanyingPeriodWorkRepository::class)
* @ORM\Entity
* @ORM\Table(name="chill_person_accompanying_period_work")
*/
class AccompanyingPeriodWork

View File

@ -4,13 +4,12 @@ namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\SocialWork\Goal;
use Chill\PersonBundle\Entity\SocialWork\Result;
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkGoalRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=AccompanyingPeriodWorkGoalRepository::class)
* @ORM\Entity
* @ORM\Table(name="chill_person_accompanying_period_work_goal")
*/
class AccompanyingPeriodWorkGoal

View File

@ -29,8 +29,7 @@ use Doctrine\Common\Collections\ArrayCollection;
/**
* ClosingMotive give an explanation why we closed the Accompanying period
*
* @ORM\Entity(
* repositoryClass="Chill\PersonBundle\Repository\AccompanyingPeriod\ClosingMotiveRepository")
* @ORM\Entity
* @ORM\Table(name="chill_person_accompanying_period_closingmotive")
*/
class ClosingMotive

View File

@ -22,13 +22,12 @@
namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Repository\AccompanyingPeriod\CommentRepository;
use Chill\MainBundle\Entity\User;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=CommentRepository::class)
* @ORM\Entity
* @ORM\Table(name="chill_person_accompanying_period_comment")
*/
class Comment

View File

@ -22,11 +22,10 @@
namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Repository\AccompanyingPeriod\OriginRepository;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=OriginRepository::class)
* @ORM\Entity
* @ORM\Table(name="chill_person_accompanying_period_origin")
*/
class Origin

View File

@ -22,7 +22,6 @@
namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Repository\AccompanyingPeriod\ResourceRepository;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\AccompanyingPeriod\Comment;
use Chill\PersonBundle\Entity\Person;
@ -30,7 +29,7 @@ use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=ResourceRepository::class)
* @ORM\Entity
* @ORM\Table(name="chill_person_accompanying_period_resource")
*/
class Resource

View File

@ -22,7 +22,6 @@
namespace Chill\PersonBundle\Entity;
use Chill\PersonBundle\Repository\AccompanyingPeriodParticipationRepository;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\Person;
use Doctrine\ORM\Mapping as ORM;
@ -31,7 +30,7 @@ use Doctrine\ORM\Mapping as ORM;
* AccompanyingPeriodParticipation Class
*
* @package Chill\PersonBundle\Entity
* @ORM\Entity(repositoryClass=AccompanyingPeriodParticipationRepository::class)
* @ORM\Entity
* @ORM\Table(name="chill_person_accompanying_period_participation")
*/
class AccompanyingPeriodParticipation

View File

@ -2,13 +2,12 @@
namespace Chill\PersonBundle\Entity\Household;
use Chill\PersonBundle\Repository\Household\HouseholdRepository;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\Collection;
use Chill\MainBundle\Entity\Address;
/**
* @ORM\Entity(repositoryClass=HouseholdRepository::class)
* @ORM\Entity
*/
class Household
{

View File

@ -3,12 +3,11 @@
namespace Chill\PersonBundle\Entity\Household;
use Doctrine\ORM\Mapping as ORM;
use Chill\PersonBundle\Repository\Household\HouseholdMembersRepository;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Entity\Household\Household;
/**
* @ORM\Entity(repositoryClass=HouseholdMembersRepository::class)
* @ORM\Entity
*/
class HouseholdMembers
{

View File

@ -25,7 +25,7 @@ use Doctrine\ORM\Mapping as ORM;
/**
* MaritalStatus
*
* @ORM\Entity()
* @ORM\Entity
* @ORM\Table(name="chill_person_marital_status")
* @ORM\HasLifecycleCallbacks()
*/

View File

@ -38,7 +38,7 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface;
/**
* Person Class
*
* @ORM\Entity(repositoryClass="Chill\PersonBundle\Repository\PersonRepository")
* @ORM\Entity
* @ORM\Table(name="chill_person_person",
* indexes={@ORM\Index(
* name="person_names",

View File

@ -8,7 +8,7 @@ use Doctrine\ORM\Mapping as ORM;
* PersonAltName
*
* @ORM\Table(name="chill_person_alt_name")
* @ORM\Entity(repositoryClass="Chill\PersonBundle\Repository\PersonAltNameRepository")
* @ORM\Entity
*/
class PersonAltName
{

View File

@ -9,7 +9,7 @@ use Chill\MainBundle\Entity\User;
* PersonNotDuplicate
*
* @ORM\Table(name="chill_person_not_duplicate")
* @ORM\Entity(repositoryClass="Chill\PersonBundle\Repository\PersonNotDuplicateRepository")
* @ORM\Entity
*/
class PersonNotDuplicate
{

View File

@ -8,7 +8,7 @@ use Doctrine\ORM\Mapping as ORM;
/**
* Person Phones
*
* @ORM\Entity()
* @ORM\Entity
* @ORM\Table(name="chill_person_phone")
*/
class PersonPhone

View File

@ -2,11 +2,10 @@
namespace Chill\PersonBundle\Entity\SocialWork;
use Chill\PersonBundle\Repository\SocialWork\EvaluationRepository;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=EvaluationRepository::class)
* @ORM\Entity
* @ORM\Table(name="chill_person_social_work_evaluation")
*/
class Evaluation

View File

@ -2,13 +2,12 @@
namespace Chill\PersonBundle\Entity\SocialWork;
use Chill\PersonBundle\Repository\SocialWork\GoalRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=GoalRepository::class)
* @ORM\Entity
* @ORM\Table(name="chill_person_social_work_goal")
*/
class Goal

View File

@ -4,13 +4,12 @@ namespace Chill\PersonBundle\Entity\SocialWork;
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork;
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkGoal;
use Chill\PersonBundle\Repository\SocialWork\ResultRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=ResultRepository::class)
* @ORM\Entity
* @ORM\Table(name="chill_person_social_work_result")
*/
class Result

View File

@ -2,13 +2,12 @@
namespace Chill\PersonBundle\Entity\SocialWork;
use Chill\PersonBundle\Repository\SocialWork\SocialActionRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=SocialActionRepository::class)
* @ORM\Entity
* @ORM\Table(name="chill_person_social_action")
*/
class SocialAction

View File

@ -1,14 +1,12 @@
<?php
namespace Chill\PersonBundle\Entity\SocialWork;
use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=SocialIssueRepository::class)
* @ORM\Entity
* @ORM\Table(name="chill_person_social_issue")
*/
class SocialIssue

View File

@ -33,9 +33,10 @@ use Chill\MainBundle\Form\Type\DataTransformer\CenterTransformer;
use Chill\PersonBundle\Config\ConfigPersonAltNamesHelper;
use Chill\PersonBundle\Form\Type\PersonAltNameType;
class CreationPersonType extends AbstractType
final class CreationPersonType extends AbstractType
{
// TODO: This is only used in test.
// TODO: See if this is still valid and update accordingly.
const NAME = 'chill_personbundle_person_creation';
const FORM_NOT_REVIEWED = 'not_reviewed';

View File

@ -3,8 +3,8 @@
namespace Chill\PersonBundle\Repository\AccompanyingPeriod;
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkGoal;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
/**
* @method AccompanyingPeriodWorkGoal|null find($id, $lockMode = null, $lockVersion = null)
@ -12,10 +12,12 @@ use Doctrine\Persistence\ManagerRegistry;
* @method AccompanyingPeriodWorkGoal[] findAll()
* @method AccompanyingPeriodWorkGoal[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class AccompanyingPeriodWorkGoalRepository extends ServiceEntityRepository
final class AccompanyingPeriodWorkGoalRepository
{
public function __construct(ManagerRegistry $registry)
private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager)
{
parent::__construct($registry, AccompanyingPeriodWorkGoal::class);
$this->repository = $entityManager->getRepository(AccompanyingPeriodWorkGoal::class);
}
}

View File

@ -3,8 +3,8 @@
namespace Chill\PersonBundle\Repository\AccompanyingPeriod;
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
/**
* @method AccompanyingPeriodWork|null find($id, $lockMode = null, $lockVersion = null)
@ -12,10 +12,12 @@ use Doctrine\Persistence\ManagerRegistry;
* @method AccompanyingPeriodWork[] findAll()
* @method AccompanyingPeriodWork[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class AccompanyingPeriodWorkRepository extends ServiceEntityRepository
final class AccompanyingPeriodWorkRepository
{
public function __construct(ManagerRegistry $registry)
private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager)
{
parent::__construct($registry, AccompanyingPeriodWork::class);
$this->repository = $entityManager->getRepository(AccompanyingPeriodWork::class);
}
}

View File

@ -22,8 +22,9 @@
namespace Chill\PersonBundle\Repository\AccompanyingPeriod;
use Chill\PersonBundle\Entity\AccompanyingPeriod\ClosingMotive;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder;
use Doctrine\ORM\Query\ResultSetMappingBuilder;
/**
@ -32,16 +33,23 @@ use Doctrine\ORM\Query\ResultSetMappingBuilder;
*
* @package Chill\PersonBundle\Repository
*/
class ClosingMotiveRepository extends EntityRepository
final class ClosingMotiveRepository
{
private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager)
{
$this->repository = $entityManager->getRepository(ClosingMotive::class);
}
/**
* @param bool $onlyLeaf
* @return mixed
*/
public function getActiveClosingMotive(bool $onlyLeaf = true)
{
$rsm = new ResultSetMappingBuilder($this->getEntityManager());
$rsm->addRootEntityFromClassMetadata($this->getClassName(), 'cm');
$rsm = new ResultSetMappingBuilder($this->repository->getEntityManager());
$rsm->addRootEntityFromClassMetadata($this->repository->getClassName(), 'cm');
$sql = "SELECT ".(string) $rsm."
FROM chill_person_accompanying_period_closingmotive AS cm
@ -56,9 +64,10 @@ class ClosingMotiveRepository extends EntityRepository
$sql .= " ORDER BY cm.ordering ASC";
return $this->_em
return $this
->repository
->getEntityManager()
->createNativeQuery($sql, $rsm)
->getResult()
;
->getResult();
}
}

View File

@ -23,8 +23,8 @@
namespace Chill\PersonBundle\Repository\AccompanyingPeriod;
use Chill\PersonBundle\Entity\AccompanyingPeriod\Comment;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
/**
* @method Comment|null find($id, $lockMode = null, $lockVersion = null)
@ -32,11 +32,12 @@ use Doctrine\Persistence\ManagerRegistry;
* @method Comment[] findAll()
* @method Comment[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class CommentRepository extends ServiceEntityRepository
final class CommentRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Comment::class);
}
private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager)
{
$this->repository = $entityManager->getRepository(Comment::class);
}
}

View File

@ -23,8 +23,8 @@
namespace Chill\PersonBundle\Repository\AccompanyingPeriod;
use Chill\PersonBundle\Entity\AccompanyingPeriod\Origin;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
/**
* @method Origin|null find($id, $lockMode = null, $lockVersion = null)
@ -32,11 +32,12 @@ use Doctrine\Persistence\ManagerRegistry;
* @method Origin[] findAll()
* @method Origin[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class OriginRepository extends ServiceEntityRepository
final class OriginRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Origin::class);
}
private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager)
{
$this->repository = $entityManager->getRepository(Origin::class);
}
}

View File

@ -23,8 +23,8 @@
namespace Chill\PersonBundle\Repository\AccompanyingPeriod;
use Chill\PersonBundle\Entity\AccompanyingPeriod\Resource;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
/**
* @method Resource|null find($id, $lockMode = null, $lockVersion = null)
@ -32,11 +32,12 @@ use Doctrine\Persistence\ManagerRegistry;
* @method Resource[] findAll()
* @method Resource[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class ResourceRepository extends ServiceEntityRepository
final class ResourceRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Resource::class);
}
private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager)
{
$this->repository = $entityManager->getRepository(Resource::class);
}
}

View File

@ -23,8 +23,8 @@
namespace Chill\PersonBundle\Repository;
use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
/**
* @method AccompanyingPeriodParticipation|null find($id, $lockMode = null, $lockVersion = null)
@ -32,11 +32,12 @@ use Doctrine\Persistence\ManagerRegistry;
* @method AccompanyingPeriodParticipation[] findAll()
* @method AccompanyingPeriodParticipation[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class AccompanyingPeriodParticipationRepository extends ServiceEntityRepository
final class AccompanyingPeriodParticipationRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, AccompanyingPeriodParticipation::class);
}
private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager)
{
$this->repository = $entityManager->getRepository(AccompanyingPeriodParticipation::class);
}
}

View File

@ -23,9 +23,8 @@
namespace Chill\PersonBundle\Repository;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\Person;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
/**
* @method AccompanyingPeriod|null find($id, $lockMode = null, $lockVersion = null)
@ -33,10 +32,12 @@ use Doctrine\Persistence\ManagerRegistry;
* @method AccompanyingPeriod[] findAll()
* @method AccompanyingPeriod[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class AccompanyingPeriodRepository extends ServiceEntityRepository
final class AccompanyingPeriodRepository
{
public function __construct(ManagerRegistry $registry)
private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager)
{
parent::__construct($registry, AccompanyingPeriod::class);
$this->repository = $entityManager->getRepository(AccompanyingPeriod::class);
}
}

View File

@ -3,8 +3,8 @@
namespace Chill\PersonBundle\Repository\Household;
use Chill\PersonBundle\Entity\Household\HouseholdMembers;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
/**
* @method HouseholdMembers|null find($id, $lockMode = null, $lockVersion = null)
@ -12,11 +12,13 @@ use Doctrine\Persistence\ManagerRegistry;
* @method HouseholdMembers[] findAll()
* @method HouseholdMembers[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class HouseholdMembersRepository extends ServiceEntityRepository
final class HouseholdMembersRepository
{
public function __construct(ManagerRegistry $registry)
private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager)
{
parent::__construct($registry, HouseholdMembers::class);
$this->repository = $entityManager->getRepository(HouseholdMembers::class);
}
// /**

View File

@ -3,8 +3,8 @@
namespace Chill\PersonBundle\Repository\Household;
use Chill\PersonBundle\Entity\Household\Household;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
/**
* @method Household|null find($id, $lockMode = null, $lockVersion = null)
@ -12,11 +12,13 @@ use Doctrine\Persistence\ManagerRegistry;
* @method Household[] findAll()
* @method Household[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class HouseholdRepository extends ServiceEntityRepository
final class HouseholdRepository
{
public function __construct(ManagerRegistry $registry)
private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager)
{
parent::__construct($registry, Household::class);
$this->repository = $entityManager->getRepository(Household::class);
}
// /**

View File

@ -2,12 +2,22 @@
namespace Chill\PersonBundle\Repository;
use Chill\PersonBundle\Entity\PersonAltName;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
/**
* PersonAltNameRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class PersonAltNameRepository extends \Doctrine\ORM\EntityRepository
final class PersonAltNameRepository
{
private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager)
{
$this->repository = $entityManager->getRepository(PersonAltName::class);
}
}

View File

@ -4,6 +4,7 @@ namespace Chill\PersonBundle\Repository;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Entity\PersonNotDuplicate;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
/**
@ -11,8 +12,15 @@ use Doctrine\ORM\EntityRepository;
*
* @package Chill\PersonBundle\Repository
*/
class PersonNotDuplicateRepository extends EntityRepository
final class PersonNotDuplicateRepository
{
private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager)
{
$this->repository = $entityManager->getRepository(PersonNotDuplicate::class);
}
/**
* @param \Chill\PersonBundle\Entity\Person $person
*
@ -20,7 +28,7 @@ class PersonNotDuplicateRepository extends EntityRepository
*/
public function findNotDuplicatePerson(Person $person)
{
$qb = $this->createQueryBuilder('pnd');
$qb = $this->repository->createQueryBuilder('pnd');
$qb->select('pnd')
->where('pnd.person1 = :person OR pnd.person2 = :person')
;

View File

@ -18,16 +18,25 @@
namespace Chill\PersonBundle\Repository;
use Chill\PersonBundle\Entity\Person;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder;
/**
* Class PersonRepository
*
* @package Chill\PersonBundle\Repository
*/
class PersonRepository extends EntityRepository
final class PersonRepository
{
private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager)
{
$this->repository = $entityManager->getRepository(Person::class);
}
public function find($id, $lockMode = null, $lockVersion = null)
{
return $this->repository->find($id, $lockMode, $lockVersion);
}
/**
* @param string $phonenumber
* @param $centers
@ -44,7 +53,7 @@ class PersonRepository extends EntityRepository
$maxResults,
array $only = ['mobile', 'phone']
) {
$qb = $this->createQueryBuilder('p');
$qb = $this->repository->createQueryBuilder('p');
$qb->select('p');
$this->addByCenters($qb, $centers);
@ -71,7 +80,7 @@ class PersonRepository extends EntityRepository
array $only = ['mobile', 'phone']
): int
{
$qb = $this->createQueryBuilder('p');
$qb = $this->repository->createQueryBuilder('p');
$qb->select('COUNT(p)');
$this->addByCenters($qb, $centers);

View File

@ -3,8 +3,8 @@
namespace Chill\PersonBundle\Repository\SocialWork;
use Chill\PersonBundle\Entity\SocialWork\Evaluation;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
/**
* @method Evaluation|null find($id, $lockMode = null, $lockVersion = null)
@ -12,10 +12,12 @@ use Doctrine\Persistence\ManagerRegistry;
* @method Evaluation[] findAll()
* @method Evaluation[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class EvaluationRepository extends ServiceEntityRepository
final class EvaluationRepository
{
public function __construct(ManagerRegistry $registry)
private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager)
{
parent::__construct($registry, Evaluation::class);
$this->repository = $entityManager->getRepository(Evaluation::class);
}
}

View File

@ -3,8 +3,8 @@
namespace Chill\PersonBundle\Repository\SocialWork;
use Chill\PersonBundle\Entity\SocialWork\Goal;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
/**
* @method Goal|null find($id, $lockMode = null, $lockVersion = null)
@ -12,10 +12,12 @@ use Doctrine\Persistence\ManagerRegistry;
* @method Goal[] findAll()
* @method Goal[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class GoalRepository extends ServiceEntityRepository
final class GoalRepository
{
public function __construct(ManagerRegistry $registry)
private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager)
{
parent::__construct($registry, Goal::class);
$this->repository = $entityManager->getRepository(Goal::class);
}
}

View File

@ -3,8 +3,8 @@
namespace Chill\PersonBundle\Repository\SocialWork;
use Chill\PersonBundle\Entity\SocialWork\Result;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
/**
* @method Result|null find($id, $lockMode = null, $lockVersion = null)
@ -12,10 +12,12 @@ use Doctrine\Persistence\ManagerRegistry;
* @method Result[] findAll()
* @method Result[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class ResultRepository extends ServiceEntityRepository
final class ResultRepository
{
public function __construct(ManagerRegistry $registry)
private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager)
{
parent::__construct($registry, Result::class);
$this->repository = $entityManager->getRepository(Result::class);
}
}

View File

@ -3,8 +3,8 @@
namespace Chill\PersonBundle\Repository\SocialWork;
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
/**
* @method SocialAction|null find($id, $lockMode = null, $lockVersion = null)
@ -12,10 +12,12 @@ use Doctrine\Persistence\ManagerRegistry;
* @method SocialAction[] findAll()
* @method SocialAction[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class SocialActionRepository extends ServiceEntityRepository
final class SocialActionRepository
{
public function __construct(ManagerRegistry $registry)
private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager)
{
parent::__construct($registry, SocialAction::class);
$this->repository = $entityManager->getRepository(SocialAction::class);
}
}

View File

@ -4,7 +4,8 @@ namespace Chill\PersonBundle\Repository\SocialWork;
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
/**
* @method SocialIssue|null find($id, $lockMode = null, $lockVersion = null)
@ -12,10 +13,12 @@ use Doctrine\Persistence\ManagerRegistry;
* @method SocialIssue[] findAll()
* @method SocialIssue[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class SocialIssueRepository extends ServiceEntityRepository
final class SocialIssueRepository
{
public function __construct(ManagerRegistry $registry)
private EntityRepository $repository;
public function __construct(EntityManagerInterface $entityManager)
{
parent::__construct($registry, SocialIssue::class);
$this->repository = $entityManager->getRepository(SocialIssue::class);
}
}

View File

@ -1,45 +0,0 @@
<template>
<accompanying-course v-bind:accompanying_course="accompanying_course"/>
<persons-associated v-bind:persons_associated="accompanying_course.persons"/>
<requestor v-bind:accompanying_course="accompanying_course"/>
</template>
<script>
import AccompanyingCourse from './components/AccompanyingCourse.vue';
import PersonsAssociated from './components/PersonsAssociated.vue';
import Requestor from './components/Requestor.vue';
export default {
name: 'App',
components: {
AccompanyingCourse,
PersonsAssociated,
Requestor
},
data() {
return {
accompanying_course: {}
};
},
computed: {
accompanyingCourseId() {
return window.accompanyingCourseId;
}
},
methods: {
async getAccompanyingCourse() {
let data_;
return fetch(`/fr/api/parcours/${accompanyingCourseId}/show`)
.then(response => response.json())
.then(data => {
this.$data.accompanying_course = data;
});
}
},
async mounted() {
await this.getAccompanyingCourse();
}
};
</script>
<style scoped></style>

View File

@ -1,26 +0,0 @@
<template>
<div class="vue-component">
<h3>Parcours</h3>
<dl>
<dt>id</dt>
<dd>{{ accompanying_course.id }}</dd>
<dt>opening_date</dt>
<dd>{{ accompanying_course.opening_date }}</dd>
<dt>closing_date</dt>
<dd>{{ accompanying_course.closing_date }}</dd>
<dt>remark</dt>
<dd>{{ accompanying_course.remark }}</dd>
<dt>closing_motive</dt>
<dd>{{ accompanying_course.closing_motive }}</dd>
</dl>
</div>
</template>
<script>
export default {
name: 'AccompanyingCourse',
props: {
accompanying_course: Object
}
}
</script>

View File

@ -1,25 +0,0 @@
<template>
<tr>
<td>{{ person.firstname }}</td>
<td>{{ person.lastname }}</td>
<td>{{ person.startdate }}</td>
<td>{{ person.enddate }}</td>
<td>
<ul class="record_actions">
<li><button class="sc-button bt-show"></button></li>
<li><button class="sc-button bt-update"></button></li>
<li><button class="sc-button bt-delete" @click.prevent="$emit('remove', person)"></button></li>
</ul>
</td>
</tr>
</template>
<script>
export default {
name: 'PersonItem',
props: {
person: { type: Object, required: true }
},
emits: ['remove']
}
</script>

View File

@ -1,69 +0,0 @@
<template>
<div class="vue-component">
<h3>Usagers concernés</h3>
<label>{{ counter }} usagers</label>
<table class="rounded">
<thead>
<tr>
<th class="chill-orange">firstname</th>
<th class="chill-orange">lastname</th>
<th class="chill-orange">startdate</th>
<th class="chill-orange">enddate</th>
<th class="chill-orange">actions</th>
</tr>
</thead>
<tbody>
<person-item
v-for="person in persons_associated"
v-bind:person="person"
v-bind:key="person.id"
@remove="removePerson" />
</tbody>
</table>
<ul class="record_actions">
<li><button class="sc-button bt-create" @click="addPerson">Ajouter un usager</button></li>
</ul>
</div>
</template>
<script>
import PersonItem from "./PersonItem.vue"
export default {
name: 'PersonsAssociated',
components: {
PersonItem
},
props: {
persons_associated: Array
},
data() {
return {
persons: this.persons_associated
}
},
computed: {
async counter() {
// Pourquoi je peux pas compter un tableau avec length ???!!!
return this.persons_associated.length // <= boum !
}
},
methods: {
addPerson() {
this.persons_associated.push({
"firstname": "Lisa",
"lastname": "Simpson",
"startdate": "1975-09-15",
"enddate": "2021-04-20"
})
},
removePerson(item) {
this.persons_associated = this.persons_associated.filter(person => person !== item)
}
}
}
</script>

View File

@ -1,16 +0,0 @@
<template>
<div class="vue-component">
<h3>Demandeur</h3>
{{ accompanying_course.id }}
{{ accompanying_course.remark }}
</div>
</template>
<script>
export default {
name: 'Requestor',
props: {
accompanying_course: Object
}
}
</script>

View File

@ -1,8 +0,0 @@
import App from './App.vue';
import { createApp } from 'vue';
const app = createApp({
template: `<app></app>`
})
.component('app', App)
.mount('#accompanying-course');

View File

@ -0,0 +1,25 @@
<template>
<accompanying-course></accompanying-course>
<persons-associated></persons-associated>
<requestor></requestor>
</template>
<script>
import { mapState } from 'vuex'
import AccompanyingCourse from './components/AccompanyingCourse.vue';
import PersonsAssociated from './components/PersonsAssociated.vue';
import Requestor from './components/Requestor.vue';
export default {
name: 'App',
components: {
AccompanyingCourse,
PersonsAssociated,
Requestor
},
computed: mapState([
'accompanyingCourse'
])
};
</script>

View File

@ -0,0 +1,49 @@
const
locale = 'fr',
format = 'json'
, accompanying_period_id = window.accompanyingCourseId //tmp
;
/*
* Endpoint chill_person_accompanying_course_api_show
* method GET, get AccompanyingCourse Object
*
* @accompanying_period_id___ integer
* @TODO var is not used but necessary in method signature
*/
let getAccompanyingCourse = (accompanying_period_id___) => { //tmp
const url = `/${locale}/person/api/1.0/accompanying-course/${accompanying_period_id}/show.${format}`;
return fetch(url)
.then(response => {
if (response.ok) { return response.json(); }
throw Error('Error with request resource response');
});
};
/*
* Endpoint chill_person_accompanying_course_api_add_participation,
* method POST/DELETE, add/close a participation to the accompanyingCourse
*
* @accompanying_period_id integer - id of accompanyingCourse
* @person_id integer - id of person
* @method string - POST or DELETE
*/
let postParticipation = (accompanying_period_id, person_id, method) => {
const url = `/${locale}/person/api/1.0/accompanying-course/${accompanying_period_id}/participation.${format}`
return fetch(url, {
method: method,
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
body: JSON.stringify({id: person_id})
})
.then(response => {
if (response.ok) { return response.json(); }
throw Error('Error with request resource response');
});
};
export {
getAccompanyingCourse,
postParticipation
};

View File

@ -0,0 +1,28 @@
<template>
<div class="vue-component">
<h3>{{ $t('course.title') }}</h3>
<dl>
<dt>{{ $t('course.id') }}</dt>
<dd>{{ accompanyingCourse.id }}</dd>
<dt>{{ $t('course.opening_date') }}</dt>
<dd>{{ $d(accompanyingCourse.openingDate.datetime, 'short') }}</dd>
<dt>{{ $t('course.closing_date') }}</dt>
<dd>{{ $d(accompanyingCourse.closingDate.datetime, 'short') }}</dd>
<dt>{{ $t('course.remark') }}</dt>
<dd>{{ accompanyingCourse.remark }}</dd>
<dt>{{ $t('course.closing_motive') }}</dt>
<dd>{{ accompanyingCourse.closing_motive }}</dd>
</dl>
</div>
</template>
<script>
export default {
name: 'AccompanyingCourse',
computed: {
accompanyingCourse() {
return this.$store.state.accompanyingCourse
}
}
}
</script>

View File

@ -0,0 +1,56 @@
<template>
<tr>
<td>{{ participation.person.firstName }}</td>
<td>{{ participation.person.lastName }}</td>
<td><span v-if="participation.startDate">
{{ $d(participation.startDate.datetime, 'short') }}</span>
</td>
<td><span v-if="participation.endDate">
{{ $d(participation.endDate.datetime, 'short') }}</span>
</td>
<td>
<ul class="record_actions">
<li>
<a class="sc-button bt-show" target="_blank"
:href="url.show"
:title="$t('action.show')">
</a>
</li>
<li>
<a class="sc-button bt-update" target="_blank"
:href="url.edit"
:title="$t('action.edit')">
</a>
</li>
<!--li>
<button class="sc-button bt-delete"
:title="$t('action.delete')"
@click.prevent="$emit('remove', participation)">
</button>
</li-->
<li>
<button class="sc-button bt-remove"
:title="$t('action.remove')"
@click.prevent="$emit('close', participation)">
</button>
</li>
</ul>
</td>
</tr>
</template>
<script>
export default {
name: 'PersonItem',
props: ['participation'],
data() {
return {
url: {
show: '/fr/person/' + this.participation.person.id + '/general',
edit: '/fr/person/' + this.participation.person.id + '/general/edit'
}
}
},
emits: ['remove', 'close']
}
</script>

View File

@ -0,0 +1,66 @@
<template>
<div class="vue-component">
<h3>{{ $t('persons_associated.title')}}</h3>
<label>{{ $tc('persons_associated.counter', counter) }}</label>
<table class="rounded">
<thead>
<tr>
<th class="chill-orange">{{ $t('persons_associated.firstname') }}</th>
<th class="chill-orange">{{ $t('persons_associated.lastname') }}</th>
<th class="chill-orange">{{ $t('persons_associated.startdate') }}</th>
<th class="chill-orange">{{ $t('persons_associated.enddate') }}</th>
<th class="chill-orange">{{ $t('action.actions') }}</th>
</tr>
</thead>
<tbody>
<person-item
v-for="participation in participations"
v-bind:participation="participation"
v-bind:key="participation.id"
@remove="removeParticipation"
@close="closeParticipation">
</person-item>
</tbody>
</table>
<add-persons></add-persons>
<ul class="record_actions">
<!--li>
<button class="sc-button orange" @click="savePersons">
{{ $t('action.save') }}
</button>
</li-->
</ul>
</div>
</template>
<script>
import { mapState } from 'vuex';
import PersonItem from "./PersonItem.vue"
import AddPersons from 'ChillPersonAssets/vuejs/_components/AddPersons.vue'
export default {
name: 'PersonsAssociated',
components: {
PersonItem,
AddPersons
},
computed: mapState({
participations: state => state.accompanyingCourse.participations,
counter: state => state.accompanyingCourse.participations.length
}),
methods: {
removeParticipation(item) {
this.$store.dispatch('removeParticipation', item)
},
closeParticipation(item) {
console.log('@@ CLICK close participation: item', item);
this.$store.dispatch('closeParticipation', item)
},
/*
savePersons() {
console.log('[wip] saving persons');
}
*/
}
}
</script>

View File

@ -0,0 +1,86 @@
<template>
<div class="vue-component">
<h3>{{ $t('requestor.title') }}</h3>
{{ accompanyingCourse.id }}
{{ accompanyingCourse.remark }}<br><br>
<!-- TESTS AREA -->
<ul class="record_actions">
<li>
<button class="sc-button bt-create" @click="modal1.showModal = true">
{{ $t('action.show_modal') }}
</button>
</li>
<li>
<button class="sc-button bt-create" @click="modal2.showModal = true">
Ouvrir une seconde modale
</button>
</li>
</ul>
<teleport to="body">
<modal v-if="modal1.showModal" :modalDialogClass="modal1.modalDialogClass" @close="modal1.showModal = false">
<template v-slot:header>
<h3 class="modal-title">Le titre de ma modale</h3>
</template>
<template v-slot:body>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus luctus facilisis suscipit. Cras pulvinar, purus sagittis pulvinar porta, enim ex posuere lacus, in pulvinar lectus magna in odio. Nullam iaculis congue lorem ac suscipit. Proin ut rutrum augue. Ut vehicula risus nec hendrerit ullamcorper. Ut volutpat eu mi eget viverra. Morbi dictum placerat suscipit. </p>
<p>Quisque non erat tincidunt, lacinia justo ut, pulvinar nisl. Nunc id enim ut sem pretium interdum consectetur eu quam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Etiam posuere erat eget augue finibus luctus. Maecenas auctor, tortor non luctus ultrices, neque neque porttitor ex, nec lacinia lorem ligula et elit. Sed tempor nulla vitae lorem sollicitudin dictum. Vestibulum nec arcu eget elit pulvinar pretium. Phasellus facilisis metus sed diam luctus, feugiat scelerisque velit dignissim.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus luctus facilisis suscipit. Cras pulvinar, purus sagittis pulvinar porta, enim ex posuere lacus, in pulvinar lectus magna in odio. Nullam iaculis congue lorem ac suscipit. Proin ut rutrum augue. Ut vehicula risus nec hendrerit ullamcorper. Ut volutpat eu mi eget viverra. Morbi dictum placerat suscipit. </p>
<p>Quisque non erat tincidunt, lacinia justo ut, pulvinar nisl. Nunc id enim ut sem pretium interdum consectetur eu quam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Etiam posuere erat eget augue finibus luctus. Maecenas auctor, tortor non luctus ultrices, neque neque porttitor ex, nec lacinia lorem ligula et elit. Sed tempor nulla vitae lorem sollicitudin dictum. Vestibulum nec arcu eget elit pulvinar pretium. Phasellus facilisis metus sed diam luctus, feugiat scelerisque velit dignissim.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus luctus facilisis suscipit. Cras pulvinar, purus sagittis pulvinar porta, enim ex posuere lacus, in pulvinar lectus magna in odio. Nullam iaculis congue lorem ac suscipit. Proin ut rutrum augue. Ut vehicula risus nec hendrerit ullamcorper. Ut volutpat eu mi eget viverra. Morbi dictum placerat suscipit. </p>
<p>Quisque non erat tincidunt, lacinia justo ut, pulvinar nisl. Nunc id enim ut sem pretium interdum consectetur eu quam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Etiam posuere erat eget augue finibus luctus. Maecenas auctor, tortor non luctus ultrices, neque neque porttitor ex, nec lacinia lorem ligula et elit. Sed tempor nulla vitae lorem sollicitudin dictum. Vestibulum nec arcu eget elit pulvinar pretium. Phasellus facilisis metus sed diam luctus, feugiat scelerisque velit dignissim.</p>
</template>
<template v-slot:footer>
<button class="sc-button green" @click="modal1.showModal = false; modal2.showModal = true">
{{ $t('action.next')}}</button>
</template>
</modal>
</teleport>
<teleport to="body">
<modal v-if="modal2.showModal" :modalDialogClass="modal2.modalDialogClass" @close="modal2.showModal = false">
<template v-slot:header>
<h3 class="modal-title">Une autre modale</h3>
</template>
<template v-slot:body>
<p>modal 2</p>
</template>
<template v-slot:footer>
<button class="sc-button green" @click="modal2.showModal = false">
{{ $t('action.save')}}</button>
</template>
</modal>
</teleport>
<!-- END TESTS -->
</div>
</template>
<script>
import Modal from 'ChillMainAssets/vuejs/_components/Modal'
export default {
name: 'Requestor',
components: {
Modal,
},
data() {
return {
modal1: {
showModal: false,
modalDialogClass: "modal-dialog-scrollable modal-xl" // modal-lg modal-md modal-sm
},
modal2: {
showModal: false,
modalDialogClass: "modal-dialog-centered modal-sm" // modal-lg modal-md modal-sm
}
}
},
computed: {
accompanyingCourse() {
return this.$store.state.accompanyingCourse
}
}
}
</script>

View File

@ -0,0 +1,23 @@
import { createApp } from 'vue'
import { _createI18n } from 'ChillMainAssets/vuejs/_js/i18n'
import { appMessages } from './js/i18n'
import { initPromise } from './store'
import App from './App.vue';
initPromise.then(store => {
//console.log('store in create_store', store);
//console.log('store accompanyingCourse', store.state.accompanyingCourse);
const i18n = _createI18n(appMessages);
const app = createApp({
template: `<app></app>`,
})
.use(store)
.use(i18n)
.component('app', App)
.mount('#accompanying-course');
});

View File

@ -0,0 +1,32 @@
import { personMessages } from 'ChillPersonAssets/vuejs/_js/i18n'
const appMessages = {
fr: {
course: {
id: "id",
title: "Parcours",
opening_date: "Date d'ouverture",
closing_date: "Date de clôture",
remark: "Commentaire",
closing_motive: "Motif de clôture",
},
persons_associated: {
title: "Usagers concernés",
counter: "Pas d'usager | 1 usager | {count} usagers",
firstname: "Prénom",
lastname: "Nom",
startdate: "Date d'entrée",
enddate: "Date de sortie",
addPerson: "Ajouter un usager",
},
requestor: {
title: "Demandeur",
},
}
};
Object.assign(appMessages.fr, personMessages.fr);
export {
appMessages
};

View File

@ -0,0 +1,76 @@
import 'es6-promise/auto';
import { createStore } from 'vuex';
import addPersons from './modules/addPersons'
import { getAccompanyingCourse, postParticipation } from '../api';
const debug = process.env.NODE_ENV !== 'production';
const id = window.accompanyingCourseId; //tmp
let initPromise = getAccompanyingCourse(id)
.then(accompanying_course => new Promise((resolve, reject) => {
const store = createStore({
strict: debug,
modules: {
addPersons
},
state: {
accompanyingCourse: accompanying_course,
errorMsg: []
},
getters: {
},
mutations: {
removeParticipation(state, item) {
//console.log('mutation: remove item', item.id);
state.accompanyingCourse.participations = state.accompanyingCourse.participations.filter(participation => participation !== item);
},
closeParticipation(state, { participation, payload }) {
console.log('### mutation: close item', { participation, payload });
// trouve dans le state le payload et le supprime du state
state.accompanyingCourse.participations = state.accompanyingCourse.participations.filter(participation => participation !== payload);
// pousse la participation
state.accompanyingCourse.participations.push(participation);
},
addParticipation(state, participation) {
//console.log('### mutation: add participation', participation);
state.accompanyingCourse.participations.push(participation);
},
},
actions: {
removeParticipation({ commit }, payload) {
commit('removeParticipation', payload);
},
closeParticipation({ commit }, payload) {
//console.log('## action: fetch delete participation: payload', payload.person.id);
postParticipation(id, payload.person.id, 'DELETE')
.then(participation => new Promise((resolve, reject) => {
//console.log('payload', payload);
commit('closeParticipation', { participation, payload });
resolve();
}))
.catch((error) => {
state.errorMsg.push(error.message);
});
},
addParticipation(addPersons, payload) {
//console.log('## action: fetch post participation: payload', payload.id);
postParticipation(id, payload.id, 'POST')
.then(participation => new Promise((resolve, reject) => {
//console.log(participation, payload);
addPersons.commit('addParticipation', participation);
addPersons.commit('resetState', payload);
resolve();
}))
.catch((error) => {
state.errorMsg.push(error.message);
});
},
}
});
//console.log('store object', store.state.accompanyingCourse.id);
resolve(store);
}));
export { initPromise };

View File

@ -0,0 +1,76 @@
import { searchPersons } from 'ChillPersonAssets/vuejs/_api/AddPersons'
import { postParticipation } from '../../api';
// initial state
const state = {
query: "",
suggested: [],
selected: []
}
// getters
const getters = {
selectedAndSuggested: state => {
const uniqBy = (a, key) => [
...new Map(
a.map(x => [key(x), x])
).values()
];
let union = [...new Set([
...state.suggested.slice().reverse(),
...state.selected.slice().reverse(),
])];
return uniqBy(union, k => k.id);
}
}
// mutations
const mutations = {
setQuery(state, query) {
//console.log('q=', query);
state.query = query;
},
loadSuggestions(state, suggested) {
state.suggested = suggested;
},
updateSelected(state, value) {
state.selected = value;
},
resetState(state, selected) {
//console.log('avant', state.selected);
state.selected = state.selected.filter(value => value !== selected);
//console.log('après', state.selected);
state.query = "";
state.suggested = [];
}
}
// actions
const actions = {
setQuery({ commit }, payload) {
//console.log('## action: setquery: payload', payload);
commit('setQuery', payload.query);
if (payload.query.length >= 3) {
searchPersons(payload.query)
.then(suggested => new Promise((resolve, reject) => {
commit('loadSuggestions', suggested.results);
resolve();
}));
} else {
commit('loadSuggestions', []);
}
},
updateSelected({ commit }, payload) {
//console.log('## action: update selected values: payload', payload);
commit('updateSelected', payload);
}
}
export default {
//namespaced: true,
state,
getters,
actions,
mutations
}

View File

@ -0,0 +1,20 @@
const
locale = 'fr',
format = 'json'
;
/*
* Endpoint chill_person_search, method GET, get a list of persons
*
* @query string - the query to search for
*/
let searchPersons = (query) => {
let url = `/${locale}/search.${format}?name=person_regular&q=${query}`;
return fetch(url)
.then(response => {
if (response.ok) { return response.json(); }
throw Error('Error with request resource response');
});
};
export { searchPersons };

View File

@ -0,0 +1,132 @@
<template>
<button class="sc-button bt-create centered mt-4" @click="openModal">
{{ $t('add_persons.search_add_others_persons') }}
</button>
<teleport to="body">
<modal v-if="modal.showModal"
:modalDialogClass="modal.modalDialogClass"
@close="modal.showModal = false">
<template v-slot:header>
<h3 class="modal-title">{{ $t('add_persons.title') }}</h3>
</template>
<template v-slot:body-fixed>
<div class="search">
<label style="float: right;">
{{ $tc('add_persons.suggested_counter', suggestedCounter) }}
</label>
<input id="search-persons"
name="query"
v-model="query"
:placeholder="$t('add_persons.search_some_persons')"
ref="search" />
<i class="fa fa-search fa-lg"></i>
</div>
</template>
<template v-slot:body>
<!--span class="discret">Selection: {{ selected }}</span-->
<div class="results">
<div class="count">
<span>
<a v-if="suggestedCounter > 0" href="#">
{{ $t('action.check_all')}}</a>
<a v-if="selectedCounter > 0" href="#">
{{ $t('action.reset')}}</a>
</span>
<span v-if="selectedCounter > 0">
{{ $tc('add_persons.selected_counter', selectedCounter) }}
</span>
</div>
<person-suggestion
v-for="item in this.selectedAndSuggested.slice().reverse()"
v-bind:item="item"
v-bind:key="item.id">
</person-suggestion>
<button v-if="query.length >= 3" class="sc-button bt-create ml-5 mt-2" name="createPerson">
{{ $t('action.create') }} "{{ query }}"
</button>
</div>
</template>
<template v-slot:footer>
<button class="sc-button green" @click="addNewPersons">
<i class="fa fa-plus fa-fw"></i>{{ $t('action.add')}}
</button>
</template>
</modal>
</teleport>
</template>
<script>
import { mapState } from 'vuex';
import Modal from 'ChillMainAssets/vuejs/_components/Modal';
import PersonSuggestion from 'ChillPersonAssets/vuejs/_components/PersonSuggestion';
export default {
name: 'AddPersons',
components: {
Modal,
PersonSuggestion,
},
data() {
return {
modal: {
showModal: false,
modalDialogClass: "modal-dialog-scrollable modal-xl"
}
}
},
computed: {
...mapState({
addPersons: state => state.addPersons
}),
query: {
set(query) {
this.$store.dispatch('setQuery', { query });
},
get() {
return this.addPersons.query;
}
},
suggested() {
return this.addPersons.suggested;
},
suggestedCounter() {
return this.addPersons.suggested.length;
},
selected() {
return this.addPersons.selected;
},
selectedCounter() {
return this.addPersons.selected.length;
},
selectedAndSuggested() {
return this.$store.getters.selectedAndSuggested;
}
},
methods: {
openModal() {
this.modal.showModal = true;
this.$nextTick(function() {
this.$refs.search.focus();
})
},
addNewPersons() {
console.log('@@@ CLICK button addPersons')
this.selected.forEach(function(item) {
//console.log('# dispatch action for each item', item);
this.$store.dispatch('addParticipation', item);
}, this
);
this.modal.showModal = false;
}
}
}
</script>

View File

@ -0,0 +1,53 @@
<template>
<div class="list-item" :class="{ checked: isChecked }">
<div class="container">
<!--a class="discret" target="_blank" :href="url.show">{{ item.id }}</a-->
<input class=""
type="checkbox"
v-model="selected"
:value="item" />
{{ item.text }}
</div>
<div class="right_actions">
<span class="badge badge-pill badge-secondary" :title="item.id">
{{ $t('item.type_person') }}
</span>
<a class="sc-button bt-show" target="_blank" :title="item.id" :href="url.show"></a>
</div>
</div>
</template>
<script>
import { mapState } from 'vuex';
export default {
name: 'PersonSuggestion',
props: ['item'],
data() {
return {
url: {
show: '/fr/person/' + this.item.id + '/general',
edit: '/fr/person/' + this.item.id + '/general/edit'
}
}
},
computed: {
selected: {
set(value) {
this.$store.dispatch('updateSelected', value);
},
get() {
return this.$store.state.addPersons.selected;
}
},
isChecked() {
return (this.selected.indexOf(this.item) === -1) ? false : true;
}
}
};
</script>

View File

@ -0,0 +1,21 @@
const personMessages = {
fr: {
add_persons: {
search_add_others_persons: "Rechercher et ajouter d'autres usagers",
title: "Ajouter des usagers",
suggested_counter: "Pas de résultats | 1 résultat | {count} résultats",
selected_counter: " 1 sélectionné | {count} sélectionnés",
search_some_persons: "Rechercher des personnes..",
},
item: {
type_person: "Usager",
type_tms: "TMS",
type_3rdparty: "Tiers",
type_menage: "Ménage"
}
}
};
export {
personMessages
};

View File

@ -5,15 +5,13 @@
{% endblock %}
{% block content %}
<h1>{{ block('title') }}</h1>
<div id="accompanying-course"></div>
{% endblock %}
{{ encore_entry_script_tags('accompanying_course') }}
{% block js %}
<script type="text/javascript">
window.accompanyingCourseId = {{ accompanyingCourse.id|e('js') }};
</script>
{{ encore_entry_script_tags('accompanying_course') }}
{% endblock %}

View File

@ -22,6 +22,7 @@ use Chill\PersonBundle\Entity\PersonNotDuplicate;
use Doctrine\ORM\EntityManagerInterface;
use Chill\PersonBundle\Entity\Person;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Chill\PersonBundle\Repository\PersonNotDuplicateRepository;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Role\Role;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
@ -62,7 +63,7 @@ class SimilarPersonMatcher
$this->tokenStorage = $tokenStorage;
}
public function matchPerson(Person $person, $precision = 0.15, $orderBy = self::SIMILAR_SEARCH_ORDER_BY_SIMILARITY)
public function matchPerson(Person $person, PersonNotDuplicateRepository $personNotDuplicateRepository, $precision = 0.15, $orderBy = self::SIMILAR_SEARCH_ORDER_BY_SIMILARITY)
{
$centers = $this->authorizationHelper->getReachableCenters(
$this->tokenStorage->getToken()->getUser(),
@ -77,8 +78,7 @@ class SimilarPersonMatcher
. ' AND p.id != :personId '
;
$notDuplicatePersons = $this->em->getRepository(PersonNotDuplicate::class)
->findNotDuplicatePerson($person);
$notDuplicatePersons = $personNotDuplicateRepository->findNotDuplicatePerson($person);
if (count($notDuplicatePersons)) {
$dql .= ' AND p.id not in (:notDuplicatePersons)';

View File

@ -25,6 +25,7 @@ namespace Chill\PersonBundle\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\DomCrawler\Form;
use Chill\MainBundle\Test\PrepareClientTrait;
use \Symfony\Component\BrowserKit\Client;
/**
* Test creation and deletion for persons
@ -33,6 +34,8 @@ class PersonControllerCreateTest extends WebTestCase
{
use PrepareClientTrait;
private Client $client;
const FIRSTNAME_INPUT = 'chill_personbundle_person_creation[firstName]';
const LASTNAME_INPUT = "chill_personbundle_person_creation[lastName]";
const GENDER_INPUT = "chill_personbundle_person_creation[gender]";
@ -42,18 +45,20 @@ class PersonControllerCreateTest extends WebTestCase
const LONG_TEXT = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosq. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta.Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosq.";
public function setUp()
public function setUp(): void
{
$this->client = $this::getClientAuthenticated();
$this->client = $this->getClientAuthenticated();
}
/**
*
* @param Form $creationForm
*/
private function fillAValidCreationForm(Form &$creationForm,
$firstname = 'God', $lastname = 'Jesus')
{
private function fillAValidCreationForm(
Form &$creationForm,
string $firstname = 'God',
string $lastname = 'Jesus'
) {
$creationForm->get(self::FIRSTNAME_INPUT)->setValue($firstname);
$creationForm->get(self::LASTNAME_INPUT)->setValue($lastname);
$creationForm->get(self::GENDER_INPUT)->select("man");

View File

@ -45,7 +45,7 @@ class PersonListWidget implements WidgetInterface
/**
* Repository for persons
*
* @var EntityRepository
* @var PersonRepository
*/
protected $personRepository;
@ -76,7 +76,7 @@ class PersonListWidget implements WidgetInterface
protected $user;
public function __construct(
EntityRepository $personRepostory,
PersonRepository $personRepostory,
EntityManager $em,
AuthorizationHelper $authorizationHelper,
TokenStorage $tokenStorage

View File

@ -8,5 +8,5 @@ module.exports = function(encore, entries)
ChillPersonAssets: __dirname + '/Resources/public'
});
encore.addEntry('accompanying_course', __dirname + '/Resources/public/js/AccompanyingCourse/index.js');
encore.addEntry('accompanying_course', __dirname + '/Resources/public/vuejs/AccompanyingCourse/index.js');
};

View File

@ -2,7 +2,9 @@ parameters:
# cl_chill_person.example.class: Chill\PersonBundle\Example
services:
_defaults:
autowire: true
autoconfigure: true
chill.person.form.type.select2maritalstatus:
class: Chill\PersonBundle\Form\Type\Select2MaritalStatusType
@ -48,3 +50,7 @@ services:
- "%chill_person.validation.birtdate_not_before%"
tags:
- { name: validator.constraint_validator, alias: birthdate_not_before }
Chill\PersonBundle\Repository\:
resource: '../Repository/'
tags: ['doctrine.repository_service']

View File

@ -2,29 +2,6 @@ services:
chill.person.repository.person:
class: Chill\PersonBundle\Repository\PersonRepository
factory: ['@doctrine.orm.entity_manager', getRepository]
arguments:
- 'Chill\PersonBundle\Entity\Person'
autowire: true
autoconfigure: true
Chill\PersonBundle\Repository\PersonRepository: '@chill.person.repository.person'
Chill\PersonBundle\Repository\AccompanyingPeriod\ClosingMotiveRepository:
class: Chill\PersonBundle\Repository\AccompanyingPeriod\ClosingMotiveRepository
factory: ['@doctrine.orm.entity_manager', getRepository]
arguments:
- 'Chill\PersonBundle\Entity\AccompanyingPeriod\ClosingMotive'
Chill\PersonBundle\Repository\AccompanyingPeriodRepository:
class: Chill\PersonBundle\Repository\AccompanyingPeriodRepository
tags: [ doctrine.repository_service ]
arguments:
- '@Doctrine\Persistence\ManagerRegistry'
Chill\PersonBundle\Repository\AccompanyingPeriodParticipationRepository:
arguments:
- '@Doctrine\Persistence\ManagerRegistry'
tags: [ doctrine.repository_service ]
Chill\PersonBundle\Repository\AccompanyingPeriod\OriginRepository:
arguments:
- '@Doctrine\Persistence\ManagerRegistry'
tags: [ doctrine.repository_service ]