mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Creation of PersonResource
This commit is contained in:
parent
7513187a6d
commit
88d1fe24b4
@ -11,6 +11,7 @@ and this project adheres to
|
|||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
<!-- write down unreleased development here -->
|
<!-- write down unreleased development here -->
|
||||||
|
* [person]: possibility to add person resources (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/382)
|
||||||
|
|
||||||
## Test releases
|
## Test releases
|
||||||
|
|
||||||
@ -32,7 +33,6 @@ and this project adheres to
|
|||||||
* add My workflow section with my opened subscriptions
|
* add My workflow section with my opened subscriptions
|
||||||
* apply workflow on documents, accompanyingCourseWork and Evaluations
|
* apply workflow on documents, accompanyingCourseWork and Evaluations
|
||||||
* [wopi-link] a new vue component allow to open wopi link in a fullscreen chill-themed modal
|
* [wopi-link] a new vue component allow to open wopi link in a fullscreen chill-themed modal
|
||||||
<!-- end -->
|
|
||||||
|
|
||||||
### test release 2022-01-19
|
### test release 2022-01-19
|
||||||
* vuejs: add dead information on all on-the-fly person render boxes, in vis graph and other templates (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/271)
|
* vuejs: add dead information on all on-the-fly person render boxes, in vis graph and other templates (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/271)
|
||||||
@ -40,6 +40,7 @@ and this project adheres to
|
|||||||
* [main] location form type: fix unmapped address field (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/246)
|
* [main] location form type: fix unmapped address field (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/246)
|
||||||
* [activity] fix wrong import of js assets for adding and viewing documents in activity (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/83 & https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/176)
|
* [activity] fix wrong import of js assets for adding and viewing documents in activity (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/83 & https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/176)
|
||||||
* [person]: space added between deathdate and age in twig renderbox (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/380)
|
* [person]: space added between deathdate and age in twig renderbox (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/380)
|
||||||
|
* [forms] dynamic picker types for user/person/thirdparty types created (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/386)
|
||||||
|
|
||||||
### test release 2022-01-17
|
### test release 2022-01-17
|
||||||
|
|
||||||
@ -49,10 +50,14 @@ and this project adheres to
|
|||||||
* [main] Add mainLocation field to User entity and add it in user form type
|
* [main] Add mainLocation field to User entity and add it in user form type
|
||||||
* [course list in person context] show full username/label for ref
|
* [course list in person context] show full username/label for ref
|
||||||
* [accompanying period work] remove the possibility to generate document from an accompanying period work
|
* [accompanying period work] remove the possibility to generate document from an accompanying period work
|
||||||
|
* vuejs: add validation on required fields for AddPerson, Address and Location components
|
||||||
|
* vuejs: treat 422 validation errors in locations and AddPerson components
|
||||||
|
* [person]: space added between deathdate and age in twig renderbox (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/380)
|
||||||
|
|
||||||
## Test releases
|
## Test releases
|
||||||
* vuejs: add validation on required fields for AddPerson, Address and Location components
|
* vuejs: add validation on required fields for AddPerson, Address and Location components
|
||||||
* vuejs: treat 422 validation errors in locations and AddPerson components
|
* vuejs: treat 422 validation errors in locations and AddPerson components
|
||||||
|
* [person]: space added between deathdate and age in twig renderbox (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/380)
|
||||||
|
|
||||||
### test release 2022-01-12
|
### test release 2022-01-12
|
||||||
|
|
||||||
|
@ -29,13 +29,9 @@ use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
|
|||||||
final class ActivityVoterTest extends KernelTestCase
|
final class ActivityVoterTest extends KernelTestCase
|
||||||
{
|
{
|
||||||
use PrepareActivityTrait;
|
use PrepareActivityTrait;
|
||||||
|
|
||||||
use PrepareCenterTrait;
|
use PrepareCenterTrait;
|
||||||
|
|
||||||
use PreparePersonTrait;
|
use PreparePersonTrait;
|
||||||
|
|
||||||
use PrepareScopeTrait;
|
use PrepareScopeTrait;
|
||||||
|
|
||||||
use PrepareUserTrait;
|
use PrepareUserTrait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,7 +37,6 @@ use function count;
|
|||||||
class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface
|
class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface
|
||||||
{
|
{
|
||||||
use TrackCreationTrait;
|
use TrackCreationTrait;
|
||||||
|
|
||||||
use TrackUpdateTrait;
|
use TrackUpdateTrait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,7 +24,6 @@ use Doctrine\ORM\Mapping as ORM;
|
|||||||
class EntityWorkflowComment implements TrackCreationInterface, TrackUpdateInterface
|
class EntityWorkflowComment implements TrackCreationInterface, TrackUpdateInterface
|
||||||
{
|
{
|
||||||
use TrackCreationTrait;
|
use TrackCreationTrait;
|
||||||
|
|
||||||
use TrackUpdateTrait;
|
use TrackUpdateTrait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -12,14 +12,18 @@ declare(strict_types=1);
|
|||||||
namespace Chill\MainBundle\Form\Type\DataTransformer;
|
namespace Chill\MainBundle\Form\Type\DataTransformer;
|
||||||
|
|
||||||
use Chill\MainBundle\Entity\User;
|
use Chill\MainBundle\Entity\User;
|
||||||
|
use Chill\PersonBundle\Entity\Person;
|
||||||
|
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||||
use Symfony\Component\Form\DataTransformerInterface;
|
use Symfony\Component\Form\DataTransformerInterface;
|
||||||
use Symfony\Component\Form\Exception\TransformationFailedException;
|
use Symfony\Component\Form\Exception\TransformationFailedException;
|
||||||
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
||||||
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
||||||
use Symfony\Component\Serializer\SerializerInterface;
|
use Symfony\Component\Serializer\SerializerInterface;
|
||||||
|
use UnexpectedValueException;
|
||||||
|
|
||||||
use function array_key_exists;
|
use function array_key_exists;
|
||||||
|
|
||||||
class UserToJsonTransformer implements DataTransformerInterface
|
class EntityToJsonTransformer implements DataTransformerInterface
|
||||||
{
|
{
|
||||||
private DenormalizerInterface $denormalizer;
|
private DenormalizerInterface $denormalizer;
|
||||||
|
|
||||||
@ -27,17 +31,22 @@ class UserToJsonTransformer implements DataTransformerInterface
|
|||||||
|
|
||||||
private SerializerInterface $serializer;
|
private SerializerInterface $serializer;
|
||||||
|
|
||||||
public function __construct(DenormalizerInterface $denormalizer, SerializerInterface $serializer, bool $multiple)
|
private string $type;
|
||||||
|
|
||||||
|
public function __construct(DenormalizerInterface $denormalizer, SerializerInterface $serializer, bool $multiple, string $type)
|
||||||
{
|
{
|
||||||
$this->denormalizer = $denormalizer;
|
$this->denormalizer = $denormalizer;
|
||||||
$this->serializer = $serializer;
|
$this->serializer = $serializer;
|
||||||
$this->multiple = $multiple;
|
$this->multiple = $multiple;
|
||||||
|
$this->type = $type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function reverseTransform($value)
|
public function reverseTransform($value)
|
||||||
{
|
{
|
||||||
$denormalized = json_decode($value, true);
|
$denormalized = json_decode($value, true);
|
||||||
|
|
||||||
|
dump($value);
|
||||||
|
|
||||||
if ($this->multiple) {
|
if ($this->multiple) {
|
||||||
if (null === $denormalized) {
|
if (null === $denormalized) {
|
||||||
return [];
|
return [];
|
||||||
@ -49,6 +58,10 @@ class UserToJsonTransformer implements DataTransformerInterface
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ('' === $value) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return $this->denormalizeOne($denormalized);
|
return $this->denormalizeOne($denormalized);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,7 +79,7 @@ class UserToJsonTransformer implements DataTransformerInterface
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function denormalizeOne(array $item): User
|
private function denormalizeOne(array $item)
|
||||||
{
|
{
|
||||||
if (!array_key_exists('type', $item)) {
|
if (!array_key_exists('type', $item)) {
|
||||||
throw new TransformationFailedException('the key "type" is missing on element');
|
throw new TransformationFailedException('the key "type" is missing on element');
|
||||||
@ -76,10 +89,30 @@ class UserToJsonTransformer implements DataTransformerInterface
|
|||||||
throw new TransformationFailedException('the key "id" is missing on element');
|
throw new TransformationFailedException('the key "id" is missing on element');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch ($this->type) {
|
||||||
|
case 'user':
|
||||||
|
$class = User::class;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'person':
|
||||||
|
$class = Person::class;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'thirdparty':
|
||||||
|
$class = ThirdParty::class;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new UnexpectedValueException('This type is not supported');
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
$this->denormalizer->denormalize(
|
$this->denormalizer->denormalize(
|
||||||
['type' => $item['type'], 'id' => $item['id']],
|
['type' => $item['type'], 'id' => $item['id']],
|
||||||
User::class,
|
$class,
|
||||||
'json',
|
'json',
|
||||||
[AbstractNormalizer::GROUPS => ['read']],
|
[AbstractNormalizer::GROUPS => ['read']],
|
||||||
);
|
);
|
@ -12,7 +12,7 @@ declare(strict_types=1);
|
|||||||
namespace Chill\MainBundle\Form\Type;
|
namespace Chill\MainBundle\Form\Type;
|
||||||
|
|
||||||
use Chill\MainBundle\Entity\User;
|
use Chill\MainBundle\Entity\User;
|
||||||
use Chill\MainBundle\Form\Type\DataTransformer\UserToJsonTransformer;
|
use Chill\MainBundle\Form\Type\DataTransformer\EntityToJsonTransformer;
|
||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Component\Form\FormInterface;
|
use Symfony\Component\Form\FormInterface;
|
||||||
@ -38,7 +38,7 @@ class PickUserDynamicType extends AbstractType
|
|||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
{
|
{
|
||||||
$builder->addViewTransformer(new UserToJsonTransformer($this->denormalizer, $this->serializer, $options['multiple']));
|
$builder->addViewTransformer(new EntityToJsonTransformer($this->denormalizer, $this->serializer, $options['multiple'], 'user'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildView(FormView $view, FormInterface $form, array $options)
|
public function buildView(FormView $view, FormInterface $form, array $options)
|
||||||
@ -58,6 +58,6 @@ class PickUserDynamicType extends AbstractType
|
|||||||
|
|
||||||
public function getBlockPrefix()
|
public function getBlockPrefix()
|
||||||
{
|
{
|
||||||
return 'pick_user_dynamic';
|
return 'pick_entity_dynamic';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@ var ShowHide = function(options) {
|
|||||||
contents.push(el);
|
contents.push(el);
|
||||||
}
|
}
|
||||||
container_content.push(contents);
|
container_content.push(contents);
|
||||||
|
// console.log('container content', container_content);
|
||||||
}
|
}
|
||||||
|
|
||||||
// attach the listener on each input
|
// attach the listener on each input
|
||||||
|
@ -5,18 +5,22 @@ import { appMessages } from 'ChillMainAssets/vuejs/PickEntity/i18n';
|
|||||||
|
|
||||||
const i18n = _createI18n(appMessages);
|
const i18n = _createI18n(appMessages);
|
||||||
|
|
||||||
window.addEventListener('DOMContentLoaded', function(e) {
|
let appsOnPage = new Map();
|
||||||
|
|
||||||
let apps = document.querySelectorAll('[data-module="pick-dynamic"]');
|
|
||||||
|
function loadDynamicPicker(element) {
|
||||||
|
|
||||||
|
let apps = element.querySelectorAll('[data-module="pick-dynamic"]');
|
||||||
|
|
||||||
apps.forEach(function(el) {
|
apps.forEach(function(el) {
|
||||||
|
|
||||||
const
|
const
|
||||||
isMultiple = parseInt(el.dataset.multiple) === 1,
|
isMultiple = parseInt(el.dataset.multiple) === 1,
|
||||||
input = document.querySelector('[data-input-uniqid="'+ el.dataset.uniqid +'"]'),
|
uniqId = el.dataset.uniqid,
|
||||||
picked = isMultiple ? JSON.parse(input.value) : [JSON.parse(input.value)];
|
input = element.querySelector('[data-input-uniqid="'+ el.dataset.uniqid +'"]'),
|
||||||
|
picked = (isMultiple) ? (JSON.parse(input.value)) : ((input.value === '[]') ? (null) : ([JSON.parse(input.value)]));
|
||||||
|
|
||||||
createApp({
|
const app = createApp({
|
||||||
template: '<pick-entity ' +
|
template: '<pick-entity ' +
|
||||||
':multiple="multiple" ' +
|
':multiple="multiple" ' +
|
||||||
':types="types" ' +
|
':types="types" ' +
|
||||||
@ -65,5 +69,36 @@ window.addEventListener('DOMContentLoaded', function(e) {
|
|||||||
})
|
})
|
||||||
.use(i18n)
|
.use(i18n)
|
||||||
.mount(el);
|
.mount(el);
|
||||||
|
|
||||||
|
appsOnPage.set(uniqId, app);
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// document.addEventListener('show-hide-show', function(e) {
|
||||||
|
// console.log('creation event caught')
|
||||||
|
// loadDynamicPicker(e.detail.container)
|
||||||
|
// })
|
||||||
|
|
||||||
|
// document.addEventListener('show-hide-hide', function(e) {
|
||||||
|
// console.log('hiding event caught')
|
||||||
|
// e.detail.container.querySelectorAll('[data-module="pick-dynamic"]').forEach((el) => {
|
||||||
|
// let uniqId = el.dataset.uniqid;
|
||||||
|
// console.log(uniqId);
|
||||||
|
// if (appsOnPage.has(uniqId)) {
|
||||||
|
// appsOnPage.get(uniqId).unmount();
|
||||||
|
// console.log('App has been unmounted')
|
||||||
|
// appsOnPage.delete(uniqId);
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// })
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', function(e) {
|
||||||
|
console.log('loaded event', e)
|
||||||
|
loadDynamicPicker(document)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<ul class="list-suggest remove-items">
|
<ul class="list-suggest remove-items" v-if="picked.length">
|
||||||
<li v-for="p in picked" @click="removeEntity(p)" :key="p.type+p.id">
|
<li v-for="p in picked" @click="removeEntity(p)" :key="p.type+p.id">
|
||||||
<span class="chill_denomination">{{ p.text }}</span>
|
<span class="chill_denomination">{{ p.text }}</span>
|
||||||
</li>
|
</li>
|
||||||
@ -79,11 +79,15 @@ export default {
|
|||||||
);
|
);
|
||||||
this.$refs.addPersons.resetSearch(); // to cast child method
|
this.$refs.addPersons.resetSearch(); // to cast child method
|
||||||
modal.showModal = false;
|
modal.showModal = false;
|
||||||
|
console.log(this.picked)
|
||||||
},
|
},
|
||||||
removeEntity(entity) {
|
removeEntity(entity) {
|
||||||
console.log('remove entity', entity);
|
console.log('remove entity', entity);
|
||||||
this.$emit('removeEntity', entity);
|
this.$emit('removeEntity', entity);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
mounted() {
|
||||||
|
console.log(this.picked);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -216,7 +216,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block pick_user_dynamic_widget %}
|
{% block pick_entity_dynamic_widget %}
|
||||||
<input type="hidden" {{ block('widget_attributes') }} {% if value is not empty %}value="{{ value }}" {% endif %} data-input-uniqid="{{ form.vars['uniqid'] }}"/>
|
<input type="hidden" {{ block('widget_attributes') }} {% if value is not empty %}value="{{ value }}" {% endif %} data-input-uniqid="{{ form.vars['uniqid'] }}"/>
|
||||||
<div data-module="pick-dynamic" data-types="{{ form.vars['types']|json_encode }}" data-multiple="{{ form.vars['multiple'] }}" data-uniqid="{{ form.vars['uniqid'] }}"></div>
|
<div data-module="pick-dynamic" data-types="{{ form.vars['types']|json_encode }}" data-multiple="{{ form.vars['multiple'] }}" data-uniqid="{{ form.vars['uniqid'] }}"></div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -44,9 +44,7 @@ use function count;
|
|||||||
final class ExportManagerTest extends KernelTestCase
|
final class ExportManagerTest extends KernelTestCase
|
||||||
{
|
{
|
||||||
use PrepareCenterTrait;
|
use PrepareCenterTrait;
|
||||||
|
|
||||||
use PrepareScopeTrait;
|
use PrepareScopeTrait;
|
||||||
|
|
||||||
use PrepareUserTrait;
|
use PrepareUserTrait;
|
||||||
|
|
||||||
private Prophet $prophet;
|
private Prophet $prophet;
|
||||||
|
@ -34,11 +34,8 @@ use function in_array;
|
|||||||
final class AuthorizationHelperTest extends KernelTestCase
|
final class AuthorizationHelperTest extends KernelTestCase
|
||||||
{
|
{
|
||||||
use PrepareCenterTrait;
|
use PrepareCenterTrait;
|
||||||
|
|
||||||
use PrepareScopeTrait;
|
use PrepareScopeTrait;
|
||||||
|
|
||||||
use PrepareUserTrait;
|
use PrepareUserTrait;
|
||||||
|
|
||||||
use ProphecyTrait;
|
use ProphecyTrait;
|
||||||
|
|
||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
|
@ -0,0 +1,178 @@
|
|||||||
|
<?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\PersonBundle\Entity\Person\PersonResource;
|
||||||
|
use Chill\PersonBundle\Form\PersonResourceType;
|
||||||
|
use Chill\PersonBundle\Repository\PersonRepository;
|
||||||
|
use Chill\PersonBundle\Repository\PersonResourceRepository;
|
||||||
|
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
|
final class PersonResourceController extends AbstractController
|
||||||
|
{
|
||||||
|
private EntityManagerInterface $em;
|
||||||
|
|
||||||
|
private PersonRepository $personRepository;
|
||||||
|
|
||||||
|
private PersonResourceRepository $personResourceRepository;
|
||||||
|
|
||||||
|
private TranslatorInterface $translator;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
PersonResourceRepository $personResourceRepository,
|
||||||
|
PersonRepository $personRepository,
|
||||||
|
EntityManagerInterface $em,
|
||||||
|
TranslatorInterface $translator
|
||||||
|
) {
|
||||||
|
$this->personResourceRepository = $personResourceRepository;
|
||||||
|
$this->personRepository = $personRepository;
|
||||||
|
$this->em = $em;
|
||||||
|
$this->translator = $translator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteAction(Request $request, $person_id, $resource_id): Response
|
||||||
|
{
|
||||||
|
$personOwner = $this->personRepository->find($person_id);
|
||||||
|
$resource = $this->personResourceRepository->find($resource_id);
|
||||||
|
|
||||||
|
$this->denyAccessUnlessGranted(PersonVoter::UPDATE, $personOwner);
|
||||||
|
|
||||||
|
if (null === $resource) {
|
||||||
|
throw $this->createNotFoundException('Unable to find Resource entity.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$form = $this->createFormBuilder()
|
||||||
|
->setAction($this->generateUrl('chill_person_resource_delete', [
|
||||||
|
'resource_id' => $resource_id,
|
||||||
|
'person_id' => $person_id,
|
||||||
|
]))
|
||||||
|
->setMethod('DELETE')
|
||||||
|
->add('submit', SubmitType::class, ['label' => 'Delete'])
|
||||||
|
->getForm();
|
||||||
|
|
||||||
|
if ($request->getMethod() === Request::METHOD_DELETE) {
|
||||||
|
$form->handleRequest($request);
|
||||||
|
|
||||||
|
if ($form->isValid()) {
|
||||||
|
$this->em->remove($resource);
|
||||||
|
$this->em->flush();
|
||||||
|
|
||||||
|
$this->addFlash('success', $this->translator
|
||||||
|
->trans('The resource has been successfully removed.'));
|
||||||
|
|
||||||
|
return $this->redirectToRoute('chill_person_resource_list', [
|
||||||
|
'person_id' => $personOwner->getId(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render(
|
||||||
|
'ChillPersonBundle:PersonResource:delete.html.twig',
|
||||||
|
[
|
||||||
|
'person' => $personOwner,
|
||||||
|
'resource' => $resource,
|
||||||
|
'form' => $form->createView(),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function editAction(Request $request, $resource_id, $person_id): Response
|
||||||
|
{
|
||||||
|
$resource = $this->personResourceRepository->find($resource_id);
|
||||||
|
$personOwner = $this->personRepository->find($person_id);
|
||||||
|
|
||||||
|
$this->denyAccessUnlessGranted(PersonVoter::UPDATE, $personOwner);
|
||||||
|
|
||||||
|
if (null === $resource) {
|
||||||
|
throw $this->createNotFoundException('Unable to find Resource entity.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$form = $this->createForm(PersonResourceType::class, $resource);
|
||||||
|
$form->handleRequest($request);
|
||||||
|
|
||||||
|
if ($form->isSubmitted() && $form->isValid()) {
|
||||||
|
$this->em->persist($resource);
|
||||||
|
$this->em->flush();
|
||||||
|
|
||||||
|
return $this->redirectToRoute('chill_person_resource_list', [
|
||||||
|
'person_id' => $personOwner->getId(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
dump($resource);
|
||||||
|
|
||||||
|
return $this->render(
|
||||||
|
'ChillPersonBundle:PersonResource:edit.html.twig',
|
||||||
|
[
|
||||||
|
'person' => $personOwner,
|
||||||
|
'resource' => $resource,
|
||||||
|
'form' => $form->createView(),
|
||||||
|
'action' => 'edit',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function listAction(Request $request, $person_id)
|
||||||
|
{
|
||||||
|
$personOwner = $this->personRepository->find($person_id);
|
||||||
|
$this->denyAccessUnlessGranted(PersonVoter::SEE, $personOwner);
|
||||||
|
|
||||||
|
$personResources = [];
|
||||||
|
$personResources = $this->personResourceRepository->findBy(['personOwner' => $personOwner->getId()]);
|
||||||
|
|
||||||
|
$form = $this->createForm(PersonResourceType::class);
|
||||||
|
|
||||||
|
$form->handleRequest($request);
|
||||||
|
|
||||||
|
if ($request->getMethod() === Request::METHOD_POST && $form->isValid()) {
|
||||||
|
$this->denyAccessUnlessGranted(PersonVoter::CREATE, $personOwner);
|
||||||
|
|
||||||
|
$personResource = new PersonResource();
|
||||||
|
|
||||||
|
$person = $form['person']->getData();
|
||||||
|
$thirdparty = $form['thirdparty']->getData();
|
||||||
|
$freetext = $form['freetext']->getData();
|
||||||
|
$comment = $form['comment']->getData();
|
||||||
|
$kind = $form['kind']->getData();
|
||||||
|
|
||||||
|
$personResource->setKind($kind);
|
||||||
|
$personResource->setPerson($person);
|
||||||
|
$personResource->setThirdParty($thirdparty);
|
||||||
|
$personResource->setFreeText($freetext);
|
||||||
|
$personResource->setComment($comment);
|
||||||
|
|
||||||
|
$personResource->setPersonOwner($personOwner);
|
||||||
|
|
||||||
|
$this->em->persist($personResource);
|
||||||
|
$this->em->flush();
|
||||||
|
|
||||||
|
return $this->redirectToRoute('chill_person_resource_list', [
|
||||||
|
'person_id' => $personOwner->getId(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render(
|
||||||
|
'ChillPersonBundle:PersonResource:list.html.twig',
|
||||||
|
[
|
||||||
|
'person' => $personOwner,
|
||||||
|
'personResources' => $personResources,
|
||||||
|
'form' => $form->createView(),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -33,7 +33,6 @@ use Symfony\Component\Validator\Constraints as Assert;
|
|||||||
class HouseholdComposition implements TrackCreationInterface, TrackUpdateInterface
|
class HouseholdComposition implements TrackCreationInterface, TrackUpdateInterface
|
||||||
{
|
{
|
||||||
use TrackCreationTrait;
|
use TrackCreationTrait;
|
||||||
|
|
||||||
use TrackUpdateTrait;
|
use TrackUpdateTrait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
275
src/Bundle/ChillPersonBundle/Entity/Person/PersonResource.php
Normal file
275
src/Bundle/ChillPersonBundle/Entity/Person/PersonResource.php
Normal file
@ -0,0 +1,275 @@
|
|||||||
|
<?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\Entity\Person;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
|
||||||
|
use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface;
|
||||||
|
use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
|
||||||
|
use Chill\MainBundle\Entity\User;
|
||||||
|
use Chill\PersonBundle\Entity\Person;
|
||||||
|
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||||
|
use DateTime;
|
||||||
|
use DateTimeInterface;
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
|
||||||
|
use Symfony\Component\Serializer\Annotation\Groups;
|
||||||
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Entity
|
||||||
|
* @ORM\Table(name="chill_person_resource")
|
||||||
|
* @DiscriminatorMap(typeProperty="type", mapping={
|
||||||
|
* "personResource": personResource::class
|
||||||
|
* })
|
||||||
|
*/
|
||||||
|
class PersonResource implements TrackCreationInterface, TrackUpdateInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @ORM\Embedded(class="Chill\MainBundle\Entity\Embeddable\CommentEmbeddable", columnPrefix="comment_")
|
||||||
|
* @Groups({"read"})
|
||||||
|
*/
|
||||||
|
private CommentEmbeddable $comment;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(type="datetime")
|
||||||
|
*/
|
||||||
|
private $createdAt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\ManyToOne(targetEntity=User::class)
|
||||||
|
* @ORM\JoinColumn(nullable=false)
|
||||||
|
*/
|
||||||
|
private User $createdBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(type="text", nullable=true)
|
||||||
|
* @Groups({"read"})
|
||||||
|
*/
|
||||||
|
private $freeText;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Id
|
||||||
|
* @ORM\GeneratedValue
|
||||||
|
* @ORM\Column(type="integer")
|
||||||
|
*/
|
||||||
|
private ?int $id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\ManyToOne(targetEntity=PersonResourceKind::class, inversedBy="personResources")
|
||||||
|
* @ORM\JoinColumn(nullable=true)
|
||||||
|
* @Groups({"read"})
|
||||||
|
*/
|
||||||
|
private $kind;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\ManyToOne(targetEntity=Person::class, inversedBy="personResources")
|
||||||
|
* @ORM\JoinColumn(nullable=true)
|
||||||
|
* @Groups({"read"})
|
||||||
|
*/
|
||||||
|
private ?Person $person = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\ManyToOne(targetEntity=Person::class)
|
||||||
|
* @ORM\JoinColumn(nullable=false)
|
||||||
|
* @Groups({"read"})
|
||||||
|
*/
|
||||||
|
private ?Person $personOwner = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\ManyToOne(targetEntity=ThirdParty::class, inversedBy="personResources")
|
||||||
|
* @ORM\JoinColumn(nullable=true)
|
||||||
|
* @Groups({"read"})
|
||||||
|
*/
|
||||||
|
private ?ThirdParty $thirdParty = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(type="datetime", nullable=true)
|
||||||
|
*/
|
||||||
|
private $updatedAt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\ManyToOne(targetEntity=User::class)
|
||||||
|
*/
|
||||||
|
private User $updatedBy;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->comment = new CommentEmbeddable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getComment(): CommentEmbeddable
|
||||||
|
{
|
||||||
|
return $this->comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCreatedAt(): ?DateTimeInterface
|
||||||
|
{
|
||||||
|
return $this->createdAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCreatedBy(): ?User
|
||||||
|
{
|
||||||
|
return $this->createdBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFreeText(): ?string
|
||||||
|
{
|
||||||
|
return $this->freeText;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GETTERS.
|
||||||
|
*/
|
||||||
|
public function getId(): ?int
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getKind(): ?PersonResourceKind
|
||||||
|
{
|
||||||
|
return $this->kind;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPerson(): ?Person
|
||||||
|
{
|
||||||
|
return $this->person;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPersonOwner(): ?Person
|
||||||
|
{
|
||||||
|
return $this->personOwner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getThirdParty(): ?ThirdParty
|
||||||
|
{
|
||||||
|
return $this->thirdParty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUpdatedAt(): ?DateTimeInterface
|
||||||
|
{
|
||||||
|
return $this->updatedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUpdatedBy(): ?User
|
||||||
|
{
|
||||||
|
return $this->updatedBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setComment(?CommentEmbeddable $comment): self
|
||||||
|
{
|
||||||
|
if (null === $comment) {
|
||||||
|
$this->comment->setComment('');
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->comment = $comment;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setCreatedAt(DateTimeInterface $createdAt): self
|
||||||
|
{
|
||||||
|
$this->createdAt = $createdAt;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setCreatedBy(?User $createdBy): self
|
||||||
|
{
|
||||||
|
$this->createdBy = $createdBy;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SETTERS.
|
||||||
|
*/
|
||||||
|
public function setFreeText(?string $freeText): self
|
||||||
|
{
|
||||||
|
$this->freeText = $freeText;
|
||||||
|
|
||||||
|
if ('' !== $freeText && null !== $freeText) {
|
||||||
|
$this->setPerson(null);
|
||||||
|
$this->setThirdParty(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setKind(?PersonResourceKind $kind): self
|
||||||
|
{
|
||||||
|
$this->kind = $kind;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setPerson(?Person $person): self
|
||||||
|
{
|
||||||
|
$this->person = $person;
|
||||||
|
|
||||||
|
if (null !== $person) {
|
||||||
|
$this->setFreeText('');
|
||||||
|
$this->setThirdParty(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setPersonOwner(?Person $personOwner): self
|
||||||
|
{
|
||||||
|
$this->personOwner = $personOwner;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setThirdParty(?ThirdParty $thirdParty): self
|
||||||
|
{
|
||||||
|
$this->thirdParty = $thirdParty;
|
||||||
|
|
||||||
|
if (null !== $thirdParty) {
|
||||||
|
$this->setFreeText('');
|
||||||
|
$this->setPerson(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setUpdatedAt(DateTimeInterface $updatedAt): self
|
||||||
|
{
|
||||||
|
$this->updatedAt = $updatedAt;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setUpdatedBy(?User $updatedBy): self
|
||||||
|
{
|
||||||
|
$this->updatedBy = $updatedBy;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Assert\Callback
|
||||||
|
*
|
||||||
|
* @param mixed $payload
|
||||||
|
*/
|
||||||
|
public function validate(ExecutionContextInterface $context, $payload)
|
||||||
|
{
|
||||||
|
if (null === $this->person && null === $this->thirdParty && null === $this->freeText) {
|
||||||
|
$context->buildViolation('You must associate at least one entity')
|
||||||
|
->atPath('person')
|
||||||
|
->addViolation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
<?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\Entity\Person;
|
||||||
|
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* **About denormalization**: this operation is operated by @see{AccompanyingPeriodResourdeNormalizer}.
|
||||||
|
*
|
||||||
|
* @ORM\Entity
|
||||||
|
* @ORM\Table(name="chill_person_resource_kind")
|
||||||
|
*/
|
||||||
|
class PersonResourceKind
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @ORM\Id
|
||||||
|
* @ORM\GeneratedValue
|
||||||
|
* @ORM\Column(type="integer")
|
||||||
|
*/
|
||||||
|
private int $id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(type="boolean")
|
||||||
|
*/
|
||||||
|
private bool $isActive = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(type="json", length=255)
|
||||||
|
*/
|
||||||
|
private array $title;
|
||||||
|
|
||||||
|
public function getId(): ?int
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIsActive(): bool
|
||||||
|
{
|
||||||
|
return $this->isActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTitle(): ?array
|
||||||
|
{
|
||||||
|
return $this->title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setIsActive(bool $isActive): self
|
||||||
|
{
|
||||||
|
$this->isActive = $isActive;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setTitle(array $title): self
|
||||||
|
{
|
||||||
|
$this->title = $title;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
95
src/Bundle/ChillPersonBundle/Form/PersonResourceType.php
Normal file
95
src/Bundle/ChillPersonBundle/Form/PersonResourceType.php
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
<?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\Form;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Form\Type\ChillTextareaType;
|
||||||
|
use Chill\MainBundle\Form\Type\CommentType;
|
||||||
|
use Chill\PersonBundle\Entity\Person\PersonResource;
|
||||||
|
use Chill\PersonBundle\Entity\Person\PersonResourceKind;
|
||||||
|
use Chill\PersonBundle\Form\Type\PickPersonDynamicType;
|
||||||
|
use Chill\PersonBundle\Templating\Entity\PersonRender;
|
||||||
|
use Chill\PersonBundle\Templating\Entity\ResourceKindRender;
|
||||||
|
use Chill\ThirdPartyBundle\Form\Type\PickThirdpartyDynamicType;
|
||||||
|
use Chill\ThirdPartyBundle\Templating\Entity\ThirdPartyRender;
|
||||||
|
use Doctrine\ORM\EntityRepository;
|
||||||
|
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
|
final class PersonResourceType extends AbstractType
|
||||||
|
{
|
||||||
|
private PersonRender $personRender;
|
||||||
|
|
||||||
|
private ResourceKindRender $resourceKindRender;
|
||||||
|
|
||||||
|
private ThirdPartyRender $thirdPartyRender;
|
||||||
|
|
||||||
|
private TranslatorInterface $translator;
|
||||||
|
|
||||||
|
public function __construct(ResourceKindRender $resourceKindRender, PersonRender $personRender, ThirdPartyRender $thirdPartyRender, TranslatorInterface $translator)
|
||||||
|
{
|
||||||
|
$this->resourceKindRender = $resourceKindRender;
|
||||||
|
$this->personRender = $personRender;
|
||||||
|
$this->thirdPartyRender = $thirdPartyRender;
|
||||||
|
$this->translator = $translator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
|
{
|
||||||
|
$builder
|
||||||
|
->add('kind', EntityType::class, [
|
||||||
|
'label' => 'Type',
|
||||||
|
'required' => false,
|
||||||
|
'class' => PersonResourceKind::class,
|
||||||
|
'query_builder' => static function (EntityRepository $er) {
|
||||||
|
$qb = $er->createQueryBuilder('pr');
|
||||||
|
$qb->where($qb->expr()->eq('pr.isActive', 'TRUE'));
|
||||||
|
|
||||||
|
return $qb;
|
||||||
|
},
|
||||||
|
'placeholder' => $this->translator->trans('Select a type'),
|
||||||
|
'choice_label' => function (PersonResourceKind $personResourceKind) {
|
||||||
|
$options = [];
|
||||||
|
|
||||||
|
return $this->resourceKindRender->renderString($personResourceKind, $options);
|
||||||
|
},
|
||||||
|
])
|
||||||
|
->add('person', PickPersonDynamicType::class, [
|
||||||
|
'label' => 'Usager',
|
||||||
|
])
|
||||||
|
->add('thirdparty', PickThirdpartyDynamicType::class, [
|
||||||
|
'label' => 'Tiers',
|
||||||
|
])
|
||||||
|
->add('freetext', ChillTextareaType::class, [
|
||||||
|
'label' => 'Description libre',
|
||||||
|
'required' => false,
|
||||||
|
])
|
||||||
|
->add('comment', CommentType::class, [
|
||||||
|
'label' => 'Note',
|
||||||
|
'required' => false,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configureOptions(OptionsResolver $resolver): void
|
||||||
|
{
|
||||||
|
$resolver->setDefaults([
|
||||||
|
'data_class' => PersonResource::class,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getBlockPrefix(): string
|
||||||
|
{
|
||||||
|
return 'chill_personbundle_person_resource';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Chill\PersonBundle\Form\Type;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Form\Type\DataTransformer\EntityToJsonTransformer;
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
use Symfony\Component\Form\FormInterface;
|
||||||
|
use Symfony\Component\Form\FormView;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
||||||
|
use Symfony\Component\Serializer\SerializerInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pick user dymically, using vuejs module "AddPerson".
|
||||||
|
*/
|
||||||
|
class PickPersonDynamicType extends AbstractType
|
||||||
|
{
|
||||||
|
private DenormalizerInterface $denormalizer;
|
||||||
|
|
||||||
|
private SerializerInterface $serializer;
|
||||||
|
|
||||||
|
public function __construct(DenormalizerInterface $denormalizer, SerializerInterface $serializer)
|
||||||
|
{
|
||||||
|
$this->denormalizer = $denormalizer;
|
||||||
|
$this->serializer = $serializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
|
{
|
||||||
|
$builder->addViewTransformer(new EntityToJsonTransformer($this->denormalizer, $this->serializer, $options['multiple'], 'person'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildView(FormView $view, FormInterface $form, array $options)
|
||||||
|
{
|
||||||
|
$view->vars['multiple'] = $options['multiple'];
|
||||||
|
$view->vars['types'] = ['person'];
|
||||||
|
$view->vars['uniqid'] = uniqid('pick_user_dyn');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
|
{
|
||||||
|
$resolver
|
||||||
|
->setDefault('multiple', false)
|
||||||
|
->setAllowedTypes('multiple', ['bool'])
|
||||||
|
->setDefault('compound', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getBlockPrefix()
|
||||||
|
{
|
||||||
|
return 'pick_entity_dynamic';
|
||||||
|
}
|
||||||
|
}
|
@ -96,6 +96,16 @@ class PersonMenuBuilder implements LocalMenuBuilderInterface
|
|||||||
'order' => 100,
|
'order' => 100,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$menu->addChild($this->translator->trans('person_resources_menu'), [
|
||||||
|
'route' => 'chill_person_resource_list',
|
||||||
|
'routeParameters' => [
|
||||||
|
'person_id' => $parameters['person']->getId(),
|
||||||
|
],
|
||||||
|
])
|
||||||
|
->setExtras([
|
||||||
|
'order' => 99999,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getMenuIds(): array
|
public static function getMenuIds(): array
|
||||||
|
@ -0,0 +1,61 @@
|
|||||||
|
<?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\Repository;
|
||||||
|
|
||||||
|
use Chill\PersonBundle\Entity\Person\PersonResource;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Doctrine\ORM\EntityRepository;
|
||||||
|
use Doctrine\Persistence\ObjectRepository;
|
||||||
|
|
||||||
|
final class PersonResourceRepository implements ObjectRepository
|
||||||
|
{
|
||||||
|
private EntityRepository $repository;
|
||||||
|
|
||||||
|
public function __construct(EntityManagerInterface $entityManager)
|
||||||
|
{
|
||||||
|
$this->repository = $entityManager->getRepository(PersonResource::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function find($id): ?PersonResource
|
||||||
|
{
|
||||||
|
return $this->repository->find($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return PersonResource[]
|
||||||
|
*/
|
||||||
|
public function findAll(): array
|
||||||
|
{
|
||||||
|
return $this->repository->findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed|null $limit
|
||||||
|
* @param mixed|null $offset
|
||||||
|
*
|
||||||
|
* @return PersonResource[]
|
||||||
|
*/
|
||||||
|
public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null): array
|
||||||
|
{
|
||||||
|
return $this->repository->findBy($criteria, $orderBy, $limit, $offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findOneBy(array $criteria): ?PersonResource
|
||||||
|
{
|
||||||
|
return $this->repository->findOneBy($criteria);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getClassName(): string
|
||||||
|
{
|
||||||
|
return PersonResource::class;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
import {createApp} from 'vue';
|
||||||
|
import SetReferrer from 'ChillPersonAssets/vuejs/_components/AccompanyingPeriod/SetReferrer.vue';
|
||||||
|
import {fetchResults} from 'ChillMainAssets/lib/api/apiMethods.js';
|
||||||
|
|
||||||
|
document.querySelectorAll('[data-set-referrer-app]').forEach(function (el) {
|
||||||
|
let
|
||||||
|
periodId = Number.parseInt(el.dataset.setReferrerAccompanyingPeriodId);
|
||||||
|
|
||||||
|
const url = `/api/1.0/person/accompanying-course/${periodId}/referrers-suggested.json`;
|
||||||
|
fetchResults(url).then(suggested => {
|
||||||
|
const app = createApp({
|
||||||
|
components: {
|
||||||
|
SetReferrer,
|
||||||
|
},
|
||||||
|
template:
|
||||||
|
'<set-referrer :suggested="this.suggested" :periodId="periodId" @referrerSet="onReferrerSet"></set-referrer>',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
suggested, periodId,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onReferrerSet(ref) {
|
||||||
|
const bloc = document.querySelector(`[data-accompanying-period-id="${this.periodId}"]`);
|
||||||
|
if (bloc === null) {
|
||||||
|
console.error('bloc not found');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const label = bloc.querySelector('[data-referrer-text]');
|
||||||
|
|
||||||
|
if (label === null) {
|
||||||
|
console.error('label not found');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
label.textContent = ref.text;
|
||||||
|
label.classList.remove('chill-no-data-statement');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.mount(el);
|
||||||
|
|
||||||
|
})
|
||||||
|
})
|
@ -0,0 +1,55 @@
|
|||||||
|
import {ShowHide} from 'ChillMainAssets/lib/show_hide/show_hide.js';
|
||||||
|
|
||||||
|
window.addEventListener('DOMContentLoaded', function() {
|
||||||
|
let
|
||||||
|
personContainer = document.querySelector('#person-entity'),
|
||||||
|
entitySelector = document.querySelector('#entity-selector'),
|
||||||
|
freetextContainer = document.querySelector('#freetext-entity'),
|
||||||
|
thirdpartyContainer = document.querySelector('#thirdparty-entity')
|
||||||
|
;
|
||||||
|
if (null === entitySelector) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
new ShowHide({
|
||||||
|
debug: false,
|
||||||
|
load_event: null,
|
||||||
|
froms: [entitySelector],
|
||||||
|
container: [personContainer],
|
||||||
|
test: function(froms, event) {
|
||||||
|
for (let container of froms) {
|
||||||
|
return container.querySelector('input[value="person"]').checked;
|
||||||
|
}
|
||||||
|
console.log('we couldnt find the input');
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
new ShowHide({
|
||||||
|
debug: false,
|
||||||
|
load_event: null,
|
||||||
|
froms: [entitySelector],
|
||||||
|
container: [thirdpartyContainer],
|
||||||
|
test: function(froms, event) {
|
||||||
|
for (let container of froms) {
|
||||||
|
return container.querySelector('input[value="thirdparty"]').checked;
|
||||||
|
}
|
||||||
|
console.log('we couldnt find the input');
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
new ShowHide({
|
||||||
|
debug: false,
|
||||||
|
load_event: null,
|
||||||
|
froms: [entitySelector],
|
||||||
|
container: [freetextContainer],
|
||||||
|
test: function(froms, event) {
|
||||||
|
for (let container of froms) {
|
||||||
|
return container.querySelector('input[value="freetext"]').checked;
|
||||||
|
}
|
||||||
|
console.log('we couldnt find the input');
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
})
|
||||||
|
});
|
@ -0,0 +1,44 @@
|
|||||||
|
<template>
|
||||||
|
<ul class="list-suggest add-items" v-if="this.suggested.length > 0">
|
||||||
|
<li v-for="r in this.suggested" @click="setReferrer(r)"><span>{{ r.text }}</span></li>
|
||||||
|
</ul>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import {makeFetch} from 'ChillMainAssets/lib/api/apiMethods.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "SetReferrer",
|
||||||
|
props: {
|
||||||
|
suggested: {
|
||||||
|
type: Array,
|
||||||
|
required: false,
|
||||||
|
default: [],
|
||||||
|
},
|
||||||
|
periodId: {
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
emits: ['referrerSet'],
|
||||||
|
methods: {
|
||||||
|
setReferrer: function(ref) {
|
||||||
|
const url = `/api/1.0/person/accompanying-course/${this.periodId}.json`;
|
||||||
|
const body = { type: "accompanying_period", user: { id: ref.id, type: ref.type }};
|
||||||
|
|
||||||
|
return makeFetch('PATCH', url, body)
|
||||||
|
.then((response) => {
|
||||||
|
this.$emit('referrerSet', ref);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
throw error;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
@ -1,4 +1,4 @@
|
|||||||
<div class="item-bloc accompanying-period-item{% if itemBlocClass is defined %} {{ itemBlocClass }}{% endif %}">
|
<div class="item-bloc accompanying-period-item{% if itemBlocClass is defined %} {{ itemBlocClass }}{% endif %}" {% if itemAttrs is defined %}{{ itemAttrs }}{% endif %}>
|
||||||
<div class="item-row">
|
<div class="item-row">
|
||||||
<div class="wrap-header">
|
<div class="wrap-header">
|
||||||
<div class="wh-row">
|
<div class="wh-row">
|
||||||
@ -45,9 +45,9 @@
|
|||||||
{% if chill_accompanying_periods.fields.user == 'visible' %}
|
{% if chill_accompanying_periods.fields.user == 'visible' %}
|
||||||
{% if period.user %}
|
{% if period.user %}
|
||||||
<abbr class="referrer" title="{{ 'Referrer'|trans }}">{{ 'Referrer'|trans }}:</abbr>
|
<abbr class="referrer" title="{{ 'Referrer'|trans }}">{{ 'Referrer'|trans }}:</abbr>
|
||||||
{{ period.user|chill_entity_render_box }}
|
<span data-referrer-text="data-referrer-text">{{ period.user|chill_entity_render_box }}</span>
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="chill-no-data-statement">{{ 'No accompanying user'|trans }}</span>
|
<span class="chill-no-data-statement" data-referrer-text="data-referrer-text">{{ 'No accompanying user'|trans }}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
<div class="col-md col-xxl">
|
||||||
|
<div id="collapseForm" class="collapse">
|
||||||
|
{% include "@ChillPerson/PersonResource/form.html.twig" %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul class="record_actions sticky-form-buttons">
|
||||||
|
<li>
|
||||||
|
<button class="btn btn-primary btn-create change-icon" type="button" data-bs-toggle="collapse" data-bs-target="#collapseForm" aria-expanded="false" aria-controls="collapseForm">
|
||||||
|
{{ 'Add a person resource'|trans }}
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
@ -0,0 +1,17 @@
|
|||||||
|
{% extends "@ChillPerson/Person/layout.html.twig" %}
|
||||||
|
|
||||||
|
{% set activeRouteKey = 'chill_person_resource_list' %}
|
||||||
|
{# {% set person = person %} #}
|
||||||
|
|
||||||
|
{% block title 'Remove resource'|trans %}
|
||||||
|
|
||||||
|
{% block personcontent %}
|
||||||
|
{{ include('@ChillMain/Util/confirmation_template.html.twig',
|
||||||
|
{
|
||||||
|
'title' : 'Remove resource'|trans,
|
||||||
|
'confirm_question' : 'Are you sure you want to remove the resource for "%name%" ?'|trans({ '%name%' : person.firstname ~ ' ' ~ person.lastname } ),
|
||||||
|
'cancel_route' : 'chill_person_resource_list',
|
||||||
|
'cancel_parameters' : { 'person_id' : person.id },
|
||||||
|
'form' : form
|
||||||
|
} ) }}
|
||||||
|
{% endblock %}
|
@ -0,0 +1,23 @@
|
|||||||
|
{% extends "@ChillPerson/Person/layout.html.twig" %}
|
||||||
|
|
||||||
|
{% set activeRouteKey = 'chill_person_resource_edit' %}
|
||||||
|
|
||||||
|
{% block js %}
|
||||||
|
{{ encore_entry_script_tags('page_person_resource_showhide_input') }}
|
||||||
|
{{ encore_entry_script_tags('mod_pickentity_type') }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block css %}
|
||||||
|
{{ encore_entry_link_tags('page_person_resource_showhide_input') }}
|
||||||
|
{{ encore_entry_link_tags('mod_pickentity_type') }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block title %}{{ 'edit resource'|trans|capitalize }}{% endblock %}
|
||||||
|
|
||||||
|
{% block personcontent %}
|
||||||
|
|
||||||
|
<h1 style="margin-bottom: 2rem;">{{ 'edit resource'|trans }}</h1>
|
||||||
|
|
||||||
|
{% include "@ChillPerson/PersonResource/form.html.twig" %}
|
||||||
|
|
||||||
|
{% endblock %}
|
@ -0,0 +1,78 @@
|
|||||||
|
{{ form_start(form, {'attr' : {'id' : 'create-form'}}) }}
|
||||||
|
|
||||||
|
{{ form_row(form.kind) }}
|
||||||
|
|
||||||
|
<div id="linked-entity">
|
||||||
|
<fieldset class="mb-3">
|
||||||
|
<div class="row">
|
||||||
|
<legend class="col-sm-4 col-form-label">Associer un</legend>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<div id="entity-selector">
|
||||||
|
<div class="form-check">
|
||||||
|
{% if resource is defined and resource.person is not null %}
|
||||||
|
<input checked type="radio" id="chill_personbundle_person_resource_linkedEntity_0" name="linked-entity" class="form-check-input" value="person" />
|
||||||
|
<label class="form-check-label" for="chill_personbundle_person_resource_linkedEntity_0">Usager</label>
|
||||||
|
{% else %}
|
||||||
|
<input type="radio" id="chill_personbundle_person_resource_linkedEntity_0" name="linked-entity" class="form-check-input" value="person" />
|
||||||
|
<label class="form-check-label" for="chill_personbundle_person_resource_linkedEntity_0">Usager</label>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="form-check">
|
||||||
|
{% if resource is defined and resource.thirdparty is not null %}
|
||||||
|
<input checked type="radio" id="chill_personbundle_person_resource_linkedEntity_1" name="linked-entity" class="form-check-input" value="thirdparty" />
|
||||||
|
<label class="form-check-label" for="chill_personbundle_person_resource_linkedEntity_1">Tiers</label>
|
||||||
|
{% else %}
|
||||||
|
<input type="radio" id="chill_personbundle_person_resource_linkedEntity_1" name="linked-entity" class="form-check-input" value="thirdparty" />
|
||||||
|
<label class="form-check-label" for="chill_personbundle_person_resource_linkedEntity_1">Tiers</label>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="form-check">
|
||||||
|
{% if resource is defined and resource.freeText is not null %}
|
||||||
|
<input checked type="radio" id="chill_personbundle_person_resource_linkedEntity_2" name="linked-entity" class="form-check-input" value="freetext" />
|
||||||
|
<label class="form-check-label" for="chill_personbundle_person_resource_linkedEntity_2">Description libre</label>
|
||||||
|
{% else %}
|
||||||
|
<input type="radio" id="chill_personbundle_person_resource_linkedEntity_2" name="linked-entity" class="form-check-input" value="freetext" />
|
||||||
|
<label class="form-check-label" for="chill_personbundle_person_resource_linkedEntity_2">Description libre</label>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div id="person-entity">
|
||||||
|
{{ form_row(form.person) }}
|
||||||
|
</div>
|
||||||
|
<div id="thirdparty-entity">
|
||||||
|
{{ form_row(form.thirdparty) }}
|
||||||
|
</div>
|
||||||
|
<div id="freetext-entity">
|
||||||
|
{{ form_row(form.freetext) }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{{ form_row(form.comment) }}
|
||||||
|
|
||||||
|
{% if action is defined %}
|
||||||
|
<ul class="record_actions sticky-form-buttons">
|
||||||
|
<li class="edit">
|
||||||
|
<button class="btn btn-edit"
|
||||||
|
type="submit" id="newPersonResource">
|
||||||
|
{{ 'edit resource'|trans|capitalize }}
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
{% else %}
|
||||||
|
<ul class="record_actions">
|
||||||
|
<li>
|
||||||
|
<button class="btn btn-create"
|
||||||
|
type="submit" id="newPersonResource">
|
||||||
|
{{ 'Save'|trans }}
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{{ form_end(form) }}
|
@ -0,0 +1,101 @@
|
|||||||
|
{% extends "@ChillPerson/Person/layout.html.twig" %}
|
||||||
|
|
||||||
|
{% set activeRouteKey = 'chill_person_resource_list' %}
|
||||||
|
|
||||||
|
{% block title %}{{ 'Person resources'|trans|capitalize ~ ' ' ~ person|chill_entity_render_string }}{% endblock %}
|
||||||
|
|
||||||
|
{% block js %}
|
||||||
|
{{ encore_entry_script_tags('page_person_resource_showhide_input') }}
|
||||||
|
{{ encore_entry_script_tags('mod_pickentity_type') }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block css %}
|
||||||
|
{{ encore_entry_link_tags('page_person_resource_showhide_input') }}
|
||||||
|
{{ encore_entry_link_tags('mod_pickentity_type') }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block personcontent %}
|
||||||
|
|
||||||
|
<h1>{{ 'List of resources'|trans }}</h1>
|
||||||
|
|
||||||
|
{% if personResources is not null %}
|
||||||
|
{% for resource in personResources %}
|
||||||
|
<div class="flex-table">
|
||||||
|
<div class="item-bloc">
|
||||||
|
<div class="item-row">
|
||||||
|
<div class="wrap-header">
|
||||||
|
<div class="wh-row">
|
||||||
|
<div class="wh-col">
|
||||||
|
{% if resource.person is not null %}
|
||||||
|
<div class="item-col">
|
||||||
|
<div class="denomination h3">
|
||||||
|
<span class="name">{{ resource.person }}</span>
|
||||||
|
<span class="badge rounded-pill bg-person">{{ 'person'|trans|capitalize }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% elseif resource.thirdparty is not null %}
|
||||||
|
<div class="item-col">
|
||||||
|
<div class="denomination h3">
|
||||||
|
<span class="name">{{ resource.thirdparty }}</span>
|
||||||
|
<span class="badge rounded-pill bg-thirdparty">
|
||||||
|
{{ 'thirdparty'|trans|capitalize }}
|
||||||
|
<i class="fa fa-fw fa-user-md"></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="item-col">
|
||||||
|
<div class="denomination h3">
|
||||||
|
<span>{{ resource.freetext }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<div class="wh-col">
|
||||||
|
{% if resource.kind %}
|
||||||
|
<span>{{ resource.kind.title.fr|capitalize }}</span>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% if resource.comment.comment is not null %}
|
||||||
|
<div class="item-row separator">
|
||||||
|
<section class="chill-entity entity-comment-embeddable">
|
||||||
|
<blockquote class="chill-user-quote">
|
||||||
|
<div>{{ resource.comment.comment }}<div>
|
||||||
|
</blockquote>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<div class="item-row separator">
|
||||||
|
<div class="item-col">
|
||||||
|
<ul class="record_actions">
|
||||||
|
<li>
|
||||||
|
<a href="{{ chill_path_add_return_path('chill_person_resource_edit', {'resource_id': resource.id,
|
||||||
|
'person_id': person.id,}) }}"
|
||||||
|
class="btn btn-sm btn-edit"
|
||||||
|
title="{{ 'Edit'|trans }}"></a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="{{ chill_path_add_return_path('chill_person_resource_delete', {'person_id': person.id,
|
||||||
|
'resource_id': resource.id}) }}"
|
||||||
|
class="btn btn-sm btn-delete"
|
||||||
|
title="{{ 'Delete'|trans }}"></a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
<p>{{ 'There are no available resources'|trans }}</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<h1 style="margin-bottom: 2rem;">{{ 'Add a person resource'|trans }}</h1>
|
||||||
|
|
||||||
|
{% include "@ChillPerson/PersonResource/create.html.twig" %}
|
||||||
|
|
||||||
|
{% endblock %}
|
@ -29,7 +29,6 @@ use function count;
|
|||||||
class AccompanyingPeriodResourceNormalizer implements DenormalizerAwareInterface, DenormalizerInterface
|
class AccompanyingPeriodResourceNormalizer implements DenormalizerAwareInterface, DenormalizerInterface
|
||||||
{
|
{
|
||||||
use DenormalizerAwareTrait;
|
use DenormalizerAwareTrait;
|
||||||
|
|
||||||
use ObjectToPopulateTrait;
|
use ObjectToPopulateTrait;
|
||||||
|
|
||||||
private ResourceRepository $repository;
|
private ResourceRepository $repository;
|
||||||
|
@ -33,7 +33,6 @@ use function is_array;
|
|||||||
class AccompanyingPeriodWorkDenormalizer implements ContextAwareDenormalizerInterface, DenormalizerAwareInterface
|
class AccompanyingPeriodWorkDenormalizer implements ContextAwareDenormalizerInterface, DenormalizerAwareInterface
|
||||||
{
|
{
|
||||||
use DenormalizerAwareTrait;
|
use DenormalizerAwareTrait;
|
||||||
|
|
||||||
use ObjectToPopulateTrait;
|
use ObjectToPopulateTrait;
|
||||||
|
|
||||||
public const GROUP_CREATE = 'accompanying_period_work:create';
|
public const GROUP_CREATE = 'accompanying_period_work:create';
|
||||||
|
@ -40,9 +40,7 @@ class PersonJsonNormalizer implements
|
|||||||
NormalizerInterface
|
NormalizerInterface
|
||||||
{
|
{
|
||||||
use DenormalizerAwareTrait;
|
use DenormalizerAwareTrait;
|
||||||
|
|
||||||
use NormalizerAwareTrait;
|
use NormalizerAwareTrait;
|
||||||
|
|
||||||
use ObjectToPopulateTrait;
|
use ObjectToPopulateTrait;
|
||||||
|
|
||||||
private CenterResolverManagerInterface $centerResolverManager;
|
private CenterResolverManagerInterface $centerResolverManager;
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
<?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\Templating\Entity;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Templating\Entity\ChillEntityRenderInterface;
|
||||||
|
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||||
|
use Chill\PersonBundle\Entity\Person\PersonResourceKind;
|
||||||
|
|
||||||
|
final class ResourceKindRender implements ChillEntityRenderInterface
|
||||||
|
{
|
||||||
|
private TranslatableStringHelper $translatableStringHelper;
|
||||||
|
|
||||||
|
public function __construct(TranslatableStringHelper $translatableStringHelper)
|
||||||
|
{
|
||||||
|
$this->translatableStringHelper = $translatableStringHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function renderBox($entity, array $options): string
|
||||||
|
{
|
||||||
|
return
|
||||||
|
'<span class="resource">' .
|
||||||
|
$this->translatableStringHelper->localize(
|
||||||
|
$entity->getTitle()
|
||||||
|
) .
|
||||||
|
'</span>';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function renderString($entity, array $options): string
|
||||||
|
{
|
||||||
|
$title = '';
|
||||||
|
|
||||||
|
if (null !== $entity->getTitle()) {
|
||||||
|
return $this->translatableStringHelper->localize($entity->getTitle());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function supports($entity, array $options): bool
|
||||||
|
{
|
||||||
|
return $entity instanceof PersonResourceKind;
|
||||||
|
}
|
||||||
|
}
|
@ -29,9 +29,7 @@ use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
|
|||||||
final class PersonVoterTest extends KernelTestCase
|
final class PersonVoterTest extends KernelTestCase
|
||||||
{
|
{
|
||||||
use PrepareCenterTrait;
|
use PrepareCenterTrait;
|
||||||
|
|
||||||
use PrepareScopeTrait;
|
use PrepareScopeTrait;
|
||||||
|
|
||||||
use PrepareUserTrait;
|
use PrepareUserTrait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -14,9 +14,12 @@ module.exports = function(encore, entries)
|
|||||||
encore.addEntry('vue_accourse_work_edit', __dirname + '/Resources/public/vuejs/AccompanyingCourseWorkEdit/index.js');
|
encore.addEntry('vue_accourse_work_edit', __dirname + '/Resources/public/vuejs/AccompanyingCourseWorkEdit/index.js');
|
||||||
encore.addEntry('vue_visgraph', __dirname + '/Resources/public/vuejs/VisGraph/index.js');
|
encore.addEntry('vue_visgraph', __dirname + '/Resources/public/vuejs/VisGraph/index.js');
|
||||||
|
|
||||||
|
encore.addEntry('mod_set_referrer', __dirname + '/Resources/public/mod/AccompanyingPeriod/setReferrer.js');
|
||||||
|
|
||||||
encore.addEntry('page_household_edit_metadata', __dirname + '/Resources/public/page/household_edit_metadata/index.js');
|
encore.addEntry('page_household_edit_metadata', __dirname + '/Resources/public/page/household_edit_metadata/index.js');
|
||||||
encore.addEntry('page_person', __dirname + '/Resources/public/page/person/index.js');
|
encore.addEntry('page_person', __dirname + '/Resources/public/page/person/index.js');
|
||||||
encore.addEntry('page_accompanying_course_index_person_locate', __dirname + '/Resources/public/page/accompanying_course_index/person_locate.js');
|
encore.addEntry('page_accompanying_course_index_person_locate', __dirname + '/Resources/public/page/accompanying_course_index/person_locate.js');
|
||||||
encore.addEntry('page_accompanying_course_index_masonry', __dirname + '/Resources/public/page/accompanying_course_index/masonry.js');
|
encore.addEntry('page_accompanying_course_index_masonry', __dirname + '/Resources/public/page/accompanying_course_index/masonry.js');
|
||||||
|
encore.addEntry('page_person_resource_showhide_input', __dirname + '/Resources/public/page/person_resource/showhide-input.js');
|
||||||
encore.addEntry('page_suggest_names', __dirname + '/Resources/public/page/person/suggest-names.js');
|
encore.addEntry('page_suggest_names', __dirname + '/Resources/public/page/person/suggest-names.js');
|
||||||
};
|
};
|
||||||
|
@ -55,6 +55,18 @@ chill_person_accompanying_period_re_open:
|
|||||||
path: /{_locale}/person/{person_id}/accompanying-period/{period_id}/re-open
|
path: /{_locale}/person/{person_id}/accompanying-period/{period_id}/re-open
|
||||||
controller: Chill\PersonBundle\Controller\AccompanyingPeriodController::reOpenAction
|
controller: Chill\PersonBundle\Controller\AccompanyingPeriodController::reOpenAction
|
||||||
|
|
||||||
|
chill_person_resource_list:
|
||||||
|
path: /{_locale}/person/{person_id}/resources/list
|
||||||
|
controller: Chill\PersonBundle\Controller\PersonResourceController::listAction
|
||||||
|
|
||||||
|
chill_person_resource_edit:
|
||||||
|
path: /{_locale}/person/{person_id}/resources/{resource_id}/edit
|
||||||
|
controller: Chill\PersonBundle\Controller\PersonResourceController::editAction
|
||||||
|
|
||||||
|
chill_person_resource_delete:
|
||||||
|
path: /{_locale}/person/{person_id}/resources/{resource_id}/delete
|
||||||
|
controller: Chill\PersonBundle\Controller\PersonResourceController::deleteAction
|
||||||
|
|
||||||
chill_person_address_list:
|
chill_person_address_list:
|
||||||
path: /{_locale}/person/{person_id}/address/list
|
path: /{_locale}/person/{person_id}/address/list
|
||||||
controller: Chill\PersonBundle\Controller\PersonAddressController::listAction
|
controller: Chill\PersonBundle\Controller\PersonAddressController::listAction
|
||||||
|
@ -0,0 +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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Chill\Migrations\Person;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creation of person resource and person resource kind.
|
||||||
|
*/
|
||||||
|
final class Version20220119155944 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql('DROP SEQUENCE chill_person_resource_id_seq CASCADE');
|
||||||
|
$this->addSql('DROP SEQUENCE chill_person_resource_kind_id_seq CASCADE');
|
||||||
|
$this->addSql('DROP TABLE chill_person_resource');
|
||||||
|
$this->addSql('DROP TABLE chill_person_resource_kind');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return 'Creation of person resource and person resource kind';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql('CREATE SEQUENCE chill_person_resource_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
|
||||||
|
$this->addSql('CREATE SEQUENCE chill_person_resource_kind_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
|
||||||
|
$this->addSql('CREATE TABLE chill_person_resource (id INT NOT NULL, person_id INT DEFAULT NULL, kind_id INT DEFAULT NULL, freeText TEXT DEFAULT NULL, createdAt TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, updatedAt TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, comment_comment TEXT DEFAULT NULL, comment_date TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, comment_userId INT DEFAULT NULL, personOwner_id INT NOT NULL, thirdParty_id INT DEFAULT NULL, createdBy_id INT NOT NULL, updatedBy_id INT DEFAULT NULL, PRIMARY KEY(id))');
|
||||||
|
$this->addSql('CREATE INDEX IDX_FA5B7D92D19C515B ON chill_person_resource (personOwner_id)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_FA5B7D92217BBB47 ON chill_person_resource (person_id)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_FA5B7D923EA5CAB0 ON chill_person_resource (thirdParty_id)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_FA5B7D9230602CA9 ON chill_person_resource (kind_id)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_FA5B7D923174800F ON chill_person_resource (createdBy_id)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_FA5B7D9265FF1AEC ON chill_person_resource (updatedBy_id)');
|
||||||
|
$this->addSql('CREATE TABLE chill_person_resource_kind (id INT NOT NULL, title JSON NOT NULL, isActive BOOLEAN NOT NULL, PRIMARY KEY(id))');
|
||||||
|
$this->addSql('ALTER TABLE chill_person_resource ADD CONSTRAINT FK_FA5B7D92D19C515B FOREIGN KEY (personOwner_id) REFERENCES chill_person_person (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||||
|
$this->addSql('ALTER TABLE chill_person_resource ADD CONSTRAINT FK_FA5B7D92217BBB47 FOREIGN KEY (person_id) REFERENCES chill_person_person (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||||
|
$this->addSql('ALTER TABLE chill_person_resource ADD CONSTRAINT FK_FA5B7D923EA5CAB0 FOREIGN KEY (thirdParty_id) REFERENCES chill_3party.third_party (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||||
|
$this->addSql('ALTER TABLE chill_person_resource ADD CONSTRAINT FK_FA5B7D9230602CA9 FOREIGN KEY (kind_id) REFERENCES chill_person_resource_kind (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||||
|
$this->addSql('ALTER TABLE chill_person_resource ADD CONSTRAINT FK_FA5B7D923174800F FOREIGN KEY (createdBy_id) REFERENCES users (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||||
|
$this->addSql('ALTER TABLE chill_person_resource ADD CONSTRAINT FK_FA5B7D9265FF1AEC FOREIGN KEY (updatedBy_id) REFERENCES users (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||||
|
}
|
||||||
|
}
|
@ -223,6 +223,23 @@ Are you sure you want to remove the accompanying period "%id%" ?: Êtes-vous s
|
|||||||
The accompanying course has been successfully removed.: La période d'accompagnement a été supprimée.
|
The accompanying course has been successfully removed.: La période d'accompagnement a été supprimée.
|
||||||
Concerned scopes: Services concernés
|
Concerned scopes: Services concernés
|
||||||
|
|
||||||
|
# person resource
|
||||||
|
|
||||||
|
person_resources_menu: "Ressources"
|
||||||
|
Person resources: "Ressources de la personne"
|
||||||
|
Add a person resource: "Ajouter une ressource"
|
||||||
|
edit resource: "Modifier ressource"
|
||||||
|
Remove resource: "Supprimer ressource"
|
||||||
|
Are you sure you want to remove the resource for "%name%" ?: Étes-vous sûr de vouloir supprimer cette ressource de %name%?
|
||||||
|
The resource has been successfully removed.: "La ressource a été supprimée."
|
||||||
|
List of resources: "Liste des ressources"
|
||||||
|
There are no available resources: "Il y aucun ressource"
|
||||||
|
no comment found: "Aucun commentaire"
|
||||||
|
Select a type: "Choisissez un type"
|
||||||
|
Select a person: "Choisissez un usager"
|
||||||
|
Select a thirdparty: "Choisissez un tiers"
|
||||||
|
|
||||||
|
|
||||||
# pickAPersonType
|
# pickAPersonType
|
||||||
Pick a person: Choisir une personne
|
Pick a person: Choisir une personne
|
||||||
|
|
||||||
|
@ -28,9 +28,7 @@ use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
|
|||||||
final class ReportVoterTest extends KernelTestCase
|
final class ReportVoterTest extends KernelTestCase
|
||||||
{
|
{
|
||||||
use PrepareCenterTrait;
|
use PrepareCenterTrait;
|
||||||
|
|
||||||
use PrepareScopeTrait;
|
use PrepareScopeTrait;
|
||||||
|
|
||||||
use PrepareUserTrait;
|
use PrepareUserTrait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -0,0 +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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Chill\ThirdPartyBundle\Form\Type;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Form\Type\DataTransformer\EntityToJsonTransformer;
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
use Symfony\Component\Form\FormInterface;
|
||||||
|
use Symfony\Component\Form\FormView;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
||||||
|
use Symfony\Component\Serializer\SerializerInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pick user dymically, using vuejs module "AddPerson".
|
||||||
|
*/
|
||||||
|
class PickThirdpartyDynamicType extends AbstractType
|
||||||
|
{
|
||||||
|
private DenormalizerInterface $denormalizer;
|
||||||
|
|
||||||
|
private SerializerInterface $serializer;
|
||||||
|
|
||||||
|
public function __construct(DenormalizerInterface $denormalizer, SerializerInterface $serializer)
|
||||||
|
{
|
||||||
|
$this->denormalizer = $denormalizer;
|
||||||
|
$this->serializer = $serializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
|
{
|
||||||
|
$builder->addViewTransformer(new EntityToJsonTransformer($this->denormalizer, $this->serializer, $options['multiple'], 'thirdparty'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildView(FormView $view, FormInterface $form, array $options)
|
||||||
|
{
|
||||||
|
$view->vars['multiple'] = $options['multiple'];
|
||||||
|
$view->vars['types'] = ['thirdparty'];
|
||||||
|
$view->vars['uniqid'] = uniqid('pick_user_dyn');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
|
{
|
||||||
|
$resolver
|
||||||
|
->setDefault('multiple', false)
|
||||||
|
->setAllowedTypes('multiple', ['bool'])
|
||||||
|
->setDefault('compound', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getBlockPrefix()
|
||||||
|
{
|
||||||
|
return 'pick_entity_dynamic';
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user