Signature zone within workflow

This commit is contained in:
LenaertsJ 2024-07-18 13:51:08 +00:00 committed by Julien Fastré
parent db73dcffc7
commit 873940786f
11 changed files with 198 additions and 19 deletions

View File

@ -0,0 +1,5 @@
kind: Feature
body: Metadata form added for person signatures
time: 2024-07-18T15:12:33.8134266+02:00
custom:
Issue: "288"

View File

@ -13,9 +13,9 @@ namespace Chill\MainBundle\Controller;
use Chill\MainBundle\Entity\User; use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Entity\Workflow\EntityWorkflow; use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
use Chill\MainBundle\Entity\Workflow\EntityWorkflowComment;
use Chill\MainBundle\Entity\Workflow\EntityWorkflowStep; use Chill\MainBundle\Entity\Workflow\EntityWorkflowStep;
use Chill\MainBundle\Form\EntityWorkflowCommentType; use Chill\MainBundle\Entity\Workflow\EntityWorkflowStepSignature;
use Chill\MainBundle\Form\WorkflowSignatureMetadataType;
use Chill\MainBundle\Form\WorkflowStepType; use Chill\MainBundle\Form\WorkflowStepType;
use Chill\MainBundle\Pagination\PaginatorFactory; use Chill\MainBundle\Pagination\PaginatorFactory;
use Chill\MainBundle\Repository\Workflow\EntityWorkflowRepository; use Chill\MainBundle\Repository\Workflow\EntityWorkflowRepository;
@ -289,6 +289,7 @@ class WorkflowController extends AbstractController
$handler = $this->entityWorkflowManager->getHandler($entityWorkflow); $handler = $this->entityWorkflowManager->getHandler($entityWorkflow);
$workflow = $this->registry->get($entityWorkflow, $entityWorkflow->getWorkflowName()); $workflow = $this->registry->get($entityWorkflow, $entityWorkflow->getWorkflowName());
$errors = []; $errors = [];
$signatures = $entityWorkflow->getCurrentStep()->getSignatures();
if (\count($workflow->getEnabledTransitions($entityWorkflow)) > 0) { if (\count($workflow->getEnabledTransitions($entityWorkflow)) > 0) {
// possible transition // possible transition
@ -341,22 +342,6 @@ class WorkflowController extends AbstractController
} }
} }
/*
$commentForm = $this->createForm(EntityWorkflowCommentType::class, $newComment = new EntityWorkflowComment());
$commentForm->handleRequest($request);
if ($commentForm->isSubmitted() && $commentForm->isValid()) {
$this->entityManager->persist($newComment);
$this->entityManager->flush();
$this->addFlash('success', $this->translator->trans('workflow.Comment added'));
return $this->redirectToRoute('chill_main_workflow_show', ['id' => $entityWorkflow->getId()]);
} elseif ($commentForm->isSubmitted() && !$commentForm->isValid()) {
$this->addFlash('error', $this->translator->trans('This form contains errors'));
}
*/
return $this->render( return $this->render(
'@ChillMain/Workflow/index.html.twig', '@ChillMain/Workflow/index.html.twig',
[ [
@ -366,7 +351,7 @@ class WorkflowController extends AbstractController
'transition_form' => isset($transitionForm) ? $transitionForm->createView() : null, 'transition_form' => isset($transitionForm) ? $transitionForm->createView() : null,
'entity_workflow' => $entityWorkflow, 'entity_workflow' => $entityWorkflow,
'transition_form_errors' => $errors, 'transition_form_errors' => $errors,
// 'comment_form' => $commentForm->createView(), 'signatures' => $signatures,
] ]
); );
} }
@ -385,4 +370,47 @@ class WorkflowController extends AbstractController
return $lines; return $lines;
} }
#[Route(path: '/{_locale}/main/workflow/signature/{signature_id}/metadata', name: 'chill_main_workflow_signature_metadata')]
public function addSignatureMetadata(int $signature_id, Request $request): Response
{
$signature = $this->entityManager->getRepository(EntityWorkflowStepSignature::class)->find($signature_id);
if ($signature->getSigner() instanceof User) {
return $this->redirectToRoute('signature_route_user');
}
$metadataForm = $this->createForm(WorkflowSignatureMetadataType::class);
$metadataForm->add('submit', SubmitType::class, ['label' => $this->translator->trans('Save')]);
$metadataForm->handleRequest($request);
if ($metadataForm->isSubmitted() && $metadataForm->isValid()) {
$data = $metadataForm->getData();
$signature->setSignatureMetadata(
[
'base_signer' => [
'document_type' => $data['documentType'],
'document_number' => $data['documentNumber'],
'expiration_date' => $data['expirationDate'],
],
]
);
$this->entityManager->persist($signature);
$this->entityManager->flush();
// Todo should redirect to document for actual signing? To be adjusted still
return $this->redirectToRoute('chill_main_workflow_show', ['id' => $signature->getStep()->getEntityWorkflow()->getId()]);
}
return $this->render(
'@ChillMain/Workflow/_signature_metadata.html.twig',
[
'metadata_form' => $metadataForm->createView(),
'person' => $signature->getSigner(),
]
);
}
} }

