mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Merge remote-tracking branch 'origin/master' into url_in_accompanyingPeriodWork_evaluations
This commit is contained in:
commit
739c7e9a77
@ -12,8 +12,8 @@ and this project adheres to
|
||||
|
||||
<!-- write down unreleased development here -->
|
||||
* [person] Add url in accompanying period work evaluations entity and form (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/476)
|
||||
|
||||
|
||||
* [person] Add document generation in admin and in person/{id}/document (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/464)
|
||||
* [activity] do not override location if already exist (when validating new activity) (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/470)
|
||||
* [parcours] Toggle emergency/intensity only by referrer (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/442)
|
||||
* [docstore] Add an API entrypoint for StoredObject (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/466)
|
||||
* [person] Add the possibility of uploading existing documents to AccPeriodWorkEvaluationDocument (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/466)
|
||||
@ -22,13 +22,14 @@ and this project adheres to
|
||||
* [Person/Household list] when listing other simultaneous members of an household, exclude the members on person, not on members (avoid to show two membersship with the same person)
|
||||
* [draft periods] add a delete button (if acl granted) on each draft period listed on draft period page (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/463)
|
||||
* [Person] Display suffixText in RenderPerson, PersonText.vue, RenderPersonBox.vue (was made for displaying "enfant confie") (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/441)
|
||||
* [person] residential address: show residential address or info in PersonRenderBox, refactor Residential Address (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/439)
|
||||
* [person] residential address: show residential address or info in PersonRenderBox, refactor Residential Address (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/439)
|
||||
* [thirdparty] Add a contact to a thirdparty from within onTheFly (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/345)
|
||||
* [documents] Improve flex-table item-col placement when long buttons and long metadata
|
||||
* [thirdparty] Fix display of multiple contact badges so they wrap onto next line (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/482)
|
||||
* [confidential] Fix position of toggle button so it does not cover text nor fall outside of box (no issue)
|
||||
* [parcours] Fix edit of both thirdparty and contact name (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/474)
|
||||
* [template] do not list inactive templates (for doc generator)
|
||||
* [person] email added to twig personRenderbox (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/490)
|
||||
|
||||
## Test releases
|
||||
|
||||
|
@ -110,10 +110,8 @@ export default function prepareLocations(store) {
|
||||
console.log('default loation id', window.default_location_id);
|
||||
if (window.default_location_id) {
|
||||
for (let group of store.state.availableLocations) {
|
||||
console.log(group);
|
||||
let location = group.locations.find((l) => l.id === window.default_location_id);
|
||||
console.log(location);
|
||||
if (location !== undefined) {
|
||||
if (location !== undefined & store.state.activity.location === null) {
|
||||
store.dispatch('updateLocation', location);
|
||||
break;
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ activity:
|
||||
Insert a document: Insérer un document
|
||||
Remove a document: Supprimer le document
|
||||
comment: Commentaire
|
||||
No documents: Pas de documents
|
||||
No documents: Aucun document
|
||||
|
||||
#timeline
|
||||
'%user% has done an %activity_type%': '%user% a effectué une activité de type "%activity_type%"'
|
||||
|
@ -207,21 +207,21 @@ final class DocGeneratorTemplateController extends AbstractController
|
||||
$context instanceof DocGeneratorContextWithPublicFormInterface
|
||||
&& $context->hasPublicForm($template, $entity) || $isTest
|
||||
) {
|
||||
if ($context instanceof DocGeneratorContextWithPublicFormInterface) {
|
||||
if ($context instanceof DocGeneratorContextWithPublicFormInterface && $context->hasPublicForm($template, $entity)) {
|
||||
$builder = $this->createFormBuilder(
|
||||
array_merge(
|
||||
$context->getFormData($template, $entity),
|
||||
$isTest ? ['test_file' => null] : []
|
||||
)
|
||||
);
|
||||
|
||||
$context->buildPublicForm($builder, $template, $entity);
|
||||
} else {
|
||||
$builder = $this->createFormBuilder(
|
||||
['test_file' => null]
|
||||
);
|
||||
}
|
||||
|
||||
$context->buildPublicForm($builder, $template, $entity);
|
||||
|
||||
if ($isTest) {
|
||||
$builder->add('test_file', FileType::class, [
|
||||
'label' => 'Template file',
|
||||
|
@ -21,6 +21,8 @@ use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use DateTime;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
@ -59,21 +61,37 @@ class DocumentAccompanyingCourseController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/{id}", name="accompanying_course_document_delete", methods="DELETE")
|
||||
* @Route("/{id}/delete", name="chill_docstore_accompanying_course_document_delete")
|
||||
*/
|
||||
public function delete(Request $request, AccompanyingPeriod $course, AccompanyingCourseDocument $document): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted(AccompanyingCourseDocumentVoter::DELETE, $document);
|
||||
|
||||
if ($this->isCsrfTokenValid('delete' . $document->getId(), $request->request->get('_token'))) {
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
$em->remove($document);
|
||||
$em->flush();
|
||||
$form = $this->createForm(FormType::class);
|
||||
$form->add('submit', SubmitType::class, ['label' => 'Delete']);
|
||||
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$this->getDoctrine()->getManager()->remove($document);
|
||||
$this->getDoctrine()->getManager()->flush();
|
||||
|
||||
$this->addFlash('success', $this->translator->trans('The document is successfully removed'));
|
||||
|
||||
if ($request->query->has('returnPath')) {
|
||||
return $this->redirect($request->query->get('returnPath'));
|
||||
}
|
||||
|
||||
return $this->redirectToRoute('accompanying_course_document_index', ['course' => $course->getId()]);
|
||||
}
|
||||
|
||||
return $this->redirectToRoute(
|
||||
'accompanying_course_document_index',
|
||||
['accompanyingCourse' => $course->getId()]
|
||||
return $this->render(
|
||||
'ChillDocStoreBundle:AccompanyingCourseDocument:delete.html.twig',
|
||||
[
|
||||
'document' => $document,
|
||||
'delete_form' => $form->createView(),
|
||||
'accompanyingCourse' => $course,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@ namespace Chill\DocStoreBundle\Controller;
|
||||
use Chill\DocStoreBundle\Entity\PersonDocument;
|
||||
use Chill\DocStoreBundle\Form\PersonDocumentType;
|
||||
use Chill\DocStoreBundle\Repository\PersonDocumentACLAwareRepositoryInterface;
|
||||
use Chill\DocStoreBundle\Security\Authorization\PersonDocumentVoter;
|
||||
use Chill\MainBundle\Pagination\PaginatorFactory;
|
||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
@ -22,6 +23,8 @@ use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||
use DateTime;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
@ -64,22 +67,37 @@ class DocumentPersonController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/{id}", name="person_document_delete", methods="DELETE")
|
||||
* @Route("/{id}/delete", name="chill_docstore_person_document_delete")
|
||||
*/
|
||||
public function delete(Request $request, Person $person, PersonDocument $document): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted('CHILL_PERSON_SEE', $person);
|
||||
$this->denyAccessUnlessGranted('CHILL_PERSON_DOCUMENT_DELETE', $document);
|
||||
$this->denyAccessUnlessGranted(PersonDocumentVoter::DELETE, $document);
|
||||
|
||||
if ($this->isCsrfTokenValid('delete' . $document->getId(), $request->request->get('_token'))) {
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
$em->remove($document);
|
||||
$em->flush();
|
||||
$form = $this->createForm(FormType::class);
|
||||
$form->add('submit', SubmitType::class, ['label' => 'Delete']);
|
||||
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$this->getDoctrine()->getManager()->remove($document);
|
||||
$this->getDoctrine()->getManager()->flush();
|
||||
|
||||
$this->addFlash('success', $this->translator->trans('The document is successfully removed'));
|
||||
|
||||
if ($request->query->has('returnPath')) {
|
||||
return $this->redirect($request->query->get('returnPath'));
|
||||
}
|
||||
|
||||
return $this->redirectToRoute('person_document_index', ['person' => $person->getId()]);
|
||||
}
|
||||
|
||||
return $this->redirectToRoute(
|
||||
'person_document_index',
|
||||
['person' => $person->getId()]
|
||||
return $this->render(
|
||||
'ChillDocStoreBundle:PersonDocument:delete.html.twig',
|
||||
[
|
||||
'document' => $document,
|
||||
'delete_form' => $form->createView(),
|
||||
'person' => $person,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
@ -98,7 +116,6 @@ class DocumentPersonController extends AbstractController
|
||||
PersonDocumentType::class,
|
||||
$document,
|
||||
[
|
||||
'center' => $document->getCenter(),
|
||||
'role' => 'CHILL_PERSON_DOCUMENT_UPDATE',
|
||||
]
|
||||
);
|
||||
@ -199,7 +216,6 @@ class DocumentPersonController extends AbstractController
|
||||
$document->setDate(new DateTime('Now'));
|
||||
|
||||
$form = $this->createForm(PersonDocumentType::class, $document, [
|
||||
'center' => $document->getCenter(),
|
||||
'role' => 'CHILL_PERSON_DOCUMENT_CREATE',
|
||||
]);
|
||||
$form->handleRequest($request);
|
||||
|
@ -13,15 +13,13 @@ namespace Chill\DocStoreBundle\Form;
|
||||
|
||||
use Chill\DocStoreBundle\Entity\Document;
|
||||
use Chill\DocStoreBundle\Entity\PersonDocument;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Form\Type\ChillDateType;
|
||||
use Chill\MainBundle\Form\Type\ChillTextareaType;
|
||||
use Chill\MainBundle\Form\Type\ScopePickerType;
|
||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
||||
use Chill\MainBundle\Security\Resolver\CenterResolverDispatcher;
|
||||
use Chill\MainBundle\Security\Resolver\ScopeResolverDispatcher;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\Persistence\ObjectManager;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
@ -31,34 +29,16 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class PersonDocumentType extends AbstractType
|
||||
{
|
||||
/**
|
||||
* @var AuthorizationHelper
|
||||
*/
|
||||
protected $authorizationHelper;
|
||||
|
||||
/**
|
||||
* @var ObjectManager
|
||||
*/
|
||||
protected $om;
|
||||
|
||||
/**
|
||||
* @var TranslatableStringHelper
|
||||
*/
|
||||
protected $translatableStringHelper;
|
||||
|
||||
/**
|
||||
* the user running this form.
|
||||
*
|
||||
* @var User
|
||||
*/
|
||||
protected $user;
|
||||
private CenterResolverDispatcher $centerResolverDispatcher;
|
||||
|
||||
private ParameterBagInterface $parameterBag;
|
||||
|
||||
private ScopeResolverDispatcher $scopeResolverDispatcher;
|
||||
|
||||
private TranslatableStringHelperInterface $translatableStringHelper;
|
||||
|
||||
public function __construct(
|
||||
TranslatableStringHelper $translatableStringHelper,
|
||||
TranslatableStringHelperInterface $translatableStringHelper,
|
||||
ScopeResolverDispatcher $scopeResolverDispatcher,
|
||||
ParameterBagInterface $parameterBag
|
||||
) {
|
||||
@ -96,7 +76,7 @@ class PersonDocumentType extends AbstractType
|
||||
|
||||
if ($isScopeConcerned && $this->parameterBag->get('chill_main')['acl']['form_show_scopes']) {
|
||||
$builder->add('scope', ScopePickerType::class, [
|
||||
'center' => $options['center'],
|
||||
'center' => $this->centerResolverDispatcher->resolveCenter($document),
|
||||
'role' => $options['role'],
|
||||
]);
|
||||
}
|
||||
@ -108,8 +88,7 @@ class PersonDocumentType extends AbstractType
|
||||
'data_class' => Document::class,
|
||||
]);
|
||||
|
||||
$resolver->setRequired(['role', 'center'])
|
||||
->setAllowedTypes('role', ['string'])
|
||||
->setAllowedTypes('center', [\Chill\MainBundle\Entity\Center::class]);
|
||||
$resolver->setRequired(['role'])
|
||||
->setAllowedTypes('role', ['string']);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +0,0 @@
|
||||
<form method="post" action="{{ path('accompanying_course_document_delete', {'id': document.id, 'course': course.id}) }}" onsubmit="return confirm('Are you sure you want to delete this item?');">
|
||||
<input type="hidden" name="_method" value="DELETE">
|
||||
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ document.id) }}">
|
||||
<button class="btn btn-delete">{{ 'Delete' | trans }}</button>
|
||||
</form>
|
@ -0,0 +1,43 @@
|
||||
{% extends "@ChillPerson/AccompanyingCourse/layout.html.twig" %}
|
||||
|
||||
{% set activeRouteKey = '' %}
|
||||
|
||||
{% block title %}{{ 'Delete document ?' }}{% endblock %}
|
||||
|
||||
{% block docdescription %}
|
||||
<dl class="chill_view_data">
|
||||
<dt>{{ 'Title'|trans }}</dt>
|
||||
<dd>{{ document.title }}</dd>
|
||||
|
||||
{% if document.scope is not null %}
|
||||
<dt>{{ 'Scope' | trans }}</dt>
|
||||
<dd>{{ document.scope.name | localize_translatable_string }}</dd>
|
||||
{% endif %}
|
||||
|
||||
<dt>{{ 'Category'|trans }}</dt>
|
||||
<dd>{{ document.category.name|localize_translatable_string }}</dd>
|
||||
|
||||
<dt>{{ 'Description' | trans }}</dt>
|
||||
<dd>
|
||||
{% if document.description is empty %}
|
||||
<span class="chill-no-data-statement">{{ 'Any description'|trans }}</span>
|
||||
{% else %}
|
||||
<blockquote class="chill-user-quote">
|
||||
{{ document.description|chill_markdown_to_html }}
|
||||
</blockquote>
|
||||
{% endif %}
|
||||
</dd>
|
||||
</dl>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{{ include('@ChillMain/Util/confirmation_template.html.twig',
|
||||
{
|
||||
'title' : 'Delete document ?'|trans,
|
||||
'display_content' : block('docdescription'),
|
||||
'confirm_question' : 'Are you sure you want to remove this document ?'|trans,
|
||||
'cancel_route' : 'accompanying_course_document_index',
|
||||
'cancel_parameters' : {'course' : accompanyingCourse.id, 'id': document.id},
|
||||
'form' : delete_form
|
||||
} ) }}
|
||||
{% endblock %}
|
@ -25,8 +25,13 @@
|
||||
{{ 'Back to the list' | trans }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="edit">
|
||||
<button class="btn btn-edit">{{ 'Edit'|trans }}</button>
|
||||
{% if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_DELETE', document) %}
|
||||
<li class="delete">
|
||||
<a href="{{ chill_return_path_or('chill_docstore_accompanying_course_document_delete', {'course': accompanyingCourse.id, 'id': document.id}) }}" class="btn btn-delete"></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li class="edit">
|
||||
<button class="btn btn-edit">{{ 'Edit'|trans }}</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
@ -49,12 +49,9 @@
|
||||
{{ 'Back to the list' | trans }}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
{{ m.download_button(document.object, document.title) }}
|
||||
</li>
|
||||
{% if chill_document_is_editable(document.object) %}
|
||||
<li>
|
||||
{{ document.object|chill_document_edit_button }}
|
||||
{% if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_DELETE', document) %}
|
||||
<li class="delete">
|
||||
<a href="{{ chill_return_path_or('chill_docstore_accompanying_course_document_delete', {'course': accompanyingCourse.id, 'id': document.id}) }}" class="btn btn-delete"></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_UPDATE', document) %}
|
||||
@ -63,6 +60,14 @@
|
||||
class="btn btn-edit" title="{{ 'Edit attributes' | trans }}"></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li>
|
||||
{{ m.download_button(document.object, document.title) }}
|
||||
</li>
|
||||
{% if chill_document_is_editable(document.object) %}
|
||||
<li>
|
||||
{{ document.object|chill_document_edit_button }}
|
||||
</li>
|
||||
{% endif %}
|
||||
{% set workflows_frame = chill_entity_workflow_list('Chill\\DocStoreBundle\\Entity\\AccompanyingCourseDocument', document.id) %}
|
||||
{% if workflows_frame is not empty %}
|
||||
<li>
|
||||
|
@ -44,6 +44,16 @@
|
||||
</div>
|
||||
<ul class="item-col record_actions flex-shrink-1">
|
||||
{% if document.course is defined %}
|
||||
{% if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_DELETE', document) %}
|
||||
<li class="delete">
|
||||
<a href="{{ chill_return_path_or('chill_docstore_accompanying_course_document_delete', {'course': accompanyingCourse.id, 'id': document.id}) }}" class="btn btn-delete"></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_UPDATE', document) %}
|
||||
<li>
|
||||
<a href="{{ path('accompanying_course_document_edit', {'course': accompanyingCourse.id, 'id': document.id }) }}" class="btn btn-update"></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_SEE_DETAILS', document) %}
|
||||
<li>
|
||||
{{ m.download_button(document.object, document.title) }}
|
||||
@ -52,15 +62,20 @@
|
||||
<a href="{{ chill_path_add_return_path('accompanying_course_document_show', {'course': accompanyingCourse.id, 'id': document.id}) }}" class="btn btn-show"></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_UPDATE', document) %}
|
||||
<li>
|
||||
<a href="{{ path('accompanying_course_document_edit', {'course': accompanyingCourse.id, 'id': document.id }) }}" class="btn btn-update"></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li>
|
||||
{{ chill_entity_workflow_list('Chill\\DocStoreBundle\\Entity\\AccompanyingCourseDocument', document.id) }}
|
||||
</li>
|
||||
{% else %}
|
||||
{% if is_granted('CHILL_PERSON_DOCUMENT_DELETE', document) %}
|
||||
<li class="delete">
|
||||
<a href="{{ chill_return_path_or('chill_docstore_person_document_delete', {'person': person.id, 'id': document.id}) }}" class="btn btn-delete"></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if is_granted('CHILL_PERSON_DOCUMENT_UPDATE', document) %}
|
||||
<li>
|
||||
<a href="{{ path('person_document_edit', {'person': person.id, 'id': document.id}) }}" class="btn btn-update"></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if is_granted('CHILL_PERSON_DOCUMENT_SEE_DETAILS', document) %}
|
||||
<li>
|
||||
{{ m.download_button(document.object, document.title) }}
|
||||
@ -69,13 +84,8 @@
|
||||
<a href="{{ path('person_document_show', {'person': person.id, 'id': document.id}) }}" class="btn btn-show"></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if is_granted('CHILL_PERSON_DOCUMENT_UPDATE', document) %}
|
||||
<li>
|
||||
<a href="{{ path('person_document_edit', {'person': person.id, 'id': document.id}) }}" class="btn btn-update"></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
@ -0,0 +1,43 @@
|
||||
{% extends "@ChillPerson/Person/layout.html.twig" %}
|
||||
|
||||
{% set activeRouteKey = '' %}
|
||||
|
||||
{% block title %}{{ 'Delete document ?' }}{% endblock %}
|
||||
|
||||
{% block docdescription %}
|
||||
<dl class="chill_view_data">
|
||||
<dt>{{ 'Title'|trans }}</dt>
|
||||
<dd>{{ document.title }}</dd>
|
||||
|
||||
{% if document.scope is not null %}
|
||||
<dt>{{ 'Scope' | trans }}</dt>
|
||||
<dd>{{ document.scope.name | localize_translatable_string }}</dd>
|
||||
{% endif %}
|
||||
|
||||
<dt>{{ 'Category'|trans }}</dt>
|
||||
<dd>{{ document.category.name|localize_translatable_string }}</dd>
|
||||
|
||||
<dt>{{ 'Description' | trans }}</dt>
|
||||
<dd>
|
||||
{% if document.description is empty %}
|
||||
<span class="chill-no-data-statement">{{ 'Any description'|trans }}</span>
|
||||
{% else %}
|
||||
<blockquote class="chill-user-quote">
|
||||
{{ document.description|chill_markdown_to_html }}
|
||||
</blockquote>
|
||||
{% endif %}
|
||||
</dd>
|
||||
</dl>
|
||||
{% endblock %}
|
||||
|
||||
{% block personcontent %}
|
||||
{{ include('@ChillMain/Util/confirmation_template.html.twig',
|
||||
{
|
||||
'title' : 'Delete document ?'|trans,
|
||||
'display_content' : block('docdescription'),
|
||||
'confirm_question' : 'Are you sure you want to remove this document ?'|trans,
|
||||
'cancel_route' : 'person_document_index',
|
||||
'cancel_parameters' : {'person' : person.id, 'id': document.id},
|
||||
'form' : delete_form
|
||||
} ) }}
|
||||
{% endblock %}
|
@ -36,20 +36,20 @@
|
||||
{{ form_row(form.description) }}
|
||||
{{ form_row(form.object, { 'label': 'Document', 'existing': document.object }) }}
|
||||
|
||||
<ul class="record_actions">
|
||||
<ul class="record_actions sticky-form-buttons">
|
||||
<li class="cancel">
|
||||
<a href="{{ path('person_document_index', {'person': person.id}) }}" class="btn btn-cancel">
|
||||
<a href="{{ chill_return_path_or('person_document_index', {'person': person.id}) }}" class="btn btn-cancel">
|
||||
{{ 'Back to the list' | trans }}
|
||||
</a>
|
||||
</li>
|
||||
{% if is_granted('CHILL_PERSON_DOCUMENT_DELETE', document) %}
|
||||
<li class="delete">
|
||||
<a href="{{ chill_return_path_or('chill_docstore_person_document_delete', {'person': person.id, 'id': document.id}) }}" class="btn btn-delete"></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li class="edit">
|
||||
<button class="btn btn-edit">{{ 'Edit'|trans }}</button>
|
||||
</li>
|
||||
{# {% if is_granted('CHILL_PERSON_DOCUMENT_DELETE', document) %}
|
||||
<li class="delete">
|
||||
{{ include('ChillDocStoreBundle:PersonDocument:_delete_form.html.twig') }}
|
||||
</li>
|
||||
{% endif %} #}
|
||||
</ul>
|
||||
|
||||
{{ form_end(form) }}
|
||||
|
@ -26,7 +26,17 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block js %}
|
||||
{{ parent() }}
|
||||
{{ encore_entry_script_tags('mod_async_upload') }}
|
||||
{{ encore_entry_script_tags('mod_docgen_picktemplate') }}
|
||||
{{ encore_entry_script_tags('mod_entity_workflow_pick') }}
|
||||
{% endblock %}
|
||||
|
||||
{% block css %}
|
||||
{{ parent() }}
|
||||
{{ encore_entry_link_tags('mod_async_upload') }}
|
||||
{{ encore_entry_link_tags('mod_docgen_picktemplate') }}
|
||||
{{ encore_entry_link_tags('mod_entity_workflow_pick') }}
|
||||
{% endblock %}
|
||||
|
||||
{% block personcontent %}
|
||||
@ -46,6 +56,8 @@
|
||||
|
||||
{{ chill_pagination(pagination) }}
|
||||
|
||||
<div data-docgen-template-picker="data-docgen-template-picker" data-entity-class="Chill\PersonBundle\Entity\Person" data-entity-id="{{ person.id }}"></div>
|
||||
|
||||
{% if is_granted('CHILL_PERSON_DOCUMENT_CREATE', person) %}
|
||||
<ul class="record_actions sticky-form-buttons">
|
||||
<li class="create">
|
||||
|
@ -40,9 +40,9 @@
|
||||
{{ form_row(form.description) }}
|
||||
{{ form_row(form.object, { 'label': 'Document', 'existing': document.object }) }}
|
||||
|
||||
<ul class="record_actions">
|
||||
<ul class="record_actions sticky-form-buttons">
|
||||
<li class="cancel">
|
||||
<a href="{{ path('person_document_index', {'person': person.id}) }}" class="btn btn-cancel">
|
||||
<a href="{{ chill_return_path_or('person_document_index', {'person': person.id}) }}" class="btn btn-cancel">
|
||||
{{ 'Back to the list' | trans }}
|
||||
</a>
|
||||
</li>
|
||||
|
@ -64,13 +64,9 @@
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
{{ m.download_button(document.object, document.title) }}
|
||||
</li>
|
||||
|
||||
{% if chill_document_is_editable(document.object) %}
|
||||
<li>
|
||||
{{ document.object|chill_document_edit_button }}
|
||||
{% if is_granted('CHILL_PERSON_DOCUMENT_DELETE', document) %}
|
||||
<li class="delete">
|
||||
<a href="{{ chill_return_path_or('chill_docstore_person_document_delete', {'person': person.id, 'id': document.id}) }}" class="btn btn-delete"></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
@ -82,5 +78,15 @@
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
{# {{ include('ChillDocStoreBundle:PersonDocument:_delete_form.html.twig') }} #}
|
||||
<li>
|
||||
{{ m.download_button(document.object, document.title) }}
|
||||
</li>
|
||||
|
||||
{% if chill_document_is_editable(document.object) %}
|
||||
<li>
|
||||
{{ document.object|chill_document_edit_button }}
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
{# {{ include('ChillDocStoreBundle:PersonDocument:_delete_form.html.twig') }} #}
|
||||
{% endblock %}
|
||||
|
@ -19,6 +19,12 @@ The document is successfully registered: Le document est enregistré
|
||||
The document is successfully updated: Le document est mis à jour
|
||||
Any description: Aucune description
|
||||
|
||||
# delete
|
||||
Delete document ?: Supprimer le document ?
|
||||
Are you sure you want to remove this document ?: Êtes-vous sûr·e de vouloir supprimer ce document ?
|
||||
The document is successfully removed: Le document a été supprimé
|
||||
|
||||
|
||||
# dropzone upload
|
||||
File too big: Fichier trop volumineux
|
||||
Drop your file or click here: Cliquez ici ou faites glissez votre nouveau fichier dans cette zone
|
||||
|
@ -27,7 +27,7 @@ interface PhoneNumberHelperInterface
|
||||
/**
|
||||
* Get type (mobile, landline, ...) for phone number.
|
||||
*/
|
||||
public function getType(string $phonenumber): string;
|
||||
public function getType(PhoneNumber $phonenumber): string;
|
||||
|
||||
/**
|
||||
* Return true if the validation is configured and available.
|
||||
|
@ -17,6 +17,7 @@ use GuzzleHttp\Exception\ConnectException;
|
||||
use GuzzleHttp\Exception\ServerException;
|
||||
use libphonenumber\NumberParseException;
|
||||
use libphonenumber\PhoneNumber;
|
||||
use libphonenumber\PhoneNumberType;
|
||||
use libphonenumber\PhoneNumberUtil;
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
@ -86,9 +87,17 @@ final class PhonenumberHelper implements PhoneNumberHelperInterface
|
||||
/**
|
||||
* Get type (mobile, landline, ...) for phone number.
|
||||
*/
|
||||
public function getType(string $phonenumber): string
|
||||
public function getType(PhoneNumber $phonenumber): string
|
||||
{
|
||||
return $this->performTwilioLookup($phonenumber) ?? 'unknown';
|
||||
switch ($this->phoneNumberUtil->getNumberType($phonenumber)) {
|
||||
case PhoneNumberType::MOBILE:
|
||||
return 'mobile';
|
||||
case PhoneNumberType::FIXED_LINE:
|
||||
case PhoneNumberType::VOIP:
|
||||
return 'landline';
|
||||
default:
|
||||
return 'landline';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -40,6 +40,10 @@ class PhonenumberNormalizer implements NormalizerInterface, DenormalizerInterfac
|
||||
*/
|
||||
public function denormalize($data, $type, $format = null, array $context = [])
|
||||
{
|
||||
if ('' === trim($data)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return $this->phoneNumberUtil->parse($data, $this->defaultCarrierCode);
|
||||
} catch (NumberParseException $e) {
|
||||
|
@ -43,7 +43,7 @@ final class ValidPhonenumber extends ConstraintValidator
|
||||
return;
|
||||
}
|
||||
|
||||
if ('' === $value) {
|
||||
if (null === $value) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@ namespace Chill\PersonBundle\Controller;
|
||||
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Entity\Person\ResidentialAddress;
|
||||
use Chill\PersonBundle\Form\Type\ResidentialAddressType;
|
||||
use Chill\PersonBundle\Form\ResidentialAddressType;
|
||||
use Chill\PersonBundle\Repository\ResidentialAddressRepository;
|
||||
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
|
@ -18,8 +18,8 @@ use Chill\PersonBundle\Repository\ResidentialAddressRepository;
|
||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Serializer\Annotation\Groups;
|
||||
use Symfony\Component\Serializer\Annotation\Context;
|
||||
use Symfony\Component\Serializer\Annotation\Groups;
|
||||
|
||||
/**
|
||||
* @ORM\Entity(repositoryClass=ResidentialAddressRepository::class)
|
||||
@ -49,7 +49,7 @@ class ResidentialAddress
|
||||
* @ORM\ManyToOne(targetEntity=Person::class)
|
||||
* @ORM\JoinColumn(nullable=true)
|
||||
* @Groups({"read"})
|
||||
* @Context(normalizationContext={"groups"={"minimal"}})
|
||||
* @Context(normalizationContext={"groups": {"minimal"}})
|
||||
*/
|
||||
private ?Person $hostPerson = null;
|
||||
|
||||
|
@ -13,6 +13,7 @@ namespace Chill\PersonBundle\Entity;
|
||||
|
||||
use DateTime;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use libphonenumber\PhoneNumber;
|
||||
|
||||
/**
|
||||
* Person Phones.
|
||||
@ -51,9 +52,9 @@ class PersonPhone
|
||||
private Person $person;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="text", length=40, nullable=false)
|
||||
* @ORM\Column(type="phone_number", nullable=false)
|
||||
*/
|
||||
private string $phonenumber = '';
|
||||
private ?PhoneNumber $phonenumber = null;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="text", length=40, nullable=true)
|
||||
@ -85,7 +86,7 @@ class PersonPhone
|
||||
return $this->person;
|
||||
}
|
||||
|
||||
public function getPhonenumber(): string
|
||||
public function getPhonenumber(): ?PhoneNumber
|
||||
{
|
||||
return $this->phonenumber;
|
||||
}
|
||||
@ -97,7 +98,8 @@ class PersonPhone
|
||||
|
||||
public function isEmpty(): bool
|
||||
{
|
||||
return empty($this->getDescription()) && empty($this->getPhonenumber());
|
||||
return ("" === $this->getDescription() || null === $this->getDescription())
|
||||
&& null === $this->getPhonenumber();
|
||||
}
|
||||
|
||||
public function setDate(DateTime $date): void
|
||||
@ -115,7 +117,7 @@ class PersonPhone
|
||||
$this->person = $person;
|
||||
}
|
||||
|
||||
public function setPhonenumber(string $phonenumber): void
|
||||
public function setPhonenumber(?PhoneNumber $phonenumber): void
|
||||
{
|
||||
$this->phonenumber = $phonenumber;
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Entity\PersonPhone;
|
||||
use Chill\PersonBundle\Form\Type\GenderType;
|
||||
use Chill\PersonBundle\Form\Type\PersonAltNameType;
|
||||
use Chill\PersonBundle\Form\Type\PersonPhoneType;
|
||||
use Chill\PersonBundle\Form\Type\Select2MaritalStatusType;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
@ -158,7 +159,7 @@ class PersonType extends AbstractType
|
||||
}
|
||||
|
||||
$builder->add('otherPhoneNumbers', ChillCollectionType::class, [
|
||||
'entry_type' => ChillPhoneNumberType::class,
|
||||
'entry_type' => PersonPhoneType::class,
|
||||
'button_add_label' => 'Add new phone',
|
||||
'button_remove_label' => 'Remove phone',
|
||||
'required' => false,
|
||||
|
@ -9,11 +9,12 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\PersonBundle\Form\Type;
|
||||
namespace Chill\PersonBundle\Form;
|
||||
|
||||
use Chill\MainBundle\Form\Type\CommentType;
|
||||
use Chill\MainBundle\Form\Type\PickAddressType;
|
||||
use Chill\PersonBundle\Entity\Person\ResidentialAddress;
|
||||
use Chill\PersonBundle\Form\Type\PickPersonDynamicType;
|
||||
use Chill\ThirdPartyBundle\Form\Type\PickThirdpartyDynamicType;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\DateType;
|
||||
|
@ -11,6 +11,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\PersonBundle\Form\Type;
|
||||
|
||||
use Chill\MainBundle\Form\Type\ChillPhoneNumberType;
|
||||
use Chill\MainBundle\Phonenumber\PhonenumberHelper;
|
||||
use Chill\PersonBundle\Entity\PersonPhone;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
@ -36,7 +37,7 @@ class PersonPhoneType extends AbstractType
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder->add('phonenumber', TelType::class, [
|
||||
$builder->add('phonenumber', ChillPhoneNumberType::class, [
|
||||
'label' => 'Other phonenumber',
|
||||
'required' => true,
|
||||
]);
|
||||
|
@ -32,26 +32,11 @@ class ResidentialAddressRepository extends ServiceEntityRepository
|
||||
parent::__construct($registry, ResidentialAddress::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Person $person
|
||||
* @param DateTimeImmutable|null $at
|
||||
* @return array|ResidentialAddress[]|null
|
||||
*/
|
||||
public function findCurrentResidentialAddressByPerson(Person $person, ?DateTimeImmutable $at = null): array
|
||||
{
|
||||
return $this->buildQueryFindCurrentResidentialAddresses($person, $at)
|
||||
->select('ra')
|
||||
->getQuery()
|
||||
->getResult();
|
||||
}
|
||||
|
||||
public function buildQueryFindCurrentResidentialAddresses(Person $person, ?DateTimeImmutable $at = null): QueryBuilder
|
||||
{
|
||||
$date = null === $at ? new DateTimeImmutable('today') : $at;
|
||||
$qb = $this->createQueryBuilder('ra');
|
||||
|
||||
|
||||
|
||||
$dateFilter = $qb->expr()->andX(
|
||||
$qb->expr()->lte('ra.startDate', ':dateIn'),
|
||||
$qb->expr()->orX(
|
||||
@ -69,6 +54,17 @@ class ResidentialAddressRepository extends ServiceEntityRepository
|
||||
return $qb;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|ResidentialAddress[]|null
|
||||
*/
|
||||
public function findCurrentResidentialAddressByPerson(Person $person, ?DateTimeImmutable $at = null): array
|
||||
{
|
||||
return $this->buildQueryFindCurrentResidentialAddresses($person, $at)
|
||||
->select('ra')
|
||||
->getQuery()
|
||||
->getResult();
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @return ResidentialAddress[] Returns an array of ResidentialAddress objects
|
||||
// */
|
||||
|
@ -170,7 +170,9 @@ export default {
|
||||
console.log('data', payload.data)
|
||||
body.name = payload.data.name;
|
||||
body.email = payload.data.email;
|
||||
body.telephone = payload.data.phonenumber;
|
||||
body.telephone = payload.data.telephone;
|
||||
body.civility = payload.data.civility;
|
||||
body.profession = payload.data.profession;
|
||||
body.address = payload.data.address ? { id: payload.data.address.address_id } : null;
|
||||
|
||||
makeFetch('PATCH', `/api/1.0/thirdparty/thirdparty/${payload.data.id}.json`, body)
|
||||
|
@ -167,6 +167,18 @@
|
||||
<span class="chill-no-data-statement">{{ 'No data given'|trans }}</span>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if person.email is not null %}
|
||||
<li>
|
||||
<i class="fa fa-li fa-envelope-o"></i><a href="{{ 'mailto:' ~ person.email }}">
|
||||
{{ person.email }}
|
||||
</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li>
|
||||
<i class="fa fa-li fa-envelope-o"></i>
|
||||
<span class="chill-no-data-statement">{{ 'No data given'|trans }}</span>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if options['addCenter'] and person|chill_resolve_center|length > 0 %}
|
||||
<li>
|
||||
<i class="fa fa-li fa-long-arrow-right"></i>
|
||||
|
@ -74,6 +74,7 @@ class PersonDocGenNormalizer implements
|
||||
|
||||
$data = [
|
||||
'type' => 'person',
|
||||
'id' => $person->getId(),
|
||||
'isNull' => false,
|
||||
'civility' => $this->normalizer->normalize($person->getCivility(), $format, array_merge($context, ['docgen:expects' => Civility::class])),
|
||||
'firstName' => $person->getFirstName(),
|
||||
@ -151,7 +152,7 @@ class PersonDocGenNormalizer implements
|
||||
$normalizer = new NormalizeNullValueHelper($this->normalizer, 'type', 'person');
|
||||
|
||||
$attributes = [
|
||||
'firstName', 'lastName', 'age', 'altNames', 'text',
|
||||
'id', 'firstName', 'lastName', 'age', 'altNames', 'text',
|
||||
'civility' => Civility::class,
|
||||
'birthdate' => DateTimeInterface::class,
|
||||
'deathdate' => DateTimeInterface::class,
|
||||
|
@ -31,6 +31,9 @@ use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
|
||||
use Symfony\Component\Serializer\Normalizer\ObjectToPopulateTrait;
|
||||
use function array_key_exists;
|
||||
use function count;
|
||||
use function in_array;
|
||||
use function is_string;
|
||||
|
||||
/**
|
||||
* Serialize a Person entity.
|
||||
@ -54,11 +57,11 @@ class PersonJsonNormalizer implements DenormalizerAwareInterface, NormalizerAwar
|
||||
private ResidentialAddressRepository $residentialAddressRepository;
|
||||
|
||||
public function __construct(
|
||||
ChillEntityRenderExtension $render,
|
||||
ChillEntityRenderExtension $render, /* TODO: replace by PersonRenderInterface, as sthis is the only one required */
|
||||
PersonRepository $repository,
|
||||
CenterResolverManagerInterface $centerResolverManager,
|
||||
ResidentialAddressRepository $residentialAddressRepository,
|
||||
PhoneNumberHelperInterface $phoneNumberHelper
|
||||
PhoneNumberHelperInterface $phoneNumberHelper /* TODO maybe not necessayr any more */
|
||||
) {
|
||||
$this->render = $render;
|
||||
$this->repository = $repository;
|
||||
@ -187,6 +190,10 @@ class PersonJsonNormalizer implements DenormalizerAwareInterface, NormalizerAwar
|
||||
public function normalize($person, $format = null, array $context = [])
|
||||
{
|
||||
$groups = $context[AbstractNormalizer::GROUPS] ?? [];
|
||||
|
||||
if (is_string($groups)) {
|
||||
$groups = [$groups];
|
||||
}
|
||||
$household = $person->getCurrentHousehold();
|
||||
$currentResidentialAddresses = $this->residentialAddressRepository->findCurrentResidentialAddressByPerson($person);
|
||||
|
||||
@ -207,8 +214,8 @@ class PersonJsonNormalizer implements DenormalizerAwareInterface, NormalizerAwar
|
||||
'gender' => $person->getGender(),
|
||||
];
|
||||
|
||||
if (in_array("minimal", $groups) && 1 === count($groups)) {
|
||||
return $data;
|
||||
if (in_array('minimal', $groups, true) && 1 === count($groups)) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
return array_merge($data, [
|
||||
|
@ -0,0 +1,179 @@
|
||||
<?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\Service\DocGenerator;
|
||||
|
||||
use Chill\DocGeneratorBundle\Context\DocGeneratorContextWithAdminFormInterface;
|
||||
use Chill\DocGeneratorBundle\Context\Exception\UnexpectedTypeException;
|
||||
use Chill\DocGeneratorBundle\Entity\DocGeneratorTemplate;
|
||||
use Chill\DocGeneratorBundle\Service\Context\BaseContextData;
|
||||
use Chill\DocStoreBundle\Entity\PersonDocument;
|
||||
use Chill\DocStoreBundle\Entity\StoredObject;
|
||||
use Chill\DocStoreBundle\Repository\DocumentCategoryRepository;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use DateTime;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
use function array_key_exists;
|
||||
|
||||
class PersonContext implements DocGeneratorContextWithAdminFormInterface
|
||||
{
|
||||
private BaseContextData $baseContextData;
|
||||
|
||||
private DocumentCategoryRepository $documentCategoryRepository;
|
||||
|
||||
private EntityManagerInterface $em;
|
||||
|
||||
private NormalizerInterface $normalizer;
|
||||
|
||||
private TranslatableStringHelperInterface $translatableStringHelper;
|
||||
|
||||
private TranslatorInterface $translator;
|
||||
|
||||
public function __construct(
|
||||
DocumentCategoryRepository $documentCategoryRepository,
|
||||
NormalizerInterface $normalizer,
|
||||
TranslatableStringHelperInterface $translatableStringHelper,
|
||||
EntityManagerInterface $em,
|
||||
TranslatorInterface $translator,
|
||||
BaseContextData $baseContextData
|
||||
) {
|
||||
$this->documentCategoryRepository = $documentCategoryRepository;
|
||||
$this->normalizer = $normalizer;
|
||||
$this->translatableStringHelper = $translatableStringHelper;
|
||||
$this->em = $em;
|
||||
$this->baseContextData = $baseContextData;
|
||||
$this->translator = $translator;
|
||||
}
|
||||
|
||||
public function adminFormReverseTransform(array $data): array
|
||||
{
|
||||
if (array_key_exists('category', $data)) {
|
||||
$data['category'] = [
|
||||
'idInsideBundle' => $data['category']->getIdInsideBundle(),
|
||||
'bundleId' => $data['category']->getBundleId(),
|
||||
];
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function adminFormTransform(array $data): array
|
||||
{
|
||||
$r = [
|
||||
'mainPerson' => $data['mainPerson'] ?? false,
|
||||
'mainPersonLabel' => $data['mainPersonLabel'] ?? $this->translator->trans('docgen.Main person'),
|
||||
];
|
||||
|
||||
if (array_key_exists('category', $data)) {
|
||||
$r['category'] = array_key_exists('category', $data) ?
|
||||
$this->documentCategoryRepository->find($data['category']) : null;
|
||||
}
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
public function buildAdminForm(FormBuilderInterface $builder): void
|
||||
{
|
||||
$builder
|
||||
->add('category', EntityType::class, [
|
||||
'placeholder' => 'Choose a document category',
|
||||
'class' => 'ChillDocStoreBundle:DocumentCategory',
|
||||
'query_builder' => static function (EntityRepository $er) {
|
||||
return $er->createQueryBuilder('c')
|
||||
->where('c.documentClass = :docClass')
|
||||
->setParameter('docClass', PersonDocument::class);
|
||||
},
|
||||
'choice_label' => function ($entity = null) {
|
||||
return $entity ? $this->translatableStringHelper->localize($entity->getName()) : '';
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
public function getData(DocGeneratorTemplate $template, $entity, array $contextGenerationData = []): array
|
||||
{
|
||||
if (!$entity instanceof Person) {
|
||||
throw new UnexpectedTypeException($entity, Person::class);
|
||||
}
|
||||
|
||||
$data = [];
|
||||
$data = array_merge($data, $this->baseContextData->getData());
|
||||
$data['person'] = $this->normalizer->normalize($entity, 'docgen', [
|
||||
'docgen:expects' => Person::class,
|
||||
'groups' => ['docgen:read', 'docgen:person:with-household', 'docgen:person:with-relations'],
|
||||
]);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'docgen.A basic context for person';
|
||||
}
|
||||
|
||||
public function getEntityClass(): string
|
||||
{
|
||||
return Person::class;
|
||||
}
|
||||
|
||||
public function getFormData(DocGeneratorTemplate $template, $entity): array
|
||||
{
|
||||
return [
|
||||
'person' => $entity,
|
||||
];
|
||||
}
|
||||
|
||||
public static function getKey(): string
|
||||
{
|
||||
return self::class;
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return 'docgen.Person basic';
|
||||
}
|
||||
|
||||
public function hasAdminForm(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Person $entity
|
||||
*/
|
||||
public function storeGenerated(DocGeneratorTemplate $template, StoredObject $storedObject, object $entity, array $contextGenerationData): void
|
||||
{
|
||||
$doc = new PersonDocument();
|
||||
$doc->setTemplate($template)
|
||||
->setTitle($this->translatableStringHelper->localize($template->getName()))
|
||||
->setDate(new DateTime())
|
||||
->setDescription($this->translatableStringHelper->localize($template->getName()))
|
||||
->setPerson($entity)
|
||||
->setObject($storedObject);
|
||||
|
||||
if (array_key_exists('category', $template->getOptions())) {
|
||||
$doc
|
||||
->setCategory(
|
||||
$this->documentCategoryRepository->find(
|
||||
$template->getOptions()['category']
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$this->em->persist($doc);
|
||||
}
|
||||
}
|
@ -38,6 +38,7 @@ final class PersonDocGenNormalizerTest extends KernelTestCase
|
||||
use ProphecyTrait;
|
||||
|
||||
private const BLANK = [
|
||||
'id' => '',
|
||||
'firstName' => '',
|
||||
'lastName' => '',
|
||||
'altNames' => '',
|
||||
|
@ -11,7 +11,15 @@ declare(strict_types=1);
|
||||
|
||||
namespace Serializer\Normalizer;
|
||||
|
||||
use Chill\MainBundle\Phonenumber\PhoneNumberHelperInterface;
|
||||
use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface;
|
||||
use Chill\MainBundle\Templating\Entity\ChillEntityRenderExtension;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Repository\PersonRepository;
|
||||
use Chill\PersonBundle\Repository\ResidentialAddressRepository;
|
||||
use Chill\PersonBundle\Serializer\Normalizer\PersonJsonNormalizer;
|
||||
use Prophecy\Argument;
|
||||
use Prophecy\PhpUnit\ProphecyTrait;
|
||||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||
@ -22,12 +30,27 @@ use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||
*/
|
||||
final class PersonJsonNormalizerTest extends KernelTestCase
|
||||
{
|
||||
private NormalizerInterface $normalizer;
|
||||
use ProphecyTrait;
|
||||
|
||||
private PersonJsonNormalizer $normalizer;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
self::bootKernel();
|
||||
$this->normalizer = self::$container->get(NormalizerInterface::class);
|
||||
|
||||
$residentialAddressRepository = $this->prophesize(ResidentialAddressRepository::class);
|
||||
$residentialAddressRepository
|
||||
->findCurrentResidentialAddressByPerson(Argument::type(Person::class), Argument::any())
|
||||
->willReturn([]);
|
||||
|
||||
$this->normalizer = $this->buildPersonJsonNormalizer(
|
||||
self::$container->get(ChillEntityRenderExtension::class),
|
||||
self::$container->get(PersonRepository::class),
|
||||
self::$container->get(CenterResolverManagerInterface::class),
|
||||
$residentialAddressRepository->reveal(),
|
||||
self::$container->get(PhoneNumberHelperInterface::class),
|
||||
self::$container->get(NormalizerInterface::class)
|
||||
);
|
||||
}
|
||||
|
||||
public function testNormalization()
|
||||
@ -37,4 +60,24 @@ final class PersonJsonNormalizerTest extends KernelTestCase
|
||||
|
||||
$this->assertIsArray($result);
|
||||
}
|
||||
|
||||
private function buildPersonJsonNormalizer(
|
||||
ChillEntityRenderExtension $render,
|
||||
PersonRepository $repository,
|
||||
CenterResolverManagerInterface $centerResolverManager,
|
||||
ResidentialAddressRepository $residentialAddressRepository,
|
||||
PhoneNumberHelperInterface $phoneNumberHelper,
|
||||
NormalizerInterface $normalizer
|
||||
): PersonJsonNormalizer {
|
||||
$personJsonNormalizer = new PersonJsonNormalizer(
|
||||
$render,
|
||||
$repository,
|
||||
$centerResolverManager,
|
||||
$residentialAddressRepository,
|
||||
$phoneNumberHelper
|
||||
);
|
||||
$personJsonNormalizer->setNormalizer($normalizer);
|
||||
|
||||
return $personJsonNormalizer;
|
||||
}
|
||||
}
|
||||
|
@ -541,6 +541,8 @@ docgen:
|
||||
A basic context for accompanying period: Contexte pour les parcours
|
||||
A context for accompanying period work: Contexte pour les actions d'accompagnement
|
||||
A context for accompanying period work evaluation: Contexte pour les évaluations dans les actions d'accompagnement
|
||||
Person basic: Personne (basique)
|
||||
A basic context for person: Contexte pour les personnes
|
||||
|
||||
period_notification:
|
||||
period_designated_subject: Vous êtes référent d'un parcours d'accompagnement
|
||||
|
@ -61,9 +61,9 @@
|
||||
<i class="fa fa-li fa-map-marker"></i>
|
||||
<address-render-box :address="thirdparty.address" :isMultiline="isMultiline"></address-render-box>
|
||||
</li>
|
||||
<li v-if="thirdparty.phonenumber">
|
||||
<li v-if="thirdparty.telephone">
|
||||
<i class="fa fa-li fa-mobile"></i>
|
||||
<a :href="'tel: ' + thirdparty.phonenumber">{{ thirdparty.phonenumber }}</a>
|
||||
<a :href="'tel: ' + thirdparty.telephone">{{ thirdparty.telephone }}</a>
|
||||
</li>
|
||||
<li v-if="thirdparty.email">
|
||||
<i class="fa fa-li fa-envelope-o"></i>
|
||||
@ -78,9 +78,9 @@
|
||||
<i class="fa fa-li fa-map-marker"></i>
|
||||
<address-render-box :address="thirdparty.address" :isMultiline="isMultiline"></address-render-box>
|
||||
</li>
|
||||
<li v-if="thirdparty.phonenumber">
|
||||
<li v-if="thirdparty.telephone">
|
||||
<i class="fa fa-li fa-mobile"></i>
|
||||
<a :href="'tel: ' + thirdparty.phonenumber">{{ thirdparty.phonenumber }}</a>
|
||||
<a :href="'tel: ' + thirdparty.telephone">{{ thirdparty.telephone }}</a>
|
||||
</li>
|
||||
<li v-if="thirdparty.email">
|
||||
<i class="fa fa-li fa-envelope-o"></i>
|
||||
|
@ -118,7 +118,7 @@
|
||||
<div class="input-group mb-3">
|
||||
<span class="input-group-text" id="phonenumber"><i class="fa fa-fw fa-phone"></i></span>
|
||||
<input class="form-control form-control-lg"
|
||||
v-model="thirdparty.phonenumber"
|
||||
v-model="thirdparty.telephone"
|
||||
v-bind:placeholder="$t('thirdparty.phonenumber')"
|
||||
v-bind:aria-label="$t('thirdparty.phonenumber')"
|
||||
aria-describedby="phonenumber" />
|
||||
|
@ -62,7 +62,7 @@ class ThirdPartyNormalizer implements NormalizerAwareInterface, NormalizerInterf
|
||||
}, $thirdParty->getTypesAndCategories()),
|
||||
'profession' => $this->normalizer->normalize($thirdParty->getProfession(), $format, $context),
|
||||
'address' => $this->normalizer->normalize($thirdParty->getAddress(), $format, ['address_rendering' => 'short']),
|
||||
'phonenumber' => $this->normalizer->normalize($thirdParty->getTelephone()),
|
||||
'telephone' => $this->normalizer->normalize($thirdParty->getTelephone()),
|
||||
'email' => $thirdParty->getEmail(),
|
||||
'isChild' => $thirdParty->isChild(),
|
||||
'parent' => $this->normalizer->normalize($thirdParty->getParent(), $format, $context),
|
||||
|
Loading…
x
Reference in New Issue
Block a user