mirror of
				https://gitlab.com/Chill-Projet/chill-bundles.git
				synced 2025-10-31 09:18:24 +00:00 
			
		
		
		
	Merge branch '292-signature-form-workflow' into 'signature-app-master'
Modify workflow form to indicate if signatures are wanted See merge request Chill-Projet/chill-bundles!713
This commit is contained in:
		| @@ -193,11 +193,6 @@ 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->load('services.yaml'); | ||||
|         $loader->load('services/doctrine.yaml'); | ||||
|   | ||||
| @@ -85,6 +85,29 @@ class Configuration implements ConfigurationInterface | ||||
|             ->end() | ||||
|             ->end() | ||||
|             ->end() // end of notifications | ||||
|             ->arrayNode('workflow_signature') | ||||
|             ->children() | ||||
|             ->arrayNode('base_signer') | ||||
|             ->children() | ||||
|             ->arrayNode('document_kinds') | ||||
|             ->arrayPrototype() | ||||
|             ->children() | ||||
|             ->scalarNode('key')->cannotBeEmpty()->end() | ||||
|             ->arrayNode('labels') | ||||
|             ->arrayPrototype() | ||||
|             ->children() | ||||
|             ->scalarNode('lang')->cannotBeEmpty()->end() | ||||
|             ->scalarNode('label')->cannotBeEmpty()->end() | ||||
|             ->end() | ||||
|             ->end() | ||||
|             ->end() | ||||
|             ->end() | ||||
|             ->end() | ||||
|             ->end() | ||||
|             ->end() | ||||
|             ->end() | ||||
|             ->end() | ||||
|             ->end() // end of workflow signature document types | ||||
|             ->arrayNode('phone_helper') | ||||
|             ->canBeUnset() | ||||
|             ->children() | ||||
| @@ -151,28 +174,6 @@ class Configuration implements ConfigurationInterface | ||||
|             ->append($this->addWidgetsConfiguration('homepage', $this->containerBuilder)) | ||||
|             ->end() // end of widgets/children | ||||
|             ->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') | ||||
|             ->defaultValue([]) | ||||
|             ->arrayPrototype() | ||||
|   | ||||
| @@ -25,7 +25,7 @@ class WorkflowSignatureMetadataType extends AbstractType | ||||
|  | ||||
|     public function buildForm(FormBuilderInterface $builder, array $options): void | ||||
|     { | ||||
|         $documentTypeChoices = $this->parameterBag->get('chill_main.id_document_kinds'); | ||||
|         $documentTypeChoices = $this->parameterBag->get('chill_main')['workflow_signature']['base_signer']['document_kinds']; | ||||
|  | ||||
|         $choices = []; | ||||
|  | ||||
|   | ||||
| @@ -17,6 +17,7 @@ use Chill\MainBundle\Form\Type\ChillTextareaType; | ||||
| use Chill\MainBundle\Form\Type\PickUserDynamicType; | ||||
| use Chill\MainBundle\Templating\TranslatableStringHelperInterface; | ||||
| use Chill\MainBundle\Workflow\WorkflowTransitionContextDTO; | ||||
| use Chill\PersonBundle\Form\Type\PickPersonDynamicType; | ||||
| use Symfony\Component\Form\AbstractType; | ||||
| use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | ||||
| use Symfony\Component\Form\Extension\Core\Type\EmailType; | ||||
| @@ -102,6 +103,7 @@ class WorkflowStepType extends AbstractType | ||||
|                 'choice_attr' => static function (Transition $transition) use ($workflow) { | ||||
|                     $toFinal = true; | ||||
|                     $isForward = 'neutral'; | ||||
|                     $isSignature = []; | ||||
|  | ||||
|                     $metadata = $workflow->getMetadataStore()->getTransitionMetadata($transition); | ||||
|  | ||||
| @@ -121,18 +123,43 @@ class WorkflowStepType extends AbstractType | ||||
|                         ) { | ||||
|                             $toFinal = false; | ||||
|                         } | ||||
|  | ||||
|                         if (\array_key_exists('isSignature', $meta)) { | ||||
|                             $isSignature = $meta['isSignature']; | ||||
|                         } | ||||
|                     } | ||||
|  | ||||
|                     return [ | ||||
|                         'data-is-transition' => 'data-is-transition', | ||||
|                         'data-to-final' => $toFinal ? '1' : '0', | ||||
|                         'data-is-forward' => $isForward, | ||||
|                         'data-is-signature' => json_encode($isSignature), | ||||
|                     ]; | ||||
|                 }, | ||||
|             ]) | ||||
|             ->add('isPersonOrUserSignature', ChoiceType::class, [ | ||||
|                 'mapped' => false, | ||||
|                 'multiple' => false, | ||||
|                 'expanded' => true, | ||||
|                 'label' => 'workflow.signature_zone.type of signature', | ||||
|                 'choices' => [ | ||||
|                     'workflow.signature_zone.persons' => 'person', | ||||
|                     'workflow.signature_zone.user' => 'user', | ||||
|                 ], | ||||
|             ]) | ||||
|             ->add('futurePersonSignatures', PickPersonDynamicType::class, [ | ||||
|                 'label' => 'workflow.signature_zone.person signatures', | ||||
|                 'multiple' => true, | ||||
|                 'empty_data' => '[]', | ||||
|             ]) | ||||
|             ->add('futureUserSignature', PickUserDynamicType::class, [ | ||||
|                 'label' => 'workflow.signature_zone.user signature', | ||||
|                 'multiple' => false, | ||||
|             ]) | ||||
|             ->add('futureDestUsers', PickUserDynamicType::class, [ | ||||
|                 'label' => 'workflow.dest for next steps', | ||||
|                 'multiple' => true, | ||||
|                 'empty_data' => '[]', | ||||
|                 'suggested' => $options['suggested_users'], | ||||
|             ]) | ||||
|             ->add('futureCcUsers', PickUserDynamicType::class, [ | ||||
| @@ -140,6 +167,8 @@ class WorkflowStepType extends AbstractType | ||||
|                 'multiple' => true, | ||||
|                 'required' => false, | ||||
|                 'suggested' => $options['suggested_users'], | ||||
|                 'empty_data' => '[]', | ||||
|                 'attr' => ['class' => 'future-cc-users'], | ||||
|             ]) | ||||
|             ->add('futureDestEmails', ChillCollectionType::class, [ | ||||
|                 'label' => 'workflow.dest by email', | ||||
|   | ||||
| @@ -4,38 +4,124 @@ window.addEventListener('DOMContentLoaded', function() { | ||||
|     let | ||||
|         divTransitions = document.querySelector('#transitions'), | ||||
|         futureDestUsersContainer = document.querySelector('#futureDests') | ||||
|     ; | ||||
|  | ||||
|     if (null !== divTransitions) { | ||||
|         new ShowHide({ | ||||
|             load_event: null, | ||||
|             froms: [divTransitions], | ||||
|             container: [futureDestUsersContainer], | ||||
|             test: function(divs, arg2, arg3) { | ||||
|                 for (let div of divs) { | ||||
|                     for (let input of div.querySelectorAll('input')) { | ||||
|                         if (input.checked) { | ||||
|                             if (input.dataset.toFinal === "1") { | ||||
|                                 return false; | ||||
|                             } else { | ||||
|                                 return true; | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 return true; | ||||
|             }, | ||||
|         }); | ||||
|     } | ||||
|         personSignatureField = document.querySelector('#person-signature-field'); | ||||
|         userSignatureField = document.querySelector('#user-signature-field'); | ||||
|         signatureTypeChoices = document.querySelector('#signature-type-choice'); | ||||
|         personChoice = document.querySelector('#workflow_step_isPersonOrUserSignature_0'); | ||||
|         userChoice = document.querySelector('#workflow_step_isPersonOrUserSignature_1'); | ||||
|         signatureZone = document.querySelector('#signature-zone'); | ||||
|   ; | ||||
|  | ||||
|     let | ||||
|         transitionFilterContainer = document.querySelector('#transitionFilter'), | ||||
|         transitions = document.querySelector('#transitions') | ||||
|       transitionFilterContainer = document.querySelector('#transitionFilter'), | ||||
|       transitionsContainer = document.querySelector('#transitions') | ||||
|     ; | ||||
|  | ||||
|     // ShowHide instance for signatureTypeChoices. This should always be present in the DOM and we toggle visibility. | ||||
|     // The field is not mapped and so not submitted with the form. Without it's presence upon DOM loading other show hides do not function well. | ||||
|     signatureTypeChoices.style.display = 'none'; | ||||
|  | ||||
|  | ||||
|     // ShowHide instance for future dest users | ||||
|     new ShowHide({ | ||||
|       debug: false, | ||||
|       load_event: null, | ||||
|       froms: [divTransitions], | ||||
|       container: [futureDestUsersContainer], | ||||
|       test: function(froms, event) { | ||||
|         for (let transition of froms) { | ||||
|           for (let input of transition.querySelectorAll('input')) { | ||||
|             if (input.checked) { | ||||
|               const inputData = JSON.parse(input.getAttribute('data-is-signature')) | ||||
|               if (inputData.includes('person') || inputData.includes('user')) { | ||||
|                 signatureTypeChoices.style.display = ''; | ||||
|                 return false; | ||||
|               } else { | ||||
|                 personChoice.checked = false | ||||
|                 userChoice.checked = false | ||||
|  | ||||
|                 signatureTypeChoices.style.display = 'none'; | ||||
|                 return true; | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|         return false; | ||||
|       } | ||||
|     }); | ||||
|  | ||||
|     // ShowHide signature zone | ||||
|     new ShowHide({ | ||||
|       debug: false, | ||||
|       load_event: null, | ||||
|       froms: [divTransitions], | ||||
|       container: [signatureZone], | ||||
|       test: function(froms, event) { | ||||
|         for (let transition of froms) { | ||||
|           for (let input of transition.querySelectorAll('input')) { | ||||
|             if (input.checked) { | ||||
|               const inputData = JSON.parse(input.getAttribute('data-is-signature')) | ||||
|               if (inputData.includes('person') || inputData.includes('user')) { | ||||
|                 signatureTypeChoices.style.display = ''; | ||||
|                 return true; | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|         return false; | ||||
|       } | ||||
|     }); | ||||
|  | ||||
|     // ShowHides for personSignatureField or userSignatureField within signature zone | ||||
|     new ShowHide({ | ||||
|       debug: false, | ||||
|       froms: [signatureTypeChoices], | ||||
|       container: [personSignatureField], | ||||
|       test: function(froms, event) { | ||||
|         for (let container of froms) { | ||||
|           return personChoice.checked; | ||||
|         } | ||||
|         return false; | ||||
|       }, | ||||
|     }); | ||||
|  | ||||
|     new ShowHide({ | ||||
|       debug: false, | ||||
|       froms: [signatureTypeChoices], | ||||
|       container: [userSignatureField], | ||||
|       test: function(froms, event) { | ||||
|         for (let container of froms) { | ||||
|           return userChoice.checked; | ||||
|         } | ||||
|         return false; | ||||
|       }, | ||||
|     }); | ||||
|  | ||||
|     if (null !== divTransitions) { | ||||
|       new ShowHide({ | ||||
|           load_event: null, | ||||
|           froms: [divTransitions], | ||||
|           container: [futureDestUsersContainer], | ||||
|           test: function(divs, arg2, arg3) { | ||||
|             for (let div of divs) { | ||||
|                   for (let input of div.querySelectorAll('input')) { | ||||
|                       if (input.checked) { | ||||
|                           if (input.dataset.toFinal === "1") { | ||||
|                               return false; | ||||
|                           } else { | ||||
|                               return true; | ||||
|                           } | ||||
|                       } | ||||
|                   } | ||||
|               } | ||||
|  | ||||
|               return true; | ||||
|           }, | ||||
|       }); | ||||
|     } | ||||
|  | ||||
|     if (null !== transitionFilterContainer) { | ||||
|         transitions.querySelectorAll('.form-check').forEach(function(row) { | ||||
|         transitionsContainer.querySelectorAll('.form-check').forEach(function(row) { | ||||
|  | ||||
|             const isForward = row.querySelector('input').dataset.isForward; | ||||
|  | ||||
| @@ -66,5 +152,4 @@ window.addEventListener('DOMContentLoaded', function() { | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
| }); | ||||
|   | ||||
| @@ -58,15 +58,34 @@ | ||||
|         {{ form_row(transition_form.transition) }} | ||||
|     </div> | ||||
|  | ||||
|     <div id="signature-zone"> | ||||
|         <div id="signature-type-choice"> | ||||
|             {{ form_row(transition_form.isPersonOrUserSignature) }} | ||||
|             {{ form_errors(transition_form.isPersonOrUserSignature) }} | ||||
|         </div> | ||||
|         <div id="user-signature-field"> | ||||
|             {{ form_row(transition_form.futureUserSignature) }} | ||||
|             {{ form_errors(transition_form.futureUserSignature) }} | ||||
|         </div> | ||||
|         <div id="person-signature-field"> | ||||
|             {{ form_row(transition_form.futurePersonSignatures) }} | ||||
|             {{ form_errors(transition_form.futurePersonSignatures) }} | ||||
|         </div> | ||||
|     </div> | ||||
|  | ||||
|     <div id="futureDests"> | ||||
|         <div id="future-dest-users"> | ||||
|         {{ form_row(transition_form.futureDestUsers) }} | ||||
|         {{ form_errors(transition_form.futureDestUsers) }} | ||||
|  | ||||
|         </div> | ||||
|         <div id="future-cc-users"> | ||||
|         {{ form_row(transition_form.futureCcUsers) }} | ||||
|         {{ form_errors(transition_form.futureCcUsers) }} | ||||
|  | ||||
|         </div> | ||||
|         <div id="future-dest-emails"> | ||||
|         {{ form_row(transition_form.futureDestEmails) }} | ||||
|         {{ form_errors(transition_form.futureDestEmails) }} | ||||
|         </div> | ||||
|     </div> | ||||
|  | ||||
|     <p>{{ form_label(transition_form.comment) }}</p> | ||||
|   | ||||
| @@ -536,6 +536,11 @@ workflow: | ||||
|             docType: Type de document | ||||
|             docNumber: Numéro de document | ||||
|             docExpiration: Date d'expiration | ||||
|         type of signature: Type de signature | ||||
|         person signatures: Selectionner usagers pour signer | ||||
|         user signature: Selectionner utilisateur pour signer | ||||
|         persons: Usagers | ||||
|         user: Utilisateur | ||||
|  | ||||
|  | ||||
| Subscribe final: Recevoir une notification à l'étape finale | ||||
|   | ||||
		Reference in New Issue
	
	Block a user