View File

@ -193,6 +193,11 @@ class ChillMainExtension extends Extension implements
[] []
); );
$container->setParameter(
'chill_main.id_document_kinds',
$config['id_document_kinds']
);
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../config')); $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../config'));
$loader->load('services.yaml'); $loader->load('services.yaml');
$loader->load('services/doctrine.yaml'); $loader->load('services/doctrine.yaml');

View File

@ -151,6 +151,28 @@ class Configuration implements ConfigurationInterface
->append($this->addWidgetsConfiguration('homepage', $this->containerBuilder)) ->append($this->addWidgetsConfiguration('homepage', $this->containerBuilder))
->end() // end of widgets/children ->end() // end of widgets/children
->end() // end of widgets ->end() // end of widgets
->arrayNode('id_document_kinds')->defaultValue([])
->arrayPrototype()
->children()
->scalarNode('key')->isRequired()->cannotBeEmpty()
->info('the key stored in database')
->example('id_card')
->end()
->arrayNode('labels')->isRequired()->requiresAtLeastOneElement()
->arrayPrototype()
->children()
->scalarNode('lang')->isRequired()->cannotBeEmpty()
->example('fr')
->end()
->scalarNode('label')->isRequired()->cannotBeEmpty()
->example('Carte de séjour')
->end()
->end()
->end()
->end()
->end()
->end()
->end() // end of document types
->arrayNode('cruds') ->arrayNode('cruds')
->defaultValue([]) ->defaultValue([])
->arrayPrototype() ->arrayPrototype()

View File

@ -0,0 +1,62 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\MainBundle\Form;
use Chill\MainBundle\Form\Type\ChillDateType;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
class WorkflowSignatureMetadataType extends AbstractType
{
public function __construct(private readonly ParameterBagInterface $parameterBag, private readonly TranslatableStringHelperInterface $translatableStringHelper) {}
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$documentTypeChoices = $this->parameterBag->get('chill_main.id_document_kinds');
$choices = [];
foreach ($documentTypeChoices as $documentType) {
$labels = [];
foreach ($documentType['labels'] as $label) {
$labels[$label['lang']] = $label['label'];
}
$localizedLabel = $this->translatableStringHelper->localize($labels);
if (null !== $localizedLabel) {
$choices[$localizedLabel] = $documentType['key'];
}
}
$builder
->add('documentType', ChoiceType::class, [
'label' => 'workflow.signature_zone.metadata.docType',
'expanded' => false,
'required' => true,
'choices' => $choices,
])
->add('documentNumber', TextType::class, [
'required' => true,
'label' => 'workflow.signature_zone.metadata.docNumber',
])
->add('expirationDate', ChillDateType::class, [
'required' => true,
'input' => 'datetime_immutable',
'label' => 'workflow.signature_zone.metadata.docExpiration',
]);
}
}

View File

