Merge remote-tracking branch 'origin/master' into track-address-reference-update

This commit is contained in:
2023-04-12 09:45:19 +02:00
273 changed files with 8869 additions and 3001 deletions

View File

@@ -14,6 +14,8 @@ namespace Chill\PersonBundle\AccompanyingPeriod\SocialIssueConsistency;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Event\PrePersistEventArgs;
use Doctrine\ORM\Event\PreUpdateEventArgs;
/**
* This service listens for preUpdate and prePersist events on some entities
@@ -26,22 +28,22 @@ use Doctrine\ORM\Event\LifecycleEventArgs;
*/
final class AccompanyingPeriodSocialIssueConsistencyEntityListener
{
public function prePersist(AccompanyingPeriodLinkedWithSocialIssuesEntityInterface $entity, LifecycleEventArgs $eventArgs)
public function prePersist(AccompanyingPeriodLinkedWithSocialIssuesEntityInterface $entity, PrePersistEventArgs $eventArgs)
{
$this->ensureConsistencyEntity($entity);
}
public function prePersistAccompanyingPeriod(AccompanyingPeriod $period, LifecycleEventArgs $eventArgs)
public function prePersistAccompanyingPeriod(AccompanyingPeriod $period, PrePersistEventArgs $eventArgs)
{
$this->ensureConsistencyAccompanyingPeriod($period);
}
public function preUpdate(AccompanyingPeriodLinkedWithSocialIssuesEntityInterface $entity, LifecycleEventArgs $eventArgs)
public function preUpdate(AccompanyingPeriodLinkedWithSocialIssuesEntityInterface $entity, PreUpdateEventArgs $eventArgs)
{
$this->ensureConsistencyEntity($entity);
}
public function preUpdateAccompanyingPeriod(AccompanyingPeriod $period, LifecycleEventArgs $eventArgs)
public function preUpdateAccompanyingPeriod(AccompanyingPeriod $period, PreUpdateEventArgs $eventArgs)
{
$this->ensureConsistencyAccompanyingPeriod($period);
}

View File

@@ -117,7 +117,7 @@ class PersonMove
$from->getId()
);
return $sqls ?? [];
return $sqls;
}
protected function createDeleteSQL(ClassMetadata $metadata, Person $from, $field): string

View File

