cs: Fix code style (safe rules only).

This commit is contained in:
Pol Dellaiera
2021-11-23 14:06:38 +01:00
parent 149d7ce991
commit 8f96a1121d
1223 changed files with 65199 additions and 64625 deletions

View File

@@ -1,13 +1,20 @@
<?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.
*/
namespace Chill\PersonBundle\AccompanyingPeriod\SocialIssueConsistency;
use Doctrine\Common\Collections\Collection;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
use Doctrine\Common\Collections\Collection;
/**
* This interface must be implemented on entities which:
* This interface must be implemented on entities which:.
*
* * have both social issue and is linked to an AccompanyingPeriod
* * when the social issues in the entity should be added to the accompanying period

View File

@@ -1,5 +1,12 @@
<?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.
*/
namespace Chill\PersonBundle\AccompanyingPeriod\SocialIssueConsistency;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
@@ -22,37 +29,18 @@ final class AccompanyingPeriodSocialIssueConsistencyEntityListener
$this->ensureConsistencyEntity($entity);
}
public function preUpdate(AccompanyingPeriodLinkedWithSocialIssuesEntityInterface $entity, LifecycleEventArgs $eventArgs)
{
$this->ensureConsistencyEntity($entity);
}
public function prePersistAccompanyingPeriod(AccompanyingPeriod $period, LifecycleEventArgs $eventArgs)
{
$this->ensureConsistencyAccompanyingPeriod($period);
}
public function preUpdateAccompanyingPeriod(AccompanyingPeriod $period, LifecycleEventArgs $eventArgs)
public function preUpdate(AccompanyingPeriodLinkedWithSocialIssuesEntityInterface $entity, LifecycleEventArgs $eventArgs)
{
$this->ensureConsistencyAccompanyingPeriod($period);
$this->ensureConsistencyEntity($entity);
}
private function ensureConsistencyEntity(AccompanyingPeriodLinkedWithSocialIssuesEntityInterface $entity): void
public function preUpdateAccompanyingPeriod(AccompanyingPeriod $period, LifecycleEventArgs $eventArgs)
{
if (NULL === $period = $entity->getAccompanyingPeriod()) {
return;
}
// remove issues parents on the entity itself
$ancestors = SocialIssue::findAncestorSocialIssues($entity->getSocialIssues());
foreach ($ancestors as $ancestor) {
$entity->removeSocialIssue($ancestor);
}
foreach ($entity->getSocialIssues() as $issue) {
// the entity itself test if the social issue is already associated, or not
$period->addSocialIssue($issue);
}
$this->ensureConsistencyAccompanyingPeriod($period);
}
@@ -64,4 +52,24 @@ final class AccompanyingPeriodSocialIssueConsistencyEntityListener
$period->removeSocialIssue($ancestor);
}
}
private function ensureConsistencyEntity(AccompanyingPeriodLinkedWithSocialIssuesEntityInterface $entity): void
{
if (null === $period = $entity->getAccompanyingPeriod()) {
return;
}
// remove issues parents on the entity itself
$ancestors = SocialIssue::findAncestorSocialIssues($entity->getSocialIssues());
foreach ($ancestors as $ancestor) {
$entity->removeSocialIssue($ancestor);
}
foreach ($entity->getSocialIssues() as $issue) {
// the entity itself test if the social issue is already associated, or not
$period->addSocialIssue($issue);
}
$this->ensureConsistencyAccompanyingPeriod($period);
}
}

View File

@@ -1,12 +1,19 @@
<?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.
*/
namespace Chill\PersonBundle\AccompanyingPeriod\Suggestion;
use Chill\MainBundle\Entity\User;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
/**
* Basic implementation: this suggestion does not return any suggestion
* Basic implementation: this suggestion does not return any suggestion.
*/
final class ReferralsSuggestion implements ReferralsSuggestionInterface
{
@@ -16,7 +23,6 @@ final class ReferralsSuggestion implements ReferralsSuggestionInterface
}
/**
* @param AccompanyingPeriod $period
* @return array|User[]
*/
public function findReferralSuggested(AccompanyingPeriod $period, int $limit = 50, int $start = 0): array

View File

@@ -1,12 +1,19 @@
<?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.
*/
namespace Chill\PersonBundle\AccompanyingPeriod\Suggestion;
use Chill\MainBundle\Entity\User;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
/**
* Process the suggestion of referral for a given accompanying period
* Process the suggestion of referral for a given accompanying period.
*/
interface ReferralsSuggestionInterface
{
@@ -16,5 +23,4 @@ interface ReferralsSuggestionInterface
* @return array|User[]
*/
public function findReferralSuggested(AccompanyingPeriod $period, int $limit = 50, int $start = 0): array;
}

View File

@@ -1,73 +1,61 @@
<?php
/*
* Copyright (C) 2016-2019 Champs-Libres <info@champs-libres.coop>
/**
* Chill is a software for social workers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Actions;
use Symfony\Component\EventDispatcher\Event;
/**
* Event triggered when an entity attached to a person is removed.
*
*
*/
class ActionEvent extends Event
{
const DELETE = 'CHILL_PERSON.DELETE_ASSOCIATED_ENTITY';
const MOVE = 'CHILL_PERSON.MOVE_ASSOCIATED_ENTITY';
public const DELETE = 'CHILL_PERSON.DELETE_ASSOCIATED_ENTITY';
public const MOVE = 'CHILL_PERSON.MOVE_ASSOCIATED_ENTITY';
/**
*
* @var int
*/
protected $personId;
/**
* the FQDN class name as recorded in doctrine
* the FQDN class name as recorded in doctrine.
*
* @var string
*/
protected $entity;
/**
* an array of key value data to describe the movement
* an array of key value data to describe the movement.
*
* @var array
*/
protected $metadata;
/**
* the sql statement
*
* @var string
* @var int
*/
protected $sqlStatement;
protected $personId;
/**
*
* @var string[]
*/
protected $preSql = [];
/**
*
* @var string[]
*/
protected $postSql = [];
/**
* @var string[]
*/
protected $preSql = [];
/**
* the sql statement.
*
* @var string
*/
protected $sqlStatement;
public function __construct($personId, $entity, $sqlStatement, $metadata = [])
{
$this->personId = $personId;
@@ -77,21 +65,17 @@ class ActionEvent extends Event
}
/**
*
* @return string[]
* Add Sql which will be executed **after** the delete statement.
*
* @param type $postSql
*
* @return $this
*/
public function getPreSql(): array
public function addPostSql(string $postSql)
{
return $this->preSql;
}
$this->postSql[] = $postSql;
/**
*
* @return string[]
*/
public function getPostSql(): array
{
return $this->postSql;
return $this;
}
/*
@@ -100,19 +84,21 @@ class ActionEvent extends Event
public function addPreSql(string $preSql)
{
$this->preSql[] = $preSql;
return $this;
}
/**
* Add Sql which will be executed **after** the delete statement
*
* @param type $postSql
* @return $this
* get the entity name, as recorded in doctrine.
*/
public function addPostSql(string $postSql)
public function getEntity(): string
{
$this->postSql[] = $postSql;
return $this;
return $this->entity;
}
public function getMetadata()
{
return $this->metadata;
}
public function getPersonId(): int
@@ -121,23 +107,23 @@ class ActionEvent extends Event
}
/**
* get the entity name, as recorded in doctrine
*
* @return string
* @return string[]
*/
public function getEntity(): string
public function getPostSql(): array
{
return $this->entity;
return $this->postSql;
}
/**
* @return string[]
*/
public function getPreSql(): array
{
return $this->preSql;
}
public function getSqlStatement()
{
return $this->sqlStatement;
}
public function getMetadata()
{
return $this->metadata;
}
}

View File

@@ -1,54 +1,45 @@
<?php
/*
* Copyright (C) 2016-2019 Champs-Libres <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Chill\PersonBundle\Actions\Remove;
use Doctrine\ORM\EntityManagerInterface;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Doctrine\ORM\Mapping\ClassMetadata;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Chill\PersonBundle\Actions\ActionEvent;
/**
* Move or delete entities associated to a person to a new one, and delete the
* old person. The data associated to a person (birthdate, name, ...) are left
* untouched on the "new one".
*
* See `getSql` for details.
*
* 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\PersonBundle\Actions\Remove;
use Chill\PersonBundle\Actions\ActionEvent;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\Person;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping\ClassMetadata;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use function array_merge;
use function implode;
use function in_array;
/**
* Move or delete entities associated to a person to a new one, and delete the
* old person. The data associated to a person (birthdate, name, ...) are left
* untouched on the "new one".
*
* See `getSql` for details.
*/
class PersonMove
{
/**
*
* @var EntityManagerInterface
*/
protected $em;
/**
*
* @var EventDispatcherInterface
*/
protected $eventDispatcher;
public function __construct(
EntityManagerInterface $em,
EntityManagerInterface $em,
EventDispatcherInterface $eventDispatcher
) {
$this->em = $em;
@@ -56,128 +47,136 @@ class PersonMove
}
/**
* Return the sql used to move or delete entities associated to a person to
* a new one, and delete the old person. The data associated to a person
* Return the sql used to move or delete entities associated to a person to
* a new one, and delete the old person. The data associated to a person
* (birthdate, name, ...) are left untouched on the "new one".
*
* The accompanying periods associated to a person are always removed. The other
*
* The accompanying periods associated to a person are always removed. The other
* associated entity are updated: the new person id is associated to the entity.
*
*
* Optionnaly, you can ask for removing entity by passing them in $deleteEntities
* parameters.
*
* parameters.
*
* The following events are triggered:
* - `'CHILL_PERSON.DELETE_ASSOCIATED_ENTITY'` is triggered when an entity
* will be removed ;
* - `'CHILL_PERSON.MOVE_ASSOCIATED_ENTITY'` is triggered when an entity
* will be moved ;
*
*
* Those events have the following metadata:
*
*
* - 'original_action' : always 'move' ;
* - 'to': the person id to move ;
*
* @param Person $from
* @param Person $to
* @param array $deleteEntities
*
* @return type
*/
public function getSQL(Person $from, Person $to, array $deleteEntities = [])
{
$sqls = [];
$toDelete = \array_merge($deleteEntities, $this->getDeleteEntities());
$toDelete = array_merge($deleteEntities, $this->getDeleteEntities());
foreach ($this->em->getMetadataFactory()->getAllMetadata() as $metadata) {
if ($metadata->isMappedSuperclass) {
continue;
}
foreach ($metadata->getAssociationMappings() as $field => $mapping) {
if ($mapping['targetEntity'] === Person::class) {
if (\in_array($metadata->getName(), $toDelete)) {
if (Person::class === $mapping['targetEntity']) {
if (in_array($metadata->getName(), $toDelete)) {
$sql = $this->createDeleteSQL($metadata, $from, $field);
$event = new ActionEvent($from->getId(), $metadata->getName(), $sql,
['to' => $to->getId(), 'original_action' => 'move']);
$event = new ActionEvent(
$from->getId(),
$metadata->getName(),
$sql,
['to' => $to->getId(), 'original_action' => 'move']
);
$this->eventDispatcher->dispatch(ActionEvent::DELETE, $event);
} else {
$sql = $this->createMoveSQL($metadata, $from, $to, $field);
$event = new ActionEvent($from->getId(), $metadata->getName(), $sql,
['to' => $to->getId(), 'original_action' => 'move']);
$event = new ActionEvent(
$from->getId(),
$metadata->getName(),
$sql,
['to' => $to->getId(), 'original_action' => 'move']
);
$this->eventDispatcher->dispatch(ActionEvent::MOVE, $event);
}
$sqls = \array_merge($sqls, $event->getPreSql(), [$event->getSqlStatement()], $event->getPostSql());
$sqls = array_merge($sqls, $event->getPreSql(), [$event->getSqlStatement()], $event->getPostSql());
}
}
}
$personMetadata = $this->em->getClassMetadata(Person::class);
$sqls[] = sprintf("DELETE FROM %s WHERE id = %d",
$sqls[] = sprintf(
'DELETE FROM %s WHERE id = %d',
$this->getTableName($personMetadata),
$from->getId());
$from->getId()
);
return $sqls ?? [];
}
protected function createMoveSQL(ClassMetadata $metadata, Person $from, Person $to, $field): string
{
$mapping = $metadata->getAssociationMapping($field);
// Set part of the query, aka <here> in "UPDATE table SET <here> "
$sets = [];
foreach ($mapping["joinColumns"] as $columns) {
$sets[] = sprintf("%s = %d", $columns["name"], $to->getId());
}
$conditions = [];
foreach ($mapping["joinColumns"] as $columns) {
$conditions[] = sprintf("%s = %d", $columns["name"], $from->getId());
}
return \sprintf("UPDATE %s SET %s WHERE %s",
$this->getTableName($metadata),
\implode(" ", $sets),
\implode(" AND ", $conditions)
);
}
protected function createDeleteSQL(ClassMetadata $metadata, Person $from, $field): string
{
$mapping = $metadata->getAssociationMapping($field);
$conditions = [];
foreach ($mapping["joinColumns"] as $columns) {
$conditions[] = sprintf("%s = %d", $columns["name"], $from->getId());
foreach ($mapping['joinColumns'] as $columns) {
$conditions[] = sprintf('%s = %d', $columns['name'], $from->getId());
}
return \sprintf("DELETE FROM %s WHERE %s",
return \sprintf(
'DELETE FROM %s WHERE %s',
$this->getTableName($metadata),
\implode(" AND ", $conditions)
);
implode(' AND ', $conditions)
);
}
protected function createMoveSQL(ClassMetadata $metadata, Person $from, Person $to, $field): string
{
$mapping = $metadata->getAssociationMapping($field);
// Set part of the query, aka <here> in "UPDATE table SET <here> "
$sets = [];
foreach ($mapping['joinColumns'] as $columns) {
$sets[] = sprintf('%s = %d', $columns['name'], $to->getId());
}
$conditions = [];
foreach ($mapping['joinColumns'] as $columns) {
$conditions[] = sprintf('%s = %d', $columns['name'], $from->getId());
}
return \sprintf(
'UPDATE %s SET %s WHERE %s',
$this->getTableName($metadata),
implode(' ', $sets),
implode(' AND ', $conditions)
);
}
/**
* return an array of classes where entities should be deleted
* instead of moved
*
* @return array
* return an array of classes where entities should be deleted
* instead of moved.
*/
protected function getDeleteEntities(): array
{
return [
AccompanyingPeriod::class
AccompanyingPeriod::class,
];
}
/**
* get the full table name with schema if it does exists
* get the full table name with schema if it does exists.
*/
private function getTableName(ClassMetadata $metadata): string
{
return empty($metadata->getSchemaName()) ?
$metadata->getTableName() :
$metadata->getSchemaName().".".$metadata->getTableName();
return empty($metadata->getSchemaName()) ?
$metadata->getTableName() :
$metadata->getSchemaName() . '.' . $metadata->getTableName();
}
}

View File

@@ -1,113 +1,125 @@
<?php
/*
* Copyright (C) 2016-2019 Champs-Libres <info@champs-libres.coop>
/**
* Chill is a software for social workers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\CRUD\Controller;
use Chill\MainBundle\CRUD\Controller\CRUDController;
use Symfony\Component\HttpFoundation\Request;
use Chill\PersonBundle\Entity\Person;
use Doctrine\ORM\QueryBuilder;
use Exception;
use Symfony\Component\HttpFoundation\Request;
use function array_merge;
/**
* Class EntityPersonCRUDController
* CRUD Controller for entities attached to a Person
*
* @package Chill\PersonBundle\CRUD\Controller
* CRUD Controller for entities attached to a Person.
*/
class EntityPersonCRUDController extends CRUDController
{
/**
* Extract the person from the request
*
* the person parameter will be `person_id` and must be
* Override the base method to add a filtering step to a person.
*
* @return QueryBuilder
*/
protected function buildQueryEntities(string $action, Request $request)
{
$qb = parent::buildQueryEntities($action, $request);
return $this->filterQueryEntitiesByPerson($action, $qb, $request);
}
/**
* @param \Chill\MainBundle\CRUD\Controller\string|string $action
*/
protected function createEntity($action, Request $request): object
{
$entity = parent::createEntity($action, $request);
$person = $this->getPerson($request);
$entity->setPerson($person);
return $entity;
}
/**
* Add a where clause to the buildQuery.
*
* @param \Chill\PersonBundle\CRUD\Controller\QueryBuilder $qb
*
* @return \Chill\PersonBundle\CRUD\Controller\QueryBuilder
*/
protected function filterQueryEntitiesByPerson(string $action, QueryBuilder $qb, Request $request): QueryBuilder
{
$qb->andWhere($qb->expr()->eq('e.person', ':person'));
$qb->setParameter('person', $this->getPerson($request));
return $qb;
}
/**
* @param mixed $entity
*
* @throws Exception
*/
protected function generateTemplateParameter(string $action, $entity, Request $request, array $defaultTemplateParameters = []): array
{
$person = $this->getPerson($request);
if (null === $person) {
throw new Exception('the `person_id` parameter is not set in the query. '
. 'You should set it or override the current method to allow another '
. 'behaviour: ' . __METHOD__);
}
return parent::generateTemplateParameter(
$action,
$entity,
$request,
array_merge(['person' => $person], $defaultTemplateParameters)
);
}
/**
* Extract the person from the request.
*
* the person parameter will be `person_id` and must be
* present in the query
*
*
* If the parameter is not set, this method will return null.
*
* If the person id does not exists, the method will throw a
*
* If the person id does not exists, the method will throw a
* Symfony\Component\HttpKernel\Exception\NotFoundHttpException
*
* @param Request $request
*
* @throws Symfony\Component\HttpKernel\Exception\NotFoundHttpException if the person with given id is not found
*/
protected function getPerson(Request $request): ?Person
{
if (FALSE === $request->query->has('person_id')) {
if (false === $request->query->has('person_id')) {
return null;
}
$person = $this->getDoctrine()
->getRepository(Person::class)
->find($request->query->getInt('person_id'))
;
if (NULL === $person) {
->find($request->query->getInt('person_id'));
if (null === $person) {
throw $this->createNotFoundException('the person with this id is not found');
}
return $person;
}
/**
* @param \Chill\MainBundle\CRUD\Controller\string|string $action
* @param Request $request
* @return object
*/
protected function createEntity($action, Request $request): object
{
$entity = parent::createEntity($action, $request);
$person = $this->getPerson($request);
$entity->setPerson($person);
return $entity;
}
/**
* @param string $action
* @param mixed $entity
* @param Request $request
* @param array $defaultTemplateParameters
* @return array
* @throws \Exception
*/
protected function generateTemplateParameter(string $action, $entity, Request $request, array $defaultTemplateParameters = array()): array
{
$person = $this->getPerson($request);
if (NULL === $person) {
throw new \Exception("the `person_id` parameter is not set in the query. "
. "You should set it or override the current method to allow another "
. "behaviour: ".__METHOD__);
}
return parent::generateTemplateParameter(
$action,
$entity,
$request,
\array_merge([ 'person' => $person ], $defaultTemplateParameters)
);
}
/**
* @param string $action
* @param mixed $entity
* @param Request $request
*
* @return string
*/
protected function getTemplateFor($action, $entity, Request $request)
@@ -115,83 +127,59 @@ class EntityPersonCRUDController extends CRUDController
if ($this->hasCustomTemplate($action, $entity, $request)) {
return $this->getActionConfig($action)['template'];
}
switch ($action) {
case 'new':
return '@ChillPerson/CRUD/new.html.twig';
case 'edit':
case 'edit':
return '@ChillPerson/CRUD/edit.html.twig';
case 'view':
return '@ChillPerson/CRUD/view.html.twig';
case 'delete':
return '@ChillPerson/CRUD/delete.html.twig';
case 'index':
return '@ChillPerson/CRUD/index.html.twig';
default:
return parent::getTemplateFor($action, $entity, $request);
}
}
/**
* @param string $action
* @param mixed $entity
* @param \Symfony\Component\Form\FormInterface $form
* @param Request $request
*
* @return \Symfony\Component\HttpFoundation\RedirectResponse
*/
protected function onBeforeRedirectAfterSubmission(string $action, $entity, \Symfony\Component\Form\FormInterface $form, Request $request)
{
$next = $request->request->get("submit", "save-and-close");
$next = $request->request->get('submit', 'save-and-close');
switch ($next) {
case "save-and-close":
return $this->redirectToRoute('chill_crud_'.$this->getCrudName().'_index', [
'person_id' => $this->getPerson($request)->getId()
case 'save-and-close':
return $this->redirectToRoute('chill_crud_' . $this->getCrudName() . '_index', [
'person_id' => $this->getPerson($request)->getId(),
]);
case "save-and-new":
return $this->redirectToRoute('chill_crud_'.$this->getCrudName().'_new', [
'person_id' => $this->getPerson($request)->getId()
case 'save-and-new':
return $this->redirectToRoute('chill_crud_' . $this->getCrudName() . '_new', [
'person_id' => $this->getPerson($request)->getId(),
]);
case "new":
return $this->redirectToRoute('chill_crud_'.$this->getCrudName().'_view', [
case 'new':
return $this->redirectToRoute('chill_crud_' . $this->getCrudName() . '_view', [
'id' => $entity->getId(),
'person_id' => $this->getPerson($request)->getId()
'person_id' => $this->getPerson($request)->getId(),
]);
default:
return $this->redirectToRoute('chill_crud_'.$this->getCrudName().'_view', [
return $this->redirectToRoute('chill_crud_' . $this->getCrudName() . '_view', [
'id' => $entity->getId(),
'person_id' => $this->getPerson($request)->getId()
]);
'person_id' => $this->getPerson($request)->getId(),
]);
}
}
/**
* Override the base method to add a filtering step to a person.
*
* @param string $action
* @param Request $request
* @return QueryBuilder
*/
protected function buildQueryEntities(string $action, Request $request)
{
$qb = parent::buildQueryEntities($action, $request);
return $this->filterQueryEntitiesByPerson($action, $qb, $request);
}
/**
* Add a where clause to the buildQuery
*
* @param string $action
* @param \Chill\PersonBundle\CRUD\Controller\QueryBuilder $qb
* @param Request $request
* @return \Chill\PersonBundle\CRUD\Controller\QueryBuilder
*/
protected function filterQueryEntitiesByPerson(string $action, QueryBuilder $qb, Request $request): QueryBuilder
{
$qb->andWhere($qb->expr()->eq('e.person', ':person'));
$qb->setParameter('person', $this->getPerson($request));
return $qb;
}
}

View File

@@ -1,44 +1,37 @@
<?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\PersonBundle\CRUD\Controller;
use Chill\MainBundle\CRUD\Controller\CRUDController;
use Symfony\Component\HttpFoundation\Request;
use Chill\PersonBundle\Entity\Person;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\RedirectResponse;
use BadMethodCallException;
use Chill\MainBundle\CRUD\Controller\CRUDController;
use Chill\PersonBundle\Entity\Person;
use LogicException;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class OneToOneEntityPersonCRUDController extends CRUDController
{
protected function getTemplateFor($action, $entity, Request $request)
protected function generateRedirectOnCreateRoute($action, Request $request, $entity)
{
if (!empty($this->crudConfig[$action]['template'])) {
return $this->crudConfig[$action]['template'];
}
switch ($action) {
case 'new':
return '@ChillPerson/CRUD/new.html.twig';
case 'edit':
return '@ChillPerson/CRUD/edit.html.twig';
case 'index':
return '@ChillPerson/CRUD/index.html.twig';
default:
throw new \LogicException("the view for action $action is not "
. "defined. You should override ".__METHOD__." to add this "
. "action");
}
throw new BadMethodCallException('Not implemented yet.');
}
protected function getEntity($action, $id, Request $request): ?object
{
$entity = parent::getEntity($action, $id, $request);
if (NULL === $entity) {
if (null === $entity) {
$entity = $this->createEntity($action, $request);
$person = $this->getDoctrine()
->getManager()
@@ -51,23 +44,40 @@ class OneToOneEntityPersonCRUDController extends CRUDController
return $entity;
}
protected function onPreFlush(string $action, $entity, FormInterface $form, Request $request)
protected function getTemplateFor($action, $entity, Request $request)
{
$this->getDoctrine()->getManager()->persist($entity);
if (!empty($this->crudConfig[$action]['template'])) {
return $this->crudConfig[$action]['template'];
}
switch ($action) {
case 'new':
return '@ChillPerson/CRUD/new.html.twig';
case 'edit':
return '@ChillPerson/CRUD/edit.html.twig';
case 'index':
return '@ChillPerson/CRUD/index.html.twig';
default:
throw new LogicException("the view for action {$action} is not "
. 'defined. You should override ' . __METHOD__ . ' to add this '
. 'action');
}
}
protected function onPostFetchEntity($action, Request $request, $entity): ?Response
{
if (FALSE === $this->getDoctrine()->getManager()->contains($entity)) {
if (false === $this->getDoctrine()->getManager()->contains($entity)) {
return new RedirectResponse($this->generateRedirectOnCreateRoute($action, $request, $entity));
}
return null;
}
protected function generateRedirectOnCreateRoute($action, Request $request, $entity)
protected function onPreFlush(string $action, $entity, FormInterface $form, Request $request)
{
throw new BadMethodCallException('Not implemented yet.');
$this->getDoctrine()->getManager()->persist($entity);
}
}

View File

@@ -1,21 +1,28 @@
<?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.
*/
namespace Chill\PersonBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Chill\PersonBundle\Widget\PersonListWidgetFactory;
use Chill\PersonBundle\DependencyInjection\CompilerPass\AccompanyingPeriodTimelineCompilerPass;
use Chill\PersonBundle\Widget\PersonListWidgetFactory;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class ChillPersonBundle extends Bundle
{
public function build(ContainerBuilder $container)
public function build(ContainerBuilder $container)
{
parent::build($container);
$container->getExtension('chill_main')
->addWidgetFactory(new PersonListWidgetFactory());
$container->addCompilerPass(new AccompanyingPeriodTimelineCompilerPass());
}
}

View File

@@ -1,24 +1,32 @@
<?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.
*/
namespace Chill\PersonBundle\Command;
use Chill\PersonBundle\Actions\Remove\PersonMove;
use Chill\PersonBundle\Entity\Person;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Chill\PersonBundle\Actions\Remove\PersonMove;
use Doctrine\ORM\EntityManagerInterface;
use Chill\PersonBundle\Entity\Person;
use Symfony\Component\Console\Exception\RuntimeException;
use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Command\Command;
use function ctype_digit;
final class ChillPersonMoveCommand extends Command
{
private PersonMove $mover;
private LoggerInterface $chillLogger;
private EntityManagerInterface $em;
private LoggerInterface $chillLogger;
private PersonMove $mover;
public function __construct(
PersonMove $mover,
@@ -32,64 +40,64 @@ final class ChillPersonMoveCommand extends Command
$this->chillLogger = $chillLogger;
}
protected function buildLoggingContext(Person $from, Person $to, $deleteEntities, $sqls)
{
$ctxt = [
'from' => $from->getId(),
'to' => $to->getId(),
];
foreach ($deleteEntities as $key => $de) {
$ctxt['delete_entity_' . $key] = $de;
}
foreach ($sqls as $key => $sql) {
$ctxt['sql_' . $key] = $sql;
}
return $ctxt;
}
protected function configure()
{
$this
->setName('chill:person:move')
->setDescription('Move all the associated entities on a "from" person to a "to" person and remove the old person')
->addOption('from', 'f', InputOption::VALUE_REQUIRED, "The person id to delete, all associated data will be moved before")
->addOption('to', 't', InputOption::VALUE_REQUIRED, "The person id which will received data")
->addOption('dump-sql', null, InputOption::VALUE_NONE, "dump sql to stdout")
->addOption('force', null, InputOption::VALUE_NONE, "execute sql instead of dumping it")
->addOption('delete-entity', null, InputOption::VALUE_REQUIRED|InputOption::VALUE_IS_ARRAY, "entity to delete", [])
;
}
protected function interact(InputInterface $input, OutputInterface $output)
{
if (FALSE === $input->hasOption('dump-sql') && FALSE === $input->hasOption('force')) {
$msg = "You must use \"--dump-sql\" or \"--force\"";
throw new RuntimeException($msg);
}
foreach (["from", "to"] as $name) {
if (empty($input->getOption($name))) {
throw new RuntimeException("You must set a \"$name\" option");
}
$id = $input->getOption($name);
if (\ctype_digit($id) === FALSE) {
throw new RuntimeException("The id in \"$name\" field does not contains "
. "only digits: $id");
}
}
->addOption('from', 'f', InputOption::VALUE_REQUIRED, 'The person id to delete, all associated data will be moved before')
->addOption('to', 't', InputOption::VALUE_REQUIRED, 'The person id which will received data')
->addOption('dump-sql', null, InputOption::VALUE_NONE, 'dump sql to stdout')
->addOption('force', null, InputOption::VALUE_NONE, 'execute sql instead of dumping it')
->addOption('delete-entity', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'entity to delete', []);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$repository = $this->em->getRepository(Person::class);
$from = $repository->find($input->getOption('from'));
$to = $repository->find($input->getOption('to'));
$to = $repository->find($input->getOption('to'));
$deleteEntities = $input->getOption('delete-entity');
if ($from === NULL) {
throw new RuntimeException(sprintf("Person \"from\" with id %d not found", $input->getOption('from')));
if (null === $from) {
throw new RuntimeException(sprintf('Person "from" with id %d not found', $input->getOption('from')));
}
if ($to === NULL) {
throw new RuntimeException(sprintf("Person \"to\" with id %d not found", $input->getOption('to')));
if (null === $to) {
throw new RuntimeException(sprintf('Person "to" with id %d not found', $input->getOption('to')));
}
$sqls = $this->mover->getSQL($from, $to, $deleteEntities);
if ($input->getOption('dump-sql')) {
foreach($sqls as $sql) {
foreach ($sqls as $sql) {
$output->writeln($sql);
}
} else {
$ctxt = $this->buildLoggingContext($from, $to, $deleteEntities, $sqls);
$this->chillLogger->notice("Trying to move a person from command line", $ctxt);
$this->chillLogger->notice('Trying to move a person from command line', $ctxt);
$connection = $this->em->getConnection();
$connection->beginTransaction();
foreach($sqls as $sql) {
foreach ($sqls as $sql) {
if ($output->isVerbose()) {
$output->writeln($sql);
}
@@ -97,25 +105,28 @@ final class ChillPersonMoveCommand extends Command
}
$connection->commit();
$this->chillLogger->notice("Move a person from command line succeeded", $ctxt);
$this->chillLogger->notice('Move a person from command line succeeded', $ctxt);
}
}
protected function buildLoggingContext(Person $from, Person $to, $deleteEntities, $sqls)
protected function interact(InputInterface $input, OutputInterface $output)
{
$ctxt = [
'from' => $from->getId(),
'to' => $to->getId()
];
if (false === $input->hasOption('dump-sql') && false === $input->hasOption('force')) {
$msg = 'You must use "--dump-sql" or "--force"';
foreach ($deleteEntities as $key => $de) {
$ctxt['delete_entity_'.$key] = $de;
}
foreach ($sqls as $key => $sql) {
$ctxt['sql_'.$key] = $sql;
throw new RuntimeException($msg);
}
return $ctxt;
foreach (['from', 'to'] as $name) {
if (empty($input->getOption($name))) {
throw new RuntimeException("You must set a \"{$name}\" option");
}
$id = $input->getOption($name);
if (ctype_digit($id) === false) {
throw new RuntimeException("The id in \"{$name}\" field does not contains "
. "only digits: {$id}");
}
}
}
}

View File

@@ -1,26 +1,30 @@
<?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\PersonBundle\Command;
use Chill\PersonBundle\Service\Import\ChillImporter;
use Chill\PersonBundle\Service\Import\SocialWorkMetadataInterface;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Doctrine\ORM\EntityManagerInterface;
use Exception;
use League\Csv\Reader;
use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Throwable;
final class ImportSocialWorkMetadata extends Command
{
/**
* @var EntityManagerInterface
*/
protected EntityManagerInterface $em;
/**
@@ -51,13 +55,13 @@ final class ImportSocialWorkMetadata extends Command
try {
$csv = Reader::createFromPath($filepath);
} catch (Throwable $e) {
throw new Exception('Error while loading CSV.',0, $e);
throw new Exception('Error while loading CSV.', 0, $e);
}
$csv->setDelimiter(';');
return true === $this->importer->import($csv) ?
0:
0 :
1;
}
}

View File

@@ -1,61 +1,54 @@
<?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.
*/
namespace Chill\PersonBundle\Config;
/**
* Give help to interact with the config for alt names
*
*
* Give help to interact with the config for alt names.
*/
class ConfigPersonAltNamesHelper
{
/**
* the raw config, directly from the container parameter
* the raw config, directly from the container parameter.
*
* @var array
*/
private $config = [];
public function __construct($config)
{
$this->config = $config;
}
/**
* Return true if at least one alt name is configured
*
* @return bool
*/
public function hasAltNames(): bool
{
return count($this->config) > 0;
}
/**
* get the choices as key => values
*
* @return array
* get the choices as key => values.
*/
public function getChoices(): array
{
$choices = [];
foreach ($this->config as $entry) {
$labels = $entry['labels'];
$lang = false;
$label = false;
$cur = reset($labels);
while ($cur) {
if (key($labels) === 'lang') {
$lang = current($labels);
}
if (key($labels) === 'label') {
$label = current($labels);
}
if ($lang !== FALSE && $label !== FALSE) {
if (false !== $lang && false !== $label) {
$choices[$entry['key']][$lang] = $label;
$lang = false;
$label = false;
@@ -63,8 +56,15 @@ class ConfigPersonAltNamesHelper
$cur = next($labels);
}
}
return $choices;
}
/**
* Return true if at least one alt name is configured.
*/
public function hasAltNames(): bool
{
return count($this->config) > 0;
}
}

View File

@@ -1,41 +1,53 @@
<?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.
*/
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\CRUD\Controller\ApiController;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Serializer\Model\Collection;
use Chill\PersonBundle\AccompanyingPeriod\Suggestion\ReferralsSuggestionInterface;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork;
use Chill\PersonBundle\Entity\AccompanyingPeriod\Comment;
use Chill\PersonBundle\Entity\AccompanyingPeriod\Resource;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
use Chill\PersonBundle\Privacy\AccompanyingPeriodPrivacyEvent;
use Chill\PersonBundle\Repository\AccompanyingPeriodACLAwareRepository;
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork;
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Serializer\Exception\RuntimeException;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Chill\PersonBundle\Privacy\AccompanyingPeriodPrivacyEvent;
use Chill\PersonBundle\Entity\Person;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Symfony\Component\Serializer\Exception\RuntimeException;
use Chill\PersonBundle\Entity\AccompanyingPeriod\Resource;
use Chill\PersonBundle\Entity\AccompanyingPeriod\Comment;
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
use Chill\MainBundle\Entity\Scope;
use Chill\PersonBundle\Repository\AccompanyingPeriodACLAwareRepository;
use Symfony\Component\Workflow\Registry;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use function array_values;
final class AccompanyingCourseApiController extends ApiController
{
private AccompanyingPeriodACLAwareRepository $accompanyingPeriodACLAwareRepository;
private EventDispatcherInterface $eventDispatcher;
private ValidatorInterface $validator;
private Registry $registry;
private ReferralsSuggestionInterface $referralAvailable;
private Registry $registry;
private ValidatorInterface $validator;
public function __construct(
EventDispatcherInterface $eventDispatcher,
ValidatorInterface $validator,
@@ -50,6 +62,11 @@ final class AccompanyingCourseApiController extends ApiController
$this->referralAvailable = $referralAvailable;
}
public function commentApi($id, Request $request, string $_format): Response
{
return $this->addRemoveSomething('comment', $id, $request, $_format, 'comment', Comment::class);
}
public function confirmApi($id, Request $request, $_format): Response
{
/** @var AccompanyingPeriod $accompanyingPeriod */
@@ -58,10 +75,11 @@ final class AccompanyingCourseApiController extends ApiController
$this->checkACL('confirm', $request, $_format, $accompanyingPeriod);
$workflow = $this->registry->get($accompanyingPeriod);
if (FALSE === $workflow->can($accompanyingPeriod, 'confirm')) {
if (false === $workflow->can($accompanyingPeriod, 'confirm')) {
// throw new BadRequestException('It is not possible to confirm this period');
$errors = $this->validator->validate($accompanyingPeriod, null, [$accompanyingPeriod::STEP_CONFIRMED]);
if( count($errors) > 0 ){
if (count($errors) > 0) {
return $this->json($errors, 422);
}
}
@@ -71,10 +89,26 @@ final class AccompanyingCourseApiController extends ApiController
$this->getDoctrine()->getManager()->flush();
return $this->json($accompanyingPeriod, Response::HTTP_OK, [], [
'groups' => [ 'read' ]
'groups' => ['read'],
]);
}
/**
* @ParamConverter("person", options={"id": "person_id"})
*/
public function getAccompanyingPeriodsByPerson(Person $person)
{
$accompanyingPeriods = $person->getCurrentAccompanyingPeriods();
$accompanyingPeriodsChecked = array_filter(
$accompanyingPeriods,
function (AccompanyingPeriod $period) {
return $this->isGranted(AccompanyingPeriodVoter::SEE, $period);
}
);
return $this->json(array_values($accompanyingPeriodsChecked), Response::HTTP_OK, [], ['groups' => ['read']]);
}
public function participationApi($id, Request $request, $_format)
{
/** @var AccompanyingPeriod $accompanyingPeriod */
@@ -82,7 +116,7 @@ final class AccompanyingCourseApiController extends ApiController
$person = $this->getSerializer()
->deserialize($request->getContent(), Person::class, $_format, []);
if (NULL === $person) {
if (null === $person) {
throw new BadRequestException('person id not found');
}
@@ -93,12 +127,16 @@ final class AccompanyingCourseApiController extends ApiController
switch ($request->getMethod()) {
case Request::METHOD_POST:
$participation = $accompanyingPeriod->createParticipationFor($person);
break;
case Request::METHOD_DELETE:
$participation = $accompanyingPeriod->closeParticipationFor($person);
break;
default:
throw new BadRequestException("This method is not supported");
throw new BadRequestException('This method is not supported');
}
$errors = $this->validator->validate($accompanyingPeriod);
@@ -110,48 +148,7 @@ final class AccompanyingCourseApiController extends ApiController
$this->getDoctrine()->getManager()->flush();
return $this->json($participation, 200, [], ['groups' => [ 'read' ]]);
}
public function resourceApi($id, Request $request, string $_format): Response
{
$accompanyingPeriod = $this->getEntity('resource', $id, $request);
$errors = $this->validator->validate($accompanyingPeriod);
if ($errors->count() > 0) {
return $this->json($errors, 422);
}
return $this->addRemoveSomething('resource', $id, $request, $_format, 'resource', Resource::class);
}
public function scopeApi($id, Request $request, string $_format): Response
{
return $this->addRemoveSomething('scope', $id, $request, $_format, 'scope', Scope::class, [ 'groups' => [ 'read' ] ]);
}
public function commentApi($id, Request $request, string $_format): Response
{
return $this->addRemoveSomething('comment', $id, $request, $_format, 'comment', Comment::class);
}
public function socialIssueApi($id, Request $request, string $_format): Response
{
return $this->addRemoveSomething('socialissue', $id, $request, $_format, 'socialIssue', SocialIssue::class, [ 'groups' => [ 'read' ] ]);
}
public function workApi($id, Request $request, string $_format): Response
{
return $this->addRemoveSomething(
'work',
$id,
$request,
$_format,
'work',
AccompanyingPeriodWork::class,
[ 'groups' => [ 'accompanying_period_work:create' ] ],
true // force persist
);
return $this->json($participation, 200, [], ['groups' => ['read']]);
}
public function requestorApi($id, Request $request, string $_format): Response
@@ -165,10 +162,11 @@ final class AccompanyingCourseApiController extends ApiController
$this->onPostCheckACL($action, $request, $_format, $accompanyingPeriod);
if (Request::METHOD_DELETE === $request->getMethod()) {
$accompanyingPeriod->setRequestor(NULL);
$accompanyingPeriod->setRequestor(null);
} elseif (Request::METHOD_POST === $request->getMethod()) {
$requestor = null;
$exceptions = [];
foreach ([Person::class, ThirdParty::class] as $class) {
try {
$requestor = $this->getSerializer()
@@ -177,7 +175,8 @@ final class AccompanyingCourseApiController extends ApiController
$exceptions[] = $e;
}
}
if ($requestor === null) {
if (null === $requestor) {
throw new BadRequestException('Could not find any person or requestor', 0, $exceptions[0]);
}
@@ -195,40 +194,35 @@ final class AccompanyingCourseApiController extends ApiController
$this->getDoctrine()->getManager()->flush();
return $this->json($accompanyingPeriod->getRequestor(), 200, [], ['groups' => [ 'read']]);
return $this->json($accompanyingPeriod->getRequestor(), 200, [], ['groups' => ['read']]);
}
protected function onPostCheckACL(string $action, Request $request, string $_format, $entity): ?Response
public function resourceApi($id, Request $request, string $_format): Response
{
$this->eventDispatcher->dispatch(
AccompanyingPeriodPrivacyEvent::ACCOMPANYING_PERIOD_PRIVACY_EVENT,
new AccompanyingPeriodPrivacyEvent($entity, [
'action' => $action,
'request' => $request->getMethod()
])
);
$accompanyingPeriod = $this->getEntity('resource', $id, $request);
$errors = $this->validator->validate($accompanyingPeriod);
return null;
if ($errors->count() > 0) {
return $this->json($errors, 422);
}
return $this->addRemoveSomething('resource', $id, $request, $_format, 'resource', Resource::class);
}
/**
* @ParamConverter("person", options={"id" = "person_id"})
*/
public function getAccompanyingPeriodsByPerson(Person $person){
$accompanyingPeriods = $person->getCurrentAccompanyingPeriods();
$accompanyingPeriodsChecked = array_filter($accompanyingPeriods,
function(AccompanyingPeriod $period){
return $this->isGranted(AccompanyingPeriodVoter::SEE, $period);
});
return $this->json(\array_values($accompanyingPeriodsChecked), Response::HTTP_OK, [], ['groups' => [ 'read']]);
public function scopeApi($id, Request $request, string $_format): Response
{
return $this->addRemoveSomething('scope', $id, $request, $_format, 'scope', Scope::class, ['groups' => ['read']]);
}
public function socialIssueApi($id, Request $request, string $_format): Response
{
return $this->addRemoveSomething('socialissue', $id, $request, $_format, 'socialIssue', SocialIssue::class, ['groups' => ['read']]);
}
/**
* @Route("/api/1.0/person/accompanying-course/{id}/referrers-suggested.{_format}",
* requirements={ "_format"="json"},
* name="chill_api_person_accompanying_period_referrers_suggested")
* @param AccompanyingPeriod $period
* @return JsonResponse
* requirements={ "_format": "json"},
* name="chill_api_person_accompanying_period_referrers_suggested")
*/
public function suggestReferrals(AccompanyingPeriod $period, string $_format = 'json'): JsonResponse
{
@@ -238,13 +232,47 @@ final class AccompanyingCourseApiController extends ApiController
$paginator = $this->getPaginatorFactory()->create($total);
if (0 < $total) {
$users = $this->referralAvailable->findReferralSuggested($period, $paginator->getItemsPerPage(),
$paginator->getCurrentPageFirstItemNumber());
$users = $this->referralAvailable->findReferralSuggested(
$period,
$paginator->getItemsPerPage(),
$paginator->getCurrentPageFirstItemNumber()
);
} else {
$users = [];
}
return $this->json(new Collection($users, $paginator), Response::HTTP_OK,
[], [ AbstractNormalizer::GROUPS => [ 'read' ]]);
return $this->json(
new Collection($users, $paginator),
Response::HTTP_OK,
[],
[AbstractNormalizer::GROUPS => ['read']]
);
}
public function workApi($id, Request $request, string $_format): Response
{
return $this->addRemoveSomething(
'work',
$id,
$request,
$_format,
'work',
AccompanyingPeriodWork::class,
['groups' => ['accompanying_period_work:create']],
true // force persist
);
}
protected function onPostCheckACL(string $action, Request $request, string $_format, $entity): ?Response
{
$this->eventDispatcher->dispatch(
AccompanyingPeriodPrivacyEvent::ACCOMPANYING_PERIOD_PRIVACY_EVENT,
new AccompanyingPeriodPrivacyEvent($entity, [
'action' => $action,
'request' => $request->getMethod(),
])
);
return null;
}
}

View File

@@ -1,47 +1,47 @@
<?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.
*/
namespace Chill\PersonBundle\Controller;
use Chill\ActivityBundle\Entity\Activity;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation;
use Chill\PersonBundle\Privacy\AccompanyingPeriodPrivacyEvent;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Form\AccompanyingCourseType;
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkRepository;
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Symfony\Component\Workflow\Registry;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use function is_array;
/**
* Class AccompanyingCourseController
*
* @package Chill\PersonBundle\Controller
* Class AccompanyingCourseController.
*/
class AccompanyingCourseController extends Controller
{
protected SerializerInterface $serializer;
protected EventDispatcherInterface $dispatcher;
protected SerializerInterface $serializer;
protected ValidatorInterface $validator;
private AccompanyingPeriodWorkRepository $workRepository;
private Registry $registry;
private AccompanyingPeriodWorkRepository $workRepository;
public function __construct(
SerializerInterface $serializer,
EventDispatcherInterface $dispatcher,
@@ -57,41 +57,80 @@ class AccompanyingCourseController extends Controller
}
/**
* @Route("/{_locale}/person/parcours/new", name="chill_person_accompanying_course_new")
* @Route("/{_locale}/parcours/{accompanying_period_id}/close", name="chill_person_accompanying_course_close")
* @ParamConverter("accompanyingCourse", options={"id": "accompanying_period_id"})
*/
public function newAction(Request $request): Response
public function closeAction(AccompanyingPeriod $accompanyingCourse, Request $request): Response
{
$period = new AccompanyingPeriod();
$em = $this->getDoctrine()->getManager();
$this->denyAccessUnlessGranted(AccompanyingPeriodVoter::EDIT, $accompanyingCourse);
if ($request->query->has('person_id')) {
$personIds = $request->query->get('person_id');
$form = $this->createForm(AccompanyingCourseType::class, $accompanyingCourse);
if (FALSE === \is_array($personIds)) {
throw new BadRequestException("person_id parameter should be an array");
}
$form->handleRequest($request);
foreach ($personIds as $personId) {
$person = $em->getRepository(Person::class)->find($personId);
if (NULL !== $person) {
$period->addPerson($person);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$workflow = $this->registry->get($accompanyingCourse);
if ($workflow->can($accompanyingCourse, 'close')) {
$errors = $this->validator->validate($accompanyingCourse, null, [$accompanyingCourse::STEP_CLOSED]);
if (count($errors) > 0) {
return $this->json($errors, 422);
}
$workflow->apply($accompanyingCourse, 'close');
$em->flush();
return $this->redirectToRoute('chill_person_accompanying_course_index', [
'accompanying_period_id' => $accompanyingCourse->getId(),
]);
}
}
$this->denyAccessUnlessGranted(AccompanyingPeriodVoter::CREATE, $period);
$em->persist($period);
$em->flush();
return $this->redirectToRoute('chill_person_accompanying_course_edit', [
'accompanying_period_id' => $period->getId()
return $this->render('@ChillPerson/AccompanyingCourse/close.html.twig', [
'form' => $form->createView(),
'accompanyingCourse' => $accompanyingCourse,
]);
}
/**
* Homepage of Accompanying Course section
* Edit page of Accompanying Course section.
*
* the page edit all blocks managed by vuejs component
*
* @Route("/{_locale}/parcours/{accompanying_period_id}/edit", name="chill_person_accompanying_course_edit")
* @ParamConverter("accompanyingCourse", options={"id": "accompanying_period_id"})
*/
public function editAction(AccompanyingPeriod $accompanyingCourse): Response
{
$this->denyAccessUnlessGranted(AccompanyingPeriodVoter::SEE, $accompanyingCourse);
return $this->render('@ChillPerson/AccompanyingCourse/edit.html.twig', [
'accompanyingCourse' => $accompanyingCourse,
]);
}
/**
* History page of Accompanying Course section.
*
* the page show anti chronologic history with all actions, title of page is 'Accompanying Course History'
*
* @Route("/{_locale}/parcours/{accompanying_period_id}/history", name="chill_person_accompanying_course_history")
* @ParamConverter("accompanyingCourse", options={"id": "accompanying_period_id"})
*/
public function historyAction(AccompanyingPeriod $accompanyingCourse): Response
{
$this->denyAccessUnlessGranted(AccompanyingPeriodVoter::SEE, $accompanyingCourse);
return $this->render('@ChillPerson/AccompanyingCourse/history.html.twig', [
'accompanyingCourse' => $accompanyingCourse,
]);
}
/**
* Homepage of Accompanying Course section.
*
* @Route("/{_locale}/parcours/{accompanying_period_id}", name="chill_person_accompanying_course_index")
* @ParamConverter("accompanyingCourse", options={"id": "accompanying_period_id"})
@@ -99,13 +138,13 @@ class AccompanyingCourseController extends Controller
public function indexAction(AccompanyingPeriod $accompanyingCourse): Response
{
$this->denyAccessUnlessGranted(AccompanyingPeriodVoter::SEE, $accompanyingCourse);
// compute some warnings
// get persons without household
$withoutHousehold = [];
foreach ($accompanyingCourse->getParticipations() as
$p) {
if (FALSE === $p->getPerson()->isSharingHousehold()) {
foreach ($accompanyingCourse->getParticipations() as $p) {
if (false === $p->getPerson()->isSharingHousehold()) {
$withoutHousehold[] = $p->getPerson();
}
}
@@ -126,82 +165,41 @@ class AccompanyingCourseController extends Controller
'withoutHousehold' => $withoutHousehold,
'participationsByHousehold' => $accompanyingCourse->actualParticipationsByHousehold(),
'works' => $works,
'activities' => $activities
'activities' => $activities,
]);
}
/**
* Edit page of Accompanying Course section
*
* the page edit all blocks managed by vuejs component
*
* @Route("/{_locale}/parcours/{accompanying_period_id}/edit", name="chill_person_accompanying_course_edit")
* @ParamConverter("accompanyingCourse", options={"id": "accompanying_period_id"})
* @Route("/{_locale}/person/parcours/new", name="chill_person_accompanying_course_new")
*/
public function editAction(AccompanyingPeriod $accompanyingCourse): Response
public function newAction(Request $request): Response
{
$this->denyAccessUnlessGranted(AccompanyingPeriodVoter::SEE, $accompanyingCourse);
$period = new AccompanyingPeriod();
$em = $this->getDoctrine()->getManager();
return $this->render('@ChillPerson/AccompanyingCourse/edit.html.twig', [
'accompanyingCourse' => $accompanyingCourse
]);
}
if ($request->query->has('person_id')) {
$personIds = $request->query->get('person_id');
/**
* History page of Accompanying Course section
*
* the page show anti chronologic history with all actions, title of page is 'Accompanying Course History'
*
* @Route("/{_locale}/parcours/{accompanying_period_id}/history", name="chill_person_accompanying_course_history")
* @ParamConverter("accompanyingCourse", options={"id": "accompanying_period_id"})
*/
public function historyAction(AccompanyingPeriod $accompanyingCourse): Response
{
$this->denyAccessUnlessGranted(AccompanyingPeriodVoter::SEE, $accompanyingCourse);
if (false === is_array($personIds)) {
throw new BadRequestException('person_id parameter should be an array');
}
return $this->render('@ChillPerson/AccompanyingCourse/history.html.twig', [
'accompanyingCourse' => $accompanyingCourse
]);
}
foreach ($personIds as $personId) {
$person = $em->getRepository(Person::class)->find($personId);
/**
* @Route("/{_locale}/parcours/{accompanying_period_id}/close", name="chill_person_accompanying_course_close")
* @ParamConverter("accompanyingCourse", options={"id": "accompanying_period_id"})
*/
public function closeAction(AccompanyingPeriod $accompanyingCourse, Request $request): Response
{
$this->denyAccessUnlessGranted(AccompanyingPeriodVoter::EDIT, $accompanyingCourse);
$form = $this->createForm(AccompanyingCourseType::class, $accompanyingCourse);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$workflow = $this->registry->get($accompanyingCourse);
if ($workflow->can($accompanyingCourse, 'close')) {
$errors = $this->validator->validate($accompanyingCourse, null, [$accompanyingCourse::STEP_CLOSED]);
if (count($errors) > 0) {
return $this->json($errors, 422);
if (null !== $person) {
$period->addPerson($person);
}
$workflow->apply($accompanyingCourse, 'close');
$em->flush();
return $this->redirectToRoute('chill_person_accompanying_course_index', [
'accompanying_period_id' => $accompanyingCourse->getId()
]);
}
}
return $this->render('@ChillPerson/AccompanyingCourse/close.html.twig', [
'form' => $form->createView(),
'accompanyingCourse' => $accompanyingCourse
$this->denyAccessUnlessGranted(AccompanyingPeriodVoter::CREATE, $period);
$em->persist($period);
$em->flush();
return $this->redirectToRoute('chill_person_accompanying_course_edit', [
'accompanying_period_id' => $period->getId(),
]);
}
}

View File

@@ -1,5 +1,12 @@
<?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.
*/
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\CRUD\Controller\ApiController;
@@ -9,15 +16,14 @@ class AccompanyingCourseWorkApiController extends ApiController
{
protected function getContextForSerialization(string $action, Request $request, string $_format, $entity): array
{
switch($action) {
switch ($action) {
case '_entity':
switch ($request->getMethod()) {
case Request::METHOD_PUT:
return [ 'groups' => [ 'accompanying_period_work:edit' ] ];
return ['groups' => ['accompanying_period_work:edit']];
}
}
return parent::getContextForSerialization($action, $request, $_format, $entity);
}
}

View File

@@ -1,29 +1,40 @@
<?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.
*/
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\Pagination\PaginatorFactory;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork;
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkRepository;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Form;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Component\Form\Form;
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkRepository;
use Psr\Log\LoggerInterface;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
class AccompanyingCourseWorkController extends AbstractController
{
private TranslatorInterface $trans;
private SerializerInterface $serializer;
private AccompanyingPeriodWorkRepository $workRepository;
private PaginatorFactory $paginator;
private LoggerInterface $chillLogger;
private PaginatorFactory $paginator;
private SerializerInterface $serializer;
private TranslatorInterface $trans;
private AccompanyingPeriodWorkRepository $workRepository;
public function __construct(
TranslatorInterface $trans,
SerializerInterface $serializer,
@@ -40,58 +51,107 @@ class AccompanyingCourseWorkController extends AbstractController
/**
* @Route(
* "{_locale}/person/accompanying-period/{id}/work/new",
* name="chill_person_accompanying_period_work_new",
* methods={"GET"}
* )
* "{_locale}/person/accompanying-period/{id}/work/new",
* name="chill_person_accompanying_period_work_new",
* methods={"GET"}
* )
*/
public function createWork(AccompanyingPeriod $period): Response
{
// TODO ACL
if ($period->getSocialIssues()->count() === 0) {
$this->addFlash('error', $this->trans->trans(
"accompanying_work.You must add at least ".
"one social issue on accompanying period")
$this->addFlash(
'error',
$this->trans->trans(
'accompanying_work.You must add at least ' .
'one social issue on accompanying period'
)
);
return $this->redirectToRoute('chill_person_accompanying_course_index', [
'accompanying_period_id' => $period->getId()
'accompanying_period_id' => $period->getId(),
]);
}
$json = $this->serializer->normalize($period, 'json', [ "groups" => [ "read" ]]);
$json = $this->serializer->normalize($period, 'json', ['groups' => ['read']]);
return $this->render('@ChillPerson/AccompanyingCourseWork/create.html.twig', [
'accompanyingCourse' => $period,
'json' => $json
'json' => $json,
]);
}
/**
* @Route(
* "{_locale}/person/accompanying-period/work/{id}/edit",
* name="chill_person_accompanying_period_work_edit",
* methods={"GET"}
* )
* "{_locale}/person/accompanying-period/work/{id}/delete",
* name="chill_person_accompanying_period_work_delete",
* methods={"GET", "POST", "DELETE"}
* )
*/
public function deleteWork(AccompanyingPeriodWork $work, Request $request): Response
{
// TODO ACL
$em = $this->getDoctrine()->getManager();
$form = $this->createDeleteForm($work->getId());
if ($request->getMethod() === Request::METHOD_DELETE) {
$form->handleRequest($request);
if ($form->isValid()) {
$this->chillLogger->notice('An accompanying period work has been removed', [
'by_user' => $this->getUser()->getUsername(),
'work_id' => $work->getId(),
'accompanying_period_id' => $work->getAccompanyingPeriod()->getId(),
]);
$em->remove($work);
$em->flush();
$this->addFlash(
'success',
$this->trans->trans('The accompanying period work has been successfully removed.')
);
return $this->redirectToRoute('chill_person_accompanying_period_work_list', [
'id' => $work->getAccompanyingPeriod()->getId(),
]);
}
}
return $this->render('@ChillPerson/AccompanyingCourseWork/delete.html.twig', [
'accompanyingCourse' => $work->getAccompanyingPeriod(),
'work' => $work,
'delete_form' => $form->createView(),
]);
}
/**
* @Route(
* "{_locale}/person/accompanying-period/work/{id}/edit",
* name="chill_person_accompanying_period_work_edit",
* methods={"GET"}
* )
*/
public function editWork(AccompanyingPeriodWork $work): Response
{
// TODO ACL
$json = $this->serializer->normalize($work, 'json', [ "groups" => [ "read" ] ]);
$json = $this->serializer->normalize($work, 'json', ['groups' => ['read']]);
return $this->render('@ChillPerson/AccompanyingCourseWork/edit.html.twig', [
'accompanyingCourse' => $work->getAccompanyingPeriod(),
'work' => $work,
'json' => $json
'json' => $json,
]);
}
/**
* @Route(
* "{_locale}/person/accompanying-period/{id}/work",
* name="chill_person_accompanying_period_work_list",
* methods={"GET"}
* )
* "{_locale}/person/accompanying-period/{id}/work",
* name="chill_person_accompanying_period_work_list",
* methods={"GET"}
* )
*/
public function listWorkByAccompanyingPeriod(AccompanyingPeriod $period): Response
{
@@ -109,54 +169,7 @@ class AccompanyingCourseWorkController extends AbstractController
return $this->render('@ChillPerson/AccompanyingCourseWork/index.html.twig', [
'accompanyingCourse' => $period,
'works' => $works,
'paginator' => $paginator
]);
}
/**
* @Route(
* "{_locale}/person/accompanying-period/work/{id}/delete",
* name="chill_person_accompanying_period_work_delete",
* methods={"GET", "POST", "DELETE"}
* )
*/
public function deleteWork(AccompanyingPeriodWork $work, Request $request): Response
{
// TODO ACL
$em = $this->getDoctrine()->getManager();
$form = $this->createDeleteForm($work->getId());
if ($request->getMethod() === Request::METHOD_DELETE) {
$form->handleRequest($request);
if ($form->isValid()) {
$this->chillLogger->notice("An accompanying period work has been removed", [
'by_user' => $this->getUser()->getUsername(),
'work_id' => $work->getId(),
'accompanying_period_id' => $work->getAccompanyingPeriod()->getId()
]);
$em->remove($work);
$em->flush();
$this->addFlash(
'success',
$this->trans->trans("The accompanying period work has been successfully removed.")
);
return $this->redirectToRoute('chill_person_accompanying_period_work_list', [
'id' => $work->getAccompanyingPeriod()->getId()
]);
}
}
return $this->render('@ChillPerson/AccompanyingCourseWork/delete.html.twig', [
'accompanyingCourse' => $work->getAccompanyingPeriod(),
'work' => $work,
'delete_form' => $form->createView()
'paginator' => $paginator,
]);
}
@@ -169,9 +182,6 @@ class AccompanyingCourseWorkController extends AbstractController
->setAction($this->generateUrl('chill_person_accompanying_period_work_delete', $params))
->setMethod('DELETE')
->add('submit', SubmitType::class, ['label' => 'Delete'])
->getForm()
;
->getForm();
}
}

View File

@@ -1,51 +1,39 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2014-2021, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Controller;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Form\AccompanyingPeriodType;
use Chill\PersonBundle\Privacy\PrivacyEvent;
use Chill\PersonBundle\Repository\AccompanyingPeriodACLAwareRepositoryInterface;
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use DateTime;
use Doctrine\DBAL\Exception;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Form\AccompanyingPeriodType;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Doctrine\Common\Collections\Criteria;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Validator\ConstraintViolationListInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use function array_filter;
/**
* Class AccompanyingPeriodController
*
* @package Chill\PersonBundle\Controller
* Class AccompanyingPeriodController.
*/
class AccompanyingPeriodController extends AbstractController
{
protected AccompanyingPeriodACLAwareRepositoryInterface $accompanyingPeriodACLAwareRepository;
/**
* @var EventDispatcherInterface
*/
@@ -56,8 +44,6 @@ class AccompanyingPeriodController extends AbstractController
*/
protected $validator;
protected AccompanyingPeriodACLAwareRepositoryInterface $accompanyingPeriodACLAwareRepository;
public function __construct(
AccompanyingPeriodACLAwareRepositoryInterface $accompanyingPeriodACLAwareRepository,
EventDispatcherInterface $eventDispatcher,
@@ -68,218 +54,71 @@ class AccompanyingPeriodController extends AbstractController
$this->validator = $validator;
}
/**
* @ParamConverter("person", options={"id"="person_id"})
*/
public function listAction(Person $person): Response
{
$this->denyAccessUnlessGranted(AccompanyingPeriodVoter::SEE, $person);
$event = new PrivacyEvent($person, [
'element_class' => AccompanyingPeriod::class,
'action' => 'list'
]);
$this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event);
$accompanyingPeriods = $this->accompanyingPeriodACLAwareRepository
->findByPerson($person, AccompanyingPeriodVoter::SEE);
return $this->render('@ChillPerson/AccompanyingPeriod/list.html.twig', [
'accompanying_periods' => $accompanyingPeriods,
'person' => $person
]);
}
public function createAction(int $person_id, Request $request): Response
{
$person = $this->_getPerson($person_id);
$this->denyAccessUnlessGranted(PersonVoter::UPDATE, $person,
'You are not allowed to update this person');
$accompanyingPeriod = new AccompanyingPeriod(new \DateTime('now'));
$accompanyingPeriod->setClosingDate(new \DateTime('now'));
$accompanyingPeriod->addPerson($person);
//or $person->addAccompanyingPeriod($accompanyingPeriod);
$form = $this->createForm(
AccompanyingPeriodType::class,
$accompanyingPeriod, [
'period_action' => 'create',
'center' => $person->getCenter()
]);
if ($request->getMethod() === 'POST') {
$form->handleRequest($request);
$errors = $this->_validatePerson($person);
$flashBag = $this->get('session')->getFlashBag();
if ($form->isValid(['Default', 'closed'])
&& count($errors) === 0) {
$em = $this->getDoctrine()->getManager();
$em->persist($accompanyingPeriod);
$em->flush();
$flashBag->add('success',
$this->get('translator')->trans(
'A period has been created.'));
return $this->redirect(
$this->generateUrl('chill_person_accompanying_period_list', [
'person_id' => $person->getId()
]));
} else {
$flashBag->add('error', $this->get('translator')
->trans('Error! Period not created!'));
foreach($errors as $error) {
$flashBag->add('info', $error->getMessage());
}
}
}
return $this->render('ChillPersonBundle:AccompanyingPeriod:form.html.twig', [
'form' => $form->createView(),
'person' => $person,
'accompanying_period' => $accompanyingPeriod
]);
}
/**
* @throws Exception
*/
public function updateAction(int $person_id, int $period_id, Request $request): Response
{
$em = $this->getDoctrine()->getManager();
/** @var AccompanyingPeriod $accompanyingPeriod */
$accompanyingPeriod = $em->getRepository(AccompanyingPeriod::class)->find($period_id);
if ($accompanyingPeriod === null) {
throw $this->createNotFoundException("Period with id " . $period_id . " is not found");
}
/** @var Person $person */
$person = $this->_getPerson($person_id);
// CHECK
if (! $accompanyingPeriod->containsPerson($person)) {
throw new Exception("Accompanying period " . $period_id . " does not contain person " . $person_id);
}
$this->denyAccessUnlessGranted(PersonVoter::UPDATE, $person,
'You are not allowed to update this person');
$form = $this->createForm(AccompanyingPeriodType::class,
$accompanyingPeriod, [
'period_action' => 'update',
'center' => $person->getCenter()
]);
if ($request->getMethod() === 'POST') {
$form->handleRequest($request);
$errors = $this->_validatePerson($person);
$flashBag = $this->get('session')->getFlashBag();
if ($form->isValid(['Default', 'closed'])
&& count($errors) === 0) {
$em->flush();
$flashBag->add('success',
$this->get('translator')->trans('An accompanying period has been updated.'));
return $this->redirect(
$this->generateUrl('chill_person_accompanying_period_list', [
'person_id' => $person->getId()
]));
} else {
$flashBag->add('error', $this->get('translator')
->trans('Error when updating the period'));
foreach($errors as $error) {
$flashBag->add('info', $error->getMessage());
}
}
}
return $this->render('ChillPersonBundle:AccompanyingPeriod:form.html.twig', [
'form' => $form->createView(),
'person' => $person,
'accompanying_period' => $accompanyingPeriod
]);
}
/**
* @throws \Exception
*/
public function closeAction(int $person_id, Request $request): Response
{
$person = $this->_getPerson($person_id);
$this->denyAccessUnlessGranted(PersonVoter::UPDATE, $person, 'You are not allowed to update this person');
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', [
'person_id' => $person->getId()
]));
'person_id' => $person->getId(),
])
);
}
$current = $person->getCurrentAccompanyingPeriod();
$form = $this->createForm(AccompanyingPeriodType::class, $current, [
'period_action' => 'close',
'center' => $person->getCenter()
'center' => $person->getCenter(),
]);
if ($request->getMethod() === 'POST') {
$form->handleRequest($request);
if ($form->isValid()){
if ($form->isValid()) {
$person->close($current);
$errors = $this->_validatePerson($person);
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();
return $this->redirect(
$this->generateUrl('chill_person_accompanying_period_list', [
'person_id' => $person->getId()
'person_id' => $person->getId(),
])
);
} else {
$this->get('session')->getFlashBag()
->add('error', $this->get('translator')
->trans('Error! Period not closed!'));
foreach ($errors as $error) {
$this->get('session')->getFlashBag()
->add('info', $error->getMessage());
}
}
$this->get('session')->getFlashBag()
->add('error', $this->get('translator')
->trans('Error! Period not closed!'));
foreach ($errors as $error) {
$this->get('session')->getFlashBag()
->add('info', $error->getMessage());
}
} else { //if form is not valid
$this->get('session')->getFlashBag()
->add('error',
->add(
'error',
$this->get('translator')
->trans('Pediod closing form is not valid')
);
@@ -294,57 +133,131 @@ class AccompanyingPeriodController extends AbstractController
return $this->render('ChillPersonBundle:AccompanyingPeriod:form.html.twig', [
'form' => $form->createView(),
'person' => $person,
'accompanying_period' => $current
'accompanying_period' => $current,
]);
}
private function _validatePerson(Person $person): ConstraintViolationListInterface
public function createAction(int $person_id, Request $request): Response
{
$errors = $this->validator->validate($person, null,
['Default']);
$person = $this->_getPerson($person_id);
// Can be disabled with config
if (false === $this->container->getParameter('chill_person.allow_multiple_simultaneous_accompanying_periods')) {
$this->denyAccessUnlessGranted(
PersonVoter::UPDATE,
$person,
'You are not allowed to update this person'
);
$errors_accompanying_period = $this->validator->validate($person, null,
['accompanying_period_consistent']);
$accompanyingPeriod = new AccompanyingPeriod(new DateTime('now'));
$accompanyingPeriod->setClosingDate(new DateTime('now'));
foreach($errors_accompanying_period as $error ) {
$errors->add($error);
$accompanyingPeriod->addPerson($person);
//or $person->addAccompanyingPeriod($accompanyingPeriod);
$form = $this->createForm(
AccompanyingPeriodType::class,
$accompanyingPeriod,
[
'period_action' => 'create',
'center' => $person->getCenter(),
]
);
if ($request->getMethod() === 'POST') {
$form->handleRequest($request);
$errors = $this->_validatePerson($person);
$flashBag = $this->get('session')->getFlashBag();
if ($form->isValid(['Default', 'closed'])
&& count($errors) === 0) {
$em = $this->getDoctrine()->getManager();
$em->persist($accompanyingPeriod);
$em->flush();
$flashBag->add(
'success',
$this->get('translator')->trans(
'A period has been created.'
)
);
return $this->redirect(
$this->generateUrl('chill_person_accompanying_period_list', [
'person_id' => $person->getId(),
])
);
}
$flashBag->add('error', $this->get('translator')
->trans('Error! Period not created!'));
foreach ($errors as $error) {
$flashBag->add('info', $error->getMessage());
}
}
return $errors;
return $this->render('ChillPersonBundle:AccompanyingPeriod:form.html.twig', [
'form' => $form->createView(),
'person' => $person,
'accompanying_period' => $accompanyingPeriod,
]);
}
/**
* @ParamConverter("person", options={"id": "person_id"})
*/
public function listAction(Person $person): Response
{
$this->denyAccessUnlessGranted(AccompanyingPeriodVoter::SEE, $person);
$event = new PrivacyEvent($person, [
'element_class' => AccompanyingPeriod::class,
'action' => 'list',
]);
$this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event);
$accompanyingPeriods = $this->accompanyingPeriodACLAwareRepository
->findByPerson($person, AccompanyingPeriodVoter::SEE);
return $this->render('@ChillPerson/AccompanyingPeriod/list.html.twig', [
'accompanying_periods' => $accompanyingPeriods,
'person' => $person,
]);
}
public function openAction(int $person_id, Request $request): Response
{
$person = $this->_getPerson($person_id);
$this->denyAccessUnlessGranted(PersonVoter::UPDATE, $person,
'You are not allowed to update this person');
$this->denyAccessUnlessGranted(
PersonVoter::UPDATE,
$person,
'You are not allowed to update this person'
);
//in case the person is already open
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', [
'person_id' => $person->getId()
]));
'person_id' => $person->getId(),
])
);
}
$accompanyingPeriod = new AccompanyingPeriod(new \DateTime());
$accompanyingPeriod = new AccompanyingPeriod(new DateTime());
$form = $this->createForm(AccompanyingPeriodType::class,
$accompanyingPeriod, [
$form = $this->createForm(
AccompanyingPeriodType::class,
$accompanyingPeriod,
[
'period_action' => 'open',
'center' => $person->getCenter()
]);
'center' => $person->getCenter(),
]
);
if ($request->getMethod() === 'POST') {
$form->handleRequest($request);
@@ -357,40 +270,41 @@ class AccompanyingPeriodController extends AbstractController
if (count($errors) <= 0) {
$this->get('session')->getFlashBag()
->add('success', $this->get('translator')
->trans('An accompanying period has been opened.',
->trans(
'An accompanying period has been opened.',
['%name%' => $person->__toString()]
));
));
$this->getDoctrine()->getManager()->flush();
return $this->redirect(
$this->generateUrl('chill_person_accompanying_period_list', [
'person_id' => $person->getId()
]));
} else {
$this->get('session')->getFlashBag()
->add('error', $this->get('translator')
->trans('Period not opened'));
foreach ($errors as $error) {
$this->get('session')->getFlashBag()
->add('info', $error->getMessage());
}
'person_id' => $person->getId(),
])
);
}
$this->get('session')->getFlashBag()
->add('error', $this->get('translator')
->trans('Period not opened'));
foreach ($errors as $error) {
$this->get('session')->getFlashBag()
->add('info', $error->getMessage());
}
} else { // if errors in forms
$this->get('session')->getFlashBag()
->add('error', $this->get('translator')
->trans('Period not opened : form is invalid')
);
->add(
'error',
$this->get('translator')
->trans('Period not opened : form is invalid')
);
}
}
return $this->render('ChillPersonBundle:AccompanyingPeriod:form.html.twig', [
'form' => $form->createView(),
'person' => $person,
'accompanying_period' => $accompanyingPeriod
'accompanying_period' => $accompanyingPeriod,
]);
}
@@ -400,20 +314,20 @@ class AccompanyingPeriodController extends AbstractController
$person = $this->_getPerson($person_id);
/* @var $period AccompanyingPeriod */
$period = \array_filter(
$period = array_filter(
$person->getAccompanyingPeriods(),
function (AccompanyingPeriod $p) use ($period_id) {
return $p->getId() === ($period_id);
}
)[0] ?? NULL;
)[0] ?? null;
if ($period === NULL) {
if (null === $period) {
throw $this->createNotFoundException('period not found');
}
$confirm = $request->query->getBoolean('confirm', false);
if ($confirm === true && $period->canBeReOpened($person)) {
if (true === $confirm && $period->canBeReOpened($person)) {
$period->reOpen();
$this->_validatePerson($person);
@@ -421,40 +335,141 @@ class AccompanyingPeriodController extends AbstractController
$this->getDoctrine()->getManager()->flush();
$this->addFlash('success', $this->get('translator')->trans(
'The period has been re-opened'));
'The period has been re-opened'
));
return $this->redirectToRoute('chill_person_accompanying_period_list', [
'person_id' => $person->getId()
'person_id' => $person->getId(),
]);
}
} elseif ($confirm === false && $period->canBeReOpened($person)) {
if (false === $confirm && $period->canBeReOpened($person)) {
return $this->render('ChillPersonBundle:AccompanyingPeriod:re_open.html.twig', [
'period' => $period,
'person' => $person
'person' => $person,
]);
} else {
return (new Response())
->setStatusCode(Response::HTTP_BAD_REQUEST)
->setContent("You cannot re-open this period");
}
return (new Response())
->setStatusCode(Response::HTTP_BAD_REQUEST)
->setContent('You cannot re-open this period');
}
/**
* @throws Exception
*/
public function updateAction(int $person_id, int $period_id, Request $request): Response
{
$em = $this->getDoctrine()->getManager();
/** @var AccompanyingPeriod $accompanyingPeriod */
$accompanyingPeriod = $em->getRepository(AccompanyingPeriod::class)->find($period_id);
if (null === $accompanyingPeriod) {
throw $this->createNotFoundException('Period with id ' . $period_id . ' is not found');
}
/** @var Person $person */
$person = $this->_getPerson($person_id);
// CHECK
if (!$accompanyingPeriod->containsPerson($person)) {
throw new Exception('Accompanying period ' . $period_id . ' does not contain person ' . $person_id);
}
$this->denyAccessUnlessGranted(
PersonVoter::UPDATE,
$person,
'You are not allowed to update this person'
);
$form = $this->createForm(
AccompanyingPeriodType::class,
$accompanyingPeriod,
[
'period_action' => 'update',
'center' => $person->getCenter(),
]
);
if ($request->getMethod() === 'POST') {
$form->handleRequest($request);
$errors = $this->_validatePerson($person);
$flashBag = $this->get('session')->getFlashBag();
if ($form->isValid(['Default', 'closed'])
&& count($errors) === 0) {
$em->flush();
$flashBag->add(
'success',
$this->get('translator')->trans('An accompanying period has been updated.')
);
return $this->redirect(
$this->generateUrl('chill_person_accompanying_period_list', [
'person_id' => $person->getId(),
])
);
}
$flashBag->add('error', $this->get('translator')
->trans('Error when updating the period'));
foreach ($errors as $error) {
$flashBag->add('info', $error->getMessage());
}
}
return $this->render('ChillPersonBundle:AccompanyingPeriod:form.html.twig', [
'form' => $form->createView(),
'person' => $person,
'accompanying_period' => $accompanyingPeriod,
]);
}
/**
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
*/
private function _getPerson(int $id) : Person
private function _getPerson(int $id): Person
{
$person = $this->getDoctrine()->getManager()
->getRepository('ChillPersonBundle:Person')->find($id);
if ($person === null) {
if (null === $person) {
throw $this->createNotFoundException('Person not found');
}
$this->denyAccessUnlessGranted(PersonVoter::SEE, $person,
"You are not allowed to see this person");
$this->denyAccessUnlessGranted(
PersonVoter::SEE,
$person,
'You are not allowed to see this person'
);
return $person;
}
private function _validatePerson(Person $person): ConstraintViolationListInterface
{
$errors = $this->validator->validate(
$person,
null,
['Default']
);
// Can be disabled with config
if (false === $this->container->getParameter('chill_person.allow_multiple_simultaneous_accompanying_periods')) {
$errors_accompanying_period = $this->validator->validate(
$person,
null,
['accompanying_period_consistent']
);
foreach ($errors_accompanying_period as $error) {
$errors->add($error);
}
}
return $errors;
}
}

View File

@@ -1,50 +1,51 @@
<?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.
*/
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\CRUD\Controller\CRUDController;
use Symfony\Component\HttpFoundation\Request;
use Chill\MainBundle\Pagination\PaginatorInterface;
use Symfony\Component\HttpFoundation\Request;
/**
* Class AdminClosingMotiveController
* Controller for closing motives
*
* @package Chill\PersonBundle\Controller
* Controller for closing motives.
*/
class AdminClosingMotiveController extends CRUDController
{
/**
* @param \Chill\MainBundle\CRUD\Controller\string|string $action
* @param Request $request
* @return object
*/
protected function createEntity($action, Request $request): object
{
$entity = parent::createEntity($action, $request);
if ($request->query->has('parent_id')) {
$parentId = $request->query->getInt('parent_id');
$parent = $this->getDoctrine()->getManager()
->getRepository($this->getEntityClass())
->find($parentId);
if (NULL === $parent) {
if (null === $parent) {
throw $this->createNotFoundException('parent id not found');
}
$entity->setParent($parent);
}
return $entity;
}
/**
* @param string $action
* @param \Doctrine\ORM\QueryBuilder|mixed $query
* @param Request $request
* @param PaginatorInterface $paginator
*
* @return \Doctrine\ORM\QueryBuilder|mixed
*/
protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator)

View File

@@ -1,26 +1,31 @@
<?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.
*/
namespace Chill\PersonBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
/**
* Class AdminController
*
* @package Chill\PersonBundle\Controller
* Class AdminController.
*/
class AdminController extends AbstractController
{
/**
* @param $_locale
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function indexAction($_locale)
{
return $this->render('ChillPersonBundle:Admin:layout.html.twig', []);
}
/**
* @return \Symfony\Component\HttpFoundation\RedirectResponse
*/

View File

@@ -1,15 +1,20 @@
<?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.
*/
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\CRUD\Controller\CRUDController;
/**
* Class AdminMaritalStatusController
*
* @package Chill\PersonBundle\Controller
* Class AdminMaritalStatusController.
*/
class AdminMaritalStatusController extends CRUDController
{
// for minimal cases, nothing is required here !
}
}

View File

@@ -1,27 +1,36 @@
<?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.
*/
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\CRUD\Controller\ApiController;
use Chill\MainBundle\Entity\Address;
use Chill\MainBundle\Entity\AddressReference;
use Chill\MainBundle\Serializer\Model\Collection;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Entity\Household\Household;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Repository\Household\HouseholdACLAwareRepositoryInterface;
use Chill\PersonBundle\Repository\Household\HouseholdRepository;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use function array_filter;
use function array_values;
class HouseholdApiController extends ApiController
{
private HouseholdRepository $householdRepository;
private HouseholdACLAwareRepositoryInterface $householdACLAwareRepository;
private HouseholdRepository $householdRepository;
public function __construct(
HouseholdRepository $householdRepository,
HouseholdACLAwareRepositoryInterface $householdACLAwareRepository
@@ -30,53 +39,44 @@ class HouseholdApiController extends ApiController
$this->householdACLAwareRepository = $householdACLAwareRepository;
}
public function householdAddressApi($id, Request $request, string $_format): Response
{
return $this->addRemoveSomething('address', $id, $request, $_format, 'address', Address::class, [ 'groups' => [ 'read' ] ]);
}
/**
* Find Household of people participating to the same AccompanyingPeriod
* @Route("/api/1.0/person/household/by-address-reference/{id}.json",
* name="chill_api_person_household_by_address_reference")
*
* @ParamConverter("person", options={"id" = "person_id"})
* @return \Symfony\Component\HttpFoundation\JsonResponse
*/
public function suggestHouseholdByAccompanyingPeriodParticipationApi(Person $person, string $_format)
public function getHouseholdByAddressReference(AddressReference $addressReference): Response
{
// TODO add acl
// TODO ACL
$this->denyAccessUnlessGranted('ROLE_USER');
$count = $this->householdRepository->countByAccompanyingPeriodParticipation($person);
$paginator = $this->getPaginatorFactory()->create($count);
$households = [];
if ($count !== 0) {
$allHouseholds = $this->householdRepository->findByAccompanyingPeriodParticipation($person,
$paginator->getItemsPerPage(), $paginator->getCurrentPageFirstItemNumber());
$currentHouseholdPerson = $person->getCurrentHousehold();
foreach ($allHouseholds as $h) {
if ($h !== $currentHouseholdPerson) {
array_push($households, $h);
}
}
if (null !== $currentHouseholdPerson) {
$count = $count - 1;
$paginator = $this->getPaginatorFactory()->create($count);
}
}
$total = $this->householdACLAwareRepository->countByAddressReference($addressReference);
$paginator = $this->getPaginatorFactory()->create($total);
$households = $this->householdACLAwareRepository->findByAddressReference(
$addressReference,
$paginator->getCurrentPageFirstItemNumber(),
$paginator->getItemsPerPage()
);
$collection = new Collection($households, $paginator);
return $this->json($collection, Response::HTTP_OK, [],
[ "groups" => ["read"]]);
return $this->json($collection, Response::HTTP_OK, [], [
AbstractNormalizer::GROUPS => ['read'],
]);
}
public function householdAddressApi($id, Request $request, string $_format): Response
{
return $this->addRemoveSomething('address', $id, $request, $_format, 'address', Address::class, ['groups' => ['read']]);
}
/**
* @Route("/api/1.0/person/address/suggest/by-household/{household_id}.{_format}",
* name="chill_person_address_suggest_by_household",
* requirements={
* "_format"="json"
* name="chill_person_address_suggest_by_household",
* requirements={
* "_format": "json"
* }
* )
* @ParamConverter("household", options={"id" = "household_id"})
* )
* @ParamConverter("household", options={"id": "household_id"})
*/
public function suggestAddressByHousehold(Household $household, string $_format)
{
@@ -90,9 +90,11 @@ class HouseholdApiController extends ApiController
$a = $participation->getAccompanyingPeriod()->getAddressLocation();
$addresses[$a->getId()] = $a;
}
if (null !== $personLocation = $participation
->getAccompanyingPeriod()->getPersonLocation()) {
$a = $personLocation->getCurrentHouseholdAddress();
if (null !== $a) {
$addresses[$a->getId()] = $a;
}
@@ -102,34 +104,59 @@ class HouseholdApiController extends ApiController
// remove the actual address
$actual = $household->getCurrentAddress();
if (null !== $actual) {
$addresses = \array_filter($addresses, fn($a) => $a !== $actual);
$addresses = array_filter($addresses, fn ($a) => $a !== $actual);
}
return $this->json(\array_values($addresses), Response::HTTP_OK, [],
[ 'groups' => [ 'read' ] ]);
return $this->json(
array_values($addresses),
Response::HTTP_OK,
[],
['groups' => ['read']]
);
}
/**
* Find Household of people participating to the same AccompanyingPeriod.
*
* @Route("/api/1.0/person/household/by-address-reference/{id}.json",
* name="chill_api_person_household_by_address_reference")
* @param AddressReference $addressReference
* @return \Symfony\Component\HttpFoundation\JsonResponse
* @ParamConverter("person", options={"id": "person_id"})
*/
public function getHouseholdByAddressReference(AddressReference $addressReference): Response
public function suggestHouseholdByAccompanyingPeriodParticipationApi(Person $person, string $_format)
{
// TODO ACL
$this->denyAccessUnlessGranted('ROLE_USER');
// TODO add acl
$total = $this->householdACLAwareRepository->countByAddressReference($addressReference);
$paginator = $this->getPaginatorFactory()->create($total);
$households = $this->householdACLAwareRepository->findByAddressReference($addressReference,
$paginator->getCurrentPageFirstItemNumber(), $paginator->getItemsPerPage());
$count = $this->householdRepository->countByAccompanyingPeriodParticipation($person);
$paginator = $this->getPaginatorFactory()->create($count);
$households = [];
if (0 !== $count) {
$allHouseholds = $this->householdRepository->findByAccompanyingPeriodParticipation(
$person,
$paginator->getItemsPerPage(),
$paginator->getCurrentPageFirstItemNumber()
);
$currentHouseholdPerson = $person->getCurrentHousehold();
foreach ($allHouseholds as $h) {
if ($h !== $currentHouseholdPerson) {
array_push($households, $h);
}
}
if (null !== $currentHouseholdPerson) {
$count = $count - 1;
$paginator = $this->getPaginatorFactory()->create($count);
}
}
$collection = new Collection($households, $paginator);
return $this->json($collection, Response::HTTP_OK, [], [
AbstractNormalizer::GROUPS => ['read']
]);
return $this->json(
$collection,
Response::HTTP_OK,
[],
['groups' => ['read']]
);
}
}

View File

@@ -1,36 +1,41 @@
<?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.
*/
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\Entity\Address;
use Chill\PersonBundle\Entity\Household\Household;
use Chill\PersonBundle\Form\HouseholdType;
use Chill\PersonBundle\Repository\Household\PositionRepository;
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\Translation\TranslatorInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Chill\PersonBundle\Entity\Household\Household;
use Chill\PersonBundle\Entity\Household\Position;
use Chill\PersonBundle\Repository\Household\PositionRepository;
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
use Symfony\Component\Security\Core\Security;
/**
* @Route("/{_locale}/person/household")
*/
class HouseholdController extends AbstractController
{
private TranslatorInterface $translator;
private PositionRepository $positionRepository;
private Security $security;
private SerializerInterface $serializer;
private Security $security;
private TranslatorInterface $translator;
public function __construct(
TranslatorInterface $translator,
@@ -46,51 +51,14 @@ class HouseholdController extends AbstractController
/**
* @Route(
* "/{household_id}/summary",
* name="chill_person_household_summary",
* methods={"GET", "HEAD"}
* )
* @ParamConverter("household", options={"id" = "household_id"})
*/
public function summary(Request $request, Household $household)
{
// TODO ACL
$positions = $this->positionRepository
->findByActiveOrdered()
;
// little performance improvement:
// initialize members collection, which will avoid
// some queries
$household->getMembers()->initialize();
if ($request->query->has('edit')) {
$form = $this->createMetadataForm($household);
} else {
$form = null;
}
return $this->render('@ChillPerson/Household/summary.html.twig',
[
'household' => $household,
'positions' => $positions,
'form' => NULL !== $form ? $form->createView() : null,
]
);
}
/**
* @Route(
* "/{household_id}/accompanying-period",
* name="chill_person_household_accompanying_period",
* methods={"GET", "HEAD"}
* )
* @ParamConverter("household", options={"id" = "household_id"})
* "/{household_id}/accompanying-period",
* name="chill_person_household_accompanying_period",
* methods={"GET", "HEAD"}
* )
* @ParamConverter("household", options={"id": "household_id"})
*/
public function accompanyingPeriod(Request $request, Household $household)
{
$currentMembers = $household->getCurrentPersons();
$accompanyingPeriods = [];
@@ -100,9 +68,8 @@ class HouseholdController extends AbstractController
foreach ($accompanyingPeriodsMember as $accompanyingPeriod) {
if (!$this->security->isGranted(AccompanyingPeriodVoter::SEE, $accompanyingPeriod)) {
continue;
} else {
$accompanyingPeriods[$accompanyingPeriod->getId()] = $accompanyingPeriod;
}
$accompanyingPeriods[$accompanyingPeriod->getId()] = $accompanyingPeriod;
}
}
@@ -115,93 +82,44 @@ class HouseholdController extends AbstractController
foreach ($accompanyingPeriodsOldMember as $accompanyingPeriod) {
if (!$this->security->isGranted(AccompanyingPeriodVoter::SEE, $accompanyingPeriod)) {
continue;
} else {
$id = $accompanyingPeriod->getId();
}
$id = $accompanyingPeriod->getId();
if (!array_key_exists($id, $accompanyingPeriodsOld) && !array_key_exists($id, $accompanyingPeriods)) {
$accompanyingPeriodsOld[$id] = $accompanyingPeriod;
}
if (!array_key_exists($id, $accompanyingPeriodsOld) && !array_key_exists($id, $accompanyingPeriods)) {
$accompanyingPeriodsOld[$id] = $accompanyingPeriod;
}
}
}
return $this->render('@ChillPerson/Household/accompanying_period.html.twig',
return $this->render(
'@ChillPerson/Household/accompanying_period.html.twig',
[
'household' => $household,
'accompanying_periods' => $accompanyingPeriods,
'accompanying_periods_old' => $accompanyingPeriodsOld
'accompanying_periods_old' => $accompanyingPeriodsOld,
]
);
}
/**
* @Route(
* "/{household_id}/addresses",
* name="chill_person_household_addresses",
* methods={"GET", "HEAD"}
* )
* @ParamConverter("household", options={"id" = "household_id"})
*/
public function addresses(Request $request, Household $household)
{
// TODO ACL
//TODO put these lines into a validator constraint on household->getAddress
$addresses = $household->getAddresses();
$cond = True;
for ($i=0; $i < count($addresses) - 1; $i++) {
if ($addresses[$i]->getValidFrom() != $addresses[$i + 1]->getValidTo()) {
$cond = False;
}
}
return $this->render('@ChillPerson/Household/addresses.html.twig',
[
'household' => $household
]
);
}
/**
* @Route(
* "/{household_id}/address/move",
* name="chill_person_household_address_move",
* methods={"GET", "HEAD", "POST"}
* )
* @ParamConverter("household", options={"id" = "household_id"})
*/
public function addressMove(Request $request, Household $household)
{
// TODO ACL
return $this->render('@ChillPerson/Household/address_move.html.twig',
[
'household' => $household
]
);
}
/**
* @Route(
* "/{household_id}/address/edit",
* name="chill_person_household_address_edit",
* methods={"GET", "HEAD", "POST"}
* )
* @ParamConverter("household", options={"id" = "household_id"})
* "/{household_id}/address/edit",
* name="chill_person_household_address_edit",
* methods={"GET", "HEAD", "POST"}
* )
* @ParamConverter("household", options={"id": "household_id"})
*/
public function addressEdit(Request $request, Household $household)
{
// TODO ACL
$address_id = $request->query->get('address_id');
$address = $this->getDoctrine()->getManager()
->getRepository(Address::class)
->find($address_id)
;
->find($address_id);
return $this->render('@ChillPerson/Household/address_edit.html.twig',
return $this->render(
'@ChillPerson/Household/address_edit.html.twig',
[
'household' => $household,
'address' => $address,
@@ -211,32 +129,61 @@ class HouseholdController extends AbstractController
/**
* @Route(
* "/{household_id}/relationship",
* name="chill_person_household_relationship",
* methods={"GET", "HEAD"}
* )
* @ParamConverter("household", options={"id" = "household_id"})
* "/{household_id}/addresses",
* name="chill_person_household_addresses",
* methods={"GET", "HEAD"}
* )
* @ParamConverter("household", options={"id": "household_id"})
*/
public function showRelationship(Request $request, Household $household)
public function addresses(Request $request, Household $household)
{
$jsonString = $this->serializer->serialize($household->getCurrentPersons(),
'json', [ AbstractNormalizer::GROUPS => ['read']]);
// TODO ACL
return $this->render('@ChillPerson/Household/relationship.html.twig',
//TODO put these lines into a validator constraint on household->getAddress
$addresses = $household->getAddresses();
$cond = true;
for ($i = 0; count($addresses) - 1 > $i; ++$i) {
if ($addresses[$i]->getValidFrom() != $addresses[$i + 1]->getValidTo()) {
$cond = false;
}
}
return $this->render(
'@ChillPerson/Household/addresses.html.twig',
[
'household' => $household,
'persons' => $jsonString
]
);
}
/**
* @Route(
* "/{household_id}/members/metadata/edit",
* name="chill_person_household_members_metadata_edit",
* methods={"GET", "POST"}
* )
* @ParamConverter("household", options={"id" = "household_id"})
* "/{household_id}/address/move",
* name="chill_person_household_address_move",
* methods={"GET", "HEAD", "POST"}
* )
* @ParamConverter("household", options={"id": "household_id"})
*/
public function addressMove(Request $request, Household $household)
{
// TODO ACL
return $this->render(
'@ChillPerson/Household/address_move.html.twig',
[
'household' => $household,
]
);
}
/**
* @Route(
* "/{household_id}/members/metadata/edit",
* name="chill_person_household_members_metadata_edit",
* methods={"GET", "POST"}
* )
* @ParamConverter("household", options={"id": "household_id"})
*/
public function editHouseholdMetadata(Request $request, Household $household)
{
@@ -251,32 +198,90 @@ class HouseholdController extends AbstractController
$this->addFlash('success', $this->translator->trans('household.data_saved'));
return $this->redirectToRoute('chill_person_household_summary', [
'household_id' => $household->getId()
'household_id' => $household->getId(),
]);
}
return $this->render('@ChillPerson/Household/edit_member_metadata.html.twig', [
'household' => $household,
'form' => $form->createView()
'form' => $form->createView(),
]);
}
/**
* @Route(
* "/{household_id}/relationship",
* name="chill_person_household_relationship",
* methods={"GET", "HEAD"}
* )
* @ParamConverter("household", options={"id": "household_id"})
*/
public function showRelationship(Request $request, Household $household)
{
$jsonString = $this->serializer->serialize(
$household->getCurrentPersons(),
'json',
[AbstractNormalizer::GROUPS => ['read']]
);
return $this->render(
'@ChillPerson/Household/relationship.html.twig',
[
'household' => $household,
'persons' => $jsonString,
]
);
}
/**
* @Route(
* "/{household_id}/summary",
* name="chill_person_household_summary",
* methods={"GET", "HEAD"}
* )
* @ParamConverter("household", options={"id": "household_id"})
*/
public function summary(Request $request, Household $household)
{
// TODO ACL
$positions = $this->positionRepository
->findByActiveOrdered();
// little performance improvement:
// initialize members collection, which will avoid
// some queries
$household->getMembers()->initialize();
if ($request->query->has('edit')) {
$form = $this->createMetadataForm($household);
} else {
$form = null;
}
return $this->render(
'@ChillPerson/Household/summary.html.twig',
[
'household' => $household,
'positions' => $positions,
'form' => null !== $form ? $form->createView() : null,
]
);
}
private function createMetadataForm(Household $household): FormInterface
{
$form = $this->createForm(
return $this->createForm(
HouseholdType::class,
$household,
[
'action' => $this->generateUrl(
'chill_person_household_members_metadata_edit',
[
'household_id' => $household->getId()
'household_id' => $household->getId(),
]
)
),
]
);
return $form;
}
}

View File

@@ -1,39 +1,44 @@
<?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.
*/
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\CRUD\Controller\ApiController;
use Chill\PersonBundle\Entity\Household\Household;
use Chill\PersonBundle\Entity\Household\HouseholdMember;
use Chill\PersonBundle\Entity\Household\Position;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Form\HouseholdMemberType;
use Chill\PersonBundle\Household\MembersEditor;
use Chill\PersonBundle\Repository\AccompanyingPeriodRepository;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Entity\Household\Household;
use Chill\PersonBundle\Form\HouseholdMemberType;
use Chill\PersonBundle\Entity\Household\HouseholdMember;
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Serializer\Exception;
use Symfony\Component\Routing\Annotation\Route;
use Chill\MainBundle\CRUD\Controller\ApiController;
use Symfony\Component\Translation\TranslatorInterface;
use Chill\PersonBundle\Household\MembersEditor;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
class HouseholdMemberController extends ApiController
{
private UrlGeneratorInterface $generator;
private TranslatorInterface $translator;
private AccompanyingPeriodRepository $periodRepository;
private TranslatorInterface $translator;
public function __construct(
UrlGeneratorInterface $generator,
TranslatorInterface $translator,
AccompanyingPeriodRepository $periodRepository
)
{
) {
$this->generator = $generator;
$this->translator = $translator;
$this->periodRepository = $periodRepository;
@@ -41,16 +46,143 @@ class HouseholdMemberController extends ApiController
/**
* @Route(
* "/api/1.0/person/household/members/move.{_format}",
* name="chill_api_person_household_members_move"
* )
* "/{_locale}/person/household/member/{id}/edit",
* name="chill_person_household_member_edit"
* )
*/
public function editMembership(Request $request, HouseholdMember $member): Response
{
// TODO ACL
$form = $this->createForm(HouseholdMemberType::class, $member, [
'validation_groups' => ['household_memberships'],
]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$this->getDoctrine()->getManager()->flush();
$this->addFlash('success', $this->translator
->trans('household.successfully saved member'));
return $this->redirect(
$request->get('returnPath', null) ??
$this->generator->generate('chill_person_household_summary', ['household_id' => $member->getHousehold()->getId()])
);
}
return $this->render('@ChillPerson/Household/Member/edit.html.twig', [
'household' => $member->getHousehold(),
'member' => $member,
'form' => $form->createView(),
]);
}
/**
* Route for showing an editor to leave a household.
*
* Possibles arguments are:
*
* * persons[]: an id of the person to add to the form
* * household: the id of the destination household
* * allow_leave_without_household: if present, the editor will allow
* to leave household without joining another
*
* @Route(
* "/{_locale}/person/household/members/editor",
* name="chill_person_household_members_editor"
* )
*/
public function editor(Request $request)
{
$em = $this->getDoctrine()->getManager();
if ($request->query->has('persons')) {
$ids = $request->query->get('persons', []);
if (0 === count($ids)) {
throw new BadRequestException('parameters persons in query ' .
'is not an array or empty');
}
$persons = $em->getRepository(Person::class)
->findById($ids);
foreach ($persons as $person) {
$this->denyAccessUnlessGranted(
PersonVoter::SEE,
$person,
"You are not allowed to see person with id {$person->getId()}"
);
}
}
if ($householdId = $request->query->get('household', false)) {
$household = $em->getRepository(Household::class)
->find($householdId);
$allowHouseholdCreate = false;
$allowHouseholdSearch = false;
$allowLeaveWithoutHousehold = false;
if (null === $household) {
throw $this->createNotFoundException('household not found');
}
// TODO ACL on household
}
$positions = $this->getDoctrine()->getManager()
->getRepository(Position::class)
->findAll();
$data = [
'persons' => $persons ?? false ?
$this->getSerializer()->normalize($persons, 'json', ['groups' => ['read']]) : [],
'household' => $household ?? false ?
$this->getSerializer()->normalize($household, 'json', ['groups' => ['read']]) : null,
'positions' => $this->getSerializer()->normalize($positions, 'json', ['groups' => ['read']]),
'allowHouseholdCreate' => $allowHouseholdCreate ?? true,
'allowHouseholdSearch' => $allowHouseholdSearch ?? true,
'allowLeaveWithoutHousehold' => $allowLeaveWithoutHousehold ?? $request->query->has('allow_leave_without_household'),
];
// context
if ($request->query->has('accompanying_period_id')) {
$period = $this->periodRepository->find(
$request->query->getInt('accompanying_period_id')
);
if (null === $period) {
throw $this->createNotFoundException('period not found');
}
// TODO add acl on accompanying Course
}
return $this->render('@ChillPerson/Household/members_editor.html.twig', [
'data' => $data,
'expandSuggestions' => (int) $request->query->getBoolean('expand_suggestions', false),
'accompanyingCourse' => $period ?? null,
]);
}
/**
* @Route(
* "/api/1.0/person/household/members/move.{_format}",
* name="chill_api_person_household_members_move"
* )
*
* @param mixed $_format
*/
public function move(Request $request, $_format): Response
{
try {
$editor = $this->getSerializer()
->deserialize($request->getContent(), MembersEditor::class,
$_format, ['groups' => [ "read" ]]);
->deserialize(
$request->getContent(),
MembersEditor::class,
$_format,
['groups' => ['read']]
);
} catch (Exception\InvalidArgumentException | Exception\UnexpectedValueException $e) {
throw new BadRequestException("Deserialization error: {$e->getMessage()}", 45896, $e);
}
@@ -68,143 +200,16 @@ class HouseholdMemberController extends ApiController
// if new household, persist it
if (
$editor->hasHousehold()
&&
FALSE === $em->contains($editor->getHousehold())
&& false === $em->contains($editor->getHousehold())
) {
$em->persist($editor->getHousehold());
}
foreach ($editor->getPersistable() as $el) {
$em->persist($el);
$em->persist($el);
}
$em->flush();
return $this->json($editor->getHousehold(), Response::HTTP_OK, [], ["groups" => ["read"]]);
}
/**
* Route for showing an editor to leave a household.
*
* Possibles arguments are:
*
* * persons[]: an id of the person to add to the form
* * household: the id of the destination household
* * allow_leave_without_household: if present, the editor will allow
* to leave household without joining another
*
* @Route(
* "/{_locale}/person/household/members/editor",
* name="chill_person_household_members_editor"
* )
*/
public function editor(Request $request)
{
$em = $this->getDoctrine()->getManager();
if ($request->query->has('persons')) {
$ids = $request->query->get('persons', []);
if (0 === count($ids)) {
throw new BadRequestException("parameters persons in query ".
"is not an array or empty");
}
$persons = $em->getRepository(Person::class)
->findById($ids)
;
foreach ($persons as $person) {
$this->denyAccessUnlessGranted(PersonVoter::SEE, $person,
"You are not allowed to see person with id {$person->getId()}"
);
}
}
if ($householdId = $request->query->get('household', false)) {
$household = $em->getRepository(Household::class)
->find($householdId)
;
$allowHouseholdCreate = false;
$allowHouseholdSearch = false;
$allowLeaveWithoutHousehold = false;
if (NULL === $household) {
throw $this->createNotFoundException('household not found');
}
// TODO ACL on household
}
$positions = $this->getDoctrine()->getManager()
->getRepository(Position::class)
->findAll()
;
$data = [
'persons' => $persons ?? false ?
$this->getSerializer()->normalize($persons, 'json', [ 'groups' => [ 'read' ]]) : [],
'household' => $household ?? false ?
$this->getSerializer()->normalize($household, 'json', [ 'groups' => [ 'read' ]]) : null,
'positions' =>
$this->getSerializer()->normalize($positions, 'json', [ 'groups' => [ 'read' ]]),
'allowHouseholdCreate' => $allowHouseholdCreate ?? true,
'allowHouseholdSearch' => $allowHouseholdSearch ?? true,
'allowLeaveWithoutHousehold' => $allowLeaveWithoutHousehold ?? $request->query->has('allow_leave_without_household'),
];
// context
if ($request->query->has('accompanying_period_id')) {
$period = $this->periodRepository->find(
$request->query->getInt('accompanying_period_id')
);
if ($period === null) {
throw $this->createNotFoundException('period not found');
}
// TODO add acl on accompanying Course
}
return $this->render('@ChillPerson/Household/members_editor.html.twig', [
'data' => $data,
'expandSuggestions' => (int) $request->query->getBoolean('expand_suggestions', false),
'accompanyingCourse' => $period ?? null,
]);
}
/**
* @Route(
* "/{_locale}/person/household/member/{id}/edit",
* name="chill_person_household_member_edit"
* )
*/
public function editMembership(Request $request, HouseholdMember $member): Response
{
// TODO ACL
$form = $this->createForm(HouseholdMemberType::class, $member, [
'validation_groups' => [ 'household_memberships' ]
]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$this->getDoctrine()->getManager()->flush();
$this->addFlash('success', $this->translator
->trans('household.successfully saved member'))
;
return $this->redirect(
$request->get('returnPath', null) ??
$this->generator->generate('chill_person_household_summary', [ 'household_id' =>
$member->getHousehold()->getId() ])
);
}
return $this->render('@ChillPerson/Household/Member/edit.html.twig', [
'household' => $member->getHousehold(),
'member' => $member,
'form' => $form->createView()
]);
return $this->json($editor->getHousehold(), Response::HTTP_OK, [], ['groups' => ['read']]);
}
}

View File

@@ -1,10 +1,17 @@
<?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.
*/
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\CRUD\Controller\ApiController;
use DateTime;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class OpeningApiController extends ApiController
{
@@ -12,6 +19,6 @@ class OpeningApiController extends ApiController
{
$qb->where($qb->expr()->gt('e.noActiveAfter', ':now'))
->orWhere($qb->expr()->isNull('e.noActiveAfter'));
$qb->setParameter('now', new \DateTime('now'));
}
$qb->setParameter('now', new DateTime('now'));
}
}

View File

@@ -1,43 +1,25 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2016, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\Entity\Address;
use Chill\MainBundle\Form\Type\AddressType;
use Chill\PersonBundle\Entity\Person;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Chill\PersonBundle\Entity\Person;
use Chill\MainBundle\Form\Type\AddressType;
use Chill\MainBundle\Entity\Address;
use Doctrine\Common\Collections\Criteria;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Validator\Validator\ValidatorInterface;
/**
* Class PersonAddressController
* Controller for addresses associated with person
*
* @package Chill\PersonBundle\Controller
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* @author Champs Libres <info@champs-libres.coop>
* Controller for addresses associated with person.
*/
class PersonAddressController extends AbstractController
{
@@ -48,78 +30,27 @@ class PersonAddressController extends AbstractController
/**
* PersonAddressController constructor.
*
* @param ValidatorInterface $validator
*/
public function __construct(ValidatorInterface $validator)
{
$this->validator = $validator;
}
public function listAction($person_id)
{
$person = $this->getDoctrine()->getManager()
->getRepository('ChillPersonBundle:Person')
->find($person_id);
if ($person === null) {
throw $this->createNotFoundException("Person with id $person_id not"
. " found ");
}
$this->denyAccessUnlessGranted(
'CHILL_PERSON_SEE',
$person,
"You are not allowed to edit this person."
);
return $this->render('ChillPersonBundle:Address:list.html.twig', array(
'person' => $person
));
}
public function newAction($person_id)
{
$person = $this->getDoctrine()->getManager()
->getRepository('ChillPersonBundle:Person')
->find($person_id);
if ($person === null) {
throw $this->createNotFoundException("Person with id $person_id not"
. " found ");
}
$this->denyAccessUnlessGranted(
'CHILL_PERSON_UPDATE',
$person,
"You are not allowed to edit this person."
);
$address = new Address();
$form = $this->createCreateForm($person, $address);
return $this->render('ChillPersonBundle:Address:new.html.twig', array(
'person' => $person,
'form' => $form->createView()
));
}
public function createAction($person_id, Request $request)
{
$person = $this->getDoctrine()->getManager()
->getRepository('ChillPersonBundle:Person')
->find($person_id);
->getRepository('ChillPersonBundle:Person')
->find($person_id);
if ($person === null) {
throw $this->createNotFoundException("Person with id $person_id not"
. " found ");
if (null === $person) {
throw $this->createNotFoundException("Person with id {$person_id} not"
. ' found ');
}
$this->denyAccessUnlessGranted(
'CHILL_PERSON_UPDATE',
$person,
"You are not allowed to edit this person."
'You are not allowed to edit this person.'
);
$address = new Address();
@@ -137,7 +68,6 @@ class PersonAddressController extends AbstractController
$this->addFlash('error', $error->getMessage());
}
} elseif ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->flush();
@@ -146,47 +76,96 @@ class PersonAddressController extends AbstractController
$this->get('translator')->trans('The new address was created successfully')
);
return $this->redirectToRoute('chill_person_address_list', array(
'person_id' => $person->getId()
));
return $this->redirectToRoute('chill_person_address_list', [
'person_id' => $person->getId(),
]);
} else {
$this->addFlash('error', $this->get('translator')
->trans('Error! Address not created!'));
->trans('Error! Address not created!'));
}
}
return $this->render('ChillPersonBundle:Address:new.html.twig', array(
return $this->render('ChillPersonBundle:Address:new.html.twig', [
'person' => $person,
'form' => $form->createView()
));
'form' => $form->createView(),
]);
}
public function editAction($person_id, $address_id)
{
$person = $this->getDoctrine()->getManager()
->getRepository('ChillPersonBundle:Person')
->find($person_id);
->getRepository('ChillPersonBundle:Person')
->find($person_id);
if ($person === null) {
throw $this->createNotFoundException("Person with id $person_id not"
. " found ");
if (null === $person) {
throw $this->createNotFoundException("Person with id {$person_id} not"
. ' found ');
}
$this->denyAccessUnlessGranted(
'CHILL_PERSON_UPDATE',
$person,
"You are not allowed to edit this person."
'You are not allowed to edit this person.'
);
$address = $this->findAddressById($person, $address_id);
$form = $this->createEditForm($person, $address);
return $this->render('ChillPersonBundle:Address:edit.html.twig', array(
'person' => $person,
'address' => $address,
'form' => $form->createView()
));
return $this->render('ChillPersonBundle:Address:edit.html.twig', [
'person' => $person,
'address' => $address,
'form' => $form->createView(),
]);
}
public function listAction($person_id)
{
$person = $this->getDoctrine()->getManager()
->getRepository('ChillPersonBundle:Person')
->find($person_id);
if (null === $person) {
throw $this->createNotFoundException("Person with id {$person_id} not"
. ' found ');
}
$this->denyAccessUnlessGranted(
'CHILL_PERSON_SEE',
$person,
'You are not allowed to edit this person.'
);
return $this->render('ChillPersonBundle:Address:list.html.twig', [
'person' => $person,
]);
}
public function newAction($person_id)
{
$person = $this->getDoctrine()->getManager()
->getRepository('ChillPersonBundle:Person')
->find($person_id);
if (null === $person) {
throw $this->createNotFoundException("Person with id {$person_id} not"
. ' found ');
}
$this->denyAccessUnlessGranted(
'CHILL_PERSON_UPDATE',
$person,
'You are not allowed to edit this person.'
);
$address = new Address();
$form = $this->createCreateForm($person, $address);
return $this->render('ChillPersonBundle:Address:new.html.twig', [
'person' => $person,
'form' => $form->createView(),
]);
}
public function updateAction($person_id, $address_id, Request $request)
@@ -195,15 +174,15 @@ class PersonAddressController extends AbstractController
->getRepository('ChillPersonBundle:Person')
->find($person_id);
if ($person === null) {
throw $this->createNotFoundException("Person with id $person_id not"
. " found ");
if (null === $person) {
throw $this->createNotFoundException("Person with id {$person_id} not"
. ' found ');
}
$this->denyAccessUnlessGranted(
'CHILL_PERSON_UPDATE',
$person,
"You are not allowed to edit this person."
'You are not allowed to edit this person.'
);
$address = $this->findAddressById($person, $address_id);
@@ -220,90 +199,84 @@ class PersonAddressController extends AbstractController
}
} elseif ($form->isValid()) {
$this->getDoctrine()->getManager()
->flush();
->flush();
$this->addFlash('success', $this->get('translator')->trans(
"The address has been successfully updated"
'The address has been successfully updated'
));
return $this->redirectToRoute('chill_person_address_list', array(
'person_id' => $person->getId()
));
return $this->redirectToRoute('chill_person_address_list', [
'person_id' => $person->getId(),
]);
} else {
$this->addFlash('error', $this->get('translator')
->trans('Error when updating the period'));
}
}
return $this->render('ChillPersonBundle:Address:edit.html.twig', array(
'person' => $person,
'address' => $address,
'form' => $form->createView()
));
return $this->render('ChillPersonBundle:Address:edit.html.twig', [
'person' => $person,
'address' => $address,
'form' => $form->createView(),
]);
}
/**
* @param Person $person
* @param Address $address
* @return \Symfony\Component\Form\Form
*/
protected function createEditForm(Person $person, Address $address)
{
$form = $this->createForm(AddressType::class, $address, array(
'method' => 'POST',
'action' => $this->generateUrl('chill_person_address_update', array(
'person_id' => $person->getId(),
'address_id' => $address->getId()
)),
'has_no_address' => true
));
$form->add('submit', SubmitType::class, array(
'label' => 'Submit'
));
return $form;
}
/**
*
* @param Person $person
* @param Address $address
* @return \Symfony\Component\Form\Form
*/
protected function createCreateForm(Person $person, Address $address)
{
$form = $this->createForm(AddressType::class, $address, array(
'method' => 'POST',
'action' => $this->generateUrl('chill_person_address_create', array(
'person_id' => $person->getId()
)),
'has_no_address' => true
));
$form = $this->createForm(AddressType::class, $address, [
'method' => 'POST',
'action' => $this->generateUrl('chill_person_address_create', [
'person_id' => $person->getId(),
]),
'has_no_address' => true,
]);
$form->add('submit', SubmitType::class, array(
'label' => 'Submit'
));
$form->add('submit', SubmitType::class, [
'label' => 'Submit',
]);
return $form;
}
/**
* @return \Symfony\Component\Form\Form
*/
protected function createEditForm(Person $person, Address $address)
{
$form = $this->createForm(AddressType::class, $address, [
'method' => 'POST',
'action' => $this->generateUrl('chill_person_address_update', [
'person_id' => $person->getId(),
'address_id' => $address->getId(),
]),
'has_no_address' => true,
]);
$form->add('submit', SubmitType::class, [
'label' => 'Submit',
]);
return $form;
}
/**
*
* @param Person $person
* @param int $address_id
* @return Address
*
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException if the address id does not exists or is not associated with given person
*
* @return Address
*/
protected function findAddressById(Person $person, $address_id)
{
$address = $this->getDoctrine()->getManager()
->getRepository(Address::class)
->find($address_id)
;
->find($address_id);
if (!$person->getAddresses()->contains($address)) {
throw $this->createAccessDeniedException("Not allowed to see this address");
throw $this->createAccessDeniedException('Not allowed to see this address');
}
return $address;
@@ -311,16 +284,17 @@ class PersonAddressController extends AbstractController
/**
* @param Chill\PersonBundle\Entity\Person $person
*
* @return \Symfony\Component\Validator\ConstraintViolationListInterface
*/
private function validatePerson(Person $person)
{
$errors = $this->validator
->validate($person, null, array('Default'));
->validate($person, null, ['Default']);
$errors_addresses_consistent = $this->validator
->validate($person, null, array('addresses_consistent'));
->validate($person, null, ['addresses_consistent']);
foreach($errors_addresses_consistent as $error) {
foreach ($errors_addresses_consistent as $error) {
$errors->add($error);
}

View File

@@ -1,70 +1,49 @@
<?php
/*
* Copyright (C) 2015-2021 Champs-Libres Coopérative <info@champs-libres.coop>
/**
* Chill is a software for social workers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Controller;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use Chill\PersonBundle\Entity\Person;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Symfony\Component\Security\Core\Role\Role;
use Chill\MainBundle\CRUD\Controller\ApiController;
use Chill\MainBundle\Entity\Address;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Chill\MainBundle\Entity\Address;
use Symfony\Component\Routing\Annotation\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Component\Security\Core\Role\Role;
use function array_filter;
use function array_values;
class PersonApiController extends ApiController
{
private AuthorizationHelper $authorizationHelper;
/**
* @param AuthorizationHelper $authorizationHelper
*/
public function __construct(AuthorizationHelper $authorizationHelper)
{
$this->authorizationHelper = $authorizationHelper;
}
protected function createEntity(string $action, Request $request): object
{
$person = 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]); */
return $person;
}
public function personAddressApi($id, Request $request, string $_format): Response
{
return $this->addRemoveSomething('address', $id, $request, $_format, 'address', Address::class, [ 'groups' => [ 'read' ] ]);
return $this->addRemoveSomething('address', $id, $request, $_format, 'address', Address::class, ['groups' => ['read']]);
}
/**
* @Route("/api/1.0/person/address/suggest/by-person/{person_id}.{_format}",
* name="chill_person_address_suggest_by_person",
* requirements={
* "_format"="json"
* name="chill_person_address_suggest_by_person",
* requirements={
* "_format": "json"
* }
* )
* @ParamConverter("person", options={"id" = "person_id"})
* )
* @ParamConverter("person", options={"id": "person_id"})
*/
public function suggestAddress(Person $person, Request $request, string $_format): Response
{
@@ -81,10 +60,20 @@ class PersonApiController extends ApiController
// remove the actual address
$actual = $person->getCurrentHouseholdAddress();
if (null !== $actual) {
$addresses = \array_filter($addresses, fn($a) => $a !== $actual);
$addresses = array_filter($addresses, fn ($a) => $a !== $actual);
}
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

@@ -1,65 +1,46 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2015, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Controller;
use Chill\PersonBundle\Privacy\PrivacyEvent;
use Psr\Log\LoggerInterface;
use Chill\PersonBundle\Config\ConfigPersonAltNamesHelper;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Form\PersonType;
use Chill\PersonBundle\Form\CreationPersonType;
use Chill\PersonBundle\Form\PersonType;
use Chill\PersonBundle\Privacy\PrivacyEvent;
use Chill\PersonBundle\Repository\PersonRepository;
use Chill\PersonBundle\Search\SimilarPersonMatcher;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Form\Extension\Core\Type\ButtonType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Form;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Security\Core\Role\Role;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use Chill\PersonBundle\Search\SimilarPersonMatcher;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Translation\TranslatorInterface;
use Chill\MainBundle\Search\SearchProvider;
use Chill\PersonBundle\Repository\PersonRepository;
use Chill\PersonBundle\Config\ConfigPersonAltNamesHelper;
use Chill\PersonBundle\Repository\PersonNotDuplicateRepository;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Routing\Annotation\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use function hash;
use function implode;
use function in_array;
use function is_array;
final class PersonController extends AbstractController
{
/**
* @var SimilarPersonMatcher
* @var ConfigPersonAltNamesHelper
*/
protected $similarPersonMatcher;
/**
* @var TranslatorInterface
*/
protected $translator;
protected $configPersonAltNameHelper;
/**
* @var EventDispatcherInterface
@@ -72,9 +53,14 @@ final class PersonController extends AbstractController
protected $personRepository;
/**
* @var ConfigPersonAltNamesHelper
* @var SimilarPersonMatcher
*/
protected $configPersonAltNameHelper;
protected $similarPersonMatcher;
/**
* @var TranslatorInterface
*/
protected $translator;
/**
* @var EntityManagerInterface
@@ -111,60 +97,28 @@ final class PersonController extends AbstractController
$this->validator = $validator;
$this->em = $em;
$this->security = $security;
}
public function getCFGroup()
{
$cFGroup = null;
$cFDefaultGroup = $this->em->getRepository("ChillCustomFieldsBundle:CustomFieldsDefaultGroup")
->findOneByEntity("Chill\PersonBundle\Entity\Person");
if($cFDefaultGroup) {
$cFGroup = $cFDefaultGroup->getCustomFieldsGroup();
}
return $cFGroup;
}
public function viewAction($person_id)
{
$person = $this->_getPerson($person_id);
if ($person === null) {
throw $this->createNotFoundException("Person with id $person_id not"
. " found on this server");
}
$this->denyAccessUnlessGranted('CHILL_PERSON_SEE', $person,
"You are not allowed to see this person.");
$event = new PrivacyEvent($person);
$this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event);
return $this->render('ChillPersonBundle:Person:view.html.twig',
array(
"person" => $person,
"cFGroup" => $this->getCFGroup(),
"alt_names" => $this->configPersonAltNameHelper->getChoices(),
));
}
public function editAction($person_id, Request $request)
{
$person = $this->_getPerson($person_id);
if ($person === null) {
if (null === $person) {
throw $this->createNotFoundException();
}
$this->denyAccessUnlessGranted('CHILL_PERSON_UPDATE', $person,
'You are not allowed to edit this person');
$this->denyAccessUnlessGranted(
'CHILL_PERSON_UPDATE',
$person,
'You are not allowed to edit this person'
);
$form = $this->createForm(PersonType::class, $person,
array(
"cFGroup" => $this->getCFGroup()
)
$form = $this->createForm(
PersonType::class,
$person,
[
'cFGroup' => $this->getCFGroup(),
]
);
$form->handleRequest($request);
@@ -172,28 +126,71 @@ final class PersonController extends AbstractController
if ($form->isSubmitted() && !$form->isValid()) {
$this->get('session')
->getFlashBag()->add('error', $this->translator
->trans('This form contains errors'));
->trans('This form contains errors'));
} elseif ($form->isSubmitted() && $form->isValid()) {
$this->get('session')->getFlashBag()
->add('success',
->add(
'success',
$this->get('translator')
->trans('The person data has been updated')
);
$this->em->flush();
return $this->redirectToRoute('chill_person_view', [
'person_id' => $person->getId()
return $this->redirectToRoute('chill_person_view', [
'person_id' => $person->getId(),
]);
}
return $this->render(
'ChillPersonBundle:Person:edit.html.twig',
['person' => $person, 'form' => $form->createView()]
);
}
return $this->render('ChillPersonBundle:Person:edit.html.twig',
array('person' => $person, 'form' => $form->createView()));
public function getCFGroup()
{
$cFGroup = null;
$cFDefaultGroup = $this->em->getRepository('ChillCustomFieldsBundle:CustomFieldsDefaultGroup')
->findOneByEntity('Chill\\PersonBundle\\Entity\\Person');
if ($cFDefaultGroup) {
$cFGroup = $cFDefaultGroup->getCustomFieldsGroup();
}
return $cFGroup;
}
/**
* Method for creating a new person
* @Route(
* "/{_locale}/person/household/{person_id}/history",
* name="chill_person_household_person_history",
* methods={"GET", "POST"}
* )
* @ParamConverter("person", options={"id": "person_id"})
*/
public function householdHistoryByPerson(Request $request, Person $person): Response
{
$this->denyAccessUnlessGranted(
'CHILL_PERSON_SEE',
$person,
'You are not allowed to see this person.'
);
$event = new PrivacyEvent($person);
$this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event);
return $this->render(
'@ChillPerson/Person/household_history.html.twig',
[
'person' => $person,
]
);
}
/**
* Method for creating a new person.
*
*The controller register data from a previous post on the form, and
* register it in the session.
@@ -201,15 +198,14 @@ 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".
*
* @param Request $request
* @return \Symfony\Component\HttpFoundation\RedirectResponse|Response
* @return Response|\Symfony\Component\HttpFoundation\RedirectResponse
*/
public function newAction(Request $request)
{
$person = new Person();
if (1 === count($this->security->getUser()
->getGroupCenters())) {
->getGroupCenters())) {
$person->setCenter(
$this->security->getUser()
->getGroupCenters()[0]
@@ -218,13 +214,13 @@ final class PersonController extends AbstractController
}
$form = $this->createForm(CreationPersonType::class, $person, [
'validation_groups' => ['create']
'validation_groups' => ['create'],
])->add('editPerson', SubmitType::class, [
'label' => 'Add the person'
'label' => 'Add the person',
])->add('createPeriod', SubmitType::class, [
'label' => 'Add the person and create an accompanying period'
'label' => 'Add the person and create an accompanying period',
])->add('createHousehold', SubmitType::class, [
'label' => 'Add the person and create an household'
'label' => 'Add the person and create an household',
]); // TODO createHousehold form action
$form->handleRequest($request);
@@ -233,14 +229,12 @@ final class PersonController extends AbstractController
$this->lastPostDataReset();
} elseif ($request->getMethod() === Request::METHOD_POST
&& $form->isValid()) {
$alternatePersons = $this->similarPersonMatcher
->matchPerson($person);
if (
FALSE === $this->isLastPostDataChanges($form, $request, true)
||
count($alternatePersons) === 0
false === $this->isLastPostDataChanges($form, $request, true)
|| count($alternatePersons) === 0
) {
$this->em->persist($person);
@@ -249,84 +243,75 @@ final class PersonController extends AbstractController
if ($form->get('createPeriod')->isClicked()) {
return $this->redirectToRoute('chill_person_accompanying_course_new', [
'person_id' => [ $person->getId() ]
'person_id' => [$person->getId()],
]);
}
return $this->redirectToRoute('chill_person_general_edit',
['person_id' => $person->getId()]);
return $this->redirectToRoute(
'chill_person_general_edit',
['person_id' => $person->getId()]
);
}
} elseif ($request->getMethod() === Request::METHOD_POST && !$form->isValid()) {
$this->addFlash('error', $this->translator->trans('This form contains errors'));
}
return $this->render('@ChillPerson/Person/create.html.twig',
return $this->render(
'@ChillPerson/Person/create.html.twig',
[
'form' => $form->createView(),
'alternatePersons' => $alternatePersons ?? []
'alternatePersons' => $alternatePersons ?? [],
]
);
}
private function isLastPostDataChanges(Form $form, Request $request, bool $replace = false): bool
public function viewAction($person_id)
{
/** @var SessionInterface $session */
$session = $this->get('session');
if (!$session->has('last_person_data')) {
return true;
$person = $this->_getPerson($person_id);
if (null === $person) {
throw $this->createNotFoundException("Person with id {$person_id} not"
. ' found on this server');
}
$newPost = $this->lastPostDataBuildHash($form, $request);
$this->denyAccessUnlessGranted(
'CHILL_PERSON_SEE',
$person,
'You are not allowed to see this person.'
);
$isChanged = $newPost !== $session->get('last_person_data');
$event = new PrivacyEvent($person);
$this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event);
if ($replace) {
$session->set('last_person_data', $newPost);
}
return $isChanged ;
}
private function lastPostDataReset(): void
{
$this->get('session')->set('last_person_data', "");
return $this->render(
'ChillPersonBundle:Person:view.html.twig',
[
'person' => $person,
'cFGroup' => $this->getCFGroup(),
'alt_names' => $this->configPersonAltNameHelper->getChoices(),
]
);
}
/**
* build the hash for posted data
* easy getting a person by his id.
*
* For privacy reasons, the data are hashed using sha512
* @param mixed $id
*
* @param Form $form
* @param Request $request
* @return string
* @return \Chill\PersonBundle\Entity\Person
*/
private function lastPostDataBuildHash(Form $form, Request $request): string
private function _getPerson($id)
{
$fields = [];
$ignoredFields = ['form_status', '_token'];
foreach ($request->request->all()[$form->getName()] as $field => $value) {
if (\in_array($field, $ignoredFields)) {
continue;
}
$fields[$field] = \is_array($value) ?
\implode(",", $value) : $value;
}
ksort($fields);
return \hash('sha512', \implode("&", $fields));
return $this->personRepository->find($id);
}
/**
*
* @param \Chill\PersonBundle\Entity\Person $person
* @return \Symfony\Component\Validator\ConstraintViolationListInterface
*/
private function _validatePersonAndAccompanyingPeriod(Person $person)
{
$errors = $this->validator
->validate($person, null, array('creation'));
->validate($person, null, ['creation']);
//validate accompanying periods
$periods = $person->getAccompanyingPeriods();
@@ -336,7 +321,7 @@ final class PersonController extends AbstractController
->validate($period);
//group errors :
foreach($period_errors as $error) {
foreach ($period_errors as $error) {
$errors->add($error);
}
}
@@ -344,39 +329,50 @@ final class PersonController extends AbstractController
return $errors;
}
/**
* easy getting a person by his id
* @return \Chill\PersonBundle\Entity\Person
*/
private function _getPerson($id)
private function isLastPostDataChanges(Form $form, Request $request, bool $replace = false): bool
{
$person = $this->personRepository->find($id);
/** @var SessionInterface $session */
$session = $this->get('session');
return $person;
if (!$session->has('last_person_data')) {
return true;
}
$newPost = $this->lastPostDataBuildHash($form, $request);
$isChanged = $session->get('last_person_data') !== $newPost;
if ($replace) {
$session->set('last_person_data', $newPost);
}
return $isChanged;
}
/**
* build the hash for posted data.
*
* @Route(
* "/{_locale}/person/household/{person_id}/history",
* name="chill_person_household_person_history",
* methods={"GET", "POST"}
* )
* @ParamConverter("person", options={"id" = "person_id"})
* For privacy reasons, the data are hashed using sha512
*/
public function householdHistoryByPerson(Request $request, Person $person): Response
private function lastPostDataBuildHash(Form $form, Request $request): string
{
$this->denyAccessUnlessGranted('CHILL_PERSON_SEE', $person,
"You are not allowed to see this person.");
$fields = [];
$ignoredFields = ['form_status', '_token'];
$event = new PrivacyEvent($person);
$this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event);
foreach ($request->request->all()[$form->getName()] as $field => $value) {
if (in_array($field, $ignoredFields)) {
continue;
}
$fields[$field] = is_array($value) ?
implode(',', $value) : $value;
}
ksort($fields);
return $this->render(
'@ChillPerson/Person/household_history.html.twig',
[
'person' => $person
]
);
return hash('sha512', implode('&', $fields));
}
private function lastPostDataReset(): void
{
$this->get('session')->set('last_person_data', '');
}
}

View File

@@ -1,29 +1,50 @@
<?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.
*/
namespace Chill\PersonBundle\Controller;
use Chill\ActivityBundle\Entity\Activity;
use Chill\DocStoreBundle\Entity\PersonDocument;
use Chill\EventBundle\Entity\Participation;
use Chill\PersonBundle\Actions\Remove\PersonMove;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Entity\PersonNotDuplicate;
use Chill\PersonBundle\Form\PersonConfimDuplicateType;
use Chill\PersonBundle\Form\PersonFindManuallyDuplicateType;
use Chill\PersonBundle\Privacy\PrivacyEvent;
use Chill\PersonBundle\Repository\PersonNotDuplicateRepository;
use Chill\PersonBundle\Repository\PersonRepository;
use Chill\PersonBundle\Search\SimilarPersonMatcher;
use Chill\TaskBundle\Entity\SingleTask;
use http\Exception\InvalidArgumentException;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Translation\TranslatorInterface;
use Chill\ActivityBundle\Entity\Activity;
use Chill\DocStoreBundle\Entity\PersonDocument;
use Chill\EventBundle\Entity\Participation;
use Chill\PersonBundle\Repository\PersonNotDuplicateRepository;
use Chill\TaskBundle\Entity\SingleTask;
class PersonDuplicateController extends Controller
{
/**
* @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
*/
private $eventDispatcher;
/**
* @var \Chill\PersonBundle\Actions\Remove\PersonMove
*/
private $personMove;
/**
* @var \Chill\PersonBundle\Repository\PersonRepository
*/
private $personRepository;
/**
* @var \Chill\PersonBundle\Search\SimilarPersonMatcher
*/
@@ -34,27 +55,12 @@ class PersonDuplicateController extends Controller
*/
private $translator;
/**
* @var \Chill\PersonBundle\Repository\PersonRepository
*/
private $personRepository;
/**
* @var \Chill\PersonBundle\Actions\Remove\PersonMove
*/
private $personMove;
/**
* @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
*/
private $eventDispatcher;
public function __construct(
SimilarPersonMatcher $similarPersonMatcher,
TranslatorInterface $translator,
PersonRepository $personRepository,
PersonMove $personMove,
EventDispatcherInterface $eventDispatcher
SimilarPersonMatcher $similarPersonMatcher,
TranslatorInterface $translator,
PersonRepository $personRepository,
PersonMove $personMove,
EventDispatcherInterface $eventDispatcher
) {
$this->similarPersonMatcher = $similarPersonMatcher;
$this->translator = $translator;
@@ -63,29 +69,6 @@ class PersonDuplicateController extends Controller
$this->eventDispatcher = $eventDispatcher;
}
public function viewAction($person_id, PersonNotDuplicateRepository $personNotDuplicateRepository)
{
$person = $this->_getPerson($person_id);
if ($person === null) {
throw $this->createNotFoundException("Person with id $person_id not"
. " found on this server");
}
$this->denyAccessUnlessGranted('CHILL_PERSON_DUPLICATE', $person,
"You are not allowed to see this person.");
$duplicatePersons = $this->similarPersonMatcher->
matchPerson($person, $personNotDuplicateRepository, 0.5, SimilarPersonMatcher::SIMILAR_SEARCH_ORDER_BY_ALPHABETICAL);
$notDuplicatePersons = $personNotDuplicateRepository->findNotDuplicatePerson($person);
return $this->render('ChillPersonBundle:PersonDuplicate:view.html.twig', [
'person' => $person,
'duplicatePersons' => $duplicatePersons,
'notDuplicatePersons' => $notDuplicatePersons,
]);
}
public function confirmAction($person1_id, $person2_id, Request $request)
{
if ($person1_id === $person2_id) {
@@ -98,17 +81,20 @@ class PersonDuplicateController extends Controller
$person1->counters = $this->_getCounters($person1_id);
$person2->counters = $this->_getCounters($person2_id);
if ($person1 === null) {
throw $this->createNotFoundException("Person with id $person1_id not"
. " found on this server");
if (null === $person1) {
throw $this->createNotFoundException("Person with id {$person1_id} not"
. ' found on this server');
}
$this->denyAccessUnlessGranted('CHILL_PERSON_DUPLICATE', $person1,
"You are not allowed to see this person.");
$this->denyAccessUnlessGranted(
'CHILL_PERSON_DUPLICATE',
$person1,
'You are not allowed to see this person.'
);
if ($person2 === null) {
throw $this->createNotFoundException("Person with id $person2_id not"
. " found on this server");
if (null === $person2) {
throw $this->createNotFoundException("Person with id {$person2_id} not"
. ' found on this server');
}
$form = $this->createForm(PersonConfimDuplicateType::class);
@@ -116,10 +102,10 @@ class PersonDuplicateController extends Controller
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$event = new PrivacyEvent($person1, array(
$event = new PrivacyEvent($person1, [
'element_class' => Person::class,
'action' => 'move'
));
'action' => 'move',
]);
$event->addPerson($person2);
$this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event);
@@ -128,7 +114,8 @@ class PersonDuplicateController extends Controller
$connection = $this->getDoctrine()->getConnection();
$connection->beginTransaction();
foreach($sqls as $sql) {
foreach ($sqls as $sql) {
$connection->executeQuery($sql);
}
$connection->commit();
@@ -143,15 +130,68 @@ class PersonDuplicateController extends Controller
]);
}
public function findManuallyDuplicateAction($person_id, Request $request)
{
$person = $this->_getPerson($person_id);
if (null === $person) {
throw $this->createNotFoundException("Person with id {$person_id} not"
. ' found on this server');
}
$this->denyAccessUnlessGranted(
'CHILL_PERSON_DUPLICATE',
$person,
'You are not allowed to see this person.'
);
$form = $this->createForm(PersonFindManuallyDuplicateType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$person2 = $form->get('person')->getData();
if (null === $person2) {
throw $this->createNotFoundException("Person with id {$person2->getId}() not"
. ' found on this server');
}
$direction = $form->get('direction')->getData();
if ('starting' === $direction) {
$params = [
'person1_id' => $person->getId(),
'person2_id' => $person2->getId(),
];
} else {
$params = [
'person1_id' => $person2->getId(),
'person2_id' => $person->getId(),
];
}
return $this->redirectToRoute('chill_person_duplicate_confirm', $params);
}
return $this->render('ChillPersonBundle:PersonDuplicate:find_manually.html.twig', [
'person' => $person,
'form' => $form->createView(),
]);
}
public function notDuplicateAction($person1_id, $person2_id)
{
[$person1, $person2] = $this->_getPersonsByPriority($person1_id, $person2_id);
$this->denyAccessUnlessGranted('CHILL_PERSON_DUPLICATE', $person1,
"You are not allowed to see this person.");
$this->denyAccessUnlessGranted(
'CHILL_PERSON_DUPLICATE',
$person1,
'You are not allowed to see this person.'
);
$personNotDuplicate = $this->getDoctrine()->getRepository(PersonNotDuplicate::class)
->findOneBy(['person1' => $person1, 'person2' => $person2]);
->findOneBy(['person1' => $person1, 'person2' => $person2]);
if (!$personNotDuplicate instanceof PersonNotDuplicate) {
$personNotDuplicate = new PersonNotDuplicate();
@@ -170,11 +210,14 @@ class PersonDuplicateController extends Controller
{
[$person1, $person2] = $this->_getPersonsByPriority($person1_id, $person2_id);
$this->denyAccessUnlessGranted('CHILL_PERSON_DUPLICATE', $person1,
"You are not allowed to see this person.");
$this->denyAccessUnlessGranted(
'CHILL_PERSON_DUPLICATE',
$person1,
'You are not allowed to see this person.'
);
$personNotDuplicate = $this->getDoctrine()->getRepository(PersonNotDuplicate::class)
->findOneBy(['person1' => $person1, 'person2' => $person2]);
->findOneBy(['person1' => $person1, 'person2' => $person2]);
if ($personNotDuplicate instanceof PersonNotDuplicate) {
$this->getDoctrine()->getManager()->remove($personNotDuplicate);
@@ -184,54 +227,56 @@ class PersonDuplicateController extends Controller
return $this->redirectToRoute('chill_person_duplicate_view', ['person_id' => $person1->getId()]);
}
public function findManuallyDuplicateAction($person_id, Request $request)
public function viewAction($person_id, PersonNotDuplicateRepository $personNotDuplicateRepository)
{
$person = $this->_getPerson($person_id);
if ($person === null) {
throw $this->createNotFoundException("Person with id $person_id not"
. " found on this server");
if (null === $person) {
throw $this->createNotFoundException("Person with id {$person_id} not"
. ' found on this server');
}
$this->denyAccessUnlessGranted('CHILL_PERSON_DUPLICATE', $person,
"You are not allowed to see this person.");
$this->denyAccessUnlessGranted(
'CHILL_PERSON_DUPLICATE',
$person,
'You are not allowed to see this person.'
);
$form = $this->createForm(PersonFindManuallyDuplicateType::class);
$duplicatePersons = $this->similarPersonMatcher->
matchPerson($person, $personNotDuplicateRepository, 0.5, SimilarPersonMatcher::SIMILAR_SEARCH_ORDER_BY_ALPHABETICAL);
$form->handleRequest($request);
$notDuplicatePersons = $personNotDuplicateRepository->findNotDuplicatePerson($person);
if ($form->isSubmitted() && $form->isValid()) {
$person2 = $form->get('person')->getData();
if ($person2 === null) {
throw $this->createNotFoundException("Person with id $person2->getId() not"
. " found on this server");
}
$direction = $form->get('direction')->getData();
if ($direction === 'starting') {
$params = [
'person1_id' => $person->getId(),
'person2_id' => $person2->getId(),
];
} else {
$params = [
'person1_id' => $person2->getId(),
'person2_id' => $person->getId(),
];
}
return $this->redirectToRoute('chill_person_duplicate_confirm', $params);
}
return $this->render('ChillPersonBundle:PersonDuplicate:find_manually.html.twig', [
return $this->render('ChillPersonBundle:PersonDuplicate:view.html.twig', [
'person' => $person,
'form' => $form->createView(),
'duplicatePersons' => $duplicatePersons,
'notDuplicatePersons' => $notDuplicatePersons,
]);
}
private function _getCounters($id): ?array
{
$em = $this->getDoctrine()->getManager();
$nb_activity = $em->getRepository(Activity::class)->findBy(['person' => $id]);
$nb_document = $em->getRepository(PersonDocument::class)->findBy(['person' => $id]);
$nb_event = $em->getRepository(Participation::class)->findBy(['person' => $id]);
$nb_task = $em->getRepository(SingleTask::class)->countByParameters(['person' => $id]);
$person = $em->getRepository(Person::class)->findOneBy(['id' => $id]);
return [
'nb_activity' => count($nb_activity),
'nb_document' => count($nb_document),
'nb_event' => count($nb_event),
'nb_task' => $nb_task,
'nb_addresses' => count($person->getAddresses()),
];
}
/**
* easy getting a person by his id
* easy getting a person by his id.
*
* @param mixed $id
*/
private function _getPerson($id): ?Person
{
@@ -252,35 +297,16 @@ class PersonDuplicateController extends Controller
$person2 = $this->_getPerson($person2_id);
}
if ($person1 === null) {
throw $this->createNotFoundException("Person with id $person1_id not"
. " found on this server");
if (null === $person1) {
throw $this->createNotFoundException("Person with id {$person1_id} not"
. ' found on this server');
}
if ($person2 === null) {
throw $this->createNotFoundException("Person with id $person2_id not"
. " found on this server");
if (null === $person2) {
throw $this->createNotFoundException("Person with id {$person2_id} not"
. ' found on this server');
}
return [$person1, $person2];
}
private function _getCounters($id): ?array
{
$em = $this->getDoctrine()->getManager();
$nb_activity = $em->getRepository(Activity::class)->findBy(['person'=>$id]);
$nb_document = $em->getRepository(PersonDocument::class)->findBy(['person'=>$id]);
$nb_event = $em->getRepository(Participation::class)->findBy(['person'=>$id]);
$nb_task = $em->getRepository(SingleTask::class)->countByParameters(['person'=>$id]);
$person = $em->getRepository(Person::class)->findOneBy(['id'=>$id]);
return [
'nb_activity' => count($nb_activity),
'nb_document' => count($nb_document),
'nb_event' => count($nb_event),
'nb_task' => $nb_task,
'nb_addresses' => count($person->getAddresses())
];
}
}

View File

@@ -1,4 +1,12 @@
<?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\PersonBundle\Controller;
@@ -6,15 +14,17 @@ namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\CRUD\Controller\ApiController;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Repository\Relationships\RelationshipRepository;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use function array_values;
class RelationshipApiController extends ApiController
{
private ValidatorInterface $validator;
private RelationshipRepository $repository;
private ValidatorInterface $validator;
public function __construct(ValidatorInterface $validator, RelationshipRepository $repository)
{
$this->validator = $validator;
@@ -22,13 +32,13 @@ class RelationshipApiController extends ApiController
}
/**
* @ParamConverter("person", options={"id" = "person_id"})
* @ParamConverter("person", options={"id": "person_id"})
*/
public function getRelationshipsByPerson(Person $person)
{
//TODO: add permissions? (voter?)
$relationships = $this->repository->findByPerson($person);
return $this->json(\array_values($relationships), Response::HTTP_OK, [], ['groups' => [ 'read']]);
return $this->json(array_values($relationships), Response::HTTP_OK, [], ['groups' => ['read']]);
}
}

View File

@@ -1,5 +1,12 @@
<?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.
*/
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\CRUD\Controller\ApiController;
@@ -36,7 +43,7 @@ class SocialIssueApiController extends ApiController
protected function onPostIndexBuildQuery(string $action, Request $request, string $_format, int $totalItems, PaginatorInterface $paginator, $query): ?Response
{
$query
->orderBy("GET_JSON_FIELD_BY_KEY(e.title, :locale)", 'ASC')
->orderBy('GET_JSON_FIELD_BY_KEY(e.title, :locale)', 'ASC')
->setParameter(':locale', $request->getLocale());
return null;

View File

@@ -1,21 +1,10 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2021, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Controller\SocialWork;
@@ -24,9 +13,7 @@ use Chill\MainBundle\CRUD\Controller\CRUDController;
/**
* Class AdminSocialIssueController
* Controller for social issues
*
* @package Chill\PersonBundle\Controller
* Controller for social issues.
*/
class AdminEvaluationController extends CRUDController
{

View File

@@ -1,21 +1,10 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2021, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Controller\SocialWork;
@@ -24,9 +13,7 @@ use Chill\MainBundle\CRUD\Controller\CRUDController;
/**
* Class AdminSocialIssueController
* Controller for social issues
*
* @package Chill\PersonBundle\Controller
* Controller for social issues.
*/
class AdminGoalController extends CRUDController
{

View File

@@ -1,21 +1,10 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2021, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Controller\SocialWork;
@@ -24,9 +13,7 @@ use Chill\MainBundle\CRUD\Controller\CRUDController;
/**
* Class AdminSocialIssueController
* Controller for social issues
*
* @package Chill\PersonBundle\Controller
* Controller for social issues.
*/
class AdminResultController extends CRUDController
{

View File

@@ -1,21 +1,10 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2021, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Controller\SocialWork;
@@ -24,9 +13,7 @@ use Chill\MainBundle\CRUD\Controller\CRUDController;
/**
* Class AdminSocialIssueController
* Controller for social issues
*
* @package Chill\PersonBundle\Controller
* Controller for social issues.
*/
class AdminSocialActionController extends CRUDController
{

View File

@@ -1,21 +1,10 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2021, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Controller\SocialWork;
@@ -24,9 +13,7 @@ use Chill\MainBundle\CRUD\Controller\CRUDController;
/**
* Class AdminSocialIssueController
* Controller for social issues
*
* @package Chill\PersonBundle\Controller
* Controller for social issues.
*/
class AdminSocialIssueController extends CRUDController
{

View File

@@ -1,22 +1,26 @@
<?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.
*/
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\Pagination\PaginatorFactory;
use Chill\MainBundle\Serializer\Model\Collection;
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
class SocialWorkEvaluationApiController extends AbstractController
{
private PaginatorFactory $paginatorFactory;
/**
* @param PaginatorFactory $paginatorFactory
*/
public function __construct(PaginatorFactory $paginatorFactory)
{
$this->paginatorFactory = $paginatorFactory;
@@ -26,21 +30,21 @@ class SocialWorkEvaluationApiController extends AbstractController
* @Route("/api/1.0/person/social-work/evaluation/by-social-action/{action_id}.json",
* name="chill_person_evaluation_index_by_social_action",
* requirements={
* "_format": "json"
* "_format": "json"
* }
* )
* @ParamConverter("action", options={"id": "action_id"})
* @param SocialAction $action
* @return Response
*/
public function listEvaluationBySocialAction(SocialAction $action): Response
{
$pagination = $this->paginatorFactory->create($action->getEvaluations()->count());
$evaluations = $action->getEvaluations()->slice($pagination->getCurrentPageFirstItemNumber(),
$pagination->getItemsPerPage());
$evaluations = $action->getEvaluations()->slice(
$pagination->getCurrentPageFirstItemNumber(),
$pagination->getItemsPerPage()
);
$collection = new Collection($evaluations, $pagination);
return $this->json($collection, Response::HTTP_OK, [], [ 'groups' => [ 'read' ]]);
return $this->json($collection, Response::HTTP_OK, [], ['groups' => ['read']]);
}
}

View File

@@ -1,13 +1,19 @@
<?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.
*/
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\CRUD\Controller\ApiController;
use Chill\MainBundle\Pagination\PaginatorFactory;
use Chill\MainBundle\Serializer\Model\Collection;
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
use Chill\PersonBundle\Entity\SocialWork\Goal;
use Chill\PersonBundle\Repository\SocialWork\GoalRepository;
use Chill\MainBundle\CRUD\Controller\ApiController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@@ -17,7 +23,6 @@ class SocialWorkGoalApiController extends ApiController
private PaginatorFactory $paginator;
public function __construct(GoalRepository $goalRepository, PaginatorFactory $paginator)
{
$this->goalRepository = $goalRepository;
@@ -28,13 +33,16 @@ class SocialWorkGoalApiController extends ApiController
{
$totalItems = $this->goalRepository->countBySocialActionWithDescendants($action);
$paginator = $this->getPaginatorFactory()->create($totalItems);
$entities = $this->goalRepository->findBySocialActionWithDescendants($action, ["id" => "ASC"],
$paginator->getItemsPerPage(), $paginator->getCurrentPageFirstItemNumber());
$entities = $this->goalRepository->findBySocialActionWithDescendants(
$action,
['id' => 'ASC'],
$paginator->getItemsPerPage(),
$paginator->getCurrentPageFirstItemNumber()
);
$model = new Collection($entities, $paginator);
return $this->json($model, Response::HTTP_OK, [], [ "groups" => [ "read" ]]);
return $this->json($model, Response::HTTP_OK, [], ['groups' => ['read']]);
}
}

View File

@@ -1,12 +1,19 @@
<?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.
*/
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\Serializer\Model\Collection;
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
use Chill\PersonBundle\Entity\SocialWork\Goal;
use Chill\PersonBundle\Repository\SocialWork\ResultRepository;
use Chill\MainBundle\CRUD\Controller\ApiController;
use Chill\MainBundle\Serializer\Model\Collection;
use Chill\PersonBundle\Entity\SocialWork\Goal;
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
use Chill\PersonBundle\Repository\SocialWork\ResultRepository;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@@ -19,29 +26,37 @@ class SocialWorkResultApiController extends ApiController
$this->resultRepository = $resultRepository;
}
public function listByGoal(Request $request, Goal $goal): Response
{
$totalItems = $this->resultRepository->countByGoal($goal);
$paginator = $this->getPaginatorFactory()->create($totalItems);
$entities = $this->resultRepository->findByGoal(
$goal,
['id' => 'ASC'],
$paginator->getItemsPerPage(),
$paginator->getCurrentPageFirstItemNumber()
);
$model = new Collection($entities, $paginator);
return $this->json($model, Response::HTTP_OK, [], ['groups' => ['read']]);
}
public function listBySocialAction(Request $request, SocialAction $action): Response
{
$totalItems = $this->resultRepository->countBySocialActionWithDescendants($action);
$paginator = $this->getPaginatorFactory()->create($totalItems);
$entities = $this->resultRepository->findBySocialActionWithDescendants($action, ["id" => "ASC"],
$paginator->getItemsPerPage(), $paginator->getCurrentPageFirstItemNumber());
$entities = $this->resultRepository->findBySocialActionWithDescendants(
$action,
['id' => 'ASC'],
$paginator->getItemsPerPage(),
$paginator->getCurrentPageFirstItemNumber()
);
$model = new Collection($entities, $paginator);
return $this->json($model, Response::HTTP_OK, [], [ "groups" => [ "read" ]]);
}
public function listByGoal(Request $request, Goal $goal): Response
{
$totalItems = $this->resultRepository->countByGoal($goal);
$paginator = $this->getPaginatorFactory()->create($totalItems);
$entities = $this->resultRepository->findByGoal($goal, ["id" => "ASC"],
$paginator->getItemsPerPage(), $paginator->getCurrentPageFirstItemNumber());
$model = new Collection($entities, $paginator);
return $this->json($model, Response::HTTP_OK, [], [ "groups" => [ "read" ]]);
return $this->json($model, Response::HTTP_OK, [], ['groups' => ['read']]);
}
}

View File

@@ -1,36 +1,40 @@
<?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.
*/
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\Serializer\Model\Collection;
use Chill\MainBundle\Pagination\PaginatorFactory;
use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository;
use Chill\MainBundle\CRUD\Controller\ApiController;
use Symfony\Component\HttpFoundation\Request;
use Chill\MainBundle\Pagination\PaginatorFactory;
use Chill\MainBundle\Serializer\Model\Collection;
use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
class SocialWorkSocialActionApiController extends ApiController
{
private SocialIssueRepository $socialIssueRepository;
private PaginatorFactory $paginator;
/**
* @param SocialIssueRepository $socialIssueRepository
*/
private SocialIssueRepository $socialIssueRepository;
public function __construct(SocialIssueRepository $socialIssueRepository, PaginatorFactory $paginator)
{
$this->socialIssueRepository = $socialIssueRepository;
$this->paginator = $paginator;
}
public function listBySocialIssueApi($id, Request $request)
{
$socialIssue = $this->socialIssueRepository
->find($id);
if (NULL === $socialIssue) {
throw $this->createNotFoundException("socialIssue not found");
if (null === $socialIssue) {
throw $this->createNotFoundException('socialIssue not found');
}
$socialActions = $socialIssue->getRecursiveSocialActions();
@@ -39,9 +43,7 @@ class SocialWorkSocialActionApiController extends ApiController
$pagination->setItemsPerPage(count($socialActions));
$collection = new Collection($socialActions, $pagination);
return $this->json($collection, JsonResponse::HTTP_OK, [], [ "groups" => [ "read" ]]);
}
return $this->json($collection, JsonResponse::HTTP_OK, [], ['groups' => ['read']]);
}
}

View File

@@ -1,27 +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\PersonBundle\Controller;
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
use Chill\MainBundle\Pagination\PaginatorFactory;
use Chill\MainBundle\Timeline\TimelineBuilder;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Privacy\PrivacyEvent;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Chill\MainBundle\Timeline\TimelineBuilder;
use Chill\MainBundle\Pagination\PaginatorFactory;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
class TimelinePersonController extends AbstractController
{
protected EventDispatcherInterface $eventDispatcher;
protected TimelineBuilder $timelineBuilder;
protected PaginatorFactory $paginatorFactory;
protected TimelineBuilder $timelineBuilder;
public function __construct(
EventDispatcherInterface $eventDispatcher,
TimelineBuilder $timelineBuilder,
@@ -35,37 +41,38 @@ class TimelinePersonController extends AbstractController
public function personAction(Request $request, $person_id)
{
$person = $this->getDoctrine()
->getRepository(Person::class)
->find($person_id);
->getRepository(Person::class)
->find($person_id);
if ($person === NULL) {
if (null === $person) {
throw $this->createNotFoundException();
}
$this->denyAccessUnlessGranted(PersonVoter::SEE, $person);
$nbItems = $this->timelineBuilder->countItems('person',
[ 'person' => $person ]
);
$nbItems = $this->timelineBuilder->countItems(
'person',
['person' => $person]
);
$paginator = $this->paginatorFactory->create($nbItems);
$event = new PrivacyEvent($person, array('action' => 'timeline'));
$event = new PrivacyEvent($person, ['action' => 'timeline']);
$this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event);
return $this->render('ChillPersonBundle:Timeline:index.html.twig', array
(
return $this->render(
'ChillPersonBundle:Timeline:index.html.twig',
[
'timeline' => $this->timelineBuilder->getTimelineHTML(
'person',
array('person' => $person),
['person' => $person],
$paginator->getCurrentPage()->getFirstItemNumber(),
$paginator->getItemsPerPage()
),
),
'person' => $person,
'nb_items' => $nbItems,
'paginator' => $paginator
)
'paginator' => $paginator,
]
);
}
}

View File

@@ -1,25 +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.
*/
namespace Chill\PersonBundle\DataFixtures\Helper;
use Chill\PersonBundle\Entity\Person;
use Doctrine\ORM\EntityManagerInterface;
use function array_pop;
use function random_int;
trait PersonRandomHelper
{
private array $randPersons = [];
private ?int $countPersons = null;
private array $randPersons = [];
protected function getRandomPerson(EntityManagerInterface $em): Person
{
$fetchBy = 5;
if (null === $this->countPersons) {
$qb = $em->createQueryBuilder();
$this->countPersons = $qb->select('count(p)')
->from(Person::class, 'p')
->getQuery()
->getSingleScalarResult()
;
->getSingleScalarResult();
}
if ([] === $this->randPersons) {
@@ -28,13 +38,11 @@ trait PersonRandomHelper
->select('p')
->from(Person::class, 'p')
->getQuery()
->setFirstResult(\random_int(0, $this->countPersons - $fetchBy))
->setFirstResult(random_int(0, $this->countPersons - $fetchBy))
->setMaxResults($fetchBy)
->getResult()
;
->getResult();
}
return \array_pop($this->randPersons);
return array_pop($this->randPersons);
}
}

View File

@@ -1,9 +1,17 @@
<?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.
*/
namespace Chill\PersonBundle\DataFixtures\Helper;
use Chill\PersonBundle\Entity\Person;
use Doctrine\ORM\EntityManagerInterface;
use function random_int;
trait RandomPersonHelperTrait
{
@@ -13,23 +21,20 @@ trait RandomPersonHelperTrait
{
$qb = $em->createQueryBuilder();
$qb
->from(Person::class, 'p')
;
->from(Person::class, 'p');
if (null === $this->nbOfPersons) {
$this->nbOfPersons = $qb
->select('COUNT(p)')
->getQuery()
->getSingleScalarResult()
;
->getSingleScalarResult();
}
return $qb
->select('p')
->setMaxResults(1)
->setFirstResult(\random_int(0, $this->nbOfPersons))
->setFirstResult(random_int(0, $this->nbOfPersons))
->getQuery()
->getSingleResult()
;
->getSingleResult();
}
}

View File

@@ -1,89 +1,68 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\DataFixtures\ORM;
use Chill\PersonBundle\Entity\AccompanyingPeriod\ClosingMotive;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Persistence\ObjectManager;
use Chill\PersonBundle\Entity\AccompanyingPeriod\ClosingMotive;
/**
* Load closing motives into database
*
* @author Julien Fastré <julien arobase fastre point info>
* Load closing motives into database.
*/
class LoadAccompanyingPeriodClosingMotive extends AbstractFixture
implements OrderedFixtureInterface
class LoadAccompanyingPeriodClosingMotive extends AbstractFixture implements OrderedFixtureInterface
{
public function getOrder() {
public static $closingMotives = [
'nothing_to_do' => [
'name' => [
'fr' => 'Plus rien à faire',
'en' => 'Nothing to do',
'nl' => 'nieks meer te doen',
],
],
'did_not_come_back' => [
'name' => [
'fr' => "N'est plus revenu",
'en' => "Did'nt come back",
'nl' => 'Niet teruggekomen',
],
],
'no_more_money' => [
'active' => false,
'name' => [
'fr' => "Plus d'argent",
'en' => 'No more money',
'nl' => 'Geen geld',
],
],
];
public static $references = [];
public function getOrder()
{
return 9500;
}
public static $closingMotives = array(
'nothing_to_do' => array(
'name' => array(
'fr' => 'Plus rien à faire',
'en' => 'Nothing to do',
'nl' => 'nieks meer te doen'
)
),
'did_not_come_back' => array(
'name' => array(
'fr' => "N'est plus revenu",
'en' => "Did'nt come back",
'nl' => "Niet teruggekomen"
)
),
'no_more_money' => array(
'active' => false,
'name' => array(
'fr' => "Plus d'argent",
'en' => "No more money",
'nl' => "Geen geld"
)
)
);
public static $references = array();
public function load(ObjectManager $manager)
public function load(ObjectManager $manager)
{
foreach (static::$closingMotives as $ref => $new) {
$motive = new ClosingMotive();
$motive->setName($new['name'])
->setActive((isset($new['active']) ? $new['active'] : true))
;
->setActive(($new['active'] ?? true));
$manager->persist($motive);
$this->addReference($ref, $motive);
echo "Adding ClosingMotive $ref\n";
echo "Adding ClosingMotive {$ref}\n";
}
$manager->flush();
}
}

View File

@@ -1,14 +1,21 @@
<?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.
*/
namespace Chill\PersonBundle\DataFixtures\ORM;
use Chill\MainBundle\DataFixtures\ORM\LoadAbstractNotificationsTrait;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\MainBundle\DataFixtures\ORM\LoadAbstractNotificationsTrait;
/**
* Load notififications into database
* Load notififications into database.
*/
class LoadAccompanyingPeriodNotifications extends AbstractFixture implements DependentFixtureInterface
{
@@ -24,20 +31,20 @@ class LoadAccompanyingPeriodNotifications extends AbstractFixture implements Dep
'center a_social',
'center a_administrative',
'center a_direction',
'multi_center'
'multi_center',
],
]
],
];
protected function getEntityRef()
{
return null;
}
public function getDependencies()
{
return [
LoadPeople::class,
];
}
protected function getEntityRef()
{
return null;
}
}

View File

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

View File

@@ -1,5 +1,12 @@
<?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.
*/
namespace Chill\PersonBundle\DataFixtures\ORM;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
@@ -8,24 +15,22 @@ use Chill\PersonBundle\Entity\SocialWork\SocialAction;
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
use Chill\PersonBundle\Repository\AccompanyingPeriodRepository;
use Chill\PersonBundle\Repository\SocialWork\EvaluationRepository;
use Chill\PersonBundle\Repository\SocialWork\SocialActionRepository;
use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository;
use DateTimeImmutable;
use Doctrine\Persistence\ObjectManager;
use Chill\PersonBundle\DataFixtures\ORM\LoadPeople;
use function array_pop;
use function array_rand;
class LoadAccompanyingPeriodWork extends \Doctrine\Bundle\FixturesBundle\Fixture implements \Doctrine\Common\DataFixtures\DependentFixtureInterface
{
private AccompanyingPeriodRepository $periodRepository;
private EvaluationRepository $evaluationRepository;
/**
* @var Evaluation[]|array
* @var array|Evaluation[]
*/
private array $cacheEvaluations = [];
/**
* @param AccompanyingPeriodRepository $periodRepository
*/
private EvaluationRepository $evaluationRepository;
private AccompanyingPeriodRepository $periodRepository;
public function __construct(
AccompanyingPeriodRepository $periodRepository,
EvaluationRepository $evaluationRepository
@@ -34,16 +39,83 @@ class LoadAccompanyingPeriodWork extends \Doctrine\Bundle\FixturesBundle\Fixture
$this->evaluationRepository = $evaluationRepository;
}
/**
* @inheritDoc
*/
public function getDependencies()
{
return [
LoadPeople::class
LoadPeople::class,
];
}
public function load(ObjectManager $manager)
{
// load all the period which are confirmed
$periods = $this->periodRepository
->findBy(['step' => AccompanyingPeriod::STEP_CONFIRMED]);
$i = 0;
while (null !== $period = array_pop($periods)) {
/** @var AccompanyingPeriod $period */
++$i;
if (0 === $i % 15) {
$manager->flush();
}
if (0 === $period->getSocialIssues()->count()) {
continue;
}
$work = new AccompanyingPeriod\AccompanyingPeriodWork();
$action = $this->getRandomAction($period->getSocialIssues()->first());
if (null !== $action) {
$work
->setAccompanyingPeriod($period)
->setSocialAction($action)
->setStartDate(new DateTimeImmutable('today'))
->addPerson($period->getPersons()->first())
->setCreatedAt(new DateTimeImmutable())
->setCreatedBy($this->getReference('center a_social'))
->setUpdatedAt(new DateTimeImmutable())
->setUpdatedBy($this->getReference('center a_social'));
$manager->persist($work);
if ($action->getEvaluations()->count() > 0) {
$ev = $action->getEvaluations()->first();
$evaluation = new AccompanyingPeriod\AccompanyingPeriodWorkEvaluation();
$evaluation->setAccompanyingPeriodWork($work)
->setEvaluation($ev);
$manager->persist($evaluation);
}
}
// 1 of 10, force an evaluation
if (0 === $i % 10) {
$evaluation = $this->getRandomEvaluation();
$action = $evaluation->getSocialAction();
$issue = $action->getIssue();
$period->addSocialIssue($issue);
$work
->setAccompanyingPeriod($period)
->setSocialAction($action)
->setStartDate(new DateTimeImmutable('today'))
->addPerson($period->getPersons()->first())
->setCreatedAt(new DateTimeImmutable())
->setCreatedBy($this->getReference('center a_social'))
->setUpdatedAt(new DateTimeImmutable())
->setUpdatedBy($this->getReference('center a_social'));
$manager->persist($work);
$ev = new AccompanyingPeriod\AccompanyingPeriodWorkEvaluation();
$ev->setAccompanyingPeriodWork($work)
->setEvaluation($evaluation);
$manager->persist($ev);
}
}
$manager->flush();
}
private function getRandomAction(SocialIssue $socialIssue): ?SocialAction
{
$actions = $socialIssue->getRecursiveSocialActions()->toArray();
@@ -52,89 +124,16 @@ class LoadAccompanyingPeriodWork extends \Doctrine\Bundle\FixturesBundle\Fixture
return null;
}
return $actions[\array_rand($actions)];
return $actions[array_rand($actions)];
}
private function getRandomEvaluation(): Evaluation
{
if (0 === count($this->cacheEvaluations)) {
$this->cacheEvaluations = $this->evaluationRepository
->findAll();
}
return $this->cacheEvaluations[\array_rand($this->cacheEvaluations)];
}
/**
* @inheritDoc
*/
public function load(ObjectManager $manager)
{
// load all the period which are confirmed
$periods = $this->periodRepository
->findBy(['step' => AccompanyingPeriod::STEP_CONFIRMED])
;
$i = 0;
while (null !== $period = \array_pop($periods)) {
/** @var AccompanyingPeriod $period */
$i++;
if (0 === $i % 15) {
$manager->flush();
}
if (0 === $period->getSocialIssues()->count()) {
continue;
}
$work = new AccompanyingPeriod\AccompanyingPeriodWork();
$action = $this->getRandomAction($period->getSocialIssues()->first());
if (null !== $action) {
$work
->setAccompanyingPeriod($period)
->setSocialAction($action)
->setStartDate(new \DateTimeImmutable('today'))
->addPerson($period->getPersons()->first())
->setCreatedAt(new \DateTimeImmutable())
->setCreatedBy($this->getReference('center a_social'))
->setUpdatedAt(new \DateTimeImmutable())
->setUpdatedBy($this->getReference('center a_social'));
$manager->persist($work);
if ($action->getEvaluations()->count() > 0) {
$ev = $action->getEvaluations()->first();
$evaluation = new AccompanyingPeriod\AccompanyingPeriodWorkEvaluation();
$evaluation->setAccompanyingPeriodWork($work)
->setEvaluation($ev);
$manager->persist($evaluation);
}
}
// 1 of 10, force an evaluation
if (0 === $i % 10) {
$evaluation = $this->getRandomEvaluation();
$action = $evaluation->getSocialAction();
$issue = $action->getIssue();
$period->addSocialIssue($issue);
$work
->setAccompanyingPeriod($period)
->setSocialAction($action)
->setStartDate(new \DateTimeImmutable('today'))
->addPerson($period->getPersons()->first())
->setCreatedAt(new \DateTimeImmutable())
->setCreatedBy($this->getReference('center a_social'))
->setUpdatedAt(new \DateTimeImmutable())
->setUpdatedBy($this->getReference('center a_social'))
;
$manager->persist($work);
$ev = new AccompanyingPeriod\AccompanyingPeriodWorkEvaluation();
$ev->setAccompanyingPeriodWork($work)
->setEvaluation($evaluation);
$manager->persist($ev);
}
if (0 === count($this->cacheEvaluations)) {
$this->cacheEvaluations = $this->evaluationRepository
->findAll();
}
$manager->flush();
return $this->cacheEvaluations[array_rand($this->cacheEvaluations)];
}
}

View File

@@ -1,78 +1,61 @@
<?php
/*
* Copyright (C) 2017 Champs Libres Cooperative <info@champs-libres.coop>
/**
* Chill is a software for social workers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\DataFixtures\ORM;
use Chill\CustomFieldsBundle\CustomFields\CustomFieldChoice;
use Chill\CustomFieldsBundle\CustomFields\CustomFieldText;
use Chill\CustomFieldsBundle\CustomFields\CustomFieldTitle;
use Chill\CustomFieldsBundle\Entity\CustomField;
use Chill\CustomFieldsBundle\Entity\CustomFieldsDefaultGroup;
use Chill\CustomFieldsBundle\Entity\CustomFieldsGroup;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\PersonBundle\Entity\Person;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Persistence\ObjectManager;
use RuntimeException;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Chill\CustomFieldsBundle\Entity\CustomField;
use Chill\CustomFieldsBundle\Entity\CustomFieldsGroup;
use Chill\CustomFieldsBundle\CustomFields\CustomFieldTitle;
use Chill\CustomFieldsBundle\CustomFields\CustomFieldText;
use Chill\CustomFieldsBundle\CustomFields\CustomFieldChoice;
use Chill\CustomFieldsBundle\Entity\CustomFieldsDefaultGroup;
use Chill\PersonBundle\Entity\Person;
use Symfony\Contracts\Translation\TranslatorInterface;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class LoadCustomFields extends AbstractFixture implements OrderedFixtureInterface,
class LoadCustomFields extends AbstractFixture implements
OrderedFixtureInterface,
ContainerAwareInterface
{
/**
*
* @var ContainerInterface
*/
private $container;
/**
*
* @var CustomField
*/
private $customFieldText;
/**
*
* @var CustomField
*/
private $customFieldChoice;
/**
* @var CustomField
*/
private $customFieldText;
/**
* @var TranslatableStringHelper
*/
private $translatableStringHelper;
/**
* @var TranslatorInterface
*/
private $translator;
/**
* LoadCustomFields constructor.
*
* @param TranslatableStringHelper $translatableStringHelper
* @param TranslatorInterface $translator
*/
public function __construct(
TranslatableStringHelper $translatableStringHelper,
@@ -81,21 +64,12 @@ class LoadCustomFields extends AbstractFixture implements OrderedFixtureInterfac
$this->translatableStringHelper = $translatableStringHelper;
$this->translator = $translator;
}
//put your code here
public function getOrder()
{
return 10003;
}
public function setContainer(ContainerInterface $container = null)
{
if ($container === null) {
throw new \RuntimeException("The given container should not be null");
}
$this->container = $container;
}
public function load(ObjectManager $manager)
{
@@ -103,45 +77,16 @@ class LoadCustomFields extends AbstractFixture implements OrderedFixtureInterfac
$this->loadData($manager);
$manager->flush();
}
private function loadData(ObjectManager $manager)
public function setContainer(?ContainerInterface $container = null)
{
$personIds = $this->container->get('doctrine.orm.entity_manager')
->createQuery("SELECT person.id FROM ChillPersonBundle:Person person")
->getScalarResult();
// get possible values for cfGroup
$choices = array_map(
function($a) { return $a["slug"]; },
$this->customFieldChoice->getOptions()["choices"]
);
// create faker
$faker = \Faker\Factory::create('fr_FR');
// select a set of people and add data
foreach ($personIds as $id) {
// add info on 1 person on 2
if (rand(0,1) === 1) {
/* @var $person Person */
$person = $manager->getRepository(Person::class)->find($id);
$person->setCFData(array(
"remarques" => $this->createCustomFieldText()
->serialize($faker->text(rand(150, 250)), $this->customFieldText),
"document-d-identite" => $this->createCustomFieldChoice()
->serialize(array($choices[array_rand($choices)]), $this->customFieldChoice)
));
}
if (null === $container) {
throw new RuntimeException('The given container should not be null');
}
$this->container = $container;
}
private function createCustomFieldText()
{
return new CustomFieldText(
$this->container->get('request_stack'),
$this->container->get('templating'),
$this->translatableStringHelper
);
}
private function createCustomFieldChoice()
{
return new CustomFieldChoice(
@@ -150,80 +95,113 @@ class LoadCustomFields extends AbstractFixture implements OrderedFixtureInterfac
$this->translatableStringHelper
);
}
private function createCustomFieldText()
{
return new CustomFieldText(
$this->container->get('request_stack'),
$this->container->get('templating'),
$this->translatableStringHelper
);
}
private function loadData(ObjectManager $manager)
{
$personIds = $this->container->get('doctrine.orm.entity_manager')
->createQuery('SELECT person.id FROM ChillPersonBundle:Person person')
->getScalarResult();
// get possible values for cfGroup
$choices = array_map(
function ($a) { return $a['slug']; },
$this->customFieldChoice->getOptions()['choices']
);
// create faker
$faker = \Faker\Factory::create('fr_FR');
// select a set of people and add data
foreach ($personIds as $id) {
// add info on 1 person on 2
if (rand(0, 1) === 1) {
/* @var $person Person */
$person = $manager->getRepository(Person::class)->find($id);
$person->setCFData([
'remarques' => $this->createCustomFieldText()
->serialize($faker->text(rand(150, 250)), $this->customFieldText),
'document-d-identite' => $this->createCustomFieldChoice()
->serialize([$choices[array_rand($choices)]], $this->customFieldChoice),
]);
}
}
}
private function loadFields(ObjectManager $manager)
{
$cfGroup = (new CustomFieldsGroup())
->setEntity(Person::class)
->setName(array("fr" => "Données"))
;
->setName(['fr' => 'Données']);
$manager->persist($cfGroup);
// make this group default for Person::class
$manager->persist(
(new CustomFieldsDefaultGroup())
->setCustomFieldsGroup($cfGroup)
->setEntity(Person::class)
);
);
// create title field
$customField0 = (new CustomField())
->setActive(true)
->setName(array("fr" => "Données personnalisées"))
->setSlug("personal-data")
->setName(['fr' => 'Données personnalisées'])
->setSlug('personal-data')
->setOrdering(10)
->setType('title')
->setOptions(array(CustomFieldTitle::TYPE => CustomFieldTitle::TYPE_TITLE))
->setCustomFieldsGroup($cfGroup)
;
->setOptions([CustomFieldTitle::TYPE => CustomFieldTitle::TYPE_TITLE])
->setCustomFieldsGroup($cfGroup);
$manager->persist($customField0);
// create text field
$this->customFieldText = (new CustomField())
->setActive(true)
->setName(array("fr" => "Remarques"))
->setSlug("remarques")
->setName(['fr' => 'Remarques'])
->setSlug('remarques')
->setOrdering(20)
->setType('text')
->setOptions(array('maxLength' => 5000))
->setCustomFieldsGroup($cfGroup)
;
->setOptions(['maxLength' => 5000])
->setCustomFieldsGroup($cfGroup);
$manager->persist($this->customFieldText);
// create choice field
$this->customFieldChoice = (new CustomField())
->setActive(true)
->setName(array("fr" => "Document d'identité"))
->setSlug("document-d-identite")
->setName(['fr' => "Document d'identité"])
->setSlug('document-d-identite')
->setOrdering(30)
->setType('choice')
->setCustomFieldsGroup($cfGroup)
->setOptions(array(
"multiple" => true,
"other" => false,
"expanded" => true,
"active" => true,
"slug" => "document-d-identite",
"choices" => array(
array(
"name" => array("fr" => "Carte d'identité"),
"active" => true,
"slug" => "carte-d-identite"
),
array(
"name" => array("fr" => "Passeport"),
"active" => true,
"slug" => "passeport"
),
array(
"name" => array("fr" => "Titre de séjour"),
"active" => true,
"slug" => "passeport"
)
)
))
;
->setOptions([
'multiple' => true,
'other' => false,
'expanded' => true,
'active' => true,
'slug' => 'document-d-identite',
'choices' => [
[
'name' => ['fr' => "Carte d'identité"],
'active' => true,
'slug' => 'carte-d-identite',
],
[
'name' => ['fr' => 'Passeport'],
'active' => true,
'slug' => 'passeport',
],
[
'name' => ['fr' => 'Titre de séjour'],
'active' => true,
'slug' => 'passeport',
],
],
]);
$manager->persist($this->customFieldChoice);
}
}

View File

@@ -1,31 +1,45 @@
<?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\PersonBundle\DataFixtures\ORM;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Entity\Household\Household;
use Chill\MainBundle\Entity\PostalCode;
use Chill\MainBundle\DataFixtures\ORM\LoadPostalCodes;
use Chill\MainBundle\Entity\Address;
use Chill\MainBundle\Entity\PostalCode;
use Chill\PersonBundle\Entity\Household\Household;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Household\MembersEditorFactory;
use DateInterval;
use DateTime;
use DateTimeImmutable;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Persistence\ObjectManager;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
use Nelmio\Alice\Loader\NativeLoader;
use Chill\MainBundle\DataFixtures\ORM\LoadPostalCodes;
use function array_pop;
use function array_rand;
use function random_int;
use function shuffle;
class LoadHousehold extends Fixture implements DependentFixtureInterface
{
private const NUMBER_OF_HOUSEHOLD = 10;
private MembersEditorFactory $editorFactory;
private EntityManagerInterface $em;
private NativeLoader $loader;
private CONST NUMBER_OF_HOUSEHOLD = 10;
private array $personIds;
public function __construct(MembersEditorFactory $editorFactory, EntityManagerInterface $em)
@@ -35,6 +49,14 @@ class LoadHousehold extends Fixture implements DependentFixtureInterface
$this->loader = new NativeLoader();
}
public function getDependencies()
{
return [
LoadPeople::class,
LoadHouseholdPosition::class,
];
}
public function load(ObjectManager $manager)
{
// generate two times the participation. This will lead to
@@ -45,87 +67,44 @@ class LoadHousehold extends Fixture implements DependentFixtureInterface
$this->generateHousehold(
$manager,
\DateTimeImmutable::createFromFormat('Y-m-d', '2010-01-01')
DateTimeImmutable::createFromFormat('Y-m-d', '2010-01-01')
);
$this->preparePersonIds();
$this->generateHousehold(
$manager,
\DateTimeImmutable::createFromFormat('Y-m-d', '2015-01-01')
DateTimeImmutable::createFromFormat('Y-m-d', '2015-01-01')
);
$manager->flush();
}
private function generateHousehold(ObjectManager $manager, \DateTimeImmutable $startDate)
private function addAddressToHousehold(Household $household, DateTimeImmutable $date, ObjectManager $manager)
{
for ($i=0; $i < self::NUMBER_OF_HOUSEHOLD; $i++) {
$household = new Household();
$manager->persist($household);
$this->addAddressToHousehold($household, clone $startDate, $manager);
$movement = $this->editorFactory->createEditor($household);
// load adults
$k = 0;
foreach ($this->getRandomPersons(1, 3) as $person) {
$date = $startDate->add(new \DateInterval('P'.\random_int(1, 200).'W'));
$position = $this->getReference(LoadHouseholdPosition::ADULT);
$movement->addMovement($date, $person, $position, $k === 0, "self generated");
$k++;
}
// load children
foreach ($this->getRandomPersons(0, 3) as $person) {
$date = $startDate->add(new \DateInterval('P'.\random_int(1, 200).'W'));
$position = $this->getReference(LoadHouseholdPosition::CHILD);
$movement->addMovement($date, $person, $position, $k === 0, "self generated");
$k++;
}
// load children out
foreach ($this->getRandomPersons(0, 2) as $person) {
$date = $startDate->add(new \DateInterval('P'.\random_int(1, 200).'W'));
$position = $this->getReference(LoadHouseholdPosition::CHILD_OUT);
$movement->addMovement($date, $person, $position, $k === 0, "self generated");
$k++;
}
foreach ($movement->getPersistable() as $obj) {
$manager->persist($obj);
}
}
}
private function addAddressToHousehold(Household $household, \DateTimeImmutable $date, ObjectManager $manager)
{
if (\random_int(0, 10) > 8) {
if (random_int(0, 10) > 8) {
// 20% of household without address
return;
}
$nb = \random_int(1, 6);
$nb = random_int(1, 6);
$i = 0;
while ($i < $nb) {
$address = $this->createAddress();
$address->setValidFrom(\DateTime::createFromImmutable($date));
$address->setValidFrom(DateTime::createFromImmutable($date));
if (\random_int(0, 20) < 1) {
$date = $date->add(new \DateInterval('P'.\random_int(8, 52).'W'));
$address->setValidTo(\DateTime::createFromImmutable($date));
if (random_int(0, 20) < 1) {
$date = $date->add(new DateInterval('P' . random_int(8, 52) . 'W'));
$address->setValidTo(DateTime::createFromImmutable($date));
}
$household->addAddress($address);
$manager->persist($address);
$date = $date->add(new \DateInterval('P'.\random_int(8, 52).'W'));
$i++;
$date = $date->add(new DateInterval('P' . random_int(8, 52) . 'W'));
++$i;
}
}
@@ -136,54 +115,92 @@ class LoadHousehold extends Fixture implements DependentFixtureInterface
'address1' => [
'street' => '<fr_FR:streetName()>',
'streetNumber' => '<fr_FR:buildingNumber()>',
'postCode' => $this->getPostalCode()
]
]
'postCode' => $this->getPostalCode(),
],
],
]);
return $objectSet->getObjects()['address1'];
}
private function getPostalCode(): PostalCode
private function generateHousehold(ObjectManager $manager, DateTimeImmutable $startDate)
{
$ref = LoadPostalCodes::$refs[\array_rand(LoadPostalCodes::$refs)];
for ($i = 0; self::NUMBER_OF_HOUSEHOLD > $i; ++$i) {
$household = new Household();
$manager->persist($household);
return $this->getReference($ref);
$this->addAddressToHousehold($household, clone $startDate, $manager);
$movement = $this->editorFactory->createEditor($household);
// load adults
$k = 0;
foreach ($this->getRandomPersons(1, 3) as $person) {
$date = $startDate->add(new DateInterval('P' . random_int(1, 200) . 'W'));
$position = $this->getReference(LoadHouseholdPosition::ADULT);
$movement->addMovement($date, $person, $position, 0 === $k, 'self generated');
++$k;
}
// load children
foreach ($this->getRandomPersons(0, 3) as $person) {
$date = $startDate->add(new DateInterval('P' . random_int(1, 200) . 'W'));
$position = $this->getReference(LoadHouseholdPosition::CHILD);
$movement->addMovement($date, $person, $position, 0 === $k, 'self generated');
++$k;
}
// load children out
foreach ($this->getRandomPersons(0, 2) as $person) {
$date = $startDate->add(new DateInterval('P' . random_int(1, 200) . 'W'));
$position = $this->getReference(LoadHouseholdPosition::CHILD_OUT);
$movement->addMovement($date, $person, $position, 0 === $k, 'self generated');
++$k;
}
foreach ($movement->getPersistable() as $obj) {
$manager->persist($obj);
}
}
}
private function preparePersonIds()
private function getPostalCode(): PostalCode
{
// @TODO: Remove this and make this service stateless
$this->personIds = $this->em
->createQuery('SELECT p.id FROM '.Person::class.' p '.
'JOIN p.center c '.
'WHERE c.name = :center '
)
->setParameter('center', 'Center A')
->getScalarResult();
$ref = LoadPostalCodes::$refs[array_rand(LoadPostalCodes::$refs)];
\shuffle($this->personIds);
return $this->getReference($ref);
}
private function getRandomPersons(int $min, int $max): array
{
$persons = [];
$nb = \random_int($min, $max);
$nb = random_int($min, $max);
for ($i=0; $i < $nb; $i++) {
$personId = \array_pop($this->personIds)['id'];
for ($i = 0; $i < $nb; ++$i) {
$personId = array_pop($this->personIds)['id'];
$persons[] = $this->em->getRepository(Person::class)->find($personId);
}
return $persons;
}
public function getDependencies()
private function preparePersonIds()
{
return [
LoadPeople::class,
LoadHouseholdPosition::class
];
// @TODO: Remove this and make this service stateless
$this->personIds = $this->em
->createQuery(
'SELECT p.id FROM ' . Person::class . ' p ' .
'JOIN p.center c ' .
'WHERE c.name = :center '
)
->setParameter('center', 'Center A')
->getScalarResult();
shuffle($this->personIds);
}
}

View File

@@ -1,5 +1,12 @@
<?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.
*/
namespace Chill\PersonBundle\DataFixtures\ORM;
use Chill\PersonBundle\Entity\Household\Position;
@@ -8,26 +15,27 @@ use Doctrine\Persistence\ObjectManager;
class LoadHouseholdPosition extends Fixture
{
const POSITIONS_DATA = [
["Adulte", true, true, 1.0, self::ADULT ],
["Enfant", true, false, 2.0, self::CHILD ],
["Enfant hors ménage", false, false, 3.0, self::CHILD_OUT ]
];
public const ADULT = 'position_adulte';
const ADULT = "position_adulte";
const CHILD = "position_enfant";
const CHILD_OUT = "position_enfant_hors";
public const CHILD = 'position_enfant';
public const CHILD_OUT = 'position_enfant_hors';
public const POSITIONS_DATA = [
['Adulte', true, true, 1.0, self::ADULT],
['Enfant', true, false, 2.0, self::CHILD],
['Enfant hors ménage', false, false, 3.0, self::CHILD_OUT],
];
public function load(ObjectManager $manager)
{
foreach (self::POSITIONS_DATA as list($name, $share, $allowHolder,
$ordering, $ref)) {
foreach (self::POSITIONS_DATA as [$name, $share, $allowHolder,
$ordering, $ref]) {
$position = (new Position())
->setLabel([ "fr" => $name ])
->setLabel(['fr' => $name])
->setAllowHolder($allowHolder)
->setShareHousehold($share)
->setOrdering($ordering)
;
->setOrdering($ordering);
$manager->persist($position);
$this->addReference($ref, $position);

View File

@@ -1,66 +1,52 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2014, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\DataFixtures\ORM;
use Chill\PersonBundle\Entity\MaritalStatus;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Persistence\ObjectManager;
use Chill\PersonBundle\Entity\MaritalStatus;
/**
* Load marital status into database
*
* @author Marc Ducobu <marc@champs-libres.coop>
* Load marital status into database.
*/
class LoadMaritalStatus extends AbstractFixture implements OrderedFixtureInterface
{
private $maritalStatuses = [
['id' => 'single', 'name' =>['en' => 'single', 'fr' => 'célibataire']],
['id' => 'married', 'name' =>['en' => 'married', 'fr' => 'marié(e)']],
['id' => 'widow', 'name' =>['en' => 'widow', 'fr' => 'veuf veuve ']],
['id' => 'separat', 'name' =>['en' => 'separated', 'fr' => 'séparé(e)']],
['id' => 'divorce', 'name' =>['en' => 'divorced', 'fr' => 'divorcé(e)']],
['id' => 'legalco', 'name' =>['en' => 'legal cohabitant', 'fr' => 'cohabitant(e) légal(e)']],
['id' => 'unknown', 'name' =>['en' => 'unknown', 'fr' => 'indéterminé']]
['id' => 'single', 'name' => ['en' => 'single', 'fr' => 'célibataire']],
['id' => 'married', 'name' => ['en' => 'married', 'fr' => 'marié(e)']],
['id' => 'widow', 'name' => ['en' => 'widow', 'fr' => 'veuf veuve ']],
['id' => 'separat', 'name' => ['en' => 'separated', 'fr' => 'séparé(e)']],
['id' => 'divorce', 'name' => ['en' => 'divorced', 'fr' => 'divorcé(e)']],
['id' => 'legalco', 'name' => ['en' => 'legal cohabitant', 'fr' => 'cohabitant(e) légal(e)']],
['id' => 'unknown', 'name' => ['en' => 'unknown', 'fr' => 'indéterminé']],
];
public function getOrder()
{
return 9999;
}
public function load(ObjectManager $manager)
{
echo "loading maritalStatuses... \n";
foreach ($this->maritalStatuses as $ms) {
echo $ms['name']['en'].' ';
echo $ms['name']['en'] . ' ';
$new_ms = new MaritalStatus();
$new_ms->setId($ms['id']);
$new_ms->setName($ms['name']);
$this->addReference('ms_'.$ms['id'], $new_ms);
$this->addReference('ms_' . $ms['id'], $new_ms);
$manager->persist($new_ms);
}
$manager->flush();
}
}

View File

@@ -1,26 +1,17 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2014, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\DataFixtures\ORM;
use Chill\MainBundle\DataFixtures\ORM\LoadPostalCodes;
use Chill\MainBundle\Doctrine\Model\Point;
use Chill\MainBundle\Entity\Address;
use Chill\MainBundle\Entity\Center;
use Chill\MainBundle\Entity\Country;
use Chill\MainBundle\Entity\PostalCode;
@@ -32,386 +23,91 @@ use Chill\MainBundle\Repository\ScopeRepository;
use Chill\MainBundle\Repository\UserRepository;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\MaritalStatus;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
use Chill\PersonBundle\Repository\MaritalStatusRepository;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository;
use DateInterval;
use DateTime;
use DateTimeImmutable;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Persistence\ObjectManager;
use Chill\PersonBundle\Entity\Person;
use Exception;
use Faker\Factory;
use Faker\Generator;
use Nelmio\Alice\Faker\GeneratorFactory;
use Nelmio\Alice\Loader\NativeLoader;
use Nelmio\Alice\ObjectSet;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Chill\MainBundle\DataFixtures\ORM\LoadPostalCodes;
use Chill\MainBundle\Entity\Address;
use Chill\MainBundle\Doctrine\Model\Point;
use Symfony\Component\Workflow\Registry;
use Symfony\Component\Workflow\Workflow;
use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository;
use function random_int;
use function ucfirst;
/**
* Load people into database
*
* Load people into database.
*/
class LoadPeople extends AbstractFixture implements OrderedFixtureInterface, ContainerAwareInterface
{
use \Symfony\Component\DependencyInjection\ContainerAwareTrait;
protected Generator $faker;
protected Registry $workflowRegistry;
protected SocialIssueRepository $socialIssueRepository;
protected CountryRepository $countryRepository;
protected NativeLoader $loader;
public const PERSON = 'person';
/**
* @var array|SocialIssue[]
* @var array|Center[]
*/
protected array $cacheSocialIssues = [];
protected array $cacheCenters = [];
/**
* @var array|Country[]
*/
protected array $cacheCountries = [];
/**
* @var array|Center[]
*/
protected array $cacheCenters = [];
protected CenterRepository $centerRepository;
/**
* @var array|MaritalStatus[]
*/
protected array $cacheMaritalStatuses = [];
protected MaritalStatusRepository $maritalStatusRepository;
/**
* @var array|Scope[]
*/
protected array $cacheScopes = [];
/**
* @var array|SocialIssue[]
*/
protected array $cacheSocialIssues = [];
/**
* @var array|User[]
*/
protected array $cacheUsers = [];
protected CenterRepository $centerRepository;
protected CountryRepository $countryRepository;
protected Generator $faker;
protected NativeLoader $loader;
protected MaritalStatusRepository $maritalStatusRepository;
protected ScopeRepository $scopeRepository;
/** @var array|User[] */
protected array $cacheUsers = [];
protected SocialIssueRepository $socialIssueRepository;
protected UserRepository $userRepository;
public const PERSON = 'person';
protected Registry $workflowRegistry;
public function __construct(
Registry $workflowRegistry,
SocialIssueRepository $socialIssueRepository,
CenterRepository $centerRepository,
CountryRepository $countryRepository,
MaritalStatusRepository $maritalStatusRepository,
ScopeRepository $scopeRepository,
UserRepository $userRepository
) {
$this->faker = Factory::create('fr_FR');
$this->faker->addProvider($this);
$this->workflowRegistry = $workflowRegistry;
$this->socialIssueRepository = $socialIssueRepository;
$this->centerRepository = $centerRepository;
$this->countryRepository = $countryRepository;
$this->maritalStatusRepository = $maritalStatusRepository;
$this->loader = new NativeLoader($this->faker);
$this->scopeRepository = $scopeRepository;
$this->userRepository = $userRepository;
}
private $genders = [Person::MALE_GENDER, Person::FEMALE_GENDER, Person::BOTH_GENDER];
public function getOrder()
{
return 10000;
}
public function load(ObjectManager $manager)
{
$this->loadExpectedPeople($manager);
$this->loadRandPeople($manager);
$manager->flush();
}
public function loadExpectedPeople(ObjectManager $manager)
{
echo "loading expected people...\n";
foreach ($this->peoples as $personDef) {
$person = $this->createExpectedPerson($personDef);
$this->addAPerson($person, $manager);
}
}
protected function loadRandPeople(ObjectManager $manager)
{
echo "loading rand people...\n";
$persons = $this->createRandPerson()->getObjects();
foreach ($persons as $person) {
$this->addAPerson($person, $manager);
}
}
private function createRandPerson(): ObjectSet
{
return $this->loader->loadData([
Person::class => [
'persons{1..300}' => [
'firstName' => '<firstname()>',
'lastName' => '<lastname()>',
'gender' => '<getRandomGender()>',
'nationality' => '<getRandomCountry()>',
'center' => '<getRandomCenter()>',
'maritalStatus' => '<getRandomMaritalStatus()>',
'birthdate' => '<dateTimeBetween("-75 years", "-1 tears")>',
'placeOfBirth' => '<city()>',
'email' => '<freeEmail()>',
'countryOfBirth' => '<getRandomCountry(80)>',
]
]
]);
}
private function createExpectedPerson($default): Person
{
$person = $this->loader->loadData([
Person::class => [
"person" => [
'firstName' => $default['firstName'] ?? '<firstname()>',
'lastName' => $default['lastName'] ?? '<lastname()>',
'gender' => '<getRandomGender()>',
'nationality' => '<getRandomCountry()>',
'center' => '<getRandomCenter()>',
'maritalStatus' => '<getRandomMaritalStatus()>',
'birthdate' => '<dateTimeBetween("-75 years", "-1 tears")>',
'placeOfBirth' => '<city()>',
'email' => '<freeEmail()>',
'countryOfBirth' => '<getRandomCountry(80)>',
],
]
])->getObjects()['person'];
// force some values
foreach ($default as $key => $value) {
switch ($key) {
case 'birthdate':
$person->setBirthdate(new \DateTime($value));
break;
case 'center':
$person->setCenter($this->centerRepository
->findOneBy(['name' => $value]));
break;
case 'countryOfBirth':
case 'nationality':
$country = $this->countryRepository
->findOneBy(['countryCode' => $value]);
$person->{'set'.\ucfirst($key)}($country);
break;
case 'maritalStatus':
$person->setMaritalStatus($this->maritalStatusRepository
->find($value));
break;
}
}
return $person;
}
/**
* create a new person from array data
*
* @throws \Exception
*/
private function addAPerson(Person $person, ObjectManager $manager)
{
$accompanyingPeriod = new AccompanyingPeriod(
(new \DateTime())
->sub(
new \DateInterval('P' . \random_int(0, 180) . 'D')
)
);
$accompanyingPeriod->setCreatedBy($this->getRandomUser())
->setCreatedAt(new \DateTimeImmutable('now'));
$person->addAccompanyingPeriod($accompanyingPeriod);
$accompanyingPeriod->addSocialIssue($this->getRandomSocialIssue());
if (\random_int(0, 10) > 3) {
// always add social scope:
$accompanyingPeriod->addScope($this->getReference('scope_social'));
$origin = $this->getReference(LoadAccompanyingPeriodOrigin::ACCOMPANYING_PERIOD_ORIGIN);
$accompanyingPeriod->setOrigin($origin);
$accompanyingPeriod->setIntensity('regular');
$accompanyingPeriod->setAddressLocation($this->createAddress());
$manager->persist($accompanyingPeriod->getAddressLocation());
$workflow = $this->workflowRegistry->get($accompanyingPeriod);
$workflow->apply($accompanyingPeriod, 'confirm');
}
$manager->persist($person);
$manager->persist($accompanyingPeriod);
echo "add person'".$person->__toString()."'\n";
$this->addReference(self::PERSON.$person->getId(), $person);
}
private function getRandomUser(): User
{
if (0 === count($this->cacheUsers)) {
$this->cacheUsers = $this->userRepository->findAll();
}
return $this->cacheUsers[\array_rand($this->cacheUsers)];
}
private function createAddress(): Address
{
$objectSet = $this->loader->loadData([
Address::class => [
'address' => [
'street' => '<fr_FR:streetName()>',
'streetNumber' => '<fr_FR:buildingNumber()>',
'validFrom' => '<dateTimeBetween(\'-1 year\', \'now\')>',
'postCode' => $this->getPostalCode()
],
],
]);
return $objectSet->getObjects()['address'];
}
private function getRandomSocialIssue(): SocialIssue
{
if (0 === count($this->cacheSocialIssues)) {
$this->cacheSocialIssues = $this->socialIssueRepository->findAll();
}
return $this->cacheSocialIssues[\array_rand($this->cacheSocialIssues)];
}
private function getPostalCode(): PostalCode
{
$ref = LoadPostalCodes::$refs[\array_rand(LoadPostalCodes::$refs)];
return $this->getReference($ref);
}
/**
* Create a random point
*
* @return Point
*/
private function getRandomPoint()
{
$lonBrussels = 4.35243;
$latBrussels = 50.84676;
$lon = $lonBrussels + 0.01 * rand(-5, 5);
$lat = $latBrussels + 0.01 * rand(-5, 5);
return Point::fromLonLat($lon, $lat);
}
/**
* Create a random address
*
* @return Address
*/
private function getRandomAddress()
{
return (new Address())
->setStreetAddress1($this->faker->streetAddress)
->setStreetAddress2(
rand(0,9) > 5 ? $this->faker->streetAddress : ''
)
->setPoint(
rand(0,9) > 5 ? $this->getRandomPoint() : NULL
)
->setPostcode($this->getReference(
LoadPostalCodes::$refs[array_rand(LoadPostalCodes::$refs)]
))
->setValidFrom($this->faker->dateTimeBetween('-5 years'))
;
}
/**
* @internal This method is public and called by faker as a custom generator
* @return Center
*/
public function getRandomCenter(): Center
{
if (0 === count($this->cacheCenters)) {
$this->cacheCenters = $this->centerRepository->findAll();
}
return $this->cacheCenters[\array_rand($this->cacheCenters)];
}
/**
* @internal This method is public and called by faker as a custom generator
* @param int $nullPercentage
* @return Country|null
* @throws \Exception
*/
public function getRandomCountry(int $nullPercentage = 20): ?Country
{
if (0 === count($this->cacheCountries)) {
$this->cacheCountries = $this->countryRepository->findAll();
}
if ($nullPercentage < \random_int(0, 100)) {
return NULL;
}
return $this->cacheCountries [\array_rand($this->cacheCountries)];
}
/**
* @internal This method is public and called by faker as a custom generator
* @return string
*/
public function getRandomGender(): string
{
return $this->genders[array_rand($this->genders)];
}
/**
* @internal This method is public and called by faker as a custom generator
* @param int $nullPercentage
* @return MaritalStatus|null
* @throws \Exception
*/
public function getRandomMaritalStatus(int $nullPercentage = 50): ?MaritalStatus
{
if (0 === count($this->cacheMaritalStatuses)) {
$this->cacheMaritalStatuses = $this->maritalStatusRepository->findAll();
}
if ($nullPercentage < \random_int(0, 100)) {
return NULL;
}
return $this->cacheMaritalStatuses[array_rand($this->cacheMaritalStatuses)];
}
private $genders = array(Person::MALE_GENDER, Person::FEMALE_GENDER, Person::BOTH_GENDER);
private $peoples = array(
array(
'lastName' => "Depardieu",
'firstName' => "Gérard",
'birthdate' => "1948-12-27",
'placeOfBirth' => "Châteauroux",
private $peoples = [
[
'lastName' => 'Depardieu',
'firstName' => 'Gérard',
'birthdate' => '1948-12-27',
'placeOfBirth' => 'Châteauroux',
'nationality' => 'RU',
'gender' => Person::MALE_GENDER,
'center' => 'Center A',
@@ -420,73 +116,73 @@ class LoadPeople extends AbstractFixture implements OrderedFixtureInterface, Con
'from' => '2015-02-01',
'to' => '2015-10-30',
'remark' => 'oops',
],[
], [
'from' => '2017-06-01',
'to' => '2018-03-30',
'remark' => 'argg',
],[
], [
'from' => '2019-01-01',
'to' => '2019-12-31',
'remark' => 'blob',
]
]
),
array(
],
],
],
[
//to have a person with same firstname as Gérard Depardieu
'lastName' => "Depardieu",
'firstName' => "Jean",
'birthdate' => "1960-10-12",
'lastName' => 'Depardieu',
'firstName' => 'Jean',
'birthdate' => '1960-10-12',
'countryOfBirth' => 'FR',
'nationality' => 'FR',
'center' => 'Center A',
'maritalStatus' => 'ms_divorce'
),
array(
'maritalStatus' => 'ms_divorce',
],
[
//to have a person with same birthdate of Gérard Depardieu
'lastName' => 'Van Snick',
'firstName' => 'Bart',
'birthdate' => '1948-12-27',
'center' => 'Center A',
'maritalStatus' => 'ms_legalco'
),
array(
'maritalStatus' => 'ms_legalco',
],
[
//to have a woman with Depardieu as FirstName
'lastName' => 'Depardieu',
'firstName' => 'Charline',
'gender' => Person::FEMALE_GENDER,
'center' => 'Center A',
'maritalStatus' => 'ms_legalco'
),
array(
'maritalStatus' => 'ms_legalco',
],
[
//to have a special character in lastName
'lastName' => 'Manço',
'firstName' => 'Étienne',
'center' => 'Center A',
'maritalStatus' => 'ms_unknown'
),
array(
'maritalStatus' => 'ms_unknown',
],
[
//to have true duplicate person
'lastName' => "Depardieu",
'firstName' => "Jean",
'birthdate' => "1960-10-12",
'lastName' => 'Depardieu',
'firstName' => 'Jean',
'birthdate' => '1960-10-12',
'countryOfBirth' => 'FR',
'nationality' => 'FR',
'center' => 'Center A',
'maritalStatus' => 'ms_divorce'
),
array(
'maritalStatus' => 'ms_divorce',
],
[
//to have false duplicate person
'lastName' => "Depardieu",
'firstName' => "Jeanne",
'birthdate' => "1966-11-13",
'lastName' => 'Depardieu',
'firstName' => 'Jeanne',
'birthdate' => '1966-11-13',
'countryOfBirth' => 'FR',
'nationality' => 'FR',
'center' => 'Center A',
'maritalStatus' => 'ms_legalco'
),
'maritalStatus' => 'ms_legalco',
],
[
'lastName' => 'Diallo',
'firstName' => "Fatoumata Binta"
'firstName' => 'Fatoumata Binta',
],
[
'lastName' => 'Diallo',
@@ -510,7 +206,7 @@ class LoadPeople extends AbstractFixture implements OrderedFixtureInterface, Con
],
[
'lastName' => 'Bah',
'firstName' => "Fatoumata Binta"
'firstName' => 'Fatoumata Binta',
],
[
'lastName' => 'Bah',
@@ -540,24 +236,320 @@ class LoadPeople extends AbstractFixture implements OrderedFixtureInterface, Con
'lastName' => 'Gaillot',
'firstName' => 'Adèle',
],
);
];
/*
private function addAccompanyingPeriods(Person $person, array $periods, ObjectManager $manager)
public function __construct(
Registry $workflowRegistry,
SocialIssueRepository $socialIssueRepository,
CenterRepository $centerRepository,
CountryRepository $countryRepository,
MaritalStatusRepository $maritalStatusRepository,
ScopeRepository $scopeRepository,
UserRepository $userRepository
) {
$this->faker = Factory::create('fr_FR');
$this->faker->addProvider($this);
$this->workflowRegistry = $workflowRegistry;
$this->socialIssueRepository = $socialIssueRepository;
$this->centerRepository = $centerRepository;
$this->countryRepository = $countryRepository;
$this->maritalStatusRepository = $maritalStatusRepository;
$this->loader = new NativeLoader($this->faker);
$this->scopeRepository = $scopeRepository;
$this->userRepository = $userRepository;
}
public function getOrder()
{
foreach ($periods as $period) {
return 10000;
}
echo "adding new past Accompanying Period..\n";
/**
* @internal This method is public and called by faker as a custom generator
*/
public function getRandomCenter(): Center
{
if (0 === count($this->cacheCenters)) {
$this->cacheCenters = $this->centerRepository->findAll();
}
/** @var AccompanyingPeriod $accompanyingPeriod
$accompanyingPeriod = new AccompanyingPeriod(new \DateTime($period['from']));
$accompanyingPeriod
->setClosingDate(new \DateTime($period['to']))
->setRemark($period['remark'])
;
return $this->cacheCenters[\array_rand($this->cacheCenters)];
}
$person->addAccompanyingPeriod($accompanyingPeriod);
/**
* @internal This method is public and called by faker as a custom generator
*
* @throws Exception
*/
public function getRandomCountry(int $nullPercentage = 20): ?Country
{
if (0 === count($this->cacheCountries)) {
$this->cacheCountries = $this->countryRepository->findAll();
}
if (random_int(0, 100) > $nullPercentage) {
return null;
}
return $this->cacheCountries[\array_rand($this->cacheCountries)];
}
/**
* @internal This method is public and called by faker as a custom generator
*/
public function getRandomGender(): string
{
return $this->genders[array_rand($this->genders)];
}
/**
* @internal This method is public and called by faker as a custom generator
*
* @throws Exception
*/
public function getRandomMaritalStatus(int $nullPercentage = 50): ?MaritalStatus
{
if (0 === count($this->cacheMaritalStatuses)) {
$this->cacheMaritalStatuses = $this->maritalStatusRepository->findAll();
}
if (random_int(0, 100) > $nullPercentage) {
return null;
}
return $this->cacheMaritalStatuses[array_rand($this->cacheMaritalStatuses)];
}
public function load(ObjectManager $manager)
{
$this->loadExpectedPeople($manager);
$this->loadRandPeople($manager);
$manager->flush();
}
public function loadExpectedPeople(ObjectManager $manager)
{
echo "loading expected people...\n";
foreach ($this->peoples as $personDef) {
$person = $this->createExpectedPerson($personDef);
$this->addAPerson($person, $manager);
}
}
*/
protected function loadRandPeople(ObjectManager $manager)
{
echo "loading rand people...\n";
$persons = $this->createRandPerson()->getObjects();
foreach ($persons as $person) {
$this->addAPerson($person, $manager);
}
}
/**
* create a new person from array data.
*
* @throws Exception
*/
private function addAPerson(Person $person, ObjectManager $manager)
{
$accompanyingPeriod = new AccompanyingPeriod(
(new DateTime())
->sub(
new DateInterval('P' . random_int(0, 180) . 'D')
)
);
$accompanyingPeriod->setCreatedBy($this->getRandomUser())
->setCreatedAt(new DateTimeImmutable('now'));
$person->addAccompanyingPeriod($accompanyingPeriod);
$accompanyingPeriod->addSocialIssue($this->getRandomSocialIssue());
if (random_int(0, 10) > 3) {
// always add social scope:
$accompanyingPeriod->addScope($this->getReference('scope_social'));
$origin = $this->getReference(LoadAccompanyingPeriodOrigin::ACCOMPANYING_PERIOD_ORIGIN);
$accompanyingPeriod->setOrigin($origin);
$accompanyingPeriod->setIntensity('regular');
$accompanyingPeriod->setAddressLocation($this->createAddress());
$manager->persist($accompanyingPeriod->getAddressLocation());
$workflow = $this->workflowRegistry->get($accompanyingPeriod);
$workflow->apply($accompanyingPeriod, 'confirm');
}
$manager->persist($person);
$manager->persist($accompanyingPeriod);
echo "add person'" . $person->__toString() . "'\n";
$this->addReference(self::PERSON . $person->getId(), $person);
}
private function createAddress(): Address
{
$objectSet = $this->loader->loadData([
Address::class => [
'address' => [
'street' => '<fr_FR:streetName()>',
'streetNumber' => '<fr_FR:buildingNumber()>',
'validFrom' => '<dateTimeBetween(\'-1 year\', \'now\')>',
'postCode' => $this->getPostalCode(),
],
],
]);
return $objectSet->getObjects()['address'];
}
private function createExpectedPerson($default): Person
{
$person = $this->loader->loadData([
Person::class => [
'person' => [
'firstName' => $default['firstName'] ?? '<firstname()>',
'lastName' => $default['lastName'] ?? '<lastname()>',
'gender' => '<getRandomGender()>',
'nationality' => '<getRandomCountry()>',
'center' => '<getRandomCenter()>',
'maritalStatus' => '<getRandomMaritalStatus()>',
'birthdate' => '<dateTimeBetween("-75 years", "-1 tears")>',
'placeOfBirth' => '<city()>',
'email' => '<freeEmail()>',
'countryOfBirth' => '<getRandomCountry(80)>',
],
],
])->getObjects()['person'];
// force some values
foreach ($default as $key => $value) {
switch ($key) {
case 'birthdate':
$person->setBirthdate(new DateTime($value));
break;
case 'center':
$person->setCenter($this->centerRepository
->findOneBy(['name' => $value]));
break;
case 'countryOfBirth':
case 'nationality':
$country = $this->countryRepository
->findOneBy(['countryCode' => $value]);
$person->{'set' . ucfirst($key)}($country);
break;
case 'maritalStatus':
$person->setMaritalStatus($this->maritalStatusRepository
->find($value));
break;
}
}
return $person;
}
private function createRandPerson(): ObjectSet
{
return $this->loader->loadData([
Person::class => [
'persons{1..300}' => [
'firstName' => '<firstname()>',
'lastName' => '<lastname()>',
'gender' => '<getRandomGender()>',
'nationality' => '<getRandomCountry()>',
'center' => '<getRandomCenter()>',
'maritalStatus' => '<getRandomMaritalStatus()>',
'birthdate' => '<dateTimeBetween("-75 years", "-1 tears")>',
'placeOfBirth' => '<city()>',
'email' => '<freeEmail()>',
'countryOfBirth' => '<getRandomCountry(80)>',
],
],
]);
}
private function getPostalCode(): PostalCode
{
$ref = LoadPostalCodes::$refs[\array_rand(LoadPostalCodes::$refs)];
return $this->getReference($ref);
}
/**
* Create a random address.
*
* @return Address
*/
private function getRandomAddress()
{
return (new Address())
->setStreetAddress1($this->faker->streetAddress)
->setStreetAddress2(
rand(0, 9) > 5 ? $this->faker->streetAddress : ''
)
->setPoint(
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 * rand(-5, 5);
$lat = $latBrussels + 0.01 * rand(-5, 5);
return Point::fromLonLat($lon, $lat);
}
private function getRandomSocialIssue(): SocialIssue
{
if (0 === count($this->cacheSocialIssues)) {
$this->cacheSocialIssues = $this->socialIssueRepository->findAll();
}
return $this->cacheSocialIssues[\array_rand($this->cacheSocialIssues)];
}
private function getRandomUser(): User
{
if (0 === count($this->cacheUsers)) {
$this->cacheUsers = $this->userRepository->findAll();
}
return $this->cacheUsers[\array_rand($this->cacheUsers)];
}
/*
private function addAccompanyingPeriods(Person $person, array $periods, ObjectManager $manager)
{
foreach ($periods as $period) {
echo "adding new past Accompanying Period..\n";
/** @var AccompanyingPeriod $accompanyingPeriod
$accompanyingPeriod = new AccompanyingPeriod(new \DateTime($period['from']));
$accompanyingPeriod
->setClosingDate(new \DateTime($period['to']))
->setRemark($period['remark'])
;
$person->addAccompanyingPeriod($accompanyingPeriod);
}
}
*/
}

View File

@@ -1,37 +1,25 @@
<?php
/*
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop>
/**
* Chill is a software for social workers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\DataFixtures\ORM;
use Chill\MainBundle\DataFixtures\ORM\LoadPermissionsGroup;
use Chill\MainBundle\Entity\RoleScope;
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Persistence\ObjectManager;
use Chill\MainBundle\DataFixtures\ORM\LoadPermissionsGroup;
use Chill\MainBundle\Entity\RoleScope;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
/**
* Add a role CHILL_PERSON_UPDATE & CHILL_PERSON_CREATE for all groups except administrative,
* and a role CHILL_PERSON_SEE for administrative
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* and a role CHILL_PERSON_SEE for administrative.
*/
class LoadPersonACL extends AbstractFixture implements OrderedFixtureInterface
{
@@ -40,7 +28,6 @@ class LoadPersonACL extends AbstractFixture implements OrderedFixtureInterface
return 9600;
}
public function load(ObjectManager $manager)
{
foreach (LoadPermissionsGroup::$refs as $permissionsGroupRef) {
@@ -60,13 +47,13 @@ class LoadPersonACL extends AbstractFixture implements OrderedFixtureInterface
);
$roleScopeUpdate = (new RoleScope())
->setRole('CHILL_PERSON_UPDATE')
->setScope(null);
->setRole('CHILL_PERSON_UPDATE')
->setScope(null);
$permissionsGroup->addRoleScope($roleScopeUpdate);
$roleScopeCreate = (new RoleScope())
->setRole('CHILL_PERSON_CREATE')
->setScope(null);
->setRole('CHILL_PERSON_CREATE')
->setScope(null);
$permissionsGroup->addRoleScope($roleScopeCreate);
$roleScopeDuplicate = (new RoleScope())
@@ -75,13 +62,13 @@ class LoadPersonACL extends AbstractFixture implements OrderedFixtureInterface
$permissionsGroup->addRoleScope($roleScopeDuplicate);
$roleScopeList = (new RoleScope())
->setRole(PersonVoter::LISTS)
->setScope(null);
->setRole(PersonVoter::LISTS)
->setScope(null);
$permissionsGroup->addRoleScope($roleScopeList);
$roleScopeStats = (new RoleScope())
->setRole(PersonVoter::STATS)
->setScope(null);
->setRole(PersonVoter::STATS)
->setScope(null);
$permissionsGroup->addRoleScope($roleScopeStats);
$manager->persist($roleScopeUpdate);
@@ -89,19 +76,19 @@ class LoadPersonACL extends AbstractFixture implements OrderedFixtureInterface
$manager->persist($roleScopeDuplicate);
break;
case 'administrative':
printf("Adding CHILL_PERSON_SEE to %s permission group \n", $permissionsGroup->getName());
$roleScopeSee = (new RoleScope())
->setRole('CHILL_PERSON_SEE')
->setScope(null);
->setRole('CHILL_PERSON_SEE')
->setScope(null);
$permissionsGroup->addRoleScope($roleScopeSee);
$manager->persist($roleScopeSee);
break;
}
}
$manager->flush();
}
}

View File

@@ -1,4 +1,12 @@
<?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\PersonBundle\DataFixtures\ORM;
@@ -10,8 +18,9 @@ use Doctrine\Persistence\ObjectManager;
class LoadRelations extends Fixture implements FixtureGroupInterface
{
public const RELATION_KEY = 'relations';
public const RELATIONS = [
public const RELATION_KEY = 'relations';
public const RELATIONS = [
['title' => ['fr' => 'Mère'], 'reverseTitle' => ['fr' => 'Fille']],
['title' => ['fr' => 'Mère'], 'reverseTitle' => ['fr' => 'Fils']],
['title' => ['fr' => 'Père'], 'reverseTitle' => ['fr' => 'Fille']],
@@ -38,17 +47,16 @@ class LoadRelations extends Fixture implements FixtureGroupInterface
public function load(ObjectManager $manager)
{
foreach (self::RELATIONS as $key => $value){
print "Creating a new relation type: relation" . $value['title']['fr'] . "reverse relation: " . $value['reverseTitle']['fr'] . "\n";
foreach (self::RELATIONS as $key => $value) {
echo 'Creating a new relation type: relation' . $value['title']['fr'] . 'reverse relation: ' . $value['reverseTitle']['fr'] . "\n";
$relation = new Relation();
$relation->setTitle($value['title'])
->setReverseTitle($value['reverseTitle']);
$manager->persist($relation);
$this->addReference(self::RELATION_KEY.$key, $relation);
$this->addReference(self::RELATION_KEY . $key, $relation);
}
$manager->flush();
}
}

View File

@@ -1,4 +1,12 @@
<?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\PersonBundle\DataFixtures\ORM;
@@ -6,15 +14,17 @@ namespace Chill\PersonBundle\DataFixtures\ORM;
use Chill\MainBundle\DataFixtures\ORM\LoadUsers;
use Chill\MainBundle\Entity\User;
use Chill\PersonBundle\DataFixtures\Helper\PersonRandomHelper;
use Chill\PersonBundle\Entity\Relationships\Relationship;
use DateTimeImmutable;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Persistence\ObjectManager;
use Chill\PersonBundle\Entity\Relationships\Relationship;
class LoadRelationships extends Fixture implements DependentFixtureInterface
{
use PersonRandomHelper;
private EntityManagerInterface $em;
public function __construct(EntityManagerInterface $em)
@@ -26,26 +36,25 @@ class LoadRelationships extends Fixture implements DependentFixtureInterface
{
return [
LoadPeople::class,
LoadRelations::class
LoadRelations::class,
];
}
public function load(ObjectManager $manager)
{
for ($i = 0; $i < 15; $i++) {
for ($i = 0; 15 > $i; ++$i) {
$user = $this->getRandomUser();
$date = new \DateTimeImmutable();
$date = new DateTimeImmutable();
$relationship = (new Relationship())
->setFromPerson($this->getRandomPerson($this->em))
->setToPerson($this->getRandomPerson($this->em))
->setRelation($this->getReference(LoadRelations::RELATION_KEY.
->setRelation($this->getReference(LoadRelations::RELATION_KEY .
\random_int(0, count(LoadRelations::RELATIONS) - 1)))
->setReverse((bool) random_int(0, 1))
->setCreatedBy($user)
->setUpdatedBy($user)
->setCreatedAt($date)
->setUpdatedAt($date)
;
->setUpdatedAt($date);
$manager->persist($relationship);
}
@@ -55,6 +64,7 @@ class LoadRelationships extends Fixture implements DependentFixtureInterface
private function getRandomUser(): User
{
$userRef = array_rand(LoadUsers::$refs);
return $this->getReference($userRef);
}
}

View File

@@ -1,5 +1,12 @@
<?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\PersonBundle\DataFixtures\ORM;
@@ -8,7 +15,9 @@ use Chill\PersonBundle\Service\Import\SocialWorkMetadata;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Persistence\ObjectManager;
use Exception;
use League\Csv\Reader;
use Throwable;
class LoadSocialWorkMetadata extends Fixture implements OrderedFixtureInterface
{
@@ -19,21 +28,21 @@ class LoadSocialWorkMetadata extends Fixture implements OrderedFixtureInterface
$this->importer = $importer;
}
public function load(ObjectManager $manager)
{
try {
$csv = Reader::createFromPath(__DIR__.'/data/social_work_metadata.csv');
} catch (\Throwable $e) {
throw new \Exception('Error while loading CSV.',0, $e);
}
$csv->setDelimiter(";");
$this->importer->import($csv);
}
public function getOrder()
{
return 9500;
}
public function load(ObjectManager $manager)
{
try {
$csv = Reader::createFromPath(__DIR__ . '/data/social_work_metadata.csv');
} catch (Throwable $e) {
throw new Exception('Error while loading CSV.', 0, $e);
}
$csv->setDelimiter(';');
$this->importer->import($csv);
}
}

View File

@@ -1,50 +1,37 @@
<?php
/*
* Copyright (C) 2014-2016 Julien Fastré <julien.fastre@champs-libres.coop>
/**
* Chill is a software for social workers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\DependencyInjection;
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
use Chill\MainBundle\DependencyInjection\MissingBundleException;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use Chill\MainBundle\Security\Authorization\ChillExportVoter;
use Chill\PersonBundle\Doctrine\DQL\AddressPart;
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use Exception;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
use Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
/**
* Class ChillPersonExtension
* Loads and manages your bundle configuration
* Loads and manages your bundle configuration.
*
* To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html}
* @package Chill\PersonBundle\DependencyInjection
*/
class ChillPersonExtension extends Extension implements PrependExtensionInterface
{
/**
* {@inheritDoc}
* @param array $configs
* @param ContainerBuilder $container
* @throws \Exception
* @throws Exception
*/
public function load(array $configs, ContainerBuilder $container)
{
@@ -52,19 +39,23 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
$config = $this->processConfiguration($configuration, $configs);
// set configuration for validation
$container->setParameter('chill_person.validation.birtdate_not_before',
$config['validation']['birthdate_not_after']);
$container->setParameter(
'chill_person.validation.birtdate_not_before',
$config['validation']['birthdate_not_after']
);
$this->handlePersonFieldsParameters($container, $config['person_fields']);
$this->handleAccompanyingPeriodsFieldsParameters($container, $config['accompanying_periods_fields']);
$container->setParameter('chill_person.allow_multiple_simultaneous_accompanying_periods',
$config['allow_multiple_simultaneous_accompanying_periods']);
$container->setParameter(
'chill_person.allow_multiple_simultaneous_accompanying_periods',
$config['allow_multiple_simultaneous_accompanying_periods']
);
// register all configuration in a unique parameter
$container->setParameter('chill_person', $config);
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../config'));
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../config'));
$loader->load('services.yaml');
$loader->load('services/widgets.yaml');
$loader->load('services/exports.yaml');
@@ -92,70 +83,6 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
}
/**
* @param ContainerBuilder $container
* @param $config
*/
private function handlePersonFieldsParameters(ContainerBuilder $container, $config)
{
if (array_key_exists('enabled', $config)) {
unset($config['enabled']);
}
$container->setParameter('chill_person.person_fields', $config);
foreach ($config as $key => $value) {
switch($key) {
case 'accompanying_period':
$container->setParameter('chill_person.accompanying_period', $value);
break;
default:
$container->setParameter('chill_person.person_fields.'.$key, $value);
break;
}
}
}
/**
* @param ContainerBuilder $container
* @param $config
*/
private function handleAccompanyingPeriodsFieldsParameters(ContainerBuilder $container, $config)
{
$container->setParameter('chill_person.accompanying_period_fields', $config);
foreach ($config as $key => $value) {
switch($key) {
case 'enabled':
break;
default:
$container->setParameter('chill_person.accompanying_period_fields.'.$key, $value);
break;
}
}
}
/**
* @param ContainerBuilder $container
* @throws MissingBundleException
*/
private function declarePersonAsCustomizable (ContainerBuilder $container)
{
$bundles = $container->getParameter('kernel.bundles');
if (!isset($bundles['ChillCustomFieldsBundle'])) {
throw new MissingBundleException('ChillCustomFieldsBundle');
}
$container->prependExtensionConfig('chill_custom_fields',
array('customizables_entities' =>
array(
array('class' => 'Chill\PersonBundle\Entity\Person', 'name' => 'PersonEntity')
)
)
);
}
/**
* @param ContainerBuilder $container
* @throws MissingBundleException
*/
public function prepend(ContainerBuilder $container)
@@ -169,152 +96,31 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
//add person_fields parameter as global
$chillPersonConfig = $container->getExtensionConfig($this->getAlias());
$config = $this->processConfiguration(new Configuration(), $chillPersonConfig);
$twigConfig = array(
'globals' => array(
'chill_person' => array(
'fields' => $config['person_fields']
),
$twigConfig = [
'globals' => [
'chill_person' => [
'fields' => $config['person_fields'],
],
'chill_accompanying_periods' => [
'fields' => $config['accompanying_periods_fields']
]
),
'form_themes' => array('ChillPersonBundle:Export:ListPersonFormFields.html.twig')
);
'fields' => $config['accompanying_periods_fields'],
],
],
'form_themes' => ['ChillPersonBundle:Export:ListPersonFormFields.html.twig'],
];
$container->prependExtensionConfig('twig', $twigConfig);
$this-> declarePersonAsCustomizable($container);
$this->declarePersonAsCustomizable($container);
//declare routes for person bundle
$container->prependExtensionConfig('chill_main', array(
'routing' => array(
'resources' => array(
'@ChillPersonBundle/config/routes.yaml'
)
)
));
}
protected function prependWorkflows(ContainerBuilder $container)
{
$container->prependExtensionConfig('framework', [
'workflows' => [
'accompanying_period_lifecycle' => [
'type' => 'state_machine',
'audit_trail' => [
'enabled' => true
],
'marking_store' => [
'type' => 'method',
'property' => 'step',
],
'supports' => [
'Chill\PersonBundle\Entity\AccompanyingPeriod'
],
'initial_marking' => 'DRAFT',
'places' => [
'DRAFT',
'CONFIRMED',
'CLOSED',
],
'transitions' => [
'confirm' => [
'from' => 'DRAFT',
'to' => 'CONFIRMED'
],
'close' => [
'from' => 'CONFIRMED',
'to' => 'CLOSED'
],
],
$container->prependExtensionConfig('chill_main', [
'routing' => [
'resources' => [
'@ChillPersonBundle/config/routes.yaml',
],
]
]);
}
/**
* Add a widget "add a person" on the homepage, automatically
*
* @param \Chill\PersonBundle\DependencyInjection\containerBuilder $container
*/
protected function prependHomepageWidget(containerBuilder $container)
{
$container->prependExtensionConfig('chill_main', array(
'widgets' => array(
'homepage' => array(
array(
'widget_alias' => 'add_person',
'order' => 2
)
)
)
));
}
/**
* Add role hierarchy.
*
* @param ContainerBuilder $container
*/
protected function prependRoleHierarchy(ContainerBuilder $container)
{
$container->prependExtensionConfig('security', [
'role_hierarchy' => [
PersonVoter::UPDATE => [PersonVoter::SEE],
PersonVoter::CREATE => [PersonVoter::SEE],
PersonVoter::LISTS => [ChillExportVoter::EXPORT],
PersonVoter::STATS => [ChillExportVoter::EXPORT],
// accompanying period
AccompanyingPeriodVoter::SEE_DETAILS => [AccompanyingPeriodVoter::SEE],
AccompanyingPeriodVoter::CREATE => [AccompanyingPeriodVoter::SEE_DETAILS],
AccompanyingPeriodVoter::DELETE => [AccompanyingPeriodVoter::SEE_DETAILS],
AccompanyingPeriodVoter::EDIT => [AccompanyingPeriodVoter::SEE_DETAILS],
// give all ACL for FULL
AccompanyingPeriodVoter::FULL => [
AccompanyingPeriodVoter::SEE_DETAILS,
AccompanyingPeriodVoter::CREATE,
AccompanyingPeriodVoter::EDIT,
AccompanyingPeriodVoter::DELETE
]
]
],
]);
}
/**
* Add DQL function linked with person
*
* @param ContainerBuilder $container
*/
protected function prependDoctrineDQL(ContainerBuilder $container)
{
//add DQL function to ORM (default entity_manager)
$container->prependExtensionConfig('doctrine', array(
'orm' => array(
'dql' => array(
'string_functions' => array(
'GET_PERSON_ADDRESS_ADDRESS_ID' => AddressPart\AddressPartAddressId::class,
'GET_PERSON_ADDRESS_STREET_ADDRESS_1' => AddressPart\AddressPartStreetAddress1::class,
'GET_PERSON_ADDRESS_STREET_ADDRESS_2' => AddressPart\AddressPartStreetAddress2::class,
'GET_PERSON_ADDRESS_VALID_FROM' => AddressPart\AddressPartValidFrom::class,
'GET_PERSON_ADDRESS_POSTCODE_LABEL' => AddressPart\AddressPartPostCodeLabel::class,
'GET_PERSON_ADDRESS_POSTCODE_CODE' => AddressPart\AddressPartPostCodeCode::class,
'GET_PERSON_ADDRESS_POSTCODE_ID' => AddressPart\AddressPartPostCodeId::class,
'GET_PERSON_ADDRESS_COUNTRY_NAME' => AddressPart\AddressPartCountryName::class,
'GET_PERSON_ADDRESS_COUNTRY_CODE' => AddressPart\AddressPartCountryCode::class,
'GET_PERSON_ADDRESS_COUNTRY_ID' => AddressPart\AddressPartCountryId::class,
),
'numeric_functions' => [
'GET_PERSON_ADDRESS_ISNOADDRESS' => AddressPart\AddressPartIsNoAddress::class,
]
)
)
));
}
/**
* @param ContainerBuilder $container
*/
protected function prependCruds(ContainerBuilder $container)
{
$container->prependExtensionConfig('chill_main', [
@@ -328,17 +134,17 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
'actions' => [
'index' => [
'template' => '@ChillPerson/ClosingMotive/index.html.twig',
'role' => 'ROLE_ADMIN'
'role' => 'ROLE_ADMIN',
],
'new' => [
'new' => [
'role' => 'ROLE_ADMIN',
'template' => '@ChillPerson/ClosingMotive/new.html.twig',
],
'edit' => [
'edit' => [
'role' => 'ROLE_ADMIN',
'template' => '@ChillPerson/ClosingMotive/edit.html.twig',
]
]
],
],
],
[
'class' => \Chill\PersonBundle\Entity\MaritalStatus::class,
@@ -351,15 +157,15 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
'role' => 'ROLE_ADMIN',
'template' => '@ChillPerson/MaritalStatus/index.html.twig',
],
'new' => [
'new' => [
'role' => 'ROLE_ADMIN',
'template' => '@ChillPerson/MaritalStatus/new.html.twig',
],
'edit' => [
'edit' => [
'role' => 'ROLE_ADMIN',
'template' => '@ChillPerson/MaritalStatus/edit.html.twig',
]
]
],
],
],
[
'class' => \Chill\PersonBundle\Entity\SocialWork\SocialIssue::class,
@@ -372,15 +178,15 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
'role' => 'ROLE_ADMIN',
'template' => '@ChillPerson/SocialWork/SocialIssue/index.html.twig',
],
'new' => [
'new' => [
'role' => 'ROLE_ADMIN',
'template' => '@ChillPerson/SocialWork/new.html.twig',
],
'edit' => [
'edit' => [
'role' => 'ROLE_ADMIN',
'template' => '@ChillPerson/SocialWork/edit.html.twig',
]
]
],
],
],
[
'class' => \Chill\PersonBundle\Entity\SocialWork\SocialAction::class,
@@ -393,15 +199,15 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
'role' => 'ROLE_ADMIN',
'template' => '@ChillPerson/SocialWork/SocialAction/index.html.twig',
],
'new' => [
'new' => [
'role' => 'ROLE_ADMIN',
'template' => '@ChillPerson/SocialWork/new.html.twig',
],
'edit' => [
'edit' => [
'role' => 'ROLE_ADMIN',
'template' => '@ChillPerson/SocialWork/edit.html.twig',
]
]
],
],
],
[
'class' => \Chill\PersonBundle\Entity\SocialWork\Goal::class,
@@ -414,15 +220,15 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
'role' => 'ROLE_ADMIN',
'template' => '@ChillPerson/SocialWork/Goal/index.html.twig',
],
'new' => [
'new' => [
'role' => 'ROLE_ADMIN',
'template' => '@ChillPerson/SocialWork/new.html.twig',
],
'edit' => [
'edit' => [
'role' => 'ROLE_ADMIN',
'template' => '@ChillPerson/SocialWork/edit.html.twig',
]
]
],
],
],
[
'class' => \Chill\PersonBundle\Entity\SocialWork\Result::class,
@@ -435,15 +241,15 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
'role' => 'ROLE_ADMIN',
'template' => '@ChillPerson/SocialWork/Result/index.html.twig',
],
'new' => [
'new' => [
'role' => 'ROLE_ADMIN',
'template' => '@ChillPerson/SocialWork/new.html.twig',
],
'edit' => [
'edit' => [
'role' => 'ROLE_ADMIN',
'template' => '@ChillPerson/SocialWork/edit.html.twig',
]
]
],
],
],
[
'class' => \Chill\PersonBundle\Entity\SocialWork\Evaluation::class,
@@ -456,15 +262,15 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
'role' => 'ROLE_ADMIN',
'template' => '@ChillPerson/SocialWork/Evaluation/index.html.twig',
],
'new' => [
'new' => [
'role' => 'ROLE_ADMIN',
'template' => '@ChillPerson/SocialWork/new.html.twig',
],
'edit' => [
'edit' => [
'role' => 'ROLE_ADMIN',
'template' => '@ChillPerson/SocialWork/edit.html.twig',
]
]
],
],
],
],
'apis' => [
@@ -484,7 +290,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
Request::METHOD_GET => true,
Request::METHOD_PUT => true,
Request::METHOD_PATCH => true,
]
],
],
'participation' => [
'methods' => [
@@ -495,8 +301,8 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
],
'roles' => [
Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE
]
Request::METHOD_DELETE => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
],
],
'resource' => [
'methods' => [
@@ -507,8 +313,8 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
],
'roles' => [
Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE
]
Request::METHOD_DELETE => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
],
],
'comment' => [
'methods' => [
@@ -519,8 +325,8 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
],
'roles' => [
Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE
]
Request::METHOD_DELETE => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
],
],
'requestor' => [
'methods' => [
@@ -531,8 +337,8 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
],
'roles' => [
Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE
]
Request::METHOD_DELETE => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
],
],
'scope' => [
'methods' => [
@@ -543,8 +349,8 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
],
'roles' => [
Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE
]
Request::METHOD_DELETE => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
],
],
'socialissue' => [
'methods' => [
@@ -556,8 +362,8 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
'controller_action' => 'socialIssueApi',
'roles' => [
Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE
]
Request::METHOD_DELETE => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
],
],
'work' => [
'methods' => [
@@ -570,7 +376,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
'roles' => [
Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
Request::METHOD_DELETE => 'ALWAYS_FAILS',
]
],
],
'confirm' => [
@@ -581,7 +387,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
],
'roles' => [
Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
]
],
],
'findAccompanyingPeriodsByPerson' => [
'path' => '/by-person/{person_id}.{_format}',
@@ -589,9 +395,9 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
'methods' => [
Request::METHOD_GET => true,
Request::METHOD_HEAD => true,
]
]
]
],
],
],
],
[
'class' => \Chill\PersonBundle\Entity\AccompanyingPeriod\Origin::class,
@@ -603,16 +409,16 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
'_index' => [
'methods' => [
Request::METHOD_GET => true,
Request::METHOD_HEAD => true
Request::METHOD_HEAD => true,
],
],
'_entity' => [
'methods' => [
Request::METHOD_GET => true,
Request::METHOD_HEAD => true
]
Request::METHOD_HEAD => true,
],
],
]
],
],
[
'class' => \Chill\PersonBundle\Entity\SocialWork\SocialIssue::class,
@@ -624,16 +430,16 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
'_index' => [
'methods' => [
Request::METHOD_GET => true,
Request::METHOD_HEAD => true
Request::METHOD_HEAD => true,
],
],
'_entity' => [
'methods' => [
Request::METHOD_GET => true,
Request::METHOD_HEAD => true
]
Request::METHOD_HEAD => true,
],
],
]
],
],
[
'class' => \Chill\PersonBundle\Entity\Person::class,
@@ -646,8 +452,8 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
'methods' => [
Request::METHOD_GET => true,
Request::METHOD_HEAD => true,
Request::METHOD_POST=> true,
Request::METHOD_PATCH => true
Request::METHOD_POST => true,
Request::METHOD_PATCH => true,
],
'roles' => [
Request::METHOD_GET => \Chill\PersonBundle\Security\Authorization\PersonVoter::SEE,
@@ -663,9 +469,9 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
Request::METHOD_GET => false,
Request::METHOD_HEAD => false,
],
'controller_action' => 'personAddressApi'
'controller_action' => 'personAddressApi',
],
]
],
],
[
'class' => \Chill\PersonBundle\Entity\Household\Household::class,
@@ -684,7 +490,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
'methods' => [
Request::METHOD_GET => true,
Request::METHOD_HEAD => true,
]
],
],
'address' => [
'methods' => [
@@ -693,16 +499,16 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
Request::METHOD_GET => false,
Request::METHOD_HEAD => false,
],
'controller_action' => 'householdAddressApi'
'controller_action' => 'householdAddressApi',
],
'suggestHouseholdByAccompanyingPeriodParticipation' => [
'path' => '/suggest/by-person/{person_id}/through-accompanying-period-participation.{_format}',
'methods' => [
Request::METHOD_GET => true,
Request::METHOD_HEAD => true,
]
]
]
],
],
],
],
[
'class' => \Chill\PersonBundle\Entity\SocialWork\SocialAction::class,
@@ -720,7 +526,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
'roles' => [
Request::METHOD_GET => 'ROLE_USER',
Request::METHOD_HEAD => 'ROLE_USER',
]
],
],
'_index' => [
'methods' => [
@@ -730,7 +536,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
'roles' => [
Request::METHOD_GET => 'ROLE_USER',
Request::METHOD_HEAD => 'ROLE_USER',
]
],
],
'listBySocialIssue' => [
'single-collection' => 'collection',
@@ -742,10 +548,9 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
'roles' => [
Request::METHOD_GET => 'ROLE_USER',
Request::METHOD_HEAD => 'ROLE_USER',
]
]
]
],
],
],
],
[
'class' => \Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork::class,
@@ -767,9 +572,9 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
Request::METHOD_HEAD => 'ROLE_USER',
Request::METHOD_PATCH => 'ROLE_USER',
Request::METHOD_PUT => 'ROLE_USER',
]
],
],
]
],
],
[
'class' => \Chill\PersonBundle\Entity\SocialWork\Result::class,
@@ -786,7 +591,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
'roles' => [
Request::METHOD_GET => 'ROLE_USER',
Request::METHOD_HEAD => 'ROLE_USER',
]
],
],
'_index' => [
'methods' => [
@@ -796,7 +601,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
'roles' => [
Request::METHOD_GET => 'ROLE_USER',
Request::METHOD_HEAD => 'ROLE_USER',
]
],
],
'by-social-action' => [
'single-collection' => 'collection',
@@ -809,7 +614,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
'roles' => [
Request::METHOD_GET => 'ROLE_USER',
Request::METHOD_HEAD => 'ROLE_USER',
]
],
],
'by-goal' => [
'single-collection' => 'collection',
@@ -822,9 +627,9 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
'roles' => [
Request::METHOD_GET => 'ROLE_USER',
Request::METHOD_HEAD => 'ROLE_USER',
]
],
],
]
],
],
[
'class' => \Chill\PersonBundle\Entity\SocialWork\Goal::class,
@@ -841,7 +646,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
'roles' => [
Request::METHOD_GET => 'ROLE_USER',
Request::METHOD_HEAD => 'ROLE_USER',
]
],
],
'_index' => [
'methods' => [
@@ -851,7 +656,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
'roles' => [
Request::METHOD_GET => 'ROLE_USER',
Request::METHOD_HEAD => 'ROLE_USER',
]
],
],
'by-social-action' => [
'single-collection' => 'collection',
@@ -864,9 +669,9 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
'roles' => [
Request::METHOD_GET => 'ROLE_USER',
Request::METHOD_HEAD => 'ROLE_USER',
]
],
],
]
],
],
[
'class' => \Chill\PersonBundle\Entity\Relationships\Relationship::class,
@@ -885,7 +690,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
Request::METHOD_POST => 'ROLE_USER',
Request::METHOD_PATCH => 'ROLE_USER',
Request::METHOD_DELETE => 'ROLE_USER',
]
],
],
'relationship-by-person' => [
'path' => '/by-person/{person_id}.json',
@@ -897,9 +702,9 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
'roles' => [
Request::METHOD_GET => 'ROLE_USER',
Request::METHOD_HEAD => 'ROLE_USER',
]
],
],
]
],
],
[
'class' => \Chill\PersonBundle\Entity\Relationships\Relation::class,
@@ -910,18 +715,197 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
'_index' => [
'methods' => [
Request::METHOD_GET => true,
Request::METHOD_HEAD => true
Request::METHOD_HEAD => true,
],
],
'_entity' => [
'methods' => [
Request::METHOD_GET => true,
Request::METHOD_HEAD => true
]
Request::METHOD_HEAD => true,
],
],
]
],
],
]
],
]);
}
/**
* Add DQL function linked with person.
*/
protected function prependDoctrineDQL(ContainerBuilder $container)
{
//add DQL function to ORM (default entity_manager)
$container->prependExtensionConfig('doctrine', [
'orm' => [
'dql' => [
'string_functions' => [
'GET_PERSON_ADDRESS_ADDRESS_ID' => AddressPart\AddressPartAddressId::class,
'GET_PERSON_ADDRESS_STREET_ADDRESS_1' => AddressPart\AddressPartStreetAddress1::class,
'GET_PERSON_ADDRESS_STREET_ADDRESS_2' => AddressPart\AddressPartStreetAddress2::class,
'GET_PERSON_ADDRESS_VALID_FROM' => AddressPart\AddressPartValidFrom::class,
'GET_PERSON_ADDRESS_POSTCODE_LABEL' => AddressPart\AddressPartPostCodeLabel::class,
'GET_PERSON_ADDRESS_POSTCODE_CODE' => AddressPart\AddressPartPostCodeCode::class,
'GET_PERSON_ADDRESS_POSTCODE_ID' => AddressPart\AddressPartPostCodeId::class,
'GET_PERSON_ADDRESS_COUNTRY_NAME' => AddressPart\AddressPartCountryName::class,
'GET_PERSON_ADDRESS_COUNTRY_CODE' => AddressPart\AddressPartCountryCode::class,
'GET_PERSON_ADDRESS_COUNTRY_ID' => AddressPart\AddressPartCountryId::class,
],
'numeric_functions' => [
'GET_PERSON_ADDRESS_ISNOADDRESS' => AddressPart\AddressPartIsNoAddress::class,
],
],
],
]);
}
/**
* Add a widget "add a person" on the homepage, automatically.
*
* @param \Chill\PersonBundle\DependencyInjection\containerBuilder $container
*/
protected function prependHomepageWidget(containerBuilder $container)
{
$container->prependExtensionConfig('chill_main', [
'widgets' => [
'homepage' => [
[
'widget_alias' => 'add_person',
'order' => 2,
],
],
],
]);
}
/**
* Add role hierarchy.
*/
protected function prependRoleHierarchy(ContainerBuilder $container)
{
$container->prependExtensionConfig('security', [
'role_hierarchy' => [
PersonVoter::UPDATE => [PersonVoter::SEE],
PersonVoter::CREATE => [PersonVoter::SEE],
PersonVoter::LISTS => [ChillExportVoter::EXPORT],
PersonVoter::STATS => [ChillExportVoter::EXPORT],
// accompanying period
AccompanyingPeriodVoter::SEE_DETAILS => [AccompanyingPeriodVoter::SEE],
AccompanyingPeriodVoter::CREATE => [AccompanyingPeriodVoter::SEE_DETAILS],
AccompanyingPeriodVoter::DELETE => [AccompanyingPeriodVoter::SEE_DETAILS],
AccompanyingPeriodVoter::EDIT => [AccompanyingPeriodVoter::SEE_DETAILS],
// give all ACL for FULL
AccompanyingPeriodVoter::FULL => [
AccompanyingPeriodVoter::SEE_DETAILS,
AccompanyingPeriodVoter::CREATE,
AccompanyingPeriodVoter::EDIT,
AccompanyingPeriodVoter::DELETE,
],
],
]);
}
protected function prependWorkflows(ContainerBuilder $container)
{
$container->prependExtensionConfig('framework', [
'workflows' => [
'accompanying_period_lifecycle' => [
'type' => 'state_machine',
'audit_trail' => [
'enabled' => true,
],
'marking_store' => [
'type' => 'method',
'property' => 'step',
],
'supports' => [
'Chill\PersonBundle\Entity\AccompanyingPeriod',
],
'initial_marking' => 'DRAFT',
'places' => [
'DRAFT',
'CONFIRMED',
'CLOSED',
],
'transitions' => [
'confirm' => [
'from' => 'DRAFT',
'to' => 'CONFIRMED',
],
'close' => [
'from' => 'CONFIRMED',
'to' => 'CLOSED',
],
],
],
],
]);
}
/**
* @throws MissingBundleException
*/
private function declarePersonAsCustomizable(ContainerBuilder $container)
{
$bundles = $container->getParameter('kernel.bundles');
if (!isset($bundles['ChillCustomFieldsBundle'])) {
throw new MissingBundleException('ChillCustomFieldsBundle');
}
$container->prependExtensionConfig(
'chill_custom_fields',
['customizables_entities' => [
['class' => 'Chill\PersonBundle\Entity\Person', 'name' => 'PersonEntity'],
],
]
);
}
/**
* @param $config
*/
private function handleAccompanyingPeriodsFieldsParameters(ContainerBuilder $container, $config)
{
$container->setParameter('chill_person.accompanying_period_fields', $config);
foreach ($config as $key => $value) {
switch ($key) {
case 'enabled':
break;
default:
$container->setParameter('chill_person.accompanying_period_fields.' . $key, $value);
break;
}
}
}
/**
* @param $config
*/
private function handlePersonFieldsParameters(ContainerBuilder $container, $config)
{
if (array_key_exists('enabled', $config)) {
unset($config['enabled']);
}
$container->setParameter('chill_person.person_fields', $config);
foreach ($config as $key => $value) {
switch ($key) {
case 'accompanying_period':
$container->setParameter('chill_person.accompanying_period', $value);
break;
default:
$container->setParameter('chill_person.person_fields.' . $key, $value);
break;
}
}
}
}

View File

@@ -1,29 +1,21 @@
<?php
/*
* Copyright (C) 2018 Champs-Libres <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Chill\PersonBundle\DependencyInjection\CompilerPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
/**
* Remove services which add AccompanyingPeriod to timeline if
* accompanying_periods are set to `hidden`
* 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\PersonBundle\DependencyInjection\CompilerPass;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use function in_array;
/**
* Remove services which add AccompanyingPeriod to timeline if
* accompanying_periods are set to `hidden`.
*/
class AccompanyingPeriodTimelineCompilerPass implements CompilerPassInterface
{
@@ -33,34 +25,33 @@ class AccompanyingPeriodTimelineCompilerPass implements CompilerPassInterface
if ($container->getParameter('chill_person.accompanying_period') !== 'hidden') {
return;
}
$definitions = [
'chill.person.timeline.accompanying_period_opening',
'chill.person.timeline.accompanying_period_closing'
'chill.person.timeline.accompanying_period_closing',
];
foreach($definitions as $definition) {
foreach ($definitions as $definition) {
$container
->removeDefinition($definition)
;
->removeDefinition($definition);
}
$definition = $container->getDefinition('chill.main.timeline_builder');
// we have to remove all methods call, and re-add them if not linked
// we have to remove all methods call, and re-add them if not linked
// to this service
$calls = $definition->getMethodCalls();
foreach($calls as list($method, $arguments)) {
if ($method !== 'addProvider') {
foreach ($calls as [$method, $arguments]) {
if ('addProvider' !== $method) {
continue;
}
$definition->removeMethodCall('addProvider');
if (FALSE === \in_array($arguments[1], $definitions)) {
if (false === in_array($arguments[1], $definitions)) {
$definition->addMethodCall($method, $arguments);
}
}
}
}
}

View File

@@ -1,140 +1,149 @@
<?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.
*/
namespace Chill\PersonBundle\DependencyInjection;
use DateInterval;
use Exception;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
/**
* This is the class that validates and merges configuration from your app/config files
* This is the class that validates and merges configuration from your app/config files.
*
* To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html#cookbook-bundles-extension-config-class}
*/
class Configuration implements ConfigurationInterface
{
private $validationBirthdateNotAfterInfos = 'The period before today during which'
. ' any birthdate is not allowed. The birthdate is expressed as ISO8601 : '
. 'https://en.wikipedia.org/wiki/ISO_8601#Durations';
private $validationBirthdateNotAfterInfos = "The period before today during which"
. " any birthdate is not allowed. The birthdate is expressed as ISO8601 : "
. "https://en.wikipedia.org/wiki/ISO_8601#Durations";
/**
* {@inheritDoc}
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder('cl_chill_person');
$rootNode = $treeBuilder->getRootNode('cl_chill_person');
$rootNode
->canBeDisabled()
->children()
->arrayNode('validation')
->canBeDisabled()
->children()
->booleanNode('center_required')
->info('Enable a center for each person entity. If disabled, you must provide your own center provider')
->defaultValue(true)
->end()
->scalarNode('birthdate_not_after')
->info($this->validationBirthdateNotAfterInfos)
->defaultValue('P1D')
->validate()
->ifTrue(function($period) {
->canBeDisabled()
->children()
->arrayNode('validation')
->canBeDisabled()
->children()
->booleanNode('center_required')
->info('Enable a center for each person entity. If disabled, you must provide your own center provider')
->defaultValue(true)
->end()
->scalarNode('birthdate_not_after')
->info($this->validationBirthdateNotAfterInfos)
->defaultValue('P1D')
->validate()
->ifTrue(function ($period) {
try {
$interval = new \DateInterval($period);
} catch (\Exception $ex) {
$interval = new DateInterval($period);
} catch (Exception $ex) {
return true;
}
return false;
})
->thenInvalid('Invalid period for birthdate validation : "%s" '
->thenInvalid('Invalid period for birthdate validation : "%s" '
. 'The parameter should match duration as defined by ISO8601 : '
. 'https://en.wikipedia.org/wiki/ISO_8601#Durations')
->end() // birthdate_not_after, parent = children of validation
->end() // children for 'validation', parent = validation
->end() //validation, parent = children of root
->end() // children of root, parent = root
->arrayNode('person_fields')
->canBeDisabled()
->children()
->append($this->addFieldNode('place_of_birth'))
->append($this->addFieldNode('email'))
->append($this->addFieldNode('phonenumber'))
->append($this->addFieldNode('mobilenumber'))
->append($this->addFieldNode('contact_info'))
->append($this->addFieldNode('nationality'))
->append($this->addFieldNode('country_of_birth'))
->append($this->addFieldNode('marital_status'))
->append($this->addFieldNode('civility'))
->append($this->addFieldNode('spoken_languages'))
->append($this->addFieldNode('address'))
->append($this->addFieldNode('accompanying_period'))
->append($this->addFieldNode('memo'))
->append($this->addFieldNode('number_of_children'))
->append($this->addFieldNode('acceptEmail'))
->arrayNode('alt_names')
->defaultValue([])
->arrayPrototype()
->children()
->scalarNode('key')
->isRequired()->cannotBeEmpty()
->end()
->arrayNode('labels')
->children()
->scalarNode('lang')->isRequired()->cannotBeEmpty()
->example('fr')
->end()
->scalarNode('label')->isRequired()->cannotBeEmpty()
->example('Nom de jeune fille')
->end()
->end()
->end()
->end()
->end()
->end()
->end() //children for 'person_fields', parent = array 'person_fields'
->end() // person_fields, parent = children of root
->arrayNode('accompanying_periods_fields')
->canBeDisabled()
->children()
->append($this->addFieldNode('user'))
->append($this->addFieldNode('createdBy'))
->append($this->addFieldNode('step'))
->append($this->addFieldNode('origin'))
->append($this->addFieldNode('intensity'))
->append($this->addFieldNode('scopes'))
->append($this->addFieldNode('requestor'))
->append($this->addFieldNode('anonymous'))
->append($this->addFieldNode('emergency'))
->append($this->addFieldNode('confidential'))
->end() //children for 'accompanying_person_fields', parent = array 'person_fields'
->end() // paccompanying_person_fields, parent = children of root
->booleanNode('allow_multiple_simultaneous_accompanying_periods')
->info('Can we have more than one simultaneous accompanying period in the same time. Default false.')
->defaultValue(false)
->end()
->end() // children of 'root', parent = root
;
->end() // birthdate_not_after, parent = children of validation
->end() // children for 'validation', parent = validation
->end() //validation, parent = children of root
->end() // children of root, parent = root
->arrayNode('person_fields')
->canBeDisabled()
->children()
->append($this->addFieldNode('place_of_birth'))
->append($this->addFieldNode('email'))
->append($this->addFieldNode('phonenumber'))
->append($this->addFieldNode('mobilenumber'))
->append($this->addFieldNode('contact_info'))
->append($this->addFieldNode('nationality'))
->append($this->addFieldNode('country_of_birth'))
->append($this->addFieldNode('marital_status'))
->append($this->addFieldNode('civility'))
->append($this->addFieldNode('spoken_languages'))
->append($this->addFieldNode('address'))
->append($this->addFieldNode('accompanying_period'))
->append($this->addFieldNode('memo'))
->append($this->addFieldNode('number_of_children'))
->append($this->addFieldNode('acceptEmail'))
->arrayNode('alt_names')
->defaultValue([])
->arrayPrototype()
->children()
->scalarNode('key')
->isRequired()->cannotBeEmpty()
->end()
->arrayNode('labels')
->children()
->scalarNode('lang')->isRequired()->cannotBeEmpty()
->example('fr')
->end()
->scalarNode('label')->isRequired()->cannotBeEmpty()
->example('Nom de jeune fille')
->end()
->end()
->end()
->end()
->end()
->end()
->end() //children for 'person_fields', parent = array 'person_fields'
->end() // person_fields, parent = children of root
->arrayNode('accompanying_periods_fields')
->canBeDisabled()
->children()
->append($this->addFieldNode('user'))
->append($this->addFieldNode('createdBy'))
->append($this->addFieldNode('step'))
->append($this->addFieldNode('origin'))
->append($this->addFieldNode('intensity'))
->append($this->addFieldNode('scopes'))
->append($this->addFieldNode('requestor'))
->append($this->addFieldNode('anonymous'))
->append($this->addFieldNode('emergency'))
->append($this->addFieldNode('confidential'))
->end() //children for 'accompanying_person_fields', parent = array 'person_fields'
->end() // paccompanying_person_fields, parent = children of root
->booleanNode('allow_multiple_simultaneous_accompanying_periods')
->info('Can we have more than one simultaneous accompanying period in the same time. Default false.')
->defaultValue(false)
->end()
->end() // children of 'root', parent = root
;
return $treeBuilder;
}
private function addFieldNode($key)
{
$tree = new TreeBuilder($key,'enum');
$tree = new TreeBuilder($key, 'enum');
$node = $tree->getRootNode($key);
switch($key) {
switch ($key) {
case 'accompanying_period':
$info = "If the accompanying periods are shown";
$info = 'If the accompanying periods are shown';
break;
default:
$info = "If the field $key must be shown";
$info = "If the field {$key} must be shown";
break;
}
$node
->values(array('hidden', 'visible'))
->values(['hidden', 'visible'])
->defaultValue('visible')
->info($info)
->end();

View File

@@ -1,20 +1,12 @@
<?php
/*
* Copyright (C) 2017 Champs Libres Cooperative <info@champs-libres.coop>
/**
* Chill is a software for social workers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Doctrine\DQL;
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
@@ -23,70 +15,64 @@ use Doctrine\ORM\Query\Parser;
use Doctrine\ORM\Query\SqlWalker;
/**
*
* USAGE GET_ADDRESS_<part>(person.id, :date, 'postcode') where part
* should be replace by the part of the address.
*
*
* This function return the current address part at the given date, for the
* given person (identified by his id)
*
* The aim of this function is to be used within reports
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* The aim of this function is to be used within reports
*/
abstract class AddressPart extends FunctionNode
{
public $fields = array(
'address_id',
'streetaddress1',
'streetaddress2',
'validfrom',
'postcode_label',
'postcode_code',
'postcode_id',
'country_name',
'country_code',
'country_id'
);
public $fields = [
'address_id',
'streetaddress1',
'streetaddress2',
'validfrom',
'postcode_label',
'postcode_code',
'postcode_id',
'country_name',
'country_code',
'country_id',
];
/**
*
* @var \Doctrine\ORM\Query\AST\Node
*/
private $pid;
/**
*
* @var \Doctrine\ORM\Query\AST\Node
*/
private $date;
/**
*
* @var \Doctrine\ORM\Query\AST\Node
*/
private $part;
/**
* return the part of the address
*
* Should be one value of the "public" amongst
* 'address_id', 'streetaddress1',
* 'streetaddress2', 'validfrom', 'postcode_label', 'postcode_code',
* @var \Doctrine\ORM\Query\AST\Node
*/
private $pid;
/**
* return the part of the address.
*
* Should be one value of the "public" amongst
* 'address_id', 'streetaddress1',
* 'streetaddress2', 'validfrom', 'postcode_label', 'postcode_code',
* 'postcode_id', 'country_name', 'country_code', 'country_id', 'isnoaddress'
*
*
* @return string
*/
abstract public function getPart();
public function getSql(SqlWalker $sqlWalker)
{
return sprintf(
'get_last_address_%s(%s, %s)',
'get_last_address_%s(%s, %s)',
$this->getPart(),
$this->pid->dispatch($sqlWalker),
$this->date->dispatch($sqlWalker)
);
);
}
public function parse(Parser $parser)

View File

@@ -1,29 +1,16 @@
<?php
/*
* Copyright (C) 2017 Champs Libres Cooperative <info@champs-libres.coop>
/**
* Chill is a software for social workers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Doctrine\DQL\AddressPart;
use Chill\PersonBundle\Doctrine\DQL\AddressPart;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class AddressPartAddressId extends AddressPart
{
public function getPart()

View File

@@ -1,29 +1,16 @@
<?php
/*
* Copyright (C) 2017 Champs Libres Cooperative <info@champs-libres.coop>
/**
* Chill is a software for social workers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Doctrine\DQL\AddressPart;
use Chill\PersonBundle\Doctrine\DQL\AddressPart;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class AddressPartCountryCode extends AddressPart
{
public function getPart()

View File

@@ -1,29 +1,16 @@
<?php
/*
* Copyright (C) 2017 Champs Libres Cooperative <info@champs-libres.coop>
/**
* Chill is a software for social workers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Doctrine\DQL\AddressPart;
use Chill\PersonBundle\Doctrine\DQL\AddressPart;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class AddressPartCountryId extends AddressPart
{
public function getPart()

View File

@@ -1,29 +1,16 @@
<?php
/*
* Copyright (C) 2017 Champs Libres Cooperative <info@champs-libres.coop>
/**
* Chill is a software for social workers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Doctrine\DQL\AddressPart;
use Chill\PersonBundle\Doctrine\DQL\AddressPart;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class AddressPartCountryName extends AddressPart
{
public function getPart()

View File

@@ -1,29 +1,16 @@
<?php
/*
* Copyright (C) 2017 Champs Libres Cooperative <info@champs-libres.coop>
/**
* Chill is a software for social workers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Doctrine\DQL\AddressPart;
use Chill\PersonBundle\Doctrine\DQL\AddressPart;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class AddressPartIsNoAddress extends AddressPart
{
public function getPart()

View File

@@ -1,29 +1,16 @@
<?php
/*
* Copyright (C) 2017 Champs Libres Cooperative <info@champs-libres.coop>
/**
* Chill is a software for social workers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Doctrine\DQL\AddressPart;
use Chill\PersonBundle\Doctrine\DQL\AddressPart;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class AddressPartPostCodeCode extends AddressPart
{
public function getPart()

View File

@@ -1,29 +1,16 @@
<?php
/*
* Copyright (C) 2017 Champs Libres Cooperative <info@champs-libres.coop>
/**
* Chill is a software for social workers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Doctrine\DQL\AddressPart;
use Chill\PersonBundle\Doctrine\DQL\AddressPart;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class AddressPartPostCodeId extends AddressPart
{
public function getPart()

View File

@@ -1,29 +1,16 @@
<?php
/*
* Copyright (C) 2017 Champs Libres Cooperative <info@champs-libres.coop>
/**
* Chill is a software for social workers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Doctrine\DQL\AddressPart;
use Chill\PersonBundle\Doctrine\DQL\AddressPart;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class AddressPartPostCodeLabel extends AddressPart
{
public function getPart()

View File

@@ -1,29 +1,16 @@
<?php
/*
* Copyright (C) 2017 Champs Libres Cooperative <info@champs-libres.coop>
/**
* Chill is a software for social workers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Doctrine\DQL\AddressPart;
use Chill\PersonBundle\Doctrine\DQL\AddressPart;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class AddressPartStreetAddress1 extends AddressPart
{
public function getPart()

View File

@@ -1,29 +1,16 @@
<?php
/*
* Copyright (C) 2017 Champs Libres Cooperative <info@champs-libres.coop>
/**
* Chill is a software for social workers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Doctrine\DQL\AddressPart;
use Chill\PersonBundle\Doctrine\DQL\AddressPart;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class AddressPartStreetAddress2 extends AddressPart
{
public function getPart()

View File

@@ -1,29 +1,16 @@
<?php
/*
* Copyright (C) 2017 Champs Libres Cooperative <info@champs-libres.coop>
/**
* Chill is a software for social workers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Doctrine\DQL\AddressPart;
use Chill\PersonBundle\Doctrine\DQL\AddressPart;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class AddressPartValidFrom extends AddressPart
{
public function getPart()

File diff suppressed because it is too large Load Diff

View File

@@ -1,169 +1,50 @@
<?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.
*/
namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\AccompanyingPeriod\SocialIssueConsistency\AccompanyingPeriodLinkedWithSocialIssuesEntityInterface;
use Chill\PersonBundle\Entity\SocialWork\Result;
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
use Chill\PersonBundle\Entity\Person;
use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface;
use Chill\MainBundle\Entity\User;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Entity\SocialWork\Result;
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use DateTimeImmutable;
use DateTimeInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use LogicException;
use Symfony\Component\Serializer\Annotation as Serializer;
use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity
* @ORM\Table(name="chill_person_accompanying_period_work")
* @Serializer\DiscriminatorMap(
* typeProperty="type",
* mapping={
* "accompanying_period_work":AccompanyingPeriodWork::class
* }
* )
*/
/**
* @ORM\Entity
* @ORM\Table(name="chill_person_accompanying_period_work")
* @Serializer\DiscriminatorMap(
* typeProperty="type",
* mapping={
* "accompanying_period_work": AccompanyingPeriodWork::class
* }
* )
*/
class AccompanyingPeriodWork implements TrackCreationInterface, TrackUpdateInterface
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
* @Serializer\Groups({"read"})
*/
private ?int $id;
/**
* @ORM\Column(type="text")
* @Serializer\Groups({"read", "accompanying_period_work:edit"})
*/
private string $note = "";
/**
* @ORM\ManyToOne(targetEntity=AccompanyingPeriod::class)
* @Serializer\Groups({"read"})
*/
private ?AccompanyingPeriod $accompanyingPeriod = null;
/**
* @ORM\ManyToOne(targetEntity=SocialAction::class)
* @Serializer\Groups({"read"})
* @Serializer\Groups({"accompanying_period_work:create"})
*/
private ?SocialAction $socialAction = null;
/**
* @ORM\Column(type="datetime_immutable")
* @Serializer\Groups({"read"})
*/
private ?\DateTimeImmutable $createdAt = null;
/**
* @ORM\ManyToOne(targetEntity=User::class)
* @ORM\JoinColumn(nullable=false)
* @Serializer\Groups({"read"})
*/
private ?User $createdBy = null;
/**
* @ORM\Column(type="datetime_immutable")
* @Serializer\Groups({"read"})
*/
private ?\DateTimeImmutable $updatedAt = null;
/**
* @ORM\ManyToOne(targetEntity=User::class)
* @ORM\JoinColumn(nullable=false)
* @Serializer\Groups({"read"})
*/
private ?User $updatedBy = null;
/**
* @ORM\Column(type="date_immutable")
* @Serializer\Groups({"accompanying_period_work:create"})
* @Serializer\Groups({"accompanying_period_work:edit"})
* @Serializer\Groups({"read"})
*/
private \DateTimeImmutable $startDate;
/**
* @ORM\Column(type="date_immutable", nullable=true, options={"default":null})
* @Serializer\Groups({"accompanying_period_work:create"})
* @Serializer\Groups({"accompanying_period_work:edit"})
* @Serializer\Groups({"read"})
* @Assert\GreaterThan(propertyPath="startDate",
* message="accompanying_course_work.The endDate should be greater than the start date"
* )
*/
private ?\DateTimeImmutable $endDate = null;
/**
* @ORM\ManyToOne(targetEntity=ThirdParty::class)
* @Serializer\Groups({"read"})
* @Serializer\Groups({"accompanying_period_work:edit"})
*
* In schema : traitant
*/
private ?ThirdParty $handlingThierParty = null;
/**
* @ORM\Column(type="boolean")
*/
private bool $createdAutomatically = false;
/**
* @ORM\Column(type="text")
*/
private string $createdAutomaticallyReason = "";
/**
* @ORM\OneToMany(
* targetEntity=AccompanyingPeriodWorkGoal::class,
* mappedBy="accompanyingPeriodWork",
* cascade={"persist"},
* orphanRemoval=true
* )
* @Serializer\Groups({"read"})
* @Serializer\Groups({"accompanying_period_work:edit"})
*/
private Collection $goals;
/**
* @ORM\ManyToMany(targetEntity=Result::class, inversedBy="accompanyingPeriodWorks")
* @ORM\JoinTable(name="chill_person_accompanying_period_work_result")
* @Serializer\Groups({"read"})
* @Serializer\Groups({"accompanying_period_work:edit"})
*/
private Collection $results;
/**
* @ORM\ManyToMany(targetEntity=ThirdParty::class)
* @ORM\JoinTable(name="chill_person_accompanying_period_work_third_party")
*
* In schema : intervenants
* @Serializer\Groups({"read"})
* @Serializer\Groups({"accompanying_period_work:edit"})
*/
private Collection $thirdParties;
/**
*
* @ORM\ManyToMany(targetEntity=Person::class)
* @ORM\JoinTable(name="chill_person_accompanying_period_work_person")
* @Serializer\Groups({"read"})
* @Serializer\Groups({"accompanying_period_work:edit"})
* @Serializer\Groups({"accompanying_period_work:create"})
*/
private Collection $persons;
{
/**
* @ORM\ManyToOne(targetEntity=AccompanyingPeriod::class)
* @Serializer\Groups({"read"})
*/
private ?AccompanyingPeriod $accompanyingPeriod = null;
/**
* @var Collection
* @ORM\OneToMany(
* targetEntity=AccompanyingPeriodWorkEvaluation::class,
* mappedBy="accompanyingPeriodWork",
@@ -171,287 +52,142 @@ use Symfony\Component\Validator\Constraints as Assert;
* orphanRemoval=true
* )
* @Serializer\Groups({"read"})
*
* @internal /!\ the serialization for write evaluations is handled in `AccompanyingPeriodWorkDenormalizer`
*/
private Collection $accompanyingPeriodWorkEvaluations;
public function __construct()
{
$this->goals = new ArrayCollection();
$this->results = new ArrayCollection();
$this->thirdParties = new ArrayCollection();
$this->persons = new ArrayCollection();
$this->accompanyingPeriodWorkEvaluations = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getNote(): ?string
{
return $this->note;
}
public function setNote(string $note): self
{
$this->note = $note;
return $this;
}
public function getAccompanyingPeriod(): ?AccompanyingPeriod
{
return $this->accompanyingPeriod;
}
/**
* Internal: you should use `$accompanyingPeriod->removeWork($work);` or
* `$accompanyingPeriod->addWork($work);`
*/
public function setAccompanyingPeriod(?AccompanyingPeriod $accompanyingPeriod): self
{
if ($this->accompanyingPeriod instanceof AccompanyingPeriod &&
$accompanyingPeriod !== $this->accompanyingPeriod) {
throw new \LogicException("A work cannot change accompanyingPeriod");
}
$this->accompanyingPeriod = $accompanyingPeriod;
return $this;
}
public function getSocialAction(): ?SocialAction
{
return $this->socialAction;
}
public function setSocialAction(?SocialAction $socialAction): self
{
$this->socialAction = $socialAction;
return $this;
}
public function getCreatedAt(): ?\DateTimeImmutable
{
return $this->createdAt;
}
public function setCreatedAt(\DateTimeInterface $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
public function getCreatedBy(): ?User
{
return $this->createdBy;
}
public function setCreatedBy(?User $createdBy): self
{
$this->createdBy = $createdBy;
return $this;
}
public function setUpdatedBy(User $user): TrackUpdateInterface
{
$this->updatedBy = $user;
return $this;
}
public function setUpdatedAt(DateTimeInterface $datetime): TrackUpdateInterface
{
$this->updatedAt = $datetime;
return $this;
}
public function getUpdatedAt(): ?\DateTimeImmutable
{
return $this->updatedAt;
}
public function getUpdatedBy(): ?User
{
return $this->updatedBy;
}
public function getStartDate(): ?\DateTimeInterface
{
return $this->startDate;
}
public function setStartDate(\DateTimeInterface $startDate): self
{
$this->startDate = $startDate;
return $this;
}
public function getEndDate(): ?\DateTimeInterface
{
return $this->endDate;
}
public function setEndDate(?\DateTimeInterface $endDate = null): self
{
$this->endDate = $endDate;
return $this;
}
public function getHandlingThierParty(): ?ThirdParty
{
return $this->handlingThierParty;
}
public function setHandlingThierParty(?ThirdParty $handlingThierParty): self
{
$this->handlingThierParty = $handlingThierParty;
return $this;
}
public function getCreatedAutomatically(): ?bool
{
return $this->createdAutomatically;
}
public function setCreatedAutomatically(bool $createdAutomatically): self
{
$this->createdAutomatically = $createdAutomatically;
return $this;
}
public function getCreatedAutomaticallyReason(): ?string
{
return $this->createdAutomaticallyReason;
}
public function setCreatedAutomaticallyReason(string $createdAutomaticallyReason): self
{
$this->createdAutomaticallyReason = $createdAutomaticallyReason;
return $this;
}
/**
* @return Collection|AccompanyingPeriodWorkGoal[]
*/
public function getGoals(): Collection
{
return $this->goals;
}
public function addGoal(AccompanyingPeriodWorkGoal $goal): self
{
if (!$this->goals->contains($goal)) {
$this->goals[] = $goal;
$goal->setAccompanyingPeriodWork($this);
}
return $this;
}
public function removeGoal(AccompanyingPeriodWorkGoal $goal): self
{
if ($this->goals->removeElement($goal)) {
// set the owning side to null (unless already changed)
if ($goal->getAccompanyingPeriodWork() === $this) {
$goal->setAccompanyingPeriodWork(null);
}
}
return $this;
}
/**
* @return Collection|Result[]
*/
public function getResults(): Collection
{
return $this->results;
}
public function addResult(Result $result): self
{
if (!$this->results->contains($result)) {
$this->results[] = $result;
}
return $this;
}
public function removeResult(Result $result): self
{
$this->results->removeElement($result);
return $this;
}
/**
* @return Collection|ThirdParty[]
*/
public function getThirdParties(): Collection
{
return $this->thirdParties;
}
public function getThirdPartys(): Collection
{
return $this->getThirdParties();
}
public function addThirdParty(ThirdParty $thirdParty): self
{
if (!$this->thirdParties->contains($thirdParty)) {
$this->thirdParties[] = $thirdParty;
}
return $this;
}
public function removeThirdParty(ThirdParty $thirdParty): self
{
$this->thirdParties->removeElement($thirdParty);
return $this;
}
public function getPersons(): Collection
{
return $this->persons;
}
public function addPerson(Person $person): self
{
if (!$this->persons->contains($person)) {
$this->persons[] = $person;
}
return $this;
}
public function removePerson(Person $person): self
{
$this->persons->removeElement($person);
return $this;
}
private Collection $accompanyingPeriodWorkEvaluations;
/**
* @return Collection
* @ORM\Column(type="datetime_immutable")
* @Serializer\Groups({"read"})
*/
public function getAccompanyingPeriodWorkEvaluations()
private ?DateTimeImmutable $createdAt = null;
/**
* @ORM\Column(type="boolean")
*/
private bool $createdAutomatically = false;
/**
* @ORM\Column(type="text")
*/
private string $createdAutomaticallyReason = '';
/**
* @ORM\ManyToOne(targetEntity=User::class)
* @ORM\JoinColumn(nullable=false)
* @Serializer\Groups({"read"})
*/
private ?User $createdBy = null;
/**
* @ORM\Column(type="date_immutable", nullable=true, options={"default": null})
* @Serializer\Groups({"accompanying_period_work:create"})
* @Serializer\Groups({"accompanying_period_work:edit"})
* @Serializer\Groups({"read"})
* @Assert\GreaterThan(propertyPath="startDate",
* message="accompanying_course_work.The endDate should be greater than the start date"
* )
*/
private ?DateTimeImmutable $endDate = null;
/**
* @ORM\OneToMany(
* targetEntity=AccompanyingPeriodWorkGoal::class,
* mappedBy="accompanyingPeriodWork",
* cascade={"persist"},
* orphanRemoval=true
* )
* @Serializer\Groups({"read"})
* @Serializer\Groups({"accompanying_period_work:edit"})
*/
private Collection $goals;
/**
* @ORM\ManyToOne(targetEntity=ThirdParty::class)
* @Serializer\Groups({"read"})
* @Serializer\Groups({"accompanying_period_work:edit"})
*
* In schema : traitant
*/
private ?ThirdParty $handlingThierParty = null;
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
* @Serializer\Groups({"read"})
*/
private ?int $id;
/**
* @ORM\Column(type="text")
* @Serializer\Groups({"read", "accompanying_period_work:edit"})
*/
private string $note = '';
/**
* @ORM\ManyToMany(targetEntity=Person::class)
* @ORM\JoinTable(name="chill_person_accompanying_period_work_person")
* @Serializer\Groups({"read"})
* @Serializer\Groups({"accompanying_period_work:edit"})
* @Serializer\Groups({"accompanying_period_work:create"})
*/
private Collection $persons;
/**
* @ORM\ManyToMany(targetEntity=Result::class, inversedBy="accompanyingPeriodWorks")
* @ORM\JoinTable(name="chill_person_accompanying_period_work_result")
* @Serializer\Groups({"read"})
* @Serializer\Groups({"accompanying_period_work:edit"})
*/
private Collection $results;
/**
* @ORM\ManyToOne(targetEntity=SocialAction::class)
* @Serializer\Groups({"read"})
* @Serializer\Groups({"accompanying_period_work:create"})
*/
private ?SocialAction $socialAction = null;
/**
* @ORM\Column(type="date_immutable")
* @Serializer\Groups({"accompanying_period_work:create"})
* @Serializer\Groups({"accompanying_period_work:edit"})
* @Serializer\Groups({"read"})
*/
private DateTimeImmutable $startDate;
/**
* @ORM\ManyToMany(targetEntity=ThirdParty::class)
* @ORM\JoinTable(name="chill_person_accompanying_period_work_third_party")
*
* In schema : intervenants
* @Serializer\Groups({"read"})
* @Serializer\Groups({"accompanying_period_work:edit"})
*/
private Collection $thirdParties;
/**
* @ORM\Column(type="datetime_immutable")
* @Serializer\Groups({"read"})
*/
private ?DateTimeImmutable $updatedAt = null;
/**
* @ORM\ManyToOne(targetEntity=User::class)
* @ORM\JoinColumn(nullable=false)
* @Serializer\Groups({"read"})
*/
private ?User $updatedBy = null;
public function __construct()
{
return $this->accompanyingPeriodWorkEvaluations;
$this->goals = new ArrayCollection();
$this->results = new ArrayCollection();
$this->thirdParties = new ArrayCollection();
$this->persons = new ArrayCollection();
$this->accompanyingPeriodWorkEvaluations = new ArrayCollection();
}
public function addAccompanyingPeriodWorkEvaluation(AccompanyingPeriodWorkEvaluation $evaluation): self
@@ -464,6 +200,150 @@ use Symfony\Component\Validator\Constraints as Assert;
return $this;
}
public function addGoal(AccompanyingPeriodWorkGoal $goal): self
{
if (!$this->goals->contains($goal)) {
$this->goals[] = $goal;
$goal->setAccompanyingPeriodWork($this);
}
return $this;
}
public function addPerson(Person $person): self
{
if (!$this->persons->contains($person)) {
$this->persons[] = $person;
}
return $this;
}
public function addResult(Result $result): self
{
if (!$this->results->contains($result)) {
$this->results[] = $result;
}
return $this;
}
public function addThirdParty(ThirdParty $thirdParty): self
{
if (!$this->thirdParties->contains($thirdParty)) {
$this->thirdParties[] = $thirdParty;
}
return $this;
}
public function getAccompanyingPeriod(): ?AccompanyingPeriod
{
return $this->accompanyingPeriod;
}
/**
* @return Collection
*/
public function getAccompanyingPeriodWorkEvaluations()
{
return $this->accompanyingPeriodWorkEvaluations;
}
public function getCreatedAt(): ?DateTimeImmutable
{
return $this->createdAt;
}
public function getCreatedAutomatically(): ?bool
{
return $this->createdAutomatically;
}
public function getCreatedAutomaticallyReason(): ?string
{
return $this->createdAutomaticallyReason;
}
public function getCreatedBy(): ?User
{
return $this->createdBy;
}
public function getEndDate(): ?DateTimeInterface
{
return $this->endDate;
}
/**
* @return AccompanyingPeriodWorkGoal[]|Collection
*/
public function getGoals(): Collection
{
return $this->goals;
}
public function getHandlingThierParty(): ?ThirdParty
{
return $this->handlingThierParty;
}
public function getId(): ?int
{
return $this->id;
}
public function getNote(): ?string
{
return $this->note;
}
public function getPersons(): Collection
{
return $this->persons;
}
/**
* @return Collection|Result[]
*/
public function getResults(): Collection
{
return $this->results;
}
public function getSocialAction(): ?SocialAction
{
return $this->socialAction;
}
public function getStartDate(): ?DateTimeInterface
{
return $this->startDate;
}
/**
* @return Collection|ThirdParty[]
*/
public function getThirdParties(): Collection
{
return $this->thirdParties;
}
public function getThirdPartys(): Collection
{
return $this->getThirdParties();
}
public function getUpdatedAt(): ?DateTimeImmutable
{
return $this->updatedAt;
}
public function getUpdatedBy(): ?User
{
return $this->updatedBy;
}
public function removeAccompanyingPeriodWorkEvaluation(AccompanyingPeriodWorkEvaluation $evaluation): self
{
$this->accompanyingPeriodWorkEvaluations
@@ -472,4 +352,130 @@ use Symfony\Component\Validator\Constraints as Assert;
return $this;
}
public function removeGoal(AccompanyingPeriodWorkGoal $goal): self
{
if ($this->goals->removeElement($goal)) {
// set the owning side to null (unless already changed)
if ($goal->getAccompanyingPeriodWork() === $this) {
$goal->setAccompanyingPeriodWork(null);
}
}
return $this;
}
public function removePerson(Person $person): self
{
$this->persons->removeElement($person);
return $this;
}
public function removeResult(Result $result): self
{
$this->results->removeElement($result);
return $this;
}
public function removeThirdParty(ThirdParty $thirdParty): self
{
$this->thirdParties->removeElement($thirdParty);
return $this;
}
/**
* Internal: you should use `$accompanyingPeriod->removeWork($work);` or
* `$accompanyingPeriod->addWork($work);`.
*/
public function setAccompanyingPeriod(?AccompanyingPeriod $accompanyingPeriod): self
{
if ($this->accompanyingPeriod instanceof AccompanyingPeriod
&& $accompanyingPeriod !== $this->accompanyingPeriod) {
throw new LogicException('A work cannot change accompanyingPeriod');
}
$this->accompanyingPeriod = $accompanyingPeriod;
return $this;
}
public function setCreatedAt(DateTimeInterface $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
public function setCreatedAutomatically(bool $createdAutomatically): self
{
$this->createdAutomatically = $createdAutomatically;
return $this;
}
public function setCreatedAutomaticallyReason(string $createdAutomaticallyReason): self
{
$this->createdAutomaticallyReason = $createdAutomaticallyReason;
return $this;
}
public function setCreatedBy(?User $createdBy): self
{
$this->createdBy = $createdBy;
return $this;
}
public function setEndDate(?DateTimeInterface $endDate = null): self
{
$this->endDate = $endDate;
return $this;
}
public function setHandlingThierParty(?ThirdParty $handlingThierParty): self
{
$this->handlingThierParty = $handlingThierParty;
return $this;
}
public function setNote(string $note): self
{
$this->note = $note;
return $this;
}
public function setSocialAction(?SocialAction $socialAction): self
{
$this->socialAction = $socialAction;
return $this;
}
public function setStartDate(DateTimeInterface $startDate): self
{
$this->startDate = $startDate;
return $this;
}
public function setUpdatedAt(DateTimeInterface $datetime): TrackUpdateInterface
{
$this->updatedAt = $datetime;
return $this;
}
public function setUpdatedBy(User $user): TrackUpdateInterface
{
$this->updatedBy = $user;
return $this;
}
}

View File

@@ -1,36 +1,37 @@
<?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.
*/
namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface;
use Chill\MainBundle\Entity\User;
use Chill\PersonBundle\Entity\SocialWork\Evaluation;
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument;
use DateInterval;
use DateTimeImmutable;
use DateTimeInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use LogicException;
use RuntimeException;
use Symfony\Component\Serializer\Annotation as Serializer;
/**
* @ORM\Entity
* @ORM\Table("chill_person_accompanying_period_work_evaluation")
* @Serializer\DiscriminatorMap(typeProperty="type", mapping={
* "accompanying_period_work_evaluation"=AccompanyingPeriodWorkEvaluation::class,
* })
* "accompanying_period_work_evaluation": AccompanyingPeriodWorkEvaluation::class,
* })
*/
class AccompanyingPeriodWorkEvaluation implements TrackUpdateInterface, TrackCreationInterface
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
* @Serializer\Groups({"read"})
*/
private ?int $id = null;
/**
* @ORM\ManyToOne(
* targetEntity=AccompanyingPeriodWork::class,
@@ -40,47 +41,6 @@ class AccompanyingPeriodWorkEvaluation implements TrackUpdateInterface, TrackCre
private ?AccompanyingPeriodWork $accompanyingPeriodWork = null;
/**
* @ORM\ManyToOne(
* targetEntity=Evaluation::class
* )
* @Serializer\Groups({"read"})
* @Serializer\Groups({"accompanying_period_work_evaluation:create"})
*/
private ?Evaluation $evaluation = null;
/**
* @ORM\Column(type="date_immutable", nullable=true, options={"default": null})
* @Serializer\Groups({"read"})
* @Serializer\Groups({"write"})
* @Serializer\Groups({"accompanying_period_work_evaluation:create"})
*/
private ?DateTimeImmutable $startDate = null;
/**
* @ORM\Column(type="date_immutable", nullable=true, options={"default": null})
* @Serializer\Groups({"read"})
* @Serializer\Groups({"write"})
* @Serializer\Groups({"accompanying_period_work_evaluation:create"})
*/
private ?DateTimeImmutable $endDate = null;
/**
* @ORM\Column(type="date_immutable", nullable=true, options={"default": null})
* @Serializer\Groups({"read"})
* @Serializer\Groups({"accompanying_period_work_evaluation:create"})
*/
private ?DateTimeImmutable $maxDate = null;
/**
* @ORM\Column(type="dateinterval", nullable=true, options={"default": null})
* @Serializer\Groups({"read"})
* @Serializer\Groups({"write"})
* @Serializer\Groups({"accompanying_period_work_evaluation:create"})
*/
private ?DateInterval $warningInterval = null;
/**
* @var string
* @ORM\Column(type="text", nullable=false, options={"default": ""})
* @Serializer\Groups({"read"})
* @Serializer\Groups({"write"})
@@ -88,14 +48,6 @@ class AccompanyingPeriodWorkEvaluation implements TrackUpdateInterface, TrackCre
*/
private string $comment = '';
/**
* @ORM\ManyToOne(
* targetEntity=User::class
* )
* @Serializer\Groups({"read"})
*/
private ?User $createdBy = null;
/**
* @ORM\Column(type="date_immutable", nullable=true, options={"default": null})
* @Serializer\Groups({"read"})
@@ -108,25 +60,43 @@ class AccompanyingPeriodWorkEvaluation implements TrackUpdateInterface, TrackCre
* )
* @Serializer\Groups({"read"})
*/
private ?User $updatedBy = null;
private ?User $createdBy = null;
/**
* @ORM\Column(type="date_immutable", nullable=true, options={"default": null})
* @Serializer\Groups({"read"})
*/
private ?DateTimeImmutable $updatedAt = null;
/**
* @var Collection
* @ORM\OneToMany(
* targetEntity=AccompanyingPeriodWorkEvaluationDocument::class,
* mappedBy="accompanyingPeriodWorkEvaluation",
* cascade={"remove"}
* )
* )
* @Serializer\Groups({"read"})
*/
private Collection $documents;
/**
* @ORM\Column(type="date_immutable", nullable=true, options={"default": null})
* @Serializer\Groups({"read"})
* @Serializer\Groups({"write"})
* @Serializer\Groups({"accompanying_period_work_evaluation:create"})
*/
private ?DateTimeImmutable $endDate = null;
/**
* @ORM\ManyToOne(
* targetEntity=Evaluation::class
* )
* @Serializer\Groups({"read"})
* @Serializer\Groups({"accompanying_period_work_evaluation:create"})
*/
private ?Evaluation $evaluation = null;
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
* @Serializer\Groups({"read"})
*/
private ?int $id = null;
/**
* This is a workaround for client, to allow them to assign arbitrary data
* dedicated to their job.
@@ -139,251 +109,51 @@ class AccompanyingPeriodWorkEvaluation implements TrackUpdateInterface, TrackCre
* @Serializer\Groups({"accompanying_period_work_evaluation:create"})
*
* @var mixed
*
*/
private $key = null;
private $key;
/**
* @ORM\Column(type="date_immutable", nullable=true, options={"default": null})
* @Serializer\Groups({"read"})
* @Serializer\Groups({"accompanying_period_work_evaluation:create"})
*/
private ?DateTimeImmutable $maxDate = null;
/**
* @ORM\Column(type="date_immutable", nullable=true, options={"default": null})
* @Serializer\Groups({"read"})
* @Serializer\Groups({"write"})
* @Serializer\Groups({"accompanying_period_work_evaluation:create"})
*/
private ?DateTimeImmutable $startDate = null;
/**
* @ORM\Column(type="date_immutable", nullable=true, options={"default": null})
* @Serializer\Groups({"read"})
*/
private ?DateTimeImmutable $updatedAt = null;
/**
* @ORM\ManyToOne(
* targetEntity=User::class
* )
* @Serializer\Groups({"read"})
*/
private ?User $updatedBy = null;
/**
* @ORM\Column(type="dateinterval", nullable=true, options={"default": null})
* @Serializer\Groups({"read"})
* @Serializer\Groups({"write"})
* @Serializer\Groups({"accompanying_period_work_evaluation:create"})
*/
private ?DateInterval $warningInterval = null;
public function __construct()
{
$this->documents = new ArrayCollection();
}
/**
* @return int|null
*/
public function getId(): ?int
{
return $this->id;
}
/**
* @return AccompanyingPeriodWork|null
*/
public function getAccompanyingPeriodWork(): ?AccompanyingPeriodWork
{
return $this->accompanyingPeriodWork;
}
/**
* @param AccompanyingPeriodWork|null $accompanyingPeriodWork
* @return AccompanyingPeriodWorkEvaluation
*/
public function setAccompanyingPeriodWork(?AccompanyingPeriodWork $accompanyingPeriodWork): AccompanyingPeriodWorkEvaluation
{
if (
$accompanyingPeriodWork instanceof AccompanyingPeriodWork
&& $this->accompanyingPeriodWork instanceof AccompanyingPeriodWork
&& $this->accompanyingPeriodWork->getId() !== $accompanyingPeriodWork->getId()) {
throw new \RuntimeException("Changing the ".
"accompanyingPeriodWork is not allowed");
}
$this->accompanyingPeriodWork = $accompanyingPeriodWork;
return $this;
}
/**
* @return Evaluation|null
*/
public function getEvaluation(): ?Evaluation
{
return $this->evaluation;
}
/**
* @param Evaluation|null $evaluation
* @return AccompanyingPeriodWorkEvaluation
*/
public function setEvaluation(?Evaluation $evaluation): AccompanyingPeriodWorkEvaluation
{
if (
($evaluation instanceof Evaluation
&& $this->evaluation instanceof Evaluation
&& $evaluation->getId() !== $this->evaluation->getId())
||
($this->evaluation instanceof Evaluation
&& null === $evaluation)
) {
$cl = AccompanyingPeriodWorkEvaluation::class;
throw new \LogicException("once set, an $cl cannot
change or remove the linked Evaluation::class");
}
$this->evaluation = $evaluation;
return $this;
}
/**
* @return DateTimeImmutable|null
*/
public function getStartDate(): ?DateTimeImmutable
{
return $this->startDate;
}
/**
* @param DateTimeImmutable|null $startDate
* @return AccompanyingPeriodWorkEvaluation
*/
public function setStartDate(?DateTimeImmutable $startDate): AccompanyingPeriodWorkEvaluation
{
$this->startDate = $startDate;
return $this;
}
/**
* @return DateTimeImmutable|null
*/
public function getEndDate(): ?DateTimeImmutable
{
return $this->endDate;
}
/**
* @param DateTimeImmutable|null $endDate
* @return AccompanyingPeriodWorkEvaluation
*/
public function setEndDate(?DateTimeImmutable $endDate): AccompanyingPeriodWorkEvaluation
{
$this->endDate = $endDate;
return $this;
}
/**
* @return DateTimeImmutable|null
*/
public function getMaxDate(): ?DateTimeImmutable
{
return $this->maxDate;
}
/**
* @param DateTimeImmutable|null $maxDate
* @return AccompanyingPeriodWorkEvaluation
*/
public function setMaxDate(?DateTimeImmutable $maxDate): AccompanyingPeriodWorkEvaluation
{
$this->maxDate = $maxDate;
return $this;
}
/**
* @return DateInterval|null
*/
public function getWarningInterval(): ?DateInterval
{
return $this->warningInterval;
}
/**
* @param DateInterval|null $warningInterval
* @return AccompanyingPeriodWorkEvaluation
*/
public function setWarningInterval(?DateInterval $warningInterval): AccompanyingPeriodWorkEvaluation
{
$this->warningInterval = $warningInterval;
return $this;
}
/**
* @return string
*/
public function getComment(): string
{
return $this->comment;
}
/**
* @param string $comment
* @return AccompanyingPeriodWorkEvaluation
*/
public function setComment(string $comment): AccompanyingPeriodWorkEvaluation
{
$this->comment = $comment;
return $this;
}
/**
* @return User|null
*/
public function getCreatedBy(): ?User
{
return $this->createdBy;
}
/**
* @param User|null $createdBy
* @return AccompanyingPeriodWorkEvaluation
*/
public function setCreatedBy(?User $createdBy): AccompanyingPeriodWorkEvaluation
{
$this->createdBy = $createdBy;
return $this;
}
/**
* @return DateTimeImmutable|null
*/
public function getCreatedAt(): ?DateTimeImmutable
{
return $this->createdAt;
}
/**
* @param DateTimeImmutable|null $createdAt
* @return AccompanyingPeriodWorkEvaluation
*/
public function setCreatedAt(\DateTimeInterface $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
/**
* @return User|null
*/
public function getUpdatedBy(): ?User
{
return $this->updatedBy;
}
/**
* @param User|null $updatedBy
* @return AccompanyingPeriodWorkEvaluation
*/
public function setUpdatedBy(?User $updatedBy): AccompanyingPeriodWorkEvaluation
{
$this->updatedBy = $updatedBy;
return $this;
}
/**
* @return DateTimeImmutable|null
*/
public function getUpdatedAt(): ?DateTimeImmutable
{
return $this->updatedAt;
}
/**
* @param DateTimeImmutable|null $updatedAt
* @return AccompanyingPeriodWorkEvaluation
*/
public function setUpdatedAt(\DateTimeInterface $updatedAt): self
{
$this->updatedAt = $updatedAt;
return $this;
}
/**
* @return Collection
*/
public function getDocuments()
{
return $this->documents;
}
public function addDocument(AccompanyingPeriodWorkEvaluationDocument $document): self
{
if (!$this->documents->contains($document)) {
@@ -394,14 +164,51 @@ class AccompanyingPeriodWorkEvaluation implements TrackUpdateInterface, TrackCre
return $this;
}
public function removeDocument(AccompanyingPeriodWorkEvaluationDocument $document): self
public function getAccompanyingPeriodWork(): ?AccompanyingPeriodWork
{
$this->documents->removeElement($document);
return $this;
return $this->accompanyingPeriodWork;
}
public function getComment(): string
{
return $this->comment;
}
public function getCreatedAt(): ?DateTimeImmutable
{
return $this->createdAt;
}
public function getCreatedBy(): ?User
{
return $this->createdBy;
}
/**
* Arbitrary data, used for client
* @return Collection
*/
public function getDocuments()
{
return $this->documents;
}
public function getEndDate(): ?DateTimeImmutable
{
return $this->endDate;
}
public function getEvaluation(): ?Evaluation
{
return $this->evaluation;
}
public function getId(): ?int
{
return $this->id;
}
/**
* Arbitrary data, used for client.
*
* @return mixed
*/
@@ -410,10 +217,111 @@ class AccompanyingPeriodWorkEvaluation implements TrackUpdateInterface, TrackCre
return $this->key;
}
public function getMaxDate(): ?DateTimeImmutable
{
return $this->maxDate;
}
public function getStartDate(): ?DateTimeImmutable
{
return $this->startDate;
}
public function getUpdatedAt(): ?DateTimeImmutable
{
return $this->updatedAt;
}
public function getUpdatedBy(): ?User
{
return $this->updatedBy;
}
public function getWarningInterval(): ?DateInterval
{
return $this->warningInterval;
}
public function removeDocument(AccompanyingPeriodWorkEvaluationDocument $document): self
{
$this->documents->removeElement($document);
return $this;
}
public function setAccompanyingPeriodWork(?AccompanyingPeriodWork $accompanyingPeriodWork): AccompanyingPeriodWorkEvaluation
{
if (
$accompanyingPeriodWork instanceof AccompanyingPeriodWork
&& $this->accompanyingPeriodWork instanceof AccompanyingPeriodWork
&& $this->accompanyingPeriodWork->getId() !== $accompanyingPeriodWork->getId()) {
throw new RuntimeException('Changing the ' .
'accompanyingPeriodWork is not allowed');
}
$this->accompanyingPeriodWork = $accompanyingPeriodWork;
return $this;
}
public function setComment(string $comment): AccompanyingPeriodWorkEvaluation
{
$this->comment = $comment;
return $this;
}
/**
* Arbitrary data, used for client
* @param DateTimeImmutable|null $createdAt
*
* @return AccompanyingPeriodWorkEvaluation
*/
public function setCreatedAt(DateTimeInterface $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
public function setCreatedBy(?User $createdBy): AccompanyingPeriodWorkEvaluation
{
$this->createdBy = $createdBy;
return $this;
}
public function setEndDate(?DateTimeImmutable $endDate): AccompanyingPeriodWorkEvaluation
{
$this->endDate = $endDate;
return $this;
}
public function setEvaluation(?Evaluation $evaluation): AccompanyingPeriodWorkEvaluation
{
if (
($evaluation instanceof Evaluation
&& $this->evaluation instanceof Evaluation
&& $evaluation->getId() !== $this->evaluation->getId())
|| ($this->evaluation instanceof Evaluation
&& null === $evaluation)
) {
$cl = AccompanyingPeriodWorkEvaluation::class;
throw new LogicException("once set, an {$cl} cannot
change or remove the linked Evaluation::class");
}
$this->evaluation = $evaluation;
return $this;
}
/**
* Arbitrary data, used for client.
*
* @param mixed $key
*
* @return AccompanyingPeriodWorkEvaluation
*/
public function setKey($key): self
@@ -422,4 +330,44 @@ class AccompanyingPeriodWorkEvaluation implements TrackUpdateInterface, TrackCre
return $this;
}
public function setMaxDate(?DateTimeImmutable $maxDate): AccompanyingPeriodWorkEvaluation
{
$this->maxDate = $maxDate;
return $this;
}
public function setStartDate(?DateTimeImmutable $startDate): AccompanyingPeriodWorkEvaluation
{
$this->startDate = $startDate;
return $this;
}
/**
* @param DateTimeImmutable|null $updatedAt
*
* @return AccompanyingPeriodWorkEvaluation
*/
public function setUpdatedAt(DateTimeInterface $updatedAt): self
{
$this->updatedAt = $updatedAt;
return $this;
}
public function setUpdatedBy(?User $updatedBy): AccompanyingPeriodWorkEvaluation
{
$this->updatedBy = $updatedBy;
return $this;
}
public function setWarningInterval(?DateInterval $warningInterval): AccompanyingPeriodWorkEvaluation
{
$this->warningInterval = $warningInterval;
return $this;
}
}

View File

@@ -1,5 +1,12 @@
<?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.
*/
namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\DocGeneratorBundle\Entity\DocGeneratorTemplate;
@@ -7,32 +14,21 @@ use Chill\DocStoreBundle\Entity\StoredObject;
use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface;
use Chill\MainBundle\Entity\User;
use DateTimeInterface;
use Doctrine\ORM\Mapping as ORM;
use RuntimeException;
use Symfony\Component\Serializer\Annotation as Serializer;
/**
* @ORM\Entity
* @ORM\Table("chill_person_accompanying_period_work_evaluation_document")
* @Serializer\DiscriminatorMap(typeProperty="type", mapping={
* "accompanying_period_work_evaluation_document"=AccompanyingPeriodWorkEvaluationDocument::class
* })
* "accompanying_period_work_evaluation_document": AccompanyingPeriodWorkEvaluationDocument::class
* })
*/
class AccompanyingPeriodWorkEvaluationDocument implements \Chill\MainBundle\Doctrine\Model\TrackCreationInterface, \Chill\MainBundle\Doctrine\Model\TrackUpdateInterface
{
/**
* @var int|null
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*
* @internal the default name exceeds 64 characters, we must set manually:
* @ORM\SequenceGenerator(sequenceName="chill_person_social_work_eval_doc_id_seq", allocationSize=1, initialValue=1000)
* @Serializer\Groups({"read"})
*/
private ?int $id;
/**
* @var AccompanyingPeriodWorkEvaluation|null
* @ORM\ManyToOne(
* targetEntity=AccompanyingPeriodWorkEvaluation::class,
* inversedBy="documents"
@@ -40,14 +36,6 @@ class AccompanyingPeriodWorkEvaluationDocument implements \Chill\MainBundle\Doct
*/
private ?AccompanyingPeriodWorkEvaluation $accompanyingPeriodWorkEvaluation = null;
/**
* @ORM\ManyToOne(
* targetEntity=User::class
* )
* @Serializer\Groups({"read"})
*/
private ?User $createdBy = null;
/**
* @ORM\Column(type="date_immutable", nullable=true, options={"default": null})
* @Serializer\Groups({"read"})
@@ -60,21 +48,26 @@ class AccompanyingPeriodWorkEvaluationDocument implements \Chill\MainBundle\Doct
* )
* @Serializer\Groups({"read"})
*/
private ?User $updatedBy = null;
private ?User $createdBy = null;
/**
* @ORM\Column(type="date_immutable", nullable=true, options={"default": null})
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*
* @internal the default name exceeds 64 characters, we must set manually:
* @ORM\SequenceGenerator(sequenceName="chill_person_social_work_eval_doc_id_seq", allocationSize=1, initialValue=1000)
* @Serializer\Groups({"read"})
*/
private ?\DateTimeImmutable $updatedAt = null;
private ?int $id;
/**
* @ORM\ManyToOne(
* targetEntity=StoredObject::class,
* cascade={"remove"},
* )
* @ORM\ManyToOne(
* targetEntity=StoredObject::class,
* cascade={"remove"},
* )
* @Serializer\Groups({"read"})
*/
*/
private ?StoredObject $storedObject = null;
/**
@@ -86,17 +79,65 @@ class AccompanyingPeriodWorkEvaluationDocument implements \Chill\MainBundle\Doct
private ?DocGeneratorTemplate $template = null;
/**
* @return AccompanyingPeriodWorkEvaluation|null
* @ORM\Column(type="date_immutable", nullable=true, options={"default": null})
* @Serializer\Groups({"read"})
*/
private ?\DateTimeImmutable $updatedAt = null;
/**
* @ORM\ManyToOne(
* targetEntity=User::class
* )
* @Serializer\Groups({"read"})
*/
private ?User $updatedBy = null;
public function getAccompanyingPeriodWorkEvaluation(): ?AccompanyingPeriodWorkEvaluation
{
return $this->accompanyingPeriodWorkEvaluation;
}
/**
* @param AccompanyingPeriodWorkEvaluation|null $accompanyingPeriodWorkEvaluation
* @return AccompanyingPeriodWorkEvaluationDocument
* @return \DateTimeImmutable|null
*/
public function getCreatedAt(): ?DateTimeInterface
{
return $this->createdAt;
}
public function getCreatedBy(): ?User
{
return $this->createdBy;
}
public function getId(): ?int
{
return $this->id;
}
public function getStoredObject(): ?StoredObject
{
return $this->storedObject;
}
public function getTemplate(): ?DocGeneratorTemplate
{
return $this->template;
}
/**
* @return DateTimeImmutable|null
*/
public function getUpdatedAt(): ?DateTimeInterface
{
return $this->updatedAt;
}
public function getUpdatedBy(): ?User
{
return $this->updatedBy;
}
public function setAccompanyingPeriodWorkEvaluation(?AccompanyingPeriodWorkEvaluation $accompanyingPeriodWorkEvaluation): AccompanyingPeriodWorkEvaluationDocument
{
// if an evaluation is already associated, we cannot change the association (removing the association,
@@ -104,111 +145,53 @@ class AccompanyingPeriodWorkEvaluationDocument implements \Chill\MainBundle\Doct
if ($this->accompanyingPeriodWorkEvaluation instanceof AccompanyingPeriodWorkEvaluation
&& $accompanyingPeriodWorkEvaluation instanceof AccompanyingPeriodWorkEvaluation) {
if ($this->accompanyingPeriodWorkEvaluation !== $accompanyingPeriodWorkEvaluation) {
throw new \RuntimeException("It is not allowed to change the evaluation for a document");
throw new RuntimeException('It is not allowed to change the evaluation for a document');
}
}
$this->accompanyingPeriodWorkEvaluation = $accompanyingPeriodWorkEvaluation;
return $this;
}
/**
* @return StoredObject|null
*/
public function getStoredObject(): ?StoredObject
public function setCreatedAt(DateTimeInterface $datetime): TrackCreationInterface
{
return $this->storedObject;
$this->createdAt = $datetime;
return $this;
}
public function setCreatedBy(User $user): TrackCreationInterface
{
$this->createdBy = $user;
return $this;
}
/**
* @param StoredObject|null $storedObject
* @return AccompanyingPeriodWorkEvaluationDocument
*/
public function setStoredObject(?StoredObject $storedObject): AccompanyingPeriodWorkEvaluationDocument
{
$this->storedObject = $storedObject;
return $this;
}
public function setCreatedBy(User $user): \Chill\MainBundle\Doctrine\Model\TrackCreationInterface
{
$this->createdBy = $user;
return $this;
}
public function setCreatedAt(\DateTimeInterface $datetime): \Chill\MainBundle\Doctrine\Model\TrackCreationInterface
{
$this->createdAt = $datetime;
return $this;
}
public function setUpdatedBy(User $user): \Chill\MainBundle\Doctrine\Model\TrackUpdateInterface
{
$this->updatedBy = $user;
return $this;
}
public function setUpdatedAt(\DateTimeInterface $datetime): \Chill\MainBundle\Doctrine\Model\TrackUpdateInterface
{
$this->updatedAt = $datetime;
return $this;
}
/**
* @return int|null
*/
public function getId(): ?int
{
return $this->id;
}
/**
* @return User|null
*/
public function getCreatedBy(): ?User
{
return $this->createdBy;
}
/**
* @return \DateTimeImmutable|null
*/
public function getCreatedAt(): ?\DateTimeInterface
{
return $this->createdAt;
}
/**
* @return User|null
*/
public function getUpdatedBy(): ?User
{
return $this->updatedBy;
}
/**
* @return DateTimeImmutable|null
*/
public function getUpdatedAt(): ?\DateTimeInterface
{
return $this->updatedAt;
}
/**
* @return DocGeneratorTemplate|null
*/
public function getTemplate(): ?DocGeneratorTemplate
{
return $this->template;
}
/**
* @param DocGeneratorTemplate|null $template
* @return AccompanyingPeriodWorkEvaluationDocument
*/
public function setTemplate(?DocGeneratorTemplate $template): AccompanyingPeriodWorkEvaluationDocument
{
$this->template = $template;
return $this;
}
public function setUpdatedAt(DateTimeInterface $datetime): TrackUpdateInterface
{
$this->updatedAt = $datetime;
return $this;
}
public function setUpdatedBy(User $user): TrackUpdateInterface
{
$this->updatedBy = $user;
return $this;
}
}

View File

@@ -1,5 +1,12 @@
<?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.
*/
namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\SocialWork\Goal;
@@ -7,20 +14,33 @@ use Chill\PersonBundle\Entity\SocialWork\Result;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use LogicException;
use Symfony\Component\Serializer\Annotation as Serializer;
/**
* @ORM\Entity
* @ORM\Table(name="chill_person_accompanying_period_work_goal")
* @Serializer\DiscriminatorMap(
* typeProperty="type",
* mapping={
* "accompanying_period_work_goal":AccompanyingPeriodWorkGoal::class
* }
* )
* typeProperty="type",
* mapping={
* "accompanying_period_work_goal": AccompanyingPeriodWorkGoal::class
* }
* )
*/
class AccompanyingPeriodWorkGoal
{
/**
* @ORM\ManyToOne(targetEntity=AccompanyingPeriodWork::class, inversedBy="goals")
*/
private $accompanyingPeriodWork;
/**
* @ORM\ManyToOne(targetEntity=Goal::class)
* @Serializer\Groups({"accompanying_period_work:edit"})
* @Serializer\Groups({"read"})
*/
private $goal;
/**
* @ORM\Id
* @ORM\GeneratedValue
@@ -36,18 +56,6 @@ class AccompanyingPeriodWorkGoal
*/
private $note;
/**
* @ORM\ManyToOne(targetEntity=AccompanyingPeriodWork::class, inversedBy="goals")
*/
private $accompanyingPeriodWork;
/**
* @ORM\ManyToOne(targetEntity=Goal::class)
* @Serializer\Groups({"accompanying_period_work:edit"})
* @Serializer\Groups({"read"})
*/
private $goal;
/**
* @ORM\ManyToMany(targetEntity=Result::class, inversedBy="accompanyingPeriodWorkGoals")
* @ORM\JoinTable(name="chill_person_accompanying_period_work_goal_result")
@@ -61,6 +69,25 @@ class AccompanyingPeriodWorkGoal
$this->results = new ArrayCollection();
}
public function addResult(Result $result): self
{
if (!$this->results->contains($result)) {
$this->results[] = $result;
}
return $this;
}
public function getAccompanyingPeriodWork(): ?AccompanyingPeriodWork
{
return $this->accompanyingPeriodWork;
}
public function getGoal(): ?Goal
{
return $this->goal;
}
public function getId(): ?int
{
return $this->id;
@@ -71,25 +98,28 @@ class AccompanyingPeriodWorkGoal
return $this->note;
}
public function setNote(string $note): self
/**
* @return Collection|Result[]
*/
public function getResults(): Collection
{
$this->note = $note;
return $this;
return $this->results;
}
public function getAccompanyingPeriodWork(): ?AccompanyingPeriodWork
public function removeResult(Result $result): self
{
return $this->accompanyingPeriodWork;
$this->results->removeElement($result);
return $this;
}
public function setAccompanyingPeriodWork(?AccompanyingPeriodWork $accompanyingPeriodWork): self
{
if ($this->accompanyingPeriodWork instanceof AccompanyingPeriodWork
&& $accompanyingPeriodWork !== $this->accompanyingPeriodWork
&& $accompanyingPeriodWork !== null
&& null !== $accompanyingPeriodWork
) {
throw new \LogicException("Change accompanying period work is not allowed");
throw new LogicException('Change accompanying period work is not allowed');
}
$this->accompanyingPeriodWork = $accompanyingPeriodWork;
@@ -97,11 +127,6 @@ class AccompanyingPeriodWorkGoal
return $this;
}
public function getGoal(): ?Goal
{
return $this->goal;
}
public function setGoal(?Goal $goal): self
{
$this->goal = $goal;
@@ -109,26 +134,9 @@ class AccompanyingPeriodWorkGoal
return $this;
}
/**
* @return Collection|Result[]
*/
public function getResults(): Collection
public function setNote(string $note): self
{
return $this->results;
}
public function addResult(Result $result): self
{
if (!$this->results->contains($result)) {
$this->results[] = $result;
}
return $this;
}
public function removeResult(Result $result): self
{
$this->results->removeElement($result);
$this->note = $note;
return $this;
}

View File

@@ -1,33 +1,20 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2014-2021, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* ClosingMotive give an explanation why we closed the Accompanying period
* ClosingMotive give an explanation why we closed the Accompanying period.
*
* @ORM\Entity
* @ORM\Table(name="chill_person_accompanying_period_closingmotive")
@@ -35,7 +22,25 @@ use Doctrine\Common\Collections\ArrayCollection;
class ClosingMotive
{
/**
* @var integer
* @var bool
*
* @ORM\Column(type="boolean")
*/
private $active = true;
/**
* Child Accompanying periods.
*
* @var Collection
*
* @ORM\OneToMany(
* targetEntity="Chill\PersonBundle\Entity\AccompanyingPeriod\ClosingMotive",
* mappedBy="parent")
*/
private $children;
/**
* @var int
*
* @ORM\Id
* @ORM\Column(name="id", type="integer")
@@ -49,41 +54,23 @@ class ClosingMotive
* @ORM\Column(type="json")
*/
private $name;
/**
* @var boolean
*
* @ORM\Column(type="boolean")
*/
private $active = true;
/**
* @var self
*
* @ORM\ManyToOne(
* targetEntity="Chill\PersonBundle\Entity\AccompanyingPeriod\ClosingMotive",
* inversedBy="children")
*/
private $parent = null;
/**
* Child Accompanying periods
* @var Collection
*
* @ORM\OneToMany(
* targetEntity="Chill\PersonBundle\Entity\AccompanyingPeriod\ClosingMotive",
* mappedBy="parent")
*/
private $children;
/**
* @var float
*
* @ORM\Column(type="float")
*/
private $ordering = 0.0;
/**
* @var self
*
* @ORM\ManyToOne(
* targetEntity="Chill\PersonBundle\Entity\AccompanyingPeriod\ClosingMotive",
* inversedBy="children")
*/
private $parent;
/**
* ClosingMotive constructor.
*/
@@ -91,11 +78,28 @@ class ClosingMotive
{
$this->children = new ArrayCollection();
}
public function addChildren(ClosingMotive $child): ClosingMotive
{
if ($this->children->contains($child)) {
return $this;
}
$this->children->add($child);
$child->setParent($this);
return $this;
}
public function getChildren(): Collection
{
return $this->children;
}
/**
* Get id
* Get id.
*
* @return integer
* @return int
*/
public function getId()
{
@@ -103,7 +107,87 @@ class ClosingMotive
}
/**
* Set name
* Get name.
*
* @return array
*/
public function getName()
{
return $this->name;
}
public function getOrdering(): float
{
return $this->ordering;
}
/**
* @return ClosingMotive
*/
public function getParent()
{
return $this->parent;
}
public function hasParent(): bool
{
return null !== $this->parent;
}
public function isActive(): bool
{
return $this->active;
}
public function isChild(): bool
{
return null !== $this->parent;
}
public function isLeaf(): bool
{
return $this->children->count() === 0;
}
public function isParent(): bool
{
return $this->children->count() > 0;
}
public function removeChildren(ClosingMotive $child): ClosingMotive
{
if ($this->children->removeElement($child)) {
$child->setParent(null);
}
return $this;
}
/**
* @return $this
*/
public function setActive(bool $active)
{
$this->active = $active;
if (false === $this->active) {
foreach ($this->getChildren() as $child) {
$child->setActive(false);
}
}
return $this;
}
public function setChildren(Collection $children): ClosingMotive
{
$this->children = $children;
return $this;
}
/**
* Set name.
*
* @param array $name
*
@@ -117,161 +201,23 @@ class ClosingMotive
}
/**
* Get name
*
* @return array
*/
public function getName()
{
return $this->name;
}
/**
* @return bool
*/
public function isActive(): bool
{
return $this->active;
}
/**
* @param bool $active
* @return $this
*/
public function setActive(bool $active)
{
$this->active = $active;
if ($this->active === FALSE) {
foreach ($this->getChildren() as $child) {
$child->setActive(FALSE);
}
}
return $this;
}
/**
* @return ClosingMotive
*/
public function getParent()
{
return $this->parent;
}
/**
* @return Collection
*/
public function getChildren(): Collection
{
return $this->children;
}
/**
* @param ClosingMotive|null $parent
* @return ClosingMotive
*/
public function setParent(?ClosingMotive $parent): ClosingMotive
{
$this->parent = $parent;
if (NULL !== $parent) {
//$parent->addChildren($this);
}
return $this;
}
/**
* @param Collection $children
* @return ClosingMotive
*/
public function setChildren(Collection $children): ClosingMotive
{
$this->children = $children;
return $this;
}
/**
* @param ClosingMotive $child
* @return ClosingMotive
*/
public function addChildren(ClosingMotive $child): ClosingMotive
{
if ($this->children->contains($child)) {
return $this;
}
$this->children->add($child);
$child->setParent($this);
return $this;
}
/**
* @param ClosingMotive $child
* @return ClosingMotive
*/
public function removeChildren(ClosingMotive $child): ClosingMotive
{
if ($this->children->removeElement($child)) {
$child->setParent(null);
}
return $this;
}
/**
* @return float
*/
public function getOrdering(): float
{
return $this->ordering;
}
/**
* @param float $ordering
* @return $this
*/
public function setOrdering(float $ordering)
{
$this->ordering = $ordering;
return $this;
}
/**
* @return bool
*/
public function isChild(): bool
{
return $this->parent !== null;
}
/**
* @return bool
*/
public function isParent(): bool
{
return $this->children->count() > 0;
}
/**
* @return bool
*/
public function isLeaf(): bool
{
return $this->children->count() === 0;
}
/**
* @return bool
*/
public function hasParent(): bool
{
return $this->parent !== null;
}
public function setParent(?ClosingMotive $parent): ClosingMotive
{
$this->parent = $parent;
if (null !== $parent) {
//$parent->addChildren($this);
}
return $this;
}
}

View File

@@ -1,60 +1,52 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2021, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\MainBundle\Entity\User;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface;
use Chill\MainBundle\Entity\User;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use DateTimeInterface;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* @ORM\Entity
* @ORM\Table(name="chill_person_accompanying_period_comment")
* @DiscriminatorMap(typeProperty="type", mapping={
* "accompanying_period_comment"=Comment::class
* "accompanying_period_comment": Comment::class
* })
*/
class Comment implements TrackCreationInterface, TrackUpdateInterface
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
* @Groups({"read"})
*/
private $id;
/**
* @ORM\ManyToOne(
* targetEntity="Chill\PersonBundle\Entity\AccompanyingPeriod",
* inversedBy="comments")
* inversedBy="comments")
* @ORM\JoinColumn(nullable=false, onDelete="CASCADE")
*/
private $accompanyingPeriod;
/**
* @ORM\Column(type="text")
* @Groups({"read", "write"})
*/
private $content;
/**
* @ORM\Column(type="datetime")
* @Groups({"read"})
*/
private $createdAt;
/**
* @ORM\ManyToOne(targetEntity=User::class)
* @ORM\JoinColumn(nullable=false)
@@ -63,10 +55,12 @@ class Comment implements TrackCreationInterface, TrackUpdateInterface
private $creator;
/**
* @ORM\Column(type="datetime")
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
* @Groups({"read"})
*/
private $createdAt;
private $id;
/**
* @ORM\Column(type="datetime")
@@ -81,20 +75,39 @@ class Comment implements TrackCreationInterface, TrackUpdateInterface
*/
private $updatedBy;
/**
* @ORM\Column(type="text")
* @Groups({"read", "write"})
*/
private $content;
public function getAccompanyingPeriod(): ?AccompanyingPeriod
{
return $this->accompanyingPeriod;
}
public function getContent(): ?string
{
return $this->content;
}
public function getCreatedAt(): ?DateTimeInterface
{
return $this->createdAt;
}
public function getCreator(): ?User
{
return $this->creator;
}
public function getId(): ?int
{
return $this->id;
}
public function getAccompanyingPeriod(): ?AccompanyingPeriod
public function getUpdatedAt(): ?DateTimeInterface
{
return $this->accompanyingPeriod;
return $this->updatedAt;
}
public function getUpdatedBy(): ?User
{
return $this->updatedBy;
}
public function setAccompanyingPeriod(?AccompanyingPeriod $accompanyingPeriod): self
@@ -104,14 +117,16 @@ class Comment implements TrackCreationInterface, TrackUpdateInterface
return $this;
}
public function getCreator(): ?User
public function setContent(string $content): self
{
return $this->creator;
$this->content = $content;
return $this;
}
public function setCreator(?User $creator): self
public function setCreatedAt(DateTimeInterface $createdAt): self
{
$this->creator = $creator;
$this->createdAt = $createdAt;
return $this;
}
@@ -121,51 +136,24 @@ class Comment implements TrackCreationInterface, TrackUpdateInterface
return $this->setCreator($user);
}
public function getCreatedAt(): ?\DateTimeInterface
public function setCreator(?User $creator): self
{
return $this->createdAt;
}
public function setCreatedAt(\DateTimeInterface $createdAt): self
{
$this->createdAt = $createdAt;
$this->creator = $creator;
return $this;
}
public function getUpdatedAt(): ?\DateTimeInterface
{
return $this->updatedAt;
}
public function setUpdatedAt(\DateTimeInterface $updatedAt): self
public function setUpdatedAt(DateTimeInterface $updatedAt): self
{
$this->updatedAt = $updatedAt;
return $this;
}
public function getUpdatedBy(): ?User
{
return $this->updatedBy;
}
public function setUpdatedBy(User $updatedBy): self
{
$this->updatedBy = $updatedBy;
return $this;
}
public function getContent(): ?string
{
return $this->content;
}
public function setContent(string $content): self
{
$this->content = $content;
return $this;
}
}

View File

@@ -1,40 +1,27 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2021, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
use DateTimeImmutable;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Serializer\Annotation as Serializer;
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* @ORM\Entity
* @ORM\Table(name="chill_person_accompanying_period_origin")
* @Serializer\DiscriminatorMap(
* typeProperty="type",
* mapping={
* "origin"=Origin::class
* })
* typeProperty="type",
* mapping={
* "origin": Origin::class
* })
*/
class Origin
{
@@ -68,6 +55,11 @@ class Origin
return $this->label;
}
public function getNoActiveAfter(): ?DateTimeImmutable
{
return $this->noActiveAfter;
}
public function setLabel(string $label): self
{
$this->label = $label;
@@ -75,12 +67,7 @@ class Origin
return $this;
}
public function getNoActiveAfter(): ?\DateTimeImmutable
{
return $this->noActiveAfter;
}
public function setNoActiveAfter(?\DateTimeImmutable $noActiveAfter): self
public function setNoActiveAfter(?DateTimeImmutable $noActiveAfter): self
{
$this->noActiveAfter = $noActiveAfter;

View File

@@ -1,59 +1,37 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2021, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\AccompanyingPeriod\Comment;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Repository\AccompanyingPeriod\ResourceRepository;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
use Symfony\Component\Serializer\Annotation\Groups;
use UnexpectedValueException;
/**
* @ORM\Entity
* @ORM\Table(
* name="chill_person_accompanying_period_resource",
* uniqueConstraints={
* @ORM\UniqueConstraint(name="person_unique", columns={"person_id", "accompanyingperiod_id"}),
* @ORM\UniqueConstraint(name="thirdparty_unique", columns={"thirdparty_id", "accompanyingperiod_id"})
* }
* name="chill_person_accompanying_period_resource",
* uniqueConstraints={
* @ORM\UniqueConstraint(name="person_unique", columns={"person_id", "accompanyingperiod_id"}),
* @ORM\UniqueConstraint(name="thirdparty_unique", columns={"thirdparty_id", "accompanyingperiod_id"})
* }
* )
* @DiscriminatorMap(typeProperty="type", mapping={
* "accompanying_period_resource"=Resource::class
* })
* "accompanying_period_resource": Resource::class
* })
*/
class Resource
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
* @Groups({"read"})
*/
private $id;
/**
* @ORM\ManyToOne(
* targetEntity="Chill\PersonBundle\Entity\AccompanyingPeriod",
@@ -64,10 +42,18 @@ class Resource
private $accompanyingPeriod;
/**
* @ORM\ManyToOne(targetEntity=ThirdParty::class)
* @ORM\ManyToOne(targetEntity=Comment::class)
* @ORM\JoinColumn(nullable=true)
*/
private $thirdParty;
private $comment;
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
* @Groups({"read"})
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity=Person::class)
@@ -76,38 +62,24 @@ class Resource
private $person;
/**
* @ORM\ManyToOne(targetEntity=Comment::class)
* @ORM\ManyToOne(targetEntity=ThirdParty::class)
* @ORM\JoinColumn(nullable=true)
*/
private $comment;
public function getId(): ?int
{
return $this->id;
}
private $thirdParty;
public function getAccompanyingPeriod(): ?AccompanyingPeriod
{
return $this->accompanyingPeriod;
}
public function setAccompanyingPeriod(?AccompanyingPeriod $accompanyingPeriod): self
public function getComment(): ?Comment
{
$this->accompanyingPeriod = $accompanyingPeriod;
return $this;
return $this->comment;
}
public function getThirdParty(): ?ThirdParty
public function getId(): ?int
{
return $this->thirdParty;
}
private function setThirdParty(?ThirdParty $thirdParty): self
{
$this->thirdParty = $thirdParty;
return $this;
return $this->id;
}
public function getPerson(): ?Person
@@ -115,16 +87,25 @@ class Resource
return $this->person;
}
private function setPerson(?Person $person): self
/**
* @return Person|ThirdParty
* @Groups({"read", "write"})
*/
public function getResource()
{
$this->person = $person;
return $this;
return $this->person ?? $this->thirdParty;
}
public function getComment(): ?Comment
public function getThirdParty(): ?ThirdParty
{
return $this->comment;
return $this->thirdParty;
}
public function setAccompanyingPeriod(?AccompanyingPeriod $accompanyingPeriod): self
{
$this->accompanyingPeriod = $accompanyingPeriod;
return $this;
}
public function setComment(?Comment $comment): self
@@ -135,36 +116,42 @@ class Resource
}
/**
*
* @param $resource Person|ThirdParty
*/
public function setResource($resource): self
{
if ($resource instanceof ThirdParty) {
$this->setThirdParty($resource);
$this->setPerson(NULL);
$this->setPerson(null);
} elseif ($resource instanceof Person) {
$this->setPerson($resource);
$this->setThirdParty(NULL);
} elseif (NULL === $resource) {
$this->setPerson(NULL);
$this->setThirdParty(NULL);
$this->setThirdParty(null);
} elseif (null === $resource) {
$this->setPerson(null);
$this->setThirdParty(null);
} else {
throw new \UnexpectedValueException(sprintf("the resource ".
"should be an instance of %s or %s", Person::class,
ThirdParty::class));
throw new UnexpectedValueException(sprintf(
'the resource ' .
'should be an instance of %s or %s',
Person::class,
ThirdParty::class
));
}
return $this;
}
/**
* @return ThirdParty|Person
* @Groups({"read", "write"})
*/
public function getResource()
private function setPerson(?Person $person): self
{
return $this->person ?? $this->thirdParty;
$this->person = $person;
return $this;
}
private function setThirdParty(?ThirdParty $thirdParty): self
{
$this->thirdParty = $thirdParty;
return $this;
}
}

View File

@@ -1,45 +1,43 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2021, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Entity;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\Person;
use DateTimeImmutable;
use DateTimeInterface;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* AccompanyingPeriodParticipation Class
* AccompanyingPeriodParticipation Class.
*
* @package Chill\PersonBundle\Entity
* @ORM\Entity
* @ORM\Table(name="chill_person_accompanying_period_participation")
* @DiscriminatorMap(typeProperty="type", mapping={
* "accompanying_period_participation"=AccompanyingPeriodParticipation::class
* })
* "accompanying_period_participation": AccompanyingPeriodParticipation::class
* })
*/
class AccompanyingPeriodParticipation
{
/**
* @ORM\ManyToOne(targetEntity=AccompanyingPeriod::class, inversedBy="participations", cascade={"persist"})
* @ORM\JoinColumn(name="accompanyingperiod_id", referencedColumnName="id", nullable=false)
*/
private $accompanyingPeriod;
/**
* @ORM\Column(type="date", nullable=true)
* @Groups({"read"})
*/
private $endDate;
/**
* @ORM\Id
* @ORM\GeneratedValue
@@ -55,31 +53,33 @@ class AccompanyingPeriodParticipation
*/
private $person;
/**
* @ORM\ManyToOne(targetEntity=AccompanyingPeriod::class, inversedBy="participations", cascade={"persist"})
* @ORM\JoinColumn(name="accompanyingperiod_id", referencedColumnName="id", nullable=false)
*/
private $accompanyingPeriod;
/**
* @ORM\Column(type="date", nullable=false)
* @Groups({"read"})
*/
private $startDate;
/**
* @ORM\Column(type="date", nullable=true)
* @Groups({"read"})
*/
private $endDate = null;
public function __construct(AccompanyingPeriod $accompanyingPeriod, Person $person)
{
$this->startDate = new \DateTimeImmutable('now');
$this->startDate = new DateTimeImmutable('now');
$this->accompanyingPeriod = $accompanyingPeriod;
$this->person = $person;
}
public function getAccompanyingPeriod(): ?AccompanyingPeriod
{
return $this->accompanyingPeriod;
}
/*
* public function setStartDate(\DateTimeInterface $startDate): self { $this->startDate = $startDate; return $this; }
*/
public function getEndDate(): ?DateTimeInterface
{
return $this->endDate;
}
public function getId(): ?int
{
return $this->id;
@@ -90,16 +90,14 @@ class AccompanyingPeriodParticipation
return $this->person;
}
public function setPerson(?Person $person): self
public function getStartDate(): ?DateTimeInterface
{
$this->person = $person;
return $this;
return $this->startDate;
}
public function getAccompanyingPeriod(): ?AccompanyingPeriod
public function isOpen(): bool
{
return $this->accompanyingPeriod;
return null === $this->endDate;
}
public function setAccompanyingPeriod(?AccompanyingPeriod $accompanyingPeriod): self
@@ -109,35 +107,23 @@ class AccompanyingPeriodParticipation
return $this;
}
public function getStartDate(): ?\DateTimeInterface
{
return $this->startDate;
}
/*
* public function setStartDate(\DateTimeInterface $startDate): self { $this->startDate = $startDate; return $this; }
*/
public function getEndDate(): ?\DateTimeInterface
{
return $this->endDate;
}
public function setEndDate(?\DateTimeInterface $endDate): self
public function setEndDate(?DateTimeInterface $endDate): self
{
$this->endDate = $endDate;
return $this;
}
public function isOpen(): bool
public function setPerson(?Person $person): self
{
return $this->endDate === null;
$this->person = $person;
return $this;
}
private function checkSameStartEnd()
private function checkSameStartEnd()
{
if($this->endDate == $this->startDate) {
if ($this->endDate == $this->startDate) {
$this->accompanyingPeriod->removeParticipation($this);
}
}

View File

@@ -1,34 +1,20 @@
<?php
/*
* Chill is a software for social workers
*
* Copyright (C) 2014-2019, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Chill\PersonBundle\Entity;
use Chill\PersonBundle\Entity\Person;
/**
* Interface which applies to entities which are associated to a single person
*
* 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\PersonBundle\Entity;
/**
* Interface which applies to entities which are associated to a single person.
*/
interface HasPerson
{
public function setPerson(Person $person = null): HasPerson;
public function getPerson(): ?Person;
public function setPerson(?Person $person = null): HasPerson;
}

View File

@@ -1,31 +1,57 @@
<?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.
*/
namespace Chill\PersonBundle\Entity\Household;
use Chill\MainBundle\Entity\Address;
use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
use Chill\PersonBundle\Validator\Constraints\Household\MaxHolder;
use DateTime;
use DateTimeImmutable;
use DateTimeInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation as Serializer;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Chill\MainBundle\Entity\Address;
use Chill\PersonBundle\Entity\Household\HouseholdMember;
use Chill\PersonBundle\Validator\Constraints\Household\MaxHolder;
use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
/**
* @ORM\Entity
* @ORM\Table(
* name="chill_person_household"
* )
* name="chill_person_household"
* )
* @Serializer\DiscriminatorMap(typeProperty="type", mapping={
* "household"=Household::class
* "household": Household::class
* })
* @MaxHolder(groups={"household_memberships"})
*/
class Household
{
/**
* Addresses.
*
* @ORM\ManyToMany(
* targetEntity="Chill\MainBundle\Entity\Address",
* cascade={"persist", "remove", "merge", "detach"})
* @ORM\JoinTable(name="chill_person_household_to_addresses")
* @ORM\OrderBy({"validFrom": "DESC", "id": "DESC"})
* @Serializer\Groups({"write"})
*/
private Collection $addresses;
/**
* @ORM\Embedded(class=CommentEmbeddable::class, columnPrefix="comment_members_")
*/
private CommentEmbeddable $commentMembers;
/**
* @ORM\Id
* @ORM\GeneratedValue
@@ -34,32 +60,15 @@ class Household
*/
private ?int $id = null;
/**
* Addresses
*
* @ORM\ManyToMany(
* targetEntity="Chill\MainBundle\Entity\Address",
* cascade={"persist", "remove", "merge", "detach"})
* @ORM\JoinTable(name="chill_person_household_to_addresses")
* @ORM\OrderBy({"validFrom" = "DESC", "id" = "DESC"})
* @Serializer\Groups({"write"})
*/
private Collection $addresses;
/**
* @ORM\OneToMany(
* targetEntity=HouseholdMember::class,
* mappedBy="household"
* )
* targetEntity=HouseholdMember::class,
* mappedBy="household"
* )
* @Serializer\Groups({"read"})
*/
private Collection $members;
/**
* @ORM\Embedded(class=CommentEmbeddable::class, columnPrefix="comment_members_")
*/
private CommentEmbeddable $commentMembers;
/**
* @ORM\Column(type="boolean", name="waiting_for_birth", options={"default": false})
*/
@@ -68,7 +77,7 @@ class Household
/**
* @ORM\Column(type="date_immutable", name="waiting_for_birth_date", nullable=true, options={"default": null})
*/
private ?\DateTimeImmutable $waitingForBirthDate = null;
private ?DateTimeImmutable $waitingForBirthDate = null;
public function __construct()
{
@@ -77,19 +86,13 @@ class Household
$this->commentMembers = new CommentEmbeddable();
}
public function getId(): ?int
{
return $this->id;
}
/**
* @param Address $address
* @return $this
*/
public function addAddress(Address $address)
{
foreach ($this->getAddresses() as $a) {
if ($a->getValidFrom() < $address->getValidFrom() && $a->getValidTo() === NULL) {
if ($a->getValidFrom() < $address->getValidFrom() && $a->getValidTo() === null) {
$a->setValidTo($address->getValidFrom());
}
}
@@ -99,35 +102,22 @@ class Household
return $this;
}
/**
* Force an address starting at the current day
* on the Household.
*
* This will force the startDate's address on today.
*
* Used on household creation.
*
* @Serializer\Groups({"create"})
*/
public function setForceAddress(Address $address)
public function addMember(HouseholdMember $member): self
{
$address->setValidFrom(new \DateTime('today'));
$this->addAddress($address);
}
if (!$this->members->contains($member)) {
$this->members[] = $member;
$member->setHousehold($this);
}
/**
* @param Address $address
*/
public function removeAddress(Address $address)
{
$this->addresses->removeElement($address);
return $this;
}
/**
* By default, the addresses are ordered by date, descending (the most
* recent first)
* recent first).
*
* @Assert\Callback(methods={"validate"})
*
* @return \Chill\MainBundle\Entity\Address[]
*/
public function getAddresses()
@@ -135,25 +125,131 @@ class Household
return $this->addresses;
}
public function getCommentMembers(): CommentEmbeddable
{
return $this->commentMembers;
}
/**
* @Serializer\Groups({ "read" })
* @Serializer\SerializedName("current_address")
*/
public function getCurrentAddress(\DateTime $at = null): ?Address
public function getCurrentAddress(?DateTime $at = null): ?Address
{
$at = $at === null ? new \DateTime('today') : $at;
$at = null === $at ? new DateTime('today') : $at;
$addrs = $this->getAddresses()->filter(function (Address $a) use ($at) {
return $a->getValidFrom() <= $at && (
NULL === $a->getValidTo() || $at < $a->getValidTo()
null === $a->getValidTo() || $a->getValidTo() > $at
);
});
if ($addrs->count() > 0) {
return $addrs->first();
} else {
return null;
}
return null;
}
public function getCurrentMembers(?DateTimeImmutable $now = null): Collection
{
return $this->getMembers()->matching($this->buildCriteriaCurrentMembers($now));
}
public function getCurrentMembersByPosition(Position $position, ?DateTimeInterface $now = null)
{
$criteria = new Criteria();
$expr = Criteria::expr();
$criteria->where($expr->eq('position', $position));
return $this->getCurrentMembers($now)->matching($criteria);
}
/**
* get current members ids.
*
* Used in serialization
*
* @Serializer\Groups({"read"})
* @Serializer\SerializedName("current_members_id")
*/
public function getCurrentMembersIds(?DateTimeImmutable $now = null): Collection
{
return $this->getCurrentMembers($now)->map(
fn (HouseholdMember $m) => $m->getId()
);
}
/**
* @return HouseholdMember[]
*/
public function getCurrentMembersOrdered(?DateTimeImmutable $now = null): Collection
{
$members = $this->getCurrentMembers($now);
$members->getIterator()
->uasort(
function (HouseholdMember $a, HouseholdMember $b) {
if ($a->getPosition() === null) {
if ($b->getPosition() === null) {
return 0;
}
return -1;
} elseif ($b->getPosition() === null) {
return 1;
}
if ($a->getPosition()->getOrdering() < $b->getPosition()->getOrdering()) {
return -1;
}
if ($a->getPosition()->getOrdering() > $b->getPosition()->getOrdering()) {
return 1;
}
if ($a->isHolder() && !$b->isHolder()) {
return 1;
}
if (!$a->isHolder() && $b->isHolder()) {
return -1;
}
return 0;
}
);
return $members;
}
public function getCurrentMembersWithoutPosition(?DateTimeInterface $now = null)
{
$criteria = new Criteria();
$expr = Criteria::expr();
$criteria->where($expr->isNull('position'));
return $this->getCurrentMembers($now)->matching($criteria);
}
/**
* Get the persons currently associated to the household.
*
* Return a list of Person, instead of a list of HouseholdMembers
*
* @return Person[]
*/
public function getCurrentPersons(?DateTimeImmutable $now = null): Collection
{
return $this->getCurrentMembers($now)
->map(function (HouseholdMember $m) { return $m->getPerson(); });
}
public function getId(): ?int
{
return $this->id;
}
/**
@@ -164,36 +260,13 @@ class Household
return $this->members;
}
public function getMembersOnRange(\DateTimeImmutable $from, ?\DateTimeImmutable $to): Collection
{
$criteria = new Criteria();
$expr = Criteria::expr();
$criteria->where(
$expr->gte('startDate', $from)
);
if (NULL !== $to) {
$criteria->andWhere(
$expr->orX(
$expr->lte('endDate', $to),
$expr->eq('endDate', NULL)
),
);
}
return $this->getMembers()
->matching($criteria)
;
}
public function getMembersDuringMembership(HouseholdMember $membership)
{
return $this->getMembersOnRange(
$membership->getStartDate(),
$membership->getEndDate()
)->filter(
function(HouseholdMember $m) use ($membership) {
function (HouseholdMember $m) use ($membership) {
return $m !== $membership;
}
);
@@ -211,104 +284,33 @@ class Household
return $this->getMembers()->matching($criteria);
}
public function getCurrentMembers(?\DateTimeImmutable $now = null): Collection
{
return $this->getMembers()->matching($this->buildCriteriaCurrentMembers($now));
}
private function buildCriteriaCurrentMembers(?\DateTimeImmutable $now = null): Criteria
public function getMembersOnRange(DateTimeImmutable $from, ?DateTimeImmutable $to): Collection
{
$criteria = new Criteria();
$expr = Criteria::expr();
$date = $now === null ? (new \DateTimeImmutable('today')) : $now;
$criteria
->where($expr->orX(
$expr->isNull('startDate'),
$expr->lte('startDate', $date)
))
->andWhere($expr->orX(
$expr->isNull('endDate'),
$expr->gt('endDate', $date)
));
return $criteria;
}
/**
* @return HouseholdMember[]
*/
public function getCurrentMembersOrdered(?\DateTimeImmutable $now = null): Collection
{
$members = $this->getCurrentMembers($now);
$members->getIterator()
->uasort(
function (HouseholdMember $a, HouseholdMember $b) {
if ($a->getPosition() === NULL) {
if ($b->getPosition() === NULL) {
return 0;
} else {
return -1;
}
} elseif ($b->getPosition() === NULL) {
return 1;
}
if ($a->getPosition()->getOrdering() < $b->getPosition()->getOrdering()) {
return -1;
}
if ($a->getPosition()->getOrdering() > $b->getPosition()->getOrdering()) {
return 1;
}
if ($a->isHolder() && !$b->isHolder()) {
return 1;
}
if (!$a->isHolder() && $b->isHolder()) {
return -1;
}
return 0;
}
$criteria->where(
$expr->gte('startDate', $from)
);
return $members;
if (null !== $to) {
$criteria->andWhere(
$expr->orX(
$expr->lte('endDate', $to),
$expr->eq('endDate', null)
),
);
}
return $this->getMembers()
->matching($criteria);
}
/**
* get current members ids
*
* Used in serialization
*
* @Serializer\Groups({"read"})
* @Serializer\SerializedName("current_members_id")
*
*/
public function getCurrentMembersIds(?\DateTimeImmutable $now = null): Collection
{
return $this->getCurrentMembers($now)->map(
fn (HouseholdMember $m) => $m->getId()
);
}
/**
* Get the persons currently associated to the household.
*
* Return a list of Person, instead of a list of HouseholdMembers
*
* @return Person[]
*/
public function getCurrentPersons(?\DateTimeImmutable $now = null): Collection
{
return $this->getCurrentMembers($now)
->map(function(HouseholdMember $m) { return $m->getPerson(); });
}
public function getNonCurrentMembers(\DateTimeImmutable $now = null): Collection
public function getNonCurrentMembers(?DateTimeImmutable $now = null): Collection
{
$criteria = new Criteria();
$expr = Criteria::expr();
$date = $now === null ? (new \DateTimeImmutable('today')) : $now;
$date = null === $now ? (new DateTimeImmutable('today')) : $now;
$criteria
->where(
@@ -324,17 +326,7 @@ class Household
return $this->getMembers()->matching($criteria);
}
public function getCurrentMembersByPosition(Position $position, \DateTimeInterface $now = null)
{
$criteria = new Criteria();
$expr = Criteria::expr();
$criteria->where($expr->eq('position', $position));
return $this->getCurrentMembers($now)->matching($criteria);
}
public function getNonCurrentMembersByPosition(Position $position, \DateTimeInterface $now = null)
public function getNonCurrentMembersByPosition(Position $position, ?DateTimeInterface $now = null)
{
$criteria = new Criteria();
$expr = Criteria::expr();
@@ -344,17 +336,7 @@ class Household
return $this->getNonCurrentMembers($now)->matching($criteria);
}
public function getCurrentMembersWithoutPosition(\DateTimeInterface $now = null)
{
$criteria = new Criteria();
$expr = Criteria::expr();
$criteria->where($expr->isNull('position'));
return $this->getCurrentMembers($now)->matching($criteria);
}
public function getNonCurrentMembersWithoutPosition(\DateTimeInterface $now = null)
public function getNonCurrentMembersWithoutPosition(?DateTimeInterface $now = null)
{
$criteria = new Criteria();
$expr = Criteria::expr();
@@ -364,14 +346,19 @@ class Household
return $this->getNonCurrentMembers($now)->matching($criteria);
}
public function addMember(HouseholdMember $member): self
public function getWaitingForBirth(): bool
{
if (!$this->members->contains($member)) {
$this->members[] = $member;
$member->setHousehold($this);
}
return $this->waitingForBirth;
}
return $this;
public function getWaitingForBirthDate(): ?DateTimeImmutable
{
return $this->waitingForBirthDate;
}
public function removeAddress(Address $address)
{
$this->addresses->removeElement($address);
}
public function removeMember(HouseholdMember $member): self
@@ -386,11 +373,6 @@ class Household
return $this;
}
public function getCommentMembers(): CommentEmbeddable
{
return $this->commentMembers;
}
public function setCommentMembers(CommentEmbeddable $commentMembers): self
{
$this->commentMembers = $commentMembers;
@@ -398,9 +380,20 @@ class Household
return $this;
}
public function getWaitingForBirth(): bool
/**
* Force an address starting at the current day
* on the Household.
*
* This will force the startDate's address on today.
*
* Used on household creation.
*
* @Serializer\Groups({"create"})
*/
public function setForceAddress(Address $address)
{
return $this->waitingForBirth;
$address->setValidFrom(new DateTime('today'));
$this->addAddress($address);
}
public function setWaitingForBirth(bool $waitingForBirth): self
@@ -410,12 +403,7 @@ class Household
return $this;
}
public function getWaitingForBirthDate(): ?\DateTimeImmutable
{
return $this->waitingForBirthDate;
}
public function setWaitingForBirthDate(?\DateTimeImmutable $waitingForBirthDate): self
public function setWaitingForBirthDate(?DateTimeImmutable $waitingForBirthDate): self
{
$this->waitingForBirthDate = $waitingForBirthDate;
@@ -425,14 +413,34 @@ class Household
public function validate(ExecutionContextInterface $context, $payload)
{
$addresses = $this->getAddresses();
$cond = True;
for ($i=0; $i < count($addresses) - 1; $i++) {
$cond = true;
for ($i = 0; count($addresses) - 1 > $i; ++$i) {
if ($addresses[$i]->getValidFrom() != $addresses[$i + 1]->getValidTo()) {
$cond = False;
$cond = false;
$context->buildViolation('The address are not sequentials. The validFrom date of one address should be equal to the validTo date of the previous address.')
->atPath('addresses')
->addViolation();
}
}
}
private function buildCriteriaCurrentMembers(?DateTimeImmutable $now = null): Criteria
{
$criteria = new Criteria();
$expr = Criteria::expr();
$date = null === $now ? (new DateTimeImmutable('today')) : $now;
$criteria
->where($expr->orX(
$expr->isNull('startDate'),
$expr->lte('startDate', $date)
))
->andWhere($expr->orX(
$expr->isNull('endDate'),
$expr->gt('endDate', $date)
));
return $criteria;
}
}

View File

@@ -1,23 +1,62 @@
<?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.
*/
namespace Chill\PersonBundle\Entity\Household;
use Doctrine\ORM\Mapping as ORM;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Entity\Household\Household;
use Chill\PersonBundle\Entity\Household\Position;
use DateTimeImmutable;
use Doctrine\ORM\Mapping as ORM;
use LogicException;
use Symfony\Component\Serializer\Annotation as Serializer;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity
* @ORM\Table(
* name="chill_person_household_members"
* )
* name="chill_person_household_members"
* )
*/
class HouseholdMember
{
/**
* @ORM\Column(type="string", length=255, nullable=true)
* @Serializer\Groups({"read"})
*/
private ?string $comment = null;
/**
* @ORM\Column(type="date_immutable", nullable=true, options={"default": null})
* @Serializer\Groups({"read"})
* @Assert\GreaterThan(
* propertyPath="startDate",
* message="household_membership.The end date must be after start date",
* groups={"household_memberships"}
* )
*/
private ?DateTimeImmutable $endDate = null;
/**
* @ORM\Column(type="boolean", options={"default": false})
* @Serializer\Groups({"read"})
*/
private bool $holder = false;
/**
* @var Household
* @ORM\ManyToOne(
* targetEntity="\Chill\PersonBundle\Entity\Household\Household"
* )
* @Assert\Valid(groups={"household_memberships"})
* @Assert\NotNull(groups={"household_memberships"})
*/
private ?Household $household = null;
/**
* @ORM\Id
* @ORM\GeneratedValue
@@ -27,52 +66,9 @@ class HouseholdMember
private $id;
/**
* @ORM\ManyToOne(targetEntity=Position::class)
* @Serializer\Groups({"read"})
* @Assert\NotNull(groups={"household_memberships_created"})
*/
private ?Position $position = null;
/**
* @ORM\Column(type="date_immutable", nullable=true, options={"default": null})
* @Serializer\Groups({"read"})
* @Assert\NotNull(groups={"household_memberships"})
*/
private ?\DateTimeImmutable $startDate = null;
/**
* @ORM\Column(type="date_immutable", nullable= true, options={"default": null})
* @Serializer\Groups({"read"})
* @Assert\GreaterThan(
* propertyPath="startDate",
* message="household_membership.The end date must be after start date",
* groups={"household_memberships"}
* )
*/
private ?\DateTimeImmutable $endDate = null;
/**
* @ORM\Column(type="string", length=255, nullable=true)
* @Serializer\Groups({"read"})
*/
private ?string $comment = NULL;
/**
* @ORM\Column(type="boolean", name="sharedhousehold")
*/
private bool $shareHousehold = false;
/**
* @ORM\Column(type="boolean", options={"default": false})
* @Serializer\Groups({"read"})
*/
private bool $holder = false;
/**
*
* @var Person
* @ORM\ManyToOne(
* targetEntity="\Chill\PersonBundle\Entity\Person"
* targetEntity="\Chill\PersonBundle\Entity\Person"
* )
* @Serializer\Groups({"read"})
* @Assert\Valid(groups={"household_memberships"})
@@ -81,74 +77,52 @@ class HouseholdMember
private ?Person $person = null;
/**
*
* @var Household
* @ORM\ManyToOne(
* targetEntity="\Chill\PersonBundle\Entity\Household\Household"
* )
* @Assert\Valid(groups={"household_memberships"})
* @ORM\ManyToOne(targetEntity=Position::class)
* @Serializer\Groups({"read"})
* @Assert\NotNull(groups={"household_memberships_created"})
*/
private ?Position $position = null;
/**
* @ORM\Column(type="boolean", name="sharedhousehold")
*/
private bool $shareHousehold = false;
/**
* @ORM\Column(type="date_immutable", nullable=true, options={"default": null})
* @Serializer\Groups({"read"})
* @Assert\NotNull(groups={"household_memberships"})
*/
private ?Household $household = null;
public function getId(): ?int
{
return $this->id;
}
public function getPosition(): ?Position
{
return $this->position;
}
public function setPosition(Position $position): self
{
if ($this->position instanceof Position) {
throw new \LogicException("The position is already set. You cannot change ".
"a position of a membership");
}
$this->position = $position;
$this->shareHousehold = $position->getShareHousehold();
return $this;
}
public function getStartDate(): ?\DateTimeImmutable
{
return $this->startDate;
}
public function setStartDate(\DateTimeImmutable $startDate): self
{
$this->startDate = $startDate;
return $this;
}
public function getEndDate(): ?\DateTimeImmutable
{
return $this->endDate;
}
public function setEndDate(?\DateTimeImmutable $endDate = null): self
{
$this->endDate = $endDate;
return $this;
}
private ?DateTimeImmutable $startDate = null;
public function getComment(): ?string
{
return $this->comment;
}
public function setComment(?string $comment): self
public function getEndDate(): ?DateTimeImmutable
{
$this->comment = $comment;
return $this->endDate;
}
return $this;
public function getHousehold(): ?Household
{
return $this->household;
}
public function getId(): ?int
{
return $this->id;
}
public function getPerson(): ?Person
{
return $this->person;
}
public function getPosition(): ?Position
{
return $this->position;
}
/**
@@ -159,44 +133,35 @@ class HouseholdMember
return $this->shareHousehold;
}
public function setShareHousehold(bool $shareHousehold): self
public function getStartDate(): ?DateTimeImmutable
{
$this->shareHousehold = $shareHousehold;
return $this->startDate;
}
public function isCurrent(?DateTimeImmutable $at = null): bool
{
$at = null === $at ? new DateTimeImmutable('now') : $at;
return $this->getStartDate() < $at && (
null === $this->getEndDate() || $this->getEndDate() > $at
);
}
public function isHolder(): bool
{
return $this->holder;
}
public function setComment(?string $comment): self
{
$this->comment = $comment;
return $this;
}
public function getPerson(): ?Person
public function setEndDate(?DateTimeImmutable $endDate = null): self
{
return $this->person;
}
public function setPerson(?Person $person): self
{
if ($this->person instanceof Person) {
throw new \LogicException("You cannot change person ".
"on a membership");
}
$this->person = $person;
$this->person->addHouseholdParticipation($this);
return $this;
}
public function getHousehold(): ?Household
{
return $this->household;
}
public function setHousehold(?Household $household): self
{
if ($this->household instanceof Household) {
throw new \LogicException("You cannot change household ".
"on a membership");
}
$this->household = $household;
$this->endDate = $endDate;
return $this;
}
@@ -208,17 +173,55 @@ class HouseholdMember
return $this;
}
public function isHolder(): bool
public function setHousehold(?Household $household): self
{
return $this->holder;
if ($this->household instanceof Household) {
throw new LogicException('You cannot change household ' .
'on a membership');
}
$this->household = $household;
return $this;
}
public function isCurrent(\DateTimeImmutable $at = null): bool
public function setPerson(?Person $person): self
{
$at = NULL === $at ? new \DateTimeImmutable('now'): $at;
if ($this->person instanceof Person) {
throw new LogicException('You cannot change person ' .
'on a membership');
}
return $this->getStartDate() < $at && (
NULL === $this->getEndDate() || $at < $this->getEndDate()
);
$this->person = $person;
$this->person->addHouseholdParticipation($this);
return $this;
}
public function setPosition(Position $position): self
{
if ($this->position instanceof Position) {
throw new LogicException('The position is already set. You cannot change ' .
'a position of a membership');
}
$this->position = $position;
$this->shareHousehold = $position->getShareHousehold();
return $this;
}
public function setShareHousehold(bool $shareHousehold): self
{
$this->shareHousehold = $shareHousehold;
return $this;
}
public function setStartDate(DateTimeImmutable $startDate): self
{
$this->startDate = $startDate;
return $this;
}
}

View File

@@ -1,10 +1,18 @@
<?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.
*/
namespace Chill\PersonBundle\Entity\Household;
use Chill\MainBundle\Entity\Address;
use Chill\PersonBundle\Entity\Household\Household;
use Chill\PersonBundle\Entity\Person;
use DateTimeImmutable;
use DateTimeInterface;
use Doctrine\ORM\Mapping as ORM;
/**
@@ -36,6 +44,26 @@ use Doctrine\ORM\Mapping as ORM;
*/
class PersonHouseholdAddress
{
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity=Address::class)
* @ORM\JoinColumn(nullable=false)
*/
private $address;
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity=Household::class)
* @ORM\JoinColumn(nullable=false)
*/
private $household;
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity=Person::class)
* @ORM\JoinColumn(nullable=false)
*/
private $person;
/**
* @ORM\Column(type="date_immutable")
@@ -47,52 +75,9 @@ class PersonHouseholdAddress
*/
private $validTo;
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity=Person::class)
* @ORM\JoinColumn(nullable=false)
*/
private $person;
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity=Household::class)
* @ORM\JoinColumn(nullable=false)
*/
private $household;
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity=Address::class)
* @ORM\JoinColumn(nullable=false)
*/
private $address;
/**
* The start date of the intersection address/household
*
* (this is not the startdate of the household, not
* the startdate of the address)
*/
public function getValidFrom(): ?\DateTimeInterface
public function getAddress(): ?Address
{
return $this->validFrom;
}
/**
* The end date of the intersection address/household
*
* (this is not the enddate of the household, not
* the enddate of the address)
*/
public function getValidTo(): ?\DateTimeImmutable
{
return $this->validTo;
}
public function getPerson(): ?Person
{
return $this->person;
return $this->address;
}
public function getHousehold(): ?Household
@@ -100,8 +85,30 @@ class PersonHouseholdAddress
return $this->relation;
}
public function getAddress(): ?Address
public function getPerson(): ?Person
{
return $this->address;
return $this->person;
}
/**
* The start date of the intersection address/household.
*
* (this is not the startdate of the household, not
* the startdate of the address)
*/
public function getValidFrom(): ?DateTimeInterface
{
return $this->validFrom;
}
/**
* The end date of the intersection address/household.
*
* (this is not the enddate of the household, not
* the enddate of the address)
*/
public function getValidTo(): ?DateTimeImmutable
{
return $this->validTo;
}
}

View File

@@ -1,8 +1,14 @@
<?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.
*/
namespace Chill\PersonBundle\Entity\Household;
use Chill\PersonBundle\Repository\Household\PositionRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation as Serializer;
@@ -10,11 +16,17 @@ use Symfony\Component\Serializer\Annotation as Serializer;
* @ORM\Entity
* @ORM\Table(name="chill_person_household_position")
* @Serializer\DiscriminatorMap(typeProperty="type", mapping={
* "household_position"=Position::class
* })
* "household_position": Position::class
* })
*/
class Position
{
/**
* @ORM\Column(type="boolean")
* @Serializer\Groups({ "read" })
*/
private bool $allowHolder = false;
/**
* @ORM\Id
* @ORM\GeneratedValue
@@ -29,23 +41,22 @@ class Position
*/
private array $label = [];
/**
* @ORM\Column(type="float")
* @Serializer\Groups({ "read" })
*/
private float $ordering = 0.00;
/**
* @ORM\Column(type="boolean")
* @Serializer\Groups({ "read" })
*/
private bool $shareHouseHold = true;
/**
* @ORM\Column(type="boolean")
* @Serializer\Groups({ "read" })
*/
private bool $allowHolder = false;
/**
* @ORM\Column(type="float")
* @Serializer\Groups({ "read" })
*/
private float $ordering = 0.00;
public function getAllowHolder(): bool
{
return $this->allowHolder;
}
public function getId(): ?int
{
@@ -57,11 +68,9 @@ class Position
return $this->label;
}
public function setLabel(array $label): self
public function getOrdering(): float
{
$this->label = $label;
return $this;
return $this->ordering;
}
public function getShareHousehold(): bool
@@ -69,18 +78,6 @@ class Position
return $this->shareHouseHold;
}
public function setShareHousehold(bool $shareHouseHold): self
{
$this->shareHouseHold = $shareHouseHold;
return $this;
}
public function getAllowHolder(): bool
{
return $this->allowHolder;
}
public function isAllowHolder(): bool
{
return $this->getAllowHolder();
@@ -93,9 +90,11 @@ class Position
return $this;
}
public function getOrdering(): float
public function setLabel(array $label): self
{
return $this->ordering;
$this->label = $label;
return $this;
}
public function setOrdering(float $ordering): self
@@ -104,4 +103,11 @@ class Position
return $this;
}
public function setShareHousehold(bool $shareHouseHold): self
{
$this->shareHouseHold = $shareHouseHold;
return $this;
}
}

View File

@@ -1,21 +1,10 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Entity;
@@ -23,18 +12,18 @@ namespace Chill\PersonBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* MaritalStatus
* MaritalStatus.
*
* @ORM\Entity
* @ORM\Table(name="chill_person_marital_status")
* @ORM\HasLifecycleCallbacks()
* @ORM\HasLifecycleCallbacks
*/
class MaritalStatus
{
/**
* @var string
*
* @ORM\Id()
* @ORM\Id
* @ORM\Column(type="string", length=7)
*/
private ?string $id;
@@ -46,9 +35,7 @@ class MaritalStatus
private array $name;
/**
* Get id
*
* @return string
* Get id.
*/
public function getId(): string
{
@@ -56,21 +43,32 @@ class MaritalStatus
}
/**
* Set id
* Get name.
*
* @return string array
*/
public function getName(): array
{
return $this->name;
}
/**
* Set id.
*
* @param string $id
* @return MaritalStatus
*/
public function setId(string $id): self
{
$this->id = $id;
return $this;
}
/**
* Set name
* Set name.
*
* @param string array $name
*
* @return MaritalStatus
*/
public function setName(array $name): self
@@ -79,14 +77,4 @@ class MaritalStatus
return $this;
}
/**
* Get name
*
* @return string array
*/
public function getName(): array
{
return $this->name;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,17 @@
<?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.
*/
namespace Chill\PersonBundle\Entity\Person;
use Chill\MainBundle\Entity\Address;
use Chill\PersonBundle\Entity\Person;
use DateTimeImmutable;
use Doctrine\ORM\Mapping as ORM;
/**
@@ -13,13 +21,18 @@ use Doctrine\ORM\Mapping as ORM;
* The computation is optimized on database side.
*
* The validFrom and validTo properties are the intersection of
* household membership and address validity. See @link{PersonHouseholdAddress}
* household membership and address validity. See @see{PersonHouseholdAddress}
*
* @ORM\Entity(readOnly=true)
* @ORM\Table("view_chill_person_current_address")
*/
class PersonCurrentAddress
{
/**
* @ORM\OneToOne(targetEntity=Address::class)
*/
protected Address $address;
/**
* @ORM\Id
* @ORM\OneToOne(targetEntity=Person::class, inversedBy="currentPersonAddress")
@@ -27,55 +40,40 @@ class PersonCurrentAddress
*/
protected Person $person;
/**
* @ORM\OneToOne(targetEntity=Address::class)
*/
protected Address $address;
/**
* @ORM\Column(name="valid_from", type="date_immutable")
*/
protected \DateTimeImmutable $validFrom;
protected DateTimeImmutable $validFrom;
/**
* @ORM\Column(name="valid_to", type="date_immutable")
*/
protected ?\DateTimeImmutable $validTo;
protected ?DateTimeImmutable $validTo;
public function getAddress(): Address
{
return $this->address;
}
/**
* @return Person
*/
public function getPerson(): Person
{
return $this->person;
}
/**
* @return Address
*/
public function getAddress(): Address
{
return $this->address;
}
/**
* This date is the intersection of household membership
* and address validity
*
* @return \DateTimeImmutable
* and address validity.
*/
public function getValidFrom(): \DateTimeImmutable
public function getValidFrom(): DateTimeImmutable
{
return $this->validFrom;
}
/**
* This date is the intersection of household membership
* and address validity
*
* @return \DateTimeImmutable|null
* and address validity.
*/
public function getValidTo(): ?\DateTimeImmutable
public function getValidTo(): ?DateTimeImmutable
{
return $this->validTo;
}

View File

@@ -1,11 +1,18 @@
<?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.
*/
namespace Chill\PersonBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* PersonAltName
* PersonAltName.
*
* @ORM\Table(name="chill_person_alt_name")
* @ORM\Entity
@@ -13,7 +20,7 @@ use Doctrine\ORM\Mapping as ORM;
class PersonAltName
{
/**
* @var integer
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
@@ -34,18 +41,17 @@ class PersonAltName
* @ORM\Column(name="label", type="text")
*/
private $label;
/**
* @var Person
*
* @ORM\ManyToOne(
* targetEntity="Chill\PersonBundle\Entity\Person",
* inversedBy="altNames"
* targetEntity="Chill\PersonBundle\Entity\Person",
* inversedBy="altNames"
* )
*/
private $person;
/**
* Get id.
*
@@ -56,6 +62,31 @@ class PersonAltName
return $this->id;
}
/**
* Get key.
*
* @return string
*/
public function getKey()
{
return $this->key;
}
/**
* Get label.
*
* @return string
*/
public function getLabel()
{
return $this->label;
}
public function getPerson(): Person
{
return $this->person;
}
/**
* Set key.
*
@@ -70,16 +101,6 @@ class PersonAltName
return $this;
}
/**
* Get key.
*
* @return string
*/
public function getKey()
{
return $this->key;
}
/**
* Set label.
*
@@ -95,31 +116,12 @@ class PersonAltName
}
/**
* Get label.
*
* @return string
*/
public function getLabel()
{
return $this->label;
}
/**
* @return Person
*/
public function getPerson(): Person
{
return $this->person;
}
/**
* @param Person|null $person
* @return $this
*/
public function setPerson(?Person $person = null)
{
$this->person = $person;
return $this;
}
}

View File

@@ -1,12 +1,20 @@
<?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.
*/
namespace Chill\PersonBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Chill\MainBundle\Entity\User;
use DateTime;
use Doctrine\ORM\Mapping as ORM;
/**
* PersonNotDuplicate
* PersonNotDuplicate.
*
* @ORM\Table(name="chill_person_not_duplicate")
* @ORM\Entity
@@ -14,8 +22,15 @@ use Chill\MainBundle\Entity\User;
class PersonNotDuplicate
{
/**
* The person's id
* @var integer
* @var DateTime
* @ORM\Column(type="datetime")
*/
private $date;
/**
* The person's id.
*
* @var int
*
* @ORM\Id
* @ORM\Column(name="id", type="integer")
@@ -37,12 +52,6 @@ class PersonNotDuplicate
*/
private $person2;
/**
* @var \DateTime
* @ORM\Column(type="datetime")
*/
private $date;
/**
* @var User
*
@@ -52,37 +61,7 @@ class PersonNotDuplicate
public function __construct()
{
$this->date = new \DateTime();
}
public function getId()
{
return $this->id;
}
public function setId($id)
{
$this->id = $id;
}
public function getPerson1()
{
return $this->person1;
}
public function setPerson1(Person $person1)
{
$this->person1 = $person1;
}
public function getPerson2()
{
return $this->person2;
}
public function setPerson2(Person $person2)
{
$this->person2 = $person2;
$this->date = new DateTime();
}
public function getDate()
@@ -90,9 +69,19 @@ class PersonNotDuplicate
return $this->date;
}
public function setDate(\DateTime $date)
public function getId()
{
$this->date = $date;
return $this->id;
}
public function getPerson1()
{
return $this->person1;
}
public function getPerson2()
{
return $this->person2;
}
public function getUser()
@@ -100,6 +89,26 @@ class PersonNotDuplicate
return $this->user;
}
public function setDate(DateTime $date)
{
$this->date = $date;
}
public function setId($id)
{
$this->id = $id;
}
public function setPerson1(Person $person1)
{
$this->person1 = $person1;
}
public function setPerson2(Person $person2)
{
$this->person2 = $person2;
}
public function setUser(User $user)
{
$this->user = $user;

View File

@@ -1,21 +1,38 @@
<?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.
*/
namespace Chill\PersonBundle\Entity;
use Chill\PersonBundle\Entity\Person;
use DateTime;
use Doctrine\ORM\Mapping as ORM;
/**
* Person Phones
* Person Phones.
*
* @ORM\Entity
* @ORM\Table(name="chill_person_phone",
* indexes={
* @ORM\Index(name="phonenumber", columns={"phonenumber"})
* })
* @ORM\Index(name="phonenumber", columns={"phonenumber"})
* })
*/
class PersonPhone
{
/**
* @ORM\Column(type="datetime", nullable=false)
*/
private DateTime $date;
/**
* @ORM\Column(type="text", nullable=true)
*/
private ?string $description = null;
/**
* @ORM\Id
* @ORM\Column(name="id", type="integer")
@@ -25,35 +42,35 @@ class PersonPhone
/**
* @ORM\ManyToOne(
* targetEntity="Chill\PersonBundle\Entity\Person",
* inversedBy="otherPhoneNumbers"
* targetEntity="Chill\PersonBundle\Entity\Person",
* inversedBy="otherPhoneNumbers"
* )
*/
private Person $person;
/**
* @ORM\Column(type="text", length=40, nullable=true)
*/
private ?string $type;
/**
* @ORM\Column(type="text", length=40, nullable=false)
*/
private string $phonenumber = '';
/**
* @ORM\Column(type="text", nullable=true)
* @ORM\Column(type="text", length=40, nullable=true)
*/
private ?string $description = null;
/**
* @ORM\Column(type="datetime", nullable=false)
*/
private \DateTime $date;
private ?string $type;
public function __construct()
{
$this->date = new \DateTime();
$this->date = new DateTime();
}
public function getDate(): DateTime
{
return $this->date;
}
public function getDescription(): ?string
{
return $this->description;
}
public function getId(): int
@@ -66,9 +83,9 @@ class PersonPhone
return $this->person;
}
public function setPerson(Person $person): void
public function getPhonenumber(): string
{
$this->person = $person;
return $this->phonenumber;
}
public function getType(): string
@@ -76,24 +93,14 @@ class PersonPhone
return $this->type;
}
public function setType(string $type): void
public function isEmpty(): bool
{
$this->type = $type;
return empty($this->getDescription()) && empty($this->getPhonenumber());
}
public function getPhonenumber(): string
public function setDate(DateTime $date): void
{
return $this->phonenumber;
}
public function setPhonenumber(string $phonenumber): void
{
$this->phonenumber = $phonenumber;
}
public function getDescription(): ?string
{
return $this->description;
$this->date = $date;
}
public function setDescription(?string $description): void
@@ -101,18 +108,18 @@ class PersonPhone
$this->description = $description;
}
public function getDate(): \DateTime
public function setPerson(Person $person): void
{
return $this->date;
$this->person = $person;
}
public function setDate(\DateTime $date): void
public function setPhonenumber(string $phonenumber): void
{
$this->date = $date;
$this->phonenumber = $phonenumber;
}
public function isEmpty(): bool
public function setType(string $type): void
{
return empty($this->getDescription()) && empty($this->getPhonenumber());
$this->type = $type;
}
}

View File

@@ -1,17 +1,23 @@
<?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.
*/
namespace Chill\PersonBundle\Entity\Relationships;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\DiscriminatorColumn;
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
use Symfony\Component\Serializer\Annotation as Serializer;
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
/**
* @ORM\Entity()
* @ORM\Entity
* @ORM\Table(name="chill_person_relations")
* @DiscriminatorMap(typeProperty="type", mapping={
* "relation"=Relation::class
* "relation": Relation::class
* })
*/
class Relation
@@ -25,10 +31,10 @@ class Relation
private ?int $id = null;
/**
* @ORM\Column(type="json", nullable=true)
* @ORM\Column(type="boolean", nullable=true)
* @Serializer\Groups({"read"})
*/
private array $title = [];
private bool $isActive = true;
/**
* @ORM\Column(type="json", nullable=true)
@@ -37,33 +43,38 @@ class Relation
private array $reverseTitle = [];
/**
* @ORM\Column(type="boolean", nullable=true)
* @ORM\Column(type="json", nullable=true)
* @Serializer\Groups({"read"})
*/
private bool $isActive = true;
private array $title = [];
public function getId(): ?int
{
return $this->id;
}
public function getIsActive(): bool
{
return $this->isActive;
}
public function getReverseTitle(): ?array
{
return $this->reverseTitle;
}
public function getTitle(): ?array
{
return $this->title;
}
public function setTitle(?array $title): self
public function setIsActive(?bool $isActive): self
{
$this->title = $title;
$this->isActive = $isActive;
return $this;
}
public function getReverseTitle(): ?array
{
return $this->reverseTitle;
}
public function setReverseTitle(?array $reverseTitle): self
{
$this->reverseTitle = $reverseTitle;
@@ -71,14 +82,9 @@ class Relation
return $this;
}
public function getIsActive(): bool
public function setTitle(?array $title): self
{
return $this->isActive;
}
public function setIsActive(?bool $isActive): self
{
$this->isActive = $isActive;
$this->title = $title;
return $this;
}

View File

@@ -1,30 +1,55 @@
<?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.
*/
namespace Chill\PersonBundle\Entity\Relationships;
use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface;
use Chill\MainBundle\Entity\User;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Entity\Relationships\Relation;
use DateTimeImmutable;
use DateTimeInterface;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
use Doctrine\ORM\Mapping\DiscriminatorColumn;
use Symfony\Component\Serializer\Annotation as Serializer;
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity()
* @ORM\Entity
* @ORM\Table(name="chill_person_relationships")
* @DiscriminatorColumn(name="relation_id", type="integer")
* @DiscriminatorMap(typeProperty="type", mapping={
* "relationship"=Relationship::class
* "relationship": Relationship::class
* })
*
*/
class Relationship implements TrackCreationInterface, TrackUpdateInterface
{
/**
* @ORM\Column(type="datetime_immutable")
*/
private ?DateTimeImmutable $createdAt = null;
/**
* @ORM\ManyToOne(targetEntity=User::class)
* @ORM\JoinColumn(nullable=false)
*/
private ?User $createdBy = null;
/**
* @ORM\ManyToOne(targetEntity=Person::class)
* @ORM\JoinColumn(nullable=false)
* @Assert\NotNull
* @Serializer\Groups({"read", "write"})
*/
private ?Person $fromPerson = null;
/**
* @ORM\Id
* @ORM\GeneratedValue
@@ -33,65 +58,50 @@ class Relationship implements TrackCreationInterface, TrackUpdateInterface
*/
private ?int $id = null;
/**
* @ORM\ManyToOne(targetEntity=Person::class)
* @ORM\JoinColumn(nullable=false)
* @Assert\NotNull()
* @Serializer\Groups({"read", "write"})
*/
private ?Person $fromPerson = null;
/**
* @ORM\ManyToOne(targetEntity=Person::class)
* @ORM\JoinColumn(nullable=false)
* @Assert\NotNull()
* @Serializer\Groups({"read", "write"})
*/
private ?Person $toPerson = null;
/**
* @ORM\ManyToOne(targetEntity=Relation::class)
* @ORM\JoinColumn(nullable=false, name="relation_id", referencedColumnName="id")
* @Assert\NotNull()
* @Assert\NotNull
* @Serializer\Groups({"read", "write"})
*/
private ?Relation $relation = null;
/**
* @ORM\Column(type="boolean")
* @Assert\Type(
* type="bool",
* message="This must be of type boolean"
* type="bool",
* message="This must be of type boolean"
* )
* @Serializer\Groups({"read", "write"})
*/
private bool $reverse;
/**
* @ORM\ManyToOne(targetEntity=User::class)
* @ORM\ManyToOne(targetEntity=Person::class)
* @ORM\JoinColumn(nullable=false)
* @Assert\NotNull
* @Serializer\Groups({"read", "write"})
*/
private ?User $createdBy = null;
/**
* @ORM\Column(type="datetime_immutable")
*/
private ?DateTimeImmutable $createdAt = null;
/**
* @ORM\ManyToOne(targetEntity=User::class)
*/
private ?User $updatedBy = null;
private ?Person $toPerson = null;
/**
* @ORM\Column(type="datetime_immutable", nullable=true)
*/
private ?DateTimeImmutable $updatedAt = null;
/**
* @ORM\ManyToOne(targetEntity=User::class)
*/
private ?User $updatedBy = null;
public function getId(): ?int
public function getCreatedAt(): ?DateTimeImmutable
{
return $this->id;
return $this->createdAt;
}
public function getCreatedBy(): ?User
{
return $this->createdBy;
}
public function getFromPerson(): ?Person
@@ -99,23 +109,14 @@ class Relationship implements TrackCreationInterface, TrackUpdateInterface
return $this->fromPerson;
}
public function setFromPerson(?Person $fromPerson): self
public function getId(): ?int
{
$this->fromPerson = $fromPerson;
return $this;
return $this->id;
}
public function getToPerson(): ?Person
public function getRelation(): ?Relation
{
return $this->toPerson;
}
public function setToPerson(?Person $toPerson): self
{
$this->toPerson = $toPerson;
return $this;
return $this->relation;
}
public function getReverse(): ?bool
@@ -123,16 +124,26 @@ class Relationship implements TrackCreationInterface, TrackUpdateInterface
return $this->reverse;
}
public function setReverse(bool $reverse): self
public function getToPerson(): ?Person
{
$this->reverse = $reverse;
return $this;
return $this->toPerson;
}
public function getCreatedBy(): ?User
public function getUpdatedAt(): ?DateTimeImmutable
{
return $this->createdBy;
return $this->updatedAt;
}
public function getUpdatedBy(): ?User
{
return $this->updatedBy;
}
public function setCreatedAt(DateTimeInterface $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
public function setCreatedBy(?User $user): self
@@ -142,51 +153,45 @@ class Relationship implements TrackCreationInterface, TrackUpdateInterface
return $this;
}
public function getCreatedAt(): ?\DateTimeImmutable
public function setFromPerson(?Person $fromPerson): self
{
return $this->createdAt;
}
public function setCreatedAt(\DateTimeInterface $createdAt): self
{
$this->createdAt = $createdAt;
$this->fromPerson = $fromPerson;
return $this;
}
public function getUpdatedBy(): ?User
{
return $this->updatedBy;
}
public function setUpdatedBy(?User $updatedBy): self
{
$this->updatedBy = $updatedBy;
return $this;
}
public function getUpdatedAt(): ?\DateTimeImmutable
{
return $this->updatedAt;
}
public function setUpdatedAt(?\DateTimeInterface $updatedAt): self
{
$this->updatedAt = $updatedAt;
return $this;
}
public function getRelation(): ?Relation
{
return $this->relation;
}
public function setRelation(?Relation $relation): self
{
$this->relation = $relation;
return $this;
}
}
public function setReverse(bool $reverse): self
{
$this->reverse = $reverse;
return $this;
}
public function setToPerson(?Person $toPerson): self
{
$this->toPerson = $toPerson;
return $this;
}
public function setUpdatedAt(?DateTimeInterface $updatedAt): self
{
$this->updatedAt = $updatedAt;
return $this;
}
public function setUpdatedBy(?User $updatedBy): self
{
$this->updatedBy = $updatedBy;
return $this;
}
}

View File

@@ -1,7 +1,15 @@
<?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.
*/
namespace Chill\PersonBundle\Entity\SocialWork;
use DateInterval;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation as Serializer;
@@ -9,11 +17,17 @@ use Symfony\Component\Serializer\Annotation as Serializer;
* @ORM\Entity
* @ORM\Table(name="chill_person_social_work_evaluation")
* @Serializer\DiscriminatorMap(typeProperty="type", mapping={
* "social_work_evaluation"=Evaluation::class
* })
* "social_work_evaluation": Evaluation::class
* })
*/
class Evaluation
{
/**
* @ORM\Column(type="dateinterval", nullable=true, options={"default": null})
* @Serializer\Groups({"read"})
*/
private $delay;
/**
* @ORM\Id
* @ORM\GeneratedValue
@@ -22,18 +36,6 @@ class Evaluation
*/
private $id;
/**
* @ORM\Column(type="json")
* @Serializer\Groups({"read"})
*/
private $title = [];
/**
* @ORM\Column(type="dateinterval", nullable=true, options={"default": null})
* @Serializer\Groups({"read"})
*/
private $delay;
/**
* @ORM\Column(type="dateinterval", nullable=true, options={"default": null})
* @Serializer\Groups({"read"})
@@ -48,56 +50,62 @@ class Evaluation
*/
private $socialAction;
/**
* @ORM\Column(type="json")
* @Serializer\Groups({"read"})
*/
private $title = [];
public function getDelay(): ?DateInterval
{
return $this->delay;
}
public function getId(): ?int
{
return $this->id;
}
public function getNotificationDelay(): ?DateInterval
{
return $this->notificationDelay;
}
public function getSocialAction(): ?SocialAction
{
return $this->socialAction;
}
public function getTitle(): array
{
return $this->title;
}
public function setTitle(array $title): self
{
$this->title = $title;
return $this;
}
public function getDelay(): ?\DateInterval
{
return $this->delay;
}
public function setDelay(\DateInterval $delay): self
public function setDelay(DateInterval $delay): self
{
$this->delay = $delay;
return $this;
}
public function getNotificationDelay(): ?\DateInterval
{
return $this->notificationDelay;
}
public function setNotificationDelay(\DateInterval $notificationDelay): self
public function setNotificationDelay(DateInterval $notificationDelay): self
{
$this->notificationDelay = $notificationDelay;
return $this;
}
public function getSocialAction(): ?SocialAction
{
return $this->socialAction;
}
public function setSocialAction(?SocialAction $socialAction): self
{
$this->socialAction = $socialAction;
return $this;
}
public function setTitle(array $title): self
{
$this->title = $title;
return $this;
}
}

View File

@@ -1,7 +1,15 @@
<?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.
*/
namespace Chill\PersonBundle\Entity\SocialWork;
use DateTimeInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
@@ -11,14 +19,19 @@ use Symfony\Component\Serializer\Annotation as Serializer;
* @ORM\Entity
* @ORM\Table(name="chill_person_social_work_goal")
* @Serializer\DiscriminatorMap(
* typeProperty="type",
* mapping={
* "social_work_goal":Goal::class
* }
* )
* typeProperty="type",
* mapping={
* "social_work_goal": Goal::class
* }
* )
*/
class Goal
{
/**
* @ORM\Column(type="datetime", nullable=true)
*/
private $desactivationDate;
/**
* @ORM\Id
* @ORM\GeneratedValue
@@ -28,15 +41,10 @@ class Goal
private $id;
/**
* @ORM\Column(type="json")
* @Serializer\Groups({"read"})
* @ORM\ManyToMany(targetEntity=Result::class, inversedBy="goals")
* @ORM\JoinTable(name="chill_person_social_work_goal_result")
*/
private $title = [];
/**
* @ORM\Column(type="datetime", nullable=true)
*/
private $desactivationDate;
private $results;
/**
* @ORM\ManyToMany(targetEntity=SocialAction::class, mappedBy="goals")
@@ -44,10 +52,10 @@ class Goal
private $socialActions;
/**
* @ORM\ManyToMany(targetEntity=Result::class, inversedBy="goals")
* @ORM\JoinTable(name="chill_person_social_work_goal_result")
* @ORM\Column(type="json")
* @Serializer\Groups({"read"})
*/
private $results;
private $title = [];
public function __construct()
{
@@ -55,67 +63,6 @@ class Goal
$this->results = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getTitle(): array
{
return $this->title;
}
public function setTitle(array $title): self
{
$this->title = $title;
return $this;
}
public function getDesactivationDate(): ?\DateTimeInterface
{
return $this->desactivationDate;
}
public function setDesactivationDate(?\DateTimeInterface $desactivationDate): self
{
$this->desactivationDate = $desactivationDate;
return $this;
}
/**
* @return Collection|SocialAction[]
*/
public function getSocialActions(): Collection
{
return $this->socialActions;
}
public function addSocialAction(SocialAction $socialAction): self
{
if (!$this->socialActions->contains($socialAction)) {
$this->socialActions[] = $socialAction;
}
return $this;
}
public function removeSocialAction(SocialAction $socialAction): self
{
$this->socialActions->removeElement($socialAction);
return $this;
}
/**
* @return Collection|Result[]
*/
public function getResults(): Collection
{
return $this->results;
}
public function addResult(Result $result): self
{
if (!$this->results->contains($result)) {
@@ -125,10 +72,71 @@ class Goal
return $this;
}
public function addSocialAction(SocialAction $socialAction): self
{
if (!$this->socialActions->contains($socialAction)) {
$this->socialActions[] = $socialAction;
}
return $this;
}
public function getDesactivationDate(): ?DateTimeInterface
{
return $this->desactivationDate;
}
public function getId(): ?int
{
return $this->id;
}
/**
* @return Collection|Result[]
*/
public function getResults(): Collection
{
return $this->results;
}
/**
* @return Collection|SocialAction[]
*/
public function getSocialActions(): Collection
{
return $this->socialActions;
}
public function getTitle(): array
{
return $this->title;
}
public function removeResult(Result $result): self
{
$this->results->removeElement($result);
return $this;
}
public function removeSocialAction(SocialAction $socialAction): self
{
$this->socialActions->removeElement($socialAction);
return $this;
}
public function setDesactivationDate(?DateTimeInterface $desactivationDate): self
{
$this->desactivationDate = $desactivationDate;
return $this;
}
public function setTitle(array $title): self
{
$this->title = $title;
return $this;
}
}

View File

@@ -1,9 +1,17 @@
<?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.
*/
namespace Chill\PersonBundle\Entity\SocialWork;
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork;
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkGoal;
use DateTimeInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
@@ -13,14 +21,34 @@ use Symfony\Component\Serializer\Annotation as Serializer;
* @ORM\Entity
* @ORM\Table(name="chill_person_social_work_result")
* @Serializer\DiscriminatorMap(
* typeProperty="type",
* mapping={
* "social_work_result":Result::class
* }
* )
* typeProperty="type",
* mapping={
* "social_work_result": Result::class
* }
* )
*/
class Result
{
/**
* @ORM\ManyToMany(targetEntity=AccompanyingPeriodWorkGoal::class, mappedBy="results")
*/
private $accompanyingPeriodWorkGoals;
/**
* @ORM\ManyToMany(targetEntity=AccompanyingPeriodWork::class, mappedBy="results")
*/
private $accompanyingPeriodWorks;
/**
* @ORM\Column(type="datetime", nullable=true)
*/
private $desactivationDate;
/**
* @ORM\ManyToMany(targetEntity=Goal::class, mappedBy="results")
*/
private $goals;
/**
* @ORM\Id
* @ORM\GeneratedValue
@@ -29,36 +57,16 @@ class Result
*/
private $id;
/**
* @ORM\Column(type="json")
* @Serializer\Groups({"read"})
*/
private $title = [];
/**
* @ORM\Column(type="datetime", nullable=true)
*/
private $desactivationDate;
/**
* @ORM\ManyToMany(targetEntity=SocialAction::class, mappedBy="results")
*/
private $socialActions;
/**
* @ORM\ManyToMany(targetEntity=Goal::class, mappedBy="results")
* @ORM\Column(type="json")
* @Serializer\Groups({"read"})
*/
private $goals;
/**
* @ORM\ManyToMany(targetEntity=AccompanyingPeriodWork::class, mappedBy="results")
*/
private $accompanyingPeriodWorks;
/**
* @ORM\ManyToMany(targetEntity=AccompanyingPeriodWorkGoal::class, mappedBy="results")
*/
private $accompanyingPeriodWorkGoals;
private $title = [];
public function __construct()
{
@@ -68,91 +76,6 @@ class Result
$this->accompanyingPeriodWorkGoals = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getTitle(): array
{
return $this->title;
}
public function setTitle(array $title): self
{
$this->title = $title;
return $this;
}
public function getDesactivationDate(): ?\DateTimeInterface
{
return $this->desactivationDate;
}
public function setDesactivationDate(?\DateTimeInterface $desactivationDate): self
{
$this->desactivationDate = $desactivationDate;
return $this;
}
/**
* @return Collection|SocialAction[]
*/
public function getSocialActions(): Collection
{
return $this->socialActions;
}
public function addSocialAction(SocialAction $socialAction): self
{
if (!$this->socialActions->contains($socialAction)) {
$this->socialActions[] = $socialAction;
}
return $this;
}
public function removeSocialAction(SocialAction $socialAction): self
{
$this->socialActions->removeElement($socialAction);
return $this;
}
/**
* @return Collection|Goal[]
*/
public function getGoals(): Collection
{
return $this->goals;
}
public function addGoal(Goal $goal): self
{
if (!$this->goals->contains($goal)) {
$this->goals[] = $goal;
}
return $this;
}
public function removeGoal(Goal $goal): self
{
$this->goals->removeElement($goal);
return $this;
}
/**
* @return Collection|AccompanyingPeriodWork[]
*/
public function getAccompanyingPeriodWorks(): Collection
{
return $this->accompanyingPeriodWorks;
}
public function addAccompanyingPeriodWork(AccompanyingPeriodWork $accompanyingPeriod): self
{
if (!$this->accompanyingPeriodWorks->contains($accompanyingPeriod)) {
@@ -162,26 +85,83 @@ class Result
return $this;
}
public function removeAccompanyingPeriodWork(AccompanyingPeriodWork $accompanyingPeriod): self
public function addAccompanyingPeriodWorkGoal(AccompanyingPeriodWorkGoal $accompanyingPeriodWorkGoal): self
{
$this->accompanyingPeriodWorks->removeElement($accompanyingPeriod);
if (!$this->accompanyingPeriodWorkGoals->contains($accompanyingPeriodWorkGoal)) {
$this->accompanyingPeriodWorkGoals[] = $accompanyingPeriodWorkGoal;
}
return $this;
}
public function addGoal(Goal $goal): self
{
if (!$this->goals->contains($goal)) {
$this->goals[] = $goal;
}
return $this;
}
public function addSocialAction(SocialAction $socialAction): self
{
if (!$this->socialActions->contains($socialAction)) {
$this->socialActions[] = $socialAction;
}
return $this;
}
/**
* @return Collection|AccompanyingPeriodWorkGoal[]
* @return AccompanyingPeriodWorkGoal[]|Collection
*/
public function getAccompanyingPeriodWorkGoals(): Collection
{
return $this->accompanyingPeriodWorkGoals;
}
public function addAccompanyingPeriodWorkGoal(AccompanyingPeriodWorkGoal $accompanyingPeriodWorkGoal): self
/**
* @return AccompanyingPeriodWork[]|Collection
*/
public function getAccompanyingPeriodWorks(): Collection
{
if (!$this->accompanyingPeriodWorkGoals->contains($accompanyingPeriodWorkGoal)) {
$this->accompanyingPeriodWorkGoals[] = $accompanyingPeriodWorkGoal;
}
return $this->accompanyingPeriodWorks;
}
public function getDesactivationDate(): ?DateTimeInterface
{
return $this->desactivationDate;
}
/**
* @return Collection|Goal[]
*/
public function getGoals(): Collection
{
return $this->goals;
}
public function getId(): ?int
{
return $this->id;
}
/**
* @return Collection|SocialAction[]
*/
public function getSocialActions(): Collection
{
return $this->socialActions;
}
public function getTitle(): array
{
return $this->title;
}
public function removeAccompanyingPeriodWork(AccompanyingPeriodWork $accompanyingPeriod): self
{
$this->accompanyingPeriodWorks->removeElement($accompanyingPeriod);
return $this;
}
@@ -192,4 +172,32 @@ class Result
return $this;
}
public function removeGoal(Goal $goal): self
{
$this->goals->removeElement($goal);
return $this;
}
public function removeSocialAction(SocialAction $socialAction): self
{
$this->socialActions->removeElement($socialAction);
return $this;
}
public function setDesactivationDate(?DateTimeInterface $desactivationDate): self
{
$this->desactivationDate = $desactivationDate;
return $this;
}
public function setTitle(array $title): self
{
$this->title = $title;
return $this;
}
}

View File

@@ -1,7 +1,16 @@
<?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.
*/
namespace Chill\PersonBundle\Entity\SocialWork;
use DateInterval;
use DateTimeInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
@@ -11,14 +20,43 @@ use Symfony\Component\Serializer\Annotation as Serializer;
* @ORM\Entity
* @ORM\Table(name="chill_person_social_action")
* @Serializer\DiscriminatorMap(
* typeProperty="type",
* mapping={
* "social_work_social_action":SocialAction::class
* }
* )
* typeProperty="type",
* mapping={
* "social_work_social_action": SocialAction::class
* }
* )
*/
class SocialAction
{
/**
* @ORM\OneToMany(targetEntity=SocialAction::class, mappedBy="parent")
*/
private $children;
/**
* @ORM\Column(type="dateinterval", nullable=true)
*/
private $defaultNotificationDelay;
/**
* @ORM\Column(type="datetime", nullable=true)
*/
private $desactivationDate;
/**
* @ORM\OneToMany(
* targetEntity=Evaluation::class,
* mappedBy="socialAction"
* )
*/
private Collection $evaluations;
/**
* @ORM\ManyToMany(targetEntity=Goal::class, inversedBy="socialActions")
* @ORM\JoinTable(name="chill_person_social_action_goal")
*/
private $goals;
/**
* @ORM\Id
* @ORM\GeneratedValue
@@ -26,11 +64,6 @@ class SocialAction
*/
private $id;
/**
* @ORM\Column(type="datetime", nullable=true)
*/
private $desactivationDate;
/**
* @ORM\ManyToOne(targetEntity=SocialIssue::class, inversedBy="socialActions")
*/
@@ -41,27 +74,6 @@ class SocialAction
*/
private $parent;
/**
* @ORM\OneToMany(targetEntity=SocialAction::class, mappedBy="parent")
*/
private $children;
/**
* @ORM\Column(type="dateinterval", nullable=true)
*/
private $defaultNotificationDelay;
/**
* @ORM\Column(type="json")
*/
private $title = [];
/**
* @ORM\ManyToMany(targetEntity=Goal::class, inversedBy="socialActions")
* @ORM\JoinTable(name="chill_person_social_action_goal")
*/
private $goals;
/**
* @ORM\ManyToMany(targetEntity=Result::class, inversedBy="socialActions")
* @ORM\JoinTable(name="chill_person_social_action_result")
@@ -69,13 +81,9 @@ class SocialAction
private $results;
/**
* @var Collection
* @ORM\OneToMany(
* targetEntity=Evaluation::class,
* mappedBy="socialAction"
* )
* @ORM\Column(type="json")
*/
private Collection $evaluations;
private $title = [];
public function __construct()
{
@@ -84,60 +92,6 @@ class SocialAction
$this->results = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getDesactivationDate(): ?\DateTimeInterface
{
return $this->desactivationDate;
}
public function setDesactivationDate(?\DateTimeInterface $desactivationDate): self
{
$this->desactivationDate = $desactivationDate;
return $this;
}
public function getIssue(): ?SocialIssue
{
return $this->issue;
}
public function setIssue(?SocialIssue $issue): self
{
$this->issue = $issue;
return $this;
}
public function getParent(): ?self
{
return $this->parent;
}
public function hasParent(): bool
{
return $this->getParent() instanceof self;
}
public function setParent(?self $parent): self
{
$this->parent = $parent;
return $this;
}
/**
* @return Collection|self[]
*/
public function getChildren(): Collection
{
return $this->children;
}
public function addChild(self $child): self
{
if (!$this->children->contains($child)) {
@@ -148,18 +102,42 @@ class SocialAction
return $this;
}
public function removeChild(self $child): self
public function addGoal(Goal $goal): self
{
if ($this->children->removeElement($child)) {
// set the owning side to null (unless already changed)
if ($child->getParent() === $this) {
$child->setParent(null);
}
if (!$this->goals->contains($goal)) {
$this->goals[] = $goal;
}
return $this;
}
public function addResult(Result $result): self
{
if (!$this->results->contains($result)) {
$this->results[] = $result;
}
return $this;
}
/**
* @return Collection|self[]
*/
public function getChildren(): Collection
{
return $this->children;
}
public function getDefaultNotificationDelay(): ?DateInterval
{
return $this->defaultNotificationDelay;
}
public function getDesactivationDate(): ?DateTimeInterface
{
return $this->desactivationDate;
}
/**
* @return Collection|self[] All the descendants (children, children of children, ...)
*/
@@ -168,10 +146,11 @@ class SocialAction
$descendants = new ArrayCollection();
foreach ($this->getChildren() as $child) {
if(! $descendants->contains($child)) {
if (!$descendants->contains($child)) {
$descendants->add($child);
foreach($child->getDescendants() as $descendantsOfChild) {
if(! $descendants->contains($descendantsOfChild)) {
foreach ($child->getDescendants() as $descendantsOfChild) {
if (!$descendants->contains($descendantsOfChild)) {
$descendants->add($descendantsOfChild);
}
}
@@ -188,35 +167,16 @@ class SocialAction
{
$descendants = $this->getDescendants();
if(! $descendants->contains($this)) {
if (!$descendants->contains($this)) {
$descendants->add($this);
}
return $descendants;
}
public function getDefaultNotificationDelay(): ?\DateInterval
public function getEvaluations(): Collection
{
return $this->defaultNotificationDelay;
}
public function setDefaultNotificationDelay(\DateInterval $defaultNotificationDelay): self
{
$this->defaultNotificationDelay = $defaultNotificationDelay;
return $this;
}
public function getTitle(): array
{
return $this->title;
}
public function setTitle(array $title): self
{
$this->title = $title;
return $this;
return $this->evaluations;
}
/**
@@ -227,10 +187,46 @@ class SocialAction
return $this->goals;
}
public function addGoal(Goal $goal): self
public function getId(): ?int
{
if (!$this->goals->contains($goal)) {
$this->goals[] = $goal;
return $this->id;
}
public function getIssue(): ?SocialIssue
{
return $this->issue;
}
public function getParent(): ?self
{
return $this->parent;
}
/**
* @return Collection|Result[]
*/
public function getResults(): Collection
{
return $this->results;
}
public function getTitle(): array
{
return $this->title;
}
public function hasParent(): bool
{
return $this->getParent() instanceof self;
}
public function removeChild(self $child): self
{
if ($this->children->removeElement($child)) {
// set the owning side to null (unless already changed)
if ($child->getParent() === $this) {
$child->setParent(null);
}
}
return $this;
@@ -243,23 +239,6 @@ class SocialAction
return $this;
}
/**
* @return Collection|Result[]
*/
public function getResults(): Collection
{
return $this->results;
}
public function addResult(Result $result): self
{
if (!$this->results->contains($result)) {
$this->results[] = $result;
}
return $this;
}
public function removeResult(Result $result): self
{
$this->results->removeElement($result);
@@ -267,11 +246,38 @@ class SocialAction
return $this;
}
/**
* @return Collection
*/
public function getEvaluations(): Collection
public function setDefaultNotificationDelay(DateInterval $defaultNotificationDelay): self
{
return $this->evaluations;
$this->defaultNotificationDelay = $defaultNotificationDelay;
return $this;
}
public function setDesactivationDate(?DateTimeInterface $desactivationDate): self
{
$this->desactivationDate = $desactivationDate;
return $this;
}
public function setIssue(?SocialIssue $issue): self
{
$this->issue = $issue;
return $this;
}
public function setParent(?self $parent): self
{
$this->parent = $parent;
return $this;
}
public function setTitle(array $title): self
{
$this->title = $title;
return $this;
}
}

View File

@@ -1,21 +1,40 @@
<?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.
*/
namespace Chill\PersonBundle\Entity\SocialWork;
use DateTimeInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* @ORM\Entity
* @ORM\Table(name="chill_person_social_issue")
* @DiscriminatorMap(typeProperty="type", mapping={
* "social_issue"=SocialIssue::class
* "social_issue": SocialIssue::class
* })
*/
class SocialIssue
{
/**
* @ORM\OneToMany(targetEntity=SocialIssue::class, mappedBy="parent")
*/
private $children;
/**
* @ORM\Column(type="datetime", nullable=true)
*/
private $desactivationDate;
/**
* @ORM\Id
* @ORM\GeneratedValue
@@ -29,14 +48,9 @@ class SocialIssue
private $parent;
/**
* @ORM\OneToMany(targetEntity=SocialIssue::class, mappedBy="parent")
* @ORM\OneToMany(targetEntity=SocialAction::class, mappedBy="issue")
*/
private $children;
/**
* @ORM\Column(type="datetime", nullable=true)
*/
private $desactivationDate;
private $socialActions;
/**
* @ORM\Column(type="json")
@@ -44,47 +58,12 @@ class SocialIssue
*/
private $title = [];
/**
* @ORM\OneToMany(targetEntity=SocialAction::class, mappedBy="issue")
*/
private $socialActions;
public function __construct()
{
$this->children = new ArrayCollection();
$this->socialActions = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getParent(): ?self
{
return $this->parent;
}
public function hasParent(): bool
{
return $this->parent !== null;
}
public function setParent(?self $parent): self
{
$this->parent = $parent;
return $this;
}
/**
* @return Collection|self[]
*/
public function getChildren(): Collection
{
return $this->children;
}
public function addChild(self $child): self
{
if (!$this->children->contains($child)) {
@@ -95,18 +74,64 @@ class SocialIssue
return $this;
}
public function removeChild(self $child): self
public function addSocialAction(SocialAction $socialAction): self
{
if ($this->children->removeElement($child)) {
// set the owning side to null (unless already changed)
if ($child->getParent() === $this) {
$child->setParent(null);
}
if (!$this->socialActions->contains($socialAction)) {
$this->socialActions[] = $socialAction;
$socialAction->setSocialIssue($this);
}
return $this;
}
/**
* In a SocialIssues's collection, find the elements which are an ancestor of
* other elements.
*
* Removing those elements of the Collection (which is not done by this method)
* will ensure that only the most descendent elements are present in the collection,
* (any ancestor of another element are present).
*
* @param Collection|SocialIssue[] $socialIssues
*
* @return Collection|SocialIssue[]
*/
public static function findAncestorSocialIssues(Collection $socialIssues): Collection
{
$ancestors = new ArrayCollection();
foreach ($socialIssues as $candidateChild) {
if ($ancestors->contains($candidateChild)) {
continue;
}
foreach ($socialIssues as $candidateParent) {
if ($ancestors->contains($candidateParent)) {
continue;
}
if ($candidateChild->isDescendantOf($candidateParent)) {
$ancestors->add($candidateParent);
}
}
}
return $ancestors;
}
/**
* @return Collection|self[]
*/
public function getChildren(): Collection
{
return $this->children;
}
public function getDesactivationDate(): ?DateTimeInterface
{
return $this->desactivationDate;
}
/**
* @return Collection|self[] All the descendants (children, children of children, ...)
*/
@@ -115,10 +140,11 @@ class SocialIssue
$descendants = new ArrayCollection();
foreach ($this->getChildren() as $child) {
if(! $descendants->contains($child)) {
if (!$descendants->contains($child)) {
$descendants->add($child);
foreach($child->getDescendants() as $descendantsOfChild) {
if(! $descendants->contains($descendantsOfChild)) {
foreach ($child->getDescendants() as $descendantsOfChild) {
if (!$descendants->contains($descendantsOfChild)) {
$descendants->add($descendantsOfChild);
}
}
@@ -128,6 +154,24 @@ class SocialIssue
return $descendants;
}
/**
* @return Collection|SocialAction[] All the descendant social actions of the entity
*/
public function getDescendantsSocialActions(): Collection
{
$descendantsSocialActions = new ArrayCollection();
foreach ($this->getSocialActions() as $socialAction) {
foreach ($socialAction->getDescendantsWithThis() as $descendant) {
if (!$descendantsSocialActions->contains($descendant)) {
$descendantsSocialActions->add($descendant);
}
}
}
return $descendantsSocialActions;
}
/**
* @return Collection|self[] All the descendants with the current entity (this)
*/
@@ -135,36 +179,40 @@ class SocialIssue
{
$descendants = $this->getDescendants();
if(! $descendants->contains($this)) {
if (!$descendants->contains($this)) {
$descendants->add($this);
}
return $descendants;
}
public function getDesactivationDate(): ?\DateTimeInterface
public function getId(): ?int
{
return $this->desactivationDate;
return $this->id;
}
public function setDesactivationDate(?\DateTimeInterface $desactivationDate): self
public function getParent(): ?self
{
$this->desactivationDate = $desactivationDate;
return $this;
return $this->parent;
}
public function getTitle(): array
/**
* @return Collection|SocialAction[] All the descendant social actions of all
* the descendants of the entity
*/
public function getRecursiveSocialActions(): Collection
{
return $this->title;
}
$recursiveSocialActions = new ArrayCollection();
public function setTitle(array $title): self
{
$this->title = $title;
foreach ($this->getDescendantsWithThis() as $socialIssue) {
foreach ($socialIssue->getDescendantsSocialActions() as $descendant) {
if (!$recursiveSocialActions->contains($descendant)) {
$recursiveSocialActions->add($descendant);
}
}
}
return $this;
return $recursiveSocialActions;
}
/**
@@ -175,11 +223,40 @@ class SocialIssue
return $this->socialActions;
}
public function addSocialAction(SocialAction $socialAction): self
public function getTitle(): array
{
if (!$this->socialActions->contains($socialAction)) {
$this->socialActions[] = $socialAction;
$socialAction->setSocialIssue($this);
return $this->title;
}
public function hasParent(): bool
{
return null !== $this->parent;
}
/**
* Recursive method which return true if the current $issue is a descendant
* of the $issue given in parameter.
*/
public function isDescendantOf(SocialIssue $issue): bool
{
if (!$this->hasParent()) {
return false;
}
if ($this->getParent() === $issue) {
return true;
}
return $this->getParent()->isDescendantOf($issue);
}
public function removeChild(self $child): self
{
if ($this->children->removeElement($child)) {
// set the owning side to null (unless already changed)
if ($child->getParent() === $this) {
$child->setParent(null);
}
}
return $this;
@@ -197,93 +274,24 @@ class SocialIssue
return $this;
}
/**
* @return Collection|SocialAction[] All the descendant social actions of the entity
*/
public function getDescendantsSocialActions(): Collection
public function setDesactivationDate(?DateTimeInterface $desactivationDate): self
{
$descendantsSocialActions = new ArrayCollection();
$this->desactivationDate = $desactivationDate;
foreach ($this->getSocialActions() as $socialAction) {
foreach ($socialAction->getDescendantsWithThis() as $descendant) {
if(! $descendantsSocialActions->contains($descendant)) {
$descendantsSocialActions->add($descendant);
}
}
}
return $descendantsSocialActions;
return $this;
}
/**
* @return Collection|SocialAction[] All the descendant social actions of all
* the descendants of the entity
*/
public function getRecursiveSocialActions(): Collection
public function setParent(?self $parent): self
{
$recursiveSocialActions = new ArrayCollection();
$this->parent = $parent;
foreach ($this->getDescendantsWithThis() as $socialIssue) {
foreach ($socialIssue->getDescendantsSocialActions() as $descendant) {
if(! $recursiveSocialActions->contains($descendant)) {
$recursiveSocialActions->add($descendant);
}
}
}
return $recursiveSocialActions;
return $this;
}
/**
* Recursive method which return true if the current $issue is a descendant
* of the $issue given in parameter.
*
* @param SocialIssue $issue
* @return bool
*/
public function isDescendantOf(SocialIssue $issue): bool
public function setTitle(array $title): self
{
if (!$this->hasParent()) {
return false;
}
$this->title = $title;
if ($this->getParent() === $issue) {
return true;
}
return $this->getParent()->isDescendantOf($issue);
}
/**
* In a SocialIssues's collection, find the elements which are an ancestor of
* other elements.
*
* Removing those elements of the Collection (which is not done by this method)
* will ensure that only the most descendent elements are present in the collection,
* (any ancestor of another element are present).
*
* @param Collection|SocialIssue[] $socialIssues
* @return Collection|SocialIssue[]
*/
public static function findAncestorSocialIssues(Collection $socialIssues): Collection
{
$ancestors = new ArrayCollection();
foreach ($socialIssues as $candidateChild) {
if ($ancestors->contains($candidateChild)) {
continue;
}
foreach ($socialIssues as $candidateParent) {
if ($ancestors->contains($candidateParent)) {
continue;
}
if ($candidateChild->isDescendantOf($candidateParent)) {
$ancestors->add($candidateParent);
}
}
}
return $ancestors;
return $this;
}
}

View File

@@ -1,17 +1,27 @@
<?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\PersonBundle\EventListener;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Entity\PersonAltName;
use Doctrine\Persistence\Event\LifecycleEventArgs;
use LogicException;
use Symfony\Component\Validator\Exception\LogicException as ExceptionLogicException;
class PersonEventListener
{
public function prePersistAltName(PersonAltName $altname)
{
$altnameCaps = mb_strtoupper($altname->getLabel(), 'UTF-8');
$altname->setLabel($altnameCaps);
}
public function prePersistPerson(Person $person): void
{
$firstnameCaps = mb_convert_case(mb_strtolower($person->getFirstName()), MB_CASE_TITLE, 'UTF-8');
@@ -21,10 +31,4 @@ class PersonEventListener
$lastnameCaps = mb_strtoupper($person->getLastName(), 'UTF-8');
$person->setLastName($lastnameCaps);
}
public function prePersistAltName(PersonAltName $altname)
{
$altnameCaps = mb_strtoupper($altname->getLabel(), 'UTF-8');
$altname->setLabel($altnameCaps);
}
}

Some files were not shown because too many files have changed in this diff Show More