Merge branch 'master' of gitlab.com:Chill-Projet/chill-bundles

This commit is contained in:
Mathieu Jaumotte 2021-12-20 12:58:35 +01:00
commit 97792fd85f
22 changed files with 128 additions and 73 deletions

View File

@ -7,7 +7,6 @@ and this project adheres to
* [Semantic Versioning](https://semver.org/spec/v2.0.0.html) for stable releases; * [Semantic Versioning](https://semver.org/spec/v2.0.0.html) for stable releases;
* date versioning for test releases * date versioning for test releases
* [accompanyingCourse_work] fix styles conflicts + fix bug with remove goal (remove goals one at a time)
## Unreleased ## Unreleased
@ -17,6 +16,15 @@ and this project adheres to
* docgen: add base context + tests * docgen: add base context + tests
* docgen: add age for person * docgen: add age for person
* [household menu] fix filiation order https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/265 * [household menu] fix filiation order https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/265
* [AddAddress]: optimize loading: wait for the user finish typing;
* [UserPicker]: fix bug with deprecated role
* [docgen]: add base context + tests
* [docgen]: add age for person
* [task]: fix dropdown menu style + fix bug in singleTaskController (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/338)
* Household: fix bug when moving person on the same day (see https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/281)
* Household: show date validFrom and validTo when moving
* address reference: add index for refid
* [accompanyingCourse_work] fix styles conflicts + fix bug with remove goal (remove goals one at a time)
## Test releases ## Test releases

View File

@ -24,7 +24,6 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\Translation\TranslatorInterface; use Symfony\Component\Translation\TranslatorInterface;
/** /**
@ -100,7 +99,7 @@ class DocumentPersonController extends AbstractController
$document, $document,
[ [
'center' => $document->getCenter(), 'center' => $document->getCenter(),
'role' => new Role('CHILL_PERSON_DOCUMENT_UPDATE'), 'role' => 'CHILL_PERSON_DOCUMENT_UPDATE',
] ]
); );
$form->handleRequest($request); $form->handleRequest($request);
@ -160,7 +159,7 @@ class DocumentPersonController extends AbstractController
$reachableScopes = $this->authorizationHelper $reachableScopes = $this->authorizationHelper
->getReachableScopes( ->getReachableScopes(
$this->getUser(), $this->getUser(),
new Role(PersonDocumentVoter::SEE), PersonDocumentVoter::SEE,
$person->getCenter() $person->getCenter()
); );
@ -204,7 +203,7 @@ class DocumentPersonController extends AbstractController
$form = $this->createForm(PersonDocumentType::class, $document, [ $form = $this->createForm(PersonDocumentType::class, $document, [
'center' => $document->getCenter(), 'center' => $document->getCenter(),
'role' => new Role('CHILL_PERSON_DOCUMENT_CREATE'), 'role' => 'CHILL_PERSON_DOCUMENT_CREATE',
]); ]);
$form->handleRequest($request); $form->handleRequest($request);

View File

@ -93,7 +93,7 @@ class PersonDocumentType extends AbstractType
]); ]);
$resolver->setRequired(['role', 'center']) $resolver->setRequired(['role', 'center'])
->setAllowedTypes('role', [\Symfony\Component\Security\Core\Role\Role::class]) ->setAllowedTypes('role', ['string'])
->setAllowedTypes('center', [\Chill\MainBundle\Entity\Center::class]); ->setAllowedTypes('center', [\Chill\MainBundle\Entity\Center::class]);
} }
} }

View File

@ -32,7 +32,11 @@
{{ form_row(form.title) }} {{ form_row(form.title) }}
{{ form_row(form.date) }} {{ form_row(form.date) }}
{{ form_row(form.category) }} {{ form_row(form.category) }}
{% if form.scope is defined %}
{{ form_row(form.scope) }} {{ form_row(form.scope) }}
{% endif %}
{{ form_row(form.description) }} {{ form_row(form.description) }}
{{ form_row(form.object, { 'label': 'Document', 'existing': document.object }) }} {{ form_row(form.object, { 'label': 'Document', 'existing': document.object }) }}

View File

@ -17,7 +17,9 @@ use Symfony\Component\Serializer\Annotation\Groups;
/** /**
* @ORM\Entity * @ORM\Entity
* @ORM\Table(name="chill_main_address_reference") * @ORM\Table(name="chill_main_address_reference", indexes={
* @ORM\Index(name="address_refid", columns={"refId"}, options={"where": "refid != ''"})
* })
* @ORM\HasLifecycleCallbacks * @ORM\HasLifecycleCallbacks
*/ */
class AddressReference class AddressReference

View File

@ -80,7 +80,7 @@ class ScopePickerType extends AbstractType
{ {
$items = $this->authorizationHelper->getReachableScopes( $items = $this->authorizationHelper->getReachableScopes(
$this->security->getUser(), $this->security->getUser(),
$options['role']->getRole(), $options['role'] instanceof Role ? $options['role']->getRole() : $options['role'],
$options['center'] $options['center']
); );

View File

@ -35,6 +35,7 @@ ul.record_actions {
} }
ul.dropdown-menu { ul.dropdown-menu {
z-index: 2000;
li { li {
display: block; display: block;
margin-right: 0; margin-right: 0;

View File

@ -17,6 +17,7 @@ use DateTimeInterface;
use IntlDateFormatter; use IntlDateFormatter;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface; use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use function array_key_exists; use function array_key_exists;
@ -36,15 +37,20 @@ class DateNormalizer implements ContextAwareNormalizerInterface, DenormalizerInt
public function denormalize($data, string $type, ?string $format = null, array $context = []) public function denormalize($data, string $type, ?string $format = null, array $context = [])
{ {
if (null === $data) {
return null;
}
switch ($type) { switch ($type) {
case DateTime::class: case DateTime::class:
return DateTime::createFromFormat(DateTimeInterface::ISO8601, $data['datetime']); return DateTime::createFromFormat(DateTimeInterface::ISO8601, $data['datetime']);
case DateTimeInterface::class: case DateTimeInterface::class:
case DateTimeImmutable::class: case DateTimeImmutable::class:
default:
return DateTimeImmutable::createFromFormat(DateTimeInterface::ISO8601, $data['datetime']); return DateTimeImmutable::createFromFormat(DateTimeInterface::ISO8601, $data['datetime']);
} }
throw new UnexpectedValueException();
} }
public function normalize($date, ?string $format = null, array $context = []) public function normalize($date, ?string $format = null, array $context = [])

View File

@ -0,0 +1,33 @@
<?php
/**
* 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.
*/
declare(strict_types=1);
namespace Chill\Migrations\Main;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
final class Version20211216213649 extends AbstractMigration
{
public function down(Schema $schema): void
{
$this->addSql('DROP INDEX address_refid');
}
public function getDescription(): string
{
return 'add an index on address reference refid';
}
public function up(Schema $schema): void
{
$this->addSql('CREATE INDEX address_refid ON chill_main_address_reference (refId) WHERE refid != \'\'');
}
}

View File

@ -20,7 +20,6 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Role\Role;
use function array_filter; use function array_filter;
use function array_values; use function array_values;
@ -69,13 +68,4 @@ class PersonApiController extends ApiController
return $this->json(array_values($addresses), Response::HTTP_OK, [], ['groups' => ['read']]); return $this->json(array_values($addresses), Response::HTTP_OK, [], ['groups' => ['read']]);
} }
protected function createEntity(string $action, Request $request): object
{
return parent::createEntity($action, $request);
// TODO temporary hack to allow creation of person with fake center
/* $centers = $this->authorizationHelper->getReachableCenters($this->getUser(),
new Role(PersonVoter::CREATE));
$person->setCenter($centers[0]); */
}
} }

View File

@ -131,6 +131,8 @@ final class PersonController extends AbstractController
->getFlashBag()->add('error', $this->translator ->getFlashBag()->add('error', $this->translator
->trans('This form contains errors')); ->trans('This form contains errors'));
} elseif ($form->isSubmitted() && $form->isValid()) { } elseif ($form->isSubmitted() && $form->isValid()) {
$this->em->flush();
$this->get('session')->getFlashBag() $this->get('session')->getFlashBag()
->add( ->add(
'success', 'success',
@ -138,8 +140,6 @@ final class PersonController extends AbstractController
->trans('The person data has been updated') ->trans('The person data has been updated')
); );
$this->em->flush();
return $this->redirectToRoute('chill_person_view', [ return $this->redirectToRoute('chill_person_view', [
'person_id' => $person->getId(), 'person_id' => $person->getId(),
]); ]);
@ -216,9 +216,8 @@ final class PersonController extends AbstractController
); );
} }
$form = $this->createForm(CreationPersonType::class, $person, [ $form = $this->createForm(CreationPersonType::class, $person)
'validation_groups' => ['create'], ->add('editPerson', SubmitType::class, [
])->add('editPerson', SubmitType::class, [
'label' => 'Add the person', 'label' => 'Add the person',
])->add('createPeriod', SubmitType::class, [ ])->add('createPeriod', SubmitType::class, [
'label' => 'Add the person and create an accompanying period', 'label' => 'Add the person and create an accompanying period',

View File

@ -62,9 +62,7 @@ use function in_array;
* @DiscriminatorMap(typeProperty="type", mapping={ * @DiscriminatorMap(typeProperty="type", mapping={
* "person": Person::class * "person": Person::class
* }) * })
* @PersonHasCenter( * @PersonHasCenter
* groups={"general", "creation"}
* )
* @HouseholdMembershipSequential( * @HouseholdMembershipSequential(
* groups={"household_memberships"} * groups={"household_memberships"}
* ) * )
@ -153,12 +151,8 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
* @var DateTime * @var DateTime
* *
* @ORM\Column(type="date", nullable=true) * @ORM\Column(type="date", nullable=true)
* @Assert\Date( * @Assert\Date
* groups={"general", "creation"} * @Birthdate
* )
* @Birthdate(
* groups={"general", "creation"}
* )
*/ */
private $birthdate; private $birthdate;
@ -241,9 +235,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
* @var DateTimeImmutable * @var DateTimeImmutable
* *
* @ORM\Column(type="date_immutable", nullable=true) * @ORM\Column(type="date_immutable", nullable=true)
* @Assert\Date( * @Assert\Date
* groups={"general", "creation"}
* )
* @Assert\GreaterThanOrEqual(propertyPath="birthdate") * @Assert\GreaterThanOrEqual(propertyPath="birthdate")
* @Assert\LessThanOrEqual("today") * @Assert\LessThanOrEqual("today")
*/ */
@ -256,8 +248,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
* *
* @ORM\Column(type="text", nullable=true) * @ORM\Column(type="text", nullable=true)
* @Assert\Email( * @Assert\Email(
* checkMX=true, * checkMX=true
* groups={"general", "creation"}
* ) * )
*/ */
private $email = ''; private $email = '';
@ -268,12 +259,9 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
* @var string * @var string
* *
* @ORM\Column(type="string", length=255) * @ORM\Column(type="string", length=255)
* @Assert\NotBlank( * @Assert\NotBlank
* groups={"general", "creation"}
* )
* @Assert\Length( * @Assert\Length(
* max=255, * max=255,
* groups={"general", "creation"}
* ) * )
*/ */
private $firstName; private $firstName;
@ -294,9 +282,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
* @var string * @var string
* *
* @ORM\Column(type="string", length=9, nullable=true) * @ORM\Column(type="string", length=9, nullable=true)
* @Assert\NotNull( * @Assert\NotNull
* groups={"general", "creation"}
* )
*/ */
private $gender; private $gender;
@ -340,12 +326,9 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
* @var string * @var string
* *
* @ORM\Column(type="string", length=255) * @ORM\Column(type="string", length=255)
* @Assert\NotBlank( * @Assert\NotBlank
* groups={"general", "creation"}
* )
* @Assert\Length( * @Assert\Length(
* max=255, * max=255,
* groups={"general", "creation"}
* ) * )
*/ */
private $lastName; private $lastName;
@ -373,9 +356,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
* @var DateTime * @var DateTime
* *
* @ORM\Column(type="date", nullable=true) * @ORM\Column(type="date", nullable=true)
* @Assert\Date( * @Assert\Date
* groups={"general", "creation"}
* )
*/ */
private ?DateTime $maritalStatusDate = null; private ?DateTime $maritalStatusDate = null;
@ -394,11 +375,9 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
* @ORM\Column(type="text") * @ORM\Column(type="text")
* @Assert\Regex( * @Assert\Regex(
* pattern="/^([\+{1}])([0-9\s*]{4,20})$/", * pattern="/^([\+{1}])([0-9\s*]{4,20})$/",
* groups={"general", "creation"}
* ) * )
* @PhonenumberConstraint( * @PhonenumberConstraint(
* type="mobile", * type="mobile",
* groups={"general", "creation"}
* ) * )
*/ */
private string $mobilenumber = ''; private string $mobilenumber = '';
@ -436,7 +415,6 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
* ) * )
* @Assert\Valid( * @Assert\Valid(
* traverse=true, * traverse=true,
* groups={"general", "creation"}
* ) * )
*/ */
private $otherPhoneNumbers; private $otherPhoneNumbers;
@ -455,11 +433,9 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
* @ORM\Column(type="text") * @ORM\Column(type="text")
* @Assert\Regex( * @Assert\Regex(
* pattern="/^([\+{1}])([0-9\s*]{4,20})$/", * pattern="/^([\+{1}])([0-9\s*]{4,20})$/",
* groups={"general", "creation"}
* ) * )
* @PhonenumberConstraint( * @PhonenumberConstraint(
* type="landline", * type="landline",
* groups={"general", "creation"}
* ) * )
*/ */
private string $phonenumber = ''; private string $phonenumber = '';

View File

@ -21,6 +21,7 @@ use Chill\MainBundle\Form\Type\Select2CountryType;
use Chill\MainBundle\Form\Type\Select2LanguageType; use Chill\MainBundle\Form\Type\Select2LanguageType;
use Chill\MainBundle\Templating\TranslatableStringHelper; use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\PersonBundle\Config\ConfigPersonAltNamesHelper; use Chill\PersonBundle\Config\ConfigPersonAltNamesHelper;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Entity\PersonPhone; use Chill\PersonBundle\Entity\PersonPhone;
use Chill\PersonBundle\Form\Type\GenderType; use Chill\PersonBundle\Form\Type\GenderType;
use Chill\PersonBundle\Form\Type\PersonAltNameType; use Chill\PersonBundle\Form\Type\PersonAltNameType;
@ -234,8 +235,7 @@ class PersonType extends AbstractType
public function configureOptions(OptionsResolver $resolver) public function configureOptions(OptionsResolver $resolver)
{ {
$resolver->setDefaults([ $resolver->setDefaults([
'data_class' => 'Chill\PersonBundle\Entity\Person', 'data_class' => Person::class,
'validation_groups' => ['general', 'creation'],
]); ]);
$resolver->setRequired([ $resolver->setRequired([

View File

@ -13,6 +13,7 @@
openPanesInModal: false, openPanesInModal: false,
stickyActions: true, stickyActions: true,
useValidFrom: true, useValidFrom: true,
useValidTo: true,
} %} } %}
</div> </div>

View File

@ -22,10 +22,8 @@
buttonSize: 'btn-lg', buttonSize: 'btn-lg',
buttonText: 'Move household', buttonText: 'Move household',
modalTitle: 'Move household', modalTitle: 'Move household',
} %}
{#
useValidFrom: true, useValidFrom: true,
#} } %}
</li> </li>
</ul> </ul>

View File

@ -38,6 +38,7 @@
buttonText: 'Move household', buttonText: 'Move household',
modalTitle: 'Move household', modalTitle: 'Move household',
buttonDisplayText: false, buttonDisplayText: false,
useValidFrom: true,
} %} } %}
</li> </li>
<li class="list-inline-item"> <li class="list-inline-item">