@@ -70,10 +70,10 @@ class AccompanyingPeriodController extends AbstractController
if ($person->isOpen() === false) {
$this->get('session')->getFlashBag()
->add('error', $this->get('translator')
->trans(
'Beware period is closed',
['%name%' => $person->__toString()]
));
->trans(
'Beware period is closed',
['%name%' => $person->__toString()]
));
return $this->redirect(
$this->generateUrl('chill_person_accompanying_period_list', [
@@ -99,9 +99,9 @@ class AccompanyingPeriodController extends AbstractController
if (count($errors) === 0) {
$this->get('session')->getFlashBag()
->add('success', $this->get('translator')
->trans('An accompanying period has been closed.', [
'%name%' => $person->__toString(),
]));
->trans('An accompanying period has been closed.', [
'%name%' => $person->__toString(),
]));
$this->getDoctrine()->getManager()->flush();
@@ -113,7 +113,7 @@ class AccompanyingPeriodController extends AbstractController
}
$this->get('session')->getFlashBag()
->add('error', $this->get('translator')
->trans('Error! Period not closed!'));
->trans('Error! Period not closed!'));
foreach ($errors as $error) {
$this->get('session')->getFlashBag()
@@ -251,10 +251,10 @@ class AccompanyingPeriodController extends AbstractController
if ($person->isOpen()) {
$this->get('session')->getFlashBag()
->add('error', $this->get('translator')
->trans(
'Error! Period %name% is not closed ; it can be open',
['%name%' => $person->__toString()]
));
->trans(
'Error! Period %name% is not closed ; it can be open',
['%name%' => $person->__toString()]
));
return $this->redirect(
$this->generateUrl('chill_person_accompanying_period_list', [
@@ -285,10 +285,10 @@ class AccompanyingPeriodController extends AbstractController
if (count($errors) <= 0) {
$this->get('session')->getFlashBag()
->add('success', $this->get('translator')
->trans(
'An accompanying period has been opened.',
['%name%' => $person->__toString()]
));
->trans(
'An accompanying period has been opened.',
['%name%' => $person->__toString()]
));
$this->getDoctrine()->getManager()->flush();
@@ -300,7 +300,7 @@ class AccompanyingPeriodController extends AbstractController
}
$this->get('session')->getFlashBag()
->add('error', $this->get('translator')
->trans('Period not opened'));
->trans('Period not opened'));
foreach ($errors as $error) {
$this->get('session')->getFlashBag()

View File

@@ -82,7 +82,7 @@ class HouseholdController extends AbstractController
}
usort($accompanyingPeriods, static function ($a, $b) {
return $b->getOpeningDate() > $a->getOpeningDate();
return $b->getOpeningDate() <=> $a->getOpeningDate();
});
$oldMembers = $household->getNonCurrentMembers();

View File

@@ -11,6 +11,8 @@ declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
use Chill\PersonBundle\Config\ConfigPersonAltNamesHelper;
use Chill\PersonBundle\Entity\Household\Household;
use Chill\PersonBundle\Entity\Household\HouseholdMember;
@@ -20,6 +22,7 @@ use Chill\PersonBundle\Form\PersonType;
use Chill\PersonBundle\Privacy\PrivacyEvent;
use Chill\PersonBundle\Repository\PersonRepository;
use Chill\PersonBundle\Search\SimilarPersonMatcher;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use DateTimeImmutable;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
@@ -44,6 +47,8 @@ use function is_array;
final class PersonController extends AbstractController
{
private AuthorizationHelperInterface $authorizationHelper;
/**
* @var ConfigPersonAltNamesHelper
*/
@@ -85,6 +90,7 @@ final class PersonController extends AbstractController
private $validator;
public function __construct(
AuthorizationHelperInterface $authorizationHelper,
SimilarPersonMatcher $similarPersonMatcher,
TranslatorInterface $translator,
EventDispatcherInterface $eventDispatcher,
@@ -93,8 +99,8 @@ final class PersonController extends AbstractController
LoggerInterface $logger,
ValidatorInterface $validator,
EntityManagerInterface $em,
Security $security
) {
$this->authorizationHelper = $authorizationHelper;
$this->similarPersonMatcher = $similarPersonMatcher;
$this->translator = $translator;
$this->eventDispatcher = $eventDispatcher;
@@ -103,7 +109,6 @@ final class PersonController extends AbstractController
$this->logger = $logger;
$this->validator = $validator;
$this->em = $em;
$this->security = $security;
}
public function editAction($person_id, Request $request)
@@ -204,22 +209,15 @@ final class PersonController extends AbstractController
*
* The next post compare the data with previous one and, if yes, show a
* review page if there are "alternate persons".
*
* @return Response|\Symfony\Component\HttpFoundation\RedirectResponse
*/
public function newAction(Request $request)
public function newAction(Request $request): Response
{
$person = new Person();
if (
1 === count($this->security->getUser()
->getGroupCenters())
) {
$person->setCenter(
$this->security->getUser()
->getGroupCenters()[0]
->getCenter()
);
$authorizedCenters =$this->authorizationHelper->getReachableCenters($this->getUser(), PersonVoter::CREATE);
if (1 === count($authorizedCenters)) {
$person->setCenter($authorizedCenters[0]);
}
$form = $this->createForm(CreationPersonType::class, $person)

View File

@@ -98,6 +98,7 @@ class ReassignAccompanyingPeriodController extends AbstractController
$total = $this->accompanyingPeriodACLAwareRepository->countByUserOpenedAccompanyingPeriod($userFrom);
$paginator = $this->paginatorFactory->create($total);
$paginator->setItemsPerPage(50);
$periods = $this->accompanyingPeriodACLAwareRepository
->findByUserAndPostalCodesOpenedAccompanyingPeriod(
$userFrom,

View File

@@ -407,6 +407,7 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
private function createExpectedPerson($default): Person
{
/** @var Person $person */
$person = $this->loader->loadData([
Person::class => [
'person' => [
@@ -439,10 +440,15 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
break;
case 'countryOfBirth':
$country = $this->countryRepository
->findOneBy(['countryCode' => $value]);
$person->setCountryOfBirth($country);
break;
case 'nationality':
$country = $this->countryRepository
->findOneBy(['countryCode' => $value]);
$person->{'set' . ucfirst($key)}($country);
$person->setNationality($country);
break;
@@ -484,42 +490,6 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
return $this->getReference($ref);
}
/**
* Create a random address.
*
* @return Address
*/
private function getRandomAddress()
{
return (new Address())
->setStreetAddress1($this->faker->streetAddress)
->setStreetAddress2(
mt_rand(0, 9) > 5 ? $this->faker->streetAddress : ''
)
->setPoint(
mt_rand(0, 9) > 5 ? $this->getRandomPoint() : null
)
->setPostcode($this->getReference(
LoadPostalCodes::$refs[array_rand(LoadPostalCodes::$refs)]
))
->setValidFrom($this->faker->dateTimeBetween('-5 years'));
}
/**
* Create a random point.
*
* @return Point
*/
private function getRandomPoint()
{
$lonBrussels = 4.35243;
$latBrussels = 50.84676;
$lon = $lonBrussels + 0.01 * mt_rand(-5, 5);
$lat = $latBrussels + 0.01 * mt_rand(-5, 5);
return Point::fromLonLat($lon, $lat);
}
private function getRandomSocialIssue(): SocialIssue
{
if (0 === count($this->cacheSocialIssues)) {

View File

@@ -129,7 +129,7 @@ class Configuration implements ConfigurationInterface
->defaultValue(false)
->end()
->end() // children of 'root', parent = root
;
;
return $treeBuilder;
}

View File

@@ -42,6 +42,7 @@ use DateTimeInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\Common\Collections\ReadableCollection;
use Doctrine\ORM\Mapping as ORM;
use Iterator;
use LogicException;
@@ -615,9 +616,9 @@ class AccompanyingPeriod implements
/**
* Get a list of person which have an adresse available for a valid location.
*
* @return Collection|Person[]
* @return ReadableCollection<(int|string), Person>
*/
public function getAvailablePersonLocation(): Collection
public function getAvailablePersonLocation(): ReadableCollection
{
return $this->getOpenParticipations()
->filter(
@@ -675,8 +676,9 @@ class AccompanyingPeriod implements
/**
* @Groups({"read"})
* @return ReadableCollection<(int|string), Comment>
*/
public function getComments(): Collection
public function getComments(): ReadableCollection
{
$pinnedComment = $this->pinnedComment;
@@ -700,7 +702,7 @@ class AccompanyingPeriod implements
/**
* @Groups({"docgen:read"})
*/
public function getCurrentParticipations(): Collection
public function getCurrentParticipations(): ReadableCollection
{
return $this->getOpenParticipations();
}
@@ -834,7 +836,10 @@ class AccompanyingPeriod implements
return $collection->count() > 0 ? $collection->first() : null;
}
public function getOpenParticipations(): Collection
/**
* @return ReadableCollection<(int|string), AccompanyingPeriodParticipation>
*/
public function getOpenParticipations(): ReadableCollection
{
return $this
->getParticipations()
@@ -860,8 +865,9 @@ class AccompanyingPeriod implements
/**
* Get the participation containing a person.
* @return ReadableCollection<(int|string), AccompanyingPeriodParticipation>
*/
public function getParticipationsContainsPerson(Person $person): Collection
public function getParticipationsContainsPerson(Person $person): ReadableCollection
{
return $this
->getParticipations()
@@ -881,7 +887,7 @@ class AccompanyingPeriod implements
/**
* Get a list of all persons which are participating to this course.
*
* @psalm-return Collection<int, Person>
* @psalm-return Collection<(int|string), Person|null>
*/
public function getPersons(): Collection
{
@@ -1155,7 +1161,7 @@ class AccompanyingPeriod implements
public function removeWork(AccompanyingPeriodWork $work): self
{
$this->work->removeElement($work);
$this->works->removeElement($work);
$work->setAccompanyingPeriod(null);
return $this;

View File

@@ -94,8 +94,8 @@ class AccompanyingPeriodWork implements AccompanyingPeriodLinkedWithSocialIssues
* @Serializer\Groups({"accompanying_period_work:create"})
* @Serializer\Groups({"accompanying_period_work:edit"})
* @Serializer\Groups({"read", "docgen:read", "read:accompanyingPeriodWork:light"})
* @Assert\GreaterThan(propertyPath="startDate",
* message="accompanying_course_work.The endDate should be greater than the start date"
* @Assert\GreaterThanOrEqual(propertyPath="startDate",
* message="accompanying_course_work.The endDate should be greater or equal than the start date"
* )
*/
private ?DateTimeImmutable $endDate = null;

View File

@@ -160,6 +160,14 @@ class AccompanyingPeriodWorkEvaluation implements TrackCreationInterface, TrackU
*/
private ?DateInterval $warningInterval = null;
/**
* @ORM\Column(type="integer", nullable=true)
* @Serializer\Groups({"read", "docgen:read"})
* @Serializer\Groups({"write"})
* @Serializer\Groups({"accompanying_period_work_evaluation:create"})
*/
private ?int $timeSpent = null;
public function __construct()
{
$this->documents = new ArrayCollection();
@@ -265,6 +273,11 @@ class AccompanyingPeriodWorkEvaluation implements TrackCreationInterface, TrackU
return $this->warningInterval;
}
public function getTimeSpent(): ?int
{
return $this->timeSpent;
}
public function removeDocument(AccompanyingPeriodWorkEvaluationDocument $document): self
{
$this->documents->removeElement($document);
@@ -322,6 +335,13 @@ class AccompanyingPeriodWorkEvaluation implements TrackCreationInterface, TrackU
return $this;
}
public function setTimeSpent(?int $timeSpent): self
{
$this->timeSpent = $timeSpent;
return $this;
}
public function setEvaluation(?Evaluation $evaluation): AccompanyingPeriodWorkEvaluation
{
if (

View File

@@ -22,6 +22,7 @@ use DateTimeInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\Common\Collections\ReadableCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation as Serializer;
use Symfony\Component\Validator\Constraints as Assert;
@@ -265,7 +266,7 @@ class Household
* @Serializer\Groups({"read"})
* @Serializer\SerializedName("current_members_id")
*/
public function getCurrentMembersIds(?DateTimeImmutable $now = null): Collection
public function getCurrentMembersIds(?DateTimeImmutable $now = null): ReadableCollection
{
return $this->getCurrentMembers($now)->map(
static fn (HouseholdMember $m) => $m->getId()
@@ -332,9 +333,9 @@ class Household
*
* Return a list of Person, instead of a list of HouseholdMembers
*
* @return Person[]
* @return ReadableCollection<(int|string), Person>
*/
public function getCurrentPersons(?DateTimeImmutable $now = null): Collection
public function getCurrentPersons(?DateTimeImmutable $now = null): ReadableCollection
{
return $this->getCurrentMembers($now)
->map(static function (HouseholdMember $m) {
@@ -358,9 +359,9 @@ class Household
/**
* get all the members during a given membership.
*
* @return Collection|HouseholdMember[]
* @return ReadableCollection<(int|string), HouseholdMember>
*/
public function getMembersDuringMembership(HouseholdMember $membership): Collection
public function getMembersDuringMembership(HouseholdMember $membership): ReadableCollection
{
return $this->getMembersOnRange(
$membership->getStartDate(),
@@ -384,7 +385,7 @@ class Household
return $this->getMembers()->matching($criteria);
}
public function getMembersOnRange(DateTimeImmutable $from, ?DateTimeImmutable $to): Collection
public function getMembersOnRange(DateTimeImmutable $from, ?DateTimeImmutable $to): ReadableCollection
{
return $this->getMembers()->filter(static function (HouseholdMember $m) use ($from, $to) {
if (null === $m->getEndDate() && null !== $to) {

View File

@@ -751,7 +751,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
foreach ($this->getAccompanyingPeriodParticipations()
->map(fn (AccompanyingPeriodParticipation $app) => $app->getAccompanyingPeriod())
as $period
) {
) {
if (!$result->contains($period)) {
$result->add($period);
}

View File

@@ -47,6 +47,7 @@ class ListEvaluation implements ListInterface, GroupedExportInterface
'endDate',
'maxDate',
'warningInterval',
'timeSpent',
'acpw_id',
'acpw_startDate',
'acpw_endDate',
@@ -295,6 +296,9 @@ class ListEvaluation implements ListInterface, GroupedExportInterface
$qb->addSelect(sprintf('workeval.%s AS %s', $field, $field));
}
// add the time spent field
$qb->addSelect('(workeval.timeSpent / 60) AS timeSpent');
// those with identity
foreach (['createdBy', 'updatedBy'] as $field) {
$qb->addSelect(sprintf('IDENTITY(workeval.%s) AS %s', $field, $field));

View File

@@ -31,13 +31,9 @@ class ReferrerFilter implements FilterInterface
private RollingDateConverterInterface $rollingDateConverter;
private UserRender $userRender;
public function __construct(
UserRender $userRender,
RollingDateConverterInterface $rollingDateConverter
) {
$this->userRender = $userRender;
$this->rollingDateConverter = $rollingDateConverter;
}

View File

@@ -36,19 +36,15 @@ class UserJobFilter implements FilterInterface
private RollingDateConverterInterface $rollingDateConverter;
private Security $security;
private TranslatableStringHelper $translatableStringHelper;
private UserJobRepositoryInterface $userJobRepository;
public function __construct(
Security $security,
TranslatableStringHelper $translatableStringHelper,
UserJobRepositoryInterface $userJobRepository,
RollingDateConverterInterface $rollingDateConverter
) {
$this->security = $security;
$this->translatableStringHelper = $translatableStringHelper;
$this->userJobRepository = $userJobRepository;
$this->rollingDateConverter = $rollingDateConverter;

View File

@@ -26,13 +26,10 @@ class AddressRefStatusFilter implements \Chill\MainBundle\Export\FilterInterface
{
private RollingDateConverterInterface $rollingDateConverter;
private TranslatableStringHelperInterface $translatableStringHelper;
public function __construct(
TranslatableStringHelperInterface $translatableStringHelper,
RollingDateConverterInterface $rollingDateConverter
) {
$this->translatableStringHelper = $translatableStringHelper;
$this->rollingDateConverter = $rollingDateConverter;
}

View File

@@ -22,13 +22,6 @@ use function in_array;
class ReferrerFilter implements FilterInterface
{
private UserRender $userRender;
public function __construct(UserRender $userRender)
{
$this->userRender = $userRender;
}
public function addRole(): ?string
{
return null;

View File

@@ -19,7 +19,6 @@ use Chill\PersonBundle\Entity\SocialWork\SocialAction;
use Chill\PersonBundle\Export\Declarations;
use Chill\PersonBundle\Templating\Entity\SocialActionRender;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query\Expr\Andx;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\CallbackTransformer;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
@@ -52,45 +51,37 @@ class SocialWorkTypeFilter implements FilterInterface
public function alterQuery(QueryBuilder $qb, $data)
{
$where = $qb->getDQLPart('where');
if (count($data['actionType']) > 0) {
$clause = $qb->expr()->in('acpw.socialAction', ':actionType');
if ($where instanceof Andx) {
$where->add($clause);
} else {
$where = $qb->expr()->andX($clause);
}
$qb->setParameter('actionType', $data['actionType']);
$qb
->andWhere($qb->expr()->in('acpw.socialAction', ':actionType'))
->setParameter('actionType', $data['actionType']);
}
if (count($data['goal']) > 0) {
if (!in_array('goal', $qb->getAllAliases(), true)) {
$qb->join('acpw.goals', 'goal');
if (!in_array('acpw_goal', $qb->getAllAliases(), true)) {
$qb->join('acpw.goals', 'acpw_goal');
}
$where->add(
$qb->expr()->in('goal.id', ':goals')
);
$orX = $qb->expr()->orX();
foreach ($data['goal'] as $goal) {
/** @var Goal $goal */
$andX = $qb->expr()->andX();
$andX->add($qb->expr()->eq('acpw_goal.goal', $goalId = ':goal_'.uniqid()));
$qb->setParameter($goalId, $goal);
$qb->setParameter('goals', $data['goal']);
}
if (count($data['result']) > 0) {
if (!in_array('result', $qb->getAllAliases(), true)) {
$qb->join('acpw.results', 'result');
if (count($data['result']) > 0) {
$orXResult = $qb->expr()->orX();
foreach ($data['result'] as $result) {
/** @var Result $result */
$orXResult->add($qb->expr()->isMemberOf($resultId = ':result_'.uniqid(), 'acpw_goal.results'));
$qb->setParameter($resultId, $result);
}
$andX->add($orXResult);
}
$orX->add($andX);
}
$where->add(
$qb->expr()->in('result.id', ':results')
);
$qb->setParameter('results', $data['result']);
$qb->andWhere($orX);
}
$qb->add('where', $where);
}
public function applyOn(): string

View File

@@ -65,9 +65,9 @@ class AccompanyingPeriodType extends AbstractType
$accompanyingPeriod = $options['data'];
if (
('close' === $options['period_action'])
|| ('create' === $options['period_action'])
|| ('update' === $options['period_action'] && !$accompanyingPeriod->isOpen())
('close' === $options['period_action'])
|| ('create' === $options['period_action'])
|| ('update' === $options['period_action'] && !$accompanyingPeriod->isOpen())
) {
$builder->add('closingDate', DateType::class, [
'required' => true,

View File

@@ -18,21 +18,28 @@ use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Symfony\Component\Serializer\SerializerInterface;
/**
* Pick user dymically, using vuejs module "AddPerson".
* m* Pick user dymically, using vuejs module "AddPerson".
*/
class PickPersonDynamicType extends AbstractType
{
private DenormalizerInterface $denormalizer;
private NormalizerInterface $normalizer;
private SerializerInterface $serializer;
public function __construct(DenormalizerInterface $denormalizer, SerializerInterface $serializer)
{
public function __construct(
DenormalizerInterface $denormalizer,
SerializerInterface $serializer,
NormalizerInterface $normalizer
) {
$this->denormalizer = $denormalizer;
$this->serializer = $serializer;
$this->normalizer = $normalizer;
}
public function buildForm(FormBuilderInterface $builder, array $options)
@@ -45,6 +52,11 @@ class PickPersonDynamicType extends AbstractType
$view->vars['multiple'] = $options['multiple'];
$view->vars['types'] = ['person'];
$view->vars['uniqid'] = uniqid('pick_user_dyn');
$view->vars['suggested'] = [];
foreach ($options['suggested'] as $person) {
$view->vars['suggested'][] = $this->normalizer->normalize($person, 'json', ['groups' => 'read']);
}
}
public function configureOptions(OptionsResolver $resolver)
@@ -52,7 +64,8 @@ class PickPersonDynamicType extends AbstractType
$resolver
->setDefault('multiple', false)
->setAllowedTypes('multiple', ['bool'])
->setDefault('compound', false);
->setDefault('compound', false)
->setDefault('suggested', []);
}
public function getBlockPrefix()

View File

@@ -28,6 +28,8 @@ use function count;
*
* - person details ;
* - accompanying period (if `visible`)
*
* @implements LocalMenuBuilderInterface<array{person: Person}>
*/
class PersonMenuBuilder implements LocalMenuBuilderInterface
{

View File

@@ -59,7 +59,7 @@ class PrivacyEvent extends Event
/**
* @var array
*/
private $persons;
private $persons = [];
/**
* PrivacyEvent constructor.
@@ -68,7 +68,6 @@ class PrivacyEvent extends Event
{
$this->person = $person;
$this->args = $args;
$this->persons = [];
}
public function addPerson(Person $person)

View File

@@ -75,7 +75,8 @@ final class PersonACLAwareRepository implements PersonACLAwareRepositoryInterfac
$birthdateAfter,
$gender,
$countryCode,
$phonenumber
$phonenumber,
$city
);
return $this->addAuthorizations($query);

View File

@@ -24,9 +24,9 @@ final class EvaluationRepository implements EvaluationRepositoryInterface
$this->repository = $entityManager->getRepository(Evaluation::class);
}
public function find($id, ?int $lockMode = null, ?int $lockVersion = null): ?Evaluation
public function find($id): ?Evaluation
{
return $this->repository->find($id, $lockMode, $lockVersion);
return $this->repository->find($id);
}
/**

View File

@@ -16,7 +16,7 @@ use Doctrine\Persistence\ObjectRepository;
interface EvaluationRepositoryInterface extends ObjectRepository
{
public function find($id, ?int $lockMode = null, ?int $lockVersion = null): ?Evaluation;
public function find($id): ?Evaluation;
/**
* @return array<int, Evaluation>

View File

@@ -38,9 +38,9 @@ final class GoalRepository implements ObjectRepository
->getSingleScalarResult();
}
public function find($id, ?int $lockMode = null, ?int $lockVersion = null): ?Goal
public function find($id): ?Goal
{
return $this->repository->find($id, $lockMode, $lockVersion);
return $this->repository->find($id);
}
/**
@@ -111,9 +111,9 @@ final class GoalRepository implements ObjectRepository
$orx = $qb->expr()->orX();
$i = 0;
foreach ($actions as $action) {
foreach ($actions as $act) {
$orx->add(":action_{$i} MEMBER OF g.socialActions");
$qb->setParameter("action_{$i}", $action);
$qb->setParameter("action_{$i}", $act);
}
$qb->where($orx);

View File

@@ -48,9 +48,9 @@ final class ResultRepository implements ObjectRepository
->getSingleScalarResult();
}
public function find($id, ?int $lockMode = null, ?int $lockVersion = null): ?Result
public function find($id): ?Result
{
return $this->repository->find($id, $lockMode, $lockVersion);
return $this->repository->find($id);
}
/**
@@ -146,9 +146,9 @@ final class ResultRepository implements ObjectRepository
$orx = $qb->expr()->orX();
$i = 0;
foreach ($actions as $action) {
foreach ($actions as $act) {
$orx->add(":action_{$i} MEMBER OF r.socialActions");
$qb->setParameter("action_{$i}", $action);
$qb->setParameter("action_{$i}", $act);
}
$qb->where($orx);

View File

@@ -32,9 +32,9 @@ final class SocialActionRepository implements ObjectRepository
return $this->repository->createQueryBuilder($alias, $indexBy);
}
public function find($id, ?int $lockMode = null, ?int $lockVersion = null): ?SocialAction
public function find($id): ?SocialAction
{
return $this->repository->find($id, $lockMode, $lockVersion);
return $this->repository->find($id);
}
/**

View File

@@ -27,9 +27,9 @@ final class SocialIssueRepository implements ObjectRepository
$this->repository = $entityManager->getRepository(SocialIssue::class);
}
public function find($id, ?int $lockMode = null, ?int $lockVersion = null): ?SocialIssue
public function find($id): ?SocialIssue
{
return $this->repository->find($id, $lockMode, $lockVersion);
return $this->repository->find($id);
}
/**

View File

@@ -1,15 +1,22 @@
import { createApp } from 'vue';
import { _createI18n } from 'ChillMainAssets/vuejs/_js/i18n';
import { store } from './store';
import { personMessages } from 'ChillPersonAssets/vuejs/_js/i18n'
import {createApp} from 'vue';
import {_createI18n} from 'ChillMainAssets/vuejs/_js/i18n';
import {store} from './store';
import {personMessages} from 'ChillPersonAssets/vuejs/_js/i18n'
import App from './App.vue';
import VueToast from "vue-toast-notification";
const i18n = _createI18n(personMessages);
const app = createApp({
template: `<app></app>`,
template: `<app></app>`,
})
.use(store)
.use(i18n)
.component('app', App)
.mount('#accompanying_course_work_create');
.use(store)
.use(i18n)
.use(VueToast, {
position: "bottom-right",
type: "error",
duration: 10000,
dismissible: true,
})
.component('app', App)
.mount('#accompanying_course_work_create');

View File

@@ -107,6 +107,9 @@ const store = createStore({
setPostingWork(state) {
state.isPostingWork = true;
},
setPostingWorkDone(state) {
state.isPostingWork = false;
},
setStartDate(state, date) {
state.startDate = date;
},
@@ -150,11 +153,12 @@ const store = createStore({
const url = `/api/1.0/person/accompanying-course/${state.accompanyingCourse.id}/work.json`;
commit('setPostingWork');
makeFetch('POST', url, payload)
return makeFetch('POST', url, payload)
.then((response) => {
window.location.assign(`/fr/person/accompanying-period/work/${response.id}/edit`)
})
.catch((error) => {
commit('setPostingWorkDone');
throw error;
});
},

View File

@@ -549,7 +549,14 @@ export default {
.catch(e => { console.log(e); throw e; });
},
submit() {
this.$store.dispatch('submit');
this.$store.dispatch('submit').catch((error) => {
if (error.name === 'ValidationException' || error.name === 'AccessException') {
error.violations.forEach((violation) => this.$toast.open({message: violation}));
} else {
this.$toast.open({message: 'An error occurred'});
throw error;
}
});
},
saveFormOnTheFly(payload) {
console.log('saveFormOnTheFly: type', payload.type, ', data', payload.data);

View File

@@ -49,6 +49,20 @@
</div>
</div>
<div class="row mb-3">
<label class="col-4 col-sm-2 col-md-4 col-lg-2 col-form-label">
{{ $t('evaluation_time_spent') }}
</label>
<div class="col-8 col-sm-4 col-md-8 col-lg-4">
<select class="form-control form-control-sm" type="time" v-model="timeSpent">
<option disabled value="">{{ $t('select_time_spent') }}</option>
<option v-for="time in timeSpentChoices" :value="time.value">
{{ time.text }}
</option>
</select>
</div>
</div>
<div class="row mb-3">
<label class="col-sm-4 col-form-label visually-hidden">{{ $t('evaluation_public_comment') }}</label>
<div class="col-sm-12">
@@ -191,6 +205,8 @@ const i18n = {
evaluation_choose_a_template: "Choisir un modèle",
evaluation_add_a_document: "Ajouter un document",
evaluation_add: "Ajouter une évaluation",
evaluation_time_spent: "Temps de rédaction",
select_time_spent: "Indiquez le temps de rédaction",
Documents: "Documents",
document_add: "Générer ou téléverser un document",
document_upload: "Téléverser un document",
@@ -224,6 +240,22 @@ export default {
maxPostSize: 15000000,
required: false,
},
timeSpentChoices: [
{ text: '1 minute', value: 60 }, { text: '2 minutes', value: 120 },
{ text: '3 minutes', value: 180 }, { text: '4 minutes', value: 240 },
{ text: '5 minutes', value: 300 }, { text: '10 minutes', value: 600 },
{ text: '15 minutes', value: 900 },{ text: '20 minutes', value: 1200 },
{ text: '25 minutes', value: 1500 }, { text: '30 minutes', value: 1800 },
{ text: '45 minutes', value: 2700 },{ text: '1 hour', value: 3600 },
{ text: '1 hour 15 minutes', value: 4500 }, { text: '1 hour 30 minutes', value: 5400 },
{ text: '1 hour 45 minutes', value: 6300 }, { text: '2 hours', value: 7200 },
{ text: '2 hours 30 minutes', value: 9000 }, { text: '3 hours', value: 10800 },
{ text: '3 hours 30 minutes', value: 12600 },{ text: '4 hours', value: 14400 },
{ text: '4 hours 30 minutes', value: 16200 },{ text: '5 hours', value: 18000 },
{ text: '5 hours 30 minutes', value: 19800 },{ text: '6 hours', value: 21600 },
{ text: '6 hours 30 minutes', value: 23400 },{ text: '7 hours', value: 25200 },
{ text: '7 hours 30 minutes', value: 27000 },{ text: '8 hours', value: 28800 },
]
}
},
computed: {
@@ -265,6 +297,10 @@ export default {
get() { return this.evaluation.warningInterval; },
set(v) { this.$store.commit('setEvaluationWarningInterval', { key: this.evaluation.key, days: v }); }
},
timeSpent: {
get() { return this.evaluation.timeSpent },
set(v) { this.$store.commit('setEvaluationTimeSpent', { key: this.evaluation.key, time: v}) }
},
comment: {
get() { return this.evaluation.comment; },
set(v) { this.$store.commit('setEvaluationComment', { key: this.evaluation.key, comment: v }); }

View File

@@ -15,7 +15,7 @@ const app = createApp({
.use(VueToast, {
position: "bottom-right",
type: "error",
duration: 5000,
duration: 10000,
dismissible: true
})
.use(i18n)

View File

@@ -116,6 +116,7 @@ const store = createStore({
endDate: e.endDate === null || e.endDate === '' ? null : { datetime: datetimeToISO(ISOToDate(e.endDate)) },
maxDate: e.maxDate === null || e.maxDate === '' ? null : { datetime: datetimeToISO(ISOToDate(e.maxDate)) },
warningInterval: intervalDaysToISO(e.warningInterval),
timeSpent: e.timeSpent,
comment: e.comment,
documents: e.documents
};
@@ -138,6 +139,7 @@ const store = createStore({
endDate: e.endDate !== null ? dateToISO(new Date(e.endDate.datetime)) : null,
maxDate: e.maxDate !== null ? dateToISO(new Date(e.maxDate.datetime)) : null,
warningInterval: e.warningInterval !== null ? intervalISOToDays(e.warningInterval) : null,
timeSpent: e.timeSpent !== null ? e.timeSpent : null,
documents: e.documents.map((d, docIndex) => {
return Object.assign(d, {
key: docIndex
@@ -258,6 +260,7 @@ const store = createStore({
endDate: null,
maxDate: null,
warningInterval: null,
timeSpent: null,
comment: "",
editEvaluation: true,
workflows_availables: state.work.workflows_availables_evaluation,
@@ -286,6 +289,10 @@ const store = createStore({
state.evaluationsPicked.find(e => e.key === key)
.warningInterval = days;
},
setEvaluationTimeSpent(state, {key, time}) {
state.evaluationsPicked.find(e => e.key === key)
.timeSpent = time;
},
setEvaluationComment(state, {key, comment}) {
state.evaluationsPicked.find(e => e.key === key)
.comment = comment;
@@ -482,7 +489,7 @@ const store = createStore({
;
commit('setIsPosting', true);
console.log('payload', payload);
console.log('the social action', payload);
return makeFetch('PUT', url, payload)
.then(data => {
@@ -493,9 +500,8 @@ const store = createStore({
window.location.assign(`/fr/person/accompanying-period/${state.work.accompanyingPeriod.id}/work`);
}
}).catch(error => {
console.log('error on submit', error);
commit('setIsPosting', false);
commit('setErrors', error.violations);
throw error;
});
},
updateDocumentTitle({commit}, payload) {

View File

@@ -118,6 +118,18 @@
</li>
{% endif %}
{% endif %}
{% if e.timeSpent is not null and e.timeSpent > 0 %}
<li>
{% set minutes = (e.timeSpent / 60) %}
<span class="item-key">{{ 'accompanying_course_work.timeSpent'|trans ~ ' : ' }}</span> {{ 'duration.minute'|trans({ '{m}' : minutes }) }}
</li>
{% elseif displayContent is defined and displayContent == 'long' %}
<li>
<span class="item-key">{{ 'accompanying_course_work.timeSpent'|trans ~ ' : ' }}</span>
<span class="chill-no-data-statement">{{ 'Not given'|trans }}</span>
</li>
{% endif %}
</ul>
</li>
</ul>
@@ -143,7 +155,7 @@
{% else %}
<span class="chill-no-data-statement">{{ 'No document found'|trans }}</span>
{% endif %}
{% endif %}
</td>

View File

@@ -36,7 +36,7 @@
{%- macro links(person, options) -%}
<ul>
<li><b>{{ person.counters.nb_activity }}</b> {{ (person.counters.nb_activity > 1)? 'activités' : 'activité' }}</li>
<li><b>{{ person.counters.nb_activity }}</b> {{ (person.counters.nb_activity > 1)? 'échanges' : 'échange' }}</li>
<li><b>{{ person.counters.nb_task }}</b> {{ (person.counters.nb_task > 1)? 'tâches' : 'tâche' }}</li>
<li><b>{{ person.counters.nb_document }}</b> {{ (person.counters.nb_document > 1)? 'documents' : 'document' }}</li>
<li><b>{{ person.counters.nb_event }}</b> {{ (person.counters.nb_event > 1)? 'événements' : 'événement' }}</li>

View File

@@ -26,6 +26,7 @@ use Chill\PersonBundle\Repository\PersonACLAwareRepositoryInterface;
use DateTime;
use Exception;
use libphonenumber\PhoneNumber;
use libphonenumber\PhoneNumberUtil;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Templating\EngineInterface;
@@ -115,23 +116,23 @@ class PersonSearch extends AbstractSearch implements HasAdvancedSearchFormInterf
{
$string = '@person ';
$string .= $data['_default'] ? '' : $data['_default'] . ' ';
$string .= !isset($data['_default']) ? '' : $data['_default'] . ' ';
foreach (['firstname', 'lastname', 'gender', 'city'] as $key) {
$string .= $data[$key] ? '' : $key . ':' .
$string .= !isset($data[$key]) ? '' : $key . ':' .
// add quote if contains spaces
(strpos($data[$key], ' ') !== false ? '"' . $data[$key] . '"' : $data[$key])
. ' ';
}
foreach (['birthdate', 'birthdate-before', 'birthdate-after'] as $key) {
$string .= $data[$key] ?
$string .= !isset($data[$key]) ?
''
:
$key . ':' . $data[$key]->format('Y-m-d') . ' ';
}
$string .= $data['phonenumber'] ? '' : 'phonenumber:' . $data['phonenumber']->getNationalNumber();
$string .= !isset($data['phonenumber']) ? '' : 'phonenumber:' . $data['phonenumber']->getNationalNumber();
return $string;
}
@@ -162,12 +163,12 @@ class PersonSearch extends AbstractSearch implements HasAdvancedSearchFormInterf
$phonenumber = new PhoneNumber();
$phonenumber->setNationalNumber($terms['phonenumber']);
} catch (Exception $ex) {
throw new ParsingException('The date for phonenumber is '
throw new ParsingException("The data for phonenumber is "
. 'not parsable', 0, $ex);
}
}
$data['phonenumber'] = $phonenumber ?? null;
$data['phonenumber'] = $phonenumber;
}
return $data;
}
@@ -202,15 +203,6 @@ class PersonSearch extends AbstractSearch implements HasAdvancedSearchFormInterf
return true;
}
/**
* (non-PHPdoc).
*
* @see \Chill\MainBundle\Search\SearchInterface::renderResult()
*
* @param mixed $start
* @param mixed $limit
* @param mixed $format
*/
public function renderResult(array $terms, $start = 0, $limit = 50, array $options = [], $format = 'html')
{
$terms = $this->findAdditionnalInDefault($terms);
@@ -235,15 +227,13 @@ class PersonSearch extends AbstractSearch implements HasAdvancedSearchFormInterf
]
);
}
if ('json' === $format) {
return [
'results' => $this->search($terms, $start, $limit, array_merge($options, ['simplify' => true])),
'pagination' => [
'more' => $paginator->hasNextPage(),
],
];
}
// format is "json"
return [
'results' => $this->search($terms, $start, $limit, array_merge($options, ['simplify' => true])),
'pagination' => [
'more' => $paginator->hasNextPage(),
],
];
}
public function supports($domain, $format)
@@ -266,14 +256,30 @@ class PersonSearch extends AbstractSearch implements HasAdvancedSearchFormInterf
'city' => $city,
] = $terms + array_fill_keys(self::POSSIBLE_KEYS, null);
foreach (['birthdateBefore', 'birthdateAfter', 'birthdate'] as $v) {
if (null !== ${$v}) {
try {
${$v} = new DateTime(${$v});
} catch (Exception $e) {
throw new ParsingException('The date is '
. 'not parsable', 0, $e);
}
if (null !== $birthdate) {
try {
$birthdate = new DateTime($birthdate);
} catch (Exception $e) {
throw new ParsingException('The date is '
. 'not parsable', 0, $e);
}
}
if (null !== $birthdateBefore) {
try {
$birthdateBefore = new DateTime($birthdateBefore);
} catch (Exception $e) {
throw new ParsingException('The date is '
. 'not parsable', 0, $e);
}
}
if (null !== $birthdateAfter) {
try {
$birthdateAfter = new DateTime($birthdateAfter);
} catch (Exception $e) {
throw new ParsingException('The date is '
. 'not parsable', 0, $e);
}
}
@@ -310,14 +316,30 @@ class PersonSearch extends AbstractSearch implements HasAdvancedSearchFormInterf
'city' => $city,
] = $terms + array_fill_keys(self::POSSIBLE_KEYS, null);
foreach (['birthdateBefore', 'birthdateAfter', 'birthdate'] as $v) {
if (null !== ${$v}) {
try {
${$v} = new DateTime(${$v});
} catch (Exception $e) {
throw new ParsingException('The date is '
. 'not parsable', 0, $e);
}
if (null !== $birthdate) {
try {
$birthdate = new DateTime($birthdate);
} catch (Exception $e) {
throw new ParsingException('The date is '
. 'not parsable', 0, $e);
}
}
if (null !== $birthdateBefore) {
try {
$birthdateBefore = new DateTime($birthdateBefore);
} catch (Exception $e) {
throw new ParsingException('The date is '
. 'not parsable', 0, $e);
}
}
if (null !== $birthdateAfter) {
try {
$birthdateAfter = new DateTime($birthdateAfter);
} catch (Exception $e) {
throw new ParsingException('The date is '
. 'not parsable', 0, $e);
}
}

View File

@@ -84,15 +84,19 @@ class SearchHouseholdApiProvider implements SearchApiInterface
count($phoneResult->getFound()) > 0 ? $phoneResult->getFound()[0] : null
);
$previousFrom = $query->getFromClause();
$previousParams = $query->getFromParams();
$query
->setDistinct(true, 'household_id')
->setDistinct(true, 'cpphm.household_id')
->setFromClause(
'view_chill_person_household_address AS vcpha ' .
'JOIN chill_person_person AS person ON vcpha.person_id = person.id'
$previousFrom . ' '.
'JOIN chill_person_household_members AS cpphm ON cpphm.person_id = person.id',
$previousParams
)
->andWhereClause('(cpphm.startDate <= NOW() AND (cpphm.endDate IS NULL or cpphm.endDate > NOW()))')
->setSelectKey('household')
->andWhereClause('vcpha.validTo IS NULL', [])
->setSelectJsonbMetadata("jsonb_build_object('id', vcpha.household_id)");
->setSelectJsonbMetadata("jsonb_build_object('id', cpphm.household_id)");
return $query;
}

View File

@@ -80,7 +80,7 @@ class SimilarPersonMatcher
->where('SIMILARITY(p.fullnameCanonical, UNACCENT(LOWER(:fullName))) >= :precision')
->andWhere($qb->expr()->in('center_history.center', ':centers'))
->andWhere($qb->expr()->andX(
$qb->expr()->lte('center_history.startDate', 'CURRENT_DATE()'),
$qb->expr()->lte('center_history.startDate', 'CURRENT_DATE()'),
$qb->expr()->orX(
$qb->expr()->isNull('center_history.endDate'),
$qb->expr()->gt('center_history.endDate', 'CURRENT_DATE()')

View File

@@ -51,7 +51,7 @@ class AccompanyingPeriodWorkEvaluationVoter extends Voter implements ChillVoterI
{
switch ($attribute) {
case self::STATS:
return $this->security->isGranted(AccompanyingPeriodWorkVoter::STATS, $subject);
return $this->security->isGranted(AccompanyingPeriodVoter::STATS, $subject);
case self::SEE:
return $this->security->isGranted(AccompanyingPeriodWorkVoter::SEE, $subject->getAccompanyingPeriodWork());

View File

@@ -24,12 +24,12 @@ class AuthorizedCenterOnPersonCreation implements AuthorizedCenterOnPersonCreati
public function __construct(AuthorizationHelperForCurrentUserInterface $authorizationHelperForCurrentUser, ParameterBagInterface $parameterBag)
{
$this->authorizationHelperForCurrentUser = $authorizationHelperForCurrentUser;
$this->showCenter = $parameterBag->get('chill_main')['acl']['form_show_centers'];
$this->showCenters = $parameterBag->get('chill_main')['acl']['form_show_centers'];
}
public function getCenters(): array
{
if (!$this->showCenter) {
if (!$this->showCenters) {
return [];
}

View File

@@ -181,7 +181,7 @@ class MembersEditorNormalizer implements DenormalizerAwareInterface, Denormalize
{
if (
null === $data['concerned'] ?? null
&& false === ·\is_array('concerned')
&& false === \is_array('concerned')
) {
throw new Exception\UnexpectedValueException("The schema does not have any key 'concerned'");
}

View File

@@ -27,6 +27,7 @@ use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Repository\PersonRepository;
use Chill\PersonBundle\Templating\Entity\PersonRenderInterface;
use DateTime;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
@@ -38,6 +39,9 @@ use Symfony\Contracts\Translation\TranslatorInterface;
use function array_key_exists;
/**
* @template-implements DocGeneratorContextWithPublicFormInterface<AccompanyingPeriod>
*/
class AccompanyingPeriodContext implements
DocGeneratorContextWithAdminFormInterface,
DocGeneratorContextWithPublicFormInterface
@@ -153,12 +157,12 @@ class AccompanyingPeriodContext implements
/**
* @param AccompanyingPeriod $entity
*/
public function buildPublicForm(FormBuilderInterface $builder, DocGeneratorTemplate $template, $entity): void
public function buildPublicForm(FormBuilderInterface $builder, DocGeneratorTemplate $template, mixed $entity): void
{
$options = $template->getOptions();
$persons = $entity->getCurrentParticipations()->map(static function (AccompanyingPeriodParticipation $p) {
$persons = new ArrayCollection($entity->getCurrentParticipations()->map(static function (AccompanyingPeriodParticipation $p) {
return $p->getPerson();
});
})->toArray());
foreach ($entity->getCurrentParticipations() as $p) {
foreach ($p->getPerson()->getResources() as $r) {
@@ -286,9 +290,6 @@ class AccompanyingPeriodContext implements
return $denormalized;
}
/**
* @param AccompanyingPeriod $entity
*/
public function storeGenerated(DocGeneratorTemplate $template, StoredObject $storedObject, object $entity, array $contextGenerationData): void
{
$doc = new AccompanyingCourseDocument();

View File

@@ -24,6 +24,8 @@ use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
*
* Although there isn't any document associated to AccompanyingPeriodWork, this context
* is use by @link{AccompanyingPeriodWorkEvaluationContext}.
*
* @implements DocGeneratorContextWithPublicFormInterface<AccompanyingPeriodWork>
*/
class AccompanyingPeriodWorkContext implements DocGeneratorContextWithPublicFormInterface
{
@@ -56,17 +58,11 @@ class AccompanyingPeriodWorkContext implements DocGeneratorContextWithPublicForm
$builder->remove('category');
}
/**
* @param AccompanyingPeriodWork $entity
*/
public function buildPublicForm(FormBuilderInterface $builder, DocGeneratorTemplate $template, $entity): void
{
$this->periodContext->buildPublicForm($builder, $template, $entity->getAccompanyingPeriod());
}
/**
* @param AccompanyingPeriodWork $entity
*/
public function getData(DocGeneratorTemplate $template, $entity, array $contextGenerationData = []): array
{
$data = $this->periodContext->getData($template, $entity->getAccompanyingPeriod(), $contextGenerationData);
@@ -88,9 +84,6 @@ class AccompanyingPeriodWorkContext implements DocGeneratorContextWithPublicForm
return AccompanyingPeriodWork::class;
}
/**
* @param AccompanyingPeriodWork $entity
*/
public function getFormData(DocGeneratorTemplate $template, $entity): array
{
return $this->periodContext->getFormData($template, $entity->getAccompanyingPeriod());
@@ -113,17 +106,17 @@ class AccompanyingPeriodWorkContext implements DocGeneratorContextWithPublicForm
public function hasPublicForm(DocGeneratorTemplate $template, $entity): bool
{
return $this->periodContext->hasPublicForm($template, $entity);
return $this->periodContext->hasPublicForm($template, $entity->getAccompanyingPeriod());
}
public function contextGenerationDataNormalize(DocGeneratorTemplate $template, $entity, array $data): array
{
return $this->periodContext->contextGenerationDataNormalize($template, $entity, $data);
return $this->periodContext->contextGenerationDataNormalize($template, $entity->getAccompanyingPeriod(), $data);
}
public function contextGenerationDataDenormalize(DocGeneratorTemplate $template, $entity, array $data): array
{
return $this->periodContext->contextGenerationDataDenormalize($template, $entity, $data);
return $this->periodContext->contextGenerationDataDenormalize($template, $entity->getAccompanyingPeriod(), $data);
}
public function storeGenerated(DocGeneratorTemplate $template, StoredObject $storedObject, object $entity, array $contextGenerationData): void

View File

@@ -26,6 +26,9 @@ use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
/**
* @implements DocGeneratorContextWithPublicFormInterface<AccompanyingPeriodWorkEvaluation>
*/
class AccompanyingPeriodWorkEvaluationContext implements
DocGeneratorContextWithAdminFormInterface,
DocGeneratorContextWithPublicFormInterface
@@ -102,17 +105,11 @@ class AccompanyingPeriodWorkEvaluationContext implements
]);
}
/**
* @param AccompanyingPeriodWorkEvaluation $entity
*/
public function buildPublicForm(FormBuilderInterface $builder, DocGeneratorTemplate $template, $entity): void
{
$this->accompanyingPeriodWorkContext->buildPublicForm($builder, $template, $entity->getAccompanyingPeriodWork());
}
/**
* @param AccompanyingPeriodWorkEvaluation $entity
*/
public function getData(DocGeneratorTemplate $template, $entity, array $contextGenerationData = []): array
{
$data = $this->accompanyingPeriodWorkContext
@@ -139,9 +136,6 @@ class AccompanyingPeriodWorkEvaluationContext implements
return AccompanyingPeriodWorkEvaluation::class;
}
/**
* @param AccompanyingPeriodWorkEvaluation $entity
*/
public function getFormData(DocGeneratorTemplate $template, $entity): array
{
return $this->accompanyingPeriodWorkContext->getFormData(
@@ -177,13 +171,13 @@ class AccompanyingPeriodWorkEvaluationContext implements
public function contextGenerationDataNormalize(DocGeneratorTemplate $template, $entity, array $data): array
{
return $this->accompanyingPeriodWorkContext
->contextGenerationDataNormalize($template, $entity, $data);
->contextGenerationDataNormalize($template, $entity->getAccompanyingPeriodWork(), $data);
}
public function contextGenerationDataDenormalize(DocGeneratorTemplate $template, $entity, array $data): array
{
return $this->accompanyingPeriodWorkContext
->contextGenerationDataDenormalize($template, $entity, $data);
->contextGenerationDataDenormalize($template, $entity->getAccompanyingPeriodWork(), $data);
}
public function storeGenerated(DocGeneratorTemplate $template, StoredObject $storedObject, object $entity, array $contextGenerationData): void

View File

@@ -249,9 +249,6 @@ final class PersonContext implements PersonContextInterface
];
}
/**
* @param Person $entity
*/
public function storeGenerated(DocGeneratorTemplate $template, StoredObject $storedObject, object $entity, array $contextGenerationData): void
{
$doc = new PersonDocument();

View File

@@ -18,6 +18,9 @@ use Chill\DocStoreBundle\Entity\StoredObject;
use Chill\PersonBundle\Entity\Person;
use Symfony\Component\Form\FormBuilderInterface;
/**
* @template-extends DocGeneratorContextWithPublicFormInterface<Person>
*/
interface PersonContextInterface extends DocGeneratorContextWithAdminFormInterface, DocGeneratorContextWithPublicFormInterface
{
public function adminFormReverseTransform(array $data): array;
@@ -26,10 +29,7 @@ interface PersonContextInterface extends DocGeneratorContextWithAdminFormInterfa
public function buildAdminForm(FormBuilderInterface $builder): void;
/**
* @param Person $entity
*/
public function buildPublicForm(FormBuilderInterface $builder, DocGeneratorTemplate $template, $entity): void;
public function buildPublicForm(FormBuilderInterface $builder, DocGeneratorTemplate $template, mixed $entity): void;
public function getData(DocGeneratorTemplate $template, $entity, array $contextGenerationData = []): array;
@@ -37,7 +37,7 @@ interface PersonContextInterface extends DocGeneratorContextWithAdminFormInterfa
public function getEntityClass(): string;
public function getFormData(DocGeneratorTemplate $template, $entity): array;
public function getFormData(DocGeneratorTemplate $template, mixed $entity): array;
public function getName(): string;
@@ -52,8 +52,5 @@ interface PersonContextInterface extends DocGeneratorContextWithAdminFormInterfa
public function contextGenerationDataDenormalize(DocGeneratorTemplate $template, $entity, array $data): array;
/**
* @param Person $entity
*/
public function storeGenerated(DocGeneratorTemplate $template, StoredObject $storedObject, object $entity, array $contextGenerationData): void;
}

View File

@@ -12,14 +12,19 @@ declare(strict_types=1);
namespace Chill\PersonBundle\Templating\Entity;
use Chill\MainBundle\Templating\Entity\AbstractChillEntityRender;
use Chill\MainBundle\Templating\Entity\BoxUtilsChillEntityRenderTrait;
use Chill\MainBundle\Templating\Entity\ChillEntityRenderInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\PersonBundle\Entity\AccompanyingPeriod\ClosingMotive;
/**
* Render closing motive.
*
* @implements ChillEntityRenderInterface<ClosingMotive>
*/
class ClosingMotiveRender extends AbstractChillEntityRender
class ClosingMotiveRender implements ChillEntityRenderInterface
{
use BoxUtilsChillEntityRenderTrait;
private const SEPARATOR = ' > ';
/**
@@ -40,9 +45,6 @@ class ClosingMotiveRender extends AbstractChillEntityRender
$this->getDefaultClosingBox();
}
/**
* @param ClosingMotive $entity
*/
public function renderString($entity, array $options): string
{
return $this->renderStringRecursive(
@@ -57,12 +59,12 @@ class ClosingMotiveRender extends AbstractChillEntityRender
return $entity instanceof ClosingMotive;
}
protected function renderStringRecursive(ClosingMotive $motive, $existing, array $options)
private function renderStringRecursive(ClosingMotive $motive, string $existing, array $options)
{
$newExisting = $this->translatableStringHelper->localize($motive->getName());
if ($motive->hasParent()) {
if (!empty($existing)) {
if ('' !== $existing) {
$newExisting = $newExisting . self::SEPARATOR . $existing;
}
@@ -73,7 +75,7 @@ class ClosingMotiveRender extends AbstractChillEntityRender
);
}
if (!empty($existing)) {
if ('' !== $existing) {
return $newExisting . self::SEPARATOR . $existing;
}

View File

@@ -12,6 +12,8 @@ declare(strict_types=1);
namespace Chill\PersonBundle\Templating\Entity;
use Chill\MainBundle\Templating\Entity\AbstractChillEntityRender;
use Chill\MainBundle\Templating\Entity\BoxUtilsChillEntityRenderTrait;
use Chill\MainBundle\Templating\Entity\ChillEntityRenderInterface;
use Chill\PersonBundle\Config\ConfigPersonAltNamesHelper;
use Chill\PersonBundle\Entity\Person;
use Symfony\Component\Templating\EngineInterface;
@@ -22,8 +24,9 @@ use function array_key_exists;
/**
* Render a Person.
*/
class PersonRender extends AbstractChillEntityRender implements PersonRenderInterface
class PersonRender implements PersonRenderInterface
{
use BoxUtilsChillEntityRenderTrait;
private ConfigPersonAltNamesHelper $configAltNamesHelper;
private EngineInterface $engine;
@@ -40,9 +43,6 @@ class PersonRender extends AbstractChillEntityRender implements PersonRenderInte
$this->translator = $translator;
}
/**
* @param Person $person
*/
public function renderBox($person, array $options): string
{
$params = [
@@ -72,9 +72,6 @@ class PersonRender extends AbstractChillEntityRender implements PersonRenderInte
$this->getDefaultClosingBox();
}
/**
* @param Person $person
*/
public function renderString($person, array $options): string
{
$options = array_merge(['addAge' => true], $options);

View File

@@ -12,9 +12,12 @@ declare(strict_types=1);
namespace Chill\PersonBundle\Templating\Entity;
use Chill\MainBundle\Templating\Entity\ChillEntityRenderInterface;
use Chill\PersonBundle\Entity\Person;
/**
* Render a Person.
*
* @extends ChillEntityRenderInterface<Person>
*/
interface PersonRenderInterface extends ChillEntityRenderInterface
{

View File

@@ -15,6 +15,9 @@ use Chill\MainBundle\Templating\Entity\ChillEntityRenderInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\PersonBundle\Entity\Person\PersonResourceKind;
/**
* @implements ChillEntityRenderInterface<PersonResourceKind>
*/
final class ResourceKindRender implements ChillEntityRenderInterface
{
private TranslatableStringHelper $translatableStringHelper;

View File

@@ -20,6 +20,9 @@ use function array_merge;
use function array_reverse;
use function implode;
/**
* @implements ChillEntityRenderInterface<SocialAction>
*/
class SocialActionRender implements ChillEntityRenderInterface
{
public const AND_CHILDREN_MENTION = 'show_and_children_mention';

View File

@@ -19,6 +19,9 @@ use Symfony\Contracts\Translation\TranslatorInterface;
use function array_reverse;
use function implode;
/**
* @implements ChillEntityRenderInterface<SocialIssue>
*/
final class SocialIssueRender implements ChillEntityRenderInterface
{
public const AND_CHILDREN_MENTION = 'show_and_children_mention';
@@ -53,9 +56,6 @@ final class SocialIssueRender implements ChillEntityRenderInterface
$this->translator = $translator;
}
/**
* @param SocialIssue $socialIssue
*/
public function renderBox($socialIssue, array $options): string
{
$options = array_merge(self::DEFAULT_ARGS, $options);
@@ -74,9 +74,6 @@ final class SocialIssueRender implements ChillEntityRenderInterface
);
}
/**
* @param SocialIssue $socialIssue
*/
public function renderString($socialIssue, array $options): string
{
/** @var SocialIssue $socialIssue */

View File

@@ -114,7 +114,7 @@ final class AccompanyingPeriodSocialIssueConsistencyEntityListenerTest extends T
protected function generateClass(AccompanyingPeriod $period, Collection $socialIssues): AccompanyingPeriodLinkedWithSocialIssuesEntityInterface
{
return new class($period, $socialIssues) implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterface {
return new class ($period, $socialIssues) implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterface {
public Collection $socialIssues;
public AccompanyingPeriod $period;

View File

@@ -159,7 +159,7 @@ final class PersonDocGenNormalizerTest extends KernelTestCase
$householdMember = new HouseholdMember();
$householdMember
->setPosition((new Position())->setAllowHolder(true)->setLabel(['fr' => 'position'])
->setShareHousehold(true))
->setShareHousehold(true))
->setHolder(true);
$person->addHouseholdParticipation($householdMember);
$household->addMember($householdMember);
@@ -171,7 +171,7 @@ final class PersonDocGenNormalizerTest extends KernelTestCase
$householdMember = new HouseholdMember();
$householdMember
->setPosition((new Position())->setAllowHolder(true)->setLabel(['fr' => 'position2'])
->setShareHousehold(true))
->setShareHousehold(true))
->setHolder(false);
$person->addHouseholdParticipation($householdMember);
$household->addMember($householdMember);

View File

@@ -12,14 +12,12 @@ declare(strict_types=1);
namespace Validator\AccompanyingPeriod;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Templating\Entity\PersonRenderInterface;
use Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod\ParticipationOverlap;
use Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod\ParticipationOverlapValidator;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Chill\ThirdPartyBundle\Templating\Entity\ThirdPartyRender;
use Doctrine\Common\Collections\ArrayCollection;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
use Symfony\Component\Validator\Test\ConstraintValidatorTestCase;
@@ -28,39 +26,92 @@ use Symfony\Component\Validator\Test\ConstraintValidatorTestCase;
* @internal
* @coversNothing
*/
final class ParticipationOverlapValidatorTest extends ConstraintValidatorTestCase
class ParticipationOverlapValidatorTest extends ConstraintValidatorTestCase
{
use ProphecyTrait;
/**
* @return mixed
*/
public function getConstraint()
public function testNoViolation(): void
{
return new ParticipationOverlap();
}
$constraint = $this->getConstraint();
public function testOneParticipation()
{
$period = new AccompanyingPeriod();
$person = new Person();
$person1 = new Person();
$person2 = new Person();
$collection = new ArrayCollection([
new AccompanyingPeriodParticipation($period, $person),
]);
$period->createParticipationFor($person1);
$period->createParticipationFor($person2);
$this->validator->validate($collection, $this->getConstraint());
$this->validator->validate($period->getParticipations(), $constraint);
$this->assertNoViolation();
}
protected function createValidator()
public function testHasTwoParticipationsOverlaps(): void
{
$constraint = $this->getConstraint();
$period = new AccompanyingPeriod();
$person1 = new Person();
$reflectionPerson = new \ReflectionClass($person1);
$personId = $reflectionPerson->getProperty('id');
$personId->setAccessible(true);
$personId->setValue($person1, 1);
$person2 = new Person();
$period->createParticipationFor($person1);
$period->createParticipationFor($person1);
$period->createParticipationFor($person2);
$this->validator->validate($period->getParticipations(), $constraint);
$this->buildViolation('participation-overlaps')
->setParameters([
'{{ start }}' => (new \DateTimeImmutable('today'))->format('d-m-Y'),
'{{ end }}' => null,
'{{ ids }}' => [null, null],
'{{ name }}' => 'person'
])
->assertRaised();
}
public function testHasTwoParticipationsButDoNotOverlaps(): void
{
$constraint = $this->getConstraint();
$period = new AccompanyingPeriod();
$person1 = new Person();
$reflectionPerson = new \ReflectionClass($person1);
$personId = $reflectionPerson->getProperty('id');
$personId->setAccessible(true);
$personId->setValue($person1, 1);
$person2 = new Person();
$participation1 = $period->createParticipationFor($person1);
$period->createParticipationFor($person1);
$participation1->setEndDate(new \DateTime('now'));
$period->createParticipationFor($person2);
$this->validator->validate($period->getParticipations(), $constraint);
$this->assertNoViolation();
}
protected function createValidator(): ParticipationOverlapValidator
{
$personRender = $this->prophesize(PersonRenderInterface::class);
$personRender->renderString(Argument::is(Person::class), [])->willReturn('person');
$personRender->renderString(Argument::type(Person::class), [])
->willReturn('person');
$thirdPartyRender = $this->prophesize(ThirdPartyRender::class);
$thirdPartyRender->renderString(Argument::is(ThirdParty::class), [])->willReturn('thirdparty');
$thirdPartyRender->renderString(Argument::type(ThirdParty::class), [])
->willReturn('third-party');
return new ParticipationOverlapValidator($personRender->reveal(), $thirdPartyRender->reveal());
return new ParticipationOverlapValidator(
$personRender->reveal(),
$thirdPartyRender->reveal()
);
}
public function getConstraint(): ParticipationOverlap
{
return new ParticipationOverlap(['message' => 'participation-overlaps']);
}
}

View File

@@ -61,9 +61,9 @@ class ParticipationOverlapValidator extends ConstraintValidator
throw new UnexpectedTypeException($participation, AccompanyingPeriodParticipation::class);
}
$personId = $participation->getPerson()->getId();
$hashPerson = spl_object_hash($participation->getPerson());
$participationList[$personId][] = $participation;
$participationList[$hashPerson][] = $participation;
}
foreach ($participationList as $group) {
@@ -78,15 +78,14 @@ class ParticipationOverlapValidator extends ConstraintValidator
if ($overlaps->hasIntersections()) {
foreach ($overlaps->getIntersections() as [$start, $end, $ids]) {
$msg = null === $end ? $constraint->message :
$constraint->message;
$msg = $constraint->message;
$this->context->buildViolation($msg)
->setParameters([
'{{ start }}' => $start->format('d-m-Y'),
'{{ end }}' => null === $end ? null : $end->format('d-m-Y'),
'{{ ids }}' => $ids,
'{{ name }}' => $this->personRender->renderString($participation->getPerson(), []),
'{{ name }}' => $this->personRender->renderString($participations[0]->getPerson(), []),
])
->addViolation();
}

View File

@@ -97,6 +97,21 @@ class AccompanyingPeriodWorkEvaluationDocumentWorkflowHandler implements EntityW
return AccompanyingPeriodWorkEvaluationDocumentVoter::SEE;
}
public function getSuggestedUsers(EntityWorkflow $entityWorkflow): array
{
$suggestedUsers = $entityWorkflow->getUsersInvolved();
$referrer = $this->getRelatedEntity($entityWorkflow)
->getAccompanyingPeriodWorkEvaluation()
->getAccompanyingPeriodWork()
->getAccompanyingPeriod()
->getUser();
$suggestedUsers[spl_object_hash($referrer)] = $referrer;
return $suggestedUsers;
}
public function getTemplate(EntityWorkflow $entityWorkflow, array $options = []): string
{
return '@ChillPerson/Workflow/_evaluation_document.html.twig';

View File

@@ -87,6 +87,20 @@ class AccompanyingPeriodWorkEvaluationWorkflowHandler implements EntityWorkflowH
return AccompanyingPeriodWorkEvaluationVoter::SEE;
}
public function getSuggestedUsers(EntityWorkflow $entityWorkflow): array
{
$suggestedUsers = $entityWorkflow->getUsersInvolved();
$referrer = $this->getRelatedEntity($entityWorkflow)
->getAccompanyingPeriodWork()
->getAccompanyingPeriod()
->getUser();
$suggestedUsers[spl_object_hash($referrer)] = $referrer;
return $suggestedUsers;
}
public function getTemplate(EntityWorkflow $entityWorkflow, array $options = []): string
{
return '@ChillPerson/Workflow/_evaluation.html.twig';

View File

@@ -94,6 +94,21 @@ class AccompanyingPeriodWorkWorkflowHandler implements EntityWorkflowHandlerInte
return null;
}
public function getSuggestedUsers(EntityWorkflow $entityWorkflow): array
{
$suggestedUsers = $entityWorkflow->getUsersInvolved();
$referrer = $this->getRelatedEntity($entityWorkflow)
->getAccompanyingPeriod()
->getUser();
if (null !== $referrer) {
$suggestedUsers[spl_object_hash($referrer)] = $referrer;
}
return $suggestedUsers;
}
public function getTemplate(EntityWorkflow $entityWorkflow, array $options = []): string
{
return '@ChillPerson/Workflow/_accompanying_period_work.html.twig';

View File

@@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\Migrations\Person;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
final class Version20230210104424 extends AbstractMigration
{
public function getDescription(): string
{
return 'Add a duration field to accompanyingPeriodWorkEvaluation';
}
public function up(Schema $schema): void
{
$this->addSql('ALTER TABLE chill_person_accompanying_period_work_evaluation ADD timeSpent INT DEFAULT NULL');
}
public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE chill_person_accompanying_period_work_evaluation DROP timeSpent');
}
}

View File

@@ -47,8 +47,8 @@ Phonenumber: 'Numéro de téléphone'
phonenumber: numéro de téléphone
Mobilenumber: 'Numéro de téléphone portable'
mobilenumber: numéro de téléphone portable
Accept short text message ?: La personne a donné l'autorisation d'utiliser ce no de téléphone pour l'envoi de rappel par SMS
Accept short text message: La personne a donné l'autorisation d'utiliser ce no de téléphone pour l'envoi de rappel par SMS
Accept short text message ?: L'usager a donné l'autorisation d'utiliser ce no de téléphone pour l'envoi de rappel par SMS
Accept short text message: L'usager a donné l'autorisation d'utiliser ce no de téléphone pour l'envoi de rappel par SMS
Other phonenumber: Autre numéro de téléphone
Others phone numbers: Autres numéros de téléphone
No additional phone numbers: Aucun numéro de téléphone supplémentaire
@@ -85,9 +85,9 @@ Course number: Parcours n°
Civility: Civilité
choose civility: --
All genders: tous les genres
Any person selected: Aucune personne sélectionnée
Create a household and add an address: Ajouter une adresse pour une personne non suivie et seule dans un ménage
A new household will be created. The person will be member of this household.: Un nouveau ménage va être créé. La personne sera membre de ce ménage.
Any person selected: Aucun usager sélectionné
Create a household and add an address: Ajouter une adresse pour un usager non suivie et seule dans un ménage
A new household will be created. The person will be member of this household.: Un nouveau ménage va être créé. L'usager sera membre de ce ménage.
Comment on the gender: Commentaire sur le genre
genderComment: Commentaire sur le genre
maritalStatus: État civil
@@ -136,10 +136,10 @@ address_country_name: Pays
address_country_code: Code pays
'Alreay existing person': 'Dossiers déjà encodés'
'Add the person': 'Ajouter la personne'
'Add the person and create an accompanying period': "Créer la personne ET créer une période d'accompagnement"
'Add the person and create a household': "Créer la personne ET créer un ménage"
Show person: Voir le dossier de la personne
'Add the person': "Ajouter l'usager"
'Add the person and create an accompanying period': "Créer l'usager et créer un parcours d'accompagnement"
'Add the person and create a household': "Créer l'usager et créer un ménage"
Show person: Voir le dossier de l'usager
'Confirm the creation': 'Confirmer la création'
'You will create this person': 'Vous allez créer le dossier suivant'
Return: Retour
@@ -148,51 +148,51 @@ Reset: 'Remise à zéro'
'The person data has been updated': 'Les données ont été mises à jour.'
'The person data provided are not valid': 'Les données introduites ne sont pas valides'
'{1} The person field %field% is incorrect. Please check. | ]1, Inf] Several person fields are incorrect. Please check.': '{1} Le champs %field% est incorrect. Veuillez le corriger. | ]1, Inf] Plusieurs champs sont incorrects. Veuillez les vérifier.'
'Add a person': 'Ajout d''une personne'
'Person Menu': 'Menu personne'
'Add a person': 'Ajout d''un usager'
'Person Menu': 'Menu usager'
'The person data are not valid': 'Les données de votre formulaire sont invalides.'
'%nb% person with similar name. Please verify that this is a new person': '{1} Une personne a un nom similaire. Vérifiez qu''il ne s''agit pas d''elle. | ]1, Inf] %nb% personnes ont un nom similaire. Vérifiez qu''il ne s''agit pas de l''une d''elles.'
'%nb% person with similar name. Please verify that this is a new person': '{1} Une usager a un nom similaire. Vérifiez qu''il ne s''agit pas d''elle. | ]1, Inf] %nb% usagers ont un nom similaire. Vérifiez qu''il ne s''agit pas de l''une d''elles.'
'The person has been created': 'Le dossier a été créé'
'Person search results': 'Recherche de personnes'
Person search results by phonenumber: Recherche de personnes par numéro de téléphone
'Search within persons': 'Recherche parmi les personnes'
Open person file: Ouvrir le dossier de la personne
'Person search results': 'Recherche de usagers'
Person search results by phonenumber: Recherche d'usager par numéro de téléphone
'Search within persons': 'Recherche parmi les usagers'
Open person file: Ouvrir le dossier de l'usager
and %number% other: '{0} et aucun autre| {1} et une autre |]1, Inf] et %number% autres'
'%total% persons matching the search pattern:': '{0} Aucune personne ne correspond aux termes de recherche : | {1} Une personne a été trouvée par la recherche : | ]1,Inf] %total% personnes correspondent aux termes de recherche :'
'%total% persons matching the search pattern:': '{0} Aucune usager ne correspond aux termes de recherche : | {1} Un usager a été trouvé par la recherche : | ]1,Inf] %total% usagers correspondent aux termes de recherche :'
'Last opening since %last_opening%': 'Dernière ouverture le %last_opening%.'
'Person accompanying period - %name%': 'Historique du dossier - %name%'
'Opening date': 'Date d''ouverture'
'Closing date': 'Date de clôture'
'Period opened': 'Période ouverte'
'Close accompanying period': 'Clôre la période'
'Open accompanying period': 'Ouvrir la période'
'Close accompanying period': 'Clôre le parcours'
'Open accompanying period': 'Ouvrir le parcours'
Period number %number%: 'Période n° %number%'
'Add an accompanying period in the past': Ajouter une période d'accompagnement dans le passé
Begin a new accompanying period: Commencer une nouvelle période d'accompagnement
Create an accompanying period: Créer une période d'accompagnement
'A period has been created.': Une période d'accompagnement a été créée.
'Error! Period not created!': La période d'accompagnement n'a pas été créée.
Update accompanying period: Mettre à jour une période d'accompagnement
'An accompanying period has been updated.': Une période d'accompagnement a été mise à jour
'Error when updating the period': Erreur pendant la mise à jour de la période d'accompagnement.
'An accompanying period has been closed.': Une période d'accompagnement a été fermée.
'Error! Period not closed!': "Erreur: la période d'accompagnement n'a pas été fermée."
'An accompanying period has been opened.': Une période d'accompagnement a été ouverte.
'Add an accompanying period in the past': Ajouter un parcours d'accompagnement dans le passé
Begin a new accompanying period: Commencer un nouveau parcours d'accompagnement
Create an accompanying period: Créer un parcours d'accompagnement
'A period has been created.': Un parcours d'accompagnement a été créé.
'Error! Period not created!': Le parcours d'accompagnement n'a pas été créé.
Update accompanying period: Mettre à jour un parcours d'accompagnement
'An accompanying period has been updated.': Un parcours d'accompagnement a été mise à jour
'Error when updating the period': Erreur pendant la mise à jour du parcours d'accompagnement.
'An accompanying period has been closed.': Un parcours d'accompagnement a été fermée.
'Error! Period not closed!': "Erreur: le parcours d'accompagnement n'a pas été fermé."
'An accompanying period has been opened.': Un parcours d'accompagnement a été ouvert.
'No remark': Pas de remarque
'Period not opened': "La période d'accompagnement n'a pas été ouverte"
"Period not opened : form is invalid": "La période n'a pas été ouverte: le formulaire est invalide."
'Period not opened': "Le parcours d'accompagnement n'a pas été ouvert"
"Period not opened : form is invalid": "Le parcours d'accompagnement n'a pas été ouverte: le formulaire est invalide."
'Closing motive': 'Motif de clôture'
This course is closed: Ce parcours est clôturé
Close accompanying course: Clôturer le parcours
Re-open accompanying course: Ré-ouvrir le parcours
'Person details': 'Détails de la personne'
'Person details': "Détails de l'usager"
'Update details for %name%': 'Modifier détails de %name%'
An accompanying period ends: Une periode d'accompagnement se clôture
An accompanying period starts: Une période d'accompagnement est ouverte
Any accompanying periods are open: Aucune période d'accompagnement ouverte
An accompanying period is open: Une période d'accompagnement est ouverte
Accompanying period list: Périodes d'accompagnement
Accompanying period list for person: Périodes d'accompagnement de la personne
An accompanying period ends: Un parcours d'accompagnement se clôture
An accompanying period starts: Un parcours d'accompagnement est ouvert
Any accompanying periods are open: Aucune parcours d'accompagnement ouvert
An accompanying period is open: Un parcours d'accompagnement est ouvert
Accompanying period list: Parcours d'accompagnement
Accompanying period list for person: Parcours d'accompagnement de l'usager
Accompanying period: Parcours d'accompagnement
Any accompanying period: Aucun parcours d'accompagnement
period: Parcours
@@ -200,17 +200,17 @@ New accompanying course: Nouveau parcours d'accompagnement
Choose a motive: Motif de fermeture
Re-open accompanying period: Ré-ouvrir
Re-Open a period: Ré-ouvrir
Are you sure you want to re-open this period ?: Êtes-vous sûr de vouloir ré-ouvrir cette période d'accompagnement ?
'The period has been re-opened': La période d'accompagnement a été ré-ouverte.
Are you sure you want to re-open this period ?: Êtes-vous sûr de vouloir ré-ouvrir cet parcours d'accompagnement ?
'The period has been re-opened': Le parcours d'accompagnement a été ré-ouverte.
Pediod closing form is not valid: Le formulaire n'est pas valide
Accompanying user: Accompagnant
No accompanying user: Aucun accompagnant
No data given: Pas d'information
Participants: Personnes impliquées
Participants: Usagers impliquées
Create an accompanying course: Créer un parcours
Accompanying courses of users: Parcours des utilisateurs
This accompanying course is still a draft: Ce parcours est encore à l'état brouillon.
Associated peoples: Personnes concernées
Associated peoples: Usagers concernées
Resources: Interlocuteurs privilégiés
Any requestor to this accompanying course: Aucun demandeur pour ce parcours
Social action: Action d'accompagnement
@@ -222,47 +222,47 @@ Social issues: Problématiques sociales
Pick a social issue: Choisir une problématique sociale
Last events on accompanying course: Dernières actions de suivi
Edit & activate accompanying course: Modifier et valider
See accompanying periods: Voir toutes les périodes d'accompagnement
See accompanying period: Voir la période
Edit accompanying period: Modifier la période
See this period: Voir cette période
See accompanying periods: Voir tous les parcours d'accompagnement
See accompanying period: Voir le parcours
Edit accompanying period: Modifier le parcours
See this period: Voir cet parcours
Requestor: Demandeur
No requestor: Pas de demandeur
No resources: "Pas d'interlocuteurs privilégiés"
Persons associated: Personnes concernés
Persons associated: Usagers concernés
Referrer: Référent
Referrers: Agents traitants
Referrer2: Agent traitant
No referrer: Pas d'agent traitant
Some peoples does not belong to any household currently. Add them to an household soon: Certaines personnes n'appartiennent à aucun ménage actuellement. Renseignez leur ménage dès que possible.
Some peoples does not belong to any household currently. Add them to an household soon: Certains usagers n'appartiennent à aucun ménage actuellement. Renseignez leur ménage dès que possible.
Add to household now: Ajouter à un ménage
Any resource for this accompanying course: Aucun interlocuteur privilégié pour ce parcours
course.draft: Brouillon
course.closed: Clôturé
Origin: Origine de la demande
Delete accompanying period: Supprimer la période d'accompagnement
Are you sure you want to remove the accompanying period "%id%" ?: Êtes-vous sûr de vouloir supprimer la période d'accompagnement %id% ?
The accompanying course has been successfully removed.: La période d'accompagnement a été supprimée.
Delete accompanying period: Supprimer le parcours d'accompagnement
Are you sure you want to remove the accompanying period "%id%" ?: Êtes-vous sûr de vouloir supprimer le parcours d'accompagnement %id% ?
The accompanying course has been successfully removed.: Le parcours d'accompagnement a été supprimé.
Concerned scopes: Services concernés
# person resource
person_resources_menu: "Personnes ressources"
Person resources: "Ressources de la personne"
Add a person resource: "Ajouter une ressource"
edit resource: "Modifier ressource"
Remove resource: "Supprimer ressource"
Person resources: "Personnes ressources de l'usager"
Add a person resource: "Ajouter une person ressource"
edit resource: "Modifier la ressource"
Remove resource: "Supprimer la ressource"
Are you sure you want to remove the resource for "%name%" ?: Étes-vous sûr de vouloir supprimer cette ressource de %name%?
The resource has been successfully removed.: "La ressource a été supprimée."
List of resources: "Liste des ressources"
There are no available resources: "Aucun ressource"
List of resources: "Liste des personnes ressources"
There are no available resources: "Aucun personne ressource"
no comment found: "Aucun commentaire"
Select a type: "Choisissez un type"
Select a person: "Choisissez une personne"
Select a person: "Choisissez un usager"
Kind: "Type"
# pickAPersonType
Pick a person: Choisir une personne
Pick a person: Choisir un usager
# Address
No address given: Pas d'adresse renseignée
@@ -277,19 +277,19 @@ New address : Nouvelle adresse
New address for %name% : Nouvelle adresse pour %name%
The new address was created successfully: La nouvelle adresse a été créée
Add an address: Ajouter une adresse
Back to the person details: Retour aux détails de la personne
Back to the person details: Retour aux détails de l'usager
# Residential address
Residential addresses history for %name%: Historique des adresses de résidence de %name%
Residential addresses history: Historique des adresses de résidence
Add a residential address: Ajouter une adresse de résidence
Which kind of residential address would you create ?: Quel type d'adresse de résidence voulez-vous créer?
The address of another person: L'adresse d'une autre personne
The address of another person: L'adresse d'une autre usager
A new address: Une nouvelle adresse
residential_address_person_explanation: L'adresse sera positionnée auprès d'une personne. Lorsque la personne déménage, l'adresse de résidence suivra également cette personne
residential_address_person_explanation: L'adresse sera positionnée auprès d'un usager. Lorsque l'usager déménage, l'adresse de résidence suivra également cette usager
residential_address_new_address_explanation: Créer une nouvelle adresse. L'adresse sera fixe.
New residential address: Nouvelle adresse de résidence
Host person: Choisir l'adresse d'une personne
Host person: Choisir l'adresse d'un usager
The new residential address was created successfully: La nouvelle adresse de résidence a été créée
Edit a residential address: Modifier l'addresse de résidence
The residential address was updated successfully: L'adresse de résidence a été mise à jour
@@ -303,29 +303,29 @@ Residential address had been deleted: L'adresse de résidence a été supprimée
#timeline
Timeline: Historique
Closing the accompanying period: Fermeture de la période d'accompagnement
Opening the accompanying period: Ouverture d'une période d'accompagnement
Closing the accompanying period: Fermeture du parcours d'accompagnement
Opening the accompanying period: Ouverture d'un parcours d'accompagnement
'Timeline for %name%': 'Historique de %name%'
# ROLES
CHILL_PERSON_SEE: Voir les personnes
CHILL_PERSON_UPDATE: Modifier les personnes
CHILL_PERSON_CREATE: Ajouter des personnes
CHILL_PERSON_STATS: Statistiques sur les personnes
CHILL_PERSON_LISTS: Liste des personnes
CHILL_PERSON_DUPLICATE: Gérer les doublons de personnes
CHILL_PERSON_SEE: Voir les usagers
CHILL_PERSON_UPDATE: Modifier les usagers
CHILL_PERSON_CREATE: Ajouter des usagers
CHILL_PERSON_STATS: Statistiques sur les usagers
CHILL_PERSON_LISTS: Liste des usagers
CHILL_PERSON_DUPLICATE: Gérer les doublons d'usagers
CHILL_PERSON_ACCOMPANYING_PERIOD_SEE: Vision simplifiée d'une période d'accompagnement
CHILL_PERSON_ACCOMPANYING_PERIOD_CONFIDENTIAL: Voir et modifier les périodes d'accompagnement confidentielles
CHILL_PERSON_ACCOMPANYING_PERIOD_DELETE: Supprimer une période d'accompagnement
CHILL_PERSON_ACCOMPANYING_PERIOD_SEE: Vision simplifiée d'un parcours d'accompagnement
CHILL_PERSON_ACCOMPANYING_PERIOD_CONFIDENTIAL: Voir et modifier les parcours d'accompagnement confidentielles
CHILL_PERSON_ACCOMPANYING_PERIOD_DELETE: Supprimer un pacours d'accompagnement
CHILL_PERSON_ACCOMPANYING_PERIOD_RE_OPEN: Ré-ouvrir un parcours clotûré
CHILL_PERSON_ACCOMPANYING_PERIOD_TOGGLE_CONFIDENTIAL_ALL: Modifier la confidentialité de tous les parcours
CHILL_PERSON_ACCOMPANYING_PERIOD_CRUD_CONFIDENTIAL: Voir les périodes d'accompagnement confidentielles
CHILL_PERSON_ACCOMPANYING_PERIOD_CREATE: Créer une période d'accompagnement
CHILL_PERSON_ACCOMPANYING_PERIOD_UPDATE: Modifier une période d'accompagnement
CHILL_PERSON_ACCOMPANYING_PERIOD_FULL: Voir les détails, créer, supprimer et mettre à jour une période d'accompagnement
CHILL_PERSON_ACCOMPANYING_PERIOD_CRUD_CONFIDENTIAL: Voir les parcours d'accompagnement confidentiels
CHILL_PERSON_ACCOMPANYING_PERIOD_CREATE: Créer un parcours d'accompagnement
CHILL_PERSON_ACCOMPANYING_PERIOD_UPDATE: Modifier un parcours d'accompagnement
CHILL_PERSON_ACCOMPANYING_PERIOD_FULL: Voir les détails, créer, supprimer et mettre à jour un parcours d'accompagnement
CHILL_PERSON_ACCOMPANYING_COURSE_REASSIGN_BULK: Réassigner les parcours en lot
CHILL_PERSON_ACCOMPANYING_PERIOD_SEE_DETAILS: Voir les détails d'une période d'accompagnement
CHILL_PERSON_ACCOMPANYING_PERIOD_SEE_DETAILS: Voir les détails d'un parcours d'accompagnement
CHILL_PERSON_ACCOMPANYING_PERIOD_STATS: Statistiques sur les parcours d'accompagnement
CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_CREATE: Créer une action d'accompagnement
@@ -342,28 +342,28 @@ CHILL_PERSON_HOUSEHOLD_EDIT: Modifier les ménages
CHILL_PERSON_HOUSEHOLD_STATS: Statistiques sur les ménages
#period
Period closed!: Période clôturée!
Period closed!: Parcours clôturé!
Pediod closing form is not valide: Le formulaire de fermeture n'est pas valide
#widget
## widget person_list
Accompanyied people: Personnes accompagnées
Accompanyied people: Usagers accompagnés
## exports
Exports of persons: Exports des personnes
Count people by various parameters.: Compte le nombre de personnes en fonction de différents filtres.
Count people: Nombre de personnes
List peoples: Liste des personnes
Create a list of people according to various filters.: Crée une liste des personnes selon différents filtres.
Exports of persons: Exports des usagers
Count people by various parameters.: Compte le nombre d'usagers en fonction de différents filtres.
Count people: Nombre d'usagers
List peoples: Liste des usagers
Create a list of people according to various filters.: Crée une liste d'usagers selon différents filtres.
Fields to include in export: Champs à inclure dans l'export
Address valid at this date: Addresse valide à cette date
Data valid at this date: Données valides à cette date
Data regarding center, addresses, and so on will be computed at this date: Les données concernant le centre, l'adresse, le ménage, sera calculé à cette date.
List duplicates: Liste des doublons
Create a list of duplicate people: Créer la liste des personnes détectées comme doublons.
Count people participating in an accompanying course: Nombre de personnes concernées par un parcours
Count people participating in an accompanying course by various parameters.: Compte le nombre de personnes concernées par un parcours
Create a list of duplicate people: Créer la liste des usagers détectés comme doublons.
Count people participating in an accompanying course: Nombre d'usagers concernés par un parcours
Count people participating in an accompanying course by various parameters.: Compte le nombre d'usagers concernées par un parcours
Exports of accompanying courses: Exports des parcours d'accompagnement
Count accompanying courses: Nombre de parcours
@@ -384,33 +384,33 @@ Count evaluation by various parameters.: Compte le nombre d'évaluations selon d
Exports of households: Exports des ménages
## persons filters
Filter by person gender: Filtrer les personnes par genre
Filter by person gender: Filtrer les usagers par genre
Accepted genders: Genres acceptés
'Filtering by genders: only %genders%': 'Filtré par genre: seulement %genders%'
Filter by person's nationality: Filtrer les personnes par nationalité
Filter by person's nationality: Filtrer les usagers par nationalité
Nationalities: Nationalités
Choose countries: Choisir les nationalités
'Filtered by nationality : %nationalities%': 'Filtré par nationalité : seulement %nationalities%'
Filter by person's birthdate: Filtrer les personnes par date de naissance
Filter by person's birthdate: Filtrer les usagers par date de naissance
Born after this date: Nés après cette date
Born before this date: Nés avant cette date
This field should not be empty: Ce champ ne peut pas être vide
This date should be after the date given in "born after" field: Cette date doit être après la date donnée du le champ "nés après le"
"Filtered by person's birthdate: between %date_from% and %date_to%": "Filtré par date de naissance de la personne: uniquement nés entre le %date_from% et %date_to%"
"Filtered by person's birthdate: between %date_from% and %date_to%": "Filtré par date de naissance de l'usager: uniquement nés entre le %date_from% et %date_to%"
Filter by person's deathdate: Filtrer les personnes par date de décès
"Filtered by person's deathdate: between %date_from% and %date_to%": "Filtré par date de naissance de la personne: uniquement nés entre le %date_from% et %date_to%"
Filter by person's deathdate: Filtrer les usagers par date de décès.
"Filtered by person's deathdate: between %date_from% and %date_to%": "Filtré par date de naissance de l'usager: uniquement nés entre le %date_from% et %date_to%"
Death after this date: Décédé après cette date
Deathdate before: Décédé avant cette date
Alive: Vivant
Deceased: Décédé
Filter in relation to this date: Filtrer par rapport à cette date
"Filtered by a state of %deadOrAlive%: at this date %date_calc%": Filtré par personnes qui sont %deadOrAlive% à cette date %date_calc%
"Filtered by a state of %deadOrAlive%: at this date %date_calc%": Filtré par usagers qui sont %deadOrAlive% à cette date %date_calc%
Filter by person's age: Filtrer les personnes par age
"Filtered by person's age: between %min_age% and %max_age%": "Filtré par âge de la personne entre %min_age% et %max_age%"
Filter by person's age: Filtrer les usagers par age.
"Filtered by person's age: between %min_age% and %max_age%": "Filtré par âge de l'usager entre %min_age% et %max_age%"
Minimum age: Âge minimum
Maximum age: Âge maximum
The minimum age should be less than the maximum age.: L'âge minimum doit être plus bas que l'âge maximum.
@@ -420,38 +420,38 @@ Date during which residential address was valid: Date de validité
Family composition: Composition familiale
Family composition at this time: Composition familiale à cette date.
Filter by person's marital status: Filtrer les personnes par état matrimonial
Filter by person's marital status: Filtrer les usagers par état matrimonial
Filtered by person's marital status: Filtré par état matrimonial
Marital status at this time: État matrimonial par rapport à cette date
Filter by entrusted child status: Filtrer les personnes "enfant confié"
Filtered by entrusted child status: Uniquement les personnes qui sont "enfant confié"
Filter by entrusted child status: Filtrer les usagers "enfant confié"
Filtered by entrusted child status: Uniquement les usagers qui sont "enfant confié"
Filter by nomadic status: Filtrer les personnes "gens du voyage"
Filtered by nomadic status: Uniquement les personnes qui sont "gens du voyage"
Filter by nomadic status: Filtrer les usagers "gens du voyage"
Filtered by nomadic status: Uniquement les usagers qui sont "gens du voyage"
"Filter by person's who have a residential address located at another user": Filtrer les personnes qui ont une addresse de résidence chez une autre personne
"Filtered by person's who have a residential address located at another user": Uniquement les personnes qui ont une addresse de résidence chez une autre personne
"Filter by person's who have a residential address located at another user": Filtrer les usagers qui ont une addresse de résidence chez une autre usager
"Filtered by person's who have a residential address located at another user": Uniquement les usagers qui ont une addresse de résidence chez une autre usager
Filter by person's that are alive or have deceased at a certain date: Filtrer les personnes qui sont décédées ou vivantes à une certaine date
Filtered by person's that are alive or have deceased at a certain date: Uniquement les personnes qui sont décédées ou vivantes à une certaine date
Filter by person's that are alive or have deceased at a certain date: Filtrer les usagers qui sont décédés ou vivantes à une certaine date
Filtered by person's that are alive or have deceased at a certain date: Uniquement les usagers qui sont décédés ou vivantes à une certaine date
"Filter by accompanying period: active period": "Filtrer les personnes par période d'accompagnement: en file active"
Having an accompanying period opened after this date: Ayant une période d'accompagnement ouverte après cette date
Having an accompanying period ending before this date, or still opened at this date: Ayant une période d'accompagnement fermée après cette date, ou toujours ouverte à cette date
"Filtered by accompanying period: persons having an accompanying period opened after the %date_from% and closed before the %date_to% (or still opened at the %date_to%)": "Filtré par période d'accompagnement: personnes ayant une période d'accompagnement ouverte après le %date_from%, et cloturée le %date_to% (ou toujours ouverte le %date_to%)"
"Filter by accompanying period: active period": "Filtrer les usagers par parcours d'accompagnement: en file active"
Having an accompanying period opened after this date: Ayant un parcours d'accompagnement ouverte après cette date
Having an accompanying period ending before this date, or still opened at this date: Ayant un parcours d'accompagnement fermée après cette date, ou toujours ouverte à cette date
"Filtered by accompanying period: persons having an accompanying period opened after the %date_from% and closed before the %date_to% (or still opened at the %date_to%)": "Filtré par parcours d'accompagnement: usagers ayant un parcours d'accompagnement ouvert après le %date_from%, et cloturé le %date_to% (ou toujours ouvert le %date_to%)"
"Filter by accompanying period: starting between two dates": "Filtrer les personnes par période d'accompagnement: début de la période entre deux dates"
"Having an accompanying period opened before this date": "Ayant une période d'accompagnement ouverte avant cette date"
"Filtered by accompanying period: persons having an accompanying period opened between the %date_from% and %date_to%": "Filtrer par période d'accompagnement: ayant une période ouverte entre le %date_from% et le %date_to%"
"Filter by accompanying period: starting between two dates": "Filtrer les usagers par parcours d'accompagnement: début de la période entre deux dates"
"Having an accompanying period opened before this date": "Ayant un parcours d'accompagnement ouvert avant cette date"
"Filtered by accompanying period: persons having an accompanying period opened between the %date_from% and %date_to%": "Filtrer par parcours d'accompagnement: ayant un parcours ouvert entre le %date_from% et le %date_to%"
"Filter by accompanying period: closed between two dates": "Filtrer les personnes par période d'accompagnement: période fermée entre deux dates"
Having an accompanying period closed after this date: Ayant une période d'accompagnement fermée après cette date
"Having an accompanying period closed before this date": "Ayant une période d'accompagnement fermée avant cette date"
"Filtered by accompanying period: persons having an accompanying period closed between the %date_from% and %date_to%": "Filtrer par période d'accompagnement: ayant une période fermée entre le %date_from% et le %date_to%"
"Filter by accompanying period: closed between two dates": "Filtrer les usagers par parcours d'accompagnement: parcours fermé entre deux dates"
Having an accompanying period closed after this date: Ayant un parcours d'accompagnement fermé après cette date
"Having an accompanying period closed before this date": "Ayant un parcours d'accompagnement fermé avant cette date"
"Filtered by accompanying period: persons having an accompanying period closed between the %date_from% and %date_to%": "Filtrer par parcours d'accompagnement: ayant un parcours fermé entre le %date_from% et le %date_to%"
Filter by person having an activity in a period: Filtrer les personnes ayant eu une échange pendant la période donnée
Filtered by person having an activity between %date_from% and %date_to% with reasons %reasons_name%: Uniquement les personnes associées à une échange entre %date_from% et %date_to% avec les sujets %reasons_name%
Filter by person having an activity in a period: Filtrer les usagers ayant eu un échange pendant la période donnée
Filtered by person having an activity between %date_from% and %date_to% with reasons %reasons_name%: Uniquement les usagers associés à un échange entre %date_from% et %date_to% avec les sujets %reasons_name%
## accompanying course filters/aggr
@@ -483,8 +483,8 @@ acp_geog_agg_unitname: Zone géographique
acp_geog_agg_unitrefid: Clé de la zone géographique
Geographical layer: Couche géographique
Select a geographical layer: Choisir une couche géographique
Group people by geographical unit based on his address: Grouper les personnes par zone géographique (sur base de l'adresse)
Filter by person's geographical unit (based on address): Filter les personnes par zone géographique (sur base de l'adresse)
Group people by geographical unit based on his address: Grouper les usagers par zone géographique (sur base de l'adresse)
Filter by person's geographical unit (based on address): Filter les usagers par zone géographique (sur base de l'adresse)
Filter by socialaction: Filtrer les parcours par action d'accompagnement
Accepted socialactions: Actions d'accompagnement
@@ -500,9 +500,9 @@ Evaluation: Évaluation
"Filtered by evaluations: only %evals%": "Filtré par évaluation: uniquement %evals%"
Group by evaluation: Grouper les parcours par évaluation
Filter accompanying course by activity type: Filtrer les parcours par type d'activité
Accepted activitytypes: Types d'activités
"Filtered by activity types: only %activitytypes%": "Filtré par type d'activité: seulement %activitytypes%"
Filter accompanying course by activity type: Filtrer les parcours par type d'échange
Accepted activitytypes: Types d'échanges
"Filtered by activity types: only %activitytypes%": "Filtré par type d'échange: seulement %activitytypes%"
Filter by origin: Filtrer les parcours par origine du parcours
Accepted origins: Origines
@@ -520,12 +520,12 @@ Administrative location: Localisation administrative
"Filtered by administratives locations: only %locations%": "Filtré par localisation administrative: uniquement %locations%"
Group by administrative location: Grouper les parcours par localisation administrative
Filter by requestor: Filtrer les parcours selon la présence du demandeur au sein des personnes concernées
Filter by requestor: Filtrer les parcours selon la présence du demandeur au sein des usagers concernés
Accepted choices: ''
is person concerned: Le demandeur est une personne concernée
is other person: Le demandeur est une personne, mais n'est pas concernée
is person concerned: Le demandeur est un usager concerné
is other person: Le demandeur est un usager, mais n'est pas concerné
no requestor: Le parcours ne comporte pas de demandeur
"Filtered by requestor: only %choice%": "Filtré par présence du demandeur au sein des personnes concernées: uniquement si %choice%"
"Filtered by requestor: only %choice%": "Filtré par présence du demandeur au sein des usagers concernés: uniquement si %choice%"
Group by requestor: Grouper les parcours selon la nature du demandeur
Filter by confidential: Filtrer les parcours par confidentialité
@@ -647,24 +647,24 @@ Rounded month duration: Durée en mois (arrondie)
current duration: en cours
duration 0 month: 0 mois (<15 jours)
' months': ' mois'
Group people by nationality: Grouper les personnes par nationalités
Group people by nationality: Grouper les usagers par nationalités
Group by level: Grouper par niveau
Group by continents: Grouper par continent
Group by country: Grouper par pays
Group people by gender: Grouper les personnes par genre
Group people by their professional situation: Grouper les personnes par situation professionelle
Group people by marital status: Grouper les personnes par état matrimonial
Group people by gender: Grouper les usagers par genre
Group people by their professional situation: Grouper les usagers par situation professionelle
Group people by marital status: Grouper les usagers par état matrimonial
Aggregate by household position: Grouper les personnes par position dans le ménage
Aggregate by household position: Grouper les usagers par position dans le ménage
Household position in relation to this date: Position dans le ménage par rapport à cette date
Household position: Position dans le ménage
Aggregate by age: Grouper les personnes par âge
Aggregate by age: Grouper les usagers par âge
Calculate age in relation to this date: Calculer l'âge par rapport à cette date
Group people by country of birth: Grouper les personnes par pays de naissance
Similar persons: Personnes similaires
Group people by country of birth: Grouper les usagers par pays de naissance
Similar persons: Usagers similaires
crud:
closing_motive:
@@ -775,8 +775,8 @@ closing_motive:
any parent: Aucun parent
new child: Nouvel enfant
Person configuration: Configuration du module "Personnes"
Configuration of person bundle: Configuration du module "Personnes"
Person configuration: Configuration du module "Usagers"
Configuration of person bundle: Configuration du module "Usagers"
person_admin:
accompanying_period: Parcours d'accompagnement
What would you like to configure ?: Que souhaitez-vous configurer ?
@@ -784,7 +784,7 @@ person_admin:
closing motives list: Liste des motifs de clotûre
closing motive explanation: >
Les motifs de clotûre donnent des indications sur la fermeture
d'une période d'accompagnement.
d'un parcours d'accompagnement.
origin: Origines
marital status: États civils
marital status list: Liste des états civils
@@ -825,11 +825,11 @@ Edit Accompanying Course: Modifier le parcours
Close Accompanying Course: Clôturer le parcours
Create Accompanying Course: Créer un nouveau parcours
Drop Accompanying Course: Supprimer le parcours
This course is located at a temporarily address. You should locate this course to an user: Le parcours est localisé à une adresse temporaire. Il devrait être localisé auprès d'une personne concernée.
This course is located at a temporarily address. You should locate this course to an user: Le parcours est localisé à une adresse temporaire. Il devrait être localisé auprès d'un usager concerné.
Accompanying course location: Localisation du parcours
This course is located by: Localisé auprès de
This course has a temporarily location: Localisation temporaire
Choose a person to locate by: Localiser auprès d'une personne concernée
Choose a person to locate by: Localiser auprès d'un usager concerné
Associate at least one member with an household, and set an address to this household: Associez au moins un membre du parcours à un ménage, et indiquez une adresse à ce ménage.
Locate by: Localiser auprès de
fix it: Compléter
@@ -884,7 +884,7 @@ Household configuration: Gestion des ménages
# accompanying course work
Accompanying Course Actions: Actions d'accompagnements
Accompanying Course Action: Action d'accompagnement
Are you sure you want to remove this work of the accompanying period %name% ?: Êtes-vous sûr de vouloir supprimer cette action de la période d'accompagnement %name% ?
Are you sure you want to remove this work of the accompanying period %name% ?: Êtes-vous sûr de vouloir supprimer cette action du parcours d'accompagnement %name% ?
The accompanying period work has been successfully removed.: L'action d'accompagnement a été supprimée.
accompanying_course_work:
create: Créer une action
@@ -908,6 +908,7 @@ accompanying_course_work:
remove: Supprimer une action d'accompagnement
social_evaluation: Évaluation
private_comment: Commentaire privé
timeSpent: Temps de rédaction
#
@@ -915,37 +916,37 @@ Person addresses: Adresses de résidence
Household addresses: Adresses de domicile
Insert an address: Insérer une adresse
see social issues: Voir les problématiques sociales
see persons associated: Voir les personnes concernées
see persons associated: Voir les usagers concernés
docgen:
Accompanying Period basic: "Parcours d'accompagnement (basique)"
Accompanying period work: "Action d'accompagnement"
Accompanying period work context: "Evaluation des actions d'accompagnement"
Main person: Personne principale
person 1: Première personne
person 2: Seconde personne
Ask for main person: Demander à l'utilisateur de préciser la personne principale
Ask for person 1: Demander à l'utilisateur de préciser la première personne
Ask for person 2: Demander à l'utilisateur de préciser la seconde personne
Main person: Usager principal
person 1: Premièr usager
person 2: Second usager
Ask for main person: Demander à l'utilisateur de préciser l'usager principal
Ask for person 1: Demander à l'utilisateur de préciser le premièr usager
Ask for person 2: Demander à l'utilisateur de préciser le second usager
A basic context for accompanying period: Contexte pour les parcours
A context for accompanying period work: Contexte pour les actions d'accompagnement
A context for accompanying period work evaluation: Contexte pour les évaluations dans les actions d'accompagnement
Person basic: Personne (basique)
A basic context for person: Contexte pour les personnes
Person basic: Usager (basique)
A basic context for person: Contexte pour les usagers
Label for third party: Label à afficher aux utilisateurs
Document title: Titre du document généré
period_notification:
period_designated_subject: Vous êtes référent d'un parcours d'accompagnement
You are designated to a new period: Vous avez été désigné référent d'un parcours d'accompagnement.
Persons are: Les personnes concernées sont les suivantes
Persons are: Les usagers concernés sont les suivantes
Social issues are: Les problématiques sociales renseignées sont les suivantes
See it online: Visualisez le parcours en ligne
Person locating period has moved: La personne qui localise un parcours a déménagé
Person locating period has moved: L'usager qui localise un parcours a déménagé
You are getting a notification for a period which does not exists any more: Cette notification ne correspond pas à une période d'accompagnement valide.
You are getting a notification for a period you are not allowed to see: La notification fait référence à une période d'accompagnement à laquelle vous n'avez pas accès.
This is the minimal period details: Période d'accompagnement n°
You are getting a notification for a period which does not exists any more: Cette notification ne correspond pas à un parcours d'accompagnement valide.
You are getting a notification for a period you are not allowed to see: La notification fait référence à un parcours d'accompagnement à laquelle vous n'avez pas accès.
This is the minimal period details: Parcours d'accompagnement n°
household_composition:
No composition yet: Aucune composition familiale renseignée
@@ -1009,7 +1010,7 @@ export:
person:
by_household_composition:
Household composition: Composition du ménage
Group course by household composition: Grouper les personnes par composition familiale
Group course by household composition: Grouper les usagers par composition familiale
Calc date: Date de calcul de la composition du ménage
course:
by_referrer:
@@ -1053,13 +1054,13 @@ export:
Filtered by person's geographical unit (based on address) computed at %datecalc%, only %units%: Filtré par unité géographique (sur base de l'adresse), calculé le %datecalc%, seulement %units%
person:
by_composition:
Filter by household composition: Filtrer les personnes par composition du ménage
Filter by household composition: Filtrer les usagers par composition du ménage
Accepted compositions: Composition de ménages
Date calc: Date de calcul
'Filtered by composition at %date%: only %compositions%': 'Filtré par composition du ménage, le %date%, seulement %compositions%'
by_no_composition:
Filter persons without household composition: Filtrer les personnes sans composition de ménage (ni ménage)
Persons filtered by no composition at %date%: Uniquement les personnes sans composition de ménage à la date du %date%
Filter persons without household composition: Filtrer les usagers sans composition de ménage (ni ménage)
Persons filtered by no composition at %date%: Uniquement les usagers sans composition de ménage à la date du %date%
Date calc: Date de calcul
by_address_ref_status:
Filter by person's address ref status: Filtrer par comparaison avec l'adresse de référence
@@ -1083,11 +1084,11 @@ export:
'Filtered by creator job: only %jobs%': 'Filtré par métier du créateur: seulement %jobs%'
list:
person_with_acp:
List peoples having an accompanying period: Liste des personnes ayant un parcours d'accompagnement
Create a list of people having an accompaying periods, according to various filters.: Génère une liste des personnes ayant un parcours d'accompagnement, selon différents critères liés au parcours ou à l'usager
List peoples having an accompanying period: Liste des usagers ayant un parcours d'accompagnement
Create a list of people having an accompaying periods, according to various filters.: Génère une liste des usagers ayant un parcours d'accompagnement, selon différents critères liés au parcours ou à l'usager
acp:
List of accompanying periods: Liste de périodes d'accompagnements
Generate a list of accompanying periods, filtered on different parameters.: Génère une liste des périodes d'accompagnement, filtrée sur différents paramètres.
List of accompanying periods: Liste des parcours d'accompagnements
Generate a list of accompanying periods, filtered on different parameters.: Génère une liste des parcours d'accompagnement, filtrée sur différents paramètres.
Date of calculation for associated elements: Date de calcul des éléments associés
The associated referree, localisation, and other elements will be valid at this date: Les éléments associés, comme la localisation, le référent et d'autres éléments seront valides à cette date
id: Identifiant du parcours
@@ -1114,8 +1115,8 @@ export:
locationPersonId: Identifiant de l'usager auprès duquel le parcours est localisé
acpaddress_fieldscountry: Pays de l'adresse
isRequestorPerson: Le demandeur est-il un usager ?
requestorPersonId: Identifiant du demandeur personne
acprequestorPerson: Nom du demandeur personne
requestorPersonId: Identifiant du demandeur usager
acprequestorPerson: Nom du demandeur usager
scopes: Services
socialIssues: Problématiques sociales
eval:
@@ -1146,6 +1147,7 @@ export:
updatedAt: Date de modification
createdBy: Créé par
updatedBy: Modifié par
timeSpent: Temps de rédaction (minutes)
acpw:
List of accompanying period works: Liste des actions
List description: Génère une liste des actions d'accompagnement, filtrée sur différents paramètres.

View File

@@ -10,7 +10,7 @@
'Opening date can not be null': 'La date d''ouverure ne peut être nulle'
'Closing date is not valid': 'La date de fermeture n''est pas valide'
'Closing date can not be null': 'La date de fermeture ne peut être nulle'
The date of closing is before the date of opening: La période de fermeture est avant la période d'ouverture
The date of closing is before the date of opening: La date de fermeture est avant la date d'ouverture
The closing date must be later than the date of creation: La date de clôture doit être postérieure à la date de création du parcours
The birthdate must be before %date%: La date de naissance doit être avant le %date%
'Invalid phone number: it should begin with the international prefix starting with "+", hold only digits and be smaller than 20 characters. Ex: +33123456789': 'Numéro de téléphone invalide: il doit commencer par le préfixe international précédé de "+", ne comporter que des chiffres et faire moins de 20 caractères. Ex: +31623456789'
@@ -47,19 +47,19 @@ household:
max_holder_overflowed: Il ne peut y avoir plus de deux titulaires simultanément. Or, avec cette modification, ce nombre sera dépassé entre le {{ start }} et le {{ end }}.
household_membership:
The end date must be after start date: La date de la fin de l'appartenance doit être postérieure à la date de début.
Person with membership covering: Une personne ne peut pas appartenir à deux ménages simultanément. Or, avec cette modification, %person_name% appartiendrait à %nbHousehold% ménages à partir du %from%.
Person with membership covering: Un usager ne peut pas appartenir à deux ménages simultanément. Or, avec cette modification, %person_name% appartiendrait à %nbHousehold% ménages à partir du %from%.
# Accompanying period
'{{ name }} is already associated to this accompanying course.': '{{ name }} est déjà associé à ce parcours.'
A course must contains at least one social issue: 'Un parcours doit être associé à au moins une problématique sociale'
A course must be associated to at least one scope: 'Un parcours doit être associé à au moins un service'
The social %name% issue cannot be deleted because it is associated with an activity or an action: 'La problématique sociale "%name%" ne peut pas être supprimée car elle est associée à une activité ou une action'
The social %name% issue cannot be deleted because it is associated with an activity or an action: 'La problématique sociale "%name%" ne peut pas être supprimée car elle est associée à un échange ou une action'
A confidential parcours must have a referrer: 'Un parcours confidentiel doit avoir un référent'
Only the referrer can change the confidentiality of a parcours: 'Seul le référent peut modifier la confidentialité'
# resource
You must associate at least one entity: Associez un usager, un tiers ou indiquez une description libre
You cannot associate a resource with the same person: Vous ne pouvez pas ajouter la personne elle-même en tant que ressource.
You cannot associate a resource with the same person: Vous ne pouvez pas ajouter l'usager lui-même en tant que ressource.
#location
The period must remain located: 'Un parcours doit être localisé'
@@ -67,7 +67,10 @@ The person where the course is located must be associated to the course. Change
#relationship
relationship:
duplicate: Une relation de filiation existe déjà entre ces 2 personnes
duplicate: Une relation de filiation existe déjà entre ces 2 usagers
person_creation:
If you want to create an household, an address is required: Pour la création d'un ménage, une adresse est requise
accompanying_course_work:
The endDate should be greater or equal than the start date: La date de fin doit être égale ou supérieure à la date de début