Merge branch '50-ajout-problematique-sociale-modele' into 139_demandeur

This commit is contained in:
Julien Fastré 2021-05-18 16:11:18 +02:00
commit e095cac7e0
15 changed files with 607 additions and 10 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -414,6 +414,27 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
],
]
],
[
'class' => \Chill\PersonBundle\Entity\SocialWork\SocialIssue::class,
'name' => 'social_work_social_issue',
'base_path' => '/api/1.0/person/social-work/social-issue',
// 'controller' => \Chill\PersonBundle\Controller\OpeningApiController::class,
'base_role' => 'ROLE_USER',
'actions' => [
'_index' => [
'methods' => [
Request::METHOD_GET => true,
Request::METHOD_HEAD => true
],
],
'_entity' => [
'methods' => [
Request::METHOD_GET => true,
Request::METHOD_HEAD => true
]
],
]
],
]
]);
}

View File

@ -27,6 +27,7 @@ use Chill\PersonBundle\Entity\AccompanyingPeriod\ClosingMotive;
use Chill\PersonBundle\Entity\AccompanyingPeriod\Comment;
use Chill\PersonBundle\Entity\AccompanyingPeriod\Origin;
use Chill\PersonBundle\Entity\AccompanyingPeriod\Resource;
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
@ -241,6 +242,16 @@ class AccompanyingPeriod
*/
private $resources;
/**
* @ORM\ManyToMany(
* targetEntity=SocialIssue::class
* )
* @ORM\JoinTable(
* name="chill_person_accompanying_period_social_issues"
* )
*/
private Collection $socialIssues;
/**
* AccompanyingPeriod constructor.
*
@ -251,6 +262,7 @@ class AccompanyingPeriod
$this->setOpeningDate($dateOpening);
$this->participations = new ArrayCollection();
$this->scopes = new ArrayCollection();
$this->socialIssues = new ArrayCollection();
}
/**
@ -461,7 +473,7 @@ class AccompanyingPeriod
return false;
}
$participation = $this->participationsContainsPerson($person);
$participation = $this->getParticipationsContainsPerson($person);
if (!null === $participation)
{
$person = $participation->getPerson();
@ -710,6 +722,23 @@ class AccompanyingPeriod
$this->resources->removeElement($resource);
}
public function getSocialIssues(): Collection
{
return $this->socialIssues;
}
public function addSocialIssues(SocialIssue $socialIssue): self
{
$this->socialIssues[] = $socialIssue;
return $this;
}
public function removeSocialIssue(SocialIssue $socialissue): void
{
$this->socialIssues->removeElement($socialIssue);
}
/**
* Get a list of all persons which are participating to this course
*/

View File

