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 709-notification-eval-action
This commit is contained in:
commit
7349be94c8
6
.changes/header.tpl.md
Normal file
6
.changes/header.tpl.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# Changelog
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
|
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html),
|
||||||
|
and is generated by [Changie](https://github.com/miniscruff/changie).
|
0
.changes/unreleased/.gitkeep
Normal file
0
.changes/unreleased/.gitkeep
Normal file
7
.changes/unreleased/Feature-20230613-154903.yaml
Normal file
7
.changes/unreleased/Feature-20230613-154903.yaml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
kind: Feature
|
||||||
|
body: When navigating from a workflow regarding to an evaluation's document to an
|
||||||
|
accompanying course, scroll directly to the document, and blink to highlight this
|
||||||
|
document
|
||||||
|
time: 2023-06-13T15:49:03.663438985+02:00
|
||||||
|
custom:
|
||||||
|
Issue: ""
|
6
.changes/unreleased/Fixed-20230606-170742.yaml
Normal file
6
.changes/unreleased/Fixed-20230606-170742.yaml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
kind: Fixed
|
||||||
|
body: use the correct annotation for the association between PersonCurrentCenter and
|
||||||
|
Person
|
||||||
|
time: 2023-06-06T17:07:42.060486553+02:00
|
||||||
|
custom:
|
||||||
|
Issue: ""
|
5
.changes/unreleased/Fixed-20230613-155453.yaml
Normal file
5
.changes/unreleased/Fixed-20230613-155453.yaml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
kind: Fixed
|
||||||
|
body: Fix birthdate timezone in PersonRenderBox
|
||||||
|
time: 2023-06-13T15:54:53.125120559+02:00
|
||||||
|
custom:
|
||||||
|
Issue: "58"
|
677
.changes/v2.0.0.md
Normal file
677
.changes/v2.0.0.md
Normal file
@ -0,0 +1,677 @@
|
|||||||
|
## 2.0.0
|
||||||
|
|
||||||
|
* this is a release to relaunch our proceess of release with semantic versioning
|
||||||
|
|
||||||
|
## Test releases
|
||||||
|
|
||||||
|
### 2.0.0-beta3
|
||||||
|
|
||||||
|
* [person][export] Fixed: rename the alias for `accompanying_period` to `acp` in filter associated with person
|
||||||
|
* [activity][export] Feature: improve label for aliases in "Filter by activity type"
|
||||||
|
* [activity][export] DX/Feature: use of an `ActivityTypeRepositoryInterface` instead of the old-style EntityRepository
|
||||||
|
* [person][export] Fixed: some inconsistency with date filter on accompanying courses
|
||||||
|
* [person][export] Fixed: use left join for related entities in accompanying course aggregators
|
||||||
|
* [workflow] Feature: allow user to copy and send manually the access link for the workflow
|
||||||
|
* [workflow] Feature: show the email addresses that received an access link for the workflow
|
||||||
|
### 2.0.0-beta2
|
||||||
|
|
||||||
|
* [workflow]: Fixed: the notification is sent when the user is added to the first step.
|
||||||
|
* [budget] Feature: allow to desactivate some charges and resources, adding an `active` key in the configuration
|
||||||
|
* [person] Feature: on Evaluation, allow to configure an URL from the admin
|
||||||
|
|
||||||
|
### 2022-06
|
||||||
|
|
||||||
|
* [workflow]: added pagination to workflow list page
|
||||||
|
* [homepage_widget]: null error on tasks widget fixed
|
||||||
|
* [person-thirdparty]: fix quick-add of names that consist of multiple parts (eg. De Vlieger) within onthefly modal person/thirdparty
|
||||||
|
* [search]: Order of birthdate fields changed in advanced search to avoid confusion.
|
||||||
|
* [workflow]: Constraint added to workflow (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/675)
|
||||||
|
* [social_action]: only show active objectives (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/625)
|
||||||
|
* [household]: Reposition and cut button for enfant hors menage have been deleted (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/620)
|
||||||
|
* [admin]: Add crud for composition type in admin (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/611)
|
||||||
|
* [social_action]: only show active objectives (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/625)
|
||||||
|
|
||||||
|
## Test releases
|
||||||
|
|
||||||
|
### 2022-05-30
|
||||||
|
|
||||||
|
* fix creating a new AccompanyingPeriodWorkEvaluationDocument when replacing the document (the workflow was lost)
|
||||||
|
|
||||||
|
### 2022-05-27
|
||||||
|
|
||||||
|
* [storedobject] add title field on StoredObject entity + use it in activity documents (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/604)
|
||||||
|
* [main] add a "read more..." on comment embeddable when overflown (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/604)
|
||||||
|
* [person] add closing motive to closed acc course (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/603)
|
||||||
|
* [person] household filiation: fetch person info when unfolding person (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/586)
|
||||||
|
* [admin] repair edit of social action in the admin (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/601)
|
||||||
|
* [admin]: add select2 to Goal form type entity fields (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/702)
|
||||||
|
* [main] allow hide permissions group list menu (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/577)
|
||||||
|
* [main] allow hide change user password menu (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/577)
|
||||||
|
* [main] filter user jobs by active jobs (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/577)
|
||||||
|
* [main] add civility to User (entity, migration and form type) (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/577)
|
||||||
|
* [admin] refactorisation of the admin section: reorganisation of the menu, translations, form types, new entities (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/592)
|
||||||
|
* [admin] add admin section for languages and countries (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/596)
|
||||||
|
* [activity] activity admin: translations + remove label field for comment on admin activity type (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/587)
|
||||||
|
* [main] admin user_job: improvements (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/588)
|
||||||
|
* [address] can add extra address info even if noAddress (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/576)
|
||||||
|
|
||||||
|
|
||||||
|
### 2022-05-06
|
||||||
|
|
||||||
|
* [person] add civility when creating a person (with the on-the-fly component or in the php form) (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/557)
|
||||||
|
* [person] add address when creating a person (with the on-the-fly component or in the php form) (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/557)
|
||||||
|
* [person] add household creation API point (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/557)
|
||||||
|
|
||||||
|
### 2021-04-29
|
||||||
|
|
||||||
|
* [person] prevent circular references in PersonDocGenNormalizer (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/527)
|
||||||
|
* [person] add maritalStatusComment to PersonDocGenNormalizer (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/582)
|
||||||
|
* Load relationships without gender in french fixtures
|
||||||
|
* Add command to remove old draft accompanying periods
|
||||||
|
* [parcours]: If users assings him/herself as referrer and job is not null. Update parcours job (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/578)
|
||||||
|
|
||||||
|
### 2021-04-28
|
||||||
|
|
||||||
|
* [address] fix bug when editing address: update location and addressreferenceId + better update of the map in edition (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/593)
|
||||||
|
* [main] avoid address reference search on undefined post code (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/561)
|
||||||
|
* [person] prevent duplicate relationship in filiation/household graph (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/560)
|
||||||
|
* [Documents] Validate storedObject and allow for null data (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/565)
|
||||||
|
* [parcours]: Comments can be unpinned + edit/delete for all users that are allowed to edit parcours (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/566)
|
||||||
|
|
||||||
|
### 2021-04-26
|
||||||
|
|
||||||
|
* [Datepickers] datepickers fixed when using keyboard to enter date (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/545)
|
||||||
|
* [social_action] Display 'agents traitants' in parcours resumé and social action list (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/568)
|
||||||
|
* [Person_search] Closed parcours shown within an accordeon that can be opened/closed (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/574)
|
||||||
|
|
||||||
|
### 2021-04-24
|
||||||
|
|
||||||
|
* [notification email on course designation] allow raw string in email content generation
|
||||||
|
* [Accompanying period work] list evaluations associated to a work by startDate, and then by id, from the most recent to older
|
||||||
|
* [Documents] Change wording 'créer' to 'enregistrer' (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/634)
|
||||||
|
* [Parcours]: The number of 'mes parcours' displayed (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/572)
|
||||||
|
* [Hompage_widget]: Renaming of tabs and removal of social actions tab (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/570)
|
||||||
|
* [activity]: Ignore thirdparties when creating a social action via an activity (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/573)
|
||||||
|
* [parcours]: change wording of warning message and button when user is not associated to a household yet (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/590#note_918370943)
|
||||||
|
* [Accompanying period work evaluations] list documents associated to a work by creation date, and then by id, from the most recent to older
|
||||||
|
* [Course comment] add validationConstraint NotNull and NotBlank on comment content, to avoid sql error
|
||||||
|
* [Notifications] delay the sending of notificaiton to kernel.terminate
|
||||||
|
* [Notifications / Period user change] fix the sending of notification when user changes
|
||||||
|
* [Activity form] invert 'incoming' and 'receiving' in Activity form
|
||||||
|
* [Activity form] keep the same order for 'attendee' field in new and edit form
|
||||||
|
* [list with period] use "sameas" test operator to introduce requestor in list
|
||||||
|
* [notification email on course designation] allow raw string in email content generation
|
||||||
|
* [Accompanying period work] list evaluations associated to a work by startDate, and then by id, from the most recent to older
|
||||||
|
* [evaluation_document] changing date to datetime in order to display the time at which document was created (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/569)
|
||||||
|
|
||||||
|
|
||||||
|
### 2021-04-13
|
||||||
|
|
||||||
|
* [person] household address: add a form for editing the validFrom date (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/541)
|
||||||
|
* [person] householdmemberseditor: fix composition type bug in select form (vuejs) (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/543)
|
||||||
|
* [docgen] add more persons choices in docgen for course: amongst requestor (if person), resources of course (if person), and PersonResource (if person);
|
||||||
|
* [docgen] add a new context with a list of activities in course
|
||||||
|
* [docgen] add a comment in budget lines
|
||||||
|
* [notifications] allow to send a notification to an email address. The address receive an access link
|
||||||
|
* [adresses] add constraints in database to avoid errors later: postcode not null, and validfrom <= validto
|
||||||
|
* [accompanying work editor] add a label on document title input
|
||||||
|
|
||||||
|
### 2021-04-07
|
||||||
|
|
||||||
|
* notification list: move action buttons outside of the toggle
|
||||||
|
* fix detecting of non-read notification
|
||||||
|
* filter users which are disabled in search user api
|
||||||
|
* order query for location and add pagination in list
|
||||||
|
* allow every person which has part for a workflow to see the workflow page
|
||||||
|
* able to see the workflow if the evaluation document has been deleted
|
||||||
|
* hardcode the list of supported mime types for edition with collabora
|
||||||
|
* list of accompanying course: allow to see the pinned comment in list_item
|
||||||
|
|
||||||
|
### 2021-04-06
|
||||||
|
|
||||||
|
* [main] notification toggle read: correct js syntax for compilation in production (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/548)
|
||||||
|
* [parcours] Display of interlocuteurs changed to flex-table in parcours edit page to prevent cut-off of information (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/535)
|
||||||
|
* [activity] espace entre les boutons pour supprimer les documents
|
||||||
|
|
||||||
|
|
||||||
|
### continuous release in February and March
|
||||||
|
|
||||||
|
* Creation of PickCivilityType, and implementation in PersonType and ThirdpartyType
|
||||||
|
* [person] Accompanying course evaluation documents: disable the WOPI edit link if mimetype not supported and if no keyInfos
|
||||||
|
(https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/585)
|
||||||
|
* [activity] display error messages above the form in creating a new location (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/481)
|
||||||
|
* [activity] show required field in activity edit/new by an asterix in the vuejs fields (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/494)
|
||||||
|
* [ACL] fix allow to see the course, event if the scope'course does not contains the scope's user
|
||||||
|
* [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)
|
||||||
|
* [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)
|
||||||
|
* [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)
|
||||||
|
* [person] Add title to AccPeriodWorkEvaluationDocument (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/466)
|
||||||
|
* [person] Order social issues by the field "ordering" (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/388)
|
||||||
|
* [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)
|
||||||
|
* [budget]: budget enabled for persons and households (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/469)
|
||||||
|
* [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)
|
||||||
|
* [household] bugfix if position of member is null, renderbox no longer throws an error (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/480)
|
||||||
|
* [parcours] location cannot be removed if linked to a user (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/478)
|
||||||
|
* [person] email added to twig personRenderbox (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/490)
|
||||||
|
* [activity] Only youngest descendant is kept for social issues and actions (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/471)
|
||||||
|
* [person] Add link to current household in person banner (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/484)
|
||||||
|
* [address] person badge in address history changed to open OnTheFly with all person info (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/489)
|
||||||
|
* [person] Change 'personne' with 'usager' and '&' with 'ET' (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/499)
|
||||||
|
* [thirdparty] Add parameter condition to display centers or not (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/500)
|
||||||
|
* [phonenumber] Remove placeholder in phonenumber field (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/496)
|
||||||
|
* [person_resource] separate create page created to avoid confusion (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/504)
|
||||||
|
* [contact] add contact button color changed plus the pipe at the side removed (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/506)
|
||||||
|
* [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)
|
||||||
|
* [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)
|
||||||
|
* [filiation] Possible to add person (or create onthefly) to add to filiation graph + add relation (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/519)
|
||||||
|
* [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 + prevent personOwner themselves to be added. (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/526)
|
||||||
|
* [aside_activity] style correction + sticky-form create button (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/529)
|
||||||
|
* [budget] order within the menu adjusted (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/592)
|
||||||
|
* [onthefly] fix create person. Bug was noticed in filiation (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/591)
|
||||||
|
* [parcours] Create document buttons made sticky (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/532)
|
||||||
|
* [person] Trailing guillemet removed (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/530)
|
||||||
|
* [notification] Display of social action within workflow notification set to display block (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/537)
|
||||||
|
* [onthefly] trim trailing whitespace in email of person and thirdparty (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/542)
|
||||||
|
|
||||||
|
* [action] Only youngest descendant is kept for social issues and actions (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/471)
|
||||||
|
## Test releases
|
||||||
|
|
||||||
|
### test release 2022-02-21
|
||||||
|
|
||||||
|
* [notifications] Word 'un' changed to number '1' for notifications in user menu (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/483)
|
||||||
|
* [documents] 'gabarit' changed to 'modèle' (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/405)
|
||||||
|
* [person_resources] Menu name and order changed (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/460)
|
||||||
|
* workflow: fix sending notifications
|
||||||
|
* [thirdparty] Extend the thirdparty search to thirdparty children (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/448)
|
||||||
|
* [person]: AddPersons: allow creation of person or thirdparty only (no users) (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/422)
|
||||||
|
* [person]: AddPersons: allow creation of person or thirdparty depending on allowed types (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/422)
|
||||||
|
* [person]: AddPersons: add suggestion of name when creating new person or thirdparty (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/422)
|
||||||
|
* [main] Address: fix small bug: when modifying an address without street (isNoAddress), also check errors if street is an empty string as back-end change null value to empty string for street (and streetNumber)
|
||||||
|
* [main] Address: stronger client-side validation of addresses (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/449)
|
||||||
|
* [person] accompanying course: filter suggested entities by open participations (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/415)
|
||||||
|
[activity] can click through the cross icon for removing person in concerned group (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/476)
|
||||||
|
[activity] correct associated persons by considering only open participations (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/476)
|
||||||
|
* [person_resources]: Renderboxes used to display person/thirdparty info (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/465)
|
||||||
|
* [Household]: Add end date in HouseholdMember form for 'enfant hors menage' (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/434)
|
||||||
|
* [homepage_widget]: If no sender then display as 'notification automatique' (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/435)
|
||||||
|
* [parcours]: Order social activities and only display most recent three in parcours resumé (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/481)
|
||||||
|
* [3party]: 3party: redirect to parent when contact (child) is opened in view page
|
||||||
|
* [parcours / addresses]: launch an event when a person change address (either through changing household or because the household is associated to a new address). If the person is localising a course, the course location go back to a temporarily address.
|
||||||
|
* [thirdparty]: address/phonenumber/email/fonction displayed in thirdpartyrenderbox (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/401)
|
||||||
|
* [thirdparty_contact]: in search results the 'qualité' is displayed (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/465)
|
||||||
|
* [bug]: fix confidential toggle of address in thirdpartyrenderbox (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/460)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### test release 2022-02-14
|
||||||
|
|
||||||
|
* AddPersons: remove ul-li html tags from AddPersons (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/419)
|
||||||
|
* [doc-generator] do not set required fields for mainPerson, person1, person2 (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement#456)
|
||||||
|
* [doc-generation] add age and obele in the mainPerson, person1 and person2 list + add obele in person renderString if addAge (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/370)
|
||||||
|
* [person] accompanying course work: fix on-the-fly update of thirdParty
|
||||||
|
* fix normalisation of accompanying course requestor api (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/378)
|
||||||
|
* [person] add a returnPath when clicking on some Person or ThirdParty badge (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/427)
|
||||||
|
* [person] accompanying course work: fix on-the-fly update of thirdParty
|
||||||
|
* [on-the-fly] close modal only after validation
|
||||||
|
* [person] correct thirdparty PATCH url + add email and altnames in AddPerson and serializer (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/433)
|
||||||
|
* change order for accompanying course work list
|
||||||
|
* [parcours]: Mes parcours brouillon added to user menu (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/440)
|
||||||
|
* [Documents]: List view adapted to display more information (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/414)
|
||||||
|
* [person]: style fix in parcours listing per person. (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/432)
|
||||||
|
* [parcours]: Only the referrer can toggle the intensity of the parcours (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/442)
|
||||||
|
* [household]: display address of current household (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/415)
|
||||||
|
* ajoute un ordre dans les localisation (api)
|
||||||
|
* [pick entity]: fix translations in modal (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/419)
|
||||||
|
* [homepage_widget]: fix translation on emergency badge (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/440)
|
||||||
|
* [person]: create person and household added to button dropdown (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/454)
|
||||||
|
* display full address in address.text in normalization. Adapt AddressRenderBox
|
||||||
|
* [address]: Correction residential address 'depuis le' (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/459)
|
||||||
|
* [Documents]: List view adapted to display more information (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/414)
|
||||||
|
* [Thirdparty_contact]: address blurred if confidential in view page (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/450)
|
||||||
|
* [thirdparty] Add a contact to a thirdparty from within onTheFly (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/345)
|
||||||
|
|
||||||
|
|
||||||
|
### test release 2021-02-01
|
||||||
|
|
||||||
|
* renommer "dossier numéro" en "parcours numéro" dans les résultats de recherche
|
||||||
|
* renomme date de début en date d'ouverture dans le formulaire parcours
|
||||||
|
* [homepage widget] improve content tables, improve counter pluralization with style on number
|
||||||
|
* [notification lists] add comments counter information
|
||||||
|
* [workflows] fix popover header with previous transition
|
||||||
|
* [parcours]: validation + message for closing parcours adjusted.
|
||||||
|
* [household]: household composition double edit button replaced by a delete action (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/426)
|
||||||
|
[fast_actions] improve fast-actions buttons override mechanism, fix https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/413
|
||||||
|
[homepage widget] add vue homepage_widget with asynchone loading, give a global view resume of the user concerned actions, notifications, etc.
|
||||||
|
* [person]: Comment on marital status is possible even if marital status is not defined (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/421)
|
||||||
|
* [parcours]: In the list of person results the requestor is not displayed if defined as anonymous (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/424)
|
||||||
|
* [bugfix]: modal closes and newly created person/thirdparty is selected when multiple persons/thirdparties are created through the modal (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/429)
|
||||||
|
* [person_resource]: Onthefly button added to view person/thirdparty and badge differentiation for a contact-thirdparty (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/428)
|
||||||
|
* [workflow][notification] improve how notifications and workflows are 'attached' to entities: contextual list, counter, buttons and vue modal
|
||||||
|
* [AddAddress] disable multiselect search, and rely only on most pertinent Cities and Street computed backend
|
||||||
|
* [fast_actions] improve fast-actions buttons override mechanism, fix https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/413
|
||||||
|
* [homepage widget] add vue homepage_widget with asynchone loading, give a global view resume of the user concerned actions, notifications, etc.
|
||||||
|
* [thirdparty] Add a contact to a thirdparty from within onTheFly (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/345)
|
||||||
|
* [homepage widget] add vue homepage_widget with asynchone loading, give a global view resume of the user concerned actions, notifications, etc.
|
||||||
|
|
||||||
|
|
||||||
|
### test release 2021-01-31
|
||||||
|
|
||||||
|
* [person] accompanying course: optimisation: do not fetch some resources for the banner (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/409)
|
||||||
|
* [person] accompanying course: close modal when edit participation (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/420)
|
||||||
|
* [person] accompanying course: treat validation error when editing on-the-fly entities (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/420)
|
||||||
|
* [activity] show activity attendee (présence) in the activity list (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/412)
|
||||||
|
* [activity] admin: change validation rule for social action visible field (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/413)
|
||||||
|
* [parcours]: component added to change the opening date of a parcours (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/411)
|
||||||
|
* [search]: listing of parcours display changed (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/410)
|
||||||
|
* [user]: page with accompanying periods to which is user is referent (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/408)
|
||||||
|
* [person] age added to renderstring + renderbox/ vue component created to display person text (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/389)
|
||||||
|
* [household member editor] allow to push to existing household
|
||||||
|
|
||||||
|
|
||||||
|
### test release 2021-01-28
|
||||||
|
|
||||||
|
* [person] improve filiations vis graph: disable physics, use chill colors for persons-households-course, increase label of relations, remove labels on household arrows and other improvements (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/286, https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/362)
|
||||||
|
* [activity] Order activity by date and by id (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/364)
|
||||||
|
* [main] increase length of 4 Address fields (change to TEXT, no size limits) (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/277)
|
||||||
|
* [main] Add confidential option for address, in edit and view (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/165)
|
||||||
|
* [person] name suggestions within create person form when person is created departing from a search input (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/377)
|
||||||
|
* [person] Add residential address entity, form and list for each person
|
||||||
|
* [aside_activity]: dynamicUserPickerType used (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/399)
|
||||||
|
* dispatching list
|
||||||
|
|
||||||
|
|
||||||
|
### test release 2021-01-26
|
||||||
|
|
||||||
|
* [parcours] comments truncated if too long + link added (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/406)
|
||||||
|
* [person]: possibility to add person resources (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/382)
|
||||||
|
* [person ressources]: module added
|
||||||
|
|
||||||
|
|
||||||
|
### test release 2022-01-24
|
||||||
|
|
||||||
|
* [person] name suggestions within create person form when person is created departing from a search input (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/377)
|
||||||
|
* [notification: formulaire création] descend la box avec la description dans le bas du formulaire
|
||||||
|
* [notification for activity]: fix link to activity
|
||||||
|
* [notification] add "URGENT" before accompanying course with emergency = true
|
||||||
|
* [notification] add a "read more" button on system notification
|
||||||
|
* [notification] add `[Chill]` in the subject of each notification, automatically
|
||||||
|
* [notification] add a counter for notification in activity list and accompanying period list, and search results
|
||||||
|
* [parcours] bugfix if deathdate is not defined (eg. for a thirdparty) parcours is still displayed. Gave error before.
|
||||||
|
* [workflow] add breadcrumb to show steps
|
||||||
|
* [popover] add popover html popup mechanism (used by workflow breadcrumb)
|
||||||
|
* [templates] improve updatedBy macro in item metadatas
|
||||||
|
* [parcours]: bug fix when comment is pinned all other comments remain in the collection (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/385)
|
||||||
|
* [workflow]
|
||||||
|
* add My workflow section with my opened subscriptions
|
||||||
|
* apply workflow on documents, accompanyingCourseWork and Evaluations
|
||||||
|
* [wopi-link] a new vue component allow to open wopi link in a fullscreen chill-themed modal
|
||||||
|
|
||||||
|
### test release 2022-01-19
|
||||||
|
* vuejs: add dead information on all on-the-fly person render boxes, in vis graph and other templates (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/271)
|
||||||
|
* [thirdparty] fix bug in 3rd party view: types was replaced by thirdPartyTypes
|
||||||
|
* [main] location form type: fix unmapped address field (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/246)
|
||||||
|
* [activity] fix wrong import of js assets for adding and viewing documents in activity (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/83 & https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/176)
|
||||||
|
* [person]: space added between deathdate and age in twig renderbox (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/380)
|
||||||
|
* [forms] dynamic picker types for user/person/thirdparty types created (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/386)
|
||||||
|
|
||||||
|
### test release 2022-01-17
|
||||||
|
|
||||||
|
* [main] Add editableByUser field to locationType entity, adapt the admin template and add this condition in the location-type endpoint (see https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/297)
|
||||||
|
* [main] Add mainLocation field to User entity and add it in user form type
|
||||||
|
* rewrite page which allow to select activity
|
||||||
|
* [main] Add mainLocation field to User entity and add it in user form type
|
||||||
|
* [course list in person context] show full username/label for ref
|
||||||
|
* [accompanying period work] remove the possibility to generate document from an accompanying period work
|
||||||
|
* vuejs: add validation on required fields for AddPerson, Address and Location components
|
||||||
|
* vuejs: treat 422 validation errors in locations and AddPerson components
|
||||||
|
* [person]: space added between deathdate and age in twig renderbox (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/380)
|
||||||
|
|
||||||
|
## Test releases
|
||||||
|
* vuejs: add validation on required fields for AddPerson, Address and Location components
|
||||||
|
* vuejs: treat 422 validation errors in locations and AddPerson components
|
||||||
|
* [person]: space added between deathdate and age in twig renderbox (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/380)
|
||||||
|
|
||||||
|
### test release 2022-01-12
|
||||||
|
|
||||||
|
* fix thirdparty normalizer on telephone field: https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/322
|
||||||
|
|
||||||
|
### test release 2022-01-11
|
||||||
|
|
||||||
|
* vuejs: translate in French all multiselect widgets
|
||||||
|
* [address] define address lines according postal standards for France and Belgium (default) and change AddressRender, chill_entity_render_box and AddressRenderBox.vue
|
||||||
|
* [household] change translations (champs-libres/departement-de-la-vendee/accent-suivi-developpement#109)
|
||||||
|
* [household] add address i18n in household component (champs-libres/departement-de-la-vendee/accent-suivi-developpement#158)
|
||||||
|
* [household] add on the fly i18n in household component
|
||||||
|
* [household] redirect to the household page when a household is created from a person (champs-libres/departement-de-la-vendee/accent-suivi-developpement#175)
|
||||||
|
* [household] household member editor: display alert if some members have already an household (champs-libres/departement-de-la-vendee/accent-suivi-developpement#172)
|
||||||
|
* [household] household member editor: do not add in new members if the member is included in the members of household (champs-libres/departement-de-la-vendee/accent-suivi-developpement#123)
|
||||||
|
* [household] household member editor: remove markNoAddress button (champs-libres/departement-de-la-vendee/accent-suivi-developpement#109)
|
||||||
|
* [person]: ordering fields in add person (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/61)
|
||||||
|
* [person]: Add email and alt names in add person (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/61)
|
||||||
|
* [accompanyingCourse] Add a delete action and delete buttons to delete a accompanying course when step = DRAFT (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/64)
|
||||||
|
* [accompanyingCourse] Add a administrative location in the accompanying course, set the user current location as default, allow to select a location in a select field and do not allow to confirm the accompanying course if location is empty.
|
||||||
|
* [accompanyingCourse] Add the administrative location in the available variables for document generation
|
||||||
|
* AddAddress: optimize loading: wait for the user finish typing;
|
||||||
|
* UserPicker: fix bug with deprecated role
|
||||||
|
* docgen: add base context + tests
|
||||||
|
* docgen: add age for person
|
||||||
|
* [household menu] fix filiation order https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/265
|
||||||
|
* [AddAddress]: optimize loading: wait for the user finish typing;
|
||||||
|
* [UserPicker]: fix bug with deprecated role
|
||||||
|
* [docgen]: add base context + tests
|
||||||
|
* [docgen]: add age for person
|
||||||
|
* [task]: fix dropdown menu style + fix bug in singleTaskController (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/338)
|
||||||
|
* Household: fix bug when moving person on the same day (see https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/281)
|
||||||
|
* Household: show date validFrom and validTo when moving
|
||||||
|
* address reference: add index for refid
|
||||||
|
* [accompanyingCourse_work] fix styles conflicts + fix bug with remove goal (remove goals one at a time)
|
||||||
|
* [accompanyingCourse] improve masonry on resume page, add origin
|
||||||
|
* [notification] new notification interface, can be associated to AccompanyingCourse/Period, Activities.
|
||||||
|
* List notifications, show, and comment in User section
|
||||||
|
* Notify button and contextual notification box on associated objects pages
|
||||||
|
* [accompanyingCourse] add a comment for each resource associated. A modal allow to save comment. Comment is displayed in on-the-fly show modal of the accompanyingCourse context (edit page + resume page).
|
||||||
|
|
||||||
|
### test release 2021-12-14
|
||||||
|
|
||||||
|
* [asideactivity] creation of aside activity category fixed (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/262)
|
||||||
|
* [vendee/person] fix typo "situation professionelle" => "situation professionnelle"
|
||||||
|
* [main] add availableForUsers condition from locationType in the location API endpoint (champs-libres/departement-de-la-vendee/accent-suivi-developpement#248)
|
||||||
|
* [main] add the current location of the user as API point + add it in the activity location list (champs-libres/departement-de-la-vendee/accent-suivi-developpement#247)
|
||||||
|
* [activity] improve show/new/edit templates, fix SEE and SEE_DETAILS acl
|
||||||
|
* [badges] create specific badge for TMS, and make person/thirdparty badges clickable with on-the-fly modal in :
|
||||||
|
* concerned groups items (activity, calendar)
|
||||||
|
* accompanyingCourseWork lists
|
||||||
|
* accompanyingCourse lists
|
||||||
|
* [acompanyingCourse] add initial comment on Resume page
|
||||||
|
* [person] create button full width (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/330)
|
||||||
|
|
||||||
|
### test release 2021-12-11
|
||||||
|
|
||||||
|
* [main] add order field to civility
|
||||||
|
* [main] change address format in case the country is France, in Address render box and address normalizer
|
||||||
|
* [person] add validator for accompanying period with a test on social issues (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/76)
|
||||||
|
* [activity] fix visibility for location
|
||||||
|
* [origin] fix origin: use correctly the translatable strings
|
||||||
|
* /!\ everyone must update the origin table. As there is only one row, execute `update chill_person_accompanying_period_origin set label = jsonb_build_object('fr', 'appel téléphonique');`
|
||||||
|
* [person] redirect bug fixed.
|
||||||
|
* [action] add an unrelated issue within action creation.
|
||||||
|
* [origin] fix origin: use correctly the translatable strings
|
||||||
|
* /!\ everyone must update the origin table. As there is only one row, execute `update chill_person_accompanying_period_origin set label = jsonb_build_object('fr', 'appel téléphonique');`
|
||||||
|
* [main] change order of civilities in civility fixtures (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/191)
|
||||||
|
* [person] set min attr in the minimum of children field (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/191)
|
||||||
|
* [person] add marital status date in person view (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/191)
|
||||||
|
* [person] show number of children + allow set number of children to null (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/191)
|
||||||
|
* [person] show acceptSMS option (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/191)
|
||||||
|
* [person] add death information in person render box in twig and vue render boxes (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/191)
|
||||||
|
* [asideactivity] creation of aside activity category fixed (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/262)
|
||||||
|
* [vendee/person] fix typo "situation professionelle" => "situation professionnelle"
|
||||||
|
* [accompanyingcourse_work] Changes in layout/behavior of edit form (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/321)
|
||||||
|
* [badge-entity] design coherency between pills badge-person and 3 kinds of badge-thirdparty
|
||||||
|
* [AddPersons] suggestions row are clickable, not only checkbox
|
||||||
|
|
||||||
|
### test release 2021-12-06
|
||||||
|
|
||||||
|
* [main] address: use search API end points for getting postal code and reference address (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/316)
|
||||||
|
* [main] address: in edit mode, select the encoded values in multiselect for address reference and city (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/316)
|
||||||
|
* [person search] fix bug when using birthdate after and birthdate before
|
||||||
|
* [person search] increase pertinence when lastname begins with search pattern
|
||||||
|
* [activity/actions] Améliore la cohérence du design entre
|
||||||
|
* la page résumé d'un parcours (liste d'actions récentes et liste d'activités récentes)
|
||||||
|
* la page liste des actions
|
||||||
|
* la page liste des activités (contexte personne / contexte parcours)
|
||||||
|
* [household] field to edit wheter person is titulaire of household or not removed (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/322)
|
||||||
|
* [activity] create work if a work with same social action is not associated to the activity
|
||||||
|
* [visgraph] improve and fix bugs on vis-network relationship graph
|
||||||
|
* [bugfix] posting of birth- and deathdate through api fixed.
|
||||||
|
* [suggestions] improve suggestions lists
|
||||||
|
|
||||||
|
### Test release 2021-11-19 - bis
|
||||||
|
|
||||||
|
* [household] do not allow to create two addresses on the same date
|
||||||
|
* [activity] handle case when there is no social action associated to social issue
|
||||||
|
* [activity] layout for issues / actions
|
||||||
|
* [activity][bugfix] in edit mode, the form will now load the social action list
|
||||||
|
|
||||||
|
|
||||||
|
### Test release 2021-11-29
|
||||||
|
|
||||||
|
* [person] suggest entities (person | thirdparty) when creating/editing the accompanying course (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/119)
|
||||||
|
* [activity] add custom validation on the Activity class, based on what is required from the ActivityType (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/188)
|
||||||
|
* [main] translate multiselect messages when selecting/creating address
|
||||||
|
* [main] set the coordinates of the city when creating a new address OR choosing "pas d'adresse complète"
|
||||||
|
* Use the user.label in accompanying course banner, instead of username;
|
||||||
|
* fix: show validation message when closing accompanying course;
|
||||||
|
* [thirdparty] link from modal to thirdparty detail page fixed (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/228)
|
||||||
|
* [assets] new asset to style suggestions lists (with add/remove item link) (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/258)
|
||||||
|
* [accompanyingCourseWorkEdit] improves hyphenation and line breaks for long badges
|
||||||
|
* [acompanyingCourse] improve Resume page
|
||||||
|
* complete all needed informations,
|
||||||
|
* actions and activities are clickables,
|
||||||
|
* better placement with js masonry blocks on top of content area,
|
||||||
|
* https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/101
|
||||||
|
* https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/295
|
||||||
|
* [activity/calendar] on show page, concerned groups of persons table adapt itself to isVisibles options
|
||||||
|
* [activity] remove the "plus" button in activity list
|
||||||
|
* [activity] check ACL on activity list in person context
|
||||||
|
* [list for accompanying course in person] filter list using ACL
|
||||||
|
* [validation] toasts are displayed for errors when modifying accompanying course (generalization required).
|
||||||
|
* [period] only the user can enable confidentiality
|
||||||
|
* add an endpoint for checking permissions. See https://gitlab.com/Chill-Projet/chill-bundles/-/merge_requests/232
|
||||||
|
* [activity] for a new activity: suggest and create on-the-fly locations based on the accompanying course location + location of the suggested parties
|
||||||
|
* [calendar] for a new rdv: suggest and create on-the-fly locations based on the accompanying course location + location of the suggested parties
|
||||||
|
* [period] Validation added when period is confidential and confirmed -> user cannot be null.
|
||||||
|
|
||||||
|
|
||||||
|
## Test releases
|
||||||
|
|
||||||
|
### Test release 2021-11-22
|
||||||
|
|
||||||
|
* [activity] delete admin_user_show in twig template because this route is not defined and should be defined
|
||||||
|
* [activity] suggest requestor, user and ressources for adding persons|user|3rdparty
|
||||||
|
* [calendar] suggest persons, professionals and invites for adding persons|3rdparty|user
|
||||||
|
* [activity] take into account the restrictions on person|thirdparties|users visibilities defined in ActivityType
|
||||||
|
* [main] Add currentLocation to the User entity + add a page for selecting this location + add in the user menu (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/133)
|
||||||
|
* [activity] add user current location as default location for a new activity (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/133)
|
||||||
|
* [task] Select2 field in task form to allow search for a user (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/167)
|
||||||
|
* remove "search by phone configuration option": search by phone is now executed by default
|
||||||
|
* remplacer le classement par ordre alphabétique par un classement par ordre de pertinence, qui tient compte:
|
||||||
|
* de la présence d'une string avec le nom de la ville;
|
||||||
|
* de la similarité;
|
||||||
|
* du fait que la recherche commence par une partie du mot recherché
|
||||||
|
* ajouter la recherche par numéro de téléphone directement dans la barre de recherche et dans le formulaire recherche avancée;
|
||||||
|
* ajouter la recherche par date de naissance directement dans la barre de recherche;
|
||||||
|
* ajouter la recherche par ville dans la recherche avancée
|
||||||
|
* ajouter un lien vers le ménage dans les résultats de recherche
|
||||||
|
* ajouter l'id du parcours dans les résultats de recherche
|
||||||
|
* ajouter le demandeur dans les résultats de recherche
|
||||||
|
* ajout d'un bouton "recherche avancée" sur la page d'accueil
|
||||||
|
* [person] create an accompanying course: add client-side validation if no origin (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/210)
|
||||||
|
* [person] fix bounds for computing current person address: the new address appears immediatly
|
||||||
|
* [docgen] create a normalizer and serializer for normalization on doc format
|
||||||
|
* [person normalization] the key center is now "centers" and is an array. Empty array if no center
|
||||||
|
* [accompanyingCourse] Ability to close accompanying course (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/296)
|
||||||
|
* [task] Select2 field in task form to allow search for a user (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/167)
|
||||||
|
* [list result] show all courses, except ones with period closed
|
||||||
|
* [accompanyingCourse] improve banner with small carousel to display slide social-issues or slide associated persons (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/69)
|
||||||
|
|
||||||
|
### Test release 2021-11-15
|
||||||
|
|
||||||
|
* [main] fix adding multiple AddresseDeRelais (combine PickAddressType with ChillCollection)
|
||||||
|
* [person]: do not suggest the current household of the person (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/51)
|
||||||
|
* [person]: display other phone numbers in view + add message in case no others phone numbers (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/184)
|
||||||
|
* unnecessary whitespace removed from person banner after person-id + double parentheses removed (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/290)
|
||||||
|
* [person]: delete accompanying period work, including related objects (cascade) (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/36)
|
||||||
|
* [address]: Display of incomplete address adjusted.
|
||||||
|
* [household]: improve relationship graph
|
||||||
|
* add form to create/edit/delete relationship link,
|
||||||
|
* improve graph refresh mechanism
|
||||||
|
* add feature to export canvas as image (png)
|
||||||
|
* [person suggest] In widget "add person", improve the pertinence of persons when one of the names starts with the pattern;
|
||||||
|
* [person] do not ask for center any more on person creation
|
||||||
|
* [3party] do not ask for center any more on 3party creation
|
||||||
|
|
||||||
|
## Test releases
|
||||||
|
|
||||||
|
### Test release 2021-11-08
|
||||||
|
|
||||||
|
* [person]: Display the name of a user when searching after a User (TMS)
|
||||||
|
* [person]: Add civility to the person
|
||||||
|
* [person]: Various improvements on the edit person form
|
||||||
|
* [person]: Set available_languages and available_countries as parameters for use in the edit person form
|
||||||
|
* [activity] Bugfix: documents can now be added to an activity.
|
||||||
|
* [tasks] improve tasks with filter order
|
||||||
|
* [tasks] refactor singleControllerTasks: limit the number of conditions from the context
|
||||||
|
* [validations] validation of accompanying period added: no duplicate participations or resources (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/60).
|
||||||
|
* [renderbox] If gender of person is not defined, no icon is displayed instead of neuter-icon (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/129).
|
||||||
|
* [confidential information] module added to blur confidential information (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/248).
|
||||||
|
* refactor `AuthorizationHelper` and `UserACLAwareRepository` to fix constructor, and separate logic for parent role helper into `ParentRoleHelper`
|
||||||
|
* [main]: filter location and locationType in backend: exclude NULL names, only active and availableToUsers
|
||||||
|
* [activity]: perform client-side validation & show/hide fields in the "new location" modal
|
||||||
|
* [person]: normalize person with CenterResolverDispatcher and handle case where center is null or multiple in PersonRenderBox
|
||||||
|
* [docstore] voter for PersonDocument and AccompanyingCourseDocument on the 2.0 way (using VoterHelperFactory)
|
||||||
|
* [docstore] add authorization check inside controller and menu
|
||||||
|
* [activity]: fix inheritance for role `ACTIVITY FULL` and add missing acl in menu
|
||||||
|
* [person] show current address in search results
|
||||||
|
* [person] show alt names in search results
|
||||||
|
* [admin]: links to activity admin section added again.
|
||||||
|
* [household]: endDate field deleted from household edit form.
|
||||||
|
* [household]: View accompanying periods of current and old household members.
|
||||||
|
* [tasks]: different layout for task list / my tasks, and fix link to tasks in alert or in warning
|
||||||
|
* [admin]: links to activity admin section added again.
|
||||||
|
* [household]: household addresses ordered by ValidFrom date and by id to show the last created address on top.
|
||||||
|
* [socialWorkAction]: display of social issue and parent issues + banner context added.
|
||||||
|
* [DBAL dependencies] Upgrade to DBAL 3.1
|
||||||
|
|
||||||
|
### Test release 2021-10-27
|
||||||
|
|
||||||
|
* [person]: delete double actions buttons on search person page
|
||||||
|
* [person]: accompanying course work: remove creation date display the list of work + handle case when end date is null
|
||||||
|
* [main]: Add new pages with a menu for managing location and location type in the admin
|
||||||
|
* [main]: Add some fixtures for location type
|
||||||
|
* [calendar]: Pass the location when transforming a calendar item (rdv) into an activity
|
||||||
|
* [calendar]: Add a user menu for "my calendar"
|
||||||
|
|
||||||
|
### Test release 2021-10-18
|
||||||
|
|
||||||
|
* [3party]: french translation of contact and company
|
||||||
|
* [3party]: show parent in list
|
||||||
|
* [3party]: change color for badge "child"
|
||||||
|
* [3party]: fix address creation
|
||||||
|
* [household members editor] finalisation of editor
|
||||||
|
* [AccompanyingCourse banner]: replace translation referrer (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/70)
|
||||||
|
* [Location]: add location system in activity and RV (calendar). User can choose in location list or create a new location.
|
||||||
|
* [household]: add relationship page with dynamic data visualisation graph
|
||||||
|
|
||||||
|
## Test releases
|
||||||
|
|
||||||
|
### Test release 2021-10-11
|
||||||
|
|
||||||
|
* Address: zoom on postal code geometry + fix origin of manually entered postal code
|
||||||
|
|
||||||
|
* in the Address vue component, order the postal code and street address by alphabetic and numeric order
|
||||||
|
|
||||||
|
* add 3 new fields to PostalCode and adapt postal code command and fixtures
|
||||||
|
|
||||||
|
* [Aside activity] Fixes for aside activity
|
||||||
|
|
||||||
|
* categories with child
|
||||||
|
* fast creation buttons
|
||||||
|
* add ordering for types
|
||||||
|
|
||||||
|
* [AccompanyingCourse Resume page] dashboard for AccompanyingCourseWork and for Activities;
|
||||||
|
* Improve badges behaviour with small screens;
|
||||||
|
|
||||||
|
* [ThirdParty]:
|
||||||
|
|
||||||
|
* third party list
|
||||||
|
* create a kind contact/institution when create a new thirdparty, and set contact embedded as kind=child;
|
||||||
|
* filter thirdparties in list
|
||||||
|
|
||||||
|
* [FilterOrder]: add development kit for generating filter and ordering in list
|
||||||
|
* [Capitalization of names] person names are capitalized on creation, on prePersist event
|
||||||
|
* [On-The-Fly] modale works for showing, editing and creating person or thirdparty ;
|
||||||
|
* [AccompanyingCourse Resume page] associated persons list, can see household when hover, and with show on-the-fly modale when clicking person ;
|
||||||
|
|
||||||
|
### test release 2021-10-04
|
||||||
|
|
||||||
|
* [Household editor][UI] Update how household suggestion and addresses are picked;
|
||||||
|
|
||||||
|
See https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/80
|
||||||
|
* [AddAddress] Handle address suggestion;
|
||||||
|
* [CenterType][Create a person] when overriding the ACL rules, allow to show a PickCenterType
|
||||||
|
when no centers are reachable by the default ACL.
|
||||||
|
* [Household] Show comment event if no address are associated with the household;
|
||||||
|
* [Person results] Add requestor into search results:
|
||||||
|
|
||||||
|
* a badge "requestor" is shown into search results;
|
||||||
|
* periods where the person is only requestor (without participating) are also shown;
|
||||||
|
|
||||||
|
Issues:
|
||||||
|
|
||||||
|
* https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/13
|
||||||
|
* https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/199
|
||||||
|
* [Person form] "accept sms" not required:
|
||||||
|
|
||||||
|
https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/37
|
||||||
|
https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/221
|
||||||
|
|
||||||
|
* [Household editor] suggest only temporarily addresses;
|
||||||
|
See https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/82
|
||||||
|
* On-The-Fly modale works for showing, editing and creating person and thirdparty ;
|
||||||
|
* AccompanyingCourse Resume page: list associated persons by household, see household when hover, and show on-the-fly modale when clicking on person ;
|
||||||
|
* [AddAddress] Handle address suggestion;
|
||||||
|
* [AddAddress][Entity address]: add a link between address and address reference;
|
||||||
|
* [Household editor] suggest household by comparing the temporary addresses from courses;
|
||||||
|
|
||||||
|
See https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/81
|
||||||
|
* On-The-Fly modale works for showing, editing and creating person and thirdparty
|
||||||
|
|
||||||
|
|
||||||
|
## Test released
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
Coming soon...
|
||||||
|
|
||||||
|
DO NOT ADD unreleased items here. Add them under "Unreleased" title
|
||||||
|
|
||||||
|
### Test release yyyy-mm-dd
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
## Stable releases
|
||||||
|
|
||||||
|
No stable releases for v2+
|
||||||
|
|
17
.changes/v2.1.0.md
Normal file
17
.changes/v2.1.0.md
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
## v2.1.0 - 2023-06-12
|
||||||
|
|
||||||
|
### Feature
|
||||||
|
|
||||||
|
* [docgen] allow to pick a third party when generating a document in context Activity, AccompanyingPeriod
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
* ([#111](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/111)) List of "my accompanying periods": separate the active and closed periods in two different lists, and show the inactive_long and inactive_short periods
|
||||||
|
|
||||||
|
### Security
|
||||||
|
|
||||||
|
* ([#105](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/105)) Rights are checked for display of 'accompanying period' tab in household menu. Rights are also checked for creation of 'accompanying period' from within household context
|
||||||
|
|
||||||
|
### DX
|
||||||
|
|
||||||
|
* Add methods to RegroupmentRepository and fullfill Center / Regroupment Doctrine mapping
|
34
.changie.yaml
Normal file
34
.changie.yaml
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
changesDir: .changes
|
||||||
|
unreleasedDir: unreleased
|
||||||
|
headerPath: header.tpl.md
|
||||||
|
changelogPath: CHANGELOG.md
|
||||||
|
versionExt: md
|
||||||
|
versionFormat: '## {{.Version}} - {{.Time.Format "2006-01-02"}}'
|
||||||
|
kindFormat: '### {{.Kind}}'
|
||||||
|
changeFormat: >-
|
||||||
|
* {{ if not (eq .Custom.Issue "") }}([#{{ .Custom.Issue }}](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/{{ .Custom.Issue }})) {{- end }}{{.Body}}
|
||||||
|
custom:
|
||||||
|
- key: Issue
|
||||||
|
label: Issue number (on chill-bundles repository) (optional)
|
||||||
|
optional: true
|
||||||
|
type: int
|
||||||
|
minInt: 1
|
||||||
|
body:
|
||||||
|
# allow multiline messages
|
||||||
|
block: true
|
||||||
|
kinds:
|
||||||
|
- label: Feature
|
||||||
|
auto: minor
|
||||||
|
- label: Deprecated
|
||||||
|
auto: minor
|
||||||
|
- label: Fixed
|
||||||
|
auto: patch
|
||||||
|
- label: Security
|
||||||
|
auto: patch
|
||||||
|
- label: DX
|
||||||
|
auto: patch
|
||||||
|
newlines:
|
||||||
|
afterChangelogHeader: 1
|
||||||
|
beforeChangelogVersion: 1
|
||||||
|
endOfVersion: 1
|
||||||
|
envPrefix: CHANGIE_
|
36
CHANGELOG.md
36
CHANGELOG.md
@ -1,16 +1,37 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to
|
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html),
|
||||||
|
and is generated by [Changie](https://github.com/miniscruff/changie).
|
||||||
|
|
||||||
* [Semantic Versioning](https://semver.org/spec/v2.0.0.html) for stable releases;
|
|
||||||
* date versioning for test releases
|
|
||||||
|
|
||||||
## Unreleased
|
## v2.1.0 - 2023-06-12
|
||||||
|
|
||||||
|
### Feature
|
||||||
|
|
||||||
|
* [docgen] allow to pick a third party when generating a document in context Activity, AccompanyingPeriod
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
* ([#111](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/111)) List of "my accompanying periods": separate the active and closed periods in two different lists, and show the inactive_long and inactive_short periods
|
||||||
|
|
||||||
|
### Security
|
||||||
|
|
||||||
|
* ([#105](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/105)) Rights are checked for display of 'accompanying period' tab in household menu. Rights are also checked for creation of 'accompanying period' from within household context
|
||||||
|
|
||||||
|
### DX
|
||||||
|
|
||||||
|
* Add methods to RegroupmentRepository and fullfill Center / Regroupment Doctrine mapping
|
||||||
|
|
||||||
|
## 2.0.0
|
||||||
|
|
||||||
|
* this is a release to relaunch our proceess of release with semantic versioning
|
||||||
|
|
||||||
|
## Test releases
|
||||||
|
|
||||||
|
### 2.0.0-beta3
|
||||||
|
|
||||||
<!-- write down unreleased development here -->
|
|
||||||
* [person][export] Fixed: rename the alias for `accompanying_period` to `acp` in filter associated with person
|
* [person][export] Fixed: rename the alias for `accompanying_period` to `acp` in filter associated with person
|
||||||
* [activity][export] Feature: improve label for aliases in "Filter by activity type"
|
* [activity][export] Feature: improve label for aliases in "Filter by activity type"
|
||||||
* [activity][export] DX/Feature: use of an `ActivityTypeRepositoryInterface` instead of the old-style EntityRepository
|
* [activity][export] DX/Feature: use of an `ActivityTypeRepositoryInterface` instead of the old-style EntityRepository
|
||||||
@ -18,9 +39,6 @@ and this project adheres to
|
|||||||
* [person][export] Fixed: use left join for related entities in accompanying course aggregators
|
* [person][export] Fixed: use left join for related entities in accompanying course aggregators
|
||||||
* [workflow] Feature: allow user to copy and send manually the access link for the workflow
|
* [workflow] Feature: allow user to copy and send manually the access link for the workflow
|
||||||
* [workflow] Feature: show the email addresses that received an access link for the workflow
|
* [workflow] Feature: show the email addresses that received an access link for the workflow
|
||||||
|
|
||||||
## Test releases
|
|
||||||
|
|
||||||
### 2.0.0-beta2
|
### 2.0.0-beta2
|
||||||
|
|
||||||
* [workflow]: Fixed: the notification is sent when the user is added to the first step.
|
* [workflow]: Fixed: the notification is sent when the user is added to the first step.
|
||||||
|
@ -26,12 +26,12 @@ final class PersonMenuBuilder implements LocalMenuBuilderInterface
|
|||||||
/**
|
/**
|
||||||
* @var AuthorizationCheckerInterface
|
* @var AuthorizationCheckerInterface
|
||||||
*/
|
*/
|
||||||
protected $authorizationChecker;
|
private $authorizationChecker;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var TranslatorInterface
|
* @var TranslatorInterface
|
||||||
*/
|
*/
|
||||||
protected $translator;
|
private $translator;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
AuthorizationCheckerInterface $authorizationChecker,
|
AuthorizationCheckerInterface $authorizationChecker,
|
||||||
|
@ -24,6 +24,9 @@ use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
|||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
use Chill\PersonBundle\Repository\PersonRepository;
|
use Chill\PersonBundle\Repository\PersonRepository;
|
||||||
use Chill\PersonBundle\Templating\Entity\PersonRenderInterface;
|
use Chill\PersonBundle\Templating\Entity\PersonRenderInterface;
|
||||||
|
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||||
|
use Chill\ThirdPartyBundle\Templating\Entity\ThirdPartyRender;
|
||||||
|
use Chill\ThirdPartyBundle\Repository\ThirdPartyRepository;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||||
@ -55,6 +58,10 @@ class ActivityContext implements
|
|||||||
|
|
||||||
private TranslatorInterface $translator;
|
private TranslatorInterface $translator;
|
||||||
|
|
||||||
|
private ThirdPartyRender $thirdPartyRender;
|
||||||
|
|
||||||
|
private ThirdPartyRepository $thirdPartyRepository;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
DocumentCategoryRepository $documentCategoryRepository,
|
DocumentCategoryRepository $documentCategoryRepository,
|
||||||
NormalizerInterface $normalizer,
|
NormalizerInterface $normalizer,
|
||||||
@ -63,7 +70,9 @@ class ActivityContext implements
|
|||||||
PersonRenderInterface $personRender,
|
PersonRenderInterface $personRender,
|
||||||
PersonRepository $personRepository,
|
PersonRepository $personRepository,
|
||||||
TranslatorInterface $translator,
|
TranslatorInterface $translator,
|
||||||
BaseContextData $baseContextData
|
BaseContextData $baseContextData,
|
||||||
|
ThirdPartyRender $thirdPartyRender,
|
||||||
|
ThirdPartyRepository $thirdPartyRepository
|
||||||
) {
|
) {
|
||||||
$this->documentCategoryRepository = $documentCategoryRepository;
|
$this->documentCategoryRepository = $documentCategoryRepository;
|
||||||
$this->normalizer = $normalizer;
|
$this->normalizer = $normalizer;
|
||||||
@ -73,6 +82,8 @@ class ActivityContext implements
|
|||||||
$this->personRepository = $personRepository;
|
$this->personRepository = $personRepository;
|
||||||
$this->translator = $translator;
|
$this->translator = $translator;
|
||||||
$this->baseContextData = $baseContextData;
|
$this->baseContextData = $baseContextData;
|
||||||
|
$this->thirdPartyRender = $thirdPartyRender;
|
||||||
|
$this->thirdPartyRepository = $thirdPartyRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function adminFormReverseTransform(array $data): array
|
public function adminFormReverseTransform(array $data): array
|
||||||
@ -89,6 +100,8 @@ class ActivityContext implements
|
|||||||
'person1Label' => $data['person1Label'] ?? $this->translator->trans('docgen.person 1'),
|
'person1Label' => $data['person1Label'] ?? $this->translator->trans('docgen.person 1'),
|
||||||
'person2' => $data['person2'] ?? false,
|
'person2' => $data['person2'] ?? false,
|
||||||
'person2Label' => $data['person2Label'] ?? $this->translator->trans('docgen.person 2'),
|
'person2Label' => $data['person2Label'] ?? $this->translator->trans('docgen.person 2'),
|
||||||
|
'thirdParty' => $data['thirdParty'] ?? false,
|
||||||
|
'thirdPartyLabel' => $data['thirdPartyLabel'] ?? $this->translator->trans('thirdParty'),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,6 +131,14 @@ class ActivityContext implements
|
|||||||
->add('person2Label', TextType::class, [
|
->add('person2Label', TextType::class, [
|
||||||
'label' => 'person 2 label',
|
'label' => 'person 2 label',
|
||||||
'required' => true,
|
'required' => true,
|
||||||
|
])
|
||||||
|
->add('thirdParty', CheckboxType::class, [
|
||||||
|
'required' => false,
|
||||||
|
'label' => 'docgen.Ask for thirdParty',
|
||||||
|
])
|
||||||
|
->add('thirdPartyLabel', TextType::class, [
|
||||||
|
'label' => 'docgen.thirdParty label',
|
||||||
|
'required' => true,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,6 +164,20 @@ class ActivityContext implements
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$thirdParties = $entity->getThirdParties();
|
||||||
|
if ($options['thirdParty'] ?? false) {
|
||||||
|
$builder->add('thirdParty', EntityType::class, [
|
||||||
|
'class' => ThirdParty::class,
|
||||||
|
'choices' => $thirdParties,
|
||||||
|
'choice_label' => fn (ThirdParty $p) => $this->thirdPartyRender->renderString($p, []),
|
||||||
|
'multiple' => false,
|
||||||
|
'required' => false,
|
||||||
|
'expanded' => true,
|
||||||
|
'label' => $options['thirdPartyLabel'],
|
||||||
|
'placeholder' => $this->translator->trans('Any third party selected'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function contextGenerationDataDenormalize(DocGeneratorTemplate $template, $entity, array $data): array
|
public function contextGenerationDataDenormalize(DocGeneratorTemplate $template, $entity, array $data): array
|
||||||
@ -157,6 +192,12 @@ class ActivityContext implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (null !== ($id = ($data['thirdParty'] ?? null))) {
|
||||||
|
$denormalized['thirdParty'] = $this->thirdPartyRepository->find($id);
|
||||||
|
} else {
|
||||||
|
$denormalized['thirdParty'] = null;
|
||||||
|
}
|
||||||
|
|
||||||
return $denormalized;
|
return $denormalized;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,9 +206,11 @@ class ActivityContext implements
|
|||||||
$normalized = [];
|
$normalized = [];
|
||||||
|
|
||||||
foreach (['mainPerson', 'person1', 'person2'] as $k) {
|
foreach (['mainPerson', 'person1', 'person2'] as $k) {
|
||||||
$normalized[$k] = null === $data[$k] ? null : $data[$k]->getId();
|
$normalized[$k] = ($data[$k] ?? null)?->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$normalized['thirdParty'] = ($data['thirdParty'] ?? null)?->getId();
|
||||||
|
|
||||||
return $normalized;
|
return $normalized;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,6 +239,13 @@ class ActivityContext implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($options['thirdParty']) {
|
||||||
|
$data['thirdParty'] = $this->normalizer->normalize($contextGenerationData['thirdParty'], 'docgen', [
|
||||||
|
'docgen:expects' => ThirdParty::class,
|
||||||
|
'groups' => 'docgen:read'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,7 +285,7 @@ class ActivityContext implements
|
|||||||
{
|
{
|
||||||
$options = $template->getOptions();
|
$options = $template->getOptions();
|
||||||
|
|
||||||
return $options['mainPerson'] || $options['person1'] || $options['person2'];
|
return $options['mainPerson'] || $options['person1'] || $options['person2'] || $options ['thirdParty'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function storeGenerated(DocGeneratorTemplate $template, StoredObject $storedObject, object $entity, array $contextGenerationData): void
|
public function storeGenerated(DocGeneratorTemplate $template, StoredObject $storedObject, object $entity, array $contextGenerationData): void
|
||||||
|
@ -140,26 +140,36 @@ class ListActivitiesByAccompanyingPeriodContext implements
|
|||||||
return $normalized;
|
return $normalized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return list
|
||||||
|
*/
|
||||||
private function filterActivitiesByUser(array $activities, User $user): array
|
private function filterActivitiesByUser(array $activities, User $user): array
|
||||||
{
|
{
|
||||||
return array_filter(
|
return array_values(
|
||||||
|
array_filter(
|
||||||
$activities,
|
$activities,
|
||||||
function ($activity) use ($user) {
|
function ($activity) use ($user) {
|
||||||
$activityUsernames = array_map(static fn ($user) => $user['username'], $activity['users'] ?? []);
|
$activityUsernames = array_map(static fn ($user) => $user['username'], $activity['users'] ?? []);
|
||||||
return in_array($user->getUsername(), $activityUsernames, true);
|
return in_array($user->getUsername(), $activityUsernames, true);
|
||||||
}
|
}
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return list
|
||||||
|
*/
|
||||||
private function filterWorksByUser(array $works, User $user): array
|
private function filterWorksByUser(array $works, User $user): array
|
||||||
{
|
{
|
||||||
return array_filter(
|
return array_values(
|
||||||
|
array_filter(
|
||||||
$works,
|
$works,
|
||||||
function ($work) use ($user) {
|
function ($work) use ($user) {
|
||||||
$workUsernames = array_map(static fn ($user) => $user['username'], $work['referrers'] ?? []);
|
$workUsernames = array_map(static fn ($user) => $user['username'], $work['referrers'] ?? []);
|
||||||
|
|
||||||
return in_array($user->getUsername(), $workUsernames, true);
|
return in_array($user->getUsername(), $workUsernames, true);
|
||||||
}
|
}
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ class CalculatorResult
|
|||||||
|
|
||||||
public $label;
|
public $label;
|
||||||
|
|
||||||
public $result;
|
public float $result;
|
||||||
|
|
||||||
public $type;
|
public $type;
|
||||||
}
|
}
|
||||||
|
@ -1,55 +1,91 @@
|
|||||||
<template>
|
<template>
|
||||||
<a :class="props.classes" @click="download_and_open($event)">
|
<a v-if="!state.is_ready" :class="props.classes" @click="download_and_open($event)">
|
||||||
<i class="fa fa-download"></i>
|
<i class="fa fa-download"></i>
|
||||||
Télécharger
|
Télécharger
|
||||||
</a>
|
</a>
|
||||||
|
<a v-else :class="props.classes" target="_blank" :type="props.storedObject.type" :download="buildDocumentName()" :href="state.href_url" ref="open_button">
|
||||||
|
<i class="fa fa-external-link"></i>
|
||||||
|
Ouvrir
|
||||||
|
</a>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {reactive} from "vue";
|
import {reactive, ref, nextTick, onMounted} from "vue";
|
||||||
import {build_download_info_link, download_and_decrypt_doc} from "./helpers";
|
import {build_download_info_link, download_and_decrypt_doc} from "./helpers";
|
||||||
import mime from "mime";
|
import mime from "mime";
|
||||||
import {StoredObject} from "../../types";
|
import {StoredObject} from "../../types";
|
||||||
|
|
||||||
interface DownloadButtonConfig {
|
interface DownloadButtonConfig {
|
||||||
storedObject: StoredObject,
|
storedObject: StoredObject,
|
||||||
classes: {[k: string]: boolean},
|
classes: { [k: string]: boolean },
|
||||||
filename?: string,
|
filename?: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DownloadButtonState {
|
interface DownloadButtonState {
|
||||||
is_ready: boolean
|
is_ready: boolean,
|
||||||
|
is_running: boolean,
|
||||||
|
href_url: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<DownloadButtonConfig>();
|
const props = defineProps<DownloadButtonConfig>();
|
||||||
const state: DownloadButtonState = reactive({is_ready: false});
|
const state: DownloadButtonState = reactive({is_ready: false, is_running: false, href_url: "#"});
|
||||||
|
|
||||||
|
const open_button = ref<HTMLAnchorElement | null>(null);
|
||||||
|
|
||||||
|
function buildDocumentName(): string {
|
||||||
|
const document_name = props.filename || 'document';
|
||||||
|
const ext = mime.getExtension(props.storedObject.type);
|
||||||
|
|
||||||
|
if (null !== ext) {
|
||||||
|
return document_name + '.' + ext;
|
||||||
|
}
|
||||||
|
|
||||||
|
return document_name;
|
||||||
|
}
|
||||||
|
|
||||||
async function download_and_open(event: Event): Promise<void> {
|
async function download_and_open(event: Event): Promise<void> {
|
||||||
const button = event.target as HTMLAnchorElement;
|
const button = event.target as HTMLAnchorElement;
|
||||||
|
|
||||||
if (!state.is_ready) {
|
if (state.is_running) {
|
||||||
event.preventDefault();
|
console.log('state is running, aborting');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
state.is_running = true;
|
||||||
|
|
||||||
|
if (state.is_ready) {
|
||||||
|
console.log('state is ready. This should not happens');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const urlInfo = build_download_info_link(props.storedObject.filename);
|
const urlInfo = build_download_info_link(props.storedObject.filename);
|
||||||
|
let raw;
|
||||||
|
|
||||||
const raw = await download_and_decrypt_doc(urlInfo, props.storedObject.keyInfos, new Uint8Array(props.storedObject.iv));
|
try {
|
||||||
|
raw = await download_and_decrypt_doc(urlInfo, props.storedObject.keyInfos, new Uint8Array(props.storedObject.iv));
|
||||||
button.href = window.URL.createObjectURL(raw);
|
} catch (e) {
|
||||||
button.type = props.storedObject.type;
|
console.error("error while downloading and decrypting document");
|
||||||
|
console.error(e);
|
||||||
button.download = props.filename || 'document';
|
throw e;
|
||||||
|
|
||||||
const ext = mime.getExtension(props.storedObject.type);
|
|
||||||
if (null !== ext) {
|
|
||||||
button.download = button.download + '.' + ext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('document downloading (and decrypting) successfully');
|
||||||
|
|
||||||
|
console.log('creating the url')
|
||||||
|
state.href_url = window.URL.createObjectURL(raw);
|
||||||
|
console.log('url created', state.href_url);
|
||||||
|
state.is_running = false;
|
||||||
state.is_ready = true;
|
state.is_ready = true;
|
||||||
|
console.log('new button marked as ready');
|
||||||
|
console.log('will click on button');
|
||||||
|
|
||||||
// for fixing https://gitlab.com/Chill-Projet/chill-bundles/-/issues/98
|
console.log('openbutton is now', open_button.value);
|
||||||
window.setTimeout(() => {
|
|
||||||
button.click()
|
await nextTick();
|
||||||
}, 750);
|
console.log('next tick actions');
|
||||||
}
|
console.log('openbutton after next tick', open_button.value);
|
||||||
|
open_button.value?.click();
|
||||||
|
console.log('open button should have been clicked');
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -149,16 +149,21 @@ async function download_and_decrypt_doc(urlGenerator: string, keyData: JsonWebKe
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (iv.length === 0) {
|
if (iv.length === 0) {
|
||||||
|
console.log('returning document immediatly');
|
||||||
return rawResponse.blob();
|
return rawResponse.blob();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('start decrypting doc');
|
||||||
|
|
||||||
const rawBuffer = await rawResponse.arrayBuffer();
|
const rawBuffer = await rawResponse.arrayBuffer();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const key = await window.crypto.subtle
|
const key = await window.crypto.subtle
|
||||||
.importKey('jwk', keyData, { name: algo }, false, ['decrypt']);
|
.importKey('jwk', keyData, { name: algo }, false, ['decrypt']);
|
||||||
|
console.log('key created');
|
||||||
const decrypted = await window.crypto.subtle
|
const decrypted = await window.crypto.subtle
|
||||||
.decrypt({ name: algo, iv: iv }, key, rawBuffer);
|
.decrypt({ name: algo, iv: iv }, key, rawBuffer);
|
||||||
|
console.log('doc decrypted');
|
||||||
|
|
||||||
return Promise.resolve(new Blob([decrypted]));
|
return Promise.resolve(new Blob([decrypted]));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -36,5 +36,4 @@ class SynchronizeEntityInfoViewsCommand extends Command
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -163,7 +163,6 @@ final class PermissionsGroupController extends AbstractController
|
|||||||
*/
|
*/
|
||||||
public function deleteLinkRoleScopeAction(int $pgid, int $rsid): Response
|
public function deleteLinkRoleScopeAction(int $pgid, int $rsid): Response
|
||||||
{
|
{
|
||||||
|
|
||||||
$permissionsGroup = $this->permissionsGroupRepository->find($pgid);
|
$permissionsGroup = $this->permissionsGroupRepository->find($pgid);
|
||||||
$roleScope = $this->roleScopeRepository->find($rsid);
|
$roleScope = $this->roleScopeRepository->find($rsid);
|
||||||
|
|
||||||
|
@ -141,5 +141,4 @@ final readonly class UserExportController
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -48,12 +48,19 @@ class Center implements HasCenterInterface
|
|||||||
*/
|
*/
|
||||||
private string $name = '';
|
private string $name = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Collection<Regroupment>
|
||||||
|
* @ORM\ManyToMany(targetEntity=Regroupment::class, mappedBy="centers")
|
||||||
|
*/
|
||||||
|
private Collection $regroupments;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Center constructor.
|
* Center constructor.
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->groupCenters = new \Doctrine\Common\Collections\ArrayCollection();
|
$this->groupCenters = new ArrayCollection();
|
||||||
|
$this->regroupments = new ArrayCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -106,6 +113,14 @@ class Center implements HasCenterInterface
|
|||||||
return $this->name;
|
return $this->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection<Regroupment>
|
||||||
|
*/
|
||||||
|
public function getRegroupments(): Collection
|
||||||
|
{
|
||||||
|
return $this->regroupments;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $name
|
* @param $name
|
||||||
*
|
*
|
||||||
|
@ -22,11 +22,12 @@ use Doctrine\ORM\Mapping as ORM;
|
|||||||
class Regroupment
|
class Regroupment
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var Center
|
|
||||||
* @ORM\ManyToMany(
|
* @ORM\ManyToMany(
|
||||||
* targetEntity=Center::class
|
* targetEntity=Center::class,
|
||||||
|
* inversedBy="regroupments"
|
||||||
* )
|
* )
|
||||||
* @ORM\Id
|
* @ORM\Id
|
||||||
|
* @var Collection<Center>
|
||||||
*/
|
*/
|
||||||
private Collection $centers;
|
private Collection $centers;
|
||||||
|
|
||||||
@ -52,6 +53,26 @@ class Regroupment
|
|||||||
$this->centers = new ArrayCollection();
|
$this->centers = new ArrayCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function addCenter(Center $center): self
|
||||||
|
{
|
||||||
|
if (!$this->centers->contains($center)) {
|
||||||
|
$this->centers->add($center);
|
||||||
|
$center->getRegroupments()->add($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeCenter(Center $center): self
|
||||||
|
{
|
||||||
|
if ($this->centers->contains($center)) {
|
||||||
|
$this->centers->removeElement($center);
|
||||||
|
$center->getRegroupments()->removeElement($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function getCenters(): Collection
|
public function getCenters(): Collection
|
||||||
{
|
{
|
||||||
return $this->centers;
|
return $this->centers;
|
||||||
|
@ -31,7 +31,7 @@ class RegroupmentType extends AbstractType
|
|||||||
->add('centers', EntityType::class, [
|
->add('centers', EntityType::class, [
|
||||||
'class' => Center::class,
|
'class' => Center::class,
|
||||||
'multiple' => true,
|
'multiple' => true,
|
||||||
'attr' => ['class' => 'select2'],
|
'expanded' => true,
|
||||||
])
|
])
|
||||||
->add('isActive', CheckboxType::class, [
|
->add('isActive', CheckboxType::class, [
|
||||||
'label' => 'Actif ?',
|
'label' => 'Actif ?',
|
||||||
|
@ -14,6 +14,8 @@ namespace Chill\MainBundle\Repository;
|
|||||||
use Chill\MainBundle\Entity\Regroupment;
|
use Chill\MainBundle\Entity\Regroupment;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Doctrine\ORM\EntityRepository;
|
use Doctrine\ORM\EntityRepository;
|
||||||
|
use Doctrine\ORM\NonUniqueResultException;
|
||||||
|
use Doctrine\ORM\NoResultException;
|
||||||
use Doctrine\Persistence\ObjectRepository;
|
use Doctrine\Persistence\ObjectRepository;
|
||||||
|
|
||||||
final class RegroupmentRepository implements ObjectRepository
|
final class RegroupmentRepository implements ObjectRepository
|
||||||
@ -59,6 +61,30 @@ final class RegroupmentRepository implements ObjectRepository
|
|||||||
return $this->repository->findOneBy($criteria, $orderBy);
|
return $this->repository->findOneBy($criteria, $orderBy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws NonUniqueResultException
|
||||||
|
* @throws NoResultException
|
||||||
|
*/
|
||||||
|
public function findOneByName(string $name): ?Regroupment
|
||||||
|
{
|
||||||
|
return $this->repository->createQueryBuilder('r')
|
||||||
|
->where('LOWER(r.name) = LOWER(:searched)')
|
||||||
|
->setParameter('searched', $name)
|
||||||
|
->getQuery()
|
||||||
|
->getSingleResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<Regroupment>
|
||||||
|
*/
|
||||||
|
public function findRegroupmentAssociatedToNoCenter(): array
|
||||||
|
{
|
||||||
|
return $this->repository->createQueryBuilder('r')
|
||||||
|
->where('SIZE(r.centers) = 0')
|
||||||
|
->getQuery()
|
||||||
|
->getResult();
|
||||||
|
}
|
||||||
|
|
||||||
public function getClassName()
|
public function getClassName()
|
||||||
{
|
{
|
||||||
return Regroupment::class;
|
return Regroupment::class;
|
||||||
|
@ -39,8 +39,13 @@
|
|||||||
{{ 'This will eventually restrict your possibilities in filtering the data.'|trans }}</p>
|
{{ 'This will eventually restrict your possibilities in filtering the data.'|trans }}</p>
|
||||||
|
|
||||||
<h3 class="m-3">{{ 'Center'|trans }}</h3>
|
<h3 class="m-3">{{ 'Center'|trans }}</h3>
|
||||||
|
|
||||||
{{ form_widget(form.centers.center) }}
|
{{ form_widget(form.centers.center) }}
|
||||||
|
|
||||||
|
<div class="mb-3 mt-3">
|
||||||
|
<input id="toggle-check-all" class="btn btn-misc" type= "button" onclick='uncheckAll(this)' value="{{ 'uncheck all centers'|trans|e('html_attr') }}"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
{% if form.centers.regroupment is defined %}
|
{% if form.centers.regroupment is defined %}
|
||||||
<h3 class="m-3">{{ 'Pick aggregated centers'|trans }}</h3>
|
<h3 class="m-3">{{ 'Pick aggregated centers'|trans }}</h3>
|
||||||
{{ form_widget(form.centers.regroupment) }}
|
{{ form_widget(form.centers.regroupment) }}
|
||||||
@ -53,3 +58,15 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
||||||
|
{% block js %}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const uncheckAll = () => {
|
||||||
|
const allCenters = document.getElementsByName('centers[center][]');
|
||||||
|
|
||||||
|
allCenters.forEach(checkbox => checkbox.checked = false)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{% endblock js %}
|
||||||
|
@ -285,6 +285,8 @@ The export will contains only data from the picked centers.: L'export ne contien
|
|||||||
This will eventually restrict your possibilities in filtering the data.: Les possibilités de filtrages seront adaptées aux droits de consultation pour les centres choisis.
|
This will eventually restrict your possibilities in filtering the data.: Les possibilités de filtrages seront adaptées aux droits de consultation pour les centres choisis.
|
||||||
Go to export options: Vers la préparation de l'export
|
Go to export options: Vers la préparation de l'export
|
||||||
Pick aggregated centers: Regroupement de centres
|
Pick aggregated centers: Regroupement de centres
|
||||||
|
uncheck all centers: Désélectionner tous les centres
|
||||||
|
check all centers: Sélectionner tous les centres
|
||||||
# export creation step 'export' : choose aggregators, filtering and formatter
|
# export creation step 'export' : choose aggregators, filtering and formatter
|
||||||
Formatter: Mise en forme
|
Formatter: Mise en forme
|
||||||
Choose the formatter: Choisissez le format d'export voulu.
|
Choose the formatter: Choisissez le format d'export voulu.
|
||||||
|
@ -51,7 +51,10 @@ class UserRefEventSubscriber implements EventSubscriberInterface
|
|||||||
|
|
||||||
public function onStateEntered(EnteredEvent $enteredEvent): void
|
public function onStateEntered(EnteredEvent $enteredEvent): void
|
||||||
{
|
{
|
||||||
if ($enteredEvent->getMarking()->has(AccompanyingPeriod::STEP_CONFIRMED)) {
|
if (
|
||||||
|
$enteredEvent->getMarking()->has(AccompanyingPeriod::STEP_CONFIRMED)
|
||||||
|
and $enteredEvent->getTransition()->getName() === 'confirm'
|
||||||
|
) {
|
||||||
$this->onPeriodConfirmed($enteredEvent->getSubject());
|
$this->onPeriodConfirmed($enteredEvent->getSubject());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,5 +34,4 @@ class AccompanyingPeriodStepChangeMessageHandler implements MessageHandlerInterf
|
|||||||
|
|
||||||
($this->changer)($period, $message->getTransition());
|
($this->changer)($period, $message->getTransition());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -84,5 +84,4 @@ class AccompanyingPeriodStepChangeRequestor
|
|||||||
$this->messageBus->dispatch(new AccompanyingPeriodStepChangeRequestMessage($accompanyingPeriodId, 'mark_active'));
|
$this->messageBus->dispatch(new AccompanyingPeriodStepChangeRequestMessage($accompanyingPeriodId, 'mark_active'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,11 @@ namespace Chill\PersonBundle\Actions\Remove;
|
|||||||
|
|
||||||
use Chill\PersonBundle\Actions\ActionEvent;
|
use Chill\PersonBundle\Actions\ActionEvent;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
|
use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation;
|
||||||
|
use Chill\PersonBundle\Entity\Household\HouseholdMember;
|
||||||
|
use Chill\PersonBundle\Entity\Household\PersonHouseholdAddress;
|
||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
|
use Chill\PersonBundle\Entity\Relationships\Relationship;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||||
@ -84,8 +88,11 @@ class PersonMove
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreach ($metadata->getAssociationMappings() as $field => $mapping) {
|
foreach ($metadata->getAssociationMappings() as $field => $mapping) {
|
||||||
if (Person::class === $mapping['targetEntity']) {
|
if (in_array($mapping['sourceEntity'], $this->getIgnoredEntities(), true)) {
|
||||||
if (in_array($metadata->getName(), $toDelete, true)) {
|
continue;
|
||||||
|
}
|
||||||
|
if (Person::class === $mapping['targetEntity'] and true === $mapping['isOwningSide']) {
|
||||||
|
if (in_array($mapping['sourceEntity'], $toDelete, true)) {
|
||||||
$sql = $this->createDeleteSQL($metadata, $from, $field);
|
$sql = $this->createDeleteSQL($metadata, $from, $field);
|
||||||
$event = new ActionEvent(
|
$event = new ActionEvent(
|
||||||
$from->getId(),
|
$from->getId(),
|
||||||
@ -120,7 +127,7 @@ class PersonMove
|
|||||||
return $sqls;
|
return $sqls;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function createDeleteSQL(ClassMetadata $metadata, Person $from, $field): string
|
private function createDeleteSQL(ClassMetadata $metadata, Person $from, $field): string
|
||||||
{
|
{
|
||||||
$mapping = $metadata->getAssociationMapping($field);
|
$mapping = $metadata->getAssociationMapping($field);
|
||||||
|
|
||||||
@ -137,26 +144,41 @@ class PersonMove
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function createMoveSQL(ClassMetadata $metadata, Person $from, Person $to, $field): string
|
private function createMoveSQL(ClassMetadata $metadata, Person $from, Person $to, $field): string
|
||||||
{
|
{
|
||||||
$mapping = $metadata->getAssociationMapping($field);
|
$mapping = $metadata->getAssociationMapping($field);
|
||||||
|
|
||||||
// Set part of the query, aka <here> in "UPDATE table SET <here> "
|
// Set part of the query, aka <here> in "UPDATE table SET <here> "
|
||||||
$sets = [];
|
$sets = [];
|
||||||
|
$conditions = [];
|
||||||
|
$tableName = '';
|
||||||
|
|
||||||
|
if (array_key_exists('joinTable', $mapping)) {
|
||||||
|
$tableName = (null !== ($mapping['joinTable']['schema'] ?? null) ? $mapping['joinTable']['schema'] . '.' : '')
|
||||||
|
. $mapping['joinTable']['name'];
|
||||||
|
|
||||||
|
foreach ($mapping['joinTable']['inverseJoinColumns'] as $columns) {
|
||||||
|
$sets[] = sprintf('%s = %d', $columns['name'], $to->getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($mapping['joinTable']['inverseJoinColumns'] as $columns) {
|
||||||
|
$conditions[] = sprintf('%s = %d', $columns['name'], $from->getId());
|
||||||
|
}
|
||||||
|
} elseif (array_key_exists('joinColumns', $mapping)) {
|
||||||
|
$tableName = $this->getTableName($metadata);
|
||||||
foreach ($mapping['joinColumns'] as $columns) {
|
foreach ($mapping['joinColumns'] as $columns) {
|
||||||
$sets[] = sprintf('%s = %d', $columns['name'], $to->getId());
|
$sets[] = sprintf('%s = %d', $columns['name'], $to->getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
$conditions = [];
|
|
||||||
|
|
||||||
foreach ($mapping['joinColumns'] as $columns) {
|
foreach ($mapping['joinColumns'] as $columns) {
|
||||||
$conditions[] = sprintf('%s = %d', $columns['name'], $from->getId());
|
$conditions[] = sprintf('%s = %d', $columns['name'], $from->getId());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return sprintf(
|
return sprintf(
|
||||||
'UPDATE %s SET %s WHERE %s',
|
'UPDATE %s SET %s WHERE %s',
|
||||||
$this->getTableName($metadata),
|
$tableName,
|
||||||
implode(' ', $sets),
|
implode(' ', $sets),
|
||||||
implode(' AND ', $conditions)
|
implode(' AND ', $conditions)
|
||||||
);
|
);
|
||||||
@ -166,10 +188,23 @@ class PersonMove
|
|||||||
* return an array of classes where entities should be deleted
|
* return an array of classes where entities should be deleted
|
||||||
* instead of moved.
|
* instead of moved.
|
||||||
*/
|
*/
|
||||||
protected function getDeleteEntities(): array
|
private function getDeleteEntities(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
AccompanyingPeriod::class,
|
Person\PersonCenterHistory::class,
|
||||||
|
HouseholdMember::class,
|
||||||
|
AccompanyingPeriodParticipation::class,
|
||||||
|
AccompanyingPeriod\AccompanyingPeriodWork::class,
|
||||||
|
Relationship::class
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getIgnoredEntities(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
Person\PersonCurrentAddress::class,
|
||||||
|
PersonHouseholdAddress::class,
|
||||||
|
Person\PersonCenterCurrent::class,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,7 +247,7 @@ class PersonDuplicateController extends Controller
|
|||||||
);
|
);
|
||||||
|
|
||||||
$duplicatePersons = $this->similarPersonMatcher->
|
$duplicatePersons = $this->similarPersonMatcher->
|
||||||
matchPerson($person, $personNotDuplicateRepository, 0.5, SimilarPersonMatcher::SIMILAR_SEARCH_ORDER_BY_ALPHABETICAL);
|
matchPerson($person, 0.5, SimilarPersonMatcher::SIMILAR_SEARCH_ORDER_BY_ALPHABETICAL, false);
|
||||||
|
|
||||||
$notDuplicatePersons = $personNotDuplicateRepository->findNotDuplicatePerson($person);
|
$notDuplicatePersons = $personNotDuplicateRepository->findNotDuplicatePerson($person);
|
||||||
|
|
||||||
@ -264,14 +264,14 @@ class PersonDuplicateController extends Controller
|
|||||||
|
|
||||||
$nb_activity = $em->getRepository(Activity::class)->findBy(['person' => $id]);
|
$nb_activity = $em->getRepository(Activity::class)->findBy(['person' => $id]);
|
||||||
$nb_document = $em->getRepository(PersonDocument::class)->findBy(['person' => $id]);
|
$nb_document = $em->getRepository(PersonDocument::class)->findBy(['person' => $id]);
|
||||||
$nb_event = $em->getRepository(Participation::class)->findBy(['person' => $id]);
|
// $nb_event = $em->getRepository(Participation::class)->findBy(['person' => $id]);
|
||||||
$nb_task = $em->getRepository(SingleTask::class)->countByParameters(['person' => $id]);
|
$nb_task = $em->getRepository(SingleTask::class)->countByParameters(['person' => $id]);
|
||||||
$person = $em->getRepository(Person::class)->findOneBy(['id' => $id]);
|
$person = $em->getRepository(Person::class)->findOneBy(['id' => $id]);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'nb_activity' => count($nb_activity),
|
'nb_activity' => count($nb_activity),
|
||||||
'nb_document' => count($nb_document),
|
'nb_document' => count($nb_document),
|
||||||
'nb_event' => count($nb_event),
|
// 'nb_event' => count($nb_event),
|
||||||
'nb_task' => $nb_task,
|
'nb_task' => $nb_task,
|
||||||
'nb_addresses' => count($person->getAddresses()),
|
'nb_addresses' => count($person->getAddresses()),
|
||||||
];
|
];
|
||||||
|
@ -12,9 +12,11 @@ declare(strict_types=1);
|
|||||||
namespace Chill\PersonBundle\Controller;
|
namespace Chill\PersonBundle\Controller;
|
||||||
|
|
||||||
use Chill\MainBundle\Pagination\PaginatorFactory;
|
use Chill\MainBundle\Pagination\PaginatorFactory;
|
||||||
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
use Chill\PersonBundle\Repository\AccompanyingPeriodRepository;
|
use Chill\PersonBundle\Repository\AccompanyingPeriodRepository;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
|
||||||
class UserAccompanyingPeriodController extends AbstractController
|
class UserAccompanyingPeriodController extends AbstractController
|
||||||
@ -32,12 +34,24 @@ class UserAccompanyingPeriodController extends AbstractController
|
|||||||
/**
|
/**
|
||||||
* @Route("/{_locale}/person/accompanying-periods/my", name="chill_person_accompanying_period_user")
|
* @Route("/{_locale}/person/accompanying-periods/my", name="chill_person_accompanying_period_user")
|
||||||
*/
|
*/
|
||||||
public function listAction(Request $request)
|
public function listAction(Request $request): Response
|
||||||
{
|
{
|
||||||
$total = $this->accompanyingPeriodRepository->countBy(['user' => $this->getUser(), 'step' => ['CONFIRMED', 'CLOSED']]);
|
$active = $request->query->getBoolean('active', true);
|
||||||
|
$steps = match ($active) {
|
||||||
|
true => [
|
||||||
|
AccompanyingPeriod::STEP_CONFIRMED,
|
||||||
|
AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG,
|
||||||
|
AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT,
|
||||||
|
],
|
||||||
|
false => [
|
||||||
|
AccompanyingPeriod::STEP_CLOSED,
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
$total = $this->accompanyingPeriodRepository->countBy(['user' => $this->getUser(), 'step' => $steps]);
|
||||||
$pagination = $this->paginatorFactory->create($total);
|
$pagination = $this->paginatorFactory->create($total);
|
||||||
$accompanyingPeriods = $this->accompanyingPeriodRepository->findBy(
|
$accompanyingPeriods = $this->accompanyingPeriodRepository->findBy(
|
||||||
['user' => $this->getUser(), 'step' => ['CONFIRMED', 'CLOSED']],
|
['user' => $this->getUser(), 'step' => $steps],
|
||||||
['openingDate' => 'DESC'],
|
['openingDate' => 'DESC'],
|
||||||
$pagination->getItemsPerPage(),
|
$pagination->getItemsPerPage(),
|
||||||
$pagination->getCurrentPageFirstItemNumber()
|
$pagination->getCurrentPageFirstItemNumber()
|
||||||
@ -46,13 +60,14 @@ class UserAccompanyingPeriodController extends AbstractController
|
|||||||
return $this->render('@ChillPerson/AccompanyingPeriod/user_periods_list.html.twig', [
|
return $this->render('@ChillPerson/AccompanyingPeriod/user_periods_list.html.twig', [
|
||||||
'accompanyingPeriods' => $accompanyingPeriods,
|
'accompanyingPeriods' => $accompanyingPeriods,
|
||||||
'pagination' => $pagination,
|
'pagination' => $pagination,
|
||||||
|
'active' => $active,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/{_locale}/person/accompanying-periods/my/drafts", name="chill_person_accompanying_period_draft_user")
|
* @Route("/{_locale}/person/accompanying-periods/my/drafts", name="chill_person_accompanying_period_draft_user")
|
||||||
*/
|
*/
|
||||||
public function listDraftsAction(Request $request)
|
public function listDraftsAction(): Response
|
||||||
{
|
{
|
||||||
$total = $this->accompanyingPeriodRepository->countBy(['user' => $this->getUser(), 'step' => 'DRAFT']);
|
$total = $this->accompanyingPeriodRepository->countBy(['user' => $this->getUser(), 'step' => 'DRAFT']);
|
||||||
$pagination = $this->paginatorFactory->create($total);
|
$pagination = $this->paginatorFactory->create($total);
|
||||||
|
@ -45,7 +45,7 @@ class PersonCenterCurrent
|
|||||||
private ?int $id = null;
|
private ?int $id = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\ManyToOne(targetEntity=Person::class, inversedBy="centerCurrent")
|
* @ORM\OneToOne(targetEntity=Person::class, inversedBy="centerCurrent")
|
||||||
*/
|
*/
|
||||||
private Person $person;
|
private Person $person;
|
||||||
|
|
||||||
|
@ -107,7 +107,6 @@ class ListHouseholdInPeriod implements ListInterface, GroupedExportInterface
|
|||||||
return $this->aggregateStringHelper->getLabelMulti($key, $values, 'export.list.household.' . $key);
|
return $this->aggregateStringHelper->getLabelMulti($key, $values, 'export.list.household.' . $key);
|
||||||
|
|
||||||
case 'compositionType':
|
case 'compositionType':
|
||||||
//dump($values);
|
|
||||||
return $this->translatableStringHelper->getLabel($key, $values, 'export.list.household.' . $key);
|
return $this->translatableStringHelper->getLabel($key, $values, 'export.list.household.' . $key);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -12,7 +12,9 @@ declare(strict_types=1);
|
|||||||
namespace Chill\PersonBundle\Menu;
|
namespace Chill\PersonBundle\Menu;
|
||||||
|
|
||||||
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
|
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
|
||||||
|
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
|
||||||
use Knp\Menu\MenuItem;
|
use Knp\Menu\MenuItem;
|
||||||
|
use Symfony\Component\Security\Core\Security;
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
class HouseholdMenuBuilder implements LocalMenuBuilderInterface
|
class HouseholdMenuBuilder implements LocalMenuBuilderInterface
|
||||||
@ -22,9 +24,12 @@ class HouseholdMenuBuilder implements LocalMenuBuilderInterface
|
|||||||
*/
|
*/
|
||||||
protected $translator;
|
protected $translator;
|
||||||
|
|
||||||
public function __construct(TranslatorInterface $translator)
|
private Security $security;
|
||||||
|
|
||||||
|
public function __construct(TranslatorInterface $translator, Security $security)
|
||||||
{
|
{
|
||||||
$this->translator = $translator;
|
$this->translator = $translator;
|
||||||
|
$this->security = $security;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildMenu($menuId, MenuItem $menu, array $parameters): void
|
public function buildMenu($menuId, MenuItem $menu, array $parameters): void
|
||||||
@ -53,12 +58,14 @@ class HouseholdMenuBuilder implements LocalMenuBuilderInterface
|
|||||||
], ])
|
], ])
|
||||||
->setExtras(['order' => 17]);
|
->setExtras(['order' => 17]);
|
||||||
|
|
||||||
|
if ($this->security->isGranted(AccompanyingPeriodVoter::SEE, $parameters['household'])) {
|
||||||
$menu->addChild($this->translator->trans('household.Accompanying period'), [
|
$menu->addChild($this->translator->trans('household.Accompanying period'), [
|
||||||
'route' => 'chill_person_household_accompanying_period',
|
'route' => 'chill_person_household_accompanying_period',
|
||||||
'routeParameters' => [
|
'routeParameters' => [
|
||||||
'household_id' => $household->getId(),
|
'household_id' => $household->getId(),
|
||||||
], ])
|
],])
|
||||||
->setExtras(['order' => 20]);
|
->setExtras(['order' => 20]);
|
||||||
|
}
|
||||||
|
|
||||||
$menu->addChild($this->translator->trans('household.Addresses'), [
|
$menu->addChild($this->translator->trans('household.Addresses'), [
|
||||||
'route' => 'chill_person_household_addresses',
|
'route' => 'chill_person_household_addresses',
|
||||||
|
@ -15,6 +15,7 @@ use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
|
|||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
use Chill\PersonBundle\Repository\ResidentialAddressRepository;
|
use Chill\PersonBundle\Repository\ResidentialAddressRepository;
|
||||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
|
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
|
||||||
|
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||||
use Knp\Menu\MenuItem;
|
use Knp\Menu\MenuItem;
|
||||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||||
use Symfony\Component\Security\Core\Security;
|
use Symfony\Component\Security\Core\Security;
|
||||||
@ -106,7 +107,8 @@ class PersonMenuBuilder implements LocalMenuBuilderInterface
|
|||||||
->setExtras([
|
->setExtras([
|
||||||
'order' => 99999,
|
'order' => 99999,
|
||||||
]);
|
]);
|
||||||
/*
|
|
||||||
|
if ($this->security->isGranted(PersonVoter::DUPLICATE, $parameters['person'])) {
|
||||||
$menu->addChild($this->translator->trans('Person duplicate'), [
|
$menu->addChild($this->translator->trans('Person duplicate'), [
|
||||||
'route' => 'chill_person_duplicate_view',
|
'route' => 'chill_person_duplicate_view',
|
||||||
'routeParameters' => [
|
'routeParameters' => [
|
||||||
@ -116,7 +118,8 @@ class PersonMenuBuilder implements LocalMenuBuilderInterface
|
|||||||
->setExtras([
|
->setExtras([
|
||||||
'order' => 99999,
|
'order' => 99999,
|
||||||
]);
|
]);
|
||||||
*/
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
'visible' === $this->showAccompanyingPeriod
|
'visible' === $this->showAccompanyingPeriod
|
||||||
&& $this->security->isGranted(AccompanyingPeriodVoter::SEE, $parameters['person'])
|
&& $this->security->isGranted(AccompanyingPeriodVoter::SEE, $parameters['person'])
|
||||||
|
@ -89,5 +89,4 @@ readonly class AccompanyingPeriodInfoRepository implements AccompanyingPeriodInf
|
|||||||
{
|
{
|
||||||
return AccompanyingPeriodInfo::class;
|
return AccompanyingPeriodInfo::class;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,8 @@
|
|||||||
<add-evaluation
|
<add-evaluation
|
||||||
v-for="e in pickedEvaluations"
|
v-for="e in pickedEvaluations"
|
||||||
v-bind:key="e.key"
|
v-bind:key="e.key"
|
||||||
v-bind:evaluation="e">
|
v-bind:evaluation="e"
|
||||||
|
v-bind:docAnchorId="this.docAnchorId">
|
||||||
</add-evaluation>
|
</add-evaluation>
|
||||||
|
|
||||||
<!-- box to add new evaluation -->
|
<!-- box to add new evaluation -->
|
||||||
@ -406,6 +407,7 @@ export default {
|
|||||||
i18n,
|
i18n,
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
docAnchorId: null,
|
||||||
isExpanded: false,
|
isExpanded: false,
|
||||||
editor: ClassicEditor,
|
editor: ClassicEditor,
|
||||||
showAddObjective: false,
|
showAddObjective: false,
|
||||||
@ -445,6 +447,13 @@ export default {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
beforeMount() {
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
this.docAnchorId = urlParams.get('doc_id');
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.scrollToElement(this.docAnchorId);
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState([
|
...mapState([
|
||||||
'work',
|
'work',
|
||||||
@ -594,7 +603,7 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
saveFormOnTheFly(payload) {
|
saveFormOnTheFly(payload) {
|
||||||
console.log('saveFormOnTheFly: type', payload.type, ', data', payload.data);
|
// console.log('saveFormOnTheFly: type', payload.type, ', data', payload.data);
|
||||||
|
|
||||||
let body = { type: payload.type };
|
let body = { type: payload.type };
|
||||||
body.name = payload.data.text;
|
body.name = payload.data.text;
|
||||||
@ -616,6 +625,12 @@ export default {
|
|||||||
this.$toast.open({message: 'An error occurred'});
|
this.$toast.open({message: 'An error occurred'});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
scrollToElement(docAnchorId) {
|
||||||
|
const documentEl = document.getElementById(`document_${docAnchorId}`);
|
||||||
|
if (documentEl) {
|
||||||
|
documentEl.scrollIntoView({behavior: 'smooth'});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<form-evaluation ref="FormEvaluation" :key="evaluation.key" :evaluation="evaluation"></form-evaluation>
|
<form-evaluation ref="FormEvaluation" :key="evaluation.key" :evaluation="evaluation" :docAnchorId="docAnchorId"></form-evaluation>
|
||||||
|
|
||||||
<ul class="record_actions">
|
<ul class="record_actions">
|
||||||
<li v-if="evaluation.workflows_availables.length > 0">
|
<li v-if="evaluation.workflows_availables.length > 0">
|
||||||
@ -85,7 +85,7 @@ export default {
|
|||||||
Modal,
|
Modal,
|
||||||
ListWorkflowModal,
|
ListWorkflowModal,
|
||||||
},
|
},
|
||||||
props: ['evaluation'],
|
props: ['evaluation', 'docAnchorId'],
|
||||||
i18n,
|
i18n,
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -79,8 +79,8 @@
|
|||||||
<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.id">
|
<div class="item-bloc" v-for="(d, i) in evaluation.documents" :key="d.id" :class="[parseInt(this.docAnchorId) === d.id ? 'bg-blink' : 'nothing']">
|
||||||
<div class="item-row">
|
<div :id="`document_${d.id}`" class="item-row">
|
||||||
<div class="input-group input-group-lg mb-3 row">
|
<div class="input-group input-group-lg mb-3 row">
|
||||||
<label class="col-sm-3 col-form-label">Titre du document:</label>
|
<label class="col-sm-3 col-form-label">Titre du document:</label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
@ -238,7 +238,7 @@ const i18n = {
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "FormEvaluation",
|
name: "FormEvaluation",
|
||||||
props: ['evaluation'],
|
props: ['evaluation', 'docAnchorId'],
|
||||||
components: {
|
components: {
|
||||||
ckeditor: CKEditor.component,
|
ckeditor: CKEditor.component,
|
||||||
PickTemplate,
|
PickTemplate,
|
||||||
@ -437,4 +437,19 @@ export default {
|
|||||||
ul.document-upload {
|
ul.document-upload {
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bg-blink{
|
||||||
|
color: #050000;
|
||||||
|
padding: 10px;
|
||||||
|
display: inline-block;
|
||||||
|
border-radius: 5px;
|
||||||
|
animation: blinkingBackground 2.2s infinite;
|
||||||
|
animation-iteration-count: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes blinkingBackground{
|
||||||
|
0% { background-color: #ed776d;}
|
||||||
|
50% { background-color: #ffffff;}
|
||||||
|
100% { background-color: #ed776d;}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -207,7 +207,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {dateToISO} from 'ChillMainAssets/chill/js/date';
|
import {dateToISO, ISOToDate} from 'ChillMainAssets/chill/js/date';
|
||||||
import AddressRenderBox from 'ChillMainAssets/vuejs/_components/Entity/AddressRenderBox.vue';
|
import AddressRenderBox from 'ChillMainAssets/vuejs/_components/Entity/AddressRenderBox.vue';
|
||||||
import Confidential from 'ChillMainAssets/vuejs/_components/Confidential.vue';
|
import Confidential from 'ChillMainAssets/vuejs/_components/Confidential.vue';
|
||||||
import BadgeEntity from 'ChillMainAssets/vuejs/_components/BadgeEntity.vue';
|
import BadgeEntity from 'ChillMainAssets/vuejs/_components/BadgeEntity.vue';
|
||||||
@ -262,7 +262,7 @@ export default {
|
|||||||
},
|
},
|
||||||
birthdate: function () {
|
birthdate: function () {
|
||||||
if (this.person.birthdate !== null || this.person.birthdate === "undefined") {
|
if (this.person.birthdate !== null || this.person.birthdate === "undefined") {
|
||||||
return new Date(this.person.birthdate.datetime);
|
return ISOToDate(this.person.birthdate.datetime);
|
||||||
} else {
|
} else {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -16,11 +16,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="wh-col">
|
<div class="wh-col">
|
||||||
{% if period.step == 'DRAFT' %}
|
{% if period.step == 'DRAFT' %}
|
||||||
<span class="badge bg-secondary">{{- 'Draft'|trans|upper -}}</span>
|
<span class="badge bg-secondary" style="font-size: 85%;" title="{{ 'course.draft'|trans|e('html_attr') }}">{{ 'course.draft'|trans }}</span>
|
||||||
{% elseif period.step == 'CONFIRMED' %}
|
{% elseif period.step == 'CLOSED' %}
|
||||||
<span class="badge bg-primary">{{- 'Confirmed'|trans|upper -}}</span>
|
<span class="badge bg-danger" style="font-size: 85%;" title="{{ 'course.closed'|trans|e('html_attr') }}">{{ 'course.closed'|trans }}</span>
|
||||||
{% else %}
|
{% elseif period.step == 'CONFIRMED_INACTIVE_SHORT' %}
|
||||||
<span class="badge bg-danger">{{- 'Closed'|trans|upper -}}</span>
|
<span class="badge bg-chill-yellow text-primary" style="font-size: 85%;" title="{{ 'course.inactive_short'|trans|e('html_attr') }}">{{ 'course.inactive_short'|trans }}</span>
|
||||||
|
{% elseif period.step == 'CONFIRMED_INACTIVE_LONG' %}
|
||||||
|
<span class="badge bg-danger" style="font-size: 85%;" title="{{ 'course.inactive_long'|trans|e('html_attr') }}">{{ 'course.inactive_long'|trans }}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -17,6 +17,15 @@
|
|||||||
<div class="col-md-10">
|
<div class="col-md-10">
|
||||||
<h1>{{ 'My accompanying periods'|trans }}</h1>
|
<h1>{{ 'My accompanying periods'|trans }}</h1>
|
||||||
|
|
||||||
|
<ul class="nav nav-pills justify-content-center">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link {% if active == true %}active{% endif %}" aria-current="page" href="{{ chill_path_forward_return_path('chill_person_accompanying_period_user', {'active': true}) }}">{{ ['Confirmed'|trans, 'course.inactive_short'|trans, 'course.inactive_long'|trans]|join(', ') }}</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item ">
|
||||||
|
<a class="nav-link {% if active == false %}active{% endif %}" href="{{ chill_path_forward_return_path('chill_person_accompanying_period_user', {'active': false}) }}">{{ 'course.closed'|trans }}</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<p>{{ 'Number of periods'|trans }}: <span class="badge rounded-pill bg-primary">{{ pagination.totalItems }}</span></p>
|
<p>{{ 'Number of periods'|trans }}: <span class="badge rounded-pill bg-primary">{{ pagination.totalItems }}</span></p>
|
||||||
|
|
||||||
<div class="flex-table accompanyingcourse-list">
|
<div class="flex-table accompanyingcourse-list">
|
||||||
|
@ -40,13 +40,14 @@
|
|||||||
{{ 'Household summary'|trans }}
|
{{ 'Household summary'|trans }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{# TODO: add ACL to check if user is allowed to edit household? #}
|
{% if is_granted('CHILL_PERSON_HOUSEHOLD_EDIT', household) %}
|
||||||
<li>
|
<li>
|
||||||
<a class="btn btn-create"
|
<a class="btn btn-create"
|
||||||
href="{{ path ('chill_household_accompanying_course_new', {'household_id' : household.id } ) }}" role="button">
|
href="{{ path ('chill_household_accompanying_course_new', {'household_id' : household.id } ) }}" role="button">
|
||||||
{{ 'Create an accompanying period'|trans }}
|
{{ 'Create an accompanying period'|trans }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
<li><b>{{ person.counters.nb_activity }}</b> {{ (person.counters.nb_activity > 1)? 'échanges' : 'échange' }}</li>
|
<li><b>{{ person.counters.nb_activity }}</b> {{ (person.counters.nb_activity > 1)? 'échanges' : 'échange' }}</li>
|
||||||
<li><b>{{ person.counters.nb_task }}</b> {{ (person.counters.nb_task > 1)? 'tâches' : 'tâche' }}</li>
|
<li><b>{{ person.counters.nb_task }}</b> {{ (person.counters.nb_task > 1)? 'tâches' : 'tâche' }}</li>
|
||||||
<li><b>{{ person.counters.nb_document }}</b> {{ (person.counters.nb_document > 1)? 'documents' : 'document' }}</li>
|
<li><b>{{ person.counters.nb_document }}</b> {{ (person.counters.nb_document > 1)? 'documents' : 'document' }}</li>
|
||||||
<li><b>{{ person.counters.nb_event }}</b> {{ (person.counters.nb_event > 1)? 'événements' : 'événement' }}</li>
|
{# <li><b>{{ person.counters.nb_event }}</b> {{ (person.counters.nb_event > 1)? 'événements' : 'événement' }}</li>#}
|
||||||
<li><b>{{ person.counters.nb_addresses }}</b> {{ (person.counters.nb_addresses > 1)? 'adresses' : 'adresse' }}</li>
|
<li><b>{{ person.counters.nb_addresses }}</b> {{ (person.counters.nb_addresses > 1)? 'adresses' : 'adresse' }}</li>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
<h1>{{ 'Merge duplicate persons folders'|trans }}</h1>
|
<h1>{{ 'Merge duplicate persons folders'|trans }}</h1>
|
||||||
|
|
||||||
<div class="col-md-6">
|
<div class="col-md-11">
|
||||||
<p><b>{{ 'Old person'|trans }}</b>:
|
<p><b>{{ 'Old person'|trans }}</b>:
|
||||||
{{ 'Old person explain'|trans }}
|
{{ 'Old person explain'|trans }}
|
||||||
</p>
|
</p>
|
||||||
@ -43,7 +43,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-6">
|
<div class="col-md-11">
|
||||||
<p><b>{{ 'New person'|trans }}</b>:
|
<p><b>{{ 'New person'|trans }}</b>:
|
||||||
{{ 'New person explain'|trans }}
|
{{ 'New person explain'|trans }}
|
||||||
</p>
|
</p>
|
||||||
@ -63,10 +63,10 @@
|
|||||||
|
|
||||||
{{ form_start(form) }}
|
{{ form_start(form) }}
|
||||||
|
|
||||||
<div class="col-md-4 centered">
|
<div class="col-md-12 centered">
|
||||||
|
|
||||||
<div class="container-fluid" style="padding-top: 1em;">
|
<div class="container-fluid" style="padding-top: 1em;">
|
||||||
<div class="col-1 clear" style="padding-top: 10px;">
|
<div class="clear" style="padding-top: 10px;">
|
||||||
{{ form_widget(form.confirm) }}
|
{{ form_widget(form.confirm) }}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-11">
|
<div class="col-11">
|
||||||
|
@ -123,7 +123,7 @@
|
|||||||
<ul class="record_actions">
|
<ul class="record_actions">
|
||||||
<li>{{ doc.storedObject|chill_document_button_group(doc.title, is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', evaluation.accompanyingPeriodWork)) }}</li>
|
<li>{{ doc.storedObject|chill_document_button_group(doc.title, is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', evaluation.accompanyingPeriodWork)) }}</li>
|
||||||
<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, 'doc_id': doc.id}) }}">
|
||||||
{{ 'Show'|trans }}
|
{{ 'Show'|trans }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -18,6 +18,7 @@ use Chill\MainBundle\Security\Authorization\VoterHelperFactoryInterface;
|
|||||||
use Chill\MainBundle\Security\Authorization\VoterHelperInterface;
|
use Chill\MainBundle\Security\Authorization\VoterHelperInterface;
|
||||||
use Chill\MainBundle\Security\ProvideRoleHierarchyInterface;
|
use Chill\MainBundle\Security\ProvideRoleHierarchyInterface;
|
||||||
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 Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||||
use Symfony\Component\Security\Core\Security;
|
use Symfony\Component\Security\Core\Security;
|
||||||
@ -119,6 +120,7 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRoleH
|
|||||||
->generate(self::class)
|
->generate(self::class)
|
||||||
->addCheckFor(null, [self::CREATE, self::REASSIGN_BULK])
|
->addCheckFor(null, [self::CREATE, self::REASSIGN_BULK])
|
||||||
->addCheckFor(AccompanyingPeriod::class, [self::TOGGLE_CONFIDENTIAL, ...self::ALL])
|
->addCheckFor(AccompanyingPeriod::class, [self::TOGGLE_CONFIDENTIAL, ...self::ALL])
|
||||||
|
->addCheckFor(Household::class, [self::SEE])
|
||||||
->addCheckFor(Person::class, [self::SEE, self::CREATE])
|
->addCheckFor(Person::class, [self::SEE, self::CREATE])
|
||||||
->addCheckFor(Center::class, [self::STATS])
|
->addCheckFor(Center::class, [self::STATS])
|
||||||
->build();
|
->build();
|
||||||
|
@ -22,10 +22,14 @@ use Chill\DocStoreBundle\Entity\StoredObject;
|
|||||||
use Chill\DocStoreBundle\Repository\DocumentCategoryRepository;
|
use Chill\DocStoreBundle\Repository\DocumentCategoryRepository;
|
||||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\Resource;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation;
|
use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation;
|
||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
use Chill\PersonBundle\Repository\PersonRepository;
|
use Chill\PersonBundle\Repository\PersonRepository;
|
||||||
use Chill\PersonBundle\Templating\Entity\PersonRenderInterface;
|
use Chill\PersonBundle\Templating\Entity\PersonRenderInterface;
|
||||||
|
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||||
|
use Chill\ThirdPartyBundle\Templating\Entity\ThirdPartyRender;
|
||||||
|
use Chill\ThirdPartyBundle\Repository\ThirdPartyRepository;
|
||||||
use DateTime;
|
use DateTime;
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
@ -40,6 +44,7 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
|||||||
use function array_key_exists;
|
use function array_key_exists;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @see AccompanyingPeriodContextTest
|
||||||
* @template-implements DocGeneratorContextWithPublicFormInterface<AccompanyingPeriod>
|
* @template-implements DocGeneratorContextWithPublicFormInterface<AccompanyingPeriod>
|
||||||
*/
|
*/
|
||||||
class AccompanyingPeriodContext implements
|
class AccompanyingPeriodContext implements
|
||||||
@ -62,6 +67,10 @@ class AccompanyingPeriodContext implements
|
|||||||
|
|
||||||
private TranslatorInterface $translator;
|
private TranslatorInterface $translator;
|
||||||
|
|
||||||
|
private ThirdPartyRender $thirdPartyRender;
|
||||||
|
|
||||||
|
private ThirdPartyRepository $thirdPartyRepository;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
DocumentCategoryRepository $documentCategoryRepository,
|
DocumentCategoryRepository $documentCategoryRepository,
|
||||||
NormalizerInterface $normalizer,
|
NormalizerInterface $normalizer,
|
||||||
@ -70,7 +79,9 @@ class AccompanyingPeriodContext implements
|
|||||||
PersonRenderInterface $personRender,
|
PersonRenderInterface $personRender,
|
||||||
PersonRepository $personRepository,
|
PersonRepository $personRepository,
|
||||||
TranslatorInterface $translator,
|
TranslatorInterface $translator,
|
||||||
BaseContextData $baseContextData
|
BaseContextData $baseContextData,
|
||||||
|
ThirdPartyRender $thirdPartyRender,
|
||||||
|
ThirdPartyRepository $thirdPartyRepository
|
||||||
) {
|
) {
|
||||||
$this->documentCategoryRepository = $documentCategoryRepository;
|
$this->documentCategoryRepository = $documentCategoryRepository;
|
||||||
$this->normalizer = $normalizer;
|
$this->normalizer = $normalizer;
|
||||||
@ -80,6 +91,8 @@ class AccompanyingPeriodContext implements
|
|||||||
$this->personRepository = $personRepository;
|
$this->personRepository = $personRepository;
|
||||||
$this->translator = $translator;
|
$this->translator = $translator;
|
||||||
$this->baseContextData = $baseContextData;
|
$this->baseContextData = $baseContextData;
|
||||||
|
$this->thirdPartyRender = $thirdPartyRender;
|
||||||
|
$this->thirdPartyRepository = $thirdPartyRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function adminFormReverseTransform(array $data): array
|
public function adminFormReverseTransform(array $data): array
|
||||||
@ -103,11 +116,12 @@ class AccompanyingPeriodContext implements
|
|||||||
'person1Label' => $data['person1Label'] ?? $this->translator->trans('docgen.person 1'),
|
'person1Label' => $data['person1Label'] ?? $this->translator->trans('docgen.person 1'),
|
||||||
'person2' => $data['person2'] ?? false,
|
'person2' => $data['person2'] ?? false,
|
||||||
'person2Label' => $data['person2Label'] ?? $this->translator->trans('docgen.person 2'),
|
'person2Label' => $data['person2Label'] ?? $this->translator->trans('docgen.person 2'),
|
||||||
|
'thirdParty' => $data['thirdParty'] ?? false,
|
||||||
|
'thirdPartyLabel' => $data['thirdPartyLabel'] ?? $this->translator->trans('Third party'),
|
||||||
];
|
];
|
||||||
|
|
||||||
if (array_key_exists('category', $data)) {
|
if (array_key_exists('category', $data)) {
|
||||||
$r['category'] = array_key_exists('category', $data) ?
|
$r['category'] = $this->documentCategoryRepository->find($data['category']);
|
||||||
$this->documentCategoryRepository->find($data['category']) : null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $r;
|
return $r;
|
||||||
@ -140,6 +154,14 @@ class AccompanyingPeriodContext implements
|
|||||||
'label' => 'person 2 label',
|
'label' => 'person 2 label',
|
||||||
'required' => true,
|
'required' => true,
|
||||||
])
|
])
|
||||||
|
->add('thirdParty', CheckboxType::class, [
|
||||||
|
'required' => false,
|
||||||
|
'label' => 'docgen.Ask for thirdParty',
|
||||||
|
])
|
||||||
|
->add('thirdPartyLabel', TextType::class, [
|
||||||
|
'label' => 'docgen.thirdParty label',
|
||||||
|
'required' => true,
|
||||||
|
])
|
||||||
->add('category', EntityType::class, [
|
->add('category', EntityType::class, [
|
||||||
'placeholder' => 'Choose a document category',
|
'placeholder' => 'Choose a document category',
|
||||||
'class' => DocumentCategory::class,
|
'class' => DocumentCategory::class,
|
||||||
@ -190,6 +212,28 @@ class AccompanyingPeriodContext implements
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$thirdParties = [...array_values(array_filter([$entity->getRequestorThirdParty()])), ...array_values(array_filter(
|
||||||
|
array_map(
|
||||||
|
fn (Resource $r): ?ThirdParty => $r->getThirdParty(),
|
||||||
|
$entity->getResources()->filter(
|
||||||
|
static fn (Resource $r): bool => null !== $r->getThirdParty()
|
||||||
|
)->toArray()
|
||||||
|
)
|
||||||
|
))];
|
||||||
|
|
||||||
|
if ($options['thirdParty'] ?? false) {
|
||||||
|
$builder->add('thirdParty', EntityType::class, [
|
||||||
|
'class' => ThirdParty::class,
|
||||||
|
'choices' => $thirdParties,
|
||||||
|
'choice_label' => fn (ThirdParty $p) => $this->thirdPartyRender->renderString($p, []),
|
||||||
|
'multiple' => false,
|
||||||
|
'required' => false,
|
||||||
|
'expanded' => true,
|
||||||
|
'label' => $options['thirdPartyLabel'],
|
||||||
|
'placeholder' => $this->translator->trans('Any third party selected'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getData(DocGeneratorTemplate $template, $entity, array $contextGenerationData = []): array
|
public function getData(DocGeneratorTemplate $template, $entity, array $contextGenerationData = []): array
|
||||||
@ -215,6 +259,13 @@ class AccompanyingPeriodContext implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($options['thirdParty']) {
|
||||||
|
$data['thirdParty'] = $this->normalizer->normalize($contextGenerationData['thirdParty'], 'docgen', [
|
||||||
|
'docgen:expects' => ThirdParty::class,
|
||||||
|
'groups' => 'docgen:read'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,7 +305,7 @@ class AccompanyingPeriodContext implements
|
|||||||
{
|
{
|
||||||
$options = $template->getOptions();
|
$options = $template->getOptions();
|
||||||
|
|
||||||
return $options['mainPerson'] || $options['person1'] || $options['person2'];
|
return $options['mainPerson'] || $options['person1'] || $options['person2'] || $options ['thirdParty'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function contextGenerationDataNormalize(DocGeneratorTemplate $template, $entity, array $data): array
|
public function contextGenerationDataNormalize(DocGeneratorTemplate $template, $entity, array $data): array
|
||||||
@ -264,6 +315,8 @@ class AccompanyingPeriodContext implements
|
|||||||
$normalized[$k] = null !== ($data[$k] ?? null) ? $data[$k]->getId() : null;
|
$normalized[$k] = null !== ($data[$k] ?? null) ? $data[$k]->getId() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$normalized['thirdParty'] = ($data['thirdParty'] ?? null)?->getId();
|
||||||
|
|
||||||
return $normalized;
|
return $normalized;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,6 +332,12 @@ class AccompanyingPeriodContext implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (null !== ($id = ($data['thirdParty'] ?? null))) {
|
||||||
|
$denormalized['thirdParty'] = $this->thirdPartyRepository->find($id);
|
||||||
|
} else {
|
||||||
|
$denormalized['thirdParty'] = null;
|
||||||
|
}
|
||||||
|
|
||||||
return $denormalized;
|
return $denormalized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,13 +18,18 @@ use Chill\DocStoreBundle\Entity\StoredObject;
|
|||||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument;
|
||||||
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\Resource;
|
||||||
use Chill\PersonBundle\Entity\SocialWork\Evaluation;
|
use Chill\PersonBundle\Entity\SocialWork\Evaluation;
|
||||||
use Chill\PersonBundle\Repository\SocialWork\EvaluationRepository;
|
use Chill\PersonBundle\Repository\SocialWork\EvaluationRepository;
|
||||||
|
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||||
|
use Chill\ThirdPartyBundle\Templating\Entity\ThirdPartyRender;
|
||||||
|
use Chill\ThirdPartyBundle\Repository\ThirdPartyRepository;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
||||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||||
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @implements DocGeneratorContextWithPublicFormInterface<AccompanyingPeriodWorkEvaluation>
|
* @implements DocGeneratorContextWithPublicFormInterface<AccompanyingPeriodWorkEvaluation>
|
||||||
@ -43,18 +48,26 @@ class AccompanyingPeriodWorkEvaluationContext implements
|
|||||||
|
|
||||||
private TranslatableStringHelperInterface $translatableStringHelper;
|
private TranslatableStringHelperInterface $translatableStringHelper;
|
||||||
|
|
||||||
|
private ThirdPartyRender $thirdPartyRender;
|
||||||
|
|
||||||
|
private TranslatorInterface $translator;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
AccompanyingPeriodWorkContext $accompanyingPeriodWorkContext,
|
AccompanyingPeriodWorkContext $accompanyingPeriodWorkContext,
|
||||||
EntityManagerInterface $em,
|
EntityManagerInterface $em,
|
||||||
EvaluationRepository $evaluationRepository,
|
EvaluationRepository $evaluationRepository,
|
||||||
NormalizerInterface $normalizer,
|
NormalizerInterface $normalizer,
|
||||||
TranslatableStringHelperInterface $translatableStringHelper
|
TranslatableStringHelperInterface $translatableStringHelper,
|
||||||
|
ThirdPartyRender $thirdPartyRender,
|
||||||
|
TranslatorInterface $translator
|
||||||
) {
|
) {
|
||||||
$this->accompanyingPeriodWorkContext = $accompanyingPeriodWorkContext;
|
$this->accompanyingPeriodWorkContext = $accompanyingPeriodWorkContext;
|
||||||
$this->em = $em;
|
$this->em = $em;
|
||||||
$this->evaluationRepository = $evaluationRepository;
|
$this->evaluationRepository = $evaluationRepository;
|
||||||
$this->normalizer = $normalizer;
|
$this->normalizer = $normalizer;
|
||||||
$this->translatableStringHelper = $translatableStringHelper;
|
$this->translatableStringHelper = $translatableStringHelper;
|
||||||
|
$this->thirdPartyRender = $thirdPartyRender;
|
||||||
|
$this->translator = $translator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function adminFormReverseTransform(array $data): array
|
public function adminFormReverseTransform(array $data): array
|
||||||
@ -102,6 +115,31 @@ class AccompanyingPeriodWorkEvaluationContext implements
|
|||||||
public function buildPublicForm(FormBuilderInterface $builder, DocGeneratorTemplate $template, $entity): void
|
public function buildPublicForm(FormBuilderInterface $builder, DocGeneratorTemplate $template, $entity): void
|
||||||
{
|
{
|
||||||
$this->accompanyingPeriodWorkContext->buildPublicForm($builder, $template, $entity->getAccompanyingPeriodWork());
|
$this->accompanyingPeriodWorkContext->buildPublicForm($builder, $template, $entity->getAccompanyingPeriodWork());
|
||||||
|
|
||||||
|
$thirdParties = [...array_values(array_filter($entity->getAccompanyingPeriodWork()->getThirdParties()->toArray())), ...array_values(array_filter([$entity->getAccompanyingPeriodWork()->getHandlingThierParty()])), ...array_values(
|
||||||
|
array_filter(
|
||||||
|
array_map(
|
||||||
|
fn (Resource $r): ?ThirdParty => $r->getThirdParty(),
|
||||||
|
$entity->getAccompanyingPeriodWork()->getAccompanyingPeriod()->getResources()->filter(
|
||||||
|
static fn (Resource $r): bool => null !== $r->getThirdParty()
|
||||||
|
)->toArray()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)];
|
||||||
|
|
||||||
|
$options = $template->getOptions();
|
||||||
|
if ($options['thirdParty'] ?? false) {
|
||||||
|
$builder->add('thirdParty', EntityType::class, [
|
||||||
|
'class' => ThirdParty::class,
|
||||||
|
'choices' => $thirdParties,
|
||||||
|
'choice_label' => fn (ThirdParty $p) => $this->thirdPartyRender->renderString($p, []),
|
||||||
|
'multiple' => false,
|
||||||
|
'required' => false,
|
||||||
|
'expanded' => true,
|
||||||
|
'label' => $options['thirdPartyLabel'],
|
||||||
|
'placeholder' => $this->translator->trans('Any third party selected'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getData(DocGeneratorTemplate $template, $entity, array $contextGenerationData = []): array
|
public function getData(DocGeneratorTemplate $template, $entity, array $contextGenerationData = []): array
|
||||||
@ -116,7 +154,6 @@ class AccompanyingPeriodWorkEvaluationContext implements
|
|||||||
AbstractNormalizer::GROUPS => ['docgen:read'],
|
AbstractNormalizer::GROUPS => ['docgen:read'],
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,14 +26,22 @@ use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
|||||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
|
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
|
||||||
use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface;
|
use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface;
|
||||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||||
|
use Chill\PersonBundle\Entity\Person\PersonResource;
|
||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
|
use Chill\PersonBundle\Entity\Person\ResidentialAddress;
|
||||||
use Chill\PersonBundle\Repository\PersonRepository;
|
use Chill\PersonBundle\Repository\PersonRepository;
|
||||||
|
use Chill\PersonBundle\Repository\ResidentialAddressRepository;
|
||||||
|
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||||
|
use Chill\ThirdPartyBundle\Templating\Entity\ThirdPartyRender;
|
||||||
|
use Chill\ThirdPartyBundle\Repository\ThirdPartyRepository;
|
||||||
use DateTime;
|
use DateTime;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Doctrine\ORM\EntityRepository;
|
use Doctrine\ORM\EntityRepository;
|
||||||
use LogicException;
|
use LogicException;
|
||||||
|
use Service\DocGenerator\PersonContextTest;
|
||||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Component\Security\Core\Security;
|
use Symfony\Component\Security\Core\Security;
|
||||||
@ -43,6 +51,9 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
|||||||
use function array_key_exists;
|
use function array_key_exists;
|
||||||
use function count;
|
use function count;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see PersonContextTest
|
||||||
|
*/
|
||||||
final class PersonContext implements PersonContextInterface
|
final class PersonContext implements PersonContextInterface
|
||||||
{
|
{
|
||||||
private AuthorizationHelperInterface $authorizationHelper;
|
private AuthorizationHelperInterface $authorizationHelper;
|
||||||
@ -67,6 +78,12 @@ final class PersonContext implements PersonContextInterface
|
|||||||
|
|
||||||
private TranslatorInterface $translator;
|
private TranslatorInterface $translator;
|
||||||
|
|
||||||
|
private ThirdPartyRender $thirdPartyRender;
|
||||||
|
|
||||||
|
private ThirdPartyRepository $thirdPartyRepository;
|
||||||
|
|
||||||
|
private ResidentialAddressRepository $residentialAddressRepository;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
AuthorizationHelperInterface $authorizationHelper,
|
AuthorizationHelperInterface $authorizationHelper,
|
||||||
BaseContextData $baseContextData,
|
BaseContextData $baseContextData,
|
||||||
@ -78,7 +95,10 @@ final class PersonContext implements PersonContextInterface
|
|||||||
ScopeRepositoryInterface $scopeRepository,
|
ScopeRepositoryInterface $scopeRepository,
|
||||||
Security $security,
|
Security $security,
|
||||||
TranslatorInterface $translator,
|
TranslatorInterface $translator,
|
||||||
TranslatableStringHelperInterface $translatableStringHelper
|
TranslatableStringHelperInterface $translatableStringHelper,
|
||||||
|
ThirdPartyRender $thirdPartyRender,
|
||||||
|
ThirdPartyRepository $thirdPartyRepository,
|
||||||
|
ResidentialAddressRepository $residentialAddressRepository
|
||||||
) {
|
) {
|
||||||
$this->authorizationHelper = $authorizationHelper;
|
$this->authorizationHelper = $authorizationHelper;
|
||||||
$this->centerResolverManager = $centerResolverManager;
|
$this->centerResolverManager = $centerResolverManager;
|
||||||
@ -91,6 +111,9 @@ final class PersonContext implements PersonContextInterface
|
|||||||
$this->showScopes = $parameterBag->get('chill_main')['acl']['form_show_scopes'];
|
$this->showScopes = $parameterBag->get('chill_main')['acl']['form_show_scopes'];
|
||||||
$this->translator = $translator;
|
$this->translator = $translator;
|
||||||
$this->translatableStringHelper = $translatableStringHelper;
|
$this->translatableStringHelper = $translatableStringHelper;
|
||||||
|
$this->thirdPartyRender = $thirdPartyRender;
|
||||||
|
$this->thirdPartyRepository = $thirdPartyRepository;
|
||||||
|
$this->residentialAddressRepository = $residentialAddressRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function adminFormReverseTransform(array $data): array
|
public function adminFormReverseTransform(array $data): array
|
||||||
@ -110,11 +133,12 @@ final class PersonContext implements PersonContextInterface
|
|||||||
$r = [
|
$r = [
|
||||||
'mainPerson' => $data['mainPerson'] ?? false,
|
'mainPerson' => $data['mainPerson'] ?? false,
|
||||||
'mainPersonLabel' => $data['mainPersonLabel'] ?? $this->translator->trans('docgen.Main person'),
|
'mainPersonLabel' => $data['mainPersonLabel'] ?? $this->translator->trans('docgen.Main person'),
|
||||||
|
'thirdParty' => $data['thirdParty'] ?? false,
|
||||||
|
'thirdPartyLabel' => $data['thirdPartyLabel'] ?? $this->translator->trans('Third party'),
|
||||||
];
|
];
|
||||||
|
|
||||||
if (array_key_exists('category', $data)) {
|
if (array_key_exists('category', $data)) {
|
||||||
$r['category'] = array_key_exists('category', $data) ?
|
$r['category'] = $this->documentCategoryRepository->find($data['category']);
|
||||||
$this->documentCategoryRepository->find($data['category']) : null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $r;
|
return $r;
|
||||||
@ -131,6 +155,14 @@ final class PersonContext implements PersonContextInterface
|
|||||||
->setParameter('docClass', PersonDocument::class),
|
->setParameter('docClass', PersonDocument::class),
|
||||||
'choice_label' => fn ($entity = null) => $entity ? $this->translatableStringHelper->localize($entity->getName()) : '',
|
'choice_label' => fn ($entity = null) => $entity ? $this->translatableStringHelper->localize($entity->getName()) : '',
|
||||||
'required' => true,
|
'required' => true,
|
||||||
|
])
|
||||||
|
->add('thirdParty', CheckboxType::class, [
|
||||||
|
'required' => false,
|
||||||
|
'label' => 'docgen.Ask for thirdParty',
|
||||||
|
])
|
||||||
|
->add('thirdPartyLabel', TextType::class, [
|
||||||
|
'label' => 'docgen.thirdParty label',
|
||||||
|
'required' => true,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,12 +171,47 @@ final class PersonContext implements PersonContextInterface
|
|||||||
*/
|
*/
|
||||||
public function buildPublicForm(FormBuilderInterface $builder, DocGeneratorTemplate $template, $entity): void
|
public function buildPublicForm(FormBuilderInterface $builder, DocGeneratorTemplate $template, $entity): void
|
||||||
{
|
{
|
||||||
|
$options = $template->getOptions();
|
||||||
|
|
||||||
$builder->add('title', TextType::class, [
|
$builder->add('title', TextType::class, [
|
||||||
'required' => true,
|
'required' => true,
|
||||||
'label' => 'docgen.Document title',
|
'label' => 'docgen.Document title',
|
||||||
'data' => $this->translatableStringHelper->localize($template->getName()),
|
'data' => $this->translatableStringHelper->localize($template->getName()),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$thirdParties = [...array_values(
|
||||||
|
array_filter(
|
||||||
|
array_map(
|
||||||
|
fn (ResidentialAddress $r): ?ThirdParty => $r->getHostThirdParty(),
|
||||||
|
$this
|
||||||
|
->residentialAddressRepository
|
||||||
|
->findCurrentResidentialAddressByPerson($entity)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
), ...array_values(
|
||||||
|
array_filter(
|
||||||
|
array_map(
|
||||||
|
fn (PersonResource $r): ?ThirdParty => $r->getThirdParty(),
|
||||||
|
$entity->getResources()->filter(
|
||||||
|
static fn (PersonResource $r): bool => null !== $r->getThirdParty()
|
||||||
|
)->toArray()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)];
|
||||||
|
|
||||||
|
if ($options['thirdParty'] ?? false) {
|
||||||
|
$builder->add('thirdParty', EntityType::class, [
|
||||||
|
'class' => ThirdParty::class,
|
||||||
|
'choices' => $thirdParties,
|
||||||
|
'choice_label' => fn (ThirdParty $p) => $this->thirdPartyRender->renderString($p, []),
|
||||||
|
'multiple' => false,
|
||||||
|
'required' => false,
|
||||||
|
'expanded' => true,
|
||||||
|
'label' => $options['thirdPartyLabel'],
|
||||||
|
'placeholder' => $this->translator->trans('Any third party selected'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->isScopeNecessary($entity)) {
|
if ($this->isScopeNecessary($entity)) {
|
||||||
$builder->add('scope', ScopePickerType::class, [
|
$builder->add('scope', ScopePickerType::class, [
|
||||||
'center' => $this->centerResolverManager->resolveCenters($entity),
|
'center' => $this->centerResolverManager->resolveCenters($entity),
|
||||||
@ -156,10 +223,6 @@ final class PersonContext implements PersonContextInterface
|
|||||||
|
|
||||||
public function getData(DocGeneratorTemplate $template, $entity, array $contextGenerationData = []): array
|
public function getData(DocGeneratorTemplate $template, $entity, array $contextGenerationData = []): array
|
||||||
{
|
{
|
||||||
if (!$entity instanceof Person) {
|
|
||||||
throw new UnexpectedTypeException($entity, Person::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
$data = [];
|
$data = [];
|
||||||
$data = array_merge($data, $this->baseContextData->getData($contextGenerationData['creator'] ?? null));
|
$data = array_merge($data, $this->baseContextData->getData($contextGenerationData['creator'] ?? null));
|
||||||
$data['person'] = $this->normalizer->normalize($entity, 'docgen', [
|
$data['person'] = $this->normalizer->normalize($entity, 'docgen', [
|
||||||
@ -170,6 +233,13 @@ final class PersonContext implements PersonContextInterface
|
|||||||
'docgen:person:with-budget' => true,
|
'docgen:person:with-budget' => true,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
if ($template->getOptions()['thirdParty']) {
|
||||||
|
$data['thirdParty'] = $this->normalizer->normalize($contextGenerationData['thirdParty'], 'docgen', [
|
||||||
|
'docgen:expects' => ThirdParty::class,
|
||||||
|
'groups' => 'docgen:read'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,6 +293,7 @@ final class PersonContext implements PersonContextInterface
|
|||||||
return [
|
return [
|
||||||
'title' => $data['title'] ?? '',
|
'title' => $data['title'] ?? '',
|
||||||
'scope_id' => $scope instanceof Scope ? $scope->getId() : null,
|
'scope_id' => $scope instanceof Scope ? $scope->getId() : null,
|
||||||
|
'thirdParty' => ($data['thirdParty'] ?? null)?->getId(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,6 +313,7 @@ final class PersonContext implements PersonContextInterface
|
|||||||
return [
|
return [
|
||||||
'title' => $data['title'] ?? '',
|
'title' => $data['title'] ?? '',
|
||||||
'scope' => $scope,
|
'scope' => $scope,
|
||||||
|
'thirdParty' => null !== ($id = ($data['thirdParty'] ?? null)) ? $this->thirdPartyRepository->find($id) : null,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ use Symfony\Component\Form\FormBuilderInterface;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @template-extends DocGeneratorContextWithPublicFormInterface<Person>
|
* @template-extends DocGeneratorContextWithPublicFormInterface<Person>
|
||||||
|
* @template-extends DocGeneratorContextWithAdminFormInterface<Person>
|
||||||
*/
|
*/
|
||||||
interface PersonContextInterface extends DocGeneratorContextWithAdminFormInterface, DocGeneratorContextWithPublicFormInterface
|
interface PersonContextInterface extends DocGeneratorContextWithAdminFormInterface, DocGeneratorContextWithPublicFormInterface
|
||||||
{
|
{
|
||||||
|
@ -51,5 +51,4 @@ class AccompanyingPeriodStepChangeCronjobTest extends TestCase
|
|||||||
// can not run: not enough elapsed time
|
// can not run: not enough elapsed time
|
||||||
yield ['2023-01-15T01:00:00+02:00', new \DateTimeImmutable('2023-01-15T00:30:00+02:00'), false];
|
yield ['2023-01-15T01:00:00+02:00', new \DateTimeImmutable('2023-01-15T00:30:00+02:00'), false];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -78,17 +78,13 @@ final class SocialWorkTypeFilterTest extends AbstractFilterTest
|
|||||||
$goals = array_unique($goals);
|
$goals = array_unique($goals);
|
||||||
$results = array_unique($results);
|
$results = array_unique($results);
|
||||||
|
|
||||||
$data = [
|
return [
|
||||||
[
|
[
|
||||||
'actionType' => implode(',', $actions),
|
'actionType' => implode(',', $actions),
|
||||||
'goal' => implode(',', $goals),
|
'goal' => implode(',', $goals),
|
||||||
'result' => implode(',', $results),
|
'result' => implode(',', $results),
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
/// TODO ne fonctionne pas
|
|
||||||
var_dump($data);
|
|
||||||
|
|
||||||
return $data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getQueryBuilders(): array
|
public function getQueryBuilders(): array
|
||||||
|
@ -0,0 +1,291 @@
|
|||||||
|
<?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 Service\DocGenerator;
|
||||||
|
|
||||||
|
use Chill\DocGeneratorBundle\Entity\DocGeneratorTemplate;
|
||||||
|
use Chill\DocGeneratorBundle\Service\Context\BaseContextData;
|
||||||
|
use Chill\DocStoreBundle\Repository\DocumentCategoryRepository;
|
||||||
|
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||||
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
|
use Chill\PersonBundle\Entity\Person;
|
||||||
|
use Chill\PersonBundle\Repository\PersonRepository;
|
||||||
|
use Chill\PersonBundle\Service\DocGenerator\AccompanyingPeriodContext;
|
||||||
|
use Chill\PersonBundle\Templating\Entity\PersonRenderInterface;
|
||||||
|
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||||
|
use Chill\ThirdPartyBundle\Repository\ThirdPartyRepository;
|
||||||
|
use Chill\ThirdPartyBundle\Templating\Entity\ThirdPartyRender;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||||
|
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||||
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
* @coversNothing
|
||||||
|
*/
|
||||||
|
class AccompanyingPeriodContextTest extends KernelTestCase
|
||||||
|
{
|
||||||
|
private BaseContextData $baseContextData;
|
||||||
|
|
||||||
|
private DocumentCategoryRepository $documentCategoryRepository;
|
||||||
|
|
||||||
|
private EntityManagerInterface $em;
|
||||||
|
|
||||||
|
private NormalizerInterface $normalizer;
|
||||||
|
|
||||||
|
private PersonRenderInterface $personRender;
|
||||||
|
|
||||||
|
private PersonRepository $personRepository;
|
||||||
|
|
||||||
|
private TranslatableStringHelperInterface $translatableStringHelper;
|
||||||
|
|
||||||
|
private TranslatorInterface $translator;
|
||||||
|
|
||||||
|
private ThirdPartyRender $thirdPartyRender;
|
||||||
|
|
||||||
|
private ThirdPartyRepository $thirdPartyRepository;
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
self::bootKernel();
|
||||||
|
$this->baseContextData = self::$container->get(BaseContextData::class);
|
||||||
|
$this->documentCategoryRepository = self::$container->get(DocumentCategoryRepository::class);
|
||||||
|
$this->em = self::$container->get(EntityManagerInterface::class);
|
||||||
|
$this->normalizer = self::$container->get(NormalizerInterface::class);
|
||||||
|
$this->personRender = self::$container->get(PersonRenderInterface::class);
|
||||||
|
$this->personRepository = self::$container->get(PersonRepository::class);
|
||||||
|
$this->translatableStringHelper = self::$container->get(TranslatableStringHelperInterface::class);
|
||||||
|
$this->translator = self::$container->get(TranslatorInterface::class);
|
||||||
|
$this->thirdPartyRender = self::$container->get(ThirdPartyRender::class);
|
||||||
|
$this->thirdPartyRepository = self::$container->get(ThirdPartyRepository::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildContext(): AccompanyingPeriodContext
|
||||||
|
{
|
||||||
|
return new AccompanyingPeriodContext(
|
||||||
|
$this->documentCategoryRepository,
|
||||||
|
$this->normalizer,
|
||||||
|
$this->translatableStringHelper,
|
||||||
|
$this->em,
|
||||||
|
$this->personRender,
|
||||||
|
$this->personRepository,
|
||||||
|
$this->translator,
|
||||||
|
$this->baseContextData,
|
||||||
|
$this->thirdPartyRender,
|
||||||
|
$this->thirdPartyRepository,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test run the methods executed when a document is generated:
|
||||||
|
*
|
||||||
|
* - normalized data from the form in a way that they are stored in message queue;
|
||||||
|
* - denormalize the data from the message queue,
|
||||||
|
* - and get the data, as they will be transmitted to the GeneratorDriver
|
||||||
|
*
|
||||||
|
* @param array $options the options, as they are stored in the DocGeneratorTemplate (the admin form data)
|
||||||
|
* @param AccompanyingPeriod $entity The entity from which the data will be extracted
|
||||||
|
* @param array $data The data, from the public form
|
||||||
|
* @param array $expectedNormalized, how the normalized data are expected (allow to check that this data will be compliant with the storage in messenger queue)
|
||||||
|
* @param callable $assertionsOnData some test that will be executed on the normalized data
|
||||||
|
* @dataProvider provideNormalizedData
|
||||||
|
*/
|
||||||
|
public function testContextGenerationDataNormalizeDenormalizeGetData(
|
||||||
|
array $options,
|
||||||
|
AccompanyingPeriod $entity,
|
||||||
|
array $data,
|
||||||
|
array $expectedNormalized,
|
||||||
|
callable $assertionsOnData
|
||||||
|
): void {
|
||||||
|
$context = $this->buildContext();
|
||||||
|
$template = new DocGeneratorTemplate();
|
||||||
|
$template->setName(["fr" =>"test"])->setContext(AccompanyingPeriodContext::class)
|
||||||
|
->setDescription("description")->setActive(true)
|
||||||
|
->setOptions($options);
|
||||||
|
|
||||||
|
$normalized = $context->contextGenerationDataNormalize($template, $entity, $data);
|
||||||
|
|
||||||
|
self::assertEquals($expectedNormalized, $normalized);
|
||||||
|
|
||||||
|
$denormalized = $context->contextGenerationDataDenormalize($template, $entity, $normalized);
|
||||||
|
|
||||||
|
$data = $context->getData($template, $entity, $denormalized);
|
||||||
|
|
||||||
|
call_user_func($assertionsOnData, $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideNormalizedData(): iterable
|
||||||
|
{
|
||||||
|
self::bootKernel();
|
||||||
|
$em = self::$container->get(EntityManagerInterface::class);
|
||||||
|
|
||||||
|
$thirdParty = $em->createQuery("SELECT t FROM " . ThirdParty::class . " t")
|
||||||
|
->setMaxResults(1)
|
||||||
|
->getSingleResult();
|
||||||
|
|
||||||
|
if (null === $thirdParty) {
|
||||||
|
throw new \RuntimeException("No thirdparty in database");
|
||||||
|
}
|
||||||
|
|
||||||
|
$period = $em->createQuery("SELECT a FROM " . AccompanyingPeriod::class . " a WHERE a.step = 'CONFIRMED'")
|
||||||
|
->setMaxResults(1)
|
||||||
|
->getSingleResult();
|
||||||
|
|
||||||
|
if (null === $period) {
|
||||||
|
throw new \RuntimeException("No confirmed period in database");
|
||||||
|
}
|
||||||
|
|
||||||
|
$person = $em->createQuery("SELECT p FROM " . Person::class . " p")
|
||||||
|
->setMaxResults(1)
|
||||||
|
->getSingleResult();
|
||||||
|
|
||||||
|
if (null === $person) {
|
||||||
|
throw new \RuntimeException("No confirmed period in database");
|
||||||
|
}
|
||||||
|
|
||||||
|
yield [
|
||||||
|
// test with only thirdParty
|
||||||
|
[
|
||||||
|
'mainPerson' => false,
|
||||||
|
'mainPersonLabel' => 'person',
|
||||||
|
'person1' => false,
|
||||||
|
'person1Label' => 'person2',
|
||||||
|
'person2' => false,
|
||||||
|
'person2Label' => 'person2',
|
||||||
|
'thirdParty' => true,
|
||||||
|
'thirdPartyLabel' => '3party'
|
||||||
|
],
|
||||||
|
$period,
|
||||||
|
[
|
||||||
|
'thirdParty' => $thirdParty
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'thirdParty' => $thirdParty->getId(),
|
||||||
|
'mainPerson' => null,
|
||||||
|
'person1' => null,
|
||||||
|
'person2' => null,
|
||||||
|
],
|
||||||
|
function (array $data) use ($thirdParty, $period) {
|
||||||
|
self::assertArrayHasKey('thirdParty', $data);
|
||||||
|
self::assertEquals($thirdParty->getId(), $data['thirdParty']['id']);
|
||||||
|
|
||||||
|
self::assertArrayHasKey('course', $data);
|
||||||
|
self::assertEquals($period->getId(), $data['course']['id']);
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
yield [
|
||||||
|
// test with only mainPerson
|
||||||
|
[
|
||||||
|
'mainPerson' => true,
|
||||||
|
'mainPersonLabel' => 'person',
|
||||||
|
'person1' => false,
|
||||||
|
'person1Label' => 'person2',
|
||||||
|
'person2' => false,
|
||||||
|
'person2Label' => 'person2',
|
||||||
|
'thirdParty' => false,
|
||||||
|
'thirdPartyLabel' => '3party'
|
||||||
|
],
|
||||||
|
$period,
|
||||||
|
[
|
||||||
|
'mainPerson' => $person,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'thirdParty' => null,
|
||||||
|
'mainPerson' => $person->getId(),
|
||||||
|
'person1' => null,
|
||||||
|
'person2' => null,
|
||||||
|
],
|
||||||
|
function (array $data) use ($person, $period) {
|
||||||
|
self::assertArrayHasKey('mainPerson', $data);
|
||||||
|
self::assertEquals($person->getId(), $data['mainPerson']['id']);
|
||||||
|
|
||||||
|
self::assertArrayHasKey('course', $data);
|
||||||
|
self::assertEquals($period->getId(), $data['course']['id']);
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
yield [
|
||||||
|
// test with every options activated
|
||||||
|
[
|
||||||
|
'mainPerson' => true,
|
||||||
|
'mainPersonLabel' => 'person',
|
||||||
|
'person1' => true,
|
||||||
|
'person1Label' => 'person2',
|
||||||
|
'person2' => true,
|
||||||
|
'person2Label' => 'person2',
|
||||||
|
'thirdParty' => true,
|
||||||
|
'thirdPartyLabel' => '3party'
|
||||||
|
],
|
||||||
|
$period,
|
||||||
|
[
|
||||||
|
'mainPerson' => $person,
|
||||||
|
'person1' => $person,
|
||||||
|
'person2' => $person,
|
||||||
|
'thirdParty' => $thirdParty,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'thirdParty' => $thirdParty->getId(),
|
||||||
|
'mainPerson' => $person->getId(),
|
||||||
|
'person1' => $person->getId(),
|
||||||
|
'person2' => $person->getId(),
|
||||||
|
],
|
||||||
|
function (array $data) use ($person, $thirdParty, $period) {
|
||||||
|
self::assertArrayHasKey('mainPerson', $data);
|
||||||
|
self::assertEquals($person->getId(), $data['mainPerson']['id']);
|
||||||
|
|
||||||
|
self::assertArrayHasKey('person1', $data);
|
||||||
|
self::assertEquals($person->getId(), $data['person1']['id']);
|
||||||
|
|
||||||
|
self::assertArrayHasKey('person2', $data);
|
||||||
|
self::assertEquals($person->getId(), $data['person2']['id']);
|
||||||
|
|
||||||
|
self::assertArrayHasKey('thirdParty', $data);
|
||||||
|
self::assertEquals($thirdParty->getId(), $data['thirdParty']['id']);
|
||||||
|
|
||||||
|
self::assertArrayHasKey('course', $data);
|
||||||
|
self::assertEquals($period->getId(), $data['course']['id']);
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
yield [
|
||||||
|
// test with any option activated
|
||||||
|
[
|
||||||
|
'mainPerson' => false,
|
||||||
|
'mainPersonLabel' => 'person',
|
||||||
|
'person1' => false,
|
||||||
|
'person1Label' => 'person2',
|
||||||
|
'person2' => false,
|
||||||
|
'person2Label' => 'person2',
|
||||||
|
'thirdParty' => false,
|
||||||
|
'thirdPartyLabel' => '3party'
|
||||||
|
],
|
||||||
|
$period,
|
||||||
|
[
|
||||||
|
'mainPerson' => null,
|
||||||
|
'person1' => null,
|
||||||
|
'person2' => null,
|
||||||
|
'thirdParty' => null,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'thirdParty' => null,
|
||||||
|
'mainPerson' => null,
|
||||||
|
'person1' => null,
|
||||||
|
'person2' => null,
|
||||||
|
],
|
||||||
|
function (array $data) use ($period) {
|
||||||
|
self::assertArrayHasKey('course', $data);
|
||||||
|
self::assertEquals($period->getId(), $data['course']['id']);
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -18,20 +18,30 @@ use Chill\DocStoreBundle\Entity\PersonDocument;
|
|||||||
use Chill\DocStoreBundle\Entity\StoredObject;
|
use Chill\DocStoreBundle\Entity\StoredObject;
|
||||||
use Chill\DocStoreBundle\Repository\DocumentCategoryRepository;
|
use Chill\DocStoreBundle\Repository\DocumentCategoryRepository;
|
||||||
use Chill\DocStoreBundle\Security\Authorization\PersonDocumentVoter;
|
use Chill\DocStoreBundle\Security\Authorization\PersonDocumentVoter;
|
||||||
|
use Chill\MainBundle\Entity\Address;
|
||||||
use Chill\MainBundle\Entity\Center;
|
use Chill\MainBundle\Entity\Center;
|
||||||
|
use Chill\MainBundle\Entity\PostalCode;
|
||||||
use Chill\MainBundle\Entity\Scope;
|
use Chill\MainBundle\Entity\Scope;
|
||||||
use Chill\MainBundle\Entity\User;
|
use Chill\MainBundle\Entity\User;
|
||||||
use Chill\MainBundle\Form\Type\ScopePickerType;
|
use Chill\MainBundle\Form\Type\ScopePickerType;
|
||||||
|
use Chill\MainBundle\Repository\ScopeRepositoryInterface;
|
||||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
|
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
|
||||||
use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface;
|
use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface;
|
||||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||||
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
|
use Chill\PersonBundle\Repository\ResidentialAddressRepository;
|
||||||
|
use Chill\PersonBundle\Service\DocGenerator\AccompanyingPeriodContext;
|
||||||
use Chill\PersonBundle\Service\DocGenerator\PersonContext;
|
use Chill\PersonBundle\Service\DocGenerator\PersonContext;
|
||||||
|
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||||
|
use Chill\ThirdPartyBundle\Repository\ThirdPartyRepository;
|
||||||
|
use Chill\ThirdPartyBundle\Templating\Entity\ThirdPartyRender;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Prophecy\Argument;
|
use Prophecy\Argument;
|
||||||
use Prophecy\Exception\Prediction\FailedPredictionException;
|
use Prophecy\Exception\Prediction\FailedPredictionException;
|
||||||
use Prophecy\PhpUnit\ProphecyTrait;
|
use Prophecy\PhpUnit\ProphecyTrait;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
||||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||||
@ -46,10 +56,142 @@ use function count;
|
|||||||
* @internal
|
* @internal
|
||||||
* @coversNothing
|
* @coversNothing
|
||||||
*/
|
*/
|
||||||
final class PersonContextTest extends TestCase
|
final class PersonContextTest extends KernelTestCase
|
||||||
{
|
{
|
||||||
use ProphecyTrait;
|
use ProphecyTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test run the methods executed when a document is generated:
|
||||||
|
*
|
||||||
|
* - normalized data from the form in a way that they are stored in message queue;
|
||||||
|
* - denormalize the data from the message queue,
|
||||||
|
* - and get the data, as they will be transmitted to the GeneratorDriver
|
||||||
|
*
|
||||||
|
* @param array $options the options, as they are stored in the DocGeneratorTemplate (the admin form data)
|
||||||
|
* @param Person $entity The entity from which the data will be extracted
|
||||||
|
* @param array $data The data, from the public form
|
||||||
|
* @param array $expectedNormalized, how the normalized data are expected (allow to check that this data will be compliant with the storage in messenger queue)
|
||||||
|
* @param callable $assertionsOnData some test that will be executed on the normalized data
|
||||||
|
* @dataProvider provideNormalizedData
|
||||||
|
*/
|
||||||
|
public function testContextGenerationDataNormalizeDenormalizeGetData(
|
||||||
|
array $options,
|
||||||
|
Person $entity,
|
||||||
|
array $data,
|
||||||
|
array $expectedNormalized,
|
||||||
|
callable $assertionsOnData
|
||||||
|
): void {
|
||||||
|
// we boot kernel only for this test
|
||||||
|
self::bootKernel();
|
||||||
|
|
||||||
|
// we create a PersonContext with the minimal dependency injection needed (relying on
|
||||||
|
// prophecy for other dependencies)
|
||||||
|
$context = $this->buildPersonContext(
|
||||||
|
null,
|
||||||
|
self::$container->get(BaseContextData::class),
|
||||||
|
self::$container->get(CenterResolverManagerInterface::class),
|
||||||
|
self::$container->get(DocumentCategoryRepository::class),
|
||||||
|
self::$container->get(EntityManagerInterface::class),
|
||||||
|
self::$container->get(NormalizerInterface::class),
|
||||||
|
(new ParameterBag(['chill_main' => ['acl' => ['form_show_scopes' => false]]])),
|
||||||
|
null,
|
||||||
|
self::$container->get(Security::class),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
self::$container->get(ThirdPartyRepository::class)
|
||||||
|
);
|
||||||
|
$template = new DocGeneratorTemplate();
|
||||||
|
$template->setName(["fr" =>"test"])->setContext(AccompanyingPeriodContext::class)
|
||||||
|
->setDescription("description")->setActive(true)
|
||||||
|
->setOptions($options);
|
||||||
|
|
||||||
|
$normalized = $context->contextGenerationDataNormalize($template, $entity, $data);
|
||||||
|
|
||||||
|
self::assertEquals($expectedNormalized, $normalized);
|
||||||
|
|
||||||
|
$denormalized = $context->contextGenerationDataDenormalize($template, $entity, $normalized);
|
||||||
|
|
||||||
|
$data = $context->getData($template, $entity, $denormalized);
|
||||||
|
|
||||||
|
call_user_func($assertionsOnData, $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideNormalizedData(): iterable
|
||||||
|
{
|
||||||
|
self::bootKernel();
|
||||||
|
$em = self::$container->get(EntityManagerInterface::class);
|
||||||
|
|
||||||
|
$thirdParty = $em->createQuery("SELECT t FROM " . ThirdParty::class . " t")
|
||||||
|
->setMaxResults(1)
|
||||||
|
->getSingleResult();
|
||||||
|
|
||||||
|
if (null === $thirdParty) {
|
||||||
|
throw new \RuntimeException("No thirdparty in database");
|
||||||
|
}
|
||||||
|
|
||||||
|
$person = $em->createQuery("SELECT p FROM " . Person::class . " p")
|
||||||
|
->setMaxResults(1)
|
||||||
|
->getSingleResult();
|
||||||
|
|
||||||
|
if (null === $person) {
|
||||||
|
throw new \RuntimeException("No confirmed period in database");
|
||||||
|
}
|
||||||
|
|
||||||
|
$category = self::$container->get(DocumentCategoryRepository::class)
|
||||||
|
->findAll()[0];
|
||||||
|
|
||||||
|
if (null === $category) {
|
||||||
|
throw new \RuntimeException("no document category in database");
|
||||||
|
}
|
||||||
|
|
||||||
|
yield [
|
||||||
|
[
|
||||||
|
'thirdParty' => true,
|
||||||
|
'thirdPartyLabel' => '3party',
|
||||||
|
'category' => $category,
|
||||||
|
],
|
||||||
|
$person,
|
||||||
|
[
|
||||||
|
'title' => 'test',
|
||||||
|
'thirdParty' => $thirdParty,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'thirdParty' => $thirdParty->getId(),
|
||||||
|
'title' => 'test',
|
||||||
|
'scope_id' => null,
|
||||||
|
],
|
||||||
|
function ($data) use ($person, $thirdParty) {
|
||||||
|
self::assertArrayHasKey('person', $data);
|
||||||
|
self::assertEquals($person->getId(), $data['person']['id']);
|
||||||
|
|
||||||
|
self::assertArrayHasKey('thirdParty', $data);
|
||||||
|
self::assertEquals($thirdParty->getId(), $data['thirdParty']['id']);
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
yield [
|
||||||
|
[
|
||||||
|
'thirdParty' => false,
|
||||||
|
'thirdPartyLabel' => '3party',
|
||||||
|
'category' => $category,
|
||||||
|
],
|
||||||
|
$person,
|
||||||
|
[
|
||||||
|
'title' => 'test',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'title' => 'test',
|
||||||
|
'scope_id' => null,
|
||||||
|
'thirdParty' => null,
|
||||||
|
],
|
||||||
|
function ($data) use ($person, $thirdParty) {
|
||||||
|
self::assertArrayHasKey('person', $data);
|
||||||
|
self::assertEquals($person->getId(), $data['person']['id']);
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test that the build person context works in the case when 'form_show_scope' is false.
|
* Test that the build person context works in the case when 'form_show_scope' is false.
|
||||||
*/
|
*/
|
||||||
@ -208,9 +350,13 @@ final class PersonContextTest extends TestCase
|
|||||||
?EntityManagerInterface $em = null,
|
?EntityManagerInterface $em = null,
|
||||||
?NormalizerInterface $normalizer = null,
|
?NormalizerInterface $normalizer = null,
|
||||||
?ParameterBagInterface $parameterBag = null,
|
?ParameterBagInterface $parameterBag = null,
|
||||||
|
?ScopeRepositoryInterface $scopeRepository = null,
|
||||||
?Security $security = null,
|
?Security $security = null,
|
||||||
?TranslatorInterface $translator = null,
|
?TranslatorInterface $translator = null,
|
||||||
?TranslatableStringHelperInterface $translatableStringHelper = null
|
?TranslatableStringHelperInterface $translatableStringHelper = null,
|
||||||
|
?ThirdPartyRender $thirdPartyRender = null,
|
||||||
|
?ThirdPartyRepository $thirdPartyRepository = null,
|
||||||
|
?ResidentialAddressRepository $residentialAddressRepository = null
|
||||||
): PersonContext {
|
): PersonContext {
|
||||||
if (null === $authorizationHelper) {
|
if (null === $authorizationHelper) {
|
||||||
$authorizationHelper = $this->prophesize(AuthorizationHelperInterface::class)->reveal();
|
$authorizationHelper = $this->prophesize(AuthorizationHelperInterface::class)->reveal();
|
||||||
@ -250,6 +396,11 @@ final class PersonContextTest extends TestCase
|
|||||||
$parameterBag = new ParameterBag(['chill_main' => ['acl' => ['form_show_scopes' => true]]]);
|
$parameterBag = new ParameterBag(['chill_main' => ['acl' => ['form_show_scopes' => true]]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (null === $scopeRepository) {
|
||||||
|
$scopeRepository = $this->prophesize(ScopeRepositoryInterface::class);
|
||||||
|
$scopeRepository = $scopeRepository->reveal();
|
||||||
|
}
|
||||||
|
|
||||||
if (null === $security) {
|
if (null === $security) {
|
||||||
$security = $this->prophesize(Security::class);
|
$security = $this->prophesize(Security::class);
|
||||||
$security->getUser()->willReturn(new User());
|
$security->getUser()->willReturn(new User());
|
||||||
@ -267,6 +418,28 @@ final class PersonContextTest extends TestCase
|
|||||||
$translatableStringHelper = $translatableStringHelper->reveal();
|
$translatableStringHelper = $translatableStringHelper->reveal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (null === $thirdPartyRender) {
|
||||||
|
$thirdPartyRender = $this->prophesize(ThirdPartyRender::class);
|
||||||
|
$thirdPartyRender = $thirdPartyRender->reveal();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $thirdPartyRepository) {
|
||||||
|
$thirdPartyRepository = $this->prophesize(ThirdPartyRepository::class);
|
||||||
|
$thirdPartyRepository = $thirdPartyRepository->reveal();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $residentialAddressRepository) {
|
||||||
|
$residentialAddressRepository = $this->prophesize(ResidentialAddressRepository::class);
|
||||||
|
$residentialAddressRepository->findCurrentResidentialAddressByPerson(Argument::type(Person::class), Argument::any())
|
||||||
|
->willReturn([
|
||||||
|
(new Person\ResidentialAddress())
|
||||||
|
->setAddress((new Address())
|
||||||
|
->setStreet('test street')
|
||||||
|
->setPostcode(new PostalCode()))
|
||||||
|
]);
|
||||||
|
$residentialAddressRepository = $residentialAddressRepository->reveal();
|
||||||
|
}
|
||||||
|
|
||||||
return new PersonContext(
|
return new PersonContext(
|
||||||
$authorizationHelper,
|
$authorizationHelper,
|
||||||
$baseContextData,
|
$baseContextData,
|
||||||
@ -275,9 +448,13 @@ final class PersonContextTest extends TestCase
|
|||||||
$em,
|
$em,
|
||||||
$normalizer,
|
$normalizer,
|
||||||
$parameterBag,
|
$parameterBag,
|
||||||
|
$scopeRepository,
|
||||||
$security,
|
$security,
|
||||||
$translator,
|
$translator,
|
||||||
$translatableStringHelper
|
$translatableStringHelper,
|
||||||
|
$thirdPartyRender,
|
||||||
|
$thirdPartyRepository,
|
||||||
|
$residentialAddressRepository
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -927,10 +927,10 @@ docgen:
|
|||||||
Accompanying period work: "Action d'accompagnement"
|
Accompanying period work: "Action d'accompagnement"
|
||||||
Accompanying period work context: "Evaluation des actions d'accompagnement"
|
Accompanying period work context: "Evaluation des actions d'accompagnement"
|
||||||
Main person: Usager principal
|
Main person: Usager principal
|
||||||
person 1: Premièr usager
|
person 1: Premier usager
|
||||||
person 2: Second usager
|
person 2: Second usager
|
||||||
Ask for main person: Demander à l'utilisateur de préciser l'usager principal
|
Ask for main person: Demander à l'utilisateur de préciser l'usager principal
|
||||||
Ask for person 1: Demander à l'utilisateur de préciser le premièr usager
|
Ask for person 1: Demander à l'utilisateur de préciser le premier usager
|
||||||
Ask for person 2: Demander à l'utilisateur de préciser le second usager
|
Ask for person 2: Demander à l'utilisateur de préciser le second usager
|
||||||
A basic context for accompanying period: Contexte pour les parcours
|
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: Contexte pour les actions d'accompagnement
|
||||||
|
@ -166,7 +166,7 @@ class LoadReports extends AbstractFixture implements ContainerAwareInterface, Or
|
|||||||
/**
|
/**
|
||||||
* pick a random choice.
|
* pick a random choice.
|
||||||
*
|
*
|
||||||
* @return string|string[] the array of slug if multiple, a single slug otherwise
|
* @return string|string[]
|
||||||
*/
|
*/
|
||||||
private function getRandomChoice(CustomField $field)
|
private function getRandomChoice(CustomField $field)
|
||||||
{
|
{
|
||||||
@ -211,6 +211,8 @@ class LoadReports extends AbstractFixture implements ContainerAwareInterface, Or
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $picked;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -226,7 +228,7 @@ class LoadReports extends AbstractFixture implements ContainerAwareInterface, Or
|
|||||||
/**
|
/**
|
||||||
* pick a choice within a 'choices' options (for choice type).
|
* pick a choice within a 'choices' options (for choice type).
|
||||||
*
|
*
|
||||||
* @return the slug of the selected choice
|
* @return string the slug of the selected choice
|
||||||
*/
|
*/
|
||||||
private function pickChoice(array $choices)
|
private function pickChoice(array $choices)
|
||||||
{
|
{
|
||||||
|
@ -21,7 +21,7 @@ use DomainException;
|
|||||||
|
|
||||||
use function array_key_exists;
|
use function array_key_exists;
|
||||||
|
|
||||||
final class ThirdPartyRepository implements ObjectRepository
|
class ThirdPartyRepository implements ObjectRepository
|
||||||
{
|
{
|
||||||
private EntityRepository $repository;
|
private EntityRepository $repository;
|
||||||
|
|
||||||
|
@ -75,6 +75,7 @@ No email given: Aucune adresse courriel renseignée
|
|||||||
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
|
||||||
No third parties: Aucun tiers
|
No third parties: Aucun tiers
|
||||||
|
Any third party selected: Aucun tiers sélectionné
|
||||||
|
|
||||||
Thirdparty handling: Tiers traitant
|
Thirdparty handling: Tiers traitant
|
||||||
Thirdparty workers: Tiers intervenants
|
Thirdparty workers: Tiers intervenants
|
||||||
@ -112,6 +113,8 @@ crud:
|
|||||||
docgen:
|
docgen:
|
||||||
A context for person with a third party (for sending mail): Un contexte d'une personne avec un tiers (pour envoyer un courrier à ce tiers, par exemple)
|
A context for person with a third party (for sending mail): Un contexte d'une personne avec un tiers (pour envoyer un courrier à ce tiers, par exemple)
|
||||||
Person with third party: Personne avec choix d'un tiers
|
Person with third party: Personne avec choix d'un tiers
|
||||||
|
Ask for thirdParty: Demander à l'utilisateur de préciser un tiers
|
||||||
|
thirdParty label: Libellé du tiers
|
||||||
|
|
||||||
# exports
|
# exports
|
||||||
export:
|
export:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user