View File

@ -63,7 +63,7 @@ class PersonJsonNormalizer implements
{ {
$person = $this->extractObjectToPopulate($type, $context); $person = $this->extractObjectToPopulate($type, $context);
if (array_key_exists('id', $data)) { if (array_key_exists('id', $data) && null === $person) {
$person = $this->repository->find($data['id']); $person = $this->repository->find($data['id']);
if (null === $person) { if (null === $person) {

View File

@ -29,7 +29,7 @@ class MaxHolderValidator extends ConstraintValidator
$covers = new DateRangeCovering( $covers = new DateRangeCovering(
self::MAX_HOLDERS, self::MAX_HOLDERS,
$holders[0]->getStartDate()->getTimezone() $holders->first()->getStartDate()->getTimezone()
); );
foreach ($holders as $key => $member) { foreach ($holders as $key => $member) {

View File

@ -21,8 +21,6 @@ Chill\PersonBundle\Entity\PersonPhone:
phonenumber: phonenumber:
- Regex: - Regex:
pattern: '/^([\+{1}])([0-9\s*]{4,20})$/' pattern: '/^([\+{1}])([0-9\s*]{4,20})$/'
groups: [ general, creation ]
message: 'Invalid phone number: it should begin with the international prefix starting with "+", hold only digits and be smaller than 20 characters. Ex: +33123456789' message: 'Invalid phone number: it should begin with the international prefix starting with "+", hold only digits and be smaller than 20 characters. Ex: +33123456789'
- Chill\MainBundle\Validation\Constraint\PhonenumberConstraint: - Chill\MainBundle\Validation\Constraint\PhonenumberConstraint:
type: any type: any
groups: [ general, creation ]

View File

@ -0,0 +1,35 @@
<?php
/**
* 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.
*/
declare(strict_types=1);
namespace Chill\Migrations\Person;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
final class Version20211216154008 extends AbstractMigration
{
public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE chill_person_household_members DROP CONSTRAINT chill_person_household_members_check');
$this->addSql('ALTER TABLE chill_person_household_members ADD CONSTRAINT chill_person_household_members_check CHECK (startdate < enddate)');
}
public function getDescription(): string
{
return 'Allow a person to be moved into different household on same day';
}
public function up(Schema $schema): void
{
$this->addSql('ALTER TABLE chill_person_household_members DROP CONSTRAINT chill_person_household_members_check');
$this->addSql('ALTER TABLE chill_person_household_members ADD CONSTRAINT chill_person_household_members_check CHECK (startdate <= enddate)');
}
}

View File

@ -590,8 +590,8 @@ final class SingleTaskController extends AbstractController
{ {
$this->denyAccessUnlessGranted(TaskVoter::SHOW, $task); $this->denyAccessUnlessGranted(TaskVoter::SHOW, $task);
if ($person = $task->getContext() instanceof Person) { if ($task->getContext() instanceof Person) {
$event = new PrivacyEvent($person, [ $event = new PrivacyEvent($task->getContext(), [
'element_class' => SingleTask::class, 'element_class' => SingleTask::class,
'element_id' => $task->getId(), 'element_id' => $task->getId(),
'action' => 'show', 'action' => 'show',

View File

@ -21,4 +21,8 @@
text-align: right; text-align: right;
} }
.column {
list-style: none;
}
} }