@ -6,10 +6,15 @@ use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository;
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;
/**
* @ORM\Entity(repositoryClass=SocialIssueRepository::class)
* @ORM\Table(name="chill_person_social_issue")
* @DiscriminatorMap(typeProperty="type", mapping={
* "social_issue"=SocialIssue::class
* })
*/
class SocialIssue
{
@ -37,6 +42,7 @@ class SocialIssue
/**
* @ORM\Column(type="json")
* @Groups({"read"})
*/
private $title = [];
@ -61,6 +67,11 @@ class SocialIssue
return $this->parent;
}
public function hasParent(): bool
{
return $this->parent !== null;
}
public function setParent(?self $parent): self
{
$this->parent = $parent;

View File

@ -0,0 +1,43 @@
<?php
namespace Chill\PersonBundle\Serializer\Normalizer;
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
use Chill\PersonBundle\Templating\Entity\SocialIssueRender;
class SocialIssueNormalizer implements NormalizerInterface, NormalizerAwareInterface
{
private SocialIssueRender $render;
use NormalizerAwareTrait;
/**
* @param SocialIssueRender $render
*/
public function __construct(SocialIssueRender $render)
{
$this->render = $render;
}
public function normalize($socialIssue, string $format = null, array $context = [])
{
/** @var SocialIssue $socialIssue */
return [
'type' => 'social_issue',
'id' => $socialIssue->getId(),
'parent_id' => $socialIssue->hasParent() ? $socialIssue->getParent()->getId() : null,
'children_ids' => $socialIssue->getChildren()->map(function (SocialIssue $si) { return $si->getId(); }),
'title' => $socialIssue->getTitle(),
'text' => $this->render->renderString($socialIssue, [])
];
}
public function supportsNormalization($data, string $format = null): bool
{
return $data instanceof SocialIssue;
}
}

View File

@ -0,0 +1,50 @@
<?php
namespace Chill\PersonBundle\Templating\Entity;
use Chill\MainBundle\Templating\Entity\ChillEntityRenderInterface;
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
use Chill\MainBundle\Templating\TranslatableStringHelper;
class SocialIssueRender implements ChillEntityRenderInterface
{
private TranslatableStringHelper $translatableStringHelper;
public const SEPARATOR_KEY = 'default.separator';
public const DEFAULT_ARGS = [
self::SEPARATOR_KEY => ' > ',
];
public function __construct(TranslatableStringHelper $translatableStringHelper)
{
$this->translatableStringHelper = $translatableStringHelper;
}
public function supports($entity, array $options): bool
{
return $entity instanceof SocialIssueRender;
}
public function renderString($socialIssue, array $options): string
{
/** @var $socialIssue SocialIssue */
$options = \array_merge(self::DEFAULT_ARGS, $options);
$str = $this->translatableStringHelper->localize($socialIssue->getTitle());
while ($socialIssue->hasParent()) {
$socialIssue = $socialIssue->getParent();
$str .= $options[self::SEPARATOR_KEY].$this->translatableStringHelper->localize(
$socialIssue->getTitle()
);
}
return $str;
}
public function renderBox($entity, array $options): string
{
return "renderBox not implemented for social issue";
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace Chill\PersonBundle\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\HttpFoundation\Request;
use Chill\MainBundle\Test\PrepareClientTrait;
class SocialIssueApiControllerTest extends WebTestCase
{
use PrepareClientTrait;
public function setUp()
{
parent::setUp();
self::bootKernel();
}
public function testList(): array
{
$client = $this->getClientAuthenticated();
$client->request(Request::METHOD_GET, '/api/1.0/person/social-work/social-issue.json');
$this->assertEquals(200, $client->getResponse()->getStatusCode());
$data = \json_decode($client->getResponse()->getContent(), true);
$this->assertGreaterThan(0, $data['count']);
$this->assertGreaterThan(0, count($data['results']));
return $data;
}
/**
* @depends testList
*/
public function testItem(array $data): void
{
$socialIssues = $data['results'];
shuffle($socialIssues);
$socialIssue = \array_pop($socialIssues);
$client = $this->getClientAuthenticated();
$client->request(Request::METHOD_GET, sprintf('/api/1.0/person/social-work/social-issue/%d.json', $socialIssue['id']));
$this->assertEquals(200, $client->getResponse()->getStatusCode());
$data = \json_decode($client->getResponse()->getContent(), true);
$this->assertArrayHasKey('id', $data);
$this->assertArrayHasKey('type', $data);
}
}

View File

@ -34,3 +34,8 @@ services:
arguments:
- '@Doctrine\Persistence\ManagerRegistry'
tags: [ doctrine.repository_service ]
Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository:
arguments:
- '@Doctrine\Persistence\ManagerRegistry'
tags: [ doctrine.repository_service ]

View File

@ -1,3 +1,10 @@
---
services:
# note: normalizers are loaded from ../services.yaml
Chill\PersonBundle\Serializer\Normalizer\:
autowire: true
resource: '../../Serializer/Normalizer'
tags:
- { name: 'serializer.normalizer', priority: 64 }

View File

@ -1,4 +1,9 @@
services:
Chill\PersonBundle\Templating\Entity\:
resource: '../../Templating/Entity'
tags:
- 'chill.render_entity'
Chill\PersonBundle\Templating\Entity\PersonRender:
arguments:
$configAltNamesHelper: '@Chill\PersonBundle\Config\ConfigPersonAltNamesHelper'
@ -8,5 +13,7 @@ services:
Chill\PersonBundle\Templating\Entity\ClosingMotiveRender:
arguments:
$translatableStringHelper: '@Chill\MainBundle\Templating\TranslatableStringHelper'
tags:
- 'chill.render_entity'
Chill\PersonBundle\Templating\Entity\SocialIssueRender:
arguments:
$translatableStringHelper: '@Chill\MainBundle\Templating\TranslatableStringHelper'

View File

@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
namespace Chill\Migrations\Person;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Add a link between social issues and accompanying periods
*/
final class Version20210518075908 extends AbstractMigration
{
public function getDescription(): string
{
return 'Add a link between social issue and accompanying period';
}
public function up(Schema $schema): void
{
$this->addSql('CREATE TABLE chill_person_accompanying_period_social_issues (accompanyingperiod_id INT NOT NULL, socialissue_id INT NOT NULL, PRIMARY KEY(accompanyingperiod_id, socialissue_id))');
$this->addSql('CREATE INDEX IDX_CAFE078F550B0C53 ON chill_person_accompanying_period_social_issues (accompanyingperiod_id)');
$this->addSql('CREATE INDEX IDX_CAFE078FA549916C ON chill_person_accompanying_period_social_issues (socialissue_id)');
$this->addSql('ALTER TABLE chill_person_accompanying_period_social_issues ADD CONSTRAINT FK_CAFE078F550B0C53 FOREIGN KEY (accompanyingperiod_id) REFERENCES chill_person_accompanying_period (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE chill_person_accompanying_period_social_issues ADD CONSTRAINT FK_CAFE078FA549916C FOREIGN KEY (socialissue_id) REFERENCES chill_person_social_issue (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
}
public function down(Schema $schema): void
{
$this->addSql('DROP TABLE chill_person_accompanying_period_social_issues');
}
}