mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Merge branch '323-related-entity-permission-give-from-workflow' into signature-app-master
This commit is contained in:
commit
903a87c589
@ -1,6 +0,0 @@
|
||||
kind: Fixed
|
||||
body: Show only the current referrer in the page "show" for an accompanying period
|
||||
workf
|
||||
time: 2024-09-16T15:18:43.017401122+02:00
|
||||
custom:
|
||||
Issue: "308"
|
6
.changes/v3.1.1.md
Normal file
6
.changes/v3.1.1.md
Normal file
@ -0,0 +1,6 @@
|
||||
## v3.1.1 - 2024-10-01
|
||||
### Fixed
|
||||
* ([#308](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/308)) Show only the current referrer in the page "show" for an accompanying period workf
|
||||
* ([#309](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/309)) Correctly compute the grouping by referrer aggregator
|
||||
|
||||
* Fixed typing of custom field long choice and custom field group
|
3
.changes/v3.2.0.md
Normal file
3
.changes/v3.2.0.md
Normal file
@ -0,0 +1,3 @@
|
||||
## v3.2.0 - 2024-10-30
|
||||
### Feature
|
||||
* Introduce a gender entity
|
4
.changes/v3.2.1.md
Normal file
4
.changes/v3.2.1.md
Normal file
@ -0,0 +1,4 @@
|
||||
## v3.2.1 - 2024-10-31
|
||||
### Fixed
|
||||
* Add the possibility of unknown to the gender entity
|
||||
* Fix the fusion of person doubles by excluding accompanyingPeriod work entities to be deleted. They are moved instead.
|
3
.changes/v3.2.2.md
Normal file
3
.changes/v3.2.2.md
Normal file
@ -0,0 +1,3 @@
|
||||
## v3.2.2 - 2024-10-31
|
||||
### Fixed
|
||||
* Fix gender translation for unknown
|
4
.changes/v3.2.3.md
Normal file
4
.changes/v3.2.3.md
Normal file
@ -0,0 +1,4 @@
|
||||
## v3.2.3 - 2024-11-05
|
||||
### Fixed
|
||||
* ([#315](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/315)) Fix display of accompanying period work referrers. Only current referrers should be displayed.
|
||||
Fix color of Chill footer
|
3
.changes/v3.2.4.md
Normal file
3
.changes/v3.2.4.md
Normal file
@ -0,0 +1,3 @@
|
||||
## v3.2.4 - 2024-11-06
|
||||
### Fixed
|
||||
* Fix compilation of chill assets
|
227
CHANGELOG.md
227
CHANGELOG.md
@ -6,22 +6,57 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html),
|
||||
and is generated by [Changie](https://github.com/miniscruff/changie).
|
||||
|
||||
|
||||
## v3.2.4 - 2024-11-06
|
||||
### Fixed
|
||||
* Fix compilation of chill assets
|
||||
|
||||
## v3.2.3 - 2024-11-05
|
||||
### Fixed
|
||||
* ([#315](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/315)) Fix display of accompanying period work referrers. Only current referrers should be displayed.
|
||||
Fix color of Chill footer
|
||||
|
||||
## v3.2.2 - 2024-10-31
|
||||
### Fixed
|
||||
* Fix gender translation for unknown
|
||||
|
||||
## v3.2.1 - 2024-10-31
|
||||
### Fixed
|
||||
* Add the possibility of unknown to the gender entity
|
||||
* Fix the fusion of person doubles by excluding accompanyingPeriod work entities to be deleted. They are moved instead.
|
||||
|
||||
## v3.2.0 - 2024-10-30
|
||||
### Feature
|
||||
* Introduce a gender entity
|
||||
|
||||
## v3.1.1 - 2024-10-01
|
||||
### Fixed
|
||||
* ([#308](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/308)) Show only the current referrer in the page "show" for an accompanying period workf
|
||||
* ([#309](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/309)) Correctly compute the grouping by referrer aggregator
|
||||
|
||||
* Fixed typing of custom field long choice and custom field group
|
||||
|
||||
## v3.1.0 - 2024-08-30
|
||||
### Feature
|
||||
* Add export aggregator to aggregate activities by household + filter persons that are not part of an accompanyingperiod during a certain timeframe.
|
||||
* Add export aggregator to aggregate activities by household + filter persons that are not part of an accompanyingperiod during a certain timeframe.
|
||||
|
||||
## v3.0.0 - 2024-08-26
|
||||
### Fixed
|
||||
* Fix delete action for accompanying periods in draft state
|
||||
* Fix connection to azure when making an calendar event in chill
|
||||
* CollectionType js fixes for remove button and adding multiple entries
|
||||
* Fix delete action for accompanying periods in draft state
|
||||
* Fix connection to azure when making an calendar event in chill
|
||||
* CollectionType js fixes for remove button and adding multiple entries
|
||||
|
||||
## v2.24.0 - 2024-09-11
|
||||
### Feature
|
||||
* ([#306](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/306)) When a document is converted or downloaded in the browser, this document is removed from the browser memory after 45s. Future click on the button re-download the document.
|
||||
* ([#306](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/306)) When a document is converted or downloaded in the browser, this document is removed from the browser memory after 45s. Future click on the button re-download the document.
|
||||
|
||||
## v2.23.0 - 2024-07-19 & 2024-07-23
|
||||
## v2.23.0 - 2024-07-23 & 2024-07-19
|
||||
### Feature
|
||||
* ([#221](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/221)) [DX] move async-upload-bundle features into chill-bundles
|
||||
* Add job bundle (module emploi)
|
||||
* Upgrade import of address list to the last version of compiled addresses of belgian-best-address
|
||||
|
||||
* Upgrade CKEditor and refactor configuration with use of typescript
|
||||
|
||||
* ([#123](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/123)) Add a button to duplicate calendar ranges from a week to another one
|
||||
* [admin] filter users by active / inactive in the admin user's list
|
||||
* ([#273](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/273)) Add the possibility to mark all notifications as read
|
||||
@ -31,6 +66,8 @@ and is generated by [Changie](https://github.com/miniscruff/changie).
|
||||
* Do not update the "createdAt" column when importing postal code which does not change
|
||||
* Display filename on file upload within the UI interface
|
||||
### Fixed
|
||||
* Fix resolving of centers for an household, which will fix in turn the access control
|
||||
* Resolved type hinting error in activity list export
|
||||
* ([#271](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/271)) Take into account the acp closing date in the acp works date filter
|
||||
|
||||
### Traduction française des principaux changements
|
||||
@ -43,25 +80,15 @@ and is generated by [Changie](https://github.com/miniscruff/changie).
|
||||
- Agrandit l'icône du type de fichier dans l'interface de dépôt de fichier;
|
||||
- correction: tient compte de la date de fermeture du parcours dans les filtres sur les actions d'accompagnement.
|
||||
|
||||
* ([#221](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/221)) [DX] move async-upload-bundle features into chill-bundles
|
||||
* Add job bundle (module emploi)
|
||||
* Upgrade import of address list to the last version of compiled addresses of belgian-best-address
|
||||
|
||||
* Upgrade CKEditor and refactor configuration with use of typescript
|
||||
|
||||
### Fixed
|
||||
* Fix resolving of centers for an household, which will fix in turn the access control
|
||||
* Resolved type hinting error in activity list export
|
||||
|
||||
## v2.22.2 - 2024-07-03
|
||||
### Fixed
|
||||
* Remove scope required for event participation stats
|
||||
* Remove scope required for event participation stats
|
||||
|
||||
## v2.22.1 - 2024-07-01
|
||||
### Fixed
|
||||
* Remove debug word
|
||||
* Remove debug word
|
||||
### DX
|
||||
* Add a command for reading official address DB from Luxembourg and update chill addresses
|
||||
* Add a command for reading official address DB from Luxembourg and update chill addresses
|
||||
|
||||
## v2.22.0 - 2024-06-25
|
||||
### Feature
|
||||
@ -104,7 +131,7 @@ and is generated by [Changie](https://github.com/miniscruff/changie).
|
||||
|
||||
## v2.20.1 - 2024-06-05
|
||||
### Fixed
|
||||
* Do not allow StoredObjectCreated for edit and convert buttons
|
||||
* Do not allow StoredObjectCreated for edit and convert buttons
|
||||
|
||||
## v2.20.0 - 2024-06-05
|
||||
### Fixed
|
||||
@ -151,96 +178,96 @@ and is generated by [Changie](https://github.com/miniscruff/changie).
|
||||
|
||||
## v2.18.2 - 2024-04-12
|
||||
### Fixed
|
||||
* ([#250](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/250)) Postal codes import : fix the source URL and the keys to handle each record
|
||||
* ([#250](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/250)) Postal codes import : fix the source URL and the keys to handle each record
|
||||
|
||||
## v2.18.1 - 2024-03-26
|
||||
### Fixed
|
||||
* Fix layout issue in document generation for admin (minor)
|
||||
* Fix layout issue in document generation for admin (minor)
|
||||
|
||||
## v2.18.0 - 2024-03-26
|
||||
### Feature
|
||||
* ([#268](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/268)) Improve admin UX to configure document templates for document generation
|
||||
* ([#268](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/268)) Improve admin UX to configure document templates for document generation
|
||||
### Fixed
|
||||
* ([#267](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/267)) Fix the join between job and user in the user list (admin): show only the current user job
|
||||
* ([#267](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/267)) Fix the join between job and user in the user list (admin): show only the current user job
|
||||
|
||||
## v2.17.0 - 2024-03-19
|
||||
### Feature
|
||||
* ([#237](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/237)) New export filter for social actions with an evaluation created between two dates
|
||||
* ([#258](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/258)) In the list of accompangying period, add the list of person's centers and the duration of the course
|
||||
* ([#238](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/238)) Allow to customize list person with new fields
|
||||
* ([#237](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/237)) New export filter for social actions with an evaluation created between two dates
|
||||
* ([#258](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/258)) In the list of accompangying period, add the list of person's centers and the duration of the course
|
||||
* ([#238](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/238)) Allow to customize list person with new fields
|
||||
* ([#159](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/159)) Admin can publish news on the homepage
|
||||
### Fixed
|
||||
* ([#264](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/264)) Fix languages: load the languages in all availables languages configured for Chill
|
||||
* ([#259](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/259)) Keep a consistent behaviour between the filtering of activities within the document generation (model "accompanying period with activities"), and the same filter in the list of activities for an accompanying period
|
||||
* ([#264](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/264)) Fix languages: load the languages in all availables languages configured for Chill
|
||||
* ([#259](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/259)) Keep a consistent behaviour between the filtering of activities within the document generation (model "accompanying period with activities"), and the same filter in the list of activities for an accompanying period
|
||||
|
||||
## v2.16.3 - 2024-02-26
|
||||
### Fixed
|
||||
* ([#236](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/236)) Fix translation of user job -> 'service' must be 'métier'
|
||||
* ([#236](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/236)) Fix translation of user job -> 'service' must be 'métier'
|
||||
### UX
|
||||
* ([#232](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/232)) Order user jobs and services alphabetically in export filters
|
||||
* ([#232](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/232)) Order user jobs and services alphabetically in export filters
|
||||
|
||||
## v2.16.2 - 2024-02-21
|
||||
### Fixed
|
||||
* Check for null values in closing motive of parcours d'accompagnement for correct rendering of template
|
||||
* Check for null values in closing motive of parcours d'accompagnement for correct rendering of template
|
||||
|
||||
## v2.16.1 - 2024-02-09
|
||||
### Fixed
|
||||
* Force bootstrap version to avoid error in builds with newer version
|
||||
* Force bootstrap version to avoid error in builds with newer version
|
||||
|
||||
## v2.16.0 - 2024-02-08
|
||||
### Feature
|
||||
* ([#231](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/231)) Create new filter for persons having a participation in an accompanying period during a certain time span
|
||||
* ([#241](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/241)) [Export][List of accompanyign period] Add two columns: the list of persons participating to the period, and their ids
|
||||
* ([#244](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/244)) Add capability to generate export about change of steps of accompanying period, and generate exports for this
|
||||
* ([#253](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/253)) Export: group accompanying period by person participating
|
||||
* ([#243](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/243)) Export: add filter for courses not linked to a reference address
|
||||
* ([#229](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/229)) Allow to group activities linked with accompanying period by reason
|
||||
* ([#115](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/115)) Prevent social work to be saved when another user edited conccurently the social work
|
||||
* Modernize the event bundle, with some new fields and multiple improvements
|
||||
* ([#231](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/231)) Create new filter for persons having a participation in an accompanying period during a certain time span
|
||||
* ([#241](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/241)) [Export][List of accompanyign period] Add two columns: the list of persons participating to the period, and their ids
|
||||
* ([#244](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/244)) Add capability to generate export about change of steps of accompanying period, and generate exports for this
|
||||
* ([#253](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/253)) Export: group accompanying period by person participating
|
||||
* ([#243](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/243)) Export: add filter for courses not linked to a reference address
|
||||
* ([#229](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/229)) Allow to group activities linked with accompanying period by reason
|
||||
* ([#115](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/115)) Prevent social work to be saved when another user edited conccurently the social work
|
||||
* Modernize the event bundle, with some new fields and multiple improvements
|
||||
### Fixed
|
||||
* ([#220](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/220)) Fix error in logs about wrong typing of eventArgs in onEditNotificationComment method
|
||||
* ([#256](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/256)) Fix the conditions upon which social actions should be optional or required in relation to social issues within the activity creation form
|
||||
* ([#220](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/220)) Fix error in logs about wrong typing of eventArgs in onEditNotificationComment method
|
||||
* ([#256](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/256)) Fix the conditions upon which social actions should be optional or required in relation to social issues within the activity creation form
|
||||
### UX
|
||||
* ([#260](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/260)) Order list of centers alphabetically in dropdown 'user' section admin.
|
||||
* ([#260](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/260)) Order list of centers alphabetically in dropdown 'user' section admin.
|
||||
|
||||
## v2.15.2 - 2024-01-11
|
||||
### Fixed
|
||||
* Fix the id_seq used when creating a new accompanying period participation during fusion of two person files
|
||||
* Fix the id_seq used when creating a new accompanying period participation during fusion of two person files
|
||||
### DX
|
||||
* Set placeholder to False for expanded EntityType form fields where required is set to False.
|
||||
* Set placeholder to False for expanded EntityType form fields where required is set to False.
|
||||
|
||||
## v2.15.1 - 2023-12-20
|
||||
### Fixed
|
||||
* Fix the household export query to exclude accompanying periods that are in draft state.
|
||||
* Fix the household export query to exclude accompanying periods that are in draft state.
|
||||
### DX
|
||||
* ([#167](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/167)) Fixed readthedocs compilation by updating readthedocs config file and requirements for Sphinx
|
||||
* ([#167](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/167)) Fixed readthedocs compilation by updating readthedocs config file and requirements for Sphinx
|
||||
|
||||
## v2.15.0 - 2023-12-11
|
||||
### Feature
|
||||
* ([#191](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/191)) Add export "number of household associate with an exchange"
|
||||
* ([#235](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/235)) Export: add dates on the filter "filter course by activity type"
|
||||
* ([#191](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/191)) Add export "number of household associate with an exchange"
|
||||
* ([#235](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/235)) Export: add dates on the filter "filter course by activity type"
|
||||
### Fixed
|
||||
* ([#214](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/214)) Fix error when posting an empty comment on an accompanying period.
|
||||
* ([#233](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/233)) Fix "filter evaluation by evaluation type" (and add select2 to the list of evaluation types to pick)
|
||||
* ([#214](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/214)) Fix error when posting an empty comment on an accompanying period.
|
||||
* ([#233](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/233)) Fix "filter evaluation by evaluation type" (and add select2 to the list of evaluation types to pick)
|
||||
* ([#234](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/234)) Fix "filter aside activity by date"
|
||||
|
||||
* ([#228](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/228)) Fix export of activity for people created before the introduction of the createdAt column on person (during v1)
|
||||
* ([#246](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/246)) Do not show activities, evaluations and social work when associated to a confidential accompanying period, except for the users which are allowed to see them
|
||||
|
||||
* ([#228](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/228)) Fix export of activity for people created before the introduction of the createdAt column on person (during v1)
|
||||
* ([#246](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/246)) Do not show activities, evaluations and social work when associated to a confidential accompanying period, except for the users which are allowed to see them
|
||||
|
||||
## v2.14.1 - 2023-11-29
|
||||
### Fixed
|
||||
* Export: fix list person with custom fields
|
||||
* ([#100](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/100)) Add a paginator to budget elements (resource and charge types) in the admin
|
||||
* Fix error in ListEvaluation when "handling agents" are alone
|
||||
* Export: fix list person with custom fields
|
||||
* ([#100](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/100)) Add a paginator to budget elements (resource and charge types) in the admin
|
||||
* Fix error in ListEvaluation when "handling agents" are alone
|
||||
|
||||
## v2.14.0 - 2023-11-24
|
||||
### Feature
|
||||
* ([#161](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/161)) Export: in filter "Filter accompanying period work (social action) by type, goal and result", order the items alphabetically or with the defined order
|
||||
* ([#161](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/161)) Export: in filter "Filter accompanying period work (social action) by type, goal and result", order the items alphabetically or with the defined order
|
||||
### Fixed
|
||||
* ([#141](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/141)) Export: on filter "action by type goals, and results", restore the fields when editing a saved export
|
||||
* ([#219](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/219)) Export: fix the list of accompanying period work, when the "calc date" is null
|
||||
* ([#222](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/222)) Fix rendering of custom fields
|
||||
* Fix various errors in custom fields administration
|
||||
* ([#141](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/141)) Export: on filter "action by type goals, and results", restore the fields when editing a saved export
|
||||
* ([#219](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/219)) Export: fix the list of accompanying period work, when the "calc date" is null
|
||||
* ([#222](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/222)) Fix rendering of custom fields
|
||||
* Fix various errors in custom fields administration
|
||||
|
||||
## v2.13.0 - 2023-11-21
|
||||
### Feature
|
||||
@ -254,7 +281,7 @@ and is generated by [Changie](https://github.com/miniscruff/changie).
|
||||
|
||||
## v2.12.1 - 2023-11-16
|
||||
### Fixed
|
||||
* ([#208](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/208)) Export: fix loading of form for "filter action by type, goal and result"
|
||||
* ([#208](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/208)) Export: fix loading of form for "filter action by type, goal and result"
|
||||
|
||||
## v2.12.0 - 2023-11-15
|
||||
### Feature
|
||||
@ -285,36 +312,36 @@ and is generated by [Changie](https://github.com/miniscruff/changie).
|
||||
|
||||
## v2.11.0 - 2023-11-07
|
||||
### Feature
|
||||
* ([#194](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/194)) Export: add a filter "filter activity by creator job"
|
||||
* ([#194](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/194)) Export: add a filter "filter activity by creator job"
|
||||
### Fixed
|
||||
* ([#185](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/185)) Export: fix "group accompanying period by geographical unit": take into account the accompanying periods when the period is not located within an unit
|
||||
* Fix "group activity by creator job" aggregator
|
||||
* ([#185](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/185)) Export: fix "group accompanying period by geographical unit": take into account the accompanying periods when the period is not located within an unit
|
||||
* Fix "group activity by creator job" aggregator
|
||||
|
||||
## v2.10.6 - 2023-11-07
|
||||
### Fixed
|
||||
* ([#182](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/182)) Fix merging of double person files. Adjustement relationship sql statement
|
||||
* ([#185](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/185)) Export: fix aggregator by geographical unit on person: avoid inconsistencies
|
||||
* ([#182](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/182)) Fix merging of double person files. Adjustement relationship sql statement
|
||||
* ([#185](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/185)) Export: fix aggregator by geographical unit on person: avoid inconsistencies
|
||||
|
||||
## v2.10.5 - 2023-11-05
|
||||
### Fixed
|
||||
* ([#183](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/183)) Fix "problem during download" on some filters, which used a wrong data type
|
||||
* ([#184](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/184)) Fix filter "activity by date"
|
||||
* ([#183](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/183)) Fix "problem during download" on some filters, which used a wrong data type
|
||||
* ([#184](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/184)) Fix filter "activity by date"
|
||||
|
||||
## v2.10.4 - 2023-10-26
|
||||
### Fixed
|
||||
* Fix null value constraint errors when merging relationships in doubles
|
||||
* Fix null value constraint errors when merging relationships in doubles
|
||||
|
||||
## v2.10.3 - 2023-10-26
|
||||
### Fixed
|
||||
* ([#175](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/175)) Replace old method of getting translator with injection of translatorInterface
|
||||
* ([#175](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/175)) Replace old method of getting translator with injection of translatorInterface
|
||||
|
||||
## v2.10.2 - 2023-10-26
|
||||
### Fixed
|
||||
* ([#175](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/175)) Use injection of translator instead of ->get().
|
||||
* ([#175](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/175)) Use injection of translator instead of ->get().
|
||||
|
||||
## v2.10.1 - 2023-10-24
|
||||
### Fixed
|
||||
* Fix export controller when generating an export without any data in session
|
||||
* Fix export controller when generating an export without any data in session
|
||||
|
||||
## v2.10.0 - 2023-10-24
|
||||
### Feature
|
||||
@ -339,11 +366,11 @@ and is generated by [Changie](https://github.com/miniscruff/changie).
|
||||
|
||||
## v2.9.2 - 2023-10-17
|
||||
### Fixed
|
||||
* Fix possible null values in string's entities
|
||||
* Fix possible null values in string's entities
|
||||
|
||||
## v2.9.1 - 2023-10-17
|
||||
### Fixed
|
||||
* Fix the handling of activity form when editing or creating an activity in an accompanying period with multiple centers
|
||||
* Fix the handling of activity form when editing or creating an activity in an accompanying period with multiple centers
|
||||
|
||||
## v2.9.0 - 2023-10-17
|
||||
### Feature
|
||||
@ -391,57 +418,57 @@ But if you do not need this any more, you must ensure that the configuration key
|
||||
|
||||
## v2.7.0 - 2023-09-27
|
||||
### Feature
|
||||
* ([#155](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/155)) The regulation list load accompanying periods by exact postal code (address associated with postal code), and not by the content of the postal code (postal code with same code's string)
|
||||
* ([#155](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/155)) The regulation list load accompanying periods by exact postal code (address associated with postal code), and not by the content of the postal code (postal code with same code's string)
|
||||
### Fixed
|
||||
* ([#142](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/142)) Fix the label of filter ActivityTypeFilter to a more obvious one
|
||||
* ([#140](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/140)) [export] Fix association of filter "filter location by type" which did not appears on "list of activities"
|
||||
* ([#142](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/142)) Fix the label of filter ActivityTypeFilter to a more obvious one
|
||||
* ([#140](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/140)) [export] Fix association of filter "filter location by type" which did not appears on "list of activities"
|
||||
|
||||
## v2.6.3 - 2023-09-19
|
||||
### Fixed
|
||||
* Remove id property from document
|
||||
mappedsuperclass
|
||||
* Remove id property from document
|
||||
mappedsuperclass
|
||||
|
||||
## v2.6.2 - 2023-09-18
|
||||
### Fixed
|
||||
* Fix doctrine mapping of AbstractTaskPlaceEvent and SingleTaskPlaceEvent: id property moved.
|
||||
* Fix doctrine mapping of AbstractTaskPlaceEvent and SingleTaskPlaceEvent: id property moved.
|
||||
|
||||
## v2.6.1 - 2023-09-14
|
||||
### Fixed
|
||||
* Filter out active centers in exports, which uses a different PickCenterType.
|
||||
* Filter out active centers in exports, which uses a different PickCenterType.
|
||||
|
||||
## v2.6.0 - 2023-09-14
|
||||
### Feature
|
||||
* ([#133](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/133)) Add locations in Aside Activity. By default, suggest user location, otherwise a select with all locations.
|
||||
* ([#133](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/133)) Adapt Aside Activity exports: display location, filter by location, group by location
|
||||
* Use the CRUD controller for center entity + add the isActive property to be able to mask instances of Center that are no longer in use.
|
||||
* ([#133](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/133)) Add locations in Aside Activity. By default, suggest user location, otherwise a select with all locations.
|
||||
* ([#133](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/133)) Adapt Aside Activity exports: display location, filter by location, group by location
|
||||
* Use the CRUD controller for center entity + add the isActive property to be able to mask instances of Center that are no longer in use.
|
||||
### Fixed
|
||||
* ([#107](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/107)) reinstate the fusion of duplicate persons
|
||||
* Missing translation in Work Actions exports
|
||||
* Reimplement the mission type filter on tasks, only for instances that have a config parameter indicating true for this.
|
||||
* ([#135](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/135)) Corrects a typing error in 2 filters, which caused an
|
||||
* ([#107](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/107)) reinstate the fusion of duplicate persons
|
||||
* Missing translation in Work Actions exports
|
||||
* Reimplement the mission type filter on tasks, only for instances that have a config parameter indicating true for this.
|
||||
* ([#135](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/135)) Corrects a typing error in 2 filters, which caused an
|
||||
error when trying to reedit a saved export
|
||||
|
||||
|
||||
* ([#136](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/136)) [household] when moving a person to a sharing position to a not-sharing position on the same household on the same date, remove the previous household membership on the same household. This fix duplicate member.
|
||||
|
||||
* ([#136](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/136)) [household] when moving a person to a sharing position to a not-sharing position on the same household on the same date, remove the previous household membership on the same household. This fix duplicate member.
|
||||
* Add missing translation for comment field placeholder in repositionning household editor.
|
||||
|
||||
* Do not send an email to creator twice when adding a comment to a notification
|
||||
* ([#107](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/107)) Fix gestion doublon functionality to work with chill bundles v2
|
||||
|
||||
* Do not send an email to creator twice when adding a comment to a notification
|
||||
* ([#107](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/107)) Fix gestion doublon functionality to work with chill bundles v2
|
||||
### UX
|
||||
* Uniformize badge-person in household banner (background, size)
|
||||
|
||||
|
||||
|
||||
## v2.5.3 - 2023-07-20
|
||||
### Fixed
|
||||
* ([#132](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/132)) Rendez-vous documents created would appear in all documents lists of all persons with an accompanying period. Or statements are now added to the where clause to filter out documents that come from unrelated accompanying period/ or person rendez-vous.
|
||||
* ([#132](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/132)) Rendez-vous documents created would appear in all documents lists of all persons with an accompanying period. Or statements are now added to the where clause to filter out documents that come from unrelated accompanying period/ or person rendez-vous.
|
||||
|
||||
## v2.5.2 - 2023-07-15
|
||||
### Fixed
|
||||
* [Collate Address] when updating address point, do not use the point's address reference if the similarity is below the requirement for associating the address reference and the address (it uses the postcode's center instead)
|
||||
* [Collate Address] when updating address point, do not use the point's address reference if the similarity is below the requirement for associating the address reference and the address (it uses the postcode's center instead)
|
||||
|
||||
## v2.5.1 - 2023-07-14
|
||||
### Fixed
|
||||
* [collate addresses] block collating addresses to another address reference where the address reference is already the best match
|
||||
* [collate addresses] block collating addresses to another address reference where the address reference is already the best match
|
||||
|
||||
## v2.5.0 - 2023-07-14
|
||||
### Feature
|
||||
|
@ -59,7 +59,8 @@
|
||||
"vue-i18n": "^9.1.6",
|
||||
"vue-multiselect": "3.0.0-alpha.2",
|
||||
"vue-toast-notification": "^3.1.2",
|
||||
"vuex": "^4.0.0"
|
||||
"vuex": "^4.0.0",
|
||||
"bootstrap-icons": "^1.11.3"
|
||||
},
|
||||
"browserslist": [
|
||||
"Firefox ESR"
|
||||
|
@ -16,7 +16,7 @@ use Chill\ActivityBundle\Repository\ActivityRepository;
|
||||
use Chill\DocStoreBundle\Repository\AssociatedEntityToStoredObjectInterface;
|
||||
use Chill\DocStoreBundle\Security\Authorization\StoredObjectRoleEnum;
|
||||
use Chill\DocStoreBundle\Security\Authorization\StoredObjectVoter\AbstractStoredObjectVoter;
|
||||
use Chill\DocStoreBundle\Service\WorkflowStoredObjectPermissionHelper;
|
||||
use Chill\MainBundle\Workflow\Helper\WorkflowRelatedEntityPermissionHelper;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
|
||||
class ActivityStoredObjectVoter extends AbstractStoredObjectVoter
|
||||
@ -24,7 +24,7 @@ class ActivityStoredObjectVoter extends AbstractStoredObjectVoter
|
||||
public function __construct(
|
||||
private readonly ActivityRepository $repository,
|
||||
Security $security,
|
||||
WorkflowStoredObjectPermissionHelper $workflowDocumentService,
|
||||
WorkflowRelatedEntityPermissionHelper $workflowDocumentService,
|
||||
) {
|
||||
parent::__construct($security, $workflowDocumentService);
|
||||
}
|
||||
|
@ -42,8 +42,8 @@ class CustomFieldLongChoice extends AbstractCustomField
|
||||
$translatableStringHelper = $this->translatableStringHelper;
|
||||
$builder->add($customField->getSlug(), Select2ChoiceType::class, [
|
||||
'choices' => $entries,
|
||||
'choice_label' => static fn (Option $option) => $translatableStringHelper->localize($option->getText()),
|
||||
'choice_value' => static fn (Option $key): ?int => null === $key ? null : $key->getId(),
|
||||
'choice_label' => static fn (?Option $option) => $translatableStringHelper->localize($option->getText()),
|
||||
'choice_value' => static fn (?Option $key): ?int => $key?->getId(),
|
||||
'multiple' => false,
|
||||
'expanded' => false,
|
||||
'required' => $customField->isRequired(),
|
||||
|
@ -46,11 +46,8 @@ class CustomFieldsGroup
|
||||
#[ORM\GeneratedValue(strategy: 'AUTO')]
|
||||
private ?int $id = null;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::JSON)]
|
||||
private $name;
|
||||
private array|string $name;
|
||||
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::JSON)]
|
||||
private array $options = [];
|
||||
@ -181,7 +178,7 @@ class CustomFieldsGroup
|
||||
*
|
||||
* @return CustomFieldsGroup
|
||||
*/
|
||||
public function setName($name)
|
||||
public function setName(array|string $name)
|
||||
{
|
||||
$this->name = $name;
|
||||
|
||||
|
@ -15,7 +15,7 @@ use Chill\DocStoreBundle\Entity\StoredObject;
|
||||
use Chill\DocStoreBundle\Repository\AssociatedEntityToStoredObjectInterface;
|
||||
use Chill\DocStoreBundle\Security\Authorization\StoredObjectRoleEnum;
|
||||
use Chill\DocStoreBundle\Security\Authorization\StoredObjectVoterInterface;
|
||||
use Chill\DocStoreBundle\Service\WorkflowStoredObjectPermissionHelper;
|
||||
use Chill\MainBundle\Workflow\Helper\WorkflowRelatedEntityPermissionHelper;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
|
||||
@ -34,7 +34,7 @@ abstract class AbstractStoredObjectVoter implements StoredObjectVoterInterface
|
||||
|
||||
public function __construct(
|
||||
private readonly Security $security,
|
||||
private readonly ?WorkflowStoredObjectPermissionHelper $workflowDocumentService = null,
|
||||
private readonly ?WorkflowRelatedEntityPermissionHelper $workflowDocumentService = null,
|
||||
) {}
|
||||
|
||||
public function supports(StoredObjectRoleEnum $attribute, StoredObject $subject): bool
|
||||
@ -49,6 +49,11 @@ abstract class AbstractStoredObjectVoter implements StoredObjectVoterInterface
|
||||
// Retrieve the related accompanying course document
|
||||
$entity = $this->getRepository()->findAssociatedEntityToStoredObject($subject);
|
||||
|
||||
if ($this->workflowDocumentService->isAllowedByWorkflow($entity)) {
|
||||
// read and write permissions are granted by workflow
|
||||
return true;
|
||||
}
|
||||
|
||||
// Determine the attribute to pass to AccompanyingCourseDocumentVoter
|
||||
$voterAttribute = $this->attributeToRole($attribute);
|
||||
|
||||
|
@ -16,7 +16,7 @@ use Chill\DocStoreBundle\Repository\AccompanyingCourseDocumentRepository;
|
||||
use Chill\DocStoreBundle\Repository\AssociatedEntityToStoredObjectInterface;
|
||||
use Chill\DocStoreBundle\Security\Authorization\AccompanyingCourseDocumentVoter;
|
||||
use Chill\DocStoreBundle\Security\Authorization\StoredObjectRoleEnum;
|
||||
use Chill\DocStoreBundle\Service\WorkflowStoredObjectPermissionHelper;
|
||||
use Chill\MainBundle\Workflow\Helper\WorkflowRelatedEntityPermissionHelper;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
|
||||
final class AccompanyingCourseDocumentStoredObjectVoter extends AbstractStoredObjectVoter
|
||||
@ -24,7 +24,7 @@ final class AccompanyingCourseDocumentStoredObjectVoter extends AbstractStoredOb
|
||||
public function __construct(
|
||||
private readonly AccompanyingCourseDocumentRepository $repository,
|
||||
Security $security,
|
||||
WorkflowStoredObjectPermissionHelper $workflowDocumentService,
|
||||
WorkflowRelatedEntityPermissionHelper $workflowDocumentService,
|
||||
) {
|
||||
parent::__construct($security, $workflowDocumentService);
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ use Chill\DocStoreBundle\Repository\AssociatedEntityToStoredObjectInterface;
|
||||
use Chill\DocStoreBundle\Repository\PersonDocumentRepository;
|
||||
use Chill\DocStoreBundle\Security\Authorization\PersonDocumentVoter;
|
||||
use Chill\DocStoreBundle\Security\Authorization\StoredObjectRoleEnum;
|
||||
use Chill\DocStoreBundle\Service\WorkflowStoredObjectPermissionHelper;
|
||||
use Chill\MainBundle\Workflow\Helper\WorkflowRelatedEntityPermissionHelper;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
|
||||
class PersonDocumentStoredObjectVoter extends AbstractStoredObjectVoter
|
||||
@ -24,7 +24,7 @@ class PersonDocumentStoredObjectVoter extends AbstractStoredObjectVoter
|
||||
public function __construct(
|
||||
private readonly PersonDocumentRepository $repository,
|
||||
Security $security,
|
||||
WorkflowStoredObjectPermissionHelper $workflowDocumentService,
|
||||
WorkflowRelatedEntityPermissionHelper $workflowDocumentService,
|
||||
) {
|
||||
parent::__construct($security, $workflowDocumentService);
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ use Chill\DocStoreBundle\Entity\StoredObject;
|
||||
use Chill\DocStoreBundle\Repository\AssociatedEntityToStoredObjectInterface;
|
||||
use Chill\DocStoreBundle\Security\Authorization\StoredObjectRoleEnum;
|
||||
use Chill\DocStoreBundle\Security\Authorization\StoredObjectVoter\AbstractStoredObjectVoter;
|
||||
use Chill\DocStoreBundle\Service\WorkflowStoredObjectPermissionHelper;
|
||||
use Chill\MainBundle\Workflow\Helper\WorkflowRelatedEntityPermissionHelper;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
@ -30,16 +30,16 @@ class AbstractStoredObjectVoterTest extends TestCase
|
||||
{
|
||||
private AssociatedEntityToStoredObjectInterface $repository;
|
||||
private Security $security;
|
||||
private WorkflowStoredObjectPermissionHelper $workflowDocumentService;
|
||||
private WorkflowRelatedEntityPermissionHelper $workflowDocumentService;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->repository = $this->createMock(AssociatedEntityToStoredObjectInterface::class);
|
||||
$this->security = $this->createMock(Security::class);
|
||||
$this->workflowDocumentService = $this->createMock(WorkflowStoredObjectPermissionHelper::class);
|
||||
$this->workflowDocumentService = $this->createMock(WorkflowRelatedEntityPermissionHelper::class);
|
||||
}
|
||||
|
||||
private function buildStoredObjectVoter(bool $canBeAssociatedWithWorkflow, AssociatedEntityToStoredObjectInterface $repository, Security $security, ?WorkflowStoredObjectPermissionHelper $workflowDocumentService = null): AbstractStoredObjectVoter
|
||||
private function buildStoredObjectVoter(bool $canBeAssociatedWithWorkflow, AssociatedEntityToStoredObjectInterface $repository, Security $security, ?WorkflowRelatedEntityPermissionHelper $workflowDocumentService = null): AbstractStoredObjectVoter
|
||||
{
|
||||
// Anonymous class extending the abstract class
|
||||
return new class ($canBeAssociatedWithWorkflow, $repository, $security, $workflowDocumentService) extends AbstractStoredObjectVoter {
|
||||
@ -47,7 +47,7 @@ class AbstractStoredObjectVoterTest extends TestCase
|
||||
private readonly bool $canBeAssociatedWithWorkflow,
|
||||
private readonly AssociatedEntityToStoredObjectInterface $repository,
|
||||
Security $security,
|
||||
?WorkflowStoredObjectPermissionHelper $workflowDocumentService = null,
|
||||
?WorkflowRelatedEntityPermissionHelper $workflowDocumentService = null,
|
||||
) {
|
||||
parent::__construct($security, $workflowDocumentService);
|
||||
}
|
||||
@ -99,6 +99,25 @@ class AbstractStoredObjectVoterTest extends TestCase
|
||||
$this->workflowDocumentService->method('notBlockedByWorkflow')->willReturn($workflowAllowed);
|
||||
}
|
||||
|
||||
public function testIsAllowedByWorkflow(): void
|
||||
{
|
||||
[$user, $token, $subject, $entity] = $this->setupMockObjects();
|
||||
$workflowRelatedEntityPermissionHelper = $this->createMock(WorkflowRelatedEntityPermissionHelper::class);
|
||||
$workflowRelatedEntityPermissionHelper->method('isAllowedByWorkflow')->withAnyParameters()->willReturn(true);
|
||||
|
||||
$associatedObjectRepository = $this->createMock(AssociatedEntityToStoredObjectInterface::class);
|
||||
$associatedObjectRepository->method('findAssociatedEntityToStoredObject')->willReturn($entity);
|
||||
|
||||
$voter = $this->buildStoredObjectVoter(
|
||||
true,
|
||||
$associatedObjectRepository,
|
||||
$this->createMock(Security::class),
|
||||
$workflowRelatedEntityPermissionHelper
|
||||
);
|
||||
|
||||
self::assertTrue($voter->voteOnAttribute(StoredObjectRoleEnum::EDIT, $subject, $token));
|
||||
}
|
||||
|
||||
public function testSupportsOnAttribute(): void
|
||||
{
|
||||
[$user, $token, $subject, $entity] = $this->setupMockObjects();
|
||||
|
@ -14,7 +14,7 @@ namespace Chill\EventBundle\Security\Authorization;
|
||||
use Chill\DocStoreBundle\Repository\AssociatedEntityToStoredObjectInterface;
|
||||
use Chill\DocStoreBundle\Security\Authorization\StoredObjectRoleEnum;
|
||||
use Chill\DocStoreBundle\Security\Authorization\StoredObjectVoter\AbstractStoredObjectVoter;
|
||||
use Chill\DocStoreBundle\Service\WorkflowStoredObjectPermissionHelper;
|
||||
use Chill\MainBundle\Workflow\Helper\WorkflowRelatedEntityPermissionHelper;
|
||||
use Chill\EventBundle\Entity\Event;
|
||||
use Chill\EventBundle\Repository\EventRepository;
|
||||
use Chill\EventBundle\Security\EventVoter;
|
||||
@ -25,7 +25,7 @@ class EventStoredObjectVoter extends AbstractStoredObjectVoter
|
||||
public function __construct(
|
||||
private readonly EventRepository $repository,
|
||||
Security $security,
|
||||
WorkflowStoredObjectPermissionHelper $workflowDocumentService,
|
||||
WorkflowRelatedEntityPermissionHelper $workflowDocumentService,
|
||||
) {
|
||||
parent::__construct($security, $workflowDocumentService);
|
||||
}
|
||||
|
@ -1,19 +0,0 @@
|
||||
footer.footer {
|
||||
padding: 0;
|
||||
background-color: white;
|
||||
border-top: 1px solid grey;
|
||||
div.sponsors {
|
||||
p {
|
||||
padding-bottom: 10px;
|
||||
color: #000;
|
||||
font-size: 16px;
|
||||
}
|
||||
background-color: white;
|
||||
padding: 2em 0;
|
||||
img {
|
||||
display: block;
|
||||
margin: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1 +0,0 @@
|
||||
require('./csconnectes.scss');
|
@ -5,8 +5,7 @@ module.exports = function(encore, chillEntries)
|
||||
personal_situation_edit_file = __dirname + '/Resources/public/module/personal_situation/index.js',
|
||||
cv_edit_file = __dirname + '/Resources/public/module/cv_edit/index.js',
|
||||
immersion_edit_file = __dirname + '/Resources/public/module/immersion_edit/index.js',
|
||||
images = __dirname + '/Resources/public/images/index.js',
|
||||
sass_styles = __dirname + '/Resources/public/sass/index.js'
|
||||
images = __dirname + '/Resources/public/images/index.js'
|
||||
;
|
||||
|
||||
encore.addEntry('dispositifs_edit', dispositif_edit_file);
|
||||
@ -15,6 +14,4 @@ module.exports = function(encore, chillEntries)
|
||||
encore.addEntry('images', images);
|
||||
encore.addEntry('cs_cv', cv_edit_file);
|
||||
|
||||
chillEntries.push(sass_styles);
|
||||
|
||||
};
|
||||
|
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Controller;
|
||||
|
||||
use Chill\MainBundle\CRUD\Controller\ApiController;
|
||||
use Chill\MainBundle\Pagination\PaginatorInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class GenderApiController extends ApiController
|
||||
{
|
||||
protected function customizeQuery(string $action, Request $request, $query): void
|
||||
{
|
||||
$query
|
||||
->andWhere(
|
||||
$query->expr()->eq('e.active', "'TRUE'")
|
||||
);
|
||||
}
|
||||
|
||||
protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator, $_format)
|
||||
{
|
||||
return $query->addOrderBy('e.order', 'ASC');
|
||||
}
|
||||
}
|
26
src/Bundle/ChillMainBundle/Controller/GenderController.php
Normal file
26
src/Bundle/ChillMainBundle/Controller/GenderController.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Controller;
|
||||
|
||||
use Chill\MainBundle\CRUD\Controller\CRUDController;
|
||||
use Chill\MainBundle\Pagination\PaginatorInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class GenderController extends CRUDController
|
||||
{
|
||||
protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator)
|
||||
{
|
||||
$query->addOrderBy('e.order', 'ASC');
|
||||
|
||||
return parent::orderQuery($action, $query, $request, $paginator);
|
||||
}
|
||||
}
|
63
src/Bundle/ChillMainBundle/DataFixtures/ORM/LoadGenders.php
Normal file
63
src/Bundle/ChillMainBundle/DataFixtures/ORM/LoadGenders.php
Normal file
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\DataFixtures\ORM;
|
||||
|
||||
use Chill\MainBundle\Entity\Gender;
|
||||
use Chill\MainBundle\Entity\GenderEnum;
|
||||
use Chill\MainBundle\Entity\GenderIconEnum;
|
||||
use Doctrine\Common\DataFixtures\AbstractFixture;
|
||||
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
|
||||
use Doctrine\Persistence\ObjectManager;
|
||||
|
||||
class LoadGenders extends AbstractFixture implements OrderedFixtureInterface
|
||||
{
|
||||
private array $genders = [
|
||||
[
|
||||
'label' => ['en' => 'man', 'fr' => 'homme'],
|
||||
'genderTranslation' => GenderEnum::MALE,
|
||||
'icon' => GenderIconEnum::MALE,
|
||||
],
|
||||
[
|
||||
'label' => ['en' => 'woman', 'fr' => 'femme'],
|
||||
'genderTranslation' => GenderEnum::FEMALE,
|
||||
'icon' => GenderIconEnum::FEMALE,
|
||||
],
|
||||
[
|
||||
'label' => ['en' => 'neutral', 'fr' => 'neutre'],
|
||||
'genderTranslation' => GenderEnum::NEUTRAL,
|
||||
'icon' => GenderIconEnum::NEUTRAL,
|
||||
],
|
||||
];
|
||||
|
||||
public function getOrder()
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
|
||||
public function load(ObjectManager $manager)
|
||||
{
|
||||
echo "loading genders... \n";
|
||||
|
||||
foreach ($this->genders as $g) {
|
||||
echo $g['label']['fr'].' ';
|
||||
$new_g = new Gender();
|
||||
$new_g->setGenderTranslation($g['genderTranslation']);
|
||||
$new_g->setLabel($g['label']);
|
||||
$new_g->setIcon($g['icon']);
|
||||
|
||||
$this->addReference('g_'.$g['genderTranslation']->value, $new_g);
|
||||
$manager->persist($new_g);
|
||||
}
|
||||
|
||||
$manager->flush();
|
||||
}
|
||||
}
|
@ -17,6 +17,8 @@ use Chill\MainBundle\Controller\CivilityApiController;
|
||||
use Chill\MainBundle\Controller\CivilityController;
|
||||
use Chill\MainBundle\Controller\CountryApiController;
|
||||
use Chill\MainBundle\Controller\CountryController;
|
||||
use Chill\MainBundle\Controller\GenderApiController;
|
||||
use Chill\MainBundle\Controller\GenderController;
|
||||
use Chill\MainBundle\Controller\GeographicalUnitApiController;
|
||||
use Chill\MainBundle\Controller\LanguageController;
|
||||
use Chill\MainBundle\Controller\LocationController;
|
||||
@ -54,6 +56,7 @@ use Chill\MainBundle\Doctrine\Type\PointType;
|
||||
use Chill\MainBundle\Entity\Center;
|
||||
use Chill\MainBundle\Entity\Civility;
|
||||
use Chill\MainBundle\Entity\Country;
|
||||
use Chill\MainBundle\Entity\Gender;
|
||||
use Chill\MainBundle\Entity\GeographicalUnitLayer;
|
||||
use Chill\MainBundle\Entity\Language;
|
||||
use Chill\MainBundle\Entity\Location;
|
||||
@ -66,6 +69,7 @@ use Chill\MainBundle\Entity\UserJob;
|
||||
use Chill\MainBundle\Form\CenterType;
|
||||
use Chill\MainBundle\Form\CivilityType;
|
||||
use Chill\MainBundle\Form\CountryType;
|
||||
use Chill\MainBundle\Form\GenderType;
|
||||
use Chill\MainBundle\Form\LanguageType;
|
||||
use Chill\MainBundle\Form\LocationFormType;
|
||||
use Chill\MainBundle\Form\LocationTypeType;
|
||||
@ -511,6 +515,28 @@ class ChillMainExtension extends Extension implements
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'class' => Gender::class,
|
||||
'name' => 'main_gender',
|
||||
'base_path' => '/admin/main/gender',
|
||||
'base_role' => 'ROLE_ADMIN',
|
||||
'form_class' => GenderType::class,
|
||||
'controller' => GenderController::class,
|
||||
'actions' => [
|
||||
'index' => [
|
||||
'role' => 'ROLE_ADMIN',
|
||||
'template' => '@ChillMain/Gender/index.html.twig',
|
||||
],
|
||||
'new' => [
|
||||
'role' => 'ROLE_ADMIN',
|
||||
'template' => '@ChillMain/Gender/new.html.twig',
|
||||
],
|
||||
'edit' => [
|
||||
'role' => 'ROLE_ADMIN',
|
||||
'template' => '@ChillMain/Gender/edit.html.twig',
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'class' => Language::class,
|
||||
'name' => 'main_language',
|
||||
@ -814,6 +840,21 @@ class ChillMainExtension extends Extension implements
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'class' => Gender::class,
|
||||
'name' => 'gender',
|
||||
'base_path' => '/api/1.0/main/gender',
|
||||
'base_role' => 'ROLE_USER',
|
||||
'controller' => GenderApiController::class,
|
||||
'actions' => [
|
||||
'_index' => [
|
||||
'methods' => [
|
||||
Request::METHOD_GET => true,
|
||||
Request::METHOD_HEAD => true,
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'class' => GeographicalUnitLayer::class,
|
||||
'controller' => GeographicalUnitApiController::class,
|
||||
|
104
src/Bundle/ChillMainBundle/Entity/Gender.php
Normal file
104
src/Bundle/ChillMainBundle/Entity/Gender.php
Normal file
@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Entity;
|
||||
|
||||
use Chill\MainBundle\Repository\GenderRepository;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
#[Serializer\DiscriminatorMap(typeProperty: 'type', mapping: ['chill_main_gender' => Gender::class])]
|
||||
#[ORM\Entity(repositoryClass: GenderRepository::class)]
|
||||
#[ORM\Table(name: 'chill_main_gender')]
|
||||
class Gender
|
||||
{
|
||||
#[Serializer\Groups(['read'])]
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::INTEGER)]
|
||||
private ?int $id = null;
|
||||
|
||||
#[Serializer\Groups(['read'])]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::JSON)]
|
||||
private array $label = [];
|
||||
|
||||
#[Serializer\Groups(['read'])]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::BOOLEAN)]
|
||||
private bool $active = true;
|
||||
|
||||
#[Assert\NotNull(message: 'You must choose a gender translation')]
|
||||
#[Serializer\Groups(['read'])]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, enumType: GenderEnum::class)]
|
||||
private GenderEnum $genderTranslation;
|
||||
|
||||
#[Serializer\Groups(['read'])]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, enumType: GenderIconEnum::class)]
|
||||
private GenderIconEnum $icon;
|
||||
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::FLOAT, name: 'ordering', nullable: true, options: ['default' => '0.0'])]
|
||||
private float $order = 0;
|
||||
|
||||
public function getId(): int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getLabel(): array
|
||||
{
|
||||
return $this->label;
|
||||
}
|
||||
|
||||
public function setLabel(array $label): void
|
||||
{
|
||||
$this->label = $label;
|
||||
}
|
||||
|
||||
public function isActive(): bool
|
||||
{
|
||||
return $this->active;
|
||||
}
|
||||
|
||||
public function setActive(bool $active): void
|
||||
{
|
||||
$this->active = $active;
|
||||
}
|
||||
|
||||
public function getGenderTranslation(): GenderEnum
|
||||
{
|
||||
return $this->genderTranslation;
|
||||
}
|
||||
|
||||
public function setGenderTranslation(GenderEnum $genderTranslation): void
|
||||
{
|
||||
$this->genderTranslation = $genderTranslation;
|
||||
}
|
||||
|
||||
public function getIcon(): GenderIconEnum
|
||||
{
|
||||
return $this->icon;
|
||||
}
|
||||
|
||||
public function setIcon(GenderIconEnum $icon): void
|
||||
{
|
||||
$this->icon = $icon;
|
||||
}
|
||||
|
||||
public function getOrder(): float
|
||||
{
|
||||
return $this->order;
|
||||
}
|
||||
|
||||
public function setOrder(float $order): void
|
||||
{
|
||||
$this->order = $order;
|
||||
}
|
||||
}
|
20
src/Bundle/ChillMainBundle/Entity/GenderEnum.php
Normal file
20
src/Bundle/ChillMainBundle/Entity/GenderEnum.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Entity;
|
||||
|
||||
enum GenderEnum: string
|
||||
{
|
||||
case MALE = 'man';
|
||||
case FEMALE = 'woman';
|
||||
case NEUTRAL = 'neutral';
|
||||
case UNKNOWN = 'unknown';
|
||||
}
|
22
src/Bundle/ChillMainBundle/Entity/GenderIconEnum.php
Normal file
22
src/Bundle/ChillMainBundle/Entity/GenderIconEnum.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Entity;
|
||||
|
||||
enum GenderIconEnum: string
|
||||
{
|
||||
case MALE = 'bi bi-gender-male';
|
||||
case FEMALE = 'bi bi-gender-female';
|
||||
case NEUTRAL = 'bi bi-gender-neuter';
|
||||
case AMBIGUOUS = 'bi bi-gender-ambiguous';
|
||||
case TRANS = 'bi bi-gender-trans';
|
||||
case UNKNOWN = 'bi bi-question';
|
||||
}
|
64
src/Bundle/ChillMainBundle/Form/GenderType.php
Normal file
64
src/Bundle/ChillMainBundle/Form/GenderType.php
Normal file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Form;
|
||||
|
||||
use Chill\MainBundle\Entity\Gender;
|
||||
use Chill\MainBundle\Entity\GenderEnum;
|
||||
use Chill\MainBundle\Entity\GenderIconEnum;
|
||||
use Chill\MainBundle\Form\Type\TranslatableStringFormType;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\EnumType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\NumberType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class GenderType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$builder
|
||||
->add('label', TranslatableStringFormType::class, [
|
||||
'required' => true,
|
||||
])
|
||||
->add('icon', EnumType::class, [
|
||||
'class' => GenderIconEnum::class,
|
||||
'choices' => GenderIconEnum::cases(),
|
||||
'expanded' => true,
|
||||
'multiple' => false,
|
||||
'mapped' => true,
|
||||
'choice_label' => fn (GenderIconEnum $enum) => '<i class="'.strtolower($enum->value).'"></i>',
|
||||
'choice_value' => fn (?GenderIconEnum $enum) => null !== $enum ? $enum->value : null,
|
||||
'label' => 'gender.admin.Select Gender Icon',
|
||||
'label_html' => true,
|
||||
])
|
||||
->add('genderTranslation', EnumType::class, [
|
||||
'class' => GenderEnum::class,
|
||||
'choice_label' => fn (GenderEnum $enum) => $enum->value,
|
||||
'label' => 'gender.admin.Select Gender Translation',
|
||||
])
|
||||
->add('active', ChoiceType::class, [
|
||||
'choices' => [
|
||||
'Active' => true,
|
||||
'Inactive' => false,
|
||||
],
|
||||
])
|
||||
->add('order', NumberType::class);
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'data_class' => Gender::class,
|
||||
]);
|
||||
}
|
||||
}
|
47
src/Bundle/ChillMainBundle/Repository/GenderRepository.php
Normal file
47
src/Bundle/ChillMainBundle/Repository/GenderRepository.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Repository;
|
||||
|
||||
use Chill\MainBundle\Entity\Gender;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @extends ServiceEntityRepository<Gender>
|
||||
*/
|
||||
class GenderRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, Gender::class);
|
||||
}
|
||||
|
||||
public function findByActiveOrdered(): array
|
||||
{
|
||||
return $this->createQueryBuilder('g')
|
||||
->select('g')
|
||||
->where('g.active = True')
|
||||
->orderBy('g.order', 'ASC')
|
||||
->getQuery()
|
||||
->getResult();
|
||||
}
|
||||
|
||||
public function findByGenderTranslation($gender): array
|
||||
{
|
||||
return $this->createQueryBuilder('g')
|
||||
->select('g')
|
||||
->where('g.genderTranslation = :gender')
|
||||
->setParameter('gender', $gender)
|
||||
->getQuery()
|
||||
->getResult();
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@ import Modal from 'bootstrap/js/dist/modal';
|
||||
import Collapse from 'bootstrap/js/src/collapse';
|
||||
import Carousel from 'bootstrap/js/src/carousel';
|
||||
import Popover from 'bootstrap/js/src/popover';
|
||||
import 'bootstrap-icons/font/bootstrap-icons.css';
|
||||
|
||||
//
|
||||
// Carousel: ACHeaderSlider is a small slider used in banner of AccompanyingCourse Section
|
||||
@ -59,4 +60,4 @@ const popoverList = triggerList.map(function (el) {
|
||||
return new Popover(el, {
|
||||
html: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -0,0 +1,11 @@
|
||||
<template>
|
||||
<i :class="gender.icon"></i>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
const props = defineProps({
|
||||
gender: Object
|
||||
})
|
||||
|
||||
</script>
|
@ -38,7 +38,9 @@ const messages = {
|
||||
person: "Usager",
|
||||
birthday: {
|
||||
man: "Né le",
|
||||
woman: "Née le"
|
||||
woman: "Née le",
|
||||
neutral: "Né·e le",
|
||||
unknown: "Né·e le",
|
||||
},
|
||||
deathdate: "Date de décès",
|
||||
household_without_address: "Le ménage de l'usager est sans adresse",
|
||||
|
@ -0,0 +1,75 @@
|
||||
{% extends '@ChillMain/CRUD/Admin/index.html.twig' %}
|
||||
|
||||
{% block title %}
|
||||
{% include('@ChillMain/CRUD/_edit_title.html.twig') %}
|
||||
{% endblock %}
|
||||
|
||||
{% form_theme form _self %}
|
||||
|
||||
{% block _gender_icon_widget %}
|
||||
{% for child in form %}
|
||||
<div class="form-check">
|
||||
<input
|
||||
type="radio"
|
||||
id="{{ child.vars.id }}"
|
||||
name="{{ child.vars.full_name }}"
|
||||
value="{{ child.vars.value }}"
|
||||
{% if child.vars.checked %}checked="checked"{% endif %}
|
||||
/>
|
||||
|
||||
<label for="{{ child.vars.id }}">{{ child.vars.label|raw }}</label>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
||||
{% block admin_content %}
|
||||
{% set formId = crudMainFormId|default('crud_main_form') %}
|
||||
|
||||
{% block crud_content_header %}
|
||||
<h1 class="mb-5">{{ ('crud.'~crud_name~'.title_edit')|trans }}</h1>
|
||||
{% endblock crud_content_header %}
|
||||
|
||||
{% block crud_content_form %}
|
||||
{{ form_start(form, { 'attr' : { 'id': formId } }) }}
|
||||
|
||||
{{ form_row(form.label) }}
|
||||
{{ form_row(form.genderTranslation) }}
|
||||
{{ form_row(form.icon) }}
|
||||
{{ form_row(form.active) }}
|
||||
{{ form_row(form.order) }}
|
||||
|
||||
{{ form_end(form) }}
|
||||
{% block crud_content_after_form %}{% endblock %}
|
||||
|
||||
{% block crud_content_form_actions %}
|
||||
<ul class="record_actions sticky-form-buttons">
|
||||
{% block content_form_actions_back %}
|
||||
<li class="cancel">
|
||||
{# <a class="btn btn-cancel" href="{{ chill_return_path_or('chill_crud_'~crud_name~'_index') }}">#}
|
||||
{# {{ 'Cancel'|trans }}#}
|
||||
{# </a>#}
|
||||
</li>
|
||||
{% endblock %}
|
||||
{% block content_form_actions_before %}{% endblock %}
|
||||
{% block content_form_actions_delete %}
|
||||
{% if chill_crud_action_exists(crud_name, 'delete') %}
|
||||
{% if is_granted(chill_crud_config('role', crud_name, 'delete'), entity) %}
|
||||
<li class="">
|
||||
<a class="btn btn-small btn-delete" href="{{ chill_path_add_return_path('chill_crud_'~crud_name~'_delete', { 'id': entity.id }) }}"></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endblock content_form_actions_delete %}
|
||||
{% block content_form_actions_save_and_close %}
|
||||
<li class="">
|
||||
<button type="submit" name="submit" value="save-and-close" class="btn btn-update" form="{{ formId }}">
|
||||
{{ 'crud.edit.save_and_close'|trans }}
|
||||
</button>
|
||||
</li>
|
||||
{% endblock %}
|
||||
{% block content_form_actions_after %}{% endblock %}
|
||||
</ul>
|
||||
{% endblock %}
|
||||
|
||||
{% endblock %}
|
||||
{% endblock admin_content %}
|
@ -0,0 +1,46 @@
|
||||
{% extends '@ChillMain/CRUD/Admin/index.html.twig' %}
|
||||
|
||||
{% block admin_content %}
|
||||
{% embed '@ChillMain/CRUD/_index.html.twig' %}
|
||||
{% block table_entities_thead_tr %}
|
||||
<th>id</th>
|
||||
<th>{{ 'label'|trans }}</th>
|
||||
<th>{{ 'icon'|trans }}</th>
|
||||
<th>{{ 'gender.genderTranslation'|trans }}</th>
|
||||
<th>{{ 'active'|trans }}</th>
|
||||
<th>{{ 'ordering'|trans }}</th>
|
||||
<th></th>
|
||||
{% endblock %}
|
||||
{% block table_entities_tbody %}
|
||||
{% for entity in entities %}
|
||||
<tr>
|
||||
<td>{{ entity.id }}</td>
|
||||
<td>{{ entity.label|localize_translatable_string }}</td>
|
||||
<td>{{ entity.icon|chill_entity_render_box }}</td>
|
||||
<td>{{ entity.genderTranslation.value }}</td>
|
||||
<td style="text-align:center;">
|
||||
{%- if entity.active -%}
|
||||
<i class="fa fa-check-square-o"></i>
|
||||
{%- else -%}
|
||||
<i class="fa fa-square-o"></i>
|
||||
{%- endif -%}
|
||||
</td>
|
||||
<td>{{ entity.order }}</td>
|
||||
<td>
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<a href="{{ chill_path_add_return_path('chill_crud_main_gender_edit', { 'id': entity.id}) }}" class="btn btn-sm btn-edit btn-mini"></a>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
||||
{% block actions_before %}
|
||||
<li class='cancel'>
|
||||
<a href="{{ path('chill_main_admin_central') }}" class="btn btn-cancel">{{'Back to the admin'|trans}}</a>
|
||||
</li>
|
||||
{% endblock %}
|
||||
{% endembed %}
|
||||
{% endblock %}
|
@ -0,0 +1,79 @@
|
||||
{% extends '@ChillMain/CRUD/Admin/index.html.twig' %}
|
||||
|
||||
{% block title %}
|
||||
{% include('@ChillMain/CRUD/_new_title.html.twig') %}
|
||||
{% endblock %}
|
||||
|
||||
{% form_theme form _self %}
|
||||
|
||||
{% block _gender_icon_widget %}
|
||||
{% for child in form %}
|
||||
<div class="form-check">
|
||||
<input
|
||||
type="radio"
|
||||
id="{{ child.vars.id }}"
|
||||
name="{{ child.vars.full_name }}"
|
||||
value="{{ child.vars.value }}"
|
||||
{% if child.vars.checked %}checked="checked"{% endif %}
|
||||
/>
|
||||
|
||||
<label for="{{ child.vars.id }}">{{ child.vars.label|raw }}</label>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
||||
{% block admin_content %}
|
||||
{% set formId = crudMainFormId|default('crud_main_form') %}
|
||||
|
||||
{% block crud_content_header %}
|
||||
<h1>{{ ('crud.' ~ crud_name ~ '.title_new')|trans({'%crud_name%' : crud_name }) }}</h1>
|
||||
{% endblock crud_content_header %}
|
||||
|
||||
{% block crud_content_form %}
|
||||
{{ form_start(form, { 'attr' : { 'id': formId } }) }}
|
||||
{{ form_row(form.label) }}
|
||||
{{ form_row(form.genderTranslation) }}
|
||||
{{ form_row(form.icon) }}
|
||||
{{ form_row(form.active) }}
|
||||
{{ form_row(form.order) }}
|
||||
{{ form_end(form) }}
|
||||
|
||||
{% block crud_content_after_form %}{% endblock %}
|
||||
|
||||
{% block crud_content_form_actions %}
|
||||
<ul class="record_actions sticky-form-buttons">
|
||||
{% block content_form_actions_back %}
|
||||
<li class="cancel">
|
||||
<a class="btn btn-cancel" href="{{ chill_return_path_or('chill_crud_'~crud_name~'_index') }}">
|
||||
{{ 'Cancel'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
{% endblock %}
|
||||
{% block content_form_actions_save_and_close %}
|
||||
<li class="">
|
||||
<button type="submit" name="submit" value="save-and-close" class="btn btn-create" form="{{ formId }}">
|
||||
{{ 'crud.new.save_and_close'|trans }}
|
||||
</button>
|
||||
</li>
|
||||
{% endblock %}
|
||||
{% block content_form_actions_save_and_show %}
|
||||
<li class="">
|
||||
<button type="submit" name="submit" value="save-and-show" class="btn btn-create" form="{{ formId }}">
|
||||
{{ 'crud.new.save_and_show'|trans }}
|
||||
</button>
|
||||
</li>
|
||||
{% endblock %}
|
||||
{% block content_form_actions_save_and_new %}
|
||||
<li class="">
|
||||
<button type="submit" name="submit" value="save-and-new" class="btn btn-create" form="{{ formId }}">
|
||||
{{ 'crud.new.save_and_new'|trans }}
|
||||
</button>
|
||||
</li>
|
||||
{% endblock %}
|
||||
</ul>
|
||||
{% endblock %}
|
||||
|
||||
{{ form_end(form) }}
|
||||
{% endblock %}
|
||||
|
||||
{% endblock admin_content %}
|
@ -62,12 +62,12 @@ abstract class AbstractSearch implements SearchInterface
|
||||
$recomposed .= ' '.$term.':';
|
||||
$containsSpace = str_contains((string) $terms[$term], ' ');
|
||||
|
||||
if ($containsSpace) {
|
||||
if ($containsSpace || is_numeric($terms[$term])) {
|
||||
$recomposed .= '"';
|
||||
}
|
||||
$recomposed .= (false === mb_stristr(' ', (string) $terms[$term])) ? $terms[$term] : '('.$terms[$term].')';
|
||||
|
||||
if ($containsSpace) {
|
||||
if ($containsSpace || is_numeric($terms[$term])) {
|
||||
$recomposed .= '"';
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ interface ChillEntityRenderInterface
|
||||
*
|
||||
* @phpstan-pure
|
||||
*/
|
||||
public function renderBox($entity, array $options): string;
|
||||
public function renderBox(mixed $entity, array $options): string;
|
||||
|
||||
/**
|
||||
* Return the entity as a string.
|
||||
@ -46,7 +46,7 @@ interface ChillEntityRenderInterface
|
||||
*
|
||||
* @phpstan-pure
|
||||
*/
|
||||
public function renderString($entity, array $options): string;
|
||||
public function renderString(mixed $entity, array $options): string;
|
||||
|
||||
/**
|
||||
* Return true if the class support this object for the given options.
|
||||
|
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Templating\Entity;
|
||||
|
||||
use Chill\MainBundle\Entity\GenderIconEnum;
|
||||
|
||||
/**
|
||||
* @implements ChillEntityRenderInterface<GenderIconEnum>
|
||||
*/
|
||||
final readonly class ChillGenderIconRender implements ChillEntityRenderInterface
|
||||
{
|
||||
public function renderBox($icon, array $options): string
|
||||
{
|
||||
return '<i class="'.htmlspecialchars($icon->value, ENT_QUOTES, 'UTF-8').'"></i>';
|
||||
}
|
||||
|
||||
public function renderString($icon, array $options): string
|
||||
{
|
||||
return $icon->value;
|
||||
}
|
||||
|
||||
public function supports($icon, array $options): bool
|
||||
{
|
||||
return $icon instanceof GenderIconEnum;
|
||||
}
|
||||
}
|
@ -9,9 +9,9 @@ declare(strict_types=1);
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\DocStoreBundle\Tests\Service;
|
||||
namespace Chill\MainBundle\Tests\Workflow\Helper;
|
||||
|
||||
use Chill\DocStoreBundle\Service\WorkflowStoredObjectPermissionHelper;
|
||||
use Chill\MainBundle\Workflow\Helper\WorkflowRelatedEntityPermissionHelper;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflowSignatureStateEnum;
|
||||
@ -36,7 +36,7 @@ use Symfony\Component\Workflow\WorkflowInterface;
|
||||
*
|
||||
* @coversNothing
|
||||
*/
|
||||
class WorkflowStoredObjectPermissionHelperTest extends TestCase
|
||||
class WorkflowRelatedEntityPermissionHelperTest extends TestCase
|
||||
{
|
||||
use ProphecyTrait;
|
||||
|
||||
@ -53,6 +53,19 @@ class WorkflowStoredObjectPermissionHelperTest extends TestCase
|
||||
self::assertEquals($expected, $helper->notBlockedByWorkflow($entityWorkflow), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideDataAllowedByWorkflow
|
||||
*/
|
||||
public function testAllowedByWorkflow(EntityWorkflow $entityWorkflow, User $user, bool $expected, string $message): void
|
||||
{
|
||||
// all entities must have this workflow name, so we are ok to set it here
|
||||
$entityWorkflow->setWorkflowName('dummy');
|
||||
$object = new \stdClass();
|
||||
$helper = $this->buildHelper($object, $entityWorkflow, $user);
|
||||
|
||||
self::assertEquals($expected, $helper->isAllowedByWorkflow($entityWorkflow), $message);
|
||||
}
|
||||
|
||||
public function testNoWorkflow(): void
|
||||
{
|
||||
$object = new \stdClass();
|
||||
@ -60,7 +73,7 @@ class WorkflowStoredObjectPermissionHelperTest extends TestCase
|
||||
self::assertTrue($helper->notBlockedByWorkflow($object), "the user is not blocked by the user, as there aren't any user inside");
|
||||
}
|
||||
|
||||
private function buildHelper(object $relatedEntity, ?EntityWorkflow $entityWorkflow, User $user): WorkflowStoredObjectPermissionHelper
|
||||
private function buildHelper(object $relatedEntity, ?EntityWorkflow $entityWorkflow, User $user): WorkflowRelatedEntityPermissionHelper
|
||||
{
|
||||
$security = $this->prophesize(Security::class);
|
||||
$security->getUser()->willReturn($user);
|
||||
@ -72,7 +85,55 @@ class WorkflowStoredObjectPermissionHelperTest extends TestCase
|
||||
$entityWorkflowManager->findByRelatedEntity(Argument::type('object'))->willReturn([]);
|
||||
}
|
||||
|
||||
return new WorkflowStoredObjectPermissionHelper($security->reveal(), $entityWorkflowManager->reveal(), $this->buildRegistry());
|
||||
return new WorkflowRelatedEntityPermissionHelper($security->reveal(), $entityWorkflowManager->reveal(), $this->buildRegistry());
|
||||
}
|
||||
|
||||
public static function provideDataAllowedByWorkflow(): iterable
|
||||
{
|
||||
$entityWorkflow = new EntityWorkflow();
|
||||
$dto = new WorkflowTransitionContextDTO($entityWorkflow);
|
||||
$entityWorkflow->setStep('test', $dto, 'to_test', new \DateTimeImmutable(), new User());
|
||||
|
||||
yield [$entityWorkflow, new User(), false, 'not allowed because the user is not present as a dest user'];
|
||||
|
||||
$entityWorkflow = new EntityWorkflow();
|
||||
$dto = new WorkflowTransitionContextDTO($entityWorkflow);
|
||||
$dto->futureDestUsers[] = $user = new User();
|
||||
$entityWorkflow->setStep('test', $dto, 'to_test', new \DateTimeImmutable(), new User());
|
||||
|
||||
yield [$entityWorkflow, $user, true, 'allowed because the user is a current user'];
|
||||
|
||||
$entityWorkflow = new EntityWorkflow();
|
||||
$dto = new WorkflowTransitionContextDTO($entityWorkflow);
|
||||
$dto->futureDestUsers[] = $user = new User();
|
||||
$entityWorkflow->setStep('test', $dto, 'to_test', new \DateTimeImmutable(), new User());
|
||||
|
||||
$dto = new WorkflowTransitionContextDTO($entityWorkflow);
|
||||
$dto->futureDestUsers[] = new User();
|
||||
$entityWorkflow->setStep('test', $dto, 'to_test', new \DateTimeImmutable(), new User());
|
||||
|
||||
yield [$entityWorkflow, $user, true, 'allowed because the user was a previous user'];
|
||||
|
||||
$entityWorkflow = new EntityWorkflow();
|
||||
$dto = new WorkflowTransitionContextDTO($entityWorkflow);
|
||||
$dto->futureDestUsers[] = $user = new User();
|
||||
$entityWorkflow->setStep('test', $dto, 'to_test', new \DateTimeImmutable(), new User());
|
||||
$dto = new WorkflowTransitionContextDTO($entityWorkflow);
|
||||
$entityWorkflow->setStep('final_positive', $dto, 'to_final_positive', new \DateTimeImmutable(), new User());
|
||||
$entityWorkflow->getCurrentStep()->setIsFinal(true);
|
||||
|
||||
yield [$entityWorkflow, $user, false, 'not allowed because: user was a previous user, but it is finalized positive'];
|
||||
|
||||
$entityWorkflow = new EntityWorkflow();
|
||||
$dto = new WorkflowTransitionContextDTO($entityWorkflow);
|
||||
$dto->futureDestUsers[] = $user = new User();
|
||||
$entityWorkflow->setStep('test', $dto, 'to_test', new \DateTimeImmutable());
|
||||
$dto = new WorkflowTransitionContextDTO($entityWorkflow);
|
||||
$entityWorkflow->setStep('final_negative', $dto, 'to_final_negative', new \DateTimeImmutable());
|
||||
$entityWorkflow->getCurrentStep()->setIsFinal(true);
|
||||
|
||||
yield [$entityWorkflow, $user, true, 'allowed: user was a previous user, it is finalized, but finalized negative'];
|
||||
|
||||
}
|
||||
|
||||
public static function provideDataNotBlockByWorkflow(): iterable
|
@ -9,7 +9,7 @@ declare(strict_types=1);
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\DocStoreBundle\Service;
|
||||
namespace Chill\MainBundle\Workflow\Helper;
|
||||
|
||||
use Chill\MainBundle\Entity\Workflow\EntityWorkflowSignatureStateEnum;
|
||||
use Chill\MainBundle\Workflow\EntityWorkflowManager;
|
||||
@ -19,7 +19,7 @@ use Symfony\Component\Workflow\Registry;
|
||||
/**
|
||||
* Check if an object, associated with a workflow, is blocked, or not, by this workflow.
|
||||
*/
|
||||
class WorkflowStoredObjectPermissionHelper
|
||||
class WorkflowRelatedEntityPermissionHelper
|
||||
{
|
||||
public function __construct(
|
||||
private readonly Security $security,
|
||||
@ -27,6 +27,38 @@ class WorkflowStoredObjectPermissionHelper
|
||||
private readonly Registry $registry,
|
||||
) {}
|
||||
|
||||
public function isAllowedByWorkflow(object $entity): bool
|
||||
{
|
||||
$entityWorkflows = $this->entityWorkflowManager->findByRelatedEntity($entity);
|
||||
$currentUser = $this->security->getUser();
|
||||
|
||||
foreach ($entityWorkflows as $entityWorkflow) {
|
||||
// if the user is finalized, we have to check if the workflow is finalPositive, or not
|
||||
if ($entityWorkflow->isFinal()) {
|
||||
$workflow = $this->registry->get($entityWorkflow, $entityWorkflow->getWorkflowName());
|
||||
$marking = $workflow->getMarkingStore()->getMarking($entityWorkflow);
|
||||
foreach ($marking->getPlaces() as $place => $int) {
|
||||
$placeMetadata = $workflow->getMetadataStore()->getPlaceMetadata($place);
|
||||
if (true === ($placeMetadata['isFinalPositive'] ?? false)) {
|
||||
// the workflow is final, and final positive, so we stop here.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($entityWorkflows as $entityWorkflow) {
|
||||
// so, the workflow is running... We return true if the current user is involved
|
||||
foreach ($entityWorkflow->getSteps() as $step) {
|
||||
if ($step->getAllDestUser()->contains($currentUser)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the user is allowed to update the given object.
|
||||
*
|
@ -54,6 +54,8 @@ services:
|
||||
|
||||
Chill\MainBundle\Templating\Entity\NewsItemRender: ~
|
||||
|
||||
Chill\MainBundle\Templating\Entity\ChillGenderIconRender: ~
|
||||
|
||||
Chill\MainBundle\Templating\Entity\UserRender: ~
|
||||
|
||||
Chill\MainBundle\Templating\Entity\UserGroupRender: ~
|
||||
|
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\Migrations\Main;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
final class Version20240926093955 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Create gender table and default entities';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
$this->addSql('CREATE SEQUENCE chill_main_gender_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
|
||||
$this->addSql('CREATE TABLE chill_main_gender (id INT NOT NULL, label JSON NOT NULL, active BOOLEAN NOT NULL, genderTranslation VARCHAR(255) NOT NULL, icon VARCHAR(255) NOT NULL, ordering DOUBLE PRECISION DEFAULT \'0.0\', PRIMARY KEY(id))');
|
||||
|
||||
// Insert the four gender records into the chill_main_gender table
|
||||
$this->addSql("
|
||||
INSERT INTO chill_main_gender (id, label, active, genderTranslation, icon, ordering)
|
||||
VALUES
|
||||
(nextval('chill_main_gender_id_seq'),
|
||||
'{\"fr\": \"homme\", \"nl\": \"man\"}',
|
||||
true,
|
||||
'man',
|
||||
'bi bi-gender-male',
|
||||
1.0
|
||||
),
|
||||
(nextval('chill_main_gender_id_seq'),
|
||||
'{\"fr\": \"femme\", \"nl\": \"vrouw\"}',
|
||||
true,
|
||||
'woman',
|
||||
'bi bi-gender-female',
|
||||
1.1
|
||||
),
|
||||
(nextval('chill_main_gender_id_seq'),
|
||||
'{\"fr\": \"neutre\", \"nl\": \"neutraal\"}',
|
||||
true,
|
||||
'neutral',
|
||||
'bi bi-gender-neuter',
|
||||
1.1
|
||||
),
|
||||
(nextval('chill_main_gender_id_seq'),
|
||||
'{\"fr\": \"inconnu\", \"nl\": \"ongekend\"}',
|
||||
true,
|
||||
'unknown',
|
||||
'bi bi-question',
|
||||
1.2
|
||||
)
|
||||
");
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$this->addSql('DROP SEQUENCE chill_main_gender_id_seq CASCADE');
|
||||
$this->addSql('DROP TABLE chill_main_gender');
|
||||
}
|
||||
}
|
@ -43,6 +43,7 @@ lifecycleUpdate: Evenements de création et mise à jour
|
||||
address_fields: Données liées à l'adresse
|
||||
Datas: Données
|
||||
No title: Aucun titre
|
||||
icon: icône
|
||||
|
||||
user:
|
||||
profile:
|
||||
@ -474,6 +475,12 @@ crud:
|
||||
title_delete: Supprimer une actualité
|
||||
button_delete: Supprimer
|
||||
confirm_message_delete: Êtes-vous sûr de vouloir supprimer l'actualité, "%as_string%" ?
|
||||
main_gender:
|
||||
index:
|
||||
title: Liste des genres
|
||||
add_new: Ajouter un genre
|
||||
title_new: Nouveau genre
|
||||
title_edit: Modifier un genre
|
||||
|
||||
No entities: Aucun élément
|
||||
|
||||
@ -781,4 +788,9 @@ news:
|
||||
read_more: Lire la suite
|
||||
show_details: Voir l'actualité
|
||||
|
||||
gender:
|
||||
genderTranslation: traduction grammaticale
|
||||
not defined: Non défini
|
||||
pick gender: Choisir une genre
|
||||
|
||||
|
||||
|
@ -201,7 +201,7 @@ class PersonMove
|
||||
private function getDeleteEntities(): array
|
||||
{
|
||||
return [
|
||||
AccompanyingPeriod\AccompanyingPeriodWork::class,
|
||||
// AccompanyingPeriod\AccompanyingPeriodWork::class,
|
||||
Relationship::class,
|
||||
];
|
||||
}
|
||||
@ -216,7 +216,7 @@ class PersonMove
|
||||
}
|
||||
|
||||
/**
|
||||
* get the full table name with schema if it does exists.
|
||||
* get the full table name with schema if it exists.
|
||||
*/
|
||||
private function getTableName(ClassMetadata $metadata): string
|
||||
{
|
||||
|
@ -15,11 +15,14 @@ use Chill\MainBundle\DataFixtures\ORM\LoadPostalCodes;
|
||||
use Chill\MainBundle\Entity\Address;
|
||||
use Chill\MainBundle\Entity\Center;
|
||||
use Chill\MainBundle\Entity\Country;
|
||||
use Chill\MainBundle\Entity\Gender;
|
||||
use Chill\MainBundle\Entity\GenderEnum;
|
||||
use Chill\MainBundle\Entity\PostalCode;
|
||||
use Chill\MainBundle\Entity\Scope;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Repository\CenterRepository;
|
||||
use Chill\MainBundle\Repository\CountryRepository;
|
||||
use Chill\MainBundle\Repository\GenderRepository;
|
||||
use Chill\MainBundle\Repository\ScopeRepository;
|
||||
use Chill\MainBundle\Repository\UserRepository;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
@ -77,12 +80,15 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
|
||||
*/
|
||||
protected array $cacheUsers = [];
|
||||
|
||||
/**
|
||||
* @var array|Gender[]
|
||||
*/
|
||||
protected array $cacheGenders = [];
|
||||
|
||||
protected Generator $faker;
|
||||
|
||||
protected NativeLoader $loader;
|
||||
|
||||
private array $genders = [Person::MALE_GENDER, Person::FEMALE_GENDER, Person::BOTH_GENDER];
|
||||
|
||||
private array $peoples = [
|
||||
[
|
||||
'lastName' => 'Depardieu',
|
||||
@ -90,7 +96,7 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
|
||||
'birthdate' => '1948-12-27',
|
||||
'placeOfBirth' => 'Châteauroux',
|
||||
'nationality' => 'RU',
|
||||
'gender' => Person::MALE_GENDER,
|
||||
'gender' => GenderEnum::MALE,
|
||||
'center' => 'Center A',
|
||||
'accompanyingPeriods' => [
|
||||
[
|
||||
@ -119,7 +125,7 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
|
||||
'maritalStatus' => 'ms_divorce',
|
||||
],
|
||||
[
|
||||
// to have a person with same birthdate of Gérard Depardieu
|
||||
// to have a person with same birthdate as Gérard Depardieu
|
||||
'lastName' => 'Van Snick',
|
||||
'firstName' => 'Bart',
|
||||
'birthdate' => '1948-12-27',
|
||||
@ -131,7 +137,7 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
|
||||
'lastName' => 'Depardieu',
|
||||
'firstName' => 'Charline',
|
||||
'birthdate' => '1970-10-15',
|
||||
'gender' => Person::FEMALE_GENDER,
|
||||
'gender' => GenderEnum::FEMALE,
|
||||
'center' => 'Center A',
|
||||
'maritalStatus' => 'ms_legalco',
|
||||
],
|
||||
@ -228,6 +234,7 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
|
||||
protected MaritalStatusRepository $maritalStatusRepository,
|
||||
protected ScopeRepository $scopeRepository,
|
||||
protected UserRepository $userRepository,
|
||||
protected GenderRepository $genderRepository,
|
||||
) {
|
||||
$this->faker = Factory::create('fr_FR');
|
||||
$this->faker->addProvider($this);
|
||||
@ -272,9 +279,17 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
|
||||
/**
|
||||
* @internal This method is public and called by faker as a custom generator
|
||||
*/
|
||||
public function getRandomGender(): string
|
||||
public function getRandomGender(int $nullPercentage = 50): ?Gender
|
||||
{
|
||||
return $this->genders[array_rand($this->genders)];
|
||||
if (0 === \count($this->cacheGenders)) {
|
||||
$this->cacheGenders = $this->genderRepository->findByActiveOrdered();
|
||||
}
|
||||
|
||||
if (\random_int(0, 100) > $nullPercentage) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->cacheGenders[array_rand($this->cacheGenders)];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -21,6 +21,7 @@ use Chill\MainBundle\Entity\Center;
|
||||
use Chill\MainBundle\Entity\Civility;
|
||||
use Chill\MainBundle\Entity\Country;
|
||||
use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
|
||||
use Chill\MainBundle\Entity\Gender;
|
||||
use Chill\MainBundle\Entity\HasCenterInterface;
|
||||
use Chill\MainBundle\Entity\Language;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
@ -62,19 +63,11 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
#[HouseholdMembershipSequential(groups: ['household_memberships'])]
|
||||
class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateInterface, \Stringable
|
||||
{
|
||||
final public const BOTH_GENDER = 'both';
|
||||
|
||||
// have days in commun
|
||||
final public const ERROR_ADDIND_PERIOD_AFTER_AN_OPEN_PERIOD = 2; // where there exist
|
||||
|
||||
final public const ERROR_PERIODS_ARE_COLLAPSING = 1; // when two different periods
|
||||
|
||||
final public const FEMALE_GENDER = 'woman';
|
||||
|
||||
final public const MALE_GENDER = 'man';
|
||||
|
||||
final public const NO_INFORMATION = 'unknown';
|
||||
|
||||
/**
|
||||
* Accept receiving email.
|
||||
*/
|
||||
@ -245,11 +238,11 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
private ?string $fullnameCanonical = '';
|
||||
|
||||
/**
|
||||
* The person's gender.
|
||||
* NEW column : The person's gender.
|
||||
*/
|
||||
#[Assert\NotNull(message: 'The gender must be set')]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 9, nullable: true)]
|
||||
private ?string $gender = null;
|
||||
#[ORM\ManyToOne(targetEntity: Gender::class)]
|
||||
private ?Gender $gender = null;
|
||||
|
||||
/**
|
||||
* Comment on gender.
|
||||
@ -1041,7 +1034,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
return $this->fullnameCanonical;
|
||||
}
|
||||
|
||||
public function getGender(): ?string
|
||||
public function getGender(): ?Gender
|
||||
{
|
||||
return $this->gender;
|
||||
}
|
||||
@ -1051,24 +1044,6 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
return $this->genderComment;
|
||||
}
|
||||
|
||||
/**
|
||||
* return gender as a Numeric form.
|
||||
* This is used for translations.
|
||||
*
|
||||
* @return int
|
||||
*
|
||||
* @deprecated Keep for legacy. Used in Chill 1.5 for feminize before icu translations
|
||||
*/
|
||||
public function getGenderNumeric()
|
||||
{
|
||||
return match ($this->getGender()) {
|
||||
self::FEMALE_GENDER => 1,
|
||||
self::MALE_GENDER => 0,
|
||||
self::BOTH_GENDER => 2,
|
||||
default => -1,
|
||||
};
|
||||
}
|
||||
|
||||
public function getHouseholdAddresses(): Collection
|
||||
{
|
||||
return $this->householdAddresses;
|
||||
@ -1570,7 +1545,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setGender(?string $gender): self
|
||||
public function setGender(?Gender $gender): self
|
||||
{
|
||||
$this->gender = $gender;
|
||||
|
||||
|
@ -55,7 +55,7 @@ readonly class ReferrerScopeAggregator implements AggregatorInterface, DataTrans
|
||||
$qb->expr()->gte('COALESCE(acp.closingDate, CURRENT_TIMESTAMP())', "{$p}_userHistory.startDate"),
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->isNull("{$p}_userHistory.endDate"),
|
||||
$qb->expr()->lt('COALESCE(acp.closingDate, CURRENT_TIMESTAMP())', "{$p}_userHistory.endDate")
|
||||
$qb->expr()->lt('COALESCE(acp.openingDate, CURRENT_TIMESTAMP())', "{$p}_userHistory.endDate")
|
||||
)
|
||||
),
|
||||
$qb->expr()->andX(
|
||||
|
@ -12,7 +12,8 @@ declare(strict_types=1);
|
||||
namespace Chill\PersonBundle\Export\Aggregator\PersonAggregators;
|
||||
|
||||
use Chill\MainBundle\Export\AggregatorInterface;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\MainBundle\Repository\GenderRepository;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Chill\PersonBundle\Export\Declarations;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
@ -20,7 +21,7 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
final readonly class GenderAggregator implements AggregatorInterface
|
||||
{
|
||||
public function __construct(private TranslatorInterface $translator) {}
|
||||
public function __construct(private TranslatorInterface $translator, private TranslatableStringHelperInterface $translatableStringHelper, private GenderRepository $repository) {}
|
||||
|
||||
public function addRole(): ?string
|
||||
{
|
||||
@ -29,7 +30,8 @@ final readonly class GenderAggregator implements AggregatorInterface
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
$qb->addSelect('person.gender as gender');
|
||||
$qb->leftJoin('person.gender', 'g');
|
||||
$qb->addSelect('g.id as gender');
|
||||
|
||||
$qb->addGroupBy('gender');
|
||||
}
|
||||
@ -48,30 +50,20 @@ final readonly class GenderAggregator implements AggregatorInterface
|
||||
|
||||
public function getLabels($key, array $values, $data)
|
||||
{
|
||||
return function ($value) {
|
||||
switch ($value) {
|
||||
case Person::FEMALE_GENDER:
|
||||
return $this->translator->trans('woman');
|
||||
|
||||
case Person::MALE_GENDER:
|
||||
return $this->translator->trans('man');
|
||||
|
||||
case Person::BOTH_GENDER:
|
||||
return $this->translator->trans('both');
|
||||
|
||||
case Person::NO_INFORMATION:
|
||||
return $this->translator->trans('unknown');
|
||||
|
||||
case null:
|
||||
case '':
|
||||
return $this->translator->trans('Not given');
|
||||
|
||||
case '_header':
|
||||
return $this->translator->trans('Gender');
|
||||
|
||||
default:
|
||||
throw new \LogicException(sprintf('The value %s is not valid', $value));
|
||||
return function (int|string|null $value) {
|
||||
if (null === $value || '' === $value) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ('_header' === $value) {
|
||||
return $this->translator->trans('Gender');
|
||||
}
|
||||
|
||||
if (null === $gender = $this->repository->find((int) $value)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return (string) $this->translatableStringHelper->localize($gender->getLabel());
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -11,11 +11,13 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\PersonBundle\Export\Filter\PersonFilters;
|
||||
|
||||
use Chill\MainBundle\Entity\Gender;
|
||||
use Chill\MainBundle\Export\DataTransformerInterface;
|
||||
use Chill\MainBundle\Export\ExportElementValidatedInterface;
|
||||
use Chill\MainBundle\Export\FilterInterface;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\MainBundle\Repository\GenderRepository;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Chill\PersonBundle\Export\Declarations;
|
||||
use Doctrine\ORM\Query\Expr;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
@ -24,17 +26,15 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
class GenderFilter implements
|
||||
ExportElementValidatedInterface,
|
||||
FilterInterface
|
||||
FilterInterface,
|
||||
DataTransformerInterface
|
||||
{
|
||||
/**
|
||||
* @var TranslatorInterface
|
||||
*/
|
||||
protected $translator;
|
||||
|
||||
public function __construct(TranslatorInterface $translator)
|
||||
{
|
||||
$this->translator = $translator;
|
||||
}
|
||||
// inject gender repository and find the active genders so that you can pass them to the ChoiceType (ordered by ordering)
|
||||
public function __construct(
|
||||
private readonly TranslatorInterface $translator,
|
||||
private readonly TranslatableStringHelperInterface $translatableStringHelper,
|
||||
private readonly GenderRepository $genderRepository,
|
||||
) {}
|
||||
|
||||
public function addRole(): ?string
|
||||
{
|
||||
@ -46,23 +46,17 @@ class GenderFilter implements
|
||||
$where = $qb->getDQLPart('where');
|
||||
$isIn = $qb->expr()->in('person.gender', ':person_gender');
|
||||
|
||||
if (!\in_array('null', $data['accepted_genders'], true)) {
|
||||
$acceptedGenders = $data['accepted_genders_entity'];
|
||||
$nullIncluded = in_array(null, $acceptedGenders ?? [], true);
|
||||
|
||||
if (!$nullIncluded) {
|
||||
$clause = $isIn;
|
||||
} else {
|
||||
$clause = $qb->expr()->orX($isIn, $qb->expr()->isNull('person.gender'));
|
||||
}
|
||||
|
||||
if ($where instanceof Expr\Andx) {
|
||||
$where->add($clause);
|
||||
} else {
|
||||
$where = $qb->expr()->andX($clause);
|
||||
}
|
||||
|
||||
$qb->add('where', $where);
|
||||
$qb->setParameter('person_gender', \array_filter(
|
||||
$data['accepted_genders'],
|
||||
static fn ($el) => 'null' !== $el
|
||||
));
|
||||
$qb->andWhere($clause);
|
||||
$qb->setParameter('person_gender', array_filter($acceptedGenders ?? [], fn ($gender) => null !== $gender));
|
||||
}
|
||||
|
||||
public function applyOn()
|
||||
@ -72,19 +66,42 @@ class GenderFilter implements
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
$builder->add('accepted_genders', ChoiceType::class, [
|
||||
'choices' => [
|
||||
'Woman' => Person::FEMALE_GENDER,
|
||||
'Man' => Person::MALE_GENDER,
|
||||
'Both' => Person::BOTH_GENDER,
|
||||
'Unknown' => Person::NO_INFORMATION,
|
||||
'Not given' => 'null',
|
||||
],
|
||||
$genderChoices = $this->genderRepository->findByActiveOrdered();
|
||||
$choices = ['None' => null];
|
||||
|
||||
foreach ($genderChoices as $gender) {
|
||||
$choices[$this->translatableStringHelper->localize($gender->getLabel())] = $gender->getId();
|
||||
}
|
||||
|
||||
$builder->add('accepted_genders_entity', ChoiceType::class, [
|
||||
'choices' => $choices,
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
'placeholder' => 'Select gender',
|
||||
]);
|
||||
}
|
||||
|
||||
public function transformData(?array $before): array
|
||||
{
|
||||
$transformedData = [];
|
||||
$transformedData['accepted_genders_entity'] = $before['accepted_genders_entity'] ?? [];
|
||||
|
||||
if (array_key_exists('accepted_genders', $before)) {
|
||||
foreach ($before['accepted_genders'] as $genderBefore) {
|
||||
foreach ($this->genderRepository->findByGenderTranslation(
|
||||
match ($genderBefore) {
|
||||
'both' => 'neutral',
|
||||
default => $genderBefore,
|
||||
}
|
||||
) as $gender) {
|
||||
$transformedData['accepted_genders_entity'][] = $gender;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $transformedData;
|
||||
}
|
||||
|
||||
public function getFormDefaultData(): array
|
||||
{
|
||||
return [];
|
||||
@ -94,11 +111,11 @@ class GenderFilter implements
|
||||
{
|
||||
$genders = [];
|
||||
|
||||
foreach ($data['accepted_genders'] as $g) {
|
||||
if ('null' === $g) {
|
||||
$genders[] = $this->translator->trans('Not given');
|
||||
foreach ($data['accepted_genders_entity'] as $g) {
|
||||
if (null === $g) {
|
||||
$genders[] = $this->translator->trans('export.filter.person.gender.no_gender');
|
||||
} else {
|
||||
$genders[] = $this->translator->trans($g);
|
||||
$genders[] = $this->translatableStringHelper->localize($this->genderRepository->find($g)->getLabel());
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,7 +137,7 @@ class GenderFilter implements
|
||||
|
||||
public function validateForm($data, ExecutionContextInterface $context)
|
||||
{
|
||||
if (!\is_array($data['accepted_genders']) || 0 === \count($data['accepted_genders'])) {
|
||||
if (!\is_iterable($data['accepted_genders_entity']) || 0 === \count($data['accepted_genders_entity'])) {
|
||||
$context->buildViolation('You should select an option')
|
||||
->addViolation();
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ use Chill\MainBundle\Export\Helper\ExportAddressHelper;
|
||||
use Chill\MainBundle\Repository\CenterRepositoryInterface;
|
||||
use Chill\MainBundle\Repository\CivilityRepositoryInterface;
|
||||
use Chill\MainBundle\Repository\CountryRepository;
|
||||
use Chill\MainBundle\Repository\GenderRepository;
|
||||
use Chill\MainBundle\Repository\LanguageRepositoryInterface;
|
||||
use Chill\MainBundle\Repository\UserRepositoryInterface;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
@ -80,6 +81,7 @@ final readonly class ListPersonHelper
|
||||
private TranslatableStringHelper $translatableStringHelper,
|
||||
private TranslatorInterface $translator,
|
||||
private UserRepositoryInterface $userRepository,
|
||||
private GenderRepository $genderRepository,
|
||||
/**
|
||||
* @var iterable<CustomizeListPersonHelperInterface>
|
||||
*/
|
||||
@ -173,6 +175,11 @@ final readonly class ListPersonHelper
|
||||
|
||||
break;
|
||||
|
||||
case 'gender':
|
||||
$qb->addSelect('IDENTITY(person.gender) AS gender');
|
||||
|
||||
break;
|
||||
|
||||
case 'maritalStatus':
|
||||
$qb->addSelect('IDENTITY(person.maritalStatus) AS maritalStatus');
|
||||
|
||||
@ -325,7 +332,13 @@ final readonly class ListPersonHelper
|
||||
return $this->translator->trans($key);
|
||||
}
|
||||
|
||||
return $this->translator->trans($value);
|
||||
if (null === $value) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$gender = $this->genderRepository->find($value);
|
||||
|
||||
return $this->translatableStringHelper->localize($gender->getLabel());
|
||||
};
|
||||
|
||||
case 'maritalStatus':
|
||||
|
@ -20,8 +20,8 @@ use Chill\MainBundle\Form\Type\PickCenterType;
|
||||
use Chill\MainBundle\Form\Type\PickCivilityType;
|
||||
use Chill\PersonBundle\Config\ConfigPersonAltNamesHelper;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Form\Type\GenderType;
|
||||
use Chill\PersonBundle\Form\Type\PersonAltNameType;
|
||||
use Chill\PersonBundle\Form\Type\PickGenderType;
|
||||
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||
use libphonenumber\PhoneNumberType;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||
@ -60,7 +60,7 @@ final class CreationPersonType extends AbstractType
|
||||
'label' => 'Civility',
|
||||
'placeholder' => 'choose civility',
|
||||
])
|
||||
->add('gender', GenderType::class, [
|
||||
->add('gender', PickGenderType::class, [
|
||||
'required' => true, 'placeholder' => null,
|
||||
])
|
||||
->add('birthdate', ChillDateType::class, [
|
||||
|
@ -24,9 +24,9 @@ use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Chill\PersonBundle\Config\ConfigPersonAltNamesHelper;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Entity\PersonPhone;
|
||||
use Chill\PersonBundle\Form\Type\GenderType;
|
||||
use Chill\PersonBundle\Form\Type\PersonAltNameType;
|
||||
use Chill\PersonBundle\Form\Type\PersonPhoneType;
|
||||
use Chill\PersonBundle\Form\Type\PickGenderType;
|
||||
use Chill\PersonBundle\Form\Type\Select2MaritalStatusType;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\CallbackTransformer;
|
||||
@ -80,7 +80,7 @@ class PersonType extends AbstractType
|
||||
'input' => 'datetime_immutable',
|
||||
'widget' => 'single_text',
|
||||
])
|
||||
->add('gender', GenderType::class, [
|
||||
->add('gender', PickGenderType::class, [
|
||||
'required' => true,
|
||||
])
|
||||
->add('genderComment', CommentType::class, [
|
||||
|
@ -1,44 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\PersonBundle\Form\Type;
|
||||
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
/**
|
||||
* A type to select the civil union state.
|
||||
*/
|
||||
class GenderType extends AbstractType
|
||||
{
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$a = [
|
||||
Person::MALE_GENDER => Person::MALE_GENDER,
|
||||
Person::FEMALE_GENDER => Person::FEMALE_GENDER,
|
||||
Person::BOTH_GENDER => Person::BOTH_GENDER,
|
||||
];
|
||||
|
||||
$resolver->setDefaults([
|
||||
'choices' => $a,
|
||||
'expanded' => true,
|
||||
'multiple' => false,
|
||||
'placeholder' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
public function getParent()
|
||||
{
|
||||
return ChoiceType::class;
|
||||
}
|
||||
}
|
51
src/Bundle/ChillPersonBundle/Form/Type/PickGenderType.php
Normal file
51
src/Bundle/ChillPersonBundle/Form/Type/PickGenderType.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\PersonBundle\Form\Type;
|
||||
|
||||
use Chill\MainBundle\Entity\Gender;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
/**
|
||||
* A type to select the civil union state.
|
||||
*/
|
||||
class PickGenderType extends AbstractType
|
||||
{
|
||||
public function __construct(private readonly TranslatableStringHelper $translatableStringHelper) {}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$resolver
|
||||
->setDefault('label', 'Gender')
|
||||
->setDefault(
|
||||
'choice_label',
|
||||
fn (Gender $gender): string => $this->translatableStringHelper->localize($gender->getLabel())
|
||||
)
|
||||
->setDefault(
|
||||
'query_builder',
|
||||
static fn (EntityRepository $er): QueryBuilder => $er->createQueryBuilder('g')
|
||||
->where('g.active = true')
|
||||
->orderBy('g.order'),
|
||||
)
|
||||
->setDefault('placeholder', 'choose gender')
|
||||
->setDefault('class', Gender::class);
|
||||
}
|
||||
|
||||
public function getParent()
|
||||
{
|
||||
return EntityType::class;
|
||||
}
|
||||
}
|
@ -45,13 +45,17 @@ class AdminPersonMenuBuilder implements LocalMenuBuilderInterface
|
||||
'route' => 'chill_crud_main_civility_index',
|
||||
])->setExtras(['order' => 2010]);
|
||||
|
||||
$menu->addChild('Gender', [
|
||||
'route' => 'chill_crud_main_gender_index',
|
||||
])->setExtras(['order' => 2020]);
|
||||
|
||||
$menu->addChild('Marital status', [
|
||||
'route' => 'chill_crud_person_marital-status_index',
|
||||
])->setExtras(['order' => 2020]);
|
||||
])->setExtras(['order' => 2030]);
|
||||
|
||||
$menu->addChild('person_admin.person_resource_kind', [
|
||||
'route' => 'chill_crud_person_resource-kind_index',
|
||||
])->setExtras(['order' => 2030]);
|
||||
])->setExtras(['order' => 2040]);
|
||||
}
|
||||
|
||||
public static function getMenuIds(): array
|
||||
|
@ -34,7 +34,7 @@ final readonly class PersonACLAwareRepository implements PersonACLAwareRepositor
|
||||
?\DateTimeInterface $birthdate = null,
|
||||
?\DateTimeInterface $birthdateBefore = null,
|
||||
?\DateTimeInterface $birthdateAfter = null,
|
||||
?string $gender = null,
|
||||
?int $gender = null,
|
||||
?string $countryCode = null,
|
||||
?string $phonenumber = null,
|
||||
?string $city = null,
|
||||
@ -62,7 +62,7 @@ final readonly class PersonACLAwareRepository implements PersonACLAwareRepositor
|
||||
?\DateTimeInterface $birthdate = null,
|
||||
?\DateTimeInterface $birthdateBefore = null,
|
||||
?\DateTimeInterface $birthdateAfter = null,
|
||||
?string $gender = null,
|
||||
?int $gender = null,
|
||||
?string $countryCode = null,
|
||||
?string $phonenumber = null,
|
||||
?string $city = null,
|
||||
@ -96,7 +96,7 @@ final readonly class PersonACLAwareRepository implements PersonACLAwareRepositor
|
||||
?\DateTimeInterface $birthdate = null,
|
||||
?\DateTimeInterface $birthdateBefore = null,
|
||||
?\DateTimeInterface $birthdateAfter = null,
|
||||
?string $gender = null,
|
||||
?int $gender = null,
|
||||
?string $countryCode = null,
|
||||
?string $phonenumber = null,
|
||||
?string $city = null,
|
||||
@ -202,7 +202,7 @@ final readonly class PersonACLAwareRepository implements PersonACLAwareRepositor
|
||||
}
|
||||
|
||||
if (null !== $gender) {
|
||||
$query->andWhereClause('person.gender = ?', [$gender]);
|
||||
$query->andWhereClause('person.gender_id = ?', [$gender]);
|
||||
}
|
||||
|
||||
return $query;
|
||||
@ -253,7 +253,7 @@ final readonly class PersonACLAwareRepository implements PersonACLAwareRepositor
|
||||
?\DateTimeInterface $birthdate = null,
|
||||
?\DateTimeInterface $birthdateBefore = null,
|
||||
?\DateTimeInterface $birthdateAfter = null,
|
||||
?string $gender = null,
|
||||
?int $gender = null,
|
||||
?string $countryCode = null,
|
||||
?string $phonenumber = null,
|
||||
?string $city = null,
|
||||
|
@ -23,7 +23,7 @@ interface PersonACLAwareRepositoryInterface
|
||||
?\DateTimeInterface $birthdate = null,
|
||||
?\DateTimeInterface $birthdateBefore = null,
|
||||
?\DateTimeInterface $birthdateAfter = null,
|
||||
?string $gender = null,
|
||||
?int $gender = null,
|
||||
?string $countryCode = null,
|
||||
?string $phonenumber = null,
|
||||
?string $city = null,
|
||||
@ -36,7 +36,7 @@ interface PersonACLAwareRepositoryInterface
|
||||
?\DateTimeInterface $birthdate = null,
|
||||
?\DateTimeInterface $birthdateBefore = null,
|
||||
?\DateTimeInterface $birthdateAfter = null,
|
||||
?string $gender = null,
|
||||
?int $gender = null,
|
||||
?string $countryCode = null,
|
||||
?string $phonenumber = null,
|
||||
?string $city = null,
|
||||
@ -55,7 +55,7 @@ interface PersonACLAwareRepositoryInterface
|
||||
?\DateTimeInterface $birthdate = null,
|
||||
?\DateTimeInterface $birthdateBefore = null,
|
||||
?\DateTimeInterface $birthdateAfter = null,
|
||||
?string $gender = null,
|
||||
?int $gender = null,
|
||||
?string $countryCode = null,
|
||||
?string $phonenumber = null,
|
||||
?string $city = null,
|
||||
|
@ -128,7 +128,7 @@ export default {
|
||||
body.mobilenumber = payload.data.mobilenumber;
|
||||
body.email = payload.data.email;
|
||||
body.altNames = payload.data.altNames;
|
||||
body.gender = payload.data.gender;
|
||||
body.gender = {id: payload.data.gender.id, type: payload.data.gender.type };
|
||||
if (payload.data.civility !== null) { body.civility = {id: payload.data.civility.id, type: payload.data.civility.type }; }
|
||||
|
||||
makeFetch('PATCH', `/api/1.0/person/person/${payload.data.id}.json`, body)
|
||||
|
@ -153,7 +153,7 @@ export default {
|
||||
body.mobilenumber = payload.data.mobilenumber;
|
||||
body.email = payload.data.email;
|
||||
body.altNames = payload.data.altNames;
|
||||
body.gender = payload.data.gender;
|
||||
body.gender = {id: payload.data.gender.id, type: payload.data.gender.type };
|
||||
if (payload.data.civility !== null) { body.civility = {id: payload.data.civility.id, type: payload.data.civility.type}; }
|
||||
|
||||
makeFetch('PATCH', `/api/1.0/person/person/${payload.data.id}.json`, body)
|
||||
|
@ -8,7 +8,7 @@
|
||||
{{ $t('household_members_editor.holder') }}
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="conc.person.birthdate !== null">{{ $t('person.born', {'gender': conc.person.gender} ) }}</div>
|
||||
<div v-if="conc.person.birthdate !== null">{{ $t('person.born', {'gender': conc.person.gender.genderTranslation} ) }}</div>
|
||||
</div>
|
||||
<div class="item-col">
|
||||
<ul class="list-content fa-ul">
|
||||
|
@ -12,10 +12,6 @@ const visMessages = {
|
||||
Holder: 'Titulaire',
|
||||
Legend: 'Calques',
|
||||
concerned: 'concerné',
|
||||
// both: 'neutre, non binaire',
|
||||
woman: 'féminin',
|
||||
man: 'masculin',
|
||||
undefined: "genre non précisé",
|
||||
years: 'ans',
|
||||
click_to_expand: 'cliquez pour étendre',
|
||||
add_relationship_link: "Créer un lien de filiation",
|
||||
@ -64,7 +60,7 @@ const visMessages = {
|
||||
placeholder: "Choisissez le genre de l'usager",
|
||||
woman: "Féminin",
|
||||
man: "Masculin",
|
||||
both: "Neutre, non binaire",
|
||||
neutral: "Neutre, non binaire",
|
||||
undefined: "Non renseigné",
|
||||
unknown: "Non renseigné"
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { createStore } from 'vuex'
|
||||
import { getHouseholdByPerson, getCoursesByPerson, getRelationshipsByPerson } from './api'
|
||||
import { getHouseholdLabel, getHouseholdWidth, getRelationshipLabel, getRelationshipTitle, getRelationshipDirection, splitId, getGender, getAge } from './vis-network'
|
||||
import { getHouseholdLabel, getHouseholdWidth, getRelationshipLabel, getRelationshipTitle, getRelationshipDirection, splitId, getAge } from './vis-network'
|
||||
import {visMessages} from "./i18n";
|
||||
import { darkBlue, darkBrown, darkGreen, lightBlue, lightBrown, lightGreen } from './colors';
|
||||
|
||||
@ -148,7 +148,7 @@ const store = createStore({
|
||||
person.group = person.type
|
||||
person._id = person.id
|
||||
person.id = `person_${person.id}`
|
||||
person.label = `*${person.text}${person.deathdate ? ' (‡)' : ''}*\n_${getGender(person.gender)}${age}_${debug}`
|
||||
person.label = `*${person.text}${person.deathdate ? ' (‡)' : ''}*\n_${person.gender.label.fr}${age}_${debug}`
|
||||
person.folded = false
|
||||
// folded is used for missing persons
|
||||
if (options.folded) {
|
||||
|
@ -141,25 +141,6 @@ window.options = {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param gender
|
||||
* @returns {string}
|
||||
*/
|
||||
const getGender = (gender) => {
|
||||
switch (gender) {
|
||||
case 'both':
|
||||
return visMessages.fr.visgraph.both
|
||||
case 'woman':
|
||||
return visMessages.fr.visgraph.woman
|
||||
case 'man':
|
||||
return visMessages.fr.visgraph.man
|
||||
case 'unknown':
|
||||
return visMessages.fr.visgraph.unknown
|
||||
default:
|
||||
return visMessages.fr.visgraph.undefined
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO only one abstract function (-> getAge() is repeated in PersonRenderBox.vue)
|
||||
* @param person
|
||||
@ -251,7 +232,6 @@ const splitId = (id, position) => {
|
||||
}
|
||||
|
||||
export {
|
||||
getGender,
|
||||
getAge,
|
||||
getHouseholdLabel,
|
||||
getHouseholdWidth,
|
||||
|
@ -24,6 +24,13 @@ const getCivilities = () =>
|
||||
throw Error('Error with request resource response');
|
||||
});
|
||||
|
||||
const getGenders = () => makeFetch("GET", '/api/1.0/main/gender.json')
|
||||
// .then(response => {
|
||||
// console.log(response)
|
||||
// if (response.ok) { return response.json(); }
|
||||
// throw Error('Error with request resource response');
|
||||
// });
|
||||
|
||||
const getCentersForPersonCreation = () => makeFetch('GET', '/api/1.0/person/creation/authorized-centers', null);
|
||||
|
||||
/*
|
||||
@ -63,10 +70,11 @@ const patchPerson = (id, body) => {
|
||||
};
|
||||
|
||||
export {
|
||||
getCentersForPersonCreation,
|
||||
getCentersForPersonCreation,
|
||||
getPerson,
|
||||
getPersonAltNames,
|
||||
getCivilities,
|
||||
getGenders,
|
||||
postPerson,
|
||||
patchPerson
|
||||
};
|
||||
|
@ -37,10 +37,9 @@
|
||||
</div>
|
||||
|
||||
<p v-if="options.addInfo === true" class="moreinfo">
|
||||
<i :class="'fa fa-fw ' + getGenderIcon" :title="$t(getGender)"></i>
|
||||
|
||||
<gender-icon-render-box v-if="person.gender" :gender="person.gender"></gender-icon-render-box>
|
||||
<time v-if="person.birthdate && !person.deathdate" :datetime="person.birthdate" :title="birthdate">
|
||||
{{ $t(getGenderTranslation) + ' ' + $d(birthdate, 'text') }}
|
||||
{{ $t(person.gender ? `renderbox.birthday.${person.gender.genderTranslation}` : 'renderbox.birthday.neutral') + ' ' + $d(birthdate, 'text') }}
|
||||
</time>
|
||||
|
||||
<time v-else-if="person.birthdate && person.deathdate" :datetime="person.deathdate"
|
||||
@ -180,6 +179,7 @@
|
||||
<script>
|
||||
import {dateToISO, ISOToDate} from 'ChillMainAssets/chill/js/date';
|
||||
import AddressRenderBox from 'ChillMainAssets/vuejs/_components/Entity/AddressRenderBox.vue';
|
||||
import GenderIconRenderBox from 'ChillMainAssets/vuejs/_components/Entity/GenderIconRenderBox.vue'
|
||||
import Confidential from 'ChillMainAssets/vuejs/_components/Confidential.vue';
|
||||
import BadgeEntity from 'ChillMainAssets/vuejs/_components/BadgeEntity.vue';
|
||||
import PersonText from 'ChillPersonAssets/vuejs/_components/Entity/PersonText.vue';
|
||||
@ -190,6 +190,7 @@ export default {
|
||||
name: "PersonRenderBox",
|
||||
components: {
|
||||
AddressRenderBox,
|
||||
GenderIconRenderBox,
|
||||
Confidential,
|
||||
BadgeEntity,
|
||||
PersonText,
|
||||
@ -222,15 +223,6 @@ export default {
|
||||
return false
|
||||
}
|
||||
},
|
||||
getGenderIcon: function () {
|
||||
return this.person.gender === 'woman' ? 'fa-venus' : this.person.gender === 'man' ? 'fa-mars' : this.person.gender === 'both' ? 'fa-neuter' : 'fa-genderless';
|
||||
},
|
||||
getGenderTranslation: function () {
|
||||
return this.person.gender === 'woman' ? 'renderbox.birthday.woman' : 'renderbox.birthday.man';
|
||||
},
|
||||
getGender() {
|
||||
return this.person.gender === 'woman' ? 'person.gender.woman' : this.person.gender === 'man' ? 'person.gender.man' : this.person.gender === 'both' ? 'person.gender.both' : 'person.gender.undefined';
|
||||
},
|
||||
birthdate: function () {
|
||||
if (this.person.birthdate !== null || this.person.birthdate === "undefined") {
|
||||
return ISOToDate(this.person.birthdate.datetime);
|
||||
|
@ -73,17 +73,16 @@
|
||||
<!-- TODO fix placeholder if undefined
|
||||
-->
|
||||
<div class="form-floating mb-3">
|
||||
<select
|
||||
<select
|
||||
class="form-select form-select-lg"
|
||||
id="gender"
|
||||
v-model="gender"
|
||||
@change="checkErrors"
|
||||
>
|
||||
<option selected disabled >{{ $t('person.gender.placeholder') }}</option>
|
||||
<option value="woman">{{ $t('person.gender.woman') }}</option>
|
||||
<option value="man">{{ $t('person.gender.man') }}</option>
|
||||
<option value="both">{{ $t('person.gender.both') }}</option>
|
||||
</select>
|
||||
>
|
||||
<option selected disabled >{{ $t('person.gender.placeholder') }}</option>
|
||||
<option v-for="g in config.genders" :value="g.id" :key="g.id">
|
||||
{{ g.label.fr }}
|
||||
</option>
|
||||
</select>
|
||||
<label>{{ $t('person.gender.title') }}</label>
|
||||
</div>
|
||||
|
||||
@ -178,7 +177,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getCentersForPersonCreation, getCivilities, getPerson, getPersonAltNames } from '../../_api/OnTheFly';
|
||||
import { getCentersForPersonCreation, getCivilities, getGenders, getPerson, getPersonAltNames } from '../../_api/OnTheFly';
|
||||
import PersonRenderBox from '../Entity/PersonRenderBox.vue';
|
||||
import AddAddress from "ChillMainAssets/vuejs/Address/components/AddAddress.vue";
|
||||
|
||||
@ -204,6 +203,7 @@ export default {
|
||||
altNames: [],
|
||||
civilities: [],
|
||||
centers: [],
|
||||
genders: []
|
||||
},
|
||||
showCenters: false, // NOTE: must remains false if the form is not in create mode
|
||||
showAddressFormValue: false,
|
||||
@ -237,8 +237,8 @@ export default {
|
||||
get() { return this.person.lastName; }
|
||||
},
|
||||
gender: {
|
||||
set(value) { this.person.gender = value; },
|
||||
get() { return this.person.gender; }
|
||||
set(value) { this.person.gender = {id: value, type: 'chill_main_gender'}; },
|
||||
get() { return this.person.gender ? this.person.gender.id : null; }
|
||||
},
|
||||
civility: {
|
||||
set(value) { this.person.civility = {id: value, type: 'chill_main_civility'}; },
|
||||
@ -300,13 +300,13 @@ export default {
|
||||
}
|
||||
},
|
||||
genderTranslation() {
|
||||
switch (this.person.gender) {
|
||||
switch (this.person.gender.genderTranslation) {
|
||||
case 'woman':
|
||||
return 'person.gender.woman';
|
||||
case 'man':
|
||||
return 'person.gender.man';
|
||||
case 'both':
|
||||
return 'person.gender.both';
|
||||
case 'neutral':
|
||||
return 'person.gender.neutral';
|
||||
case 'unknown':
|
||||
return 'person.gender.unknown';
|
||||
default:
|
||||
@ -334,6 +334,12 @@ export default {
|
||||
this.config.civilities = civilities.results;
|
||||
}
|
||||
});
|
||||
getGenders()
|
||||
.then(genders => {
|
||||
if ('results' in genders) {
|
||||
this.config.genders = genders.results;
|
||||
}
|
||||
});
|
||||
if (this.action !== 'create') {
|
||||
this.loadData();
|
||||
} else {
|
||||
|
@ -15,7 +15,7 @@ const personMessages = {
|
||||
person: {
|
||||
firstname: "Prénom",
|
||||
lastname: "Nom",
|
||||
born: (ctx: {gender: "man"|"woman"|"unknown"}) => {
|
||||
born: (ctx: {gender: "man"|"woman"|"neutral"}) => {
|
||||
if (ctx.gender === 'man') {
|
||||
return 'Né le';
|
||||
} else if (ctx.gender === 'woman') {
|
||||
@ -36,7 +36,7 @@ const personMessages = {
|
||||
placeholder: "Choisissez le genre de l'usager",
|
||||
woman: "Féminin",
|
||||
man: "Masculin",
|
||||
both: "Neutre, non binaire",
|
||||
neutral: "Neutre, non binaire",
|
||||
unknown: "Non renseigné",
|
||||
undefined: "Non renseigné"
|
||||
},
|
||||
|
@ -33,7 +33,7 @@
|
||||
{% if w.referrers %}
|
||||
<li>
|
||||
<span class="item-key">{{ 'Referrers'|trans ~ ' : ' }}</span>
|
||||
{% for rh in w.referrersHistory %}
|
||||
{% for rh in w.referrersHistoryCurrent %}
|
||||
<span class="badge-user">{{ rh.user|chill_entity_render_box({'at_date': rh.startDate}) }}</span>
|
||||
{% endfor %}
|
||||
{% if w.referrers|length == 0 %}
|
||||
|
@ -85,13 +85,8 @@
|
||||
{%- endif -%}
|
||||
</div>
|
||||
{%- if options['addInfo'] -%}
|
||||
{% set gender = (person.gender == 'woman') ? 'fa-venus' :
|
||||
(person.gender == 'man') ? 'fa-mars' : (person.gender == 'both') ? 'fa-neuter' : 'fa-genderless' %}
|
||||
{% set genderTitle = (person.gender == 'woman') ? 'woman' :
|
||||
(person.gender == 'man') ? 'man' : (person.gender == 'both') ? 'both' : 'Not given'|trans %}
|
||||
<p class="moreinfo">
|
||||
<i class="fa fa-fw {{ gender }}" title="{{ genderTitle|trans }}"></i>
|
||||
|
||||
{% if person.gender is not null %}{{ person.gender.icon|chill_entity_render_box }}{% endif %}
|
||||
{%- if person.deathdate is not null -%}
|
||||
{%- if person.birthdate is not null -%}
|
||||
{# must be on one line to avoid spaces with dash #}
|
||||
@ -106,7 +101,7 @@
|
||||
{%- endif -%}
|
||||
{%- elseif person.birthdate is not null -%}
|
||||
<time datetime="{{ person.birthdate|date('Y-m-d') }}" title="{{ 'Birthdate'|trans }}">
|
||||
{{ 'Born the date'|trans({'gender': person.gender,
|
||||
{{ 'Born the date'|trans({'gender': person.gender ? person.gender.genderTranslation.value : 'neutral',
|
||||
'birthdate': person.birthdate|format_date("medium") }) }}
|
||||
</time>
|
||||
{%- if options['addAge'] -%}
|
||||
|
@ -45,7 +45,7 @@
|
||||
<div class="ms-auto">
|
||||
{% if acp.requestoranonymous == false and acp.requestorPerson is same as(person) %}
|
||||
<span class="as-requestor badge bg-info" title="{{ 'Requestor'|trans|e('html_attr') }}">
|
||||
{{ 'Requestor'|trans({'gender': person.gender}) }}
|
||||
{{ 'Requestor'|trans({'gender': person.gender ? person.gender.genderTranslation.value : 'neutral'}) }}
|
||||
</span>
|
||||
{% endif %}
|
||||
|
||||
@ -119,7 +119,7 @@
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if participating %}
|
||||
{{ 'person.and_himself'|trans({'gender': person.gender}) }}
|
||||
{{ 'person.And himself'|trans({'gender': person.gender ? person.gender.genderTranslation.value : 'neutral'}) }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
@ -131,7 +131,7 @@
|
||||
<div class="wl-col title">
|
||||
<h3>
|
||||
{% if acp.requestorPerson is not null %}
|
||||
{{ 'Requestor'|trans({'gender': acp.requestorPerson.gender}) }}
|
||||
{{ 'Requestor'|trans({'gender': acp.requestorPerson.gender ? person.gender.genderTranslation.value : 'neutral'}) }}
|
||||
{% else %}
|
||||
{{ 'Requestor'|trans({'gender': 'other'})}}
|
||||
{% endif %}
|
||||
|
@ -73,8 +73,11 @@ This view should receive those arguments:
|
||||
{% endfor %}
|
||||
|
||||
<dt>{{ 'Gender'|trans }} :</dt>
|
||||
<dd>{{ ( person.gender|default('Not given'))|trans }}</dd>
|
||||
|
||||
{% if person.gender %}
|
||||
<dd>{{ ( person.gender.label|localize_translatable_string ) }}</dd>
|
||||
{% else %}
|
||||
<dd>{{ 'gender.not defined'|trans }}</dd>
|
||||
{% endif %}
|
||||
</dl>
|
||||
</figure>
|
||||
</div>
|
||||
@ -253,7 +256,6 @@ This view should receive those arguments:
|
||||
<dd>{% if el.description is not empty %}{{ el.description }} : {% endif %}<a href="tel:{{ el.phonenumber|phone_number_format('E164') }}">{{ el.phonenumber|chill_format_phonenumber }}</a></dd>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</dl>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<ul>
|
||||
<li><b>{{ 'gender'|trans }}</b>:
|
||||
{{ person.gender|trans }}</li>
|
||||
{{ person.gender.label|localize_translatable_string }}</li>
|
||||
<li><b>{{ 'maritalStatus'|trans }}</b>:
|
||||
{% if person.maritalStatus %}{{ person.maritalStatus.name|localize_translatable_string }}{% endif %}</li>
|
||||
<li><b>{{ 'birthdate'|trans }}</b>:
|
||||
|
@ -14,6 +14,7 @@ namespace Chill\PersonBundle\Search;
|
||||
use Chill\MainBundle\Form\Type\ChillDateType;
|
||||
use Chill\MainBundle\Form\Type\ChillPhoneNumberType;
|
||||
use Chill\MainBundle\Pagination\PaginatorFactory;
|
||||
use Chill\MainBundle\Repository\GenderRepository;
|
||||
use Chill\MainBundle\Search\AbstractSearch;
|
||||
use Chill\MainBundle\Search\HasAdvancedSearchFormInterface;
|
||||
use Chill\MainBundle\Search\ParsingException;
|
||||
@ -21,7 +22,7 @@ use Chill\MainBundle\Search\SearchInterface;
|
||||
use Chill\MainBundle\Search\Utils\ExtractDateFromPattern;
|
||||
use Chill\MainBundle\Search\Utils\ExtractPhonenumberFromPattern;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Form\Type\GenderType;
|
||||
use Chill\PersonBundle\Form\Type\PickGenderType;
|
||||
use Chill\PersonBundle\Repository\PersonACLAwareRepositoryInterface;
|
||||
use libphonenumber\PhoneNumber;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
@ -36,7 +37,14 @@ class PersonSearch extends AbstractSearch implements HasAdvancedSearchFormInterf
|
||||
'birthdate-after', 'gender', 'nationality', 'phonenumber', 'city',
|
||||
];
|
||||
|
||||
public function __construct(private readonly \Twig\Environment $templating, private readonly ExtractDateFromPattern $extractDateFromPattern, private readonly ExtractPhonenumberFromPattern $extractPhonenumberFromPattern, private readonly PaginatorFactory $paginatorFactory, private readonly PersonACLAwareRepositoryInterface $personACLAwareRepository) {}
|
||||
public function __construct(
|
||||
private readonly \Twig\Environment $templating,
|
||||
private readonly ExtractDateFromPattern $extractDateFromPattern,
|
||||
private readonly ExtractPhonenumberFromPattern $extractPhonenumberFromPattern,
|
||||
private readonly PaginatorFactory $paginatorFactory,
|
||||
private readonly PersonACLAwareRepositoryInterface $personACLAwareRepository,
|
||||
private readonly GenderRepository $genderRepository,
|
||||
) {}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
@ -69,7 +77,7 @@ class PersonSearch extends AbstractSearch implements HasAdvancedSearchFormInterf
|
||||
'required' => false,
|
||||
'label' => 'Part of the phonenumber',
|
||||
])
|
||||
->add('gender', GenderType::class, [
|
||||
->add('gender', PickGenderType::class, [
|
||||
'label' => 'Gender',
|
||||
'required' => false,
|
||||
'expanded' => false,
|
||||
@ -87,7 +95,7 @@ class PersonSearch extends AbstractSearch implements HasAdvancedSearchFormInterf
|
||||
|
||||
$string .= !isset($data['_default']) ? '' : $data['_default'].' ';
|
||||
|
||||
foreach (['firstname', 'lastname', 'gender', 'city'] as $key) {
|
||||
foreach (['firstname', 'lastname', 'city'] as $key) {
|
||||
$string .= !isset($data[$key]) ? '' : $key.':'.
|
||||
// add quote if contains spaces
|
||||
(str_contains((string) $data[$key], ' ') ? '"'.$data[$key].'"' : $data[$key])
|
||||
@ -103,6 +111,8 @@ class PersonSearch extends AbstractSearch implements HasAdvancedSearchFormInterf
|
||||
|
||||
$string .= !isset($data['phonenumber']) ? '' : 'phonenumber:'.$data['phonenumber']->getNationalNumber();
|
||||
|
||||
$string .= !isset($data['gender']) ? '' : 'gender:"'.$data['gender']->getId().'"';
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
@ -110,7 +120,7 @@ class PersonSearch extends AbstractSearch implements HasAdvancedSearchFormInterf
|
||||
{
|
||||
$data = [];
|
||||
|
||||
foreach (['firstname', 'lastname', 'gender', '_default', 'phonenumber', 'city'] as $key) {
|
||||
foreach (['firstname', 'lastname', '_default', 'phonenumber', 'city'] as $key) {
|
||||
$data[$key] = $terms[$key] ?? null;
|
||||
}
|
||||
|
||||
@ -137,6 +147,10 @@ class PersonSearch extends AbstractSearch implements HasAdvancedSearchFormInterf
|
||||
$data['phonenumber'] = $phonenumber;
|
||||
}
|
||||
|
||||
if (array_key_exists('gender', $terms)) {
|
||||
$data['gender'] = $this->genderRepository->find((int) $terms['gender']);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
@ -256,7 +270,7 @@ class PersonSearch extends AbstractSearch implements HasAdvancedSearchFormInterf
|
||||
$birthdate,
|
||||
$birthdateBefore,
|
||||
$birthdateAfter,
|
||||
$gender,
|
||||
null !== $gender ? (int) $gender : null,
|
||||
$countryCode,
|
||||
$phonenumber,
|
||||
$city
|
||||
@ -316,7 +330,7 @@ class PersonSearch extends AbstractSearch implements HasAdvancedSearchFormInterf
|
||||
$birthdate,
|
||||
$birthdateBefore,
|
||||
$birthdateAfter,
|
||||
$gender,
|
||||
null !== $gender ? (int) $gender : null,
|
||||
$countryCode,
|
||||
$phonenumber,
|
||||
$city
|
||||
|
@ -14,7 +14,7 @@ namespace Chill\PersonBundle\Security\Authorization\StoredObjectVoter;
|
||||
use Chill\DocStoreBundle\Repository\AssociatedEntityToStoredObjectInterface;
|
||||
use Chill\DocStoreBundle\Security\Authorization\StoredObjectRoleEnum;
|
||||
use Chill\DocStoreBundle\Security\Authorization\StoredObjectVoter\AbstractStoredObjectVoter;
|
||||
use Chill\DocStoreBundle\Service\WorkflowStoredObjectPermissionHelper;
|
||||
use Chill\MainBundle\Workflow\Helper\WorkflowRelatedEntityPermissionHelper;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument;
|
||||
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocumentRepository;
|
||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodWorkEvaluationDocumentVoter;
|
||||
@ -25,7 +25,7 @@ class AccompanyingPeriodWorkEvaluationDocumentStoredObjectVoter extends Abstract
|
||||
public function __construct(
|
||||
private readonly AccompanyingPeriodWorkEvaluationDocumentRepository $repository,
|
||||
Security $security,
|
||||
WorkflowStoredObjectPermissionHelper $workflowDocumentService,
|
||||
WorkflowRelatedEntityPermissionHelper $workflowDocumentService,
|
||||
) {
|
||||
parent::__construct($security, $workflowDocumentService);
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ use Chill\DocGeneratorBundle\Serializer\Helper\NormalizeNullValueHelper;
|
||||
use Chill\MainBundle\Entity\Address;
|
||||
use Chill\MainBundle\Entity\Center;
|
||||
use Chill\MainBundle\Entity\Civility;
|
||||
use Chill\MainBundle\Entity\Gender;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
use Chill\PersonBundle\Entity\Household\Household;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
@ -30,7 +31,6 @@ use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
||||
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
class PersonDocGenNormalizer implements
|
||||
ContextAwareNormalizerInterface,
|
||||
@ -40,7 +40,7 @@ class PersonDocGenNormalizer implements
|
||||
|
||||
private const CIRCULAR_KEY = 'person:circular';
|
||||
|
||||
public function __construct(private readonly PersonRenderInterface $personRender, private readonly RelationshipRepository $relationshipRepository, private readonly TranslatorInterface $translator, private readonly TranslatableStringHelper $translatableStringHelper, private readonly SummaryBudgetInterface $summaryBudget) {}
|
||||
public function __construct(private readonly PersonRenderInterface $personRender, private readonly RelationshipRepository $relationshipRepository, private readonly TranslatableStringHelper $translatableStringHelper, private readonly SummaryBudgetInterface $summaryBudget) {}
|
||||
|
||||
public function normalize($person, $format = null, array $context = [])
|
||||
{
|
||||
@ -67,6 +67,7 @@ class PersonDocGenNormalizer implements
|
||||
// when a person reference the same person... take care of circular references
|
||||
AbstractNormalizer::CIRCULAR_REFERENCE_HANDLER => fn ($object, $format, $context) => $this->normalizer->normalize(null, $format, $context),
|
||||
]);
|
||||
$genderContext = array_merge($context, ['docgen:expects' => Gender::class]);
|
||||
|
||||
if (null === $person) {
|
||||
return $this->normalizeNullValue($format, $context);
|
||||
@ -94,7 +95,7 @@ class PersonDocGenNormalizer implements
|
||||
'age' => (int) $person->getAge(),
|
||||
'birthdate' => $this->normalizer->normalize($person->getBirthdate(), $format, $dateContext),
|
||||
'deathdate' => $this->normalizer->normalize($person->getDeathdate(), $format, $dateContext),
|
||||
'gender' => $this->translator->trans($person->getGender()),
|
||||
'gender' => $this->normalizer->normalize($person->getGender(), $format, $genderContext),
|
||||
'maritalStatus' => null !== ($ms = $person->getMaritalStatus()) ? $this->translatableStringHelper->localize($ms->getName()) : '',
|
||||
'maritalStatusDate' => $this->normalizer->normalize($person->getMaritalStatusDate(), $format, $dateContext),
|
||||
'maritalStatusComment' => $this->normalizer->normalize($person->getMaritalStatusComment(), $format, $dateContext),
|
||||
|
@ -13,6 +13,7 @@ namespace Chill\PersonBundle\Serializer\Normalizer;
|
||||
|
||||
use Chill\MainBundle\Entity\Center;
|
||||
use Chill\MainBundle\Entity\Civility;
|
||||
use Chill\MainBundle\Entity\Gender;
|
||||
use Chill\MainBundle\Phonenumber\PhoneNumberHelperInterface;
|
||||
use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface;
|
||||
use Chill\MainBundle\Templating\Entity\ChillEntityRenderExtension;
|
||||
@ -112,7 +113,9 @@ class PersonJsonNormalizer implements DenormalizerAwareInterface, NormalizerAwar
|
||||
break;
|
||||
|
||||
case 'gender':
|
||||
$person->setGender($data[$item]);
|
||||
$gender = $this->denormalizer->denormalize($data[$item], Gender::class, $format, []);
|
||||
|
||||
$person->setGender($gender);
|
||||
|
||||
break;
|
||||
|
||||
@ -199,7 +202,7 @@ class PersonJsonNormalizer implements DenormalizerAwareInterface, NormalizerAwar
|
||||
'phonenumber' => $this->normalizer->normalize($person->getPhonenumber(), $format, $context),
|
||||
'mobilenumber' => $this->normalizer->normalize($person->getMobilenumber(), $format, $context),
|
||||
'email' => $person->getEmail(),
|
||||
'gender' => $person->getGender(),
|
||||
'gender' => $this->normalizer->normalize($person->getGender(), $format, $context),
|
||||
'civility' => $this->normalizer->normalize($person->getCivility(), $format, $context),
|
||||
];
|
||||
|
||||
|
@ -11,6 +11,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace Tests\Controller\AccompanyingCoursWorkApiController;
|
||||
|
||||
use Chill\MainBundle\Entity\Gender;
|
||||
use Chill\MainBundle\Entity\GenderEnum;
|
||||
use Chill\MainBundle\Entity\GenderIconEnum;
|
||||
use Chill\MainBundle\Repository\UserRepositoryInterface;
|
||||
use Chill\MainBundle\Test\PrepareClientTrait;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
@ -129,8 +132,15 @@ class ConflictTest extends WebTestCase
|
||||
|
||||
$period = new AccompanyingPeriod();
|
||||
$em->persist($period);
|
||||
|
||||
$gender = new Gender();
|
||||
$gender->setGenderTranslation(GenderEnum::MALE);
|
||||
$gender->setLabel(['fr' => 'homme']);
|
||||
$gender->setIcon(GenderIconEnum::MALE);
|
||||
$em->persist($gender);
|
||||
|
||||
$period->addPerson(($p = new Person())->setFirstName('test')->setLastName('test')
|
||||
->setBirthdate(new \DateTime('1980-01-01'))->setGender(Person::BOTH_GENDER));
|
||||
->setBirthdate(new \DateTime('1980-01-01'))->setGender($gender));
|
||||
$em->persist($p);
|
||||
$issue = (new SocialIssue())->setTitle(['fr' => 'test']);
|
||||
$em->persist($issue);
|
||||
|
@ -14,6 +14,9 @@ namespace Chill\PersonBundle\Tests\Controller;
|
||||
use Chill\MainBundle\Entity\Address;
|
||||
use Chill\MainBundle\Entity\AddressReference;
|
||||
use Chill\MainBundle\Entity\Center;
|
||||
use Chill\MainBundle\Entity\Gender;
|
||||
use Chill\MainBundle\Entity\GenderEnum;
|
||||
use Chill\MainBundle\Entity\GenderIconEnum;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Test\PrepareClientTrait;
|
||||
use Chill\PersonBundle\Entity\Household\Household;
|
||||
@ -51,9 +54,15 @@ final class HouseholdApiControllerTest extends WebTestCase
|
||||
->setMaxResults(1)
|
||||
->getQuery()->getSingleResult();
|
||||
|
||||
$gender = new Gender();
|
||||
$gender->setGenderTranslation(GenderEnum::MALE);
|
||||
$gender->setLabel(['fr' => 'homme']);
|
||||
$gender->setIcon(GenderIconEnum::MALE);
|
||||
$em->persist($gender);
|
||||
|
||||
$p = new Person();
|
||||
$p->setFirstname('test')->setLastName('test lastname')
|
||||
->setGender(Person::BOTH_GENDER)
|
||||
->setGender($gender)
|
||||
->setCenter($centerA);
|
||||
$em->persist($p);
|
||||
$h = new Household();
|
||||
|
@ -112,24 +112,24 @@ final class PersonControllerCreateTest extends WebTestCase
|
||||
|
||||
$genderType = $form->get(self::GENDER_INPUT);
|
||||
$this->assertEquals(
|
||||
'radio',
|
||||
'select',
|
||||
$genderType->getType(),
|
||||
'The gender input has radio buttons'
|
||||
'The gender input is a select form to select a gender entity'
|
||||
);
|
||||
$this->assertEquals(
|
||||
3,
|
||||
\count($genderType->availableOptionValues()),
|
||||
'The gender input has three options: man, women and undefined'
|
||||
);
|
||||
$this->assertTrue(
|
||||
\in_array('man', $genderType->availableOptionValues(), true),
|
||||
'gender has "homme" option'
|
||||
);
|
||||
$this->assertTrue(
|
||||
\in_array('woman', $genderType->availableOptionValues(), true),
|
||||
'gender has "femme" option'
|
||||
);
|
||||
$this->assertFalse($genderType->hasValue(), 'The gender input is not checked');
|
||||
/* $this->assertEquals(
|
||||
3,
|
||||
\count($genderType->availableOptionValues()),
|
||||
'The gender input has three options: man, women and undefined'
|
||||
);
|
||||
$this->assertTrue(
|
||||
\in_array('man', $genderType->availableOptionValues(), true),
|
||||
'gender has "homme" option'
|
||||
);
|
||||
$this->assertTrue(
|
||||
\in_array('woman', $genderType->availableOptionValues(), true),
|
||||
'gender has "femme" option'
|
||||
);
|
||||
$this->assertFalse($genderType->hasValue(), 'The gender input is not checked');*/
|
||||
|
||||
return $form;
|
||||
}
|
||||
@ -226,7 +226,8 @@ final class PersonControllerCreateTest extends WebTestCase
|
||||
) {
|
||||
$creationForm->get(self::FIRSTNAME_INPUT)->setValue($firstname.'_'.uniqid());
|
||||
$creationForm->get(self::LASTNAME_INPUT)->setValue($lastname.'_'.uniqid());
|
||||
$creationForm->get(self::GENDER_INPUT)->select('man');
|
||||
// Todo change hardcoded id
|
||||
$creationForm->get(self::GENDER_INPUT)->select(5);
|
||||
$date = $birthdate ?? new \DateTime('1947-02-01');
|
||||
$creationForm->get(self::BIRTHDATE_INPUT)->setValue($date->format('Y-m-d'));
|
||||
|
||||
|
@ -12,6 +12,9 @@ declare(strict_types=1);
|
||||
namespace Chill\PersonBundle\Tests\Controller;
|
||||
|
||||
use Chill\MainBundle\Entity\Center;
|
||||
use Chill\MainBundle\Entity\Gender;
|
||||
use Chill\MainBundle\Entity\GenderEnum;
|
||||
use Chill\MainBundle\Entity\GenderIconEnum;
|
||||
use Chill\MainBundle\Repository\CenterRepositoryInterface;
|
||||
use Chill\MainBundle\Test\PrepareClientTrait;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
@ -160,12 +163,18 @@ final class PersonControllerUpdateTest extends WebTestCase
|
||||
$em = self::getContainer()->get(EntityManagerInterface::class);
|
||||
$center = $centerRepository->findOneBy(['name' => 'Center A']);
|
||||
|
||||
$gender = new Gender();
|
||||
$gender->setGenderTranslation(GenderEnum::MALE);
|
||||
$gender->setLabel(['fr' => 'homme']);
|
||||
$gender->setIcon(GenderIconEnum::MALE);
|
||||
$em->persist($gender);
|
||||
|
||||
$person = new Person();
|
||||
$person
|
||||
->setFirstName('Foo')
|
||||
->setLastName('Bar')
|
||||
->setBirthdate(new \DateTime('2017-09-30'))
|
||||
->setGender(Person::MALE_GENDER)
|
||||
->setGender($gender)
|
||||
->setCenter($center);
|
||||
|
||||
$em->persist($person);
|
||||
|
@ -11,6 +11,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\PersonBundle\Tests\Controller;
|
||||
|
||||
use Chill\MainBundle\Entity\Gender;
|
||||
use Chill\MainBundle\Entity\GenderEnum;
|
||||
use Chill\MainBundle\Entity\GenderIconEnum;
|
||||
use Chill\MainBundle\Repository\CenterRepositoryInterface;
|
||||
use Chill\MainBundle\Test\PrepareClientTrait;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
@ -99,12 +102,18 @@ final class PersonControllerViewTest extends WebTestCase
|
||||
$em = self::getContainer()->get(EntityManagerInterface::class);
|
||||
$center = $centerRepository->findOneBy(['name' => 'Center A']);
|
||||
|
||||
$gender = new Gender();
|
||||
$gender->setGenderTranslation(GenderEnum::MALE);
|
||||
$gender->setLabel(['fr' => 'homme']);
|
||||
$gender->setIcon(GenderIconEnum::MALE);
|
||||
$em->persist($gender);
|
||||
|
||||
$person = new Person();
|
||||
$person
|
||||
->setFirstName('Foo')
|
||||
->setLastName('Bar')
|
||||
->setBirthdate(new \DateTime('2017-09-30'))
|
||||
->setGender(Person::MALE_GENDER)
|
||||
->setGender($gender)
|
||||
->setCenter($center);
|
||||
|
||||
$em->persist($person);
|
||||
|
@ -41,13 +41,13 @@ final class GenderFilterTest extends AbstractFilterTest
|
||||
{
|
||||
return [
|
||||
[
|
||||
'accepted_genders' => [Person::FEMALE_GENDER],
|
||||
'accepted_genders' => ['man'],
|
||||
],
|
||||
[
|
||||
'accepted_genders' => [Person::MALE_GENDER],
|
||||
'accepted_genders' => ['woman'],
|
||||
],
|
||||
[
|
||||
'accepted_genders' => [Person::MALE_GENDER, Person::BOTH_GENDER],
|
||||
'accepted_genders' => ['man', 'both'],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
@ -257,7 +257,7 @@ final class PersonDocGenNormalizerTest extends KernelTestCase
|
||||
$personDocGenNormalizer = new PersonDocGenNormalizer(
|
||||
$personRender ?? self::getContainer()->get(PersonRender::class),
|
||||
$relationshipRepository ?? self::getContainer()->get(RelationshipRepository::class),
|
||||
$translator ?? self::getContainer()->get(TranslatorInterface::class),
|
||||
// $translator ?? self::getContainer()->get(TranslatorInterface::class),
|
||||
$translatableStringHelper ?? self::getContainer()->get(TranslatableStringHelperInterface::class),
|
||||
$summaryBudget->reveal(),
|
||||
);
|
||||
@ -299,7 +299,7 @@ final class PersonDocGenNormalizerTest extends KernelTestCase
|
||||
$normalizer = new PersonDocGenNormalizer(
|
||||
$personRender ?? self::getContainer()->get(PersonRender::class),
|
||||
$relationshipRepository,
|
||||
$translator ?? self::getContainer()->get(TranslatorInterface::class),
|
||||
// $translator ?? self::getContainer()->get(TranslatorInterface::class),
|
||||
$translatableStringHelper ?? self::getContainer()->get(TranslatableStringHelperInterface::class),
|
||||
$summaryBudget->reveal()
|
||||
);
|
||||
|
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\Migrations\Person;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
final class Version20240926100337 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Add foreign key gender property to person and transfer values';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE chill_person_person ADD gender_id INT DEFAULT NULL');
|
||||
$this->addSql('ALTER TABLE chill_person_person ADD CONSTRAINT FK_BF210A14708A0E0 FOREIGN KEY (gender_id) REFERENCES chill_main_gender (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||
$this->addSql('CREATE INDEX IDX_BF210A14708A0E0 ON chill_person_person (gender_id)');
|
||||
|
||||
// transfer gender values to point to corresponding gender entity within new column
|
||||
$this->addSql("
|
||||
UPDATE chill_person_person AS p
|
||||
SET gender_id = g.id
|
||||
FROM chill_main_gender AS g
|
||||
WHERE g.genderTranslation = p.gender AND p.gender IN ('man', 'woman', 'unknown')
|
||||
OR (g.genderTranslation = 'neutral' AND p.gender = 'both')
|
||||
");
|
||||
|
||||
// delete old gender column
|
||||
$this->addSql('ALTER TABLE chill_person_person DROP gender');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE chill_person_person ADD gender VARCHAR(9) DEFAULT NULL');
|
||||
$this->addSql('ALTER TABLE chill_person_person DROP gender_id');
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ Born the date: >-
|
||||
{gender, select,
|
||||
man {Né le {birthdate}}
|
||||
woman {Née le {birthdate}}
|
||||
neutral {Né·e le {birthdate}}
|
||||
other {Né·e le {birthdate}}
|
||||
}
|
||||
|
||||
@ -9,17 +10,18 @@ Requestor: >-
|
||||
{gender, select,
|
||||
man {Demandeur}
|
||||
woman {Demandeuse}
|
||||
other {Demandeur·euse}
|
||||
neutral {Demandeur·euse}
|
||||
}
|
||||
|
||||
person:
|
||||
and_himself: >-
|
||||
from_the: depuis le
|
||||
And himself: >-
|
||||
{gender, select,
|
||||
man {et lui-même}
|
||||
woman {et elle-même}
|
||||
neutral {et lui·elle-même}
|
||||
other {et lui·elle-même}
|
||||
}
|
||||
from_the: depuis le
|
||||
|
||||
household:
|
||||
Household: Ménage
|
||||
|
@ -64,6 +64,7 @@ Female: Femme
|
||||
#Both: Neutre
|
||||
man: Homme
|
||||
woman: Femme
|
||||
neutral: Neutre
|
||||
#both: Neutre
|
||||
Man: Homme
|
||||
Woman: Femme
|
||||
@ -1192,6 +1193,8 @@ export:
|
||||
date_after: Après le
|
||||
date_before: Avant le
|
||||
title: Filtrer les usagers n'ayant été associés à aucun parcours
|
||||
gender:
|
||||
no_gender: genre non specifié
|
||||
|
||||
course:
|
||||
not_having_address_reference:
|
||||
|
Loading…
x
Reference in New Issue
Block a user