mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Merge remote-tracking branch 'origin/issue491_thirdparty_edit_modal' into issue491_thirdparty_edit_modal
This commit is contained in:
commit
5d4149db35
18
CHANGELOG.md
18
CHANGELOG.md
@ -11,6 +11,15 @@ and this project adheres to
|
|||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
<!-- write down unreleased development here -->
|
<!-- write down unreleased development here -->
|
||||||
|
* [search] enforce limit of results for fetching rsults by search api https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/576
|
||||||
|
* [activity] Fix delete button for document (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/554)
|
||||||
|
* [activity] Add return path the document generation (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/553)
|
||||||
|
* [person] add person ressource to person docgen normaliser (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/517)
|
||||||
|
* [person] AccompanyingCourseWorkEdit: fix deleting evaluation documents (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/546)
|
||||||
|
* [person] AccompanyingCourseWorkEdit: download existing documents (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/512)
|
||||||
|
* [person] AccompanyingCourseWorkEdit: replace document by a new one (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/511)
|
||||||
|
* [person] AccompanyingPeriodWork: add referrers to work, add doctrine event listener to add logged user to referrers collection and display a referrers list in work list (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/502)
|
||||||
|
* [person] AccompanyingPeriodWorkEvaluation: fix circular reference when serialising (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/495)
|
||||||
* [person] order accompanying period by opening date in search persons, person and household period lists (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/493)
|
* [person] order accompanying period by opening date in search persons, person and household period lists (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/493)
|
||||||
* [parcours] autosave of the pinned comment for draft accompanying course (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/477)
|
* [parcours] autosave of the pinned comment for draft accompanying course (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/477)
|
||||||
* [main] filter user job in undispatch acc period to assign (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/472)
|
* [main] filter user job in undispatch acc period to assign (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/472)
|
||||||
@ -46,6 +55,15 @@ and this project adheres to
|
|||||||
* [thirdparty] For contacts show current civility/profession in edit form + fix saving of edited information (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/491)
|
* [thirdparty] For contacts show current civility/profession in edit form + fix saving of edited information (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/491)
|
||||||
* [household] create-edit household composition placed in separate page to avoid confusion (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/505)
|
* [household] create-edit household composition placed in separate page to avoid confusion (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/505)
|
||||||
* [blur] Improved positioning of toggle icon (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/486)
|
* [blur] Improved positioning of toggle icon (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/486)
|
||||||
|
* [thirdparty] add firstname field to thirdparty 'child' or 'contact' types (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/508)
|
||||||
|
* [household] create-edit household composition placed in separate page to avoid confusion (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/505)
|
||||||
|
* [blur] Improved positioning of toggle icon (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/486)
|
||||||
|
* [parcours] List of parcours for a specific user so they can be reassigned in case of absence (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/509)
|
||||||
|
* [thirdparty] Thirdparty view page, english text translated (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/534)
|
||||||
|
* [social_action] Translation changed in evaluation section (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/512)
|
||||||
|
* [household] Within parcours listing page of household add create button (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/560)
|
||||||
|
* [person_resource] bugfix when adding thirdparty or freetext resource (no issue)
|
||||||
|
* [aside_activity] style correction + sticky-form create button (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/529)
|
||||||
|
|
||||||
## Test releases
|
## Test releases
|
||||||
|
|
||||||
|
@ -250,11 +250,6 @@ parameters:
|
|||||||
count: 1
|
count: 1
|
||||||
path: src/Bundle/ChillMainBundle/Entity/Address.php
|
path: src/Bundle/ChillMainBundle/Entity/Address.php
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: src/Bundle/ChillMainBundle/Entity/Embeddable/CommentEmbeddable.php
|
|
||||||
|
|
||||||
-
|
-
|
||||||
message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#"
|
message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#"
|
||||||
count: 1
|
count: 1
|
||||||
|
@ -179,14 +179,15 @@ final class ActivityController extends AbstractController
|
|||||||
{
|
{
|
||||||
$view = null;
|
$view = null;
|
||||||
|
|
||||||
[$person, $accompanyingPeriod] = $this->getEntity($request);
|
|
||||||
|
|
||||||
$entity = $this->activityRepository->find($id);
|
$entity = $this->activityRepository->find($id);
|
||||||
|
|
||||||
if (null === $entity) {
|
if (null === $entity) {
|
||||||
throw $this->createNotFoundException('Unable to find Activity entity.');
|
throw $this->createNotFoundException('Unable to find Activity entity.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$accompanyingPeriod = $entity->getAccompanyingPeriod();
|
||||||
|
$person = $entity->getPerson();
|
||||||
|
|
||||||
if ($entity->getAccompanyingPeriod() instanceof AccompanyingPeriod) {
|
if ($entity->getAccompanyingPeriod() instanceof AccompanyingPeriod) {
|
||||||
$view = 'ChillActivityBundle:Activity:editAccompanyingCourse.html.twig';
|
$view = 'ChillActivityBundle:Activity:editAccompanyingCourse.html.twig';
|
||||||
$accompanyingPeriod = $entity->getAccompanyingPeriod();
|
$accompanyingPeriod = $entity->getAccompanyingPeriod();
|
||||||
@ -220,6 +221,9 @@ final class ActivityController extends AbstractController
|
|||||||
$this->entityManager->persist($entity);
|
$this->entityManager->persist($entity);
|
||||||
$this->entityManager->flush();
|
$this->entityManager->flush();
|
||||||
|
|
||||||
|
$params = $this->buildParamsToUrl($person, $accompanyingPeriod);
|
||||||
|
$params['id'] = $entity->getId();
|
||||||
|
|
||||||
if ($form->has('gendocTemplateId') && null !== $form['gendocTemplateId']->getData()) {
|
if ($form->has('gendocTemplateId') && null !== $form['gendocTemplateId']->getData()) {
|
||||||
return $this->redirectToRoute(
|
return $this->redirectToRoute(
|
||||||
'chill_docgenerator_generate_from_template',
|
'chill_docgenerator_generate_from_template',
|
||||||
@ -227,15 +231,13 @@ final class ActivityController extends AbstractController
|
|||||||
'template' => $form->get('gendocTemplateId')->getData(),
|
'template' => $form->get('gendocTemplateId')->getData(),
|
||||||
'entityClassName' => Activity::class,
|
'entityClassName' => Activity::class,
|
||||||
'entityId' => $entity->getId(),
|
'entityId' => $entity->getId(),
|
||||||
|
'returnPath' => $this->generateUrl('chill_activity_activity_edit', $params),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addFlash('success', $this->get('translator')->trans('Success : activity updated!'));
|
$this->addFlash('success', $this->get('translator')->trans('Success : activity updated!'));
|
||||||
|
|
||||||
$params = $this->buildParamsToUrl($person, $accompanyingPeriod);
|
|
||||||
$params['id'] = $entity->getId();
|
|
||||||
|
|
||||||
return $this->redirectToRoute('chill_activity_activity_show', $params);
|
return $this->redirectToRoute('chill_activity_activity_show', $params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -444,6 +446,9 @@ final class ActivityController extends AbstractController
|
|||||||
'template' => $form->get('gendocTemplateId')->getData(),
|
'template' => $form->get('gendocTemplateId')->getData(),
|
||||||
'entityClassName' => Activity::class,
|
'entityClassName' => Activity::class,
|
||||||
'entityId' => $entity->getId(),
|
'entityId' => $entity->getId(),
|
||||||
|
'returnPath' => $this->generateUrl('chill_activity_activity_edit', [
|
||||||
|
'id' => $entity->getId(),
|
||||||
|
]),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -305,6 +305,7 @@ class ActivityType extends AbstractType
|
|||||||
'label' => $activityType->getLabel('documents'),
|
'label' => $activityType->getLabel('documents'),
|
||||||
'required' => $activityType->isRequired('documents'),
|
'required' => $activityType->isRequired('documents'),
|
||||||
'allow_add' => true,
|
'allow_add' => true,
|
||||||
|
'allow_delete' => true,
|
||||||
'button_add_label' => 'activity.Insert a document',
|
'button_add_label' => 'activity.Insert a document',
|
||||||
'button_remove_label' => 'activity.Remove a document',
|
'button_remove_label' => 'activity.Remove a document',
|
||||||
'empty_collection_explain' => 'No documents',
|
'empty_collection_explain' => 'No documents',
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
div.chill-dropzone__below-zone {
|
||||||
|
a.btn-delete {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// do it in js does not work
|
||||||
|
// document.addEventListener('DOMContentLoaded', e => {
|
||||||
|
// const dropzoneBelow = document.querySelectorAll('div.chill-dropzone__below-zone');
|
||||||
|
// dropzoneBelow.forEach(
|
||||||
|
// d => {
|
||||||
|
// const a = d.querySelector('a.btn-delete');
|
||||||
|
// d.removeChild(a);
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
// });
|
@ -30,4 +30,5 @@
|
|||||||
{{ parent() }}
|
{{ parent() }}
|
||||||
{{ encore_entry_link_tags('mod_async_upload') }}
|
{{ encore_entry_link_tags('mod_async_upload') }}
|
||||||
{{ encore_entry_link_tags('vue_activity') }}
|
{{ encore_entry_link_tags('vue_activity') }}
|
||||||
|
{{ encore_entry_link_tags('page_edit_activity') }}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
|
|
||||||
{% include 'ChillActivityBundle:Activity:list.html.twig' with {'context': 'person'} %}
|
{% include 'ChillActivityBundle:Activity:list.html.twig' with {'context': 'person'} %}
|
||||||
|
|
||||||
{% if is_granted('CHILL_ACTIVITY_CREATE', person) %}
|
{% if is_granted('CHILL_ACTIVITY_CREATE_PERSON', person) %}
|
||||||
<ul class="record_actions sticky-form-buttons">
|
<ul class="record_actions sticky-form-buttons">
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ path('chill_activity_activity_new', {'person_id': person_id, 'accompanying_period_id': accompanying_course_id}) }}"
|
<a href="{{ path('chill_activity_activity_new', {'person_id': person_id, 'accompanying_period_id': accompanying_course_id}) }}"
|
||||||
|
@ -7,5 +7,7 @@ module.exports = function(encore, entries)
|
|||||||
ChillActivityAssets: __dirname + '/Resources/public'
|
ChillActivityAssets: __dirname + '/Resources/public'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
encore.addEntry('page_edit_activity', __dirname + '/Resources/public/page/edit_activity/index.scss');
|
||||||
|
|
||||||
encore.addEntry('vue_activity', __dirname + '/Resources/public/vuejs/Activity/index.js');
|
encore.addEntry('vue_activity', __dirname + '/Resources/public/vuejs/Activity/index.js');
|
||||||
};
|
};
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="item-col">
|
<div class="item-col" style="justify-content: flex-end;">
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<ul class="list-content fa-ul">
|
<ul class="list-content fa-ul">
|
||||||
<li>
|
<li>
|
||||||
@ -79,7 +79,7 @@
|
|||||||
|
|
||||||
{{ chill_pagination(paginator) }}
|
{{ chill_pagination(paginator) }}
|
||||||
|
|
||||||
<ul class="record_actions">
|
<ul class="record_actions sticky-form-buttons">
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ chill_path_add_return_path('chill_crud_aside_activity_new') }}" class="btn btn-create">
|
<a href="{{ chill_path_add_return_path('chill_crud_aside_activity_new') }}" class="btn btn-create">
|
||||||
{{ 'Create'|trans }}
|
{{ 'Create'|trans }}
|
||||||
|
@ -61,13 +61,13 @@ class StoredObject implements AsyncFileInterface, Document
|
|||||||
/**
|
/**
|
||||||
* @var int[]
|
* @var int[]
|
||||||
* @ORM\Column(type="json", name="iv")
|
* @ORM\Column(type="json", name="iv")
|
||||||
* @Serializer\Groups({"write"})
|
* @Serializer\Groups({"read", "write"})
|
||||||
*/
|
*/
|
||||||
private array $iv = [];
|
private array $iv = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="json", name="key")
|
* @ORM\Column(type="json", name="key")
|
||||||
* @Serializer\Groups({"write"})
|
* @Serializer\Groups({"read", "write"})
|
||||||
*/
|
*/
|
||||||
private array $keyInfos = [];
|
private array $keyInfos = [];
|
||||||
|
|
||||||
|
@ -73,6 +73,7 @@ var download = (button) => {
|
|||||||
button.type = mimeType;
|
button.type = mimeType;
|
||||||
button.textContent = labelReady;
|
button.textContent = labelReady;
|
||||||
if (hasFilename) {
|
if (hasFilename) {
|
||||||
|
|
||||||
button.download = filename;
|
button.download = filename;
|
||||||
if (extension !== false) {
|
if (extension !== false) {
|
||||||
button.download = button.download + '.' + extension;
|
button.download = button.download + '.' + extension;
|
||||||
@ -92,4 +93,4 @@ window.addEventListener('load', function(e) {
|
|||||||
initializeButtons(e.target);
|
initializeButtons(e.target);
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = initializeButtons;
|
export { initializeButtons, download };
|
@ -1,6 +1,6 @@
|
|||||||
var algo = 'AES-CBC';
|
var algo = 'AES-CBC';
|
||||||
import Dropzone from 'dropzone';
|
import Dropzone from 'dropzone';
|
||||||
var initializeDownload = require('./downloader.js');
|
import { initializeButtons } from './downloader.js';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -359,7 +359,7 @@ var insertDownloadButton = (zone, zoneData) => {
|
|||||||
|
|
||||||
addBelowButton(newButton, zone, zoneData);
|
addBelowButton(newButton, zone, zoneData);
|
||||||
//zone.appendChild(newButton);
|
//zone.appendChild(newButton);
|
||||||
initializeDownload(zone);
|
initializeButtons(zone);
|
||||||
};
|
};
|
||||||
|
|
||||||
window.addEventListener('load', function(e) {
|
window.addEventListener('load', function(e) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<a class="btn btn-create" :title="$t(buttonTitle)" @click="openModal">
|
<a :class="btnClasses" :title="$t(buttonTitle)" @click="openModal">
|
||||||
<span>{{ $t(buttonTitle) }}</span>
|
<span>{{ $t(buttonTitle) }}</span>
|
||||||
</a>
|
</a>
|
||||||
<teleport to="body">
|
<teleport to="body">
|
||||||
@ -96,10 +96,27 @@ export default {
|
|||||||
Modal
|
Modal
|
||||||
},
|
},
|
||||||
i18n,
|
i18n,
|
||||||
props: [
|
props: {
|
||||||
'buttonTitle',
|
buttonTitle: {
|
||||||
'options'
|
type: String,
|
||||||
],
|
default: 'Ajouter un document',
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
type: Object,
|
||||||
|
default: {
|
||||||
|
maxFiles: 1,
|
||||||
|
maxPostSize: 262144000, // 250MB
|
||||||
|
required: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
btnClasses: {
|
||||||
|
type: Object,
|
||||||
|
default: {
|
||||||
|
btn: true,
|
||||||
|
'btn-create': true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
emits: ['addDocument'],
|
emits: ['addDocument'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
<template>
|
||||||
|
<a
|
||||||
|
class="btn btn-download"
|
||||||
|
:title="$t(buttonTitle)"
|
||||||
|
:data-key=JSON.stringify(storedObject.keyInfos)
|
||||||
|
:data-iv=JSON.stringify(storedObject.iv)
|
||||||
|
:data-mime-type=storedObject.type
|
||||||
|
:data-label-preparing="$t('dataLabelPreparing')"
|
||||||
|
:data-label-ready="$t('dataLabelReady')"
|
||||||
|
:data-temp-url-get-generator="url"
|
||||||
|
@click.once="downloadDocument">
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { download } from '../../module/async_upload/downloader';
|
||||||
|
|
||||||
|
const i18n = {
|
||||||
|
messages: {
|
||||||
|
fr: {
|
||||||
|
dataLabelPreparing: "Chargement...",
|
||||||
|
dataLabelReady: "",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "AddAsyncUploadDownloader",
|
||||||
|
i18n,
|
||||||
|
props: [
|
||||||
|
'buttonTitle',
|
||||||
|
'storedObject'
|
||||||
|
],
|
||||||
|
computed: {
|
||||||
|
url() {
|
||||||
|
return `/asyncupload/temp_url/generate/GET?object_name=${this.storedObject.filename}`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
downloadDocument(e) {
|
||||||
|
download(e.target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -26,6 +26,7 @@ use Symfony\Component\Filesystem\Filesystem;
|
|||||||
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
||||||
|
|
||||||
use function count;
|
use function count;
|
||||||
|
use function strlen;
|
||||||
|
|
||||||
class LoadPostalCodesCommand extends Command
|
class LoadPostalCodesCommand extends Command
|
||||||
{
|
{
|
||||||
@ -118,6 +119,13 @@ class LoadPostalCodesCommand extends Command
|
|||||||
|
|
||||||
private function addPostalCode($row, OutputInterface $output)
|
private function addPostalCode($row, OutputInterface $output)
|
||||||
{
|
{
|
||||||
|
if ('FR' === $row[2] && strlen($row[0]) === 4) {
|
||||||
|
// CP in FRANCE are on 5 digit
|
||||||
|
// For CP starting with a zero, the starting zero can be remove if stored as number in a csv
|
||||||
|
// add a zero if CP from FR and on 4 digit
|
||||||
|
$row[0] = '0' . $row[0];
|
||||||
|
}
|
||||||
|
|
||||||
if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) {
|
if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) {
|
||||||
$output->writeln('handling row: ' . $row[0] . ' | ' . $row[1] . ' | ' . $row[2]);
|
$output->writeln('handling row: ' . $row[0] . ' | ' . $row[1] . ' | ' . $row[2]);
|
||||||
}
|
}
|
||||||
|
@ -114,6 +114,11 @@ class ChillMainExtension extends Extension implements
|
|||||||
$config['available_countries']
|
$config['available_countries']
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$container->setParameter(
|
||||||
|
'chill_main.access_global_history',
|
||||||
|
$config['access_global_history']
|
||||||
|
);
|
||||||
|
|
||||||
$container->setParameter(
|
$container->setParameter(
|
||||||
'chill_main.routing.resources',
|
'chill_main.routing.resources',
|
||||||
$config['routing']['resources']
|
$config['routing']['resources']
|
||||||
|
@ -113,6 +113,9 @@ class Configuration implements ConfigurationInterface
|
|||||||
->end()
|
->end()
|
||||||
->end()
|
->end()
|
||||||
->end()
|
->end()
|
||||||
|
->booleanNode('access_global_history')
|
||||||
|
->defaultTrue()
|
||||||
|
->end()
|
||||||
->arrayNode('redis')
|
->arrayNode('redis')
|
||||||
->children()
|
->children()
|
||||||
->scalarNode('host')
|
->scalarNode('host')
|
||||||
|
@ -61,7 +61,7 @@ class CommentEmbeddable
|
|||||||
|
|
||||||
public function isEmpty()
|
public function isEmpty()
|
||||||
{
|
{
|
||||||
return empty($this->getComment());
|
return null === $this->getComment() || '' === $this->getComment();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setComment(?string $comment)
|
public function setComment(?string $comment)
|
||||||
|
@ -40,6 +40,7 @@ class UserJob
|
|||||||
* @var array|string[]A
|
* @var array|string[]A
|
||||||
* @ORM\Column(name="label", type="json")
|
* @ORM\Column(name="label", type="json")
|
||||||
* @Serializer\Groups({"read", "docgen:read"})
|
* @Serializer\Groups({"read", "docgen:read"})
|
||||||
|
* @Serializer\Context({"is-translatable": true}, groups={"docgen:read"})
|
||||||
*/
|
*/
|
||||||
protected array $label = [];
|
protected array $label = [];
|
||||||
|
|
||||||
|
@ -42,9 +42,6 @@
|
|||||||
<a class="btn btn-sm btn-show" :href="getUrl(e)">
|
<a class="btn btn-sm btn-show" :href="getUrl(e)">
|
||||||
{{ $t('show_entity', { entity: $t('the_evaluation') }) }}
|
{{ $t('show_entity', { entity: $t('the_evaluation') }) }}
|
||||||
</a>
|
</a>
|
||||||
<a class="btn btn-sm btn-update" :href="getUrl(e.accompanyingPeriodWork)">
|
|
||||||
{{ $t('show_entity', { entity: $t('the_action') }) }}
|
|
||||||
</a>
|
|
||||||
<a class="btn btn-sm btn-show" :href="getUrl(e.accompanyingPeriodWork.accompanyingPeriod)">
|
<a class="btn btn-sm btn-show" :href="getUrl(e.accompanyingPeriodWork.accompanyingPeriod)">
|
||||||
{{ $t('show_entity', { entity: $t('the_course') }) }}
|
{{ $t('show_entity', { entity: $t('the_course') }) }}
|
||||||
</a>
|
</a>
|
||||||
@ -102,4 +99,4 @@ export default {
|
|||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -223,18 +223,25 @@ export default {
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
if (typeof this.type === 'undefined') { // action=create or addContact
|
if (typeof this.type === 'undefined') { // action=create or addContact
|
||||||
console.log('will rewrite data');
|
// console.log('will rewrite data');
|
||||||
if (this.action === 'addContact') {
|
if (this.action === 'addContact') {
|
||||||
type = 'thirdparty'
|
type = 'thirdparty'
|
||||||
data = this.$refs.castThirdparty.$data.thirdparty;
|
data = this.$refs.castThirdparty.$data.thirdparty;
|
||||||
console.log('data original', data);
|
// console.log('data original', data);
|
||||||
data.civility = data.civility ? {type: 'chill_main_civility', id: data.civility.id} : null;
|
|
||||||
data.profession = data.profession ? {type: 'third_party_profession', id: data.profession.id} : null;
|
|
||||||
data.parent = {type: "thirdparty", id: this.parent.id};
|
data.parent = {type: "thirdparty", id: this.parent.id};
|
||||||
|
data.civility = {type: 'chill_main_civility', id: data.civility.id};
|
||||||
|
data.profession = {type: 'third_party_profession', id: data.profession.id};
|
||||||
} else {
|
} else {
|
||||||
type = this.$refs.castNew.radioType;
|
type = this.$refs.castNew.radioType;
|
||||||
data = this.$refs.castNew.castDataByType();
|
data = this.$refs.castNew.castDataByType();
|
||||||
console.log(data)
|
// console.log('type', type);
|
||||||
|
if (null !== data.civility) {
|
||||||
|
data.civility = {type: 'chill_main_civility', id: data.civility.id};
|
||||||
|
}
|
||||||
|
if (null !== data.profession) {
|
||||||
|
data.profession = {type: 'third_party_profession', id: data.profession.id};
|
||||||
|
}
|
||||||
|
// console.log('onthefly data', data);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw 'error with object type';
|
throw 'error with object type';
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
</a>
|
</a>
|
||||||
{% for menu in menus %}
|
{% for menu in menus %}
|
||||||
<a class="list-group-item list-group-item-action" href="{{ menu.uri }}">
|
<a class="list-group-item list-group-item-action" href="{{ menu.uri }}">
|
||||||
{{ menu.label|upper }}
|
{{ menu.label|trans|upper }}
|
||||||
</a>
|
</a>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,60 +1,62 @@
|
|||||||
{% extends '@ChillMain/Admin/Permission/layout_crud_permission_index.html.twig' %}
|
{% extends '@ChillMain/Admin/Permission/layout_crud_permission_index.html.twig' %}
|
||||||
|
|
||||||
{% block admin_content -%}
|
{% block admin_content -%}
|
||||||
{% embed '@ChillMain/CRUD/_index.html.twig' %}
|
|
||||||
{% block table_entities_thead_tr %}
|
<h1>{{"Users"|trans}}</h1>
|
||||||
<th>{{ 'crud.admin_user.index.is_active'|trans }}</th>
|
{% for entity in entities %}
|
||||||
<th>{{ 'crud.admin_user.index.usernames'|trans }}</th>
|
<div class="flex-table">
|
||||||
<th>{{ 'crud.admin_user.index.mains'|trans }}</th>
|
<div class="item-bloc">
|
||||||
<th> </th>
|
<div class="item-row">
|
||||||
{% endblock %}
|
<div class="item-col">
|
||||||
{% block table_entities_tbody %}
|
{{ entity.label }}
|
||||||
{% for entity in entities %}
|
|
||||||
<tr data-username="{{ entity.username|e('html_attr') }}">
|
|
||||||
<td>
|
|
||||||
{% if entity.isEnabled %}
|
{% if entity.isEnabled %}
|
||||||
<i class="fa fa-check chill-green"></i>
|
<i class="fa fa-check chill-green"></i>
|
||||||
{% else %}
|
{% else %}
|
||||||
<i class="fa fa-times chill-red"></i>
|
<i class="fa fa-times chill-red"></i>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</div>
|
||||||
<td>
|
<div class="item-col"><i>{{ entity.email }}</i></div>
|
||||||
{{ entity.username }}
|
</div>
|
||||||
<br/>
|
<div class="item-row">
|
||||||
{{ entity.label }}
|
<div class="item-col">
|
||||||
<br/>
|
login: {{ entity.username|e('html_attr') }}
|
||||||
{{ entity.email }}
|
</div>
|
||||||
</td>
|
<div class="item-col">
|
||||||
<td>
|
|
||||||
{% if entity.userJob %}
|
{% if entity.userJob %}
|
||||||
{{ entity.userJob.label|localize_translatable_string }}
|
{{ entity.userJob.label|localize_translatable_string }}
|
||||||
<br/>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item-row">
|
||||||
|
<div class="item-col">
|
||||||
{% if entity.mainScope %}
|
{% if entity.mainScope %}
|
||||||
{{ entity.mainScope.name|localize_translatable_string }}
|
{{ entity.mainScope.name|localize_translatable_string }}
|
||||||
<br/>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if entity.mainCenter %}
|
{% if entity.mainCenter %}
|
||||||
{{ entity.mainCenter.name }}
|
, {{ entity.mainCenter.name }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</div>
|
||||||
<td>
|
</div>
|
||||||
<ul class="record_actions">
|
<div class="item-row">
|
||||||
|
<ul class="record_actions">
|
||||||
|
<li>
|
||||||
|
<a class="btn btn-edit" href="{{ path('chill_crud_admin_user_edit', { 'id': entity.id }) }}"></a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a class="btn btn-chill-red" href="{{ path('admin_user_edit_password', { 'id' : entity.id }) }}" title="{{ 'Edit password'|trans|e('html_attr') }}"><i class="fa fa-ellipsis-h"></i></a>
|
||||||
|
</li>
|
||||||
|
{% if is_granted('ROLE_ALLOWED_TO_SWITCH') %}
|
||||||
<li>
|
<li>
|
||||||
<a class="btn btn-edit" href="{{ path('chill_crud_admin_user_edit', { 'id': entity.id }) }}"></a>
|
<a class="btn btn-chill-blue" href="{{ path('chill_main_homepage', {'_switch_user': entity.username }) }}" title="{{ "Impersonate"|trans|e('html_attr') }}"><i class="fa fa-user-secret"></i></a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
{% endif %}
|
||||||
<a class="btn btn-chill-red" href="{{ path('admin_user_edit_password', { 'id' : entity.id }) }}" title="{{ 'Edit password'|trans|e('html_attr') }}"><i class="fa fa-ellipsis-h"></i></a>
|
</ul>
|
||||||
</li>
|
</div>
|
||||||
{% if is_granted('ROLE_ALLOWED_TO_SWITCH') %}
|
</div>
|
||||||
<li>
|
|
||||||
<a class="btn btn-chill-blue" href="{{ path('chill_main_homepage', {'_switch_user': entity.username }) }}" title="{{ "Impersonate"|trans|e('html_attr') }}"><i class="fa fa-user-secret"></i></a>
|
</div>
|
||||||
</li>
|
{% endfor %}
|
||||||
{% endif %}
|
|
||||||
</ul>
|
{{ chill_pagination(paginator) }}
|
||||||
</td>
|
|
||||||
</tr>
|
{% endblock %}
|
||||||
{% endfor %}
|
|
||||||
{% endblock %}
|
|
||||||
{% endembed %}
|
|
||||||
{% endblock %}
|
|
@ -14,6 +14,7 @@ namespace Chill\MainBundle\Routing\MenuBuilder;
|
|||||||
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
|
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
|
||||||
use Chill\MainBundle\Security\Authorization\ChillExportVoter;
|
use Chill\MainBundle\Security\Authorization\ChillExportVoter;
|
||||||
use Knp\Menu\MenuItem;
|
use Knp\Menu\MenuItem;
|
||||||
|
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||||
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
|
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
@ -22,23 +23,20 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
|||||||
*/
|
*/
|
||||||
class SectionMenuBuilder implements LocalMenuBuilderInterface
|
class SectionMenuBuilder implements LocalMenuBuilderInterface
|
||||||
{
|
{
|
||||||
/**
|
protected AuthorizationCheckerInterface $authorizationChecker;
|
||||||
* @var AuthorizationCheckerInterface
|
|
||||||
*/
|
|
||||||
protected $authorizationChecker;
|
|
||||||
|
|
||||||
/**
|
protected ParameterBagInterface $parameterBag;
|
||||||
* @var TranslatorInterface
|
|
||||||
*/
|
protected TranslatorInterface $translator;
|
||||||
protected $translator;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SectionMenuBuilder constructor.
|
* SectionMenuBuilder constructor.
|
||||||
*/
|
*/
|
||||||
public function __construct(AuthorizationCheckerInterface $authorizationChecker, TranslatorInterface $translator)
|
public function __construct(AuthorizationCheckerInterface $authorizationChecker, TranslatorInterface $translator, ParameterBagInterface $parameterBag)
|
||||||
{
|
{
|
||||||
$this->authorizationChecker = $authorizationChecker;
|
$this->authorizationChecker = $authorizationChecker;
|
||||||
$this->translator = $translator;
|
$this->translator = $translator;
|
||||||
|
$this->parameterBag = $parameterBag;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,14 +52,16 @@ class SectionMenuBuilder implements LocalMenuBuilderInterface
|
|||||||
'order' => 0,
|
'order' => 0,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$menu->addChild($this->translator->trans('Global timeline'), [
|
if ($this->parameterBag->get('chill_main.access_global_history')) {
|
||||||
'route' => 'chill_center_timeline',
|
$menu->addChild($this->translator->trans('Global timeline'), [
|
||||||
])
|
'route' => 'chill_center_timeline',
|
||||||
->setExtras(
|
])
|
||||||
[
|
->setExtras(
|
||||||
'order' => 10,
|
[
|
||||||
]
|
'order' => 10,
|
||||||
);
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->authorizationChecker->isGranted(ChillExportVoter::EXPORT)) {
|
if ($this->authorizationChecker->isGranted(ChillExportVoter::EXPORT)) {
|
||||||
$menu->addChild($this->translator->trans('Export Menu'), [
|
$menu->addChild($this->translator->trans('Export Menu'), [
|
||||||
|
@ -11,6 +11,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Chill\MainBundle\Search;
|
namespace Chill\MainBundle\Search;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Pagination\Paginator;
|
||||||
use Chill\MainBundle\Pagination\PaginatorFactory;
|
use Chill\MainBundle\Pagination\PaginatorFactory;
|
||||||
use Chill\MainBundle\Serializer\Model\Collection;
|
use Chill\MainBundle\Serializer\Model\Collection;
|
||||||
use Doctrine\DBAL\Types\Types;
|
use Doctrine\DBAL\Types\Types;
|
||||||
@ -102,9 +103,9 @@ class SearchApi
|
|||||||
return $items;
|
return $items;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildUnionQuery(array $queries, $types, $parameters)
|
private function buildUnionQuery(array $queries, $types, $parameters, Paginator $paginator)
|
||||||
{
|
{
|
||||||
$query = '{unions} ORDER BY pertinence DESC';
|
$query = '{unions} ORDER BY pertinence DESC LIMIT ? OFFSET ?';
|
||||||
$unions = [];
|
$unions = [];
|
||||||
$parameters = [];
|
$parameters = [];
|
||||||
|
|
||||||
@ -113,6 +114,10 @@ class SearchApi
|
|||||||
$parameters = array_merge($parameters, $q->buildParameters());
|
$parameters = array_merge($parameters, $q->buildParameters());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add pagination limit
|
||||||
|
$parameters[] = $paginator->getItemsPerPage();
|
||||||
|
$parameters[] = $paginator->getCurrentPageFirstItemNumber();
|
||||||
|
|
||||||
$union = implode(' UNION ', $unions);
|
$union = implode(' UNION ', $unions);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
@ -132,9 +137,9 @@ class SearchApi
|
|||||||
return (int) $countNq->getSingleScalarResult();
|
return (int) $countNq->getSingleScalarResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function fetchRawResult($queries, $types, $parameters, $paginator): array
|
private function fetchRawResult($queries, $types, $parameters, Paginator $paginator): array
|
||||||
{
|
{
|
||||||
[$union, $parameters] = $this->buildUnionQuery($queries, $types, $parameters);
|
[$union, $parameters] = $this->buildUnionQuery($queries, $types, $parameters, $paginator);
|
||||||
$rsm = new ResultSetMappingBuilder($this->em);
|
$rsm = new ResultSetMappingBuilder($this->em);
|
||||||
$rsm->addScalarResult('key', 'key', Types::STRING)
|
$rsm->addScalarResult('key', 'key', Types::STRING)
|
||||||
->addScalarResult('metadata', 'metadata', Types::JSON)
|
->addScalarResult('metadata', 'metadata', Types::JSON)
|
||||||
|
@ -39,7 +39,7 @@ class CommentEmbeddableDocGenNormalizer implements ContextAwareNormalizerInterfa
|
|||||||
*/
|
*/
|
||||||
public function normalize($object, ?string $format = null, array $context = []): array
|
public function normalize($object, ?string $format = null, array $context = []): array
|
||||||
{
|
{
|
||||||
if (null === $object) {
|
if (null === $object || ($object->isEmpty())) {
|
||||||
return [
|
return [
|
||||||
'comment' => '',
|
'comment' => '',
|
||||||
'isNull' => true,
|
'isNull' => true,
|
||||||
@ -52,7 +52,11 @@ class CommentEmbeddableDocGenNormalizer implements ContextAwareNormalizerInterfa
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = $this->userRepository->find($object->getUserId());
|
if (null === $object->getUserId()) {
|
||||||
|
$user = null;
|
||||||
|
} else {
|
||||||
|
$user = $this->userRepository->find($object->getUserId());
|
||||||
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'comment' => $object->getComment(),
|
'comment' => $object->getComment(),
|
||||||
|
@ -16,10 +16,10 @@ use libphonenumber\PhoneNumber;
|
|||||||
use libphonenumber\PhoneNumberUtil;
|
use libphonenumber\PhoneNumberUtil;
|
||||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||||
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
|
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
|
||||||
|
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
|
||||||
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
||||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
|
||||||
|
|
||||||
class PhonenumberNormalizer implements NormalizerInterface, DenormalizerInterface
|
class PhonenumberNormalizer implements ContextAwareNormalizerInterface, DenormalizerInterface
|
||||||
{
|
{
|
||||||
private string $defaultCarrierCode;
|
private string $defaultCarrierCode;
|
||||||
|
|
||||||
@ -53,6 +53,10 @@ class PhonenumberNormalizer implements NormalizerInterface, DenormalizerInterfac
|
|||||||
|
|
||||||
public function normalize($object, ?string $format = null, array $context = []): string
|
public function normalize($object, ?string $format = null, array $context = []): string
|
||||||
{
|
{
|
||||||
|
if ('docgen' === $format && null === $object) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
return $this->phoneNumberUtil->formatOutOfCountryCallingNumber($object, $this->defaultCarrierCode);
|
return $this->phoneNumberUtil->formatOutOfCountryCallingNumber($object, $this->defaultCarrierCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,8 +65,18 @@ class PhonenumberNormalizer implements NormalizerInterface, DenormalizerInterfac
|
|||||||
return 'libphonenumber\PhoneNumber' === $type;
|
return 'libphonenumber\PhoneNumber' === $type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function supportsNormalization($data, ?string $format = null)
|
public function supportsNormalization($data, ?string $format = null, array $context = []): bool
|
||||||
{
|
{
|
||||||
return $data instanceof PhoneNumber;
|
if ($data instanceof PhoneNumber && 'json' === $format) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('docgen' === $format && (
|
||||||
|
$data instanceof PhoneNumber || PhoneNumber::class === ($context['docgen:expects'] ?? null)
|
||||||
|
)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,10 +100,10 @@ final class UserControllerTest extends WebTestCase
|
|||||||
$crawler = $this->client->followRedirect();
|
$crawler = $this->client->followRedirect();
|
||||||
|
|
||||||
// Check data in the show view
|
// Check data in the show view
|
||||||
$this->assertGreaterThan(
|
$this->assertStringContainsString(
|
||||||
0,
|
'Test_user',
|
||||||
$crawler->filter('td:contains("Test_user")')->count(),
|
$crawler->text(),
|
||||||
'Missing element td:contains("Test user")'
|
'page contains the name of the user'
|
||||||
);
|
);
|
||||||
|
|
||||||
//test the auth of the new client
|
//test the auth of the new client
|
||||||
@ -125,11 +125,7 @@ final class UserControllerTest extends WebTestCase
|
|||||||
$this->client->submit($form);
|
$this->client->submit($form);
|
||||||
$crawler = $this->client->followRedirect();
|
$crawler = $this->client->followRedirect();
|
||||||
// Check the element contains an attribute with value equals "Foo"
|
// Check the element contains an attribute with value equals "Foo"
|
||||||
$this->assertGreaterThan(
|
$this->assertResponseIsSuccessful();
|
||||||
0,
|
|
||||||
$crawler->filter('[data-username="' . $username . '"]')->count(),
|
|
||||||
'Missing element [data-username="Foo bar"]'
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -13,9 +13,8 @@ services:
|
|||||||
- { name: 'chill.menu_builder' }
|
- { name: 'chill.menu_builder' }
|
||||||
|
|
||||||
Chill\MainBundle\Routing\MenuBuilder\SectionMenuBuilder:
|
Chill\MainBundle\Routing\MenuBuilder\SectionMenuBuilder:
|
||||||
arguments:
|
autowire: true
|
||||||
$authorizationChecker: '@Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface'
|
autoconfigure: true
|
||||||
$translator: '@Symfony\Contracts\Translation\TranslatorInterface'
|
|
||||||
tags:
|
tags:
|
||||||
- { name: 'chill.menu_builder' }
|
- { name: 'chill.menu_builder' }
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ namespace Chill\PersonBundle\Controller;
|
|||||||
|
|
||||||
use Chill\ActivityBundle\Entity\Activity;
|
use Chill\ActivityBundle\Entity\Activity;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
|
use Chill\PersonBundle\Entity\Household\Household;
|
||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
use Chill\PersonBundle\Form\AccompanyingCourseType;
|
use Chill\PersonBundle\Form\AccompanyingCourseType;
|
||||||
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkRepository;
|
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkRepository;
|
||||||
@ -279,6 +280,40 @@ class AccompanyingCourseController extends Controller
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Route("/{_locale}/person/household/parcours/new", name="chill_household_accompanying_course_new")
|
||||||
|
*/
|
||||||
|
public function newHouseholdParcoursAction(Request $request): Response
|
||||||
|
{
|
||||||
|
$period = new AccompanyingPeriod();
|
||||||
|
$em = $this->getDoctrine()->getManager();
|
||||||
|
|
||||||
|
if ($request->query->has('household_id')) {
|
||||||
|
$householdId = $request->query->get('household_id');
|
||||||
|
|
||||||
|
$household = $em->getRepository(Household::class)->find($householdId);
|
||||||
|
$members = $household->getCurrentMembers();
|
||||||
|
|
||||||
|
if (null !== $members) {
|
||||||
|
foreach ($members as $m) {
|
||||||
|
$period->addPerson($m->getPerson());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$userLocation = $this->getUser()->getCurrentLocation();
|
||||||
|
$period->setAdministrativeLocation($userLocation);
|
||||||
|
|
||||||
|
$this->denyAccessUnlessGranted(AccompanyingPeriodVoter::CREATE, $period);
|
||||||
|
|
||||||
|
$em->persist($period);
|
||||||
|
$em->flush();
|
||||||
|
|
||||||
|
return $this->redirectToRoute('chill_person_accompanying_course_edit', [
|
||||||
|
'accompanying_period_id' => $period->getId(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/{_locale}/parcours/{accompanying_period_id}/open", name="chill_person_accompanying_course_reopen")
|
* @Route("/{_locale}/parcours/{accompanying_period_id}/open", name="chill_person_accompanying_course_reopen")
|
||||||
* @ParamConverter("accompanyingCourse", options={"id": "accompanying_period_id"})
|
* @ParamConverter("accompanyingCourse", options={"id": "accompanying_period_id"})
|
||||||
|
@ -0,0 +1,114 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Chill\PersonBundle\Controller;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\User;
|
||||||
|
use Chill\MainBundle\Pagination\PaginatorFactory;
|
||||||
|
use Chill\MainBundle\Repository\UserRepository;
|
||||||
|
use Chill\MainBundle\Templating\Entity\UserRender;
|
||||||
|
use Chill\PersonBundle\Repository\AccompanyingPeriodACLAwareRepositoryInterface;
|
||||||
|
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
||||||
|
use Symfony\Component\Form\FormFactoryInterface;
|
||||||
|
use Symfony\Component\Form\FormInterface;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
|
||||||
|
use Symfony\Component\Security\Core\Security;
|
||||||
|
use Symfony\Component\Templating\EngineInterface;
|
||||||
|
|
||||||
|
class ReassignAccompanyingPeriodController extends AbstractController
|
||||||
|
{
|
||||||
|
private AccompanyingPeriodACLAwareRepositoryInterface $accompanyingPeriodACLAwareRepository;
|
||||||
|
|
||||||
|
private EngineInterface $engine;
|
||||||
|
|
||||||
|
private FormFactoryInterface $formFactory;
|
||||||
|
|
||||||
|
private PaginatorFactory $paginatorFactory;
|
||||||
|
|
||||||
|
private Security $security;
|
||||||
|
|
||||||
|
private UserRender $userRender;
|
||||||
|
|
||||||
|
private UserRepository $userRepository;
|
||||||
|
|
||||||
|
public function __construct(AccompanyingPeriodACLAwareRepositoryInterface $accompanyingPeriodACLAwareRepository, UserRepository $userRepository, EngineInterface $engine, FormFactoryInterface $formFactory, PaginatorFactory $paginatorFactory, Security $security, UserRender $userRender)
|
||||||
|
{
|
||||||
|
$this->accompanyingPeriodACLAwareRepository = $accompanyingPeriodACLAwareRepository;
|
||||||
|
$this->engine = $engine;
|
||||||
|
$this->formFactory = $formFactory;
|
||||||
|
$this->paginatorFactory = $paginatorFactory;
|
||||||
|
$this->security = $security;
|
||||||
|
$this->userRepository = $userRepository;
|
||||||
|
$this->userRender = $userRender;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Route("/{_locale}/person/accompanying-periods/reassign", name="chill_course_list_reassign")
|
||||||
|
*/
|
||||||
|
public function listAction(Request $request): Response
|
||||||
|
{
|
||||||
|
if (!$this->security->isGranted('ROLE_USER') || !$this->security->getUser() instanceof User) {
|
||||||
|
throw new AccessDeniedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
$form = $this->buildFilterForm();
|
||||||
|
|
||||||
|
$form->handleRequest($request);
|
||||||
|
|
||||||
|
$total = $this->accompanyingPeriodACLAwareRepository->countByUserOpenedAccompanyingPeriod(
|
||||||
|
$form['user']->getData()
|
||||||
|
);
|
||||||
|
$paginator = $this->paginatorFactory->create($total);
|
||||||
|
$periods = $this->accompanyingPeriodACLAwareRepository
|
||||||
|
->findByUserOpenedAccompanyingPeriod(
|
||||||
|
$form['user']->getData(),
|
||||||
|
['openingDate' => 'ASC'],
|
||||||
|
$paginator->getItemsPerPage(),
|
||||||
|
$paginator->getCurrentPageFirstItemNumber()
|
||||||
|
);
|
||||||
|
|
||||||
|
return new Response(
|
||||||
|
$this->engine->render('@ChillPerson/AccompanyingPeriod/reassign_list.html.twig', [
|
||||||
|
'paginator' => $paginator,
|
||||||
|
'periods' => $periods,
|
||||||
|
'form' => $form->createView(),
|
||||||
|
])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildFilterForm(): FormInterface
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'user' => null,
|
||||||
|
];
|
||||||
|
$builder = $this->formFactory->createBuilder(FormType::class, $data, [
|
||||||
|
'method' => 'get', 'csrf_protection' => false, ]);
|
||||||
|
|
||||||
|
$builder
|
||||||
|
->add('user', EntityType::class, [
|
||||||
|
'class' => User::class,
|
||||||
|
'choices' => $this->userRepository->findByActive(['username' => 'ASC']),
|
||||||
|
'choice_label' => function (User $u) {
|
||||||
|
return $this->userRender->renderString($u, []);
|
||||||
|
},
|
||||||
|
'multiple' => false,
|
||||||
|
'label' => 'User',
|
||||||
|
'required' => false,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $builder->getForm();
|
||||||
|
}
|
||||||
|
}
|
@ -59,6 +59,16 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
|
|||||||
$config['allow_multiple_simultaneous_accompanying_periods']
|
$config['allow_multiple_simultaneous_accompanying_periods']
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$container->setParameter(
|
||||||
|
'chill_person.create_person_allowed',
|
||||||
|
$config['create_person_allowed']
|
||||||
|
);
|
||||||
|
|
||||||
|
$container->setParameter(
|
||||||
|
'chill_person.create_parcours_allowed',
|
||||||
|
$config['create_parcours_allowed']
|
||||||
|
);
|
||||||
|
|
||||||
// register all configuration in a unique parameter
|
// register all configuration in a unique parameter
|
||||||
$container->setParameter('chill_person', $config);
|
$container->setParameter('chill_person', $config);
|
||||||
|
|
||||||
|
@ -62,6 +62,12 @@ class Configuration implements ConfigurationInterface
|
|||||||
->end() // children for 'validation', parent = validation
|
->end() // children for 'validation', parent = validation
|
||||||
->end() //validation, parent = children of root
|
->end() //validation, parent = children of root
|
||||||
->end() // children of root, parent = root
|
->end() // children of root, parent = root
|
||||||
|
->booleanNode('create_person_allowed')
|
||||||
|
->defaultTrue()
|
||||||
|
->end()
|
||||||
|
->booleanNode('create_parcours_allowed')
|
||||||
|
->defaultTrue()
|
||||||
|
->end()
|
||||||
->arrayNode('person_fields')
|
->arrayNode('person_fields')
|
||||||
->canBeDisabled()
|
->canBeDisabled()
|
||||||
->children()
|
->children()
|
||||||
|
@ -142,6 +142,15 @@ class AccompanyingPeriodWork implements AccompanyingPeriodLinkedWithSocialIssues
|
|||||||
*/
|
*/
|
||||||
private Collection $persons;
|
private Collection $persons;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\ManyToMany(targetEntity=User::class)
|
||||||
|
* @ORM\JoinTable(name="chill_person_accompanying_period_work_referrer")
|
||||||
|
* @Serializer\Groups({"read", "docgen:read", "read:accompanyingPeriodWork:light"})
|
||||||
|
* @Serializer\Groups({"accompanying_period_work:edit"})
|
||||||
|
* @Serializer\Groups({"accompanying_period_work:create"})
|
||||||
|
*/
|
||||||
|
private Collection $referrers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\ManyToMany(targetEntity=Result::class, inversedBy="accompanyingPeriodWorks")
|
* @ORM\ManyToMany(targetEntity=Result::class, inversedBy="accompanyingPeriodWorks")
|
||||||
* @ORM\JoinTable(name="chill_person_accompanying_period_work_result")
|
* @ORM\JoinTable(name="chill_person_accompanying_period_work_result")
|
||||||
@ -196,6 +205,7 @@ class AccompanyingPeriodWork implements AccompanyingPeriodLinkedWithSocialIssues
|
|||||||
$this->thirdParties = new ArrayCollection();
|
$this->thirdParties = new ArrayCollection();
|
||||||
$this->persons = new ArrayCollection();
|
$this->persons = new ArrayCollection();
|
||||||
$this->accompanyingPeriodWorkEvaluations = new ArrayCollection();
|
$this->accompanyingPeriodWorkEvaluations = new ArrayCollection();
|
||||||
|
$this->referrers = new ArrayCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addAccompanyingPeriodWorkEvaluation(AccompanyingPeriodWorkEvaluation $evaluation): self
|
public function addAccompanyingPeriodWorkEvaluation(AccompanyingPeriodWorkEvaluation $evaluation): self
|
||||||
@ -227,6 +237,15 @@ class AccompanyingPeriodWork implements AccompanyingPeriodLinkedWithSocialIssues
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function addReferrer(User $referrer): self
|
||||||
|
{
|
||||||
|
if (!$this->referrers->contains($referrer)) {
|
||||||
|
$this->referrers[] = $referrer;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function addResult(Result $result): self
|
public function addResult(Result $result): self
|
||||||
{
|
{
|
||||||
if (!$this->results->contains($result)) {
|
if (!$this->results->contains($result)) {
|
||||||
@ -308,6 +327,14 @@ class AccompanyingPeriodWork implements AccompanyingPeriodLinkedWithSocialIssues
|
|||||||
return $this->persons;
|
return $this->persons;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection|User[]
|
||||||
|
*/
|
||||||
|
public function getReferrers(): Collection
|
||||||
|
{
|
||||||
|
return $this->referrers;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Collection|Result[]
|
* @return Collection|Result[]
|
||||||
*/
|
*/
|
||||||
@ -382,6 +409,13 @@ class AccompanyingPeriodWork implements AccompanyingPeriodLinkedWithSocialIssues
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function removeReferrer(User $referrer): self
|
||||||
|
{
|
||||||
|
$this->referrers->removeElement($referrer);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function removeResult(Result $result): self
|
public function removeResult(Result $result): self
|
||||||
{
|
{
|
||||||
$this->results->removeElement($result);
|
$this->results->removeElement($result);
|
||||||
|
@ -124,6 +124,7 @@ class AccompanyingPeriodWorkEvaluation implements TrackCreationInterface, TrackU
|
|||||||
/**
|
/**
|
||||||
* @ORM\Column(type="date_immutable", nullable=true, options={"default": null})
|
* @ORM\Column(type="date_immutable", nullable=true, options={"default": null})
|
||||||
* @Serializer\Groups({"read", "docgen:read"})
|
* @Serializer\Groups({"read", "docgen:read"})
|
||||||
|
* @Serializer\Groups({"write"})
|
||||||
* @Serializer\Groups({"accompanying_period_work_evaluation:create"})
|
* @Serializer\Groups({"accompanying_period_work_evaluation:create"})
|
||||||
*/
|
*/
|
||||||
private ?DateTimeImmutable $maxDate = null;
|
private ?DateTimeImmutable $maxDate = null;
|
||||||
|
@ -26,6 +26,7 @@ use Chill\PersonBundle\Entity\Household\Household;
|
|||||||
use Chill\PersonBundle\Entity\Household\HouseholdMember;
|
use Chill\PersonBundle\Entity\Household\HouseholdMember;
|
||||||
use Chill\PersonBundle\Entity\Household\PersonHouseholdAddress;
|
use Chill\PersonBundle\Entity\Household\PersonHouseholdAddress;
|
||||||
use Chill\PersonBundle\Entity\Person\PersonCurrentAddress;
|
use Chill\PersonBundle\Entity\Person\PersonCurrentAddress;
|
||||||
|
use Chill\PersonBundle\Entity\Person\PersonResource;
|
||||||
use Chill\PersonBundle\Validator\Constraints\Household\HouseholdMembershipSequential;
|
use Chill\PersonBundle\Validator\Constraints\Household\HouseholdMembershipSequential;
|
||||||
use Chill\PersonBundle\Validator\Constraints\Person\Birthdate;
|
use Chill\PersonBundle\Validator\Constraints\Person\Birthdate;
|
||||||
use Chill\PersonBundle\Validator\Constraints\Person\PersonHasCenter;
|
use Chill\PersonBundle\Validator\Constraints\Person\PersonHasCenter;
|
||||||
@ -451,6 +452,13 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
|||||||
*/
|
*/
|
||||||
private $proxyAccompanyingPeriodOpenState = false; //TO-DELETE ?
|
private $proxyAccompanyingPeriodOpenState = false; //TO-DELETE ?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\OneToMany(targetEntity=PersonResource::class, mappedBy="personOwner")
|
||||||
|
*
|
||||||
|
* @var Collection|PersonResource[];
|
||||||
|
*/
|
||||||
|
private Collection $resources;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The person's spoken languages.
|
* The person's spoken languages.
|
||||||
*
|
*
|
||||||
@ -493,6 +501,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
|||||||
$this->maritalStatusComment = new CommentEmbeddable();
|
$this->maritalStatusComment = new CommentEmbeddable();
|
||||||
$this->periodLocatedOn = new ArrayCollection();
|
$this->periodLocatedOn = new ArrayCollection();
|
||||||
$this->accompanyingPeriodRequested = new ArrayCollection();
|
$this->accompanyingPeriodRequested = new ArrayCollection();
|
||||||
|
$this->resources = new ArrayCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1301,6 +1310,14 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
|||||||
return $this->placeOfBirth;
|
return $this->placeOfBirth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return PersonResource[]|Collection
|
||||||
|
*/
|
||||||
|
public function getResources()
|
||||||
|
{
|
||||||
|
return $this->resources;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get spokenLanguages.
|
* Get spokenLanguages.
|
||||||
*
|
*
|
||||||
|
@ -19,7 +19,7 @@ use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
|
|||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
|
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||||
use Symfony\Component\Serializer\Annotation\Groups;
|
use Symfony\Component\Serializer\Annotation\Groups;
|
||||||
use Symfony\Component\Validator\Constraints as Assert;
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||||
@ -27,7 +27,7 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
|||||||
/**
|
/**
|
||||||
* @ORM\Entity
|
* @ORM\Entity
|
||||||
* @ORM\Table(name="chill_person_resource")
|
* @ORM\Table(name="chill_person_resource")
|
||||||
* @DiscriminatorMap(typeProperty="type", mapping={
|
* @Serializer\DiscriminatorMap(typeProperty="type", mapping={
|
||||||
* "personResource": personResource::class
|
* "personResource": personResource::class
|
||||||
* })
|
* })
|
||||||
*/
|
*/
|
||||||
@ -39,13 +39,13 @@ class PersonResource implements TrackCreationInterface, TrackUpdateInterface
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Embedded(class="Chill\MainBundle\Entity\Embeddable\CommentEmbeddable", columnPrefix="comment_")
|
* @ORM\Embedded(class="Chill\MainBundle\Entity\Embeddable\CommentEmbeddable", columnPrefix="comment_")
|
||||||
* @Groups({"read"})
|
* @Serializer\Groups({"read", "docgen:read"})
|
||||||
*/
|
*/
|
||||||
private CommentEmbeddable $comment;
|
private CommentEmbeddable $comment;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="text", nullable=true)
|
* @ORM\Column(type="text", nullable=true)
|
||||||
* @Groups({"read"})
|
* @Groups({"read", "docgen:read"})
|
||||||
*/
|
*/
|
||||||
private ?string $freeText = null;
|
private ?string $freeText = null;
|
||||||
|
|
||||||
@ -53,25 +53,30 @@ class PersonResource implements TrackCreationInterface, TrackUpdateInterface
|
|||||||
* @ORM\Id
|
* @ORM\Id
|
||||||
* @ORM\GeneratedValue
|
* @ORM\GeneratedValue
|
||||||
* @ORM\Column(type="integer")
|
* @ORM\Column(type="integer")
|
||||||
|
* @Groups({"read", "docgen:read"})
|
||||||
*/
|
*/
|
||||||
private ?int $id;
|
private ?int $id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\ManyToOne(targetEntity=PersonResourceKind::class, inversedBy="personResources")
|
* @ORM\ManyToOne(targetEntity=PersonResourceKind::class, inversedBy="personResources")
|
||||||
* @ORM\JoinColumn(nullable=true)
|
* @ORM\JoinColumn(nullable=true)
|
||||||
* @Groups({"read"})
|
* @Groups({"read", "docgen:read"})
|
||||||
*/
|
*/
|
||||||
private $kind;
|
private ?PersonResourceKind $kind = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\ManyToOne(targetEntity=Person::class, inversedBy="personResources")
|
* The person which host the owner of this resource.
|
||||||
|
*
|
||||||
|
* @ORM\ManyToOne(targetEntity=Person::class)
|
||||||
* @ORM\JoinColumn(nullable=true)
|
* @ORM\JoinColumn(nullable=true)
|
||||||
* @Groups({"read"})
|
* @Groups({"read", "docgen:read"})
|
||||||
*/
|
*/
|
||||||
private ?Person $person = null;
|
private ?Person $person = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\ManyToOne(targetEntity=Person::class)
|
* The person linked with this resource.
|
||||||
|
*
|
||||||
|
* @ORM\ManyToOne(targetEntity=Person::class, inversedBy="resources")
|
||||||
* @ORM\JoinColumn(nullable=false)
|
* @ORM\JoinColumn(nullable=false)
|
||||||
* @Groups({"read"})
|
* @Groups({"read"})
|
||||||
*/
|
*/
|
||||||
@ -80,7 +85,7 @@ class PersonResource implements TrackCreationInterface, TrackUpdateInterface
|
|||||||
/**
|
/**
|
||||||
* @ORM\ManyToOne(targetEntity=ThirdParty::class, inversedBy="personResources")
|
* @ORM\ManyToOne(targetEntity=ThirdParty::class, inversedBy="personResources")
|
||||||
* @ORM\JoinColumn(nullable=true)
|
* @ORM\JoinColumn(nullable=true)
|
||||||
* @Groups({"read"})
|
* @Groups({"read", "docgen:read"})
|
||||||
*/
|
*/
|
||||||
private ?ThirdParty $thirdParty = null;
|
private ?ThirdParty $thirdParty = null;
|
||||||
|
|
||||||
@ -122,6 +127,26 @@ class PersonResource implements TrackCreationInterface, TrackUpdateInterface
|
|||||||
return $this->personOwner;
|
return $this->personOwner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Groups({"read", "docgen:read"})
|
||||||
|
*/
|
||||||
|
public function getResourceKind(): string
|
||||||
|
{
|
||||||
|
if ($this->getPerson() instanceof Person) {
|
||||||
|
return 'person';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->getThirdParty() instanceof ThirdParty) {
|
||||||
|
return 'thirdparty';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null !== $this->getFreeText()) {
|
||||||
|
return 'freetext';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'none';
|
||||||
|
}
|
||||||
|
|
||||||
public function getThirdParty(): ?ThirdParty
|
public function getThirdParty(): ?ThirdParty
|
||||||
{
|
{
|
||||||
return $this->thirdParty;
|
return $this->thirdParty;
|
||||||
@ -205,5 +230,10 @@ class PersonResource implements TrackCreationInterface, TrackUpdateInterface
|
|||||||
$context->buildViolation('You must associate at least one entity')
|
$context->buildViolation('You must associate at least one entity')
|
||||||
->addViolation();
|
->addViolation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (null !== $this->person && $this->person === $this->personOwner) {
|
||||||
|
$context->buildViolation('You cannot associate a resource with the same person')
|
||||||
|
->addViolation();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,10 +12,9 @@ declare(strict_types=1);
|
|||||||
namespace Chill\PersonBundle\Entity\Person;
|
namespace Chill\PersonBundle\Entity\Person;
|
||||||
|
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* **About denormalization**: this operation is operated by @see{AccompanyingPeriodResourdeNormalizer}.
|
|
||||||
*
|
|
||||||
* @ORM\Entity
|
* @ORM\Entity
|
||||||
* @ORM\Table(name="chill_person_resource_kind")
|
* @ORM\Table(name="chill_person_resource_kind")
|
||||||
*/
|
*/
|
||||||
@ -25,8 +24,9 @@ class PersonResourceKind
|
|||||||
* @ORM\Id
|
* @ORM\Id
|
||||||
* @ORM\GeneratedValue
|
* @ORM\GeneratedValue
|
||||||
* @ORM\Column(type="integer")
|
* @ORM\Column(type="integer")
|
||||||
|
* @Serializer\Groups({"docgen:read"})
|
||||||
*/
|
*/
|
||||||
private int $id;
|
private ?int $id = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="boolean")
|
* @ORM\Column(type="boolean")
|
||||||
@ -35,6 +35,8 @@ class PersonResourceKind
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="json", length=255)
|
* @ORM\Column(type="json", length=255)
|
||||||
|
* @Serializer\Groups({"docgen:read"})
|
||||||
|
* @Serializer\Context({"is-translatable": true}, groups={"docgen:read"})
|
||||||
*/
|
*/
|
||||||
private array $title;
|
private array $title;
|
||||||
|
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Chill\PersonBundle\EventListener;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\User;
|
||||||
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork;
|
||||||
|
use Symfony\Component\Security\Core\Security;
|
||||||
|
|
||||||
|
class AccompanyingPeriodWorkEventListener
|
||||||
|
{
|
||||||
|
private Security $security;
|
||||||
|
|
||||||
|
public function __construct(Security $security)
|
||||||
|
{
|
||||||
|
$this->security = $security;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function prePersistAccompanyingPeriodWork(AccompanyingPeriodWork $work): void
|
||||||
|
{
|
||||||
|
if ($this->security->getUser() instanceof User) {
|
||||||
|
$work->addReferrer($this->security->getUser());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -68,12 +68,14 @@ class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($this->security->isGranted(AccompanyingPeriodVoter::SEE_DETAILS, $period)) {
|
if ($this->security->isGranted(AccompanyingPeriodVoter::SEE_DETAILS, $period)) {
|
||||||
$menu->addChild($this->translator->trans('Accompanying Course History'), [
|
/*
|
||||||
'route' => 'chill_person_accompanying_course_history',
|
$menu->addChild($this->translator->trans('Accompanying Course History'), [
|
||||||
'routeParameters' => [
|
'route' => 'chill_person_accompanying_course_history',
|
||||||
'accompanying_period_id' => $period->getId(),
|
'routeParameters' => [
|
||||||
], ])
|
'accompanying_period_id' => $period->getId(),
|
||||||
->setExtras(['order' => 30]);
|
], ])
|
||||||
|
->setExtras(['order' => 30]);
|
||||||
|
*/
|
||||||
|
|
||||||
$menu->addChild($this->translator->trans('Accompanying Course Comment'), [
|
$menu->addChild($this->translator->trans('Accompanying Course Comment'), [
|
||||||
'route' => 'chill_person_accompanying_period_comment_list',
|
'route' => 'chill_person_accompanying_period_comment_list',
|
||||||
|
@ -14,6 +14,7 @@ namespace Chill\PersonBundle\Menu;
|
|||||||
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
|
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
|
||||||
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||||
use Knp\Menu\MenuItem;
|
use Knp\Menu\MenuItem;
|
||||||
|
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||||
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
|
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
@ -22,23 +23,20 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
|||||||
*/
|
*/
|
||||||
class SectionMenuBuilder implements LocalMenuBuilderInterface
|
class SectionMenuBuilder implements LocalMenuBuilderInterface
|
||||||
{
|
{
|
||||||
/**
|
protected AuthorizationCheckerInterface $authorizationChecker;
|
||||||
* @var AuthorizationCheckerInterface
|
|
||||||
*/
|
|
||||||
protected $authorizationChecker;
|
|
||||||
|
|
||||||
/**
|
protected ParameterBagInterface $parameterBag;
|
||||||
* @var TranslatorInterface
|
|
||||||
*/
|
protected TranslatorInterface $translator;
|
||||||
protected $translator;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SectionMenuBuilder constructor.
|
* SectionMenuBuilder constructor.
|
||||||
*/
|
*/
|
||||||
public function __construct(AuthorizationCheckerInterface $authorizationChecker, TranslatorInterface $translator)
|
public function __construct(AuthorizationCheckerInterface $authorizationChecker, TranslatorInterface $translator, ParameterBagInterface $parameterBag)
|
||||||
{
|
{
|
||||||
$this->authorizationChecker = $authorizationChecker;
|
$this->authorizationChecker = $authorizationChecker;
|
||||||
$this->translator = $translator;
|
$this->translator = $translator;
|
||||||
|
$this->parameterBag = $parameterBag;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -46,7 +44,7 @@ class SectionMenuBuilder implements LocalMenuBuilderInterface
|
|||||||
*/
|
*/
|
||||||
public function buildMenu($menuId, MenuItem $menu, array $parameters)
|
public function buildMenu($menuId, MenuItem $menu, array $parameters)
|
||||||
{
|
{
|
||||||
if ($this->authorizationChecker->isGranted(PersonVoter::CREATE)) {
|
if ($this->authorizationChecker->isGranted(PersonVoter::CREATE) && $this->parameterBag->get('chill_person.create_person_allowed')) {
|
||||||
$menu->addChild($this->translator->trans('Add a person'), [
|
$menu->addChild($this->translator->trans('Add a person'), [
|
||||||
'route' => 'chill_person_new',
|
'route' => 'chill_person_new',
|
||||||
])
|
])
|
||||||
@ -56,12 +54,22 @@ class SectionMenuBuilder implements LocalMenuBuilderInterface
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$menu->addChild($this->translator->trans('Create an accompanying course'), [
|
if ($this->parameterBag->get('chill_person.create_parcours_allowed')) {
|
||||||
'route' => 'chill_person_accompanying_course_new',
|
$menu->addChild($this->translator->trans('Create an accompanying course'), [
|
||||||
|
'route' => 'chill_person_accompanying_course_new',
|
||||||
|
])
|
||||||
|
->setExtras([
|
||||||
|
'order' => 11,
|
||||||
|
'icons' => ['plus'],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$menu->addChild($this->translator->trans('Accompanying courses of users'), [
|
||||||
|
'route' => 'chill_course_list_reassign',
|
||||||
])
|
])
|
||||||
->setExtras([
|
->setExtras([
|
||||||
'order' => 11,
|
'order' => 12,
|
||||||
'icons' => ['plus'],
|
'icons' => ['task'],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,9 +87,12 @@ class AccompanyingPeriodWorkEvaluationRepository implements ObjectRepository
|
|||||||
->join('work.accompanyingPeriod', 'period')
|
->join('work.accompanyingPeriod', 'period')
|
||||||
->where(
|
->where(
|
||||||
$qb->expr()->andX(
|
$qb->expr()->andX(
|
||||||
$qb->expr()->eq('period.user', ':user'),
|
|
||||||
$qb->expr()->isNull('e.endDate'),
|
$qb->expr()->isNull('e.endDate'),
|
||||||
$qb->expr()->gte(':now', $qb->expr()->diff('e.maxDate', 'e.warningInterval'))
|
$qb->expr()->gte(':now', $qb->expr()->diff('e.maxDate', 'e.warningInterval')),
|
||||||
|
$qb->expr()->orX(
|
||||||
|
$qb->expr()->eq('period.user', ':user'),
|
||||||
|
$qb->expr()->isMemberOf(':user', 'work.referrers')
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
->setParameters([
|
->setParameters([
|
||||||
|
@ -159,9 +159,12 @@ final class AccompanyingPeriodWorkRepository implements ObjectRepository
|
|||||||
->join('w.accompanyingPeriod', 'period')
|
->join('w.accompanyingPeriod', 'period')
|
||||||
->where(
|
->where(
|
||||||
$qb->expr()->andX(
|
$qb->expr()->andX(
|
||||||
$qb->expr()->eq('period.user', ':user'),
|
|
||||||
$qb->expr()->gte('w.endDate', ':since'),
|
$qb->expr()->gte('w.endDate', ':since'),
|
||||||
$qb->expr()->lte('w.startDate', ':until')
|
$qb->expr()->lte('w.startDate', ':until'),
|
||||||
|
$qb->expr()->orX(
|
||||||
|
$qb->expr()->eq('period.user', ':user'),
|
||||||
|
$qb->expr()->isMemberOf(':user', 'w.referrers')
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
->setParameters([
|
->setParameters([
|
||||||
|
@ -11,12 +11,14 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Chill\PersonBundle\Repository;
|
namespace Chill\PersonBundle\Repository;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\User;
|
||||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
||||||
use Chill\MainBundle\Security\Resolver\CenterResolverDispatcherInterface;
|
use Chill\MainBundle\Security\Resolver\CenterResolverDispatcherInterface;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
use Symfony\Component\Security\Core\Security;
|
use DateTime;
|
||||||
|
|
||||||
|
use Symfony\Component\Security\Core\Security;
|
||||||
use function count;
|
use function count;
|
||||||
|
|
||||||
final class AccompanyingPeriodACLAwareRepository implements AccompanyingPeriodACLAwareRepositoryInterface
|
final class AccompanyingPeriodACLAwareRepository implements AccompanyingPeriodACLAwareRepositoryInterface
|
||||||
@ -41,6 +43,37 @@ final class AccompanyingPeriodACLAwareRepository implements AccompanyingPeriodAC
|
|||||||
$this->centerResolverDispatcher = $centerResolverDispatcher;
|
$this->centerResolverDispatcher = $centerResolverDispatcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function buildQueryOpenedAccompanyingCourseByUser(?User $user)
|
||||||
|
{
|
||||||
|
$qb = $this->accompanyingPeriodRepository->createQueryBuilder('ap');
|
||||||
|
|
||||||
|
$qb->where($qb->expr()->eq('ap.user', ':user'))
|
||||||
|
->andWhere(
|
||||||
|
$qb->expr()->neq('ap.step', ':draft'),
|
||||||
|
$qb->expr()->orX(
|
||||||
|
$qb->expr()->isNull('ap.closingDate'),
|
||||||
|
$qb->expr()->gt('ap.closingDate', ':now')
|
||||||
|
)
|
||||||
|
)
|
||||||
|
->setParameter('user', $user)
|
||||||
|
->setParameter('now', new DateTime('now'))
|
||||||
|
->setParameter('draft', AccompanyingPeriod::STEP_DRAFT);
|
||||||
|
|
||||||
|
return $qb;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function countByUserOpenedAccompanyingPeriod(?User $user): int
|
||||||
|
{
|
||||||
|
if (null === $user) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->buildQueryOpenedAccompanyingCourseByUser($user)
|
||||||
|
->select('COUNT(ap)')
|
||||||
|
->getQuery()
|
||||||
|
->getSingleScalarResult();
|
||||||
|
}
|
||||||
|
|
||||||
public function findByPerson(
|
public function findByPerson(
|
||||||
Person $person,
|
Person $person,
|
||||||
string $role,
|
string $role,
|
||||||
@ -92,4 +125,25 @@ final class AccompanyingPeriodACLAwareRepository implements AccompanyingPeriodAC
|
|||||||
|
|
||||||
return $qb->getQuery()->getResult();
|
return $qb->getQuery()->getResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array|AccompanyingPeriod[]
|
||||||
|
*/
|
||||||
|
public function findByUserOpenedAccompanyingPeriod(?User $user, array $orderBy = [], int $limit = 0, int $offset = 50): array
|
||||||
|
{
|
||||||
|
if (null === $user) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$qb = $this->buildQueryOpenedAccompanyingCourseByUser($user);
|
||||||
|
|
||||||
|
$qb->setFirstResult($offset)
|
||||||
|
->setMaxResults($limit);
|
||||||
|
|
||||||
|
foreach ($orderBy as $field => $direction) {
|
||||||
|
$qb->addOrderBy('ap.' . $field, $direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $qb->getQuery()->getResult();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,10 +11,13 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Chill\PersonBundle\Repository;
|
namespace Chill\PersonBundle\Repository;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\User;
|
||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
|
|
||||||
interface AccompanyingPeriodACLAwareRepositoryInterface
|
interface AccompanyingPeriodACLAwareRepositoryInterface
|
||||||
{
|
{
|
||||||
|
public function countByUserOpenedAccompanyingPeriod(?User $user): int;
|
||||||
|
|
||||||
public function findByPerson(
|
public function findByPerson(
|
||||||
Person $person,
|
Person $person,
|
||||||
string $role,
|
string $role,
|
||||||
@ -22,4 +25,6 @@ interface AccompanyingPeriodACLAwareRepositoryInterface
|
|||||||
?int $limit = null,
|
?int $limit = null,
|
||||||
?int $offset = null
|
?int $offset = null
|
||||||
): array;
|
): array;
|
||||||
|
|
||||||
|
public function findByUserOpenedAccompanyingPeriod(?User $user, array $orderBy = [], int $limit = 0, int $offset = 50): array;
|
||||||
}
|
}
|
||||||
|
@ -78,6 +78,16 @@ final class AccompanyingPeriodRepository implements ObjectRepository
|
|||||||
->getResult();
|
->getResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function findConfirmedByUser(User $user)
|
||||||
|
{
|
||||||
|
$qb = $this->createQueryBuilder('ap');
|
||||||
|
$qb->where($qb->expr()->eq('ap.user', ':user'))
|
||||||
|
->andWhere('ap.step', 'CONFIRMED')
|
||||||
|
->setParameter('user', $user);
|
||||||
|
|
||||||
|
return $qb;
|
||||||
|
}
|
||||||
|
|
||||||
public function findOneBy(array $criteria): ?AccompanyingPeriod
|
public function findOneBy(array $criteria): ?AccompanyingPeriod
|
||||||
{
|
{
|
||||||
return $this->findOneBy($criteria);
|
return $this->findOneBy($criteria);
|
||||||
|
@ -167,14 +167,19 @@ export default {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
else if (payload.type === 'thirdparty') {
|
else if (payload.type === 'thirdparty') {
|
||||||
|
// console.log('data', payload.data)
|
||||||
|
body.firstname = payload.data.firstname;
|
||||||
body.name = payload.data.name;
|
body.name = payload.data.name;
|
||||||
body.email = payload.data.email;
|
body.email = payload.data.email;
|
||||||
body.telephone = payload.data.telephone;
|
body.telephone = payload.data.telephone;
|
||||||
body.civility = {type: 'chill_main_civility', id: payload.data.civility.id};
|
|
||||||
body.profession = {type: 'third_party_profession', id: payload.data.profession.id};
|
|
||||||
body.address = payload.data.address ? { id: payload.data.address.address_id } : null;
|
body.address = payload.data.address ? { id: payload.data.address.address_id } : null;
|
||||||
|
if (null !== payload.data.civility) {
|
||||||
console.log('body', body);
|
body.civility = {type: 'chill_main_civility', id: payload.data.civility.id};
|
||||||
|
}
|
||||||
|
if (null !== payload.data.profession) {
|
||||||
|
body.profession = {type: 'third_party_profession', id: payload.data.profession.id};
|
||||||
|
}
|
||||||
|
// console.log('body', body);
|
||||||
|
|
||||||
makeFetch('PATCH', `/api/1.0/thirdparty/thirdparty/${payload.data.id}.json`, body)
|
makeFetch('PATCH', `/api/1.0/thirdparty/thirdparty/${payload.data.id}.json`, body)
|
||||||
.then(response => {
|
.then(response => {
|
||||||
|
@ -127,7 +127,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<ul class="record_actions" v-if="evaluationsForAction.length > 0">
|
<ul class="record_actions" v-if="evaluationsForAction.length > 0">
|
||||||
<li>
|
<li>
|
||||||
<button :title="$t('add_an_evaluation')" class="btn btn-create" @click="toggleAddEvaluation"></button>
|
<button :title="$t('add_an_evaluation')" class="btn btn-create" @click="toggleAddEvaluation">{{ $t('add_an_evaluation') }}</button>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
@ -151,6 +151,37 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="referrers" class="action-row">
|
||||||
|
<h3>{{ $t('referrers') }}</h3>
|
||||||
|
|
||||||
|
<div v-if="!hasReferrers">
|
||||||
|
<p class="chill-no-data-statement">{{ $t('no_referrers') }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-else>
|
||||||
|
<ul class="list-suggest remove-items inline">
|
||||||
|
<li v-for="u in referrers" :key="u.id" :title="$t('remove_referrer')" @click="removeReferrer(u)">
|
||||||
|
<span>
|
||||||
|
{{ u.text }}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul class="record_actions">
|
||||||
|
<li class="add-persons">
|
||||||
|
<add-persons
|
||||||
|
ref="referrerPicker"
|
||||||
|
:key="referrerPicker.key"
|
||||||
|
:buttonTitle="$t('add_referrers')"
|
||||||
|
:modalTitle="$t('choose_referrers')"
|
||||||
|
:options="referrerPicker.options"
|
||||||
|
@addNewPersons="addReferrers">
|
||||||
|
</add-persons>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="handlingThirdParty" class="action-row">
|
<div id="handlingThirdParty" class="action-row">
|
||||||
<h3>{{ $t('handling_thirdparty') }}</h3>
|
<h3>{{ $t('handling_thirdparty') }}</h3>
|
||||||
|
|
||||||
@ -289,7 +320,6 @@ import PersonText from 'ChillPersonAssets/vuejs/_components/Entity/PersonText.vu
|
|||||||
import {buildLinkCreate} from 'ChillMainAssets/lib/entity-workflow/api.js';
|
import {buildLinkCreate} from 'ChillMainAssets/lib/entity-workflow/api.js';
|
||||||
import { makeFetch } from 'ChillMainAssets/lib/api/apiMethods';
|
import { makeFetch } from 'ChillMainAssets/lib/api/apiMethods';
|
||||||
|
|
||||||
|
|
||||||
const i18n = {
|
const i18n = {
|
||||||
messages: {
|
messages: {
|
||||||
fr: {
|
fr: {
|
||||||
@ -319,9 +349,13 @@ const i18n = {
|
|||||||
add_thirdparties: "Ajouter des tiers",
|
add_thirdparties: "Ajouter des tiers",
|
||||||
choose_thirdparties: "Choisir des tiers",
|
choose_thirdparties: "Choisir des tiers",
|
||||||
fix_these_errors: "Veuillez corriger les erreurs suivantes :",
|
fix_these_errors: "Veuillez corriger les erreurs suivantes :",
|
||||||
available_evaluations_text: "Évaluations disponibles pour ajout :",
|
available_evaluations_text: "Documents disponibles pour ajout :",
|
||||||
no_evaluations_available: "Aucune évaluation disponible",
|
no_evaluations_available: "Aucune évaluation disponible",
|
||||||
no_goals_available: "Aucun objectif disponible",
|
no_goals_available: "Aucun objectif disponible",
|
||||||
|
referrers: "Agents traitants",
|
||||||
|
no_referrers: "Aucun agent traitant",
|
||||||
|
choose_referrers: "Choisir des agents traitants",
|
||||||
|
remove_referrer: "Enlever l'agent"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -370,6 +404,17 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
referrerPicker: {
|
||||||
|
key: 'referrer',
|
||||||
|
options: {
|
||||||
|
type: ['user'],
|
||||||
|
priority: null,
|
||||||
|
uniq: false,
|
||||||
|
button: {
|
||||||
|
display: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -381,6 +426,7 @@ export default {
|
|||||||
'personsReachables',
|
'personsReachables',
|
||||||
'handlingThirdParty',
|
'handlingThirdParty',
|
||||||
'thirdParties',
|
'thirdParties',
|
||||||
|
'referrers',
|
||||||
'isPosting',
|
'isPosting',
|
||||||
'errors',
|
'errors',
|
||||||
'templatesAvailablesForAction',
|
'templatesAvailablesForAction',
|
||||||
@ -389,6 +435,7 @@ export default {
|
|||||||
'hasResultsForAction',
|
'hasResultsForAction',
|
||||||
'hasHandlingThirdParty',
|
'hasHandlingThirdParty',
|
||||||
'hasThirdParties',
|
'hasThirdParties',
|
||||||
|
'hasReferrers'
|
||||||
]),
|
]),
|
||||||
startDate: {
|
startDate: {
|
||||||
get() {
|
get() {
|
||||||
@ -465,6 +512,14 @@ export default {
|
|||||||
removeThirdParty(t) {
|
removeThirdParty(t) {
|
||||||
this.$store.commit('removeThirdParty', t);
|
this.$store.commit('removeThirdParty', t);
|
||||||
},
|
},
|
||||||
|
addReferrers({selected, modal}) {
|
||||||
|
this.$store.commit('addReferrers', selected.map(r => r.result));
|
||||||
|
this.$refs.referrerPicker.resetSearch();
|
||||||
|
modal.showModal = false;
|
||||||
|
},
|
||||||
|
removeReferrer(u) {
|
||||||
|
this.$store.commit('removeReferrer', u);
|
||||||
|
},
|
||||||
goToGenerateWorkflow({link}) {
|
goToGenerateWorkflow({link}) {
|
||||||
console.log('save before leave to generate workflow')
|
console.log('save before leave to generate workflow')
|
||||||
const callback = (data) => {
|
const callback = (data) => {
|
||||||
@ -521,6 +576,7 @@ div#workEditor {
|
|||||||
"objectives objectives"
|
"objectives objectives"
|
||||||
"evaluations evaluations"
|
"evaluations evaluations"
|
||||||
"persons persons"
|
"persons persons"
|
||||||
|
"referrers referrers"
|
||||||
"handling handling"
|
"handling handling"
|
||||||
"tparties tparties"
|
"tparties tparties"
|
||||||
"errors errors";
|
"errors errors";
|
||||||
@ -543,6 +599,8 @@ div#workEditor {
|
|||||||
grid-area: handling; }
|
grid-area: handling; }
|
||||||
#thirdParties {
|
#thirdParties {
|
||||||
grid-area: tparties; }
|
grid-area: tparties; }
|
||||||
|
#referrers {
|
||||||
|
grid-area: referrers; }
|
||||||
#errors {
|
#errors {
|
||||||
grid-area: errors; }
|
grid-area: errors; }
|
||||||
|
|
||||||
@ -657,5 +715,4 @@ div#workEditor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
</li>
|
</li>
|
||||||
<li v-if="canDelete">
|
<li v-if="canDelete">
|
||||||
<a class="btn btn-delete" @click="modal.showModal = true" :title="$t('action.delete')"></a>
|
<a class="btn btn-delete" @click="modal.showModal = true" :title="$t('action.delete')">{{ $t('delete_evaluation')}}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -72,7 +72,8 @@ const i18n = {
|
|||||||
sure: "Êtes-vous sûr?",
|
sure: "Êtes-vous sûr?",
|
||||||
sure_description: "Cette évaluation sera supprimée de cette action d'accompagnement",
|
sure_description: "Cette évaluation sera supprimée de cette action d'accompagnement",
|
||||||
ok: "Supprimer"
|
ok: "Supprimer"
|
||||||
}
|
},
|
||||||
|
delete_evaluation: "Supprimer l'évaluation",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -65,16 +65,17 @@
|
|||||||
<h5>{{ $t('Documents') }} :</h5>
|
<h5>{{ $t('Documents') }} :</h5>
|
||||||
|
|
||||||
<div class="flex-table">
|
<div class="flex-table">
|
||||||
<div class="item-bloc" v-for="(d, i) in evaluation.documents" :key="d.key">
|
<div class="item-bloc" v-for="(d, i) in evaluation.documents" :key="d.id">
|
||||||
<div class="item-row">
|
<div class="item-row">
|
||||||
<div class="input-group input-group-lg mb-3">
|
<div class="input-group input-group-lg mb-3">
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input
|
||||||
class="form-control form-control-lg"
|
class="form-control"
|
||||||
style="font-weight: bold;"
|
style="font-weight: bold;"
|
||||||
type="text"
|
type="text"
|
||||||
:value="d.title"
|
:value="d.title"
|
||||||
:id="d.id"
|
:id="d.id"
|
||||||
|
:data-key="i"
|
||||||
@input="onInputDocumentTitle"/>
|
@input="onInputDocumentTitle"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -84,6 +85,8 @@
|
|||||||
<p v-if="d.createdBy" class="createdBy">Créé par {{ d.createdBy.text }}<br/>
|
<p v-if="d.createdBy" class="createdBy">Créé par {{ d.createdBy.text }}<br/>
|
||||||
Le {{ $d(ISOToDatetime(d.createdAt.datetime), 'long') }}</p>
|
Le {{ $d(ISOToDatetime(d.createdAt.datetime), 'long') }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item-row">
|
||||||
<div class="item-col">
|
<div class="item-col">
|
||||||
<ul class="record_actions" >
|
<ul class="record_actions" >
|
||||||
<li v-if="d.workflows_availables.length > 0">
|
<li v-if="d.workflows_availables.length > 0">
|
||||||
@ -98,6 +101,23 @@
|
|||||||
@go-to-generate-workflow="goToGenerateWorkflowEvaluationDocument"
|
@go-to-generate-workflow="goToGenerateWorkflowEvaluationDocument"
|
||||||
></list-workflow-modal>
|
></list-workflow-modal>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<add-async-upload
|
||||||
|
:buttonTitle="$t('replace')"
|
||||||
|
:options="asyncUploadOptions"
|
||||||
|
:btnClasses="{'btn': true, 'btn-edit': true}"
|
||||||
|
@addDocument="(arg) => replaceDocument(d, arg)"
|
||||||
|
>
|
||||||
|
</add-async-upload>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<add-async-upload-downloader
|
||||||
|
:buttonTitle="$t('download')"
|
||||||
|
:storedObject="d.storedObject"
|
||||||
|
>
|
||||||
|
</add-async-upload-downloader>
|
||||||
|
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a :href="buildEditLink(d.storedObject)" class="btn btn-wopilink"></a>
|
<a :href="buildEditLink(d.storedObject)" class="btn btn-wopilink"></a>
|
||||||
</li>
|
</li>
|
||||||
@ -152,6 +172,7 @@ import { mapGetters, mapState } from 'vuex';
|
|||||||
import PickTemplate from 'ChillDocGeneratorAssets/vuejs/_components/PickTemplate.vue';
|
import PickTemplate from 'ChillDocGeneratorAssets/vuejs/_components/PickTemplate.vue';
|
||||||
import {buildLink} from 'ChillDocGeneratorAssets/lib/document-generator';
|
import {buildLink} from 'ChillDocGeneratorAssets/lib/document-generator';
|
||||||
import AddAsyncUpload from 'ChillDocStoreAssets/vuejs/_components/AddAsyncUpload.vue';
|
import AddAsyncUpload from 'ChillDocStoreAssets/vuejs/_components/AddAsyncUpload.vue';
|
||||||
|
import AddAsyncUploadDownloader from 'ChillDocStoreAssets/vuejs/_components/AddAsyncUploadDownloader.vue';
|
||||||
import ListWorkflowModal from 'ChillMainAssets/vuejs/_components/EntityWorkflow/ListWorkflowModal.vue';
|
import ListWorkflowModal from 'ChillMainAssets/vuejs/_components/EntityWorkflow/ListWorkflowModal.vue';
|
||||||
import {buildLinkCreate} from 'ChillMainAssets/lib/entity-workflow/api.js';
|
import {buildLinkCreate} from 'ChillMainAssets/lib/entity-workflow/api.js';
|
||||||
|
|
||||||
@ -176,7 +197,9 @@ const i18n = {
|
|||||||
document_upload: "Téléverser un document",
|
document_upload: "Téléverser un document",
|
||||||
document_title: "Titre du document",
|
document_title: "Titre du document",
|
||||||
template_title: "Nom du template",
|
template_title: "Nom du template",
|
||||||
browse: "Ajouter un document"
|
browse: "Ajouter un document",
|
||||||
|
replace: "Remplacer",
|
||||||
|
download: "Télécharger le fichier existant"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -188,6 +211,7 @@ export default {
|
|||||||
ckeditor: CKEditor.component,
|
ckeditor: CKEditor.component,
|
||||||
PickTemplate,
|
PickTemplate,
|
||||||
AddAsyncUpload,
|
AddAsyncUpload,
|
||||||
|
AddAsyncUploadDownloader,
|
||||||
ListWorkflowModal,
|
ListWorkflowModal,
|
||||||
},
|
},
|
||||||
i18n,
|
i18n,
|
||||||
@ -274,8 +298,9 @@ export default {
|
|||||||
},
|
},
|
||||||
onInputDocumentTitle(event) {
|
onInputDocumentTitle(event) {
|
||||||
const id = Number(event.target.id);
|
const id = Number(event.target.id);
|
||||||
|
const key = Number(event.target.dataset.key) + 1;
|
||||||
const title = event.target.value;
|
const title = event.target.value;
|
||||||
this.$store.commit('updateDocumentTitle', {id: id, evaluationKey: this.evaluation.key, title: title});
|
this.$store.commit('updateDocumentTitle', {id: id, key: key, evaluationKey: this.evaluation.key, title: title});
|
||||||
},
|
},
|
||||||
addDocument(storedObject) {
|
addDocument(storedObject) {
|
||||||
let document = {
|
let document = {
|
||||||
@ -285,6 +310,14 @@ export default {
|
|||||||
};
|
};
|
||||||
this.$store.commit('addDocument', {key: this.evaluation.key, document: document});
|
this.$store.commit('addDocument', {key: this.evaluation.key, document: document});
|
||||||
},
|
},
|
||||||
|
replaceDocument(oldDocument, storedObject) {
|
||||||
|
let document = {
|
||||||
|
type: 'accompanying_period_work_evaluation_document',
|
||||||
|
storedObject: storedObject,
|
||||||
|
title: oldDocument.title
|
||||||
|
};
|
||||||
|
this.$store.commit('replaceDocument', {key: this.evaluation.key, document: document, oldDocument: oldDocument});
|
||||||
|
},
|
||||||
removeDocument(document) {
|
removeDocument(document) {
|
||||||
if (window.confirm("Êtes-vous sûr·e de vouloir supprimer le document qui a pour titre \"" + document.title +"\" ?")) {
|
if (window.confirm("Êtes-vous sûr·e de vouloir supprimer le document qui a pour titre \"" + document.title +"\" ?")) {
|
||||||
this.$store.commit('removeDocument', {key: this.evaluation.key, document: document});
|
this.$store.commit('removeDocument', {key: this.evaluation.key, document: document});
|
||||||
|
@ -31,6 +31,7 @@ const store = createStore({
|
|||||||
.map(p => p.person),
|
.map(p => p.person),
|
||||||
handlingThirdParty: window.accompanyingCourseWork.handlingThierParty,
|
handlingThirdParty: window.accompanyingCourseWork.handlingThierParty,
|
||||||
thirdParties: window.accompanyingCourseWork.thirdParties,
|
thirdParties: window.accompanyingCourseWork.thirdParties,
|
||||||
|
referrers: window.accompanyingCourseWork.referrers,
|
||||||
isPosting: false,
|
isPosting: false,
|
||||||
errors: [],
|
errors: [],
|
||||||
},
|
},
|
||||||
@ -54,6 +55,9 @@ const store = createStore({
|
|||||||
hasHandlingThirdParty(state) {
|
hasHandlingThirdParty(state) {
|
||||||
return state.handlingThirdParty !== null;
|
return state.handlingThirdParty !== null;
|
||||||
},
|
},
|
||||||
|
hasReferrers(state) {
|
||||||
|
return state.referrers.length > 0;
|
||||||
|
},
|
||||||
hasThirdParties(state) {
|
hasThirdParties(state) {
|
||||||
return state.thirdParties.length > 0;
|
return state.thirdParties.length > 0;
|
||||||
},
|
},
|
||||||
@ -82,6 +86,7 @@ const store = createStore({
|
|||||||
},
|
},
|
||||||
results: state.resultsPicked.map(r => ({id: r.id, type: r.type})),
|
results: state.resultsPicked.map(r => ({id: r.id, type: r.type})),
|
||||||
thirdParties: state.thirdParties.map(t => ({id: t.id, type: t.type})),
|
thirdParties: state.thirdParties.map(t => ({id: t.id, type: t.type})),
|
||||||
|
referrers: state.referrers.map(t => ({id: t.id, type: t.type})),
|
||||||
goals: state.goalsPicked.map(g => {
|
goals: state.goalsPicked.map(g => {
|
||||||
let o = {
|
let o = {
|
||||||
type: g.type,
|
type: g.type,
|
||||||
@ -131,9 +136,9 @@ const store = createStore({
|
|||||||
endDate: e.endDate !== null ? ISOToDatetime(e.endDate.datetime) : null,
|
endDate: e.endDate !== null ? ISOToDatetime(e.endDate.datetime) : null,
|
||||||
maxDate: e.maxDate !== null ? ISOToDatetime(e.maxDate.datetime) : null,
|
maxDate: e.maxDate !== null ? ISOToDatetime(e.maxDate.datetime) : null,
|
||||||
warningInterval: e.warningInterval !== null ? intervalISOToDays(e.warningInterval) : null,
|
warningInterval: e.warningInterval !== null ? intervalISOToDays(e.warningInterval) : null,
|
||||||
documents: e.documents.map((d, dindex) => {
|
documents: e.documents.map((d, docIndex) => {
|
||||||
return Object.assign(d, {
|
return Object.assign(d, {
|
||||||
key: index
|
key: docIndex
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
@ -213,13 +218,26 @@ const store = createStore({
|
|||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
removeDocument(state, {key, document}) {
|
removeDocument(state, {key, document}) {
|
||||||
let evaluations = state.evaluationsPicked.find(e => e.key === key);
|
let evaluation = state.evaluationsPicked.find(e => e.key === key);
|
||||||
|
if (evaluation === undefined) {
|
||||||
if (evaluations === undefined) {
|
return;
|
||||||
|
}
|
||||||
|
evaluation.documents = evaluation.documents.filter(d => d.key !== document.key);
|
||||||
|
},
|
||||||
|
replaceDocument(state, payload) {
|
||||||
|
let evaluation = state.evaluationsPicked.find(e => e.key === payload.key);
|
||||||
|
if (evaluation === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
evaluations.documents = evaluations.documents.filter(d => d.key !== document.key);
|
let newDocument = Object.assign(
|
||||||
|
payload.document, {
|
||||||
|
key: evaluation.documents.length + 1,
|
||||||
|
workflows_availables: state.work.workflows_availables_evaluation_documents,
|
||||||
|
workflows: [],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
evaluation.documents = evaluation.documents.map(d => d.id === payload.oldDocument.id ? newDocument : d);
|
||||||
},
|
},
|
||||||
addEvaluation(state, evaluation) {
|
addEvaluation(state, evaluation) {
|
||||||
let e = {
|
let e = {
|
||||||
@ -302,6 +320,18 @@ const store = createStore({
|
|||||||
state.thirdParties = state.thirdParties
|
state.thirdParties = state.thirdParties
|
||||||
.filter(t => t.id !== thirdParty.id);
|
.filter(t => t.id !== thirdParty.id);
|
||||||
},
|
},
|
||||||
|
addReferrers(state, referrers) {
|
||||||
|
let ids = state.referrers.map(t => t.id);
|
||||||
|
let unexistings = referrers.filter(t => !ids.includes(t.id));
|
||||||
|
|
||||||
|
for (let i in unexistings) {
|
||||||
|
state.referrers.push(unexistings[i]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
removeReferrer(state, user) {
|
||||||
|
state.referrers = state.referrers
|
||||||
|
.filter(u => u.id !== user.id);
|
||||||
|
},
|
||||||
setErrors(state, errors) {
|
setErrors(state, errors) {
|
||||||
state.errors = errors;
|
state.errors = errors;
|
||||||
},
|
},
|
||||||
@ -309,13 +339,17 @@ const store = createStore({
|
|||||||
state.isPosting = st;
|
state.isPosting = st;
|
||||||
},
|
},
|
||||||
updateDocumentTitle(state, payload) {
|
updateDocumentTitle(state, payload) {
|
||||||
state.evaluationsPicked.find(e => e.key === payload.evaluationKey)
|
if (payload.id === 0) {
|
||||||
|
state.evaluationsPicked.find(e => e.key === payload.evaluationKey)
|
||||||
|
.documents.find(d => d.key === payload.key).title = payload.title;
|
||||||
|
} else {
|
||||||
|
state.evaluationsPicked.find(e => e.key === payload.evaluationKey)
|
||||||
.documents.find(d => d.id === payload.id).title = payload.title;
|
.documents.find(d => d.id === payload.id).title = payload.title;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
updateThirdParty({ commit }, payload) {
|
updateThirdParty({ commit }, payload) {
|
||||||
console.log(payload);
|
|
||||||
commit('updateThirdParty', payload);
|
commit('updateThirdParty', payload);
|
||||||
},
|
},
|
||||||
getReachablesGoalsForAction({ getters, commit, dispatch }) {
|
getReachablesGoalsForAction({ getters, commit, dispatch }) {
|
||||||
@ -408,6 +442,9 @@ const store = createStore({
|
|||||||
removeDocument({commit}, payload) {
|
removeDocument({commit}, payload) {
|
||||||
commit('removeDocument', payload);
|
commit('removeDocument', payload);
|
||||||
},
|
},
|
||||||
|
replaceDocument({commit}, payload) {
|
||||||
|
commit('replaceDocument', payload);
|
||||||
|
},
|
||||||
submit({ getters, state, commit }, callback) {
|
submit({ getters, state, commit }, callback) {
|
||||||
let
|
let
|
||||||
payload = getters.buildPayload,
|
payload = getters.buildPayload,
|
||||||
|
@ -24,11 +24,11 @@
|
|||||||
|
|
||||||
<div class="form-floating mb-3">
|
<div class="form-floating mb-3">
|
||||||
<input
|
<input
|
||||||
class="form-control form-control-lg"
|
class="form-control form-control-lg"
|
||||||
id="lastname"
|
id="lastname"
|
||||||
v-model="lastName"
|
v-model="lastName"
|
||||||
:placeholder="$t('person.lastname')"
|
:placeholder="$t('person.lastname')"
|
||||||
@change="checkErrors"
|
@change="checkErrors"
|
||||||
/>
|
/>
|
||||||
<label for="lastname">{{ $t('person.lastname') }}</label>
|
<label for="lastname">{{ $t('person.lastname') }}</label>
|
||||||
</div>
|
</div>
|
||||||
@ -43,11 +43,11 @@
|
|||||||
|
|
||||||
<div class="form-floating mb-3">
|
<div class="form-floating mb-3">
|
||||||
<input
|
<input
|
||||||
class="form-control form-control-lg"
|
class="form-control form-control-lg"
|
||||||
id="firstname"
|
id="firstname"
|
||||||
v-model="firstName"
|
v-model="firstName"
|
||||||
:placeholder="$t('person.firstname')"
|
:placeholder="$t('person.firstname')"
|
||||||
@change="checkErrors"
|
@change="checkErrors"
|
||||||
/>
|
/>
|
||||||
<label for="firstname">{{ $t('person.firstname') }}</label>
|
<label for="firstname">{{ $t('person.firstname') }}</label>
|
||||||
</div>
|
</div>
|
||||||
@ -62,10 +62,10 @@
|
|||||||
|
|
||||||
<div v-for="(a, i) in config.altNames" :key="a.key" class="form-floating mb-3">
|
<div v-for="(a, i) in config.altNames" :key="a.key" class="form-floating mb-3">
|
||||||
<input
|
<input
|
||||||
class="form-control form-control-lg"
|
class="form-control form-control-lg"
|
||||||
:id="a.key"
|
:id="a.key"
|
||||||
:value="personAltNamesLabels[i]"
|
:value="personAltNamesLabels[i]"
|
||||||
@input="onAltNameInput"
|
@input="onAltNameInput"
|
||||||
/>
|
/>
|
||||||
<label :for="a.key">{{ a.labels.fr }}</label>
|
<label :for="a.key">{{ a.labels.fr }}</label>
|
||||||
</div>
|
</div>
|
||||||
@ -125,9 +125,9 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="alert alert-warning" v-if="errors.length">
|
<div class="alert alert-warning" v-if="errors.length">
|
||||||
<ul>
|
<ul>
|
||||||
<li v-for="(e, i) in errors" :key="i">{{ e }}</li>
|
<li v-for="(e, i) in errors" :key="i">{{ e }}</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -238,13 +238,13 @@ export default {
|
|||||||
checkErrors(e) {
|
checkErrors(e) {
|
||||||
this.errors = [];
|
this.errors = [];
|
||||||
if (!this.person.lastName) {
|
if (!this.person.lastName) {
|
||||||
this.errors.push("Le nom ne doit pas être vide.");
|
this.errors.push("Le nom ne doit pas être vide.");
|
||||||
}
|
}
|
||||||
if (!this.person.firstName) {
|
if (!this.person.firstName) {
|
||||||
this.errors.push("Le prénom ne doit pas être vide.");
|
this.errors.push("Le prénom ne doit pas être vide.");
|
||||||
}
|
}
|
||||||
if (!this.person.gender) {
|
if (!this.person.gender) {
|
||||||
this.errors.push("Le genre doit être renseigné");
|
this.errors.push("Le genre doit être renseigné");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
loadData() {
|
loadData() {
|
||||||
|
@ -28,11 +28,14 @@
|
|||||||
{% if w.createdBy %}
|
{% if w.createdBy %}
|
||||||
<div class="wl-row">
|
<div class="wl-row">
|
||||||
<div class="wl-col title">
|
<div class="wl-col title">
|
||||||
<h3>{{ 'Referrer'|trans }}</h3>
|
<h3>{{ 'Referrers'|trans }}</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="wl-col list">
|
<div class="wl-col list">
|
||||||
<p class="wl-item">
|
<p class="wl-item">
|
||||||
{{ w.createdBy|chill_entity_render_box }}
|
{% for u in w.referrers %}
|
||||||
|
{{ u|chill_entity_render_box }}
|
||||||
|
{% if not loop.last %}, {% endif %}
|
||||||
|
{% endfor %}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -0,0 +1,82 @@
|
|||||||
|
{% extends 'ChillMainBundle::layout.html.twig' %}
|
||||||
|
|
||||||
|
{% block title 'period_by_user_list.Period by user'|trans %}
|
||||||
|
|
||||||
|
{% block js %}
|
||||||
|
{{ encore_entry_script_tags('mod_set_referrer') }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block css %}
|
||||||
|
{{ encore_entry_link_tags('mod_set_referrer') }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% macro period_meta(period) %}
|
||||||
|
{% if is_granted('CHILL_PERSON_ACCOMPANYING_PERIOD_UPDATE', period) %}
|
||||||
|
<div class="item-col item-meta">
|
||||||
|
{% set job_id = null %}
|
||||||
|
{% if period.job is defined %}
|
||||||
|
{% set job_id = period.job.id %}
|
||||||
|
{% endif %}
|
||||||
|
<span
|
||||||
|
data-set-referrer-app="data-set-referrer-app"
|
||||||
|
data-set-referrer-accompanying-period-id="{{ period.id }}"
|
||||||
|
data-set-referrer-job-id="{{ job_id }}"
|
||||||
|
></span>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
|
||||||
|
{% macro period_actions(period) %}
|
||||||
|
{% if is_granted('CHILL_PERSON_ACCOMPANYING_PERIOD_SEE', period) %}
|
||||||
|
<li>
|
||||||
|
<a href="{{ chill_path_add_return_path('chill_person_accompanying_course_index', {'accompanying_period_id': period.id}) }}" class="btn btn-show"></a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% import _self as m %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="col-10">
|
||||||
|
<h1>{{ block('title') }}</h1>
|
||||||
|
|
||||||
|
{{ form_start(form) }}
|
||||||
|
<div class="row filter-box">
|
||||||
|
<div class="col-md-6">
|
||||||
|
{{ form_label(form.user ) }}
|
||||||
|
{{ form_widget(form.user, {'attr': {'class': 'select2'}}) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul class="record_actions">
|
||||||
|
<li>
|
||||||
|
<button type="submit" class="btn btn-save change-icon">
|
||||||
|
<i class="fa fa-filter"></i> Filtrer
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
{{ form_end(form) }}
|
||||||
|
|
||||||
|
{% if form.user.vars.value is empty %}
|
||||||
|
<p class="chill-no-data-statement">{{ 'period_by_user_list.Pick a user'|trans }}</p>
|
||||||
|
{% elseif periods|length == 0 and form.user.vars.value is not empty %}
|
||||||
|
<p class="chill-no-data-statement">{{ 'period_by_user_list.Any course or no authorization to see them'|trans }}</p>
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
<p><span class="badge rounded-pill bg-primary">{{ paginator.totalItems }}</span> parcours à réassigner (calculé ce jour à {{ null|format_time('medium') }})</p>
|
||||||
|
|
||||||
|
<div class="flex-table">
|
||||||
|
{% for period in periods %}
|
||||||
|
{% include '@ChillPerson/AccompanyingPeriod/_list_item.html.twig' with {'period': period,
|
||||||
|
'recordAction': m.period_actions(period), 'itemMeta': m.period_meta(period) } %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{{ chill_pagination(paginator) }}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -46,13 +46,13 @@
|
|||||||
{{ 'Household summary'|trans }}
|
{{ 'Household summary'|trans }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{#
|
{# TODO: add ACL to check if user is allowed to edit household? #}
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ path ('chill_person_household_accompanying_course_new', {'household_id' : [ household.id ] } ) }}" class="btn btn-create">
|
<a class="btn btn-create"
|
||||||
{{ 'Create an accompanying period'|trans }}
|
href="{{ path ('chill_household_accompanying_course_new', {'household_id' : household.id } ) }}" role="button">
|
||||||
|
{{ 'Create an accompanying period'|trans }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
#}
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
|
{%- import "@ChillDocStore/Macro/macro.html.twig" as m -%}
|
||||||
|
|
||||||
<div class="flex-table accompanying_course_work-list">
|
<div class="flex-table accompanying_course_work-list">
|
||||||
<div class="item-bloc evaluation-item bg-chill-llight-gray">
|
<div class="item-bloc evaluation-item bg-chill-llight-gray">
|
||||||
|
<div class="item-row mb-2">
|
||||||
|
<h1>{{ doc.title }}</h1>
|
||||||
|
</div>
|
||||||
<div class="item-row mb-2">
|
<div class="item-row mb-2">
|
||||||
<h2 class="badge-title">
|
<h2 class="badge-title">
|
||||||
<span class="title_label"></span>
|
<span class="title_label"></span>
|
||||||
@ -20,6 +25,24 @@
|
|||||||
</span>
|
</span>
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="item-row mb-2">
|
||||||
|
<div class="item-col" style="width: 17%;">
|
||||||
|
<h4 class="title_label">
|
||||||
|
{{ 'Participants'|trans }}
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
<div class="item-col list">
|
||||||
|
{% for p in evaluation.accompanyingPeriodWork.persons %}
|
||||||
|
{% include '@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with {
|
||||||
|
targetEntity: { name: 'person', id: p.id },
|
||||||
|
action: 'show',
|
||||||
|
displayBadge: true,
|
||||||
|
buttonText: p|chill_entity_render_string,
|
||||||
|
isDead: p.deathdate is not null
|
||||||
|
} %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="item-row column">
|
<div class="item-row column">
|
||||||
<table class="obj-res-eval my-3" style="font-size: 110% !important;">
|
<table class="obj-res-eval my-3" style="font-size: 110% !important;">
|
||||||
<thead>
|
<thead>
|
||||||
@ -92,12 +115,19 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if display_action is defined and display_action == true %}
|
{% if display_action is defined and display_action == true %}
|
||||||
{# TODO add acl #}
|
{% if is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', evaluation.accompanyingPeriodWork) %}
|
||||||
<ul class="record_actions">
|
<ul class="record_actions">
|
||||||
|
<li>{{ m.download_button(doc.storedObject, doc.title) }}</li>
|
||||||
|
{% if chill_document_is_editable(doc.storedObject) %}
|
||||||
|
<li>
|
||||||
|
{{ doc.storedObject|chill_document_edit_button }}
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
<li>
|
<li>
|
||||||
<a class="btn btn-show" href="{{ path('chill_person_accompanying_period_work_edit', {'id': evaluation.accompanyingPeriodWork.id}) }}">
|
<a class="btn btn-show" href="{{ path('chill_person_accompanying_period_work_edit', {'id': evaluation.accompanyingPeriodWork.id}) }}">
|
||||||
{{ 'Show'|trans }}
|
{{ 'Show'|trans }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -14,6 +14,7 @@ namespace Chill\PersonBundle\Serializer\Normalizer;
|
|||||||
use Chill\MainBundle\Repository\Workflow\EntityWorkflowRepository;
|
use Chill\MainBundle\Repository\Workflow\EntityWorkflowRepository;
|
||||||
use Chill\MainBundle\Workflow\Helper\MetadataExtractor;
|
use Chill\MainBundle\Workflow\Helper\MetadataExtractor;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation;
|
||||||
|
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
||||||
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
|
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
|
||||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
|
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
|
||||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
|
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
|
||||||
@ -46,7 +47,10 @@ class AccompanyingPeriodWorkEvaluationNormalizer implements ContextAwareNormaliz
|
|||||||
{
|
{
|
||||||
$initial = $this->normalizer->normalize($object, $format, array_merge(
|
$initial = $this->normalizer->normalize($object, $format, array_merge(
|
||||||
$context,
|
$context,
|
||||||
[self::IGNORE_EVALUATION => spl_object_hash($object)]
|
[self::IGNORE_EVALUATION => spl_object_hash($object)],
|
||||||
|
[AbstractNormalizer::CIRCULAR_REFERENCE_HANDLER => static function ($object, $format, $context) {
|
||||||
|
return $object->getId();
|
||||||
|
}]
|
||||||
));
|
));
|
||||||
|
|
||||||
// due to bug: https://api-platform.com/docs/core/serialization/#collection-relation
|
// due to bug: https://api-platform.com/docs/core/serialization/#collection-relation
|
||||||
|
@ -23,6 +23,7 @@ use Chill\PersonBundle\Templating\Entity\PersonRenderInterface;
|
|||||||
use DateTimeInterface;
|
use DateTimeInterface;
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
|
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
|
||||||
|
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
||||||
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
|
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
|
||||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
|
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
|
||||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
|
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
|
||||||
@ -30,6 +31,8 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
|||||||
|
|
||||||
use function array_map;
|
use function array_map;
|
||||||
use function implode;
|
use function implode;
|
||||||
|
use function in_array;
|
||||||
|
use function is_string;
|
||||||
|
|
||||||
class PersonDocGenNormalizer implements
|
class PersonDocGenNormalizer implements
|
||||||
ContextAwareNormalizerInterface,
|
ContextAwareNormalizerInterface,
|
||||||
@ -63,6 +66,15 @@ class PersonDocGenNormalizer implements
|
|||||||
$dateContext = $context;
|
$dateContext = $context;
|
||||||
$dateContext['docgen:expects'] = DateTimeInterface::class;
|
$dateContext['docgen:expects'] = DateTimeInterface::class;
|
||||||
$addressContext = array_merge($context, ['docgen:expects' => Address::class]);
|
$addressContext = array_merge($context, ['docgen:expects' => Address::class]);
|
||||||
|
$personResourceContext = array_merge($context, [
|
||||||
|
'docgen:expects' => Person\PersonResource::class,
|
||||||
|
// we simplify the list of attributes for the embedded persons
|
||||||
|
AbstractNormalizer::GROUPS => ['docgen:read'],
|
||||||
|
// when a person reference the same person... take care of circular references
|
||||||
|
AbstractNormalizer::CIRCULAR_REFERENCE_HANDLER => function ($object, $format, $context) {
|
||||||
|
return $this->normalizer->normalize(null, $format, $context);
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
if (null === $person) {
|
if (null === $person) {
|
||||||
return $this->normalizeNullValue($format, $context);
|
return $this->normalizeNullValue($format, $context);
|
||||||
@ -104,6 +116,7 @@ class PersonDocGenNormalizer implements
|
|||||||
'memo' => $person->getMemo(),
|
'memo' => $person->getMemo(),
|
||||||
'numberOfChildren' => (string) $person->getNumberOfChildren(),
|
'numberOfChildren' => (string) $person->getNumberOfChildren(),
|
||||||
'address' => $this->normalizer->normalize($person->getCurrentPersonAddress(), $format, $addressContext),
|
'address' => $this->normalizer->normalize($person->getCurrentPersonAddress(), $format, $addressContext),
|
||||||
|
//'resources' => $this->normalizer->normalize($person->getResources(), $format, $personResourceContext),
|
||||||
];
|
];
|
||||||
|
|
||||||
if ($context['docgen:person:with-household'] ?? false) {
|
if ($context['docgen:person:with-household'] ?? false) {
|
||||||
@ -147,6 +160,17 @@ class PersonDocGenNormalizer implements
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function hasGroup($context, string $group): bool
|
||||||
|
{
|
||||||
|
$groups = $context[AbstractNormalizer::GROUPS] ?? [];
|
||||||
|
|
||||||
|
if (is_string($groups)) {
|
||||||
|
$groups = [$groups];
|
||||||
|
}
|
||||||
|
|
||||||
|
return in_array($group, $groups, true);
|
||||||
|
}
|
||||||
|
|
||||||
private function normalizeNullValue(string $format, array $context)
|
private function normalizeNullValue(string $format, array $context)
|
||||||
{
|
{
|
||||||
$normalizer = new NormalizeNullValueHelper($this->normalizer, 'type', 'person');
|
$normalizer = new NormalizeNullValueHelper($this->normalizer, 'type', 'person');
|
||||||
@ -169,6 +193,8 @@ class PersonDocGenNormalizer implements
|
|||||||
|
|
||||||
$data = $normalizer->normalize($attributes, $format, $context);
|
$data = $normalizer->normalize($attributes, $format, $context);
|
||||||
|
|
||||||
|
//$data['resources'] = [];
|
||||||
|
|
||||||
if ($context['docgen:person:with-relations'] ?? false) {
|
if ($context['docgen:person:with-relations'] ?? false) {
|
||||||
$data['relations'] = [];
|
$data['relations'] = [];
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ use Chill\PersonBundle\Entity\Household\HouseholdMember;
|
|||||||
use Chill\PersonBundle\Entity\Household\Position;
|
use Chill\PersonBundle\Entity\Household\Position;
|
||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
use DateTimeImmutable;
|
use DateTimeImmutable;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||||
|
|
||||||
@ -25,17 +26,24 @@ use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
|||||||
*/
|
*/
|
||||||
final class HouseholdNormalizerTest extends KernelTestCase
|
final class HouseholdNormalizerTest extends KernelTestCase
|
||||||
{
|
{
|
||||||
|
private EntityManagerInterface $entityManager;
|
||||||
|
|
||||||
private ?NormalizerInterface $normalizer;
|
private ?NormalizerInterface $normalizer;
|
||||||
|
|
||||||
|
private array $toDelete;
|
||||||
|
|
||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
self::bootKernel();
|
self::bootKernel();
|
||||||
$this->normalizer = self::$container->get(NormalizerInterface::class);
|
$this->normalizer = self::$container->get(NormalizerInterface::class);
|
||||||
|
$this->entityManager = self::$container->get(EntityManagerInterface::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testNormalizationRecursive()
|
public function testNormalizationRecursive()
|
||||||
{
|
{
|
||||||
$person = new Person();
|
$person = new Person();
|
||||||
|
$person->setFirstName('ok')->setLastName('ok');
|
||||||
|
$this->entityManager->persist($person);
|
||||||
$member = new HouseholdMember();
|
$member = new HouseholdMember();
|
||||||
$household = new Household();
|
$household = new Household();
|
||||||
$position = (new Position())
|
$position = (new Position())
|
||||||
@ -44,7 +52,8 @@ final class HouseholdNormalizerTest extends KernelTestCase
|
|||||||
|
|
||||||
$member->setPerson($person)
|
$member->setPerson($person)
|
||||||
->setStartDate(new DateTimeImmutable('1 year ago'))
|
->setStartDate(new DateTimeImmutable('1 year ago'))
|
||||||
->setEndDate(new DateTimeImmutable('1 month ago'));
|
->setEndDate(new DateTimeImmutable('1 month ago'))
|
||||||
|
->setPosition($position);
|
||||||
|
|
||||||
$household->addMember($member);
|
$household->addMember($member);
|
||||||
|
|
||||||
|
@ -61,8 +61,8 @@ class AccompanyingPeriodWorkEvaluationDocumentWorkflowHandler implements EntityW
|
|||||||
return $this->translator->trans(
|
return $this->translator->trans(
|
||||||
'workflow.Doc for evaluation (n°%eval%)',
|
'workflow.Doc for evaluation (n°%eval%)',
|
||||||
['%eval%' => $entityWorkflow->getRelatedEntityId()]
|
['%eval%' => $entityWorkflow->getRelatedEntityId()]
|
||||||
) . ' - ' . $this->translatableStringHelper->localize($doc->getAccompanyingPeriodWorkEvaluation()
|
) . ' (' . $this->translatableStringHelper->localize($doc->getAccompanyingPeriodWorkEvaluation()
|
||||||
->getEvaluation()->getTitle());
|
->getEvaluation()->getTitle()) . ') ' . $doc->getTitle();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getRelatedEntity(EntityWorkflow $entityWorkflow): ?AccompanyingPeriodWorkEvaluationDocument
|
public function getRelatedEntity(EntityWorkflow $entityWorkflow): ?AccompanyingPeriodWorkEvaluationDocument
|
||||||
|
@ -95,11 +95,6 @@ chill_person_address_update:
|
|||||||
chill_person_timeline:
|
chill_person_timeline:
|
||||||
path: /{_locale}/person/{person_id}/timeline
|
path: /{_locale}/person/{person_id}/timeline
|
||||||
controller: Chill\PersonBundle\Controller\TimelinePersonController::personAction
|
controller: Chill\PersonBundle\Controller\TimelinePersonController::personAction
|
||||||
options:
|
|
||||||
menus:
|
|
||||||
person:
|
|
||||||
order: 60
|
|
||||||
label: Timeline
|
|
||||||
|
|
||||||
chill_person_admin:
|
chill_person_admin:
|
||||||
path: "/{_locale}/admin/person"
|
path: "/{_locale}/admin/person"
|
||||||
|
@ -41,6 +41,11 @@ services:
|
|||||||
autowire: true
|
autowire: true
|
||||||
tags: ['controller.service_arguments']
|
tags: ['controller.service_arguments']
|
||||||
|
|
||||||
|
Chill\PersonBundle\Controller\ReassignAccompanyingPeriodController:
|
||||||
|
autoconfigure: true
|
||||||
|
autowire: true
|
||||||
|
tags: ['controller.service_arguments']
|
||||||
|
|
||||||
Chill\PersonBundle\Controller\PersonApiController:
|
Chill\PersonBundle\Controller\PersonApiController:
|
||||||
arguments:
|
arguments:
|
||||||
$authorizationHelper: '@Chill\MainBundle\Security\Authorization\AuthorizationHelper'
|
$authorizationHelper: '@Chill\MainBundle\Security\Authorization\AuthorizationHelper'
|
||||||
|
@ -12,3 +12,13 @@ services:
|
|||||||
event: 'prePersist'
|
event: 'prePersist'
|
||||||
entity: 'Chill\PersonBundle\Entity\PersonAltName'
|
entity: 'Chill\PersonBundle\Entity\PersonAltName'
|
||||||
method: 'prePersistAltName'
|
method: 'prePersistAltName'
|
||||||
|
|
||||||
|
Chill\PersonBundle\EventListener\AccompanyingPeriodWorkEventListener:
|
||||||
|
autoconfigure: true
|
||||||
|
autowire: true
|
||||||
|
tags:
|
||||||
|
-
|
||||||
|
name: 'doctrine.orm.entity_listener'
|
||||||
|
event: 'prePersist'
|
||||||
|
entity: 'Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork'
|
||||||
|
method: 'prePersistAccompanyingPeriodWork'
|
@ -0,0 +1,42 @@
|
|||||||
|
<?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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add referrers to AccompanyingPeriodWork.
|
||||||
|
*/
|
||||||
|
final class Version20220310063629 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql('DROP TABLE chill_person_accompanying_period_work_referrer');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return 'Add referrers to AccompanyingPeriodWork';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql('CREATE TABLE chill_person_accompanying_period_work_referrer (accompanyingperiodwork_id INT NOT NULL, user_id INT NOT NULL, PRIMARY KEY(accompanyingperiodwork_id, user_id))');
|
||||||
|
$this->addSql('CREATE INDEX IDX_3619F5EBB99F6060 ON chill_person_accompanying_period_work_referrer (accompanyingperiodwork_id)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_3619F5EBA76ED395 ON chill_person_accompanying_period_work_referrer (user_id)');
|
||||||
|
$this->addSql('ALTER TABLE chill_person_accompanying_period_work_referrer ADD CONSTRAINT FK_3619F5EBB99F6060 FOREIGN KEY (accompanyingperiodwork_id) REFERENCES chill_person_accompanying_period_work (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||||
|
$this->addSql('ALTER TABLE chill_person_accompanying_period_work_referrer ADD CONSTRAINT FK_3619F5EBA76ED395 FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||||
|
$this->addSql('INSERT INTO chill_person_accompanying_period_work_referrer (accompanyingperiodwork_id, user_id)
|
||||||
|
SELECT id, createdby_id FROM chill_person_accompanying_period_work');
|
||||||
|
}
|
||||||
|
}
|
@ -194,6 +194,7 @@ No accompanying user: Aucun accompagnant
|
|||||||
No data given: Pas d'information
|
No data given: Pas d'information
|
||||||
Participants: Personnes impliquées
|
Participants: Personnes impliquées
|
||||||
Create an accompanying course: Créer un parcours
|
Create an accompanying course: Créer un parcours
|
||||||
|
Accompanying courses of users: Parcours des utilisateurs
|
||||||
This accompanying course is still a draft: Ce parcours est encore à l'état brouillon.
|
This accompanying course is still a draft: Ce parcours est encore à l'état brouillon.
|
||||||
Associated peoples: Usagers concernés
|
Associated peoples: Usagers concernés
|
||||||
Resources: Interlocuteurs privilégiés
|
Resources: Interlocuteurs privilégiés
|
||||||
@ -213,6 +214,7 @@ No requestor: Pas de demandeur
|
|||||||
No resources: "Pas d'interlocuteurs privilégiés"
|
No resources: "Pas d'interlocuteurs privilégiés"
|
||||||
Persons associated: Usagers concernés
|
Persons associated: Usagers concernés
|
||||||
Referrer: Référent
|
Referrer: Référent
|
||||||
|
Referrers: Référents
|
||||||
Some peoples does not belong to any household currently. Add them to an household soon: Certaines personnes n'appartiennent à aucun ménage actuellement. Renseignez leur ménage dès que possible.
|
Some peoples does not belong to any household currently. Add them to an household soon: Certaines personnes n'appartiennent à aucun ménage actuellement. Renseignez leur ménage dès que possible.
|
||||||
Add to household now: Ajouter à un ménage
|
Add to household now: Ajouter à un ménage
|
||||||
Any resource for this accompanying course: Aucun interlocuteur privilégié pour ce parcours
|
Any resource for this accompanying course: Aucun interlocuteur privilégié pour ce parcours
|
||||||
@ -494,6 +496,7 @@ Remove household composition: Supprimer composition familiale
|
|||||||
Are you sure you want to remove this composition?: Etes-vous sûr de vouloir supprimer cette composition familiale ?
|
Are you sure you want to remove this composition?: Etes-vous sûr de vouloir supprimer cette composition familiale ?
|
||||||
Concerns household n°%id%: Concerne le ménage n°%id%
|
Concerns household n°%id%: Concerne le ménage n°%id%
|
||||||
Composition: Composition
|
Composition: Composition
|
||||||
|
The composition has been successfully removed.: La composition a été supprimée.
|
||||||
|
|
||||||
# accompanying course work
|
# accompanying course work
|
||||||
Accompanying Course Actions: Actions d'accompagnements
|
Accompanying Course Actions: Actions d'accompagnements
|
||||||
@ -577,3 +580,8 @@ My accompanying periods in draft: Mes parcours brouillons
|
|||||||
|
|
||||||
workflow:
|
workflow:
|
||||||
Doc for evaluation (n°%eval%): Document de l'évaluation n°%eval%
|
Doc for evaluation (n°%eval%): Document de l'évaluation n°%eval%
|
||||||
|
|
||||||
|
period_by_user_list:
|
||||||
|
Period by user: Parcours d'accompagnement par utilisateur
|
||||||
|
Pick a user: Choisissez un utilisateur pour obtenir la liste de ses parcours
|
||||||
|
Any course or no authorization to see them: Aucun parcours pour ce référent, ou aucun droit pour visualiser les parcours de ce référent.
|
||||||
|
@ -46,6 +46,7 @@ class ChillThirdPartyExtension extends Extension implements PrependExtensionInte
|
|||||||
$loader->load('services/fixtures.yaml');
|
$loader->load('services/fixtures.yaml');
|
||||||
$loader->load('services/serializer.yaml');
|
$loader->load('services/serializer.yaml');
|
||||||
$loader->load('services/repository.yaml');
|
$loader->load('services/repository.yaml');
|
||||||
|
$loader->load('services/doctrineEventListener.yaml');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function prepend(ContainerBuilder $container)
|
public function prepend(ContainerBuilder $container)
|
||||||
|
@ -197,6 +197,12 @@ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface
|
|||||||
*/
|
*/
|
||||||
private ?string $email = null;
|
private ?string $email = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(name="firstname", type="string", length=255, nullable=true)
|
||||||
|
* @Groups({"read", "write", "docgen:read", "docgen:read:3party:parent"})
|
||||||
|
*/
|
||||||
|
private ?string $firstname = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int
|
* @var int
|
||||||
* @ORM\Column(name="id", type="integer")
|
* @ORM\Column(name="id", type="integer")
|
||||||
@ -454,12 +460,12 @@ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface
|
|||||||
return $this->email;
|
return $this->email;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getFirstname(): ?string
|
||||||
* Get id.
|
{
|
||||||
*
|
return $this->firstname;
|
||||||
* @return int
|
}
|
||||||
*/
|
|
||||||
public function getId()
|
public function getId(): ?int
|
||||||
{
|
{
|
||||||
return $this->id;
|
return $this->id;
|
||||||
}
|
}
|
||||||
@ -469,12 +475,7 @@ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface
|
|||||||
return $this->kind;
|
return $this->kind;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getName(): string
|
||||||
* Get name.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getName()
|
|
||||||
{
|
{
|
||||||
return $this->name;
|
return $this->name;
|
||||||
}
|
}
|
||||||
@ -766,6 +767,13 @@ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setFirstname($firstname): self
|
||||||
|
{
|
||||||
|
$this->firstname = $firstname;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function setKind(?string $kind): ThirdParty
|
public function setKind(?string $kind): ThirdParty
|
||||||
{
|
{
|
||||||
$this->kind = $kind;
|
$this->kind = $kind;
|
||||||
@ -773,14 +781,7 @@ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function setName($name): self
|
||||||
* Set name.
|
|
||||||
*
|
|
||||||
* @param string $name
|
|
||||||
*
|
|
||||||
* @return ThirdParty
|
|
||||||
*/
|
|
||||||
public function setName($name)
|
|
||||||
{
|
{
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
|
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Chill\ThirdPartyBundle\EventListener;
|
||||||
|
|
||||||
|
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||||
|
|
||||||
|
use const MB_CASE_TITLE;
|
||||||
|
|
||||||
|
class ThirdPartyEventListener
|
||||||
|
{
|
||||||
|
public function prePersistThirdParty(ThirdParty $thirdparty): void
|
||||||
|
{
|
||||||
|
if ($thirdparty->getKind() !== 'company') {
|
||||||
|
$firstnameCaps = mb_convert_case(mb_strtolower($thirdparty->getFirstname()), MB_CASE_TITLE, 'UTF-8');
|
||||||
|
$firstnameCaps = ucwords(strtolower($firstnameCaps), " \t\r\n\f\v'-");
|
||||||
|
$thirdparty->setFirstName($firstnameCaps);
|
||||||
|
|
||||||
|
$lastnameCaps = mb_strtoupper($thirdparty->getName(), 'UTF-8');
|
||||||
|
$thirdparty->setName($lastnameCaps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -102,6 +102,10 @@ class ThirdPartyType extends AbstractType
|
|||||||
// Contact Person ThirdParty (child)
|
// Contact Person ThirdParty (child)
|
||||||
if (ThirdParty::KIND_CONTACT === $options['kind'] || ThirdParty::KIND_CHILD === $options['kind']) {
|
if (ThirdParty::KIND_CONTACT === $options['kind'] || ThirdParty::KIND_CHILD === $options['kind']) {
|
||||||
$builder
|
$builder
|
||||||
|
->add('firstname', TextType::class, [
|
||||||
|
'label' => 'firstname',
|
||||||
|
'required' => false,
|
||||||
|
])
|
||||||
->add('civility', PickCivilityType::class, [
|
->add('civility', PickCivilityType::class, [
|
||||||
'label' => 'thirdparty.Civility',
|
'label' => 'thirdparty.Civility',
|
||||||
'placeholder' => 'thirdparty.choose civility',
|
'placeholder' => 'thirdparty.choose civility',
|
||||||
@ -149,7 +153,7 @@ class ThirdPartyType extends AbstractType
|
|||||||
'by_reference' => false,
|
'by_reference' => false,
|
||||||
'button_add_label' => 'Add a contact',
|
'button_add_label' => 'Add a contact',
|
||||||
'button_remove_label' => 'Remove a contact',
|
'button_remove_label' => 'Remove a contact',
|
||||||
'empty_collection_explain' => 'Any contact',
|
'empty_collection_explain' => 'No contacts associated',
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,15 +65,15 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="thirdparty.kind === 'child' || thirdparty.kind === 'contact'">
|
<div v-if="thirdparty.kind === 'child' || thirdparty.kind === 'contact'">
|
||||||
<div id="child-info">
|
<div class="child-info">
|
||||||
<div class="input-group mb-3">
|
<div class="input-group mb-3 input-section">
|
||||||
<select class="form-select form-select-lg" id="civility"
|
<select class="form-select form-select-lg" id="civility"
|
||||||
v-model="thirdparty.civility">
|
v-model="thirdparty.civility">
|
||||||
<option selected disabled :value="null" >{{ $t('thirdparty.civility') }}</option>
|
<option selected disabled :value="null" >{{ $t('thirdparty.civility') }}</option>
|
||||||
<option v-for="civility in civilities" :key="civility.id" :value="civility">{{ civility.name.fr }}</option>
|
<option v-for="civility in civilities" :key="civility.id" :value="civility">{{ civility.name.fr }}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="input-group mb-3">
|
<div class="input-group mb-3 input-section">
|
||||||
<select class="form-select form-select-lg" id="profession"
|
<select class="form-select form-select-lg" id="profession"
|
||||||
v-model="thirdparty.profession">
|
v-model="thirdparty.profession">
|
||||||
<option selected disabled :value="null">{{ $t('thirdparty.profession') }}</option>
|
<option selected disabled :value="null">{{ $t('thirdparty.profession') }}</option>
|
||||||
@ -81,18 +81,48 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="child-info">
|
||||||
|
<div class="input-section">
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input class="form-control form-control-lg" id="firstname" v-model="thirdparty.firstname" v-bind:placeholder="$t('thirdparty.firstname')" />
|
||||||
|
<label for="firstname">{{ $t('thirdparty.firstname') }}</label>
|
||||||
|
</div>
|
||||||
|
<div v-if="queryItems">
|
||||||
|
<ul class="list-suggest add-items inline">
|
||||||
|
<li v-for="(qi, i) in queryItems" :key="i" @click="addQueryItem('firstName', qi)">
|
||||||
|
<span class="person-text">{{ qi }}</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-section">
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input class="form-control form-control-lg" id="name" v-model="thirdparty.name" v-bind:placeholder="$t('thirdparty.lastname')" />
|
||||||
|
<label for="name">{{ $t('thirdparty.lastname') }}</label>
|
||||||
|
</div>
|
||||||
|
<div v-if="queryItems">
|
||||||
|
<ul class="list-suggest add-items inline">
|
||||||
|
<li v-for="(qi, i) in queryItems" :key="i" @click="addQueryItem('name', qi)">
|
||||||
|
<span class="person-text">{{ qi }}</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-floating mb-3">
|
<div v-if="thirdparty.kind === 'company'">
|
||||||
<input class="form-control form-control-lg" id="name" v-model="thirdparty.name" v-bind:placeholder="$t('thirdparty.name')" />
|
<div class="form-floating mb-3">
|
||||||
<label for="name">{{ $t('thirdparty.name') }}</label>
|
<input class="form-control form-control-lg" id="name" v-model="thirdparty.name" v-bind:placeholder="$t('thirdparty.name')" />
|
||||||
</div>
|
<label for="name">{{ $t('thirdparty.name') }}</label>
|
||||||
<div v-if="query">
|
</div>
|
||||||
<ul class="list-suggest add-items inline">
|
<div v-if="query">
|
||||||
<li @click="addQuery(query)">
|
<ul class="list-suggest add-items inline">
|
||||||
<span class="person-text">{{ query }}</span>
|
<li @click="addQuery(query)">
|
||||||
</li>
|
<span class="person-text">{{ query }}</span>
|
||||||
</ul>
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template
|
<template
|
||||||
@ -158,6 +188,7 @@ export default {
|
|||||||
type: 'thirdparty',
|
type: 'thirdparty',
|
||||||
address: null,
|
address: null,
|
||||||
kind: 'company',
|
kind: 'company',
|
||||||
|
firstname: '',
|
||||||
name: '',
|
name: '',
|
||||||
telephone: '',
|
telephone: '',
|
||||||
civility: null,
|
civility: null,
|
||||||
@ -212,6 +243,9 @@ export default {
|
|||||||
//this.context = context; <--
|
//this.context = context; <--
|
||||||
return context;
|
return context;
|
||||||
},
|
},
|
||||||
|
queryItems() {
|
||||||
|
return this.query ? this.query.split(' ') : null;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
loadData(){
|
loadData(){
|
||||||
@ -260,14 +294,24 @@ export default {
|
|||||||
console.log('switch address to edit mode', this.context);
|
console.log('switch address to edit mode', this.context);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
addQueryItem(field, queryItem) {
|
||||||
|
switch (field) {
|
||||||
|
case 'name':
|
||||||
|
this.thirdparty.name = queryItem;
|
||||||
|
break;
|
||||||
|
case 'firstName':
|
||||||
|
this.thirdparty.firstname = queryItem;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
addQuery(query) {
|
addQuery(query) {
|
||||||
this.thirdparty.name = query;
|
this.thirdparty.name = query;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
let dependencies = [];
|
let dependencies = [];
|
||||||
dependencies.push(this.loadProfessions());
|
dependencies.push(this.loadProfessions());
|
||||||
dependencies.push(this.loadCivilities());
|
dependencies.push(this.loadCivilities());
|
||||||
if (this.action !== 'create') {
|
if (this.action !== 'create') {
|
||||||
if (this.id) {
|
if (this.id) {
|
||||||
dependencies.push(this.loadData());
|
dependencies.push(this.loadData());
|
||||||
@ -305,12 +349,13 @@ dl {
|
|||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
#child-info {
|
.child-info {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
div {
|
.input-section {
|
||||||
width: 49%;
|
width: 49%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
const thirdpartyMessages = {
|
const thirdpartyMessages = {
|
||||||
fr: {
|
fr: {
|
||||||
thirdparty: {
|
thirdparty: {
|
||||||
|
firstname: "Prénom",
|
||||||
|
lastname: "Nom",
|
||||||
name: "Dénomination",
|
name: "Dénomination",
|
||||||
email: "Courriel",
|
email: "Courriel",
|
||||||
phonenumber: "Téléphone",
|
phonenumber: "Téléphone",
|
||||||
|
@ -3,6 +3,10 @@
|
|||||||
{{ form_row(form.civility) }}
|
{{ form_row(form.civility) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% if form.firstname is defined %}
|
||||||
|
{{ form_row(form.firstname) }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{{ form_row(form.name) }}
|
{{ form_row(form.name) }}
|
||||||
|
|
||||||
{% if form.nameCompany is defined %}
|
{% if form.nameCompany is defined %}
|
||||||
|
@ -7,6 +7,11 @@
|
|||||||
{{ form_errors(form.civility) }}
|
{{ form_errors(form.civility) }}
|
||||||
{{ form_label(form.civility) }}
|
{{ form_label(form.civility) }}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group col-md-5 mb-3">
|
||||||
|
{{ form_widget(form.firstname) }}
|
||||||
|
{{ form_errors(form.firstname) }}
|
||||||
|
{{ form_label(form.firstname) }}
|
||||||
|
</div>
|
||||||
<div class="form-group col-md-5 mb-3">
|
<div class="form-group col-md-5 mb-3">
|
||||||
{{ form_widget(form.name) }}
|
{{ form_widget(form.name) }}
|
||||||
{{ form_errors(form.name) }}
|
{{ form_errors(form.name) }}
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
{% extends "@ChillMain/layout.html.twig" %}
|
{% extends "@ChillMain/layout.html.twig" %}
|
||||||
|
|
||||||
{% set thirdParty = entity %}
|
{% set thirdParty = entity %}
|
||||||
{% set title_ = 'Show third party %name%'|trans({'%name%' : thirdParty.name }) %}
|
{% set name = thirdParty.firstname is not empty ? thirdParty.firstname ~ ' ' ~ thirdParty.name : thirdParty.name %}
|
||||||
|
{% set title_ = 'Show third party %name%'|trans({'%name%' : name }) %}
|
||||||
|
|
||||||
{% block title title_ %}
|
{% block title title_ %}
|
||||||
|
|
||||||
@ -25,7 +26,7 @@
|
|||||||
<dt>{{ 'Name'|trans }}</dt>
|
<dt>{{ 'Name'|trans }}</dt>
|
||||||
<dd>
|
<dd>
|
||||||
{% if thirdParty.isLeaf == true %}{{ thirdParty.civility }}{% endif %}
|
{% if thirdParty.isLeaf == true %}{{ thirdParty.civility }}{% endif %}
|
||||||
{{ thirdParty.name }}
|
{{ thirdParty.firstname ~ ' ' ~ thirdParty.name }}
|
||||||
</dd>
|
</dd>
|
||||||
|
|
||||||
{% if thirdParty.kind == 'company' %}
|
{% if thirdParty.kind == 'company' %}
|
||||||
@ -60,7 +61,7 @@
|
|||||||
{% if types|length > 0 %}
|
{% if types|length > 0 %}
|
||||||
{{ types|join(', ') }}
|
{{ types|join(', ') }}
|
||||||
{% else %}
|
{% else %}
|
||||||
<p class="chill-no-data-statement">{{ 'thirdParty.Any categories' }}</p>
|
<p class="chill-no-data-statement">{{ 'thirdparty.no_categories'|trans }}</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</dd>
|
</dd>
|
||||||
|
|
||||||
@ -110,7 +111,7 @@
|
|||||||
<dt>{{ 'Contacts'|trans }}</dt>
|
<dt>{{ 'Contacts'|trans }}</dt>
|
||||||
<dd>
|
<dd>
|
||||||
{% if thirdParty.activeChildren|length == 0 %}
|
{% if thirdParty.activeChildren|length == 0 %}
|
||||||
<p class="chill-no-data-statement">{{ 'Any contacts associated'|trans }}</p>
|
<p class="chill-no-data-statement">{{ 'No contacts associated'|trans }}</p>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="flex-table">
|
<div class="flex-table">
|
||||||
{% for tp in thirdParty.activeChildren %}
|
{% for tp in thirdParty.activeChildren %}
|
||||||
|
@ -43,6 +43,7 @@ class ThirdPartyNormalizer implements NormalizerAwareInterface, NormalizerInterf
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'type' => 'thirdparty',
|
'type' => 'thirdparty',
|
||||||
|
'firstname' => $thirdParty->getFirstname(),
|
||||||
'name' => $thirdParty->getName(),
|
'name' => $thirdParty->getName(),
|
||||||
'text' => $this->thirdPartyRender->renderString($thirdParty, []),
|
'text' => $this->thirdPartyRender->renderString($thirdParty, []),
|
||||||
'id' => $thirdParty->getId(),
|
'id' => $thirdParty->getId(),
|
||||||
|
@ -77,7 +77,9 @@ class ThirdPartyRender extends AbstractChillEntityRender
|
|||||||
$acronym = '';
|
$acronym = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
return $civility . $entity->getName() . $acronym;
|
$firstname = empty($entity->getFirstname()) ? '' : $entity->getFirstname();
|
||||||
|
|
||||||
|
return $civility . $firstname . ' ' . $entity->getName() . $acronym;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function supports($entity, array $options): bool
|
public function supports($entity, array $options): bool
|
||||||
|
@ -20,6 +20,8 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
enum:
|
enum:
|
||||||
- "thirdparty"
|
- "thirdparty"
|
||||||
|
firstname:
|
||||||
|
type: string
|
||||||
name:
|
name:
|
||||||
type: string
|
type: string
|
||||||
email:
|
email:
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
services:
|
||||||
|
Chill\ThirdPartyBundle\EventListener\ThirdPartyEventListener:
|
||||||
|
autoconfigure: true
|
||||||
|
tags:
|
||||||
|
-
|
||||||
|
name: 'doctrine.orm.entity_listener'
|
||||||
|
event: 'prePersist'
|
||||||
|
entity: 'Chill\ThirdPartyBundle\Entity\ThirdParty'
|
||||||
|
method: 'prePersistThirdParty'
|
@ -39,15 +39,17 @@ final class Version20211007165001 extends AbstractMigration
|
|||||||
$this->addSql("
|
$this->addSql("
|
||||||
UPDATE chill_3party.third_party
|
UPDATE chill_3party.third_party
|
||||||
SET canonicalized =
|
SET canonicalized =
|
||||||
UNACCENT(
|
UNACCENT(
|
||||||
LOWER(
|
LOWER(
|
||||||
name ||
|
name ||
|
||||||
CASE WHEN COALESCE(name_company, '') <> '' THEN ' ' ELSE '' END ||
|
CASE WHEN COALESCE (firstname, '') <> '' THEN ' ' ELSE '' END ||
|
||||||
COALESCE(name_company, '') ||
|
COALESCE(firstname, '') ||
|
||||||
CASE WHEN COALESCE(acronym, '') <> '' THEN ' ' ELSE '' END ||
|
CASE WHEN COALESCE(name_company, '') <> '' THEN ' ' ELSE '' END ||
|
||||||
COALESCE(acronym, '')
|
COALESCE(name_company, '') ||
|
||||||
)
|
CASE WHEN COALESCE(acronym, '') <> '' THEN ' ' ELSE '' END ||
|
||||||
)
|
COALESCE(acronym, '')
|
||||||
|
)
|
||||||
|
)
|
||||||
");
|
");
|
||||||
$this->addSql("
|
$this->addSql("
|
||||||
CREATE OR REPLACE FUNCTION chill_3party.canonicalize() RETURNS TRIGGER
|
CREATE OR REPLACE FUNCTION chill_3party.canonicalize() RETURNS TRIGGER
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Chill\Migrations\ThirdParty;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-generated Migration: Please modify to your needs!
|
||||||
|
*/
|
||||||
|
final class Version20220322095659 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this down() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('ALTER TABLE chill_3party.third_party DROP firstname');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return 'Add firstname to thirdparty';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this up() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('ALTER TABLE chill_3party.third_party ADD firstname VARCHAR(255) DEFAULT NULL');
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
Third party: Tiers
|
Third party: Tiers
|
||||||
Third parties: Tiers
|
Third parties: Tiers
|
||||||
third parties: tiers
|
third parties: tiers
|
||||||
|
firstname: Prénom
|
||||||
name: Nom
|
name: Nom
|
||||||
telephone: Téléphone
|
telephone: Téléphone
|
||||||
adress: Adresse
|
adress: Adresse
|
||||||
@ -15,6 +16,7 @@ thirdparty.No_comment: Aucun commentaire
|
|||||||
thirdparty.NameCompany: Service/Département
|
thirdparty.NameCompany: Service/Département
|
||||||
thirdparty.Acronym: Sigle
|
thirdparty.Acronym: Sigle
|
||||||
thirdparty.Categories: Catégories
|
thirdparty.Categories: Catégories
|
||||||
|
thirdparty.no_categories: Aucune catégorie
|
||||||
thirdparty.Child: Personne de contact
|
thirdparty.Child: Personne de contact
|
||||||
thirdparty.child: Personne de contact
|
thirdparty.child: Personne de contact
|
||||||
thirdparty.Children: Personnes de contact
|
thirdparty.Children: Personnes de contact
|
||||||
@ -63,13 +65,12 @@ Show thirdparty: Voir le tiers
|
|||||||
Add a contact: Ajouter un contact
|
Add a contact: Ajouter un contact
|
||||||
Remove a contact: Supprimer
|
Remove a contact: Supprimer
|
||||||
Contacts: Contacts
|
Contacts: Contacts
|
||||||
Any contact: Aucun contact
|
No contacts associated: Aucun contact
|
||||||
|
|
||||||
No nameCompany given: Aucune raison sociale renseignée
|
No nameCompany given: Aucune raison sociale renseignée
|
||||||
No acronym given: Aucun sigle renseigné
|
No acronym given: Aucun sigle renseigné
|
||||||
No phone given: Aucun téléphone renseigné
|
No phone given: Aucun téléphone renseigné
|
||||||
No email given: Aucune adresse courriel renseignée
|
No email given: Aucune adresse courriel renseignée
|
||||||
thirdparty.Any categories: Aucune catégorie
|
|
||||||
|
|
||||||
The party is visible in those centers: Le tiers est visible dans ces centres
|
The party is visible in those centers: Le tiers est visible dans ces centres
|
||||||
The party is not visible in any center: Le tiers n'est associé à aucun centre
|
The party is not visible in any center: Le tiers n'est associé à aucun centre
|
||||||
|
@ -14,7 +14,7 @@ window.addEventListener('DOMContentLoaded', function(e) {
|
|||||||
office_frame.setAttribute('allowfullscreen', 'true');
|
office_frame.setAttribute('allowfullscreen', 'true');
|
||||||
|
|
||||||
// The sandbox attribute is needed to allow automatic redirection to the O365 sign-in page in the business user flow
|
// The sandbox attribute is needed to allow automatic redirection to the O365 sign-in page in the business user flow
|
||||||
office_frame.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-forms allow-popups allow-top-navigation allow-popups-to-escape-sandbox');
|
office_frame.setAttribute('sandbox', 'allow-downloads allow-scripts allow-same-origin allow-forms allow-popups allow-top-navigation allow-popups-to-escape-sandbox');
|
||||||
frameholder.appendChild(office_frame);
|
frameholder.appendChild(office_frame);
|
||||||
|
|
||||||
document.getElementById('office_form').submit();
|
document.getElementById('office_form').submit();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user