@ -0,0 +1,19 @@
<h2>{{ 'workflow.signature_zone.title'|trans }}</h2>
<div class="flex-table justify-content-center">
<div class="item-bloc">
{% for s in signatures %}
<div class="item-row mb-2">
<div class="col-sm-6"><span>{{ s.signer|chill_entity_render_box }}</span></div>
<div class="col-sm-6">
<a class="btn btn-show" href="{{ chill_path_add_return_path('chill_main_workflow_signature_metadata', { 'signature_id': s.id}) }}">{{ 'workflow.signature_zone.button_sign'|trans }}</a>
{% if s.state is same as('signed') %}
<p class="updatedBy">{{ s.stateDate }}</p>
{% endif %}
</div>
</div>
{% endfor %}
</div>
</div>

View File

@ -0,0 +1,24 @@
{% extends '@ChillMain/layout.html.twig' %}
{% block title %}
{{ 'Signature'|trans }}
{% endblock %}
{% block content %}
<div class="col-10 workflow">
<h1 class="mb-5">{{ 'workflow.signature_zone.metadata.sign_by'|trans({ '%name%' : person.firstname ~ ' ' ~ person.lastname}) }}</h1>
{% if metadata_form is not null %}
{{ form_start(metadata_form) }}
{{ form_row(metadata_form.documentType) }}
{{ form_row(metadata_form.documentNumber) }}
{{ form_row(metadata_form.expirationDate) }}
<ul class="record_actions">
<li>
{{ form_widget(metadata_form.submit, { 'attr' : { 'class' : 'btn btn-submit' }} ) }}
</li>
</ul>
{{ form_end(metadata_form) }}
{% endif %}
</div>
{% endblock %}

View File

@ -57,6 +57,9 @@
</section> </section>
<section class="step my-4">{% include '@ChillMain/Workflow/_follow.html.twig' %}</section> <section class="step my-4">{% include '@ChillMain/Workflow/_follow.html.twig' %}</section>
{% if signatures|length > 0 %}
<section class="step my-4">{% include '@ChillMain/Workflow/_signature.html.twig' %}</section>
{% endif %}
<section class="step my-4">{% include '@ChillMain/Workflow/_decision.html.twig' %}</section>{# <section class="step my-4">{% include '@ChillMain/Workflow/_decision.html.twig' %}</section>{#
<section class="step my-4">{% include '@ChillMain/Workflow/_comment.html.twig' %}</section> #} <section class="step my-4">{% include '@ChillMain/Workflow/_comment.html.twig' %}</section> #}
<section class="step my-4">{% include '@ChillMain/Workflow/_history.html.twig' %}</section> <section class="step my-4">{% include '@ChillMain/Workflow/_history.html.twig' %}</section>

View File

@ -133,6 +133,8 @@ services:
Chill\MainBundle\Form\WorkflowStepType: ~ Chill\MainBundle\Form\WorkflowStepType: ~
Chill\MainBundle\Form\WorkflowSignatureMetadataType: ~
Chill\MainBundle\Form\DataMapper\PrivateCommentDataMapper: Chill\MainBundle\Form\DataMapper\PrivateCommentDataMapper:
autowire: true autowire: true
autoconfigure: true autoconfigure: true

View File

@ -528,6 +528,15 @@ workflow:
This link grant any user to apply a transition: Le lien d'accès suivant permet d'appliquer une transition This link grant any user to apply a transition: Le lien d'accès suivant permet d'appliquer une transition
The workflow may be accssed through this link: Une transition peut être appliquée sur ce workflow grâce au lien d'accès suivant The workflow may be accssed through this link: Une transition peut être appliquée sur ce workflow grâce au lien d'accès suivant
signature_zone:
title: Appliquer les signatures électroniques
button_sign: Signer
metadata:
sign_by: 'Signature pour %name%'
docType: Type de document
docNumber: Numéro de document
docExpiration: Date d'expiration
Subscribe final: Recevoir une notification à l'étape finale Subscribe final: Recevoir une notification à l'étape finale
Subscribe all steps: Recevoir une notification à chaque étape Subscribe all steps: Recevoir une notification à chaque étape