mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-11-19 02:17:45 +00:00
Compare commits
2 Commits
v4.7.0
...
fix_calend
| Author | SHA1 | Date | |
|---|---|---|---|
| 90d3bf32e6 | |||
| ebc2921696 |
6
.changes/unreleased/Feature-20250722-155039.yaml
Normal file
6
.changes/unreleased/Feature-20250722-155039.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
kind: Feature
|
||||||
|
body: Show filters on list pages unfolded by default
|
||||||
|
time: 2025-07-22T15:50:39.338057044+02:00
|
||||||
|
custom:
|
||||||
|
Issue: "399"
|
||||||
|
SchemaChange: No schema change
|
||||||
6
.changes/unreleased/Feature-20250811-152154.yaml
Normal file
6
.changes/unreleased/Feature-20250811-152154.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
kind: Feature
|
||||||
|
body: Add 45 and 60 min calendar ranges
|
||||||
|
time: 2025-08-11T15:21:54.209009751+02:00
|
||||||
|
custom:
|
||||||
|
Issue: "409"
|
||||||
|
SchemaChange: No schema change
|
||||||
6
.changes/unreleased/Fixed-20250806-134609.yaml
Normal file
6
.changes/unreleased/Fixed-20250806-134609.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
kind: Fixed
|
||||||
|
body: adjust display logic for accompanying period dates, include closing date if period is closed.
|
||||||
|
time: 2025-08-06T13:46:09.241584292+02:00
|
||||||
|
custom:
|
||||||
|
Issue: "382"
|
||||||
|
SchemaChange: No schema change
|
||||||
6
.changes/unreleased/Fixed-20250806-173527.yaml
Normal file
6
.changes/unreleased/Fixed-20250806-173527.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
kind: Fixed
|
||||||
|
body: add min and step attributes to integer field in DateIntervalType
|
||||||
|
time: 2025-08-06T17:35:27.413787704+02:00
|
||||||
|
custom:
|
||||||
|
Issue: "384"
|
||||||
|
SchemaChange: No schema change
|
||||||
6
.changes/unreleased/Fixed-20250811-155212.yaml
Normal file
6
.changes/unreleased/Fixed-20250811-155212.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
kind: Fixed
|
||||||
|
body: fix date formatting in calendar range display
|
||||||
|
time: 2025-08-11T15:52:12.949078671+02:00
|
||||||
|
custom:
|
||||||
|
Issue: ""
|
||||||
|
SchemaChange: No schema change
|
||||||
6
.changes/unreleased/UX-20250722-132637.yaml
Normal file
6
.changes/unreleased/UX-20250722-132637.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
kind: UX
|
||||||
|
body: Limit display of participations in event list
|
||||||
|
time: 2025-07-22T13:26:37.500656935+02:00
|
||||||
|
custom:
|
||||||
|
Issue: ""
|
||||||
|
SchemaChange: No schema change
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
## v4.1.0 - 2025-08-26
|
|
||||||
### Feature
|
|
||||||
* ([#400](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/400)) Add filter to social actions list to filter out actions where current user intervenes
|
|
||||||
* ([#399](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/399)) Show filters on list pages unfolded by default
|
|
||||||
* Expansion of event module with new fields in the creation form: thematic, internal/external animator, responsable, and budget elements. Filtering options in the event list + adapted exports
|
|
||||||
|
|
||||||
**Schema Change**: Add columns or tables
|
|
||||||
### Fixed
|
|
||||||
* ([#382](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/382)) adjust display logic for accompanying period dates, include closing date if period is closed.
|
|
||||||
* ([#384](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/384)) add min and step attributes to integer field in DateIntervalType
|
|
||||||
### UX
|
|
||||||
* Limit display of participations in event list
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
## v4.2.0 - 2025-09-02
|
|
||||||
### Feature
|
|
||||||
* ([#64](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/64)) Add external identifier for a Person
|
|
||||||
|
|
||||||
**Schema Change**: Add columns or tables
|
|
||||||
* ([#330](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/330) Allow users to choose for which notifications they want to receive an email
|
|
||||||
### Fixed
|
|
||||||
* ([#422](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/422)) Fixed html layout of pages for recovering password
|
|
||||||
* Fix typo in 'uncheckAll' script for centers selection
|
|
||||||
* Fix incorrect parameter name in event details link
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
## v4.2.1 - 2025-09-03
|
|
||||||
### Fixed
|
|
||||||
* Fix exports to work with DirectExportInterface
|
|
||||||
### DX
|
|
||||||
* Improve error message when a stored object cannot be written on local disk
|
|
||||||
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
## v4.3.0 - 2025-09-08
|
|
||||||
### Feature
|
|
||||||
* ([#409](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/409)) Add 45 and 60 min calendar ranges
|
|
||||||
* Add a command to generate a list of permissions
|
|
||||||
* ([#412](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/412)) Add an absence end date
|
|
||||||
|
|
||||||
**Schema Change**: Add columns or tables
|
|
||||||
### Fixed
|
|
||||||
* fix date formatting in calendar range display
|
|
||||||
* Change route URL to avoid clash with person duplicate controller method
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
## v4.4.0 - 2025-09-11
|
|
||||||
### Feature
|
|
||||||
* ([#359](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/359)) Allow the merge of two accompanying period works
|
|
||||||
* ([#369](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/369)) Duplication of a document to another accompanying period work evaluation
|
|
||||||
* ([#359](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/359)) Fusion of two accompanying period works
|
|
||||||
### Fixed
|
|
||||||
* Fix display of 'duplicate' and 'merge' buttons in CRUD templates
|
|
||||||
* Fix saving notification preferences in user's profile
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
## v4.4.1 - 2025-09-11
|
|
||||||
### Fixed
|
|
||||||
* fix translations in duplicate evaluation document modal and realign close modal button
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
## v4.4.2 - 2025-09-12
|
|
||||||
### Fixed
|
|
||||||
* Fix document generation and workflow generation do not work on accompanying period work documents
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
## v4.5.0 - 2025-10-03
|
|
||||||
### Feature
|
|
||||||
* Only allow delete of attachment on workflows that are not final
|
|
||||||
* Move up signature buttons on index workflow page for easier access
|
|
||||||
* Filter out document from attachment list if it is the same as the workflow document
|
|
||||||
* Block edition on attached document on workflow, if the workflow is finalized or sent external
|
|
||||||
* Convert workflow's attached document to pdf while sending them external
|
|
||||||
* After a signature is canceled or rejected, going to a waiting page until the post-process routines apply a workflow transition
|
|
||||||
### Fixed
|
|
||||||
* ([#426](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/426)) Increased the number of required characters when setting a new password in Chill from 9 to 14 - GDPR compliance
|
|
||||||
* Fix permissions on storedObject which are subject by a workflow
|
|
||||||
### DX
|
|
||||||
* Introduce a WaitingScreen component to display a waiting screen
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
## v4.5.1 - 2025-10-03
|
|
||||||
### Fixed
|
|
||||||
* Add missing javascript dependency
|
|
||||||
* Add exception handling for conversion of attachment on sending external, when documens are already in pdf
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
## v4.6.0 - 2025-10-15
|
|
||||||
### Feature
|
|
||||||
* ([#423](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/423)) Create environment banner that can be activated and configured depending on the image deployed
|
|
||||||
* ([#394](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/394)) Only show active workflow on the page "my tracked workflow"
|
|
||||||
### Fixed
|
|
||||||
* Fix loading of classLists in SocialIssuesAcc.vue, ensure elements are present
|
|
||||||
* Fix the rendering of list of StoredObjectVersions, where there are kept version (before converting to pdf) and intermediate versions deleted
|
|
||||||
* ([#434](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/434)) Notification: fix editing of sent notification by removing form.addressesEmails, a field that no longer exists
|
|
||||||
* Fix loading of social issues and social actions within vue component
|
|
||||||
* ([#446](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/446)) Add unique condition on stored object filename, with cleaning step on existing duplicate filenames
|
|
||||||
|
|
||||||
**Schema Change**: Drop or rename table or columns, or enforce new constraint that must be manually fixed
|
|
||||||
* [workflow] take permissions into account to delete the workflow attachment
|
|
||||||
* ([#448](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/448)) Fix the execution of daily cronjob notification, when the previous last execution storage was invalid
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
## v4.6.1 - 2025-10-27
|
|
||||||
### Fixed
|
|
||||||
* Fix export case where no 'reason' is picked within the PersonHavingActivityBetweenDateFilter.php
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
## v4.7.0 - 2025-11-10
|
|
||||||
### Feature
|
|
||||||
* ([#385](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/385)) Create invitation list in user menu
|
|
||||||
* ([#404](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/404)) Add columns for comments linked to an activity in the activity list export
|
|
||||||
### Fixed
|
|
||||||
* ([#451](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/451)) Fix: display also social actions linked to parents of the selected social issue
|
|
||||||
* ([#453](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/453)) Fix: export actions and their results in csv even when action does not have any goals attached to it.
|
|
||||||
* Fix the possibility to delete a workflow
|
|
||||||
|
|
||||||
**Schema Change**: Drop or rename table or columns, or enforce new constraint that must be manually fixed
|
|
||||||
* ([#457](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/457)) Fix the fusion of thirdparty properties that are located in another schema than public for TO_ONE relations + add extra loop for MANY_TO_MANY relations where thirdparty is the source instead of the target
|
|
||||||
* ([#428](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/428)) Fix suggestion of referrer when creating notification for accompanyingPeriodWorkDocument
|
|
||||||
### DX
|
|
||||||
* Send notifications log to dedicated channel, if it exists
|
|
||||||
|
|
||||||
### UX
|
|
||||||
* ([#425](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/425)) Change the terms 'cercle' and 'centre' to 'service', and 'territoire' respectively.
|
|
||||||
* ([#542](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/542)) Improve the ux for selecting whether user wants to be notified of the final step of a workflow or all steps
|
|
||||||
* Expand timeSpent choices for evaluation document and translate them to user locale or fallback 'fr'
|
|
||||||
* ([#455](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/455)) Change the order of display for results and objectives in the social work/action form
|
|
||||||
* Wrap text when it is too long within badges
|
|
||||||
@@ -7,6 +7,14 @@
|
|||||||
"message": "'app' is assigned a value but never used.",
|
"message": "'app' is assigned a value but never used.",
|
||||||
"hash": "f8c2979921289906e3baabae31ba101ead91504f"
|
"hash": "f8c2979921289906e3baabae31ba101ead91504f"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/index.js",
|
||||||
|
"line": 57,
|
||||||
|
"column": 23,
|
||||||
|
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||||
|
"message": "'event' is defined but never used.",
|
||||||
|
"hash": "cf0cf378f71403f62a6425f384ccbbdec433d1f2"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillCalendarBundle/Resources/public/module/Invite/answer.js",
|
"path": "src/Bundle/ChillCalendarBundle/Resources/public/module/Invite/answer.js",
|
||||||
"line": 7,
|
"line": 7,
|
||||||
@@ -119,6 +127,46 @@
|
|||||||
"message": "'payload' is defined but never used.",
|
"message": "'payload' is defined but never used.",
|
||||||
"hash": "66c545917093ba30f1d6ca10ddaa676140e749bd"
|
"hash": "66c545917093ba30f1d6ca10ddaa676140e749bd"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/App2.vue",
|
||||||
|
"line": 224,
|
||||||
|
"column": 10,
|
||||||
|
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||||
|
"message": "'reactive' is defined but never used.",
|
||||||
|
"hash": "96ed76a9828138fb125fc36c4b55e900bbfe87c2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/App2.vue",
|
||||||
|
"line": 230,
|
||||||
|
"column": 5,
|
||||||
|
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||||
|
"message": "'DropArg' is defined but never used.",
|
||||||
|
"hash": "bd405399a4091d65e8391404bfb0c4611816c8e0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/App2.vue",
|
||||||
|
"line": 251,
|
||||||
|
"column": 9,
|
||||||
|
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||||
|
"message": "'t' is assigned a value but never used.",
|
||||||
|
"hash": "bc09207a496405f7a71c178e522b89aeb1f7ebd3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/App2.vue",
|
||||||
|
"line": 356,
|
||||||
|
"column": 32,
|
||||||
|
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||||
|
"message": "'arg' is defined but never used.",
|
||||||
|
"hash": "aeae152f0669b946a1ad681dd52b0ef03393ae79"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/App2.vue",
|
||||||
|
"line": 434,
|
||||||
|
"column": 11,
|
||||||
|
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||||
|
"message": "'changedEvent' is assigned a value but never used.",
|
||||||
|
"hash": "a7a81a6bf09d00c0364e3aa8207ffad853f0547b"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/Components/EditLocation.vue",
|
"path": "src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/Components/EditLocation.vue",
|
||||||
"line": 77,
|
"line": 77,
|
||||||
@@ -351,6 +399,14 @@
|
|||||||
"message": "'error' is defined but never used.",
|
"message": "'error' is defined but never used.",
|
||||||
"hash": "e26e5e101e90d2b7ee84d6f5de8c819e52129c17"
|
"hash": "e26e5e101e90d2b7ee84d6f5de8c819e52129c17"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillDocStoreBundle/Resources/public/module/async_upload/index.ts",
|
||||||
|
"line": 29,
|
||||||
|
"column": 14,
|
||||||
|
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||||
|
"message": "'vm' is defined but never used.",
|
||||||
|
"hash": "8e7f5e89dd72c54459cf82156389b88988f97d63"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillDocStoreBundle/Resources/public/module/async_upload/uploader.js",
|
"path": "src/Bundle/ChillDocStoreBundle/Resources/public/module/async_upload/uploader.js",
|
||||||
"line": 39,
|
"line": 39,
|
||||||
@@ -559,6 +615,14 @@
|
|||||||
"message": "'ref' is defined but never used.",
|
"message": "'ref' is defined but never used.",
|
||||||
"hash": "2a27cd6d06a26e1326654c929068e3704137e24b"
|
"hash": "2a27cd6d06a26e1326654c929068e3704137e24b"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/HistoryButton/HistoryButtonList.vue",
|
||||||
|
"line": 57,
|
||||||
|
"column": 17,
|
||||||
|
"ruleId": "vue/valid-v-for",
|
||||||
|
"message": "Custom elements in iteration require 'v-bind:key' directives.",
|
||||||
|
"hash": "cce787939524e83dd135869e13738ef332d7156c"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/WopiEditButton.vue",
|
"path": "src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/WopiEditButton.vue",
|
||||||
"line": 15,
|
"line": 15,
|
||||||
@@ -919,6 +983,22 @@
|
|||||||
"message": "'_e' is defined but never used.",
|
"message": "'_e' is defined but never used.",
|
||||||
"hash": "1d6448401778e8c56554020fe5abd47851ed33f3"
|
"hash": "1d6448401778e8c56554020fe5abd47851ed33f3"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillMainBundle/Resources/public/module/wopi-link/index.js",
|
||||||
|
"line": 21,
|
||||||
|
"column": 55,
|
||||||
|
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||||
|
"message": "'e' is defined but never used.",
|
||||||
|
"hash": "eae499e4f6e9f43a9d17f9cd917cb6d3d97be25c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillMainBundle/Resources/public/page/export/download-export.js",
|
||||||
|
"line": 3,
|
||||||
|
"column": 55,
|
||||||
|
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||||
|
"message": "'e' is defined but never used.",
|
||||||
|
"hash": "088fd383e7807e484aefc9825209bc7c8942bd22"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/page/homepage_widget/index.js",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/page/homepage_widget/index.js",
|
||||||
"line": 9,
|
"line": 9,
|
||||||
@@ -1009,19 +1089,115 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue",
|
||||||
"line": 516,
|
"line": 247,
|
||||||
"column": 21,
|
"column": 5,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||||
"message": "Unexpected mutation of \"context\" prop.",
|
"message": "'postAddressToPerson' is defined but never used.",
|
||||||
"hash": "984c4203f2ac1e1bb65f9ce76ecd03b763cfaa83"
|
"hash": "8a41c437cf2b5554cbbe1704cd51f3102b3d5994"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue",
|
||||||
"line": 517,
|
"line": 248,
|
||||||
|
"column": 5,
|
||||||
|
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||||
|
"message": "'postAddressToHousehold' is defined but never used.",
|
||||||
|
"hash": "66dec84b2ece299daf21308e5e60d497ba442b27"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue",
|
||||||
|
"line": 490,
|
||||||
"column": 21,
|
"column": 21,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"context\" prop.",
|
"message": "Unexpected mutation of \"context\" prop.",
|
||||||
"hash": "c9fb019bc21bfa77d989ed596913b99dd653c594"
|
"hash": "0d3f40c47974a4371072b3b9ee04b197c830162d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue",
|
||||||
|
"line": 491,
|
||||||
|
"column": 21,
|
||||||
|
"ruleId": "vue/no-mutating-props",
|
||||||
|
"message": "Unexpected mutation of \"context\" prop.",
|
||||||
|
"hash": "8e877b7e588c30e182f7b572bdb9685360f9cf99"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue",
|
||||||
|
"line": 508,
|
||||||
|
"column": 47,
|
||||||
|
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||||
|
"message": "'reject' is defined but never used.",
|
||||||
|
"hash": "5a3e3401bc3c765d91faaf4cfde57697af1262b7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue",
|
||||||
|
"line": 525,
|
||||||
|
"column": 47,
|
||||||
|
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||||
|
"message": "'reject' is defined but never used.",
|
||||||
|
"hash": "35a741d90379574b9323279f5802193d0c98a9dc"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue",
|
||||||
|
"line": 553,
|
||||||
|
"column": 47,
|
||||||
|
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||||
|
"message": "'reject' is defined but never used.",
|
||||||
|
"hash": "c23d1ddf6c0d10ae97948e74aee9c14b9320b86c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue",
|
||||||
|
"line": 572,
|
||||||
|
"column": 47,
|
||||||
|
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||||
|
"message": "'reject' is defined but never used.",
|
||||||
|
"hash": "4322e81c6ea9d9734c680633a724d5bd4fabacb2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue",
|
||||||
|
"line": 803,
|
||||||
|
"column": 47,
|
||||||
|
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||||
|
"message": "'reject' is defined but never used.",
|
||||||
|
"hash": "7928a6461b9d394c7d97f048933553936f7d8963"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue",
|
||||||
|
"line": 852,
|
||||||
|
"column": 47,
|
||||||
|
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||||
|
"message": "'reject' is defined but never used.",
|
||||||
|
"hash": "e5afdb8efccb5470a08dde48f755b1268fa947b5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressMore.vue",
|
||||||
|
"line": 93,
|
||||||
|
"column": 17,
|
||||||
|
"ruleId": "vue/no-mutating-props",
|
||||||
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
|
"hash": "68f5e1cf5c03f9ada59c9e0afca0b74c7f3fca4b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressMore.vue",
|
||||||
|
"line": 101,
|
||||||
|
"column": 17,
|
||||||
|
"ruleId": "vue/no-mutating-props",
|
||||||
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
|
"hash": "50d730f6109092baff2db66adc44dc1315e2bda2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressMore.vue",
|
||||||
|
"line": 109,
|
||||||
|
"column": 17,
|
||||||
|
"ruleId": "vue/no-mutating-props",
|
||||||
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
|
"hash": "573e4c041ce663f28b933d7a675c2a525aba644c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressMore.vue",
|
||||||
|
"line": 117,
|
||||||
|
"column": 17,
|
||||||
|
"ruleId": "vue/no-mutating-props",
|
||||||
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
|
"hash": "293f845eeab515b1df4649d136c2d8219ed59c4d"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressMore.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressMore.vue",
|
||||||
@@ -1048,180 +1224,204 @@
|
|||||||
"hash": "2d5a5e680ff207ad97c7e7b7d999064b561dfd8a"
|
"hash": "2d5a5e680ff207ad97c7e7b7d999064b561dfd8a"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressMore.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||||
"line": 149,
|
"line": 106,
|
||||||
"column": 17,
|
"column": 17,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "e4c1ecd7ae77d46ac3625c5bbe92a24d6a964db9"
|
"hash": "d52356f2af31d0167c02330ec22d09fbfa6b2b9f"
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressMore.vue",
|
|
||||||
"line": 157,
|
|
||||||
"column": 17,
|
|
||||||
"ruleId": "vue/no-mutating-props",
|
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
|
||||||
"hash": "4dece2db87c6ce1c04ae06c088ddfe916c1c0c61"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressMore.vue",
|
|
||||||
"line": 165,
|
|
||||||
"column": 17,
|
|
||||||
"ruleId": "vue/no-mutating-props",
|
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
|
||||||
"hash": "facc7a0f17bdf19396fae3d0de3da82e60503c0d"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressMore.vue",
|
|
||||||
"line": 173,
|
|
||||||
"column": 17,
|
|
||||||
"ruleId": "vue/no-mutating-props",
|
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
|
||||||
"hash": "19de32c76518387218264d7c4dab914d143a9cca"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||||
"line": 130,
|
"line": 114,
|
||||||
"column": 17,
|
"column": 17,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "239ac02a02694d5b20ab30d4c7ce5838c51d1515"
|
"hash": "c8e8e06f370f93bf05867e93b5f037dfa46937b1"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||||
"line": 138,
|
"line": 128,
|
||||||
"column": 17,
|
|
||||||
"ruleId": "vue/no-mutating-props",
|
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
|
||||||
"hash": "a54f9bc6d1edfa4df93c7dd7d409cfef3fccf99e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
|
||||||
"line": 152,
|
|
||||||
"column": 13,
|
"column": 13,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "74a5f664d18f3916ea908897fcd0291cb0128f29"
|
"hash": "9abaf71ca4b4f292b3b01e724d0a7733365e71f1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||||
|
"line": 129,
|
||||||
|
"column": 13,
|
||||||
|
"ruleId": "vue/no-mutating-props",
|
||||||
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
|
"hash": "0b0743959778a9e3d93089b132608816ee4e6646"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||||
|
"line": 132,
|
||||||
|
"column": 13,
|
||||||
|
"ruleId": "vue/no-mutating-props",
|
||||||
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
|
"hash": "9759da7b7859b8ee8efaf74876430658ac6b6fe2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||||
|
"line": 133,
|
||||||
|
"column": 13,
|
||||||
|
"ruleId": "vue/no-mutating-props",
|
||||||
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
|
"hash": "dba8be9a27ab74ec743b7d9e07c05d857b407dd3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||||
|
"line": 134,
|
||||||
|
"column": 13,
|
||||||
|
"ruleId": "vue/no-mutating-props",
|
||||||
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
|
"hash": "9b1f5bce779aafc46b19d7a5d266eaa29f8f9be9"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||||
|
"line": 139,
|
||||||
|
"column": 13,
|
||||||
|
"ruleId": "vue/no-mutating-props",
|
||||||
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
|
"hash": "fe6fc4aea0994ba9da15b7c09d308842b67958cb"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||||
"line": 153,
|
"line": 153,
|
||||||
"column": 13,
|
"column": 55,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "'reject' is defined but never used.",
|
||||||
"hash": "740ea5d793c7a34c9f352d8b333f3aa04cc80ee8"
|
"hash": "bd0e024fcad2e3f4566f15293e3c25c840f6dd3e"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||||
"line": 156,
|
"line": 154,
|
||||||
"column": 13,
|
|
||||||
"ruleId": "vue/no-mutating-props",
|
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
|
||||||
"hash": "af8aca18f0226a5988ed90d44d95e2d607bfb5e6"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
|
||||||
"line": 157,
|
|
||||||
"column": 13,
|
|
||||||
"ruleId": "vue/no-mutating-props",
|
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
|
||||||
"hash": "7bc2453017793ae20cd6c10005f941d384b59d84"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
|
||||||
"line": 158,
|
|
||||||
"column": 13,
|
|
||||||
"ruleId": "vue/no-mutating-props",
|
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
|
||||||
"hash": "571b4ee5f22358dd165ec59696bb3439b7c9ff6c"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
|
||||||
"line": 163,
|
|
||||||
"column": 13,
|
|
||||||
"ruleId": "vue/no-mutating-props",
|
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
|
||||||
"hash": "cfcb5946c86e289fc61623a794284a5a272d02e8"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
|
||||||
"line": 178,
|
|
||||||
"column": 37,
|
"column": 37,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "0ec402e43cb08bf129e0737c0d2c4f6d0c7af8bd"
|
"hash": "596c4b180b926b7829f987384328bf5636cd367a"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||||
"line": 196,
|
"line": 171,
|
||||||
|
"column": 59,
|
||||||
|
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||||
|
"message": "'reject' is defined but never used.",
|
||||||
|
"hash": "5b41d5f9b45da074fb7bbbbd45e0da501da72071"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||||
|
"line": 172,
|
||||||
"column": 41,
|
"column": 41,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "ec178d33e067aac892e015002afb6f3a2ff98762"
|
"hash": "d92b92a25043244cca809bd129633b7e024e26b4"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||||
"line": 214,
|
"line": 190,
|
||||||
"column": 17,
|
"column": 17,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "c0f4e5454e672b6064eb9cf6c235c6810f7bfa80"
|
"hash": "dd9a85ea740742d620e864796f67c5bff834486d"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||||
"line": 215,
|
"line": 191,
|
||||||
"column": 17,
|
"column": 17,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "e3dd840d2474f9865a45822872bf9ecfb15961d7"
|
"hash": "e3e59960d0d50709a57b336f66b586710b774892"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||||
"line": 216,
|
"line": 192,
|
||||||
"column": 17,
|
"column": 17,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "a32a60382b145cc7a4a7ebe01ec435b8e3103320"
|
"hash": "fe11b0e54396511e7b3b08615a78d22fc27e2fad"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||||
"line": 246,
|
"line": 222,
|
||||||
"column": 13,
|
"column": 13,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "082447e5c731012f3acc282943502775dfd24797"
|
"hash": "63c14c2150c33ec701bc4a0ff94efde69537d490"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||||
"line": 118,
|
"line": 96,
|
||||||
"column": 20,
|
"column": 20,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "d4fba4fe09af3c0937c0dd164928c8930c1591b5"
|
"hash": "d2a9fdaeef0e2810f480022d4c6f99e4f76a818e"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||||
"line": 118,
|
"line": 96,
|
||||||
"column": 20,
|
"column": 20,
|
||||||
"ruleId": "vue/no-side-effects-in-computed-properties",
|
"ruleId": "vue/no-side-effects-in-computed-properties",
|
||||||
"message": "Unexpected side effect in \"cities\" computed property.",
|
"message": "Unexpected side effect in \"cities\" computed property.",
|
||||||
"hash": "1113a114d5aaf9f32f442916d25458541c5af35c"
|
"hash": "dd92a60a9b1ebefeb9a90941d45326fbfa483733"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||||
|
"line": 102,
|
||||||
|
"column": 17,
|
||||||
|
"ruleId": "vue/no-mutating-props",
|
||||||
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
|
"hash": "04be01ab638ce01f568fb0216929e65e1175ca23"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||||
|
"line": 110,
|
||||||
|
"column": 17,
|
||||||
|
"ruleId": "vue/no-mutating-props",
|
||||||
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
|
"hash": "8619c8e0b63e87d09268832f90e4fba06b87e41f"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||||
"line": 124,
|
"line": 124,
|
||||||
"column": 17,
|
"column": 13,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "fa56a7c93583f0a9d0c2ecac10228c4f4fc1bc3a"
|
"hash": "281f918da00635079501418b1e6b2c05b62eb4a7"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||||
"line": 132,
|
"line": 125,
|
||||||
"column": 17,
|
"column": 13,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "9fe87937ea67d1dae95fb3d44d4be0da2eba0905"
|
"hash": "c131b09fa67ab1d069f1d04a54582d6b0f206153"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||||
|
"line": 126,
|
||||||
|
"column": 13,
|
||||||
|
"ruleId": "vue/no-mutating-props",
|
||||||
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
|
"hash": "3d3a2a4add64c291b8f5f1cddd90a173cd6a819d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||||
|
"line": 131,
|
||||||
|
"column": 21,
|
||||||
|
"ruleId": "vue/no-mutating-props",
|
||||||
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
|
"hash": "ed48f4988914d7897018a2e06830a97e6740b3e8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||||
|
"line": 145,
|
||||||
|
"column": 13,
|
||||||
|
"ruleId": "vue/no-mutating-props",
|
||||||
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
|
"hash": "744f3a7610d4d6015e50e25149bceffd6c6e2763"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||||
@@ -1241,139 +1441,115 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||||
"line": 148,
|
"line": 149,
|
||||||
"column": 13,
|
"column": 17,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "ab4f478fbfbc954b8dff75176dcd432f9ff28cfc"
|
"hash": "1e7b1ad55866f708baaca72dfa4ff26d6f8e5d21"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||||
"line": 153,
|
"line": 152,
|
||||||
"column": 21,
|
|
||||||
"ruleId": "vue/no-mutating-props",
|
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
|
||||||
"hash": "1d907d149f9ddb62e32140a90efe9a74b3e71fef"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
|
||||||
"line": 167,
|
|
||||||
"column": 13,
|
"column": 13,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "8aa37d2d4f011773e68838a2c88017875de563b5"
|
"hash": "84779331536ffceec8d4a8c5ca4307310b882549"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||||
"line": 168,
|
"line": 161,
|
||||||
"column": 13,
|
"column": 13,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "a4827a357e52a51fa9262319114d81a130296acf"
|
"hash": "0789999841be671a4d8ab080d6fdb679f843eb52"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||||
"line": 169,
|
"line": 170,
|
||||||
"column": 13,
|
"column": 51,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "'reject' is defined but never used.",
|
||||||
"hash": "a4c9715664202949e3242b8d4aa4098288b46dc4"
|
"hash": "bbb17afa114f016e2058d90aa32d2a625804f0d1"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||||
"line": 171,
|
"line": 171,
|
||||||
"column": 17,
|
|
||||||
"ruleId": "vue/no-mutating-props",
|
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
|
||||||
"hash": "f3e9e21e433e90ec7b615b8940d43c4177372b66"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
|
||||||
"line": 174,
|
|
||||||
"column": 13,
|
|
||||||
"ruleId": "vue/no-mutating-props",
|
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
|
||||||
"hash": "770b7a24cc24b380e88db47d62422c8e1ece2571"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
|
||||||
"line": 183,
|
|
||||||
"column": 13,
|
|
||||||
"ruleId": "vue/no-mutating-props",
|
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
|
||||||
"hash": "2aef3c519a9ec6abcfe7573989d3de19d5c4c752"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
|
||||||
"line": 193,
|
|
||||||
"column": 33,
|
"column": 33,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "5d1f97e4d7d9f47399d312e8b9f95ef9e3843b8c"
|
"hash": "5fbe407ceceb37bff2ac800ceddd7942540132f1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||||
|
"line": 190,
|
||||||
|
"column": 55,
|
||||||
|
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||||
|
"message": "'reject' is defined but never used.",
|
||||||
|
"hash": "e2af91def877befbabef8e93deba4c58a3ee2ded"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||||
|
"line": 191,
|
||||||
|
"column": 37,
|
||||||
|
"ruleId": "vue/no-mutating-props",
|
||||||
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
|
"hash": "ee8544ee45681a650ed7d4918ae979685cdd8f0f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||||
|
"line": 210,
|
||||||
|
"column": 17,
|
||||||
|
"ruleId": "vue/no-mutating-props",
|
||||||
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
|
"hash": "5d9d2217c8c7e6571bc9f72a98ea5b370edb4968"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||||
|
"line": 211,
|
||||||
|
"column": 17,
|
||||||
|
"ruleId": "vue/no-mutating-props",
|
||||||
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
|
"hash": "6e04619b373c23c91f6c36c2aad314ac16cdb697"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||||
|
"line": 212,
|
||||||
|
"column": 17,
|
||||||
|
"ruleId": "vue/no-mutating-props",
|
||||||
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
|
"hash": "39df045639a62f64ccdb03a80e286bc3ad772587"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||||
"line": 213,
|
"line": 213,
|
||||||
"column": 37,
|
|
||||||
"ruleId": "vue/no-mutating-props",
|
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
|
||||||
"hash": "c1df874f790ef0c036bf58ae8a8db1ee173685d4"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
|
||||||
"line": 232,
|
|
||||||
"column": 17,
|
"column": 17,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "476e6588a28ac9382e8b9d2e63a8babecd23bad8"
|
"hash": "c399a43fa797a8ce61c9d96a644a39cc84a387b7"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||||
"line": 233,
|
"line": 245,
|
||||||
"column": 17,
|
|
||||||
"ruleId": "vue/no-mutating-props",
|
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
|
||||||
"hash": "6a0c82ba72d6d87217bf33a6ad8e40a4b81bc802"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
|
||||||
"line": 234,
|
|
||||||
"column": 17,
|
|
||||||
"ruleId": "vue/no-mutating-props",
|
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
|
||||||
"hash": "741d5af6c7d90041c0dc1c1df2e8699b80fca69a"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
|
||||||
"line": 235,
|
|
||||||
"column": 17,
|
|
||||||
"ruleId": "vue/no-mutating-props",
|
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
|
||||||
"hash": "c3ffd141f58d532663875cc5c7d338ed00db2a6d"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
|
||||||
"line": 267,
|
|
||||||
"column": 13,
|
"column": 13,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "2700f258396516a2fe971618fafbcdf72cdda3ab"
|
"hash": "04337a07944caaa4819cfebcf29e1a7cbfdf248b"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CountrySelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CountrySelection.vue",
|
||||||
"line": 94,
|
"line": 76,
|
||||||
"column": 13,
|
"column": 13,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "4be1b0592efa775092a91a1d744e16ce98bd216e"
|
"hash": "373a2e31f110d138c66d77f1faf5dc61545c55af"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CountrySelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CountrySelection.vue",
|
||||||
"line": 99,
|
"line": 81,
|
||||||
"column": 13,
|
"column": 13,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "19b54b6d76c30249d520a296f826eda9d6eb0668"
|
"hash": "421eb6a63224b4b1d81b216677a710c5c99ddee3"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/DatePane.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/DatePane.vue",
|
||||||
@@ -1393,19 +1569,19 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/EditPane.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/EditPane.vue",
|
||||||
"line": 169,
|
"line": 155,
|
||||||
"column": 17,
|
"column": 17,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "dcb7b34098062760ddbb849655a5bb3ca65c36d3"
|
"hash": "b3a822914fcb5e2fcf28efc331a45b9205002eeb"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/EditPane.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/EditPane.vue",
|
||||||
"line": 178,
|
"line": 164,
|
||||||
"column": 17,
|
"column": 17,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "86b3ecf201025cac36878c5e4bf8850fb9d58cb5"
|
"hash": "72c7d850f6cdeaf65b373a33234222f9766ee30b"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/index.js",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/index.js",
|
||||||
@@ -1455,6 +1631,14 @@
|
|||||||
"message": "'app' is assigned a value but never used.",
|
"message": "'app' is assigned a value but never used.",
|
||||||
"hash": "9e6125f4fc387dc362c69cc6e3ce360eb2851f1b"
|
"hash": "9e6125f4fc387dc362c69cc6e3ce360eb2851f1b"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/PickEntity/PickEntity.vue",
|
||||||
|
"line": 60,
|
||||||
|
"column": 22,
|
||||||
|
"ruleId": "vue/require-valid-default-prop",
|
||||||
|
"message": "Type of the default value for 'suggested' prop must be a function.",
|
||||||
|
"hash": "d30212820bc2e97fa02d75dbc3a014558693f169"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/Parts/AddressDetailsMap.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/Parts/AddressDetailsMap.vue",
|
||||||
"line": 24,
|
"line": 24,
|
||||||
@@ -1543,6 +1727,14 @@
|
|||||||
"message": "'tags' is assigned a value but never used.",
|
"message": "'tags' is assigned a value but never used.",
|
||||||
"hash": "ae9bb2e0651c118ed9efd227e88b86cc83f5d80d"
|
"hash": "ae9bb2e0651c118ed9efd227e88b86cc83f5d80d"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/StickyNav.vue",
|
||||||
|
"line": 116,
|
||||||
|
"column": 18,
|
||||||
|
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||||
|
"message": "'event' is defined but never used.",
|
||||||
|
"hash": "201f182769c6dfb87148b841e7d9b592be429669"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/index.js",
|
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/index.js",
|
||||||
"line": 19,
|
"line": 19,
|
||||||
@@ -1575,6 +1767,14 @@
|
|||||||
"message": "'app' is assigned a value but never used.",
|
"message": "'app' is assigned a value but never used.",
|
||||||
"hash": "aaaaa63e7a60443b8cbf8191feb9142852ebdf1c"
|
"hash": "aaaaa63e7a60443b8cbf8191feb9142852ebdf1c"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue",
|
||||||
|
"line": 79,
|
||||||
|
"column": 13,
|
||||||
|
"ruleId": "vue/require-v-for-key",
|
||||||
|
"message": "Elements in iteration expect to have 'v-bind:key' directives.",
|
||||||
|
"hash": "422f53925922e59655d0f71624c19af75d41628c"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/index.js",
|
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/index.js",
|
||||||
"line": 12,
|
"line": 12,
|
||||||
@@ -1615,6 +1815,22 @@
|
|||||||
"message": "'evalFQDN' is assigned a value but never used.",
|
"message": "'evalFQDN' is assigned a value but never used.",
|
||||||
"hash": "7fc32caafa23addddf44f3acbc5045b4523a0271"
|
"hash": "7fc32caafa23addddf44f3acbc5045b4523a0271"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/store.js",
|
||||||
|
"line": 611,
|
||||||
|
"column": 9,
|
||||||
|
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||||
|
"message": "'errors' is assigned a value but never used.",
|
||||||
|
"hash": "c41cf979fc1626c38328dbf1028800c3395496bd"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/ExportFormActionGoalResult/App.vue",
|
||||||
|
"line": 282,
|
||||||
|
"column": 7,
|
||||||
|
"ruleId": "@typescript-eslint/no-unused-expressions",
|
||||||
|
"message": "Expected an assignment or function call and instead saw an expression.",
|
||||||
|
"hash": "de3a6e2bb10a80a2bacba665be74266c7efc7d64"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/ExportFormActionGoalResult/index.js",
|
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/ExportFormActionGoalResult/index.js",
|
||||||
"line": 16,
|
"line": 16,
|
||||||
@@ -1631,6 +1847,38 @@
|
|||||||
"message": "'app' is assigned a value but never used.",
|
"message": "'app' is assigned a value but never used.",
|
||||||
"hash": "2f161e663689e3e4dfe2c53b0d64c91a4d2b1a60"
|
"hash": "2f161e663689e3e4dfe2c53b0d64c91a4d2b1a60"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/App.vue",
|
||||||
|
"line": 263,
|
||||||
|
"column": 19,
|
||||||
|
"ruleId": "vue/return-in-computed-property",
|
||||||
|
"message": "Expected to return a value in \"refreshNetwork\" computed property.",
|
||||||
|
"hash": "2c1b08a49098c83b09058cedc0a962126e91e544"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/App.vue",
|
||||||
|
"line": 270,
|
||||||
|
"column": 7,
|
||||||
|
"ruleId": "vue/no-side-effects-in-computed-properties",
|
||||||
|
"message": "Unexpected side effect in \"legendLayers\" computed property.",
|
||||||
|
"hash": "760948d2187c853f17ac9a1bd7107e883092d4f4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/App.vue",
|
||||||
|
"line": 281,
|
||||||
|
"column": 5,
|
||||||
|
"ruleId": "vue/no-dupe-keys",
|
||||||
|
"message": "Duplicate key 'checkedLayers'. May cause name collision in script or template tag.",
|
||||||
|
"hash": "447edb461e15e3ff5c60c8ecba88131e442539aa"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/App.vue",
|
||||||
|
"line": 353,
|
||||||
|
"column": 7,
|
||||||
|
"ruleId": "@typescript-eslint/no-unused-expressions",
|
||||||
|
"message": "Expected an assignment or function call and instead saw an expression.",
|
||||||
|
"hash": "9cf656cbf1eb3d7cc0082e63adcd320b6093d14f"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/index.js",
|
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/index.js",
|
||||||
"line": 20,
|
"line": 20,
|
||||||
@@ -1639,6 +1887,22 @@
|
|||||||
"message": "'app' is assigned a value but never used.",
|
"message": "'app' is assigned a value but never used.",
|
||||||
"hash": "9e94e6412b8a44e47bfe8e66218cad09cff5bed4"
|
"hash": "9e94e6412b8a44e47bfe8e66218cad09cff5bed4"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/AccompanyingPeriod/SetReferrer.vue",
|
||||||
|
"line": 42,
|
||||||
|
"column": 16,
|
||||||
|
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||||
|
"message": "'response' is defined but never used.",
|
||||||
|
"hash": "62de07b13c662e32332bb062038acee23978ea70"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/AddPersons.vue",
|
||||||
|
"line": 356,
|
||||||
|
"column": 28,
|
||||||
|
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||||
|
"message": "'_response' is defined but never used.",
|
||||||
|
"hash": "097e7788a2b5dea500b80b8a3cf968e57063a66a"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/AddPersons/TypeUserGroup.vue",
|
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/AddPersons/TypeUserGroup.vue",
|
||||||
"line": 6,
|
"line": 6,
|
||||||
@@ -1654,5 +1918,45 @@
|
|||||||
"ruleId": "@typescript-eslint/no-unused-vars",
|
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||||
"message": "'UserRenderBoxBadge' is defined but never used.",
|
"message": "'UserRenderBoxBadge' is defined but never used.",
|
||||||
"hash": "99eba0d8633b2c9497417f4f61ec4194dbb2a96b"
|
"hash": "99eba0d8633b2c9497417f4f61ec4194dbb2a96b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillWopiBundle/src/Resources/public/module/pending/index.ts",
|
||||||
|
"line": 4,
|
||||||
|
"column": 3,
|
||||||
|
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||||
|
"message": "'StoredObjectStatus' is defined but never used.",
|
||||||
|
"hash": "63f8c4572293916850d6165647774b27d4b732c6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillWopiBundle/src/Resources/public/module/pending/index.ts",
|
||||||
|
"line": 5,
|
||||||
|
"column": 3,
|
||||||
|
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||||
|
"message": "'StoredObjectStatusChange' is defined but never used.",
|
||||||
|
"hash": "a87c178e3eb5999bf0f46b3fa1c6da77e1be08b9"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillWopiBundle/src/Resources/public/module/pending/index.ts",
|
||||||
|
"line": 30,
|
||||||
|
"column": 61,
|
||||||
|
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||||
|
"message": "'e' is defined but never used.",
|
||||||
|
"hash": "02953121583f4f73742a19adab099ab63df9076e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillWopiBundle/src/Resources/public/module/pending/index.ts",
|
||||||
|
"line": 31,
|
||||||
|
"column": 32,
|
||||||
|
"ruleId": "@typescript-eslint/no-explicit-any",
|
||||||
|
"message": "Unexpected any. Specify a different type.",
|
||||||
|
"hash": "af48e21a1651b6017ede882dab249c00a818a44d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "src/Bundle/ChillWopiBundle/src/Resources/public/module/pending/index.ts",
|
||||||
|
"line": 37,
|
||||||
|
"column": 16,
|
||||||
|
"ruleId": "@typescript-eslint/no-explicit-any",
|
||||||
|
"message": "Unexpected any. Specify a different type.",
|
||||||
|
"hash": "7513ea552a0a649ce4ab93b6cf9d40bfef4f68d9"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -18,9 +18,6 @@ migrations/*
|
|||||||
templates/*
|
templates/*
|
||||||
translations/*
|
translations/*
|
||||||
|
|
||||||
# we allow developers to add customization on their installation, without commiting it
|
|
||||||
config/packages/dev/*
|
|
||||||
|
|
||||||
###> symfony/framework-bundle ###
|
###> symfony/framework-bundle ###
|
||||||
/.env.local
|
/.env.local
|
||||||
/.env.local.php
|
/.env.local.php
|
||||||
|
|||||||
@@ -27,11 +27,11 @@ Chill is a comprehensive web application built as a set of Symfony bundles. It i
|
|||||||
|
|
||||||
## Project Structure
|
## Project Structure
|
||||||
|
|
||||||
Note: This is a project that's existed for a long time, and throughout the years we've used multiple structures inside each bundle. When having the choice, the developers should choose the new structure.
|
Note: This is a project which exists from a long time ago, and we found multiple structure inside each bundle. When having the choice, the developers should choose the new structure.
|
||||||
|
|
||||||
The project follows a standard Symfony bundle structure:
|
The project follows a standard Symfony bundle structure:
|
||||||
- `/src/Bundle/`: Contains all the Chill bundles. The code is either at the root of the bundle directory, or within a `src/` directory (preferred). See psr4 mapping at the root's `composer.json`.
|
- `/src/Bundle/`: Contains all the Chill bundles. The code is either at the root of the bundle directory, or within a `src/` directory (preferred). See psr4 mapping at the root's `composer.json`.
|
||||||
- each bundle comes with its own tests, either in the `Tests` directory (when the code is directly within the bundle directory (for instance `src/Bundle/ChillMainBundle/Tests`, `src/Bundle/ChillPersonBundle/Tests`)), or inside the `tests` directory, alongside the `src/` sub-directory (example: `src/Bundle/ChillWopiBundle/tests`) (this is the preferred way).
|
- each bundle come with his own tests, either in the `Tests` directory (when the code is directly within the bundle directory (for instance `src/Bundle/ChillMainBundle/Tests`, `src/Bundle/ChillPersonBundle/Tests`)), or inside the `tests` directory, alongside to the `src/` sub-directory (example: `src/Bundle/ChillWopiBundle/tests`) (this is the preferred way).
|
||||||
- `/docs/`: Contains project documentation
|
- `/docs/`: Contains project documentation
|
||||||
|
|
||||||
Each bundle typically has the following structure:
|
Each bundle typically has the following structure:
|
||||||
@@ -46,13 +46,13 @@ Each bundle typically has the following structure:
|
|||||||
|
|
||||||
### A special word about TicketBundle
|
### A special word about TicketBundle
|
||||||
|
|
||||||
The ticket bundle is developed using a kind of "Command" pattern. The controller fills a "Command," and a "CommandHandler" handles this command. They are saved in the `src/Bundle/ChillTicketBundle/src/Action` directory.
|
The ticket bundle is developed using a kind of "Command" pattern. The controller fill a "Command", and a "CommandHandler" handle this command. They are savec in the `src/Bundle/ChillTicketBundle/src/Action` directory.
|
||||||
|
|
||||||
## Development Guidelines
|
## Development Guidelines
|
||||||
|
|
||||||
### Building and Configuration Instructions
|
### Building and Configuration Instructions
|
||||||
|
|
||||||
All the commands should be run through the `symfony` command, which will configure the required variables.
|
All the command should be run through the `symfony` command, which will configure the required variables.
|
||||||
|
|
||||||
For assets, we must ensure that we use node at version `^20.0.0`. This is done using `nvm use 20`.
|
For assets, we must ensure that we use node at version `^20.0.0`. This is done using `nvm use 20`.
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ For assets, we must ensure that we use node at version `^20.0.0`. This is done u
|
|||||||
docker compose up -d
|
docker compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
6. **Set Up the Database**:
|
5. **Set Up the Database**:
|
||||||
```bash
|
```bash
|
||||||
# Create the database
|
# Create the database
|
||||||
symfony console doctrine:database:create
|
symfony console doctrine:database:create
|
||||||
@@ -99,20 +99,20 @@ For assets, we must ensure that we use node at version `^20.0.0`. This is done u
|
|||||||
symfony console doctrine:fixtures:load
|
symfony console doctrine:fixtures:load
|
||||||
```
|
```
|
||||||
|
|
||||||
7. **Build Assets**:
|
6. **Build Assets**:
|
||||||
```bash
|
```bash
|
||||||
nvm use 20
|
nvm use 20
|
||||||
yarn run encore dev
|
yarn run encore dev
|
||||||
```
|
```
|
||||||
|
|
||||||
8. **Start the Development Server**:
|
7. **Start the Development Server**:
|
||||||
```bash
|
```bash
|
||||||
symfony server:start -d
|
symfony server:start -d
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Docker Setup
|
#### Docker Setup
|
||||||
|
|
||||||
The project includes a Docker configuration for easier development:
|
The project includes Docker configuration for easier development:
|
||||||
|
|
||||||
1. **Start Docker Services**:
|
1. **Start Docker Services**:
|
||||||
```bash
|
```bash
|
||||||
@@ -153,9 +153,9 @@ Key configuration files:
|
|||||||
|
|
||||||
Each time a doctrine entity is created, we generate migration to adapt the database.
|
Each time a doctrine entity is created, we generate migration to adapt the database.
|
||||||
|
|
||||||
The migration is created using the command `symfony console doctrine:migrations:diff --no-interaction --namespace <namespace>`, where the namespace is the relevant namespace for migration. As this is a bash script, remember to quote the `\` (`\` must become `\\` in your command).
|
The migration are created using the command `symfony console doctrine:migrations:diff --no-interaction --namespace <namespace>`, where the namespace is the relevant namespace for migration. As this is a bash script, do not forget to quote the `\` (`\` must become `\\` in your command).
|
||||||
|
|
||||||
Each bundle has his own namespace for migration (always ask me to confirm that command with a list of updated / created entities so that I can confirm to you that it is ok):
|
Each bundle has his own namespace for migration (always ask me to confirm that command, with a list of updated / created entities so that I can confirm you that it is ok):
|
||||||
|
|
||||||
- `Chill\Bundle\ActivityBundle` writes migrations to `Chill\Migrations\Activity`;
|
- `Chill\Bundle\ActivityBundle` writes migrations to `Chill\Migrations\Activity`;
|
||||||
- `Chill\Bundle\BudgetBundle` writes migrations to `Chill\Migrations\Budget`;
|
- `Chill\Bundle\BudgetBundle` writes migrations to `Chill\Migrations\Budget`;
|
||||||
@@ -183,7 +183,7 @@ Once created the, comment's classes should be removed and a description of the c
|
|||||||
|
|
||||||
When we need to use a DateTime or DateTimeImmutable that need to express "now", we prefer the usage of
|
When we need to use a DateTime or DateTimeImmutable that need to express "now", we prefer the usage of
|
||||||
`Symfony\Component\Clock\ClockInterface`, where possible. This is usually not possible in doctrine entities,
|
`Symfony\Component\Clock\ClockInterface`, where possible. This is usually not possible in doctrine entities,
|
||||||
where injection does not work when restoring an entity from a database, but usually possible in services.
|
where injection does not work when restoring an entity from database, but usually possible in services.
|
||||||
|
|
||||||
In test, we use `\Symfony\Component\Clock\MockClock` which is an implementation of `Symfony\Component\Clock\ClockInterface`
|
In test, we use `\Symfony\Component\Clock\MockClock` which is an implementation of `Symfony\Component\Clock\ClockInterface`
|
||||||
where we have full and easy control of the date.
|
where we have full and easy control of the date.
|
||||||
@@ -198,9 +198,9 @@ The project uses PHPUnit for testing. Each bundle has its own test suite, and th
|
|||||||
|
|
||||||
For creating mock, we prefer using prophecy (library phpspec/prophecy).
|
For creating mock, we prefer using prophecy (library phpspec/prophecy).
|
||||||
|
|
||||||
##### Useful helpers and tips that avoid creating a mock
|
##### Useful helpers and tips that avoid create a mock
|
||||||
|
|
||||||
Some notable implementations that are test helpers and avoid creating a mock:
|
Some notable implementations that are tests helper, and avoid to create a mock:
|
||||||
|
|
||||||
- `\Psr\Log\NullLogger`, an implementation of `\Psr\Log\LoggerInterface`;
|
- `\Psr\Log\NullLogger`, an implementation of `\Psr\Log\LoggerInterface`;
|
||||||
- `\Symfony\Component\Clock\MockClock`, an implementation of `Symfony\Component\Clock\ClockInterface` (already mentioned above);
|
- `\Symfony\Component\Clock\MockClock`, an implementation of `Symfony\Component\Clock\ClockInterface` (already mentioned above);
|
||||||
@@ -240,6 +240,9 @@ The tests are run from the project's root (not from the bundle's root).
|
|||||||
# Run all tests
|
# Run all tests
|
||||||
vendor/bin/phpunit
|
vendor/bin/phpunit
|
||||||
|
|
||||||
|
# Run tests for a specific bundle
|
||||||
|
vendor/bin/phpunit --testsuite NameBundle
|
||||||
|
|
||||||
# Run a specific test file
|
# Run a specific test file
|
||||||
vendor/bin/phpunit path/to/TestFile.php
|
vendor/bin/phpunit path/to/TestFile.php
|
||||||
|
|
||||||
@@ -247,9 +250,6 @@ vendor/bin/phpunit path/to/TestFile.php
|
|||||||
vendor/bin/phpunit --filter methodName path/to/TestFile.php
|
vendor/bin/phpunit --filter methodName path/to/TestFile.php
|
||||||
```
|
```
|
||||||
|
|
||||||
When writing tests, only test specific files. Do not run all tests or the full
|
|
||||||
test suite.
|
|
||||||
|
|
||||||
#### Test Structure
|
#### Test Structure
|
||||||
|
|
||||||
Tests are organized by bundle and follow the same structure as the bundle itself:
|
Tests are organized by bundle and follow the same structure as the bundle itself:
|
||||||
@@ -297,7 +297,7 @@ class TicketTest extends TestCase
|
|||||||
|
|
||||||
#### Test Database
|
#### Test Database
|
||||||
|
|
||||||
For tests that require a database, the project uses a postgresql database filled with fixtures (usage of doctrine-fixtures). You can configure a different database for testing in the `.env.test` file.
|
For tests that require a database, the project uses postgresql database filled by fixtures (usage of doctrine-fixtures). You can configure a different database for testing in the `.env.test` file.
|
||||||
|
|
||||||
### Code Quality Tools
|
### Code Quality Tools
|
||||||
|
|
||||||
|
|||||||
119
CHANGELOG.md
119
CHANGELOG.md
@@ -6,125 +6,6 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html),
|
|||||||
and is generated by [Changie](https://github.com/miniscruff/changie).
|
and is generated by [Changie](https://github.com/miniscruff/changie).
|
||||||
|
|
||||||
|
|
||||||
## v4.7.0 - 2025-11-10
|
|
||||||
### Feature
|
|
||||||
* ([#385](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/385)) Create invitation list in user menu
|
|
||||||
* ([#404](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/404)) Add columns for comments linked to an activity in the activity list export
|
|
||||||
### Fixed
|
|
||||||
* ([#451](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/451)) Fix: display also social actions linked to parents of the selected social issue
|
|
||||||
* ([#453](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/453)) Fix: export actions and their results in csv even when action does not have any goals attached to it.
|
|
||||||
* Fix the possibility to delete a workflow
|
|
||||||
|
|
||||||
**Schema Change**: Drop or rename table or columns, or enforce new constraint that must be manually fixed
|
|
||||||
* ([#457](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/457)) Fix the fusion of thirdparty properties that are located in another schema than public for TO_ONE relations + add extra loop for MANY_TO_MANY relations where thirdparty is the source instead of the target
|
|
||||||
* ([#428](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/428)) Fix suggestion of referrer when creating notification for accompanyingPeriodWorkDocument
|
|
||||||
### DX
|
|
||||||
* Send notifications log to dedicated channel, if it exists
|
|
||||||
|
|
||||||
### UX
|
|
||||||
* ([#425](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/425)) Change the terms 'cercle' and 'centre' to 'service', and 'territoire' respectively.
|
|
||||||
* ([#542](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/542)) Improve the ux for selecting whether user wants to be notified of the final step of a workflow or all steps
|
|
||||||
* Expand timeSpent choices for evaluation document and translate them to user locale or fallback 'fr'
|
|
||||||
* ([#455](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/455)) Change the order of display for results and objectives in the social work/action form
|
|
||||||
* Wrap text when it is too long within badges
|
|
||||||
|
|
||||||
## v4.6.1 - 2025-10-27
|
|
||||||
### Fixed
|
|
||||||
* Fix export case where no 'reason' is picked within the PersonHavingActivityBetweenDateFilter.php
|
|
||||||
|
|
||||||
## v4.6.0 - 2025-10-15
|
|
||||||
### Feature
|
|
||||||
* ([#423](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/423)) Create environment banner that can be activated and configured depending on the image deployed
|
|
||||||
* ([#394](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/394)) Only show active workflow on the page "my tracked workflow"
|
|
||||||
### Fixed
|
|
||||||
* Fix loading of classLists in SocialIssuesAcc.vue, ensure elements are present
|
|
||||||
* Fix the rendering of list of StoredObjectVersions, where there are kept version (before converting to pdf) and intermediate versions deleted
|
|
||||||
* ([#434](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/434)) Notification: fix editing of sent notification by removing form.addressesEmails, a field that no longer exists
|
|
||||||
* Fix loading of social issues and social actions within vue component
|
|
||||||
* ([#446](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/446)) Add unique condition on stored object filename, with cleaning step on existing duplicate filenames
|
|
||||||
|
|
||||||
**Schema Change**: Drop or rename table or columns, or enforce new constraint that must be manually fixed
|
|
||||||
* [workflow] take permissions into account to delete the workflow attachment
|
|
||||||
* ([#448](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/448)) Fix the execution of daily cronjob notification, when the previous last execution storage was invalid
|
|
||||||
|
|
||||||
## v4.5.1 - 2025-10-03
|
|
||||||
### Fixed
|
|
||||||
* Add missing javascript dependency
|
|
||||||
* Add exception handling for conversion of attachment on sending external, when documens are already in pdf
|
|
||||||
|
|
||||||
## v4.5.0 - 2025-10-03
|
|
||||||
### Feature
|
|
||||||
* Only allow delete of attachment on workflows that are not final
|
|
||||||
* Move up signature buttons on index workflow page for easier access
|
|
||||||
* Filter out document from attachment list if it is the same as the workflow document
|
|
||||||
* Block edition on attached document on workflow, if the workflow is finalized or sent external
|
|
||||||
* Convert workflow's attached document to pdf while sending them external
|
|
||||||
* After a signature is canceled or rejected, going to a waiting page until the post-process routines apply a workflow transition
|
|
||||||
### Fixed
|
|
||||||
* ([#426](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/426)) Increased the number of required characters when setting a new password in Chill from 9 to 14 - GDPR compliance
|
|
||||||
* Fix permissions on storedObject which are subject by a workflow
|
|
||||||
### DX
|
|
||||||
* Introduce a WaitingScreen component to display a waiting screen
|
|
||||||
|
|
||||||
## v4.4.2 - 2025-09-12
|
|
||||||
### Fixed
|
|
||||||
* Fix document generation and workflow generation do not work on accompanying period work documents
|
|
||||||
|
|
||||||
## v4.4.1 - 2025-09-11
|
|
||||||
### Fixed
|
|
||||||
* fix translations in duplicate evaluation document modal and realign close modal button
|
|
||||||
|
|
||||||
## v4.4.0 - 2025-09-11
|
|
||||||
### Feature
|
|
||||||
* ([#359](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/359)) Allow the merge of two accompanying period works
|
|
||||||
* ([#369](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/369)) Duplication of a document to another accompanying period work evaluation
|
|
||||||
* ([#359](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/359)) Fusion of two accompanying period works
|
|
||||||
### Fixed
|
|
||||||
* Fix display of 'duplicate' and 'merge' buttons in CRUD templates
|
|
||||||
* Fix saving notification preferences in user's profile
|
|
||||||
|
|
||||||
## v4.3.0 - 2025-09-08
|
|
||||||
### Feature
|
|
||||||
* ([#409](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/409)) Add 45 and 60 min calendar ranges
|
|
||||||
* Add a command to generate a list of permissions
|
|
||||||
* ([#412](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/412)) Add an absence end date
|
|
||||||
|
|
||||||
**Schema Change**: Add columns or tables
|
|
||||||
### Fixed
|
|
||||||
* fix date formatting in calendar range display
|
|
||||||
* Change route URL to avoid clash with person duplicate controller method
|
|
||||||
|
|
||||||
## v4.2.1 - 2025-09-03
|
|
||||||
### Fixed
|
|
||||||
* Fix exports to work with DirectExportInterface
|
|
||||||
### DX
|
|
||||||
* Improve error message when a stored object cannot be written on local disk
|
|
||||||
|
|
||||||
|
|
||||||
## v4.2.0 - 2025-09-02
|
|
||||||
### Feature
|
|
||||||
* ([#64](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/64)) Add external identifier for a Person
|
|
||||||
|
|
||||||
**Schema Change**: Add columns or tables
|
|
||||||
* ([#330](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/330) Allow users to choose for which notifications they want to receive an email
|
|
||||||
### Fixed
|
|
||||||
* ([#422](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/422)) Fixed html layout of pages for recovering password
|
|
||||||
* Fix typo in 'uncheckAll' script for centers selection
|
|
||||||
* Fix incorrect parameter name in event details link
|
|
||||||
|
|
||||||
## v4.1.0 - 2025-08-26
|
|
||||||
### Feature
|
|
||||||
* ([#400](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/400)) Add filter to social actions list to filter out actions where current user intervenes
|
|
||||||
* ([#399](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/399)) Show filters on list pages unfolded by default
|
|
||||||
* Expansion of event module with new fields in the creation form: thematic, internal/external animator, responsable, and budget elements. Filtering options in the event list + adapted exports
|
|
||||||
|
|
||||||
**Schema Change**: Add columns or tables
|
|
||||||
### Fixed
|
|
||||||
* ([#382](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/382)) adjust display logic for accompanying period dates, include closing date if period is closed.
|
|
||||||
* ([#384](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/384)) add min and step attributes to integer field in DateIntervalType
|
|
||||||
### UX
|
|
||||||
* Limit display of participations in event list
|
|
||||||
|
|
||||||
## v4.0.2 - 2025-07-09
|
## v4.0.2 - 2025-07-09
|
||||||
### Fixed
|
### Fixed
|
||||||
* Fix add missing translation
|
* Fix add missing translation
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
"ext-openssl": "*",
|
"ext-openssl": "*",
|
||||||
"ext-redis": "*",
|
"ext-redis": "*",
|
||||||
"ext-zlib": "*",
|
"ext-zlib": "*",
|
||||||
"champs-libres/wopi-bundle": "dev-symfony-v5@dev",
|
"champs-libres/wopi-bundle": "dev-master@dev",
|
||||||
"champs-libres/wopi-lib": "dev-master@dev",
|
"champs-libres/wopi-lib": "dev-master@dev",
|
||||||
"doctrine/data-fixtures": "^1.8",
|
"doctrine/data-fixtures": "^1.8",
|
||||||
"doctrine/doctrine-bundle": "^2.1",
|
"doctrine/doctrine-bundle": "^2.1",
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
|
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
|
||||||
|
loophp\PsrHttpMessageBridgeBundle\PsrHttpMessageBridgeBundle::class => ['all' => true],
|
||||||
ChampsLibres\WopiBundle\WopiBundle::class => ['all' => true],
|
ChampsLibres\WopiBundle\WopiBundle::class => ['all' => true],
|
||||||
Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true],
|
Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true],
|
||||||
Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['dev' => true, 'test' => true],
|
Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['dev' => true, 'test' => true],
|
||||||
@@ -36,5 +37,4 @@ return [
|
|||||||
Chill\WopiBundle\ChillWopiBundle::class => ['all' => true],
|
Chill\WopiBundle\ChillWopiBundle::class => ['all' => true],
|
||||||
Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
|
Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
|
||||||
Symfony\UX\Translator\UxTranslatorBundle::class => ['all' => true],
|
Symfony\UX\Translator\UxTranslatorBundle::class => ['all' => true],
|
||||||
loophp\PsrHttpMessageBridgeBundle\PsrHttpMessageBridgeBundle::class => ['all' => true],
|
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,13 +1,6 @@
|
|||||||
chill_main:
|
chill_main:
|
||||||
available_languages: [ '%env(resolve:LOCALE)%', 'en' ]
|
available_languages: [ '%env(resolve:LOCALE)%', 'en' ]
|
||||||
available_countries: ['BE', 'FR']
|
available_countries: ['BE', 'FR']
|
||||||
top_banner:
|
|
||||||
visible: false
|
|
||||||
text:
|
|
||||||
fr: 'Vous travaillez actuellement avec la version de PRÉ-PRODUCTION.'
|
|
||||||
nl: 'Je werkt momenteel in de PRE-PRODUCTIE versie'
|
|
||||||
color: '#353535'
|
|
||||||
background_color: '#d8bb48'
|
|
||||||
notifications:
|
notifications:
|
||||||
from_email: '%env(resolve:NOTIFICATION_FROM_EMAIL)%'
|
from_email: '%env(resolve:NOTIFICATION_FROM_EMAIL)%'
|
||||||
from_name: '%env(resolve:NOTIFICATION_FROM_NAME)%'
|
from_name: '%env(resolve:NOTIFICATION_FROM_NAME)%'
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
chill_aside_activity:
|
|
||||||
show_concerned_persons_count: hidden
|
|
||||||
@@ -23,8 +23,8 @@ class "Document" {
|
|||||||
- text description
|
- text description
|
||||||
- ArrayCollection_DocumentCategory categories
|
- ArrayCollection_DocumentCategory categories
|
||||||
- varchar_150 content #link to openstack
|
- varchar_150 content #link to openstack
|
||||||
- Territoire territoire
|
- Center center
|
||||||
- Service service
|
- Cercle cercle
|
||||||
- User user
|
- User user
|
||||||
- DateTime date # Creation date
|
- DateTime date # Creation date
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ Certaines données sont historisées:
|
|||||||
|
|
||||||
- les référents d'un parcours;
|
- les référents d'un parcours;
|
||||||
- les statuts d'un parcours;
|
- les statuts d'un parcours;
|
||||||
- la liaison entre les territoires et les usagers;
|
- la liaison entre les centres et les usagers;
|
||||||
- etc.
|
- etc.
|
||||||
|
|
||||||
Dans ces cas-là, Chill crée généralement deux colonnes, qui sont habituellement nommées :code:`startDate` et :code:`endDate`. Lorsque la colonne :code:`endDate` est à :code:`NULL`, cela signifie que la période n'est pas "fermée". La colonne :code:`startDate` n'est pas nullable.
|
Dans ces cas-là, Chill crée généralement deux colonnes, qui sont habituellement nommées :code:`startDate` et :code:`endDate`. Lorsque la colonne :code:`endDate` est à :code:`NULL`, cela signifie que la période n'est pas "fermée". La colonne :code:`startDate` n'est pas nullable.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
order,table_schema,table_name,commentaire
|
order,table_schema,table_name,commentaire
|
||||||
1,chill_3party,party_category,Catégorie de tiers
|
1,chill_3party,party_category,Catégorie de tiers
|
||||||
2,chill_3party,party_center,Association entre les tiers et les territoires (déprécié)
|
2,chill_3party,party_center,Association entre les tiers et les centres (déprécié)
|
||||||
3,chill_3party,party_profession,Profession du tiers (déprécié)
|
3,chill_3party,party_profession,Profession du tiers (déprécié)
|
||||||
4,chill_3party,third_party,Tiers
|
4,chill_3party,third_party,Tiers
|
||||||
5,chill_3party,thirdparty_category,association tiers - catégories
|
5,chill_3party,thirdparty_category,association tiers - catégories
|
||||||
@@ -54,7 +54,7 @@ order,table_schema,table_name,commentaire
|
|||||||
53,public,activitytpresence,Présence aux échanges
|
53,public,activitytpresence,Présence aux échanges
|
||||||
54,public,activitytype,Types d'échanges
|
54,public,activitytype,Types d'échanges
|
||||||
55,public,activitytypecategory,Catégories de types d'échanges
|
55,public,activitytypecategory,Catégories de types d'échanges
|
||||||
56,public,centers,"Territoires (territoires, agences, etc.)"
|
56,public,centers,"Centres (territoires, agences, etc.)"
|
||||||
57,public,chill_activity_activity_chill_person_socialaction,
|
57,public,chill_activity_activity_chill_person_socialaction,
|
||||||
58,public,chill_activity_activity_chill_person_socialissue
|
58,public,chill_activity_activity_chill_person_socialissue
|
||||||
59,public,chill_docgen_template,Gabarits de documents
|
59,public,chill_docgen_template,Gabarits de documents
|
||||||
@@ -111,7 +111,7 @@ order,table_schema,table_name,commentaire
|
|||||||
110,public,chill_person_marital_status,Etats civils
|
110,public,chill_person_marital_status,Etats civils
|
||||||
111,public,chill_person_not_duplicate,
|
111,public,chill_person_not_duplicate,
|
||||||
112,public,chill_person_person,Usagers
|
112,public,chill_person_person,Usagers
|
||||||
113,public,chill_person_person_center_history,Historique des territoires d'un usagers
|
113,public,chill_person_person_center_history,Historique des centres d'un usagers
|
||||||
114,public,chill_person_persons_to_addresses,Déprécié
|
114,public,chill_person_persons_to_addresses,Déprécié
|
||||||
115,public,chill_person_phone,Numéros d etéléphone supplémentaires d'un usager
|
115,public,chill_person_phone,Numéros d etéléphone supplémentaires d'un usager
|
||||||
116,public,chill_person_relations,Types de relations de filiation
|
116,public,chill_person_relations,Types de relations de filiation
|
||||||
@@ -142,7 +142,7 @@ order,table_schema,table_name,commentaire
|
|||||||
141,public,permission_groups
|
141,public,permission_groups
|
||||||
142,public,permissionsgroup_rolescope
|
142,public,permissionsgroup_rolescope
|
||||||
143,public,persons_spoken_languages
|
143,public,persons_spoken_languages
|
||||||
144,public,regroupment,Regroupement de territoires
|
144,public,regroupment,Regroupement de centres
|
||||||
145,public,regroupment_center,
|
145,public,regroupment_center,
|
||||||
146,public,role_scopes,
|
146,public,role_scopes,
|
||||||
147,public,scopes,Services
|
147,public,scopes,Services
|
||||||
|
|||||||
|
@@ -55,7 +55,6 @@
|
|||||||
"@tsconfig/node20": "^20.1.4",
|
"@tsconfig/node20": "^20.1.4",
|
||||||
"@types/dompurify": "^3.0.5",
|
"@types/dompurify": "^3.0.5",
|
||||||
"@types/leaflet": "^1.9.3",
|
"@types/leaflet": "^1.9.3",
|
||||||
"@vueuse/core": "^13.9.0",
|
|
||||||
"bootstrap-icons": "^1.11.3",
|
"bootstrap-icons": "^1.11.3",
|
||||||
"dropzone": "^5.7.6",
|
"dropzone": "^5.7.6",
|
||||||
"es6-promise": "^4.2.8",
|
"es6-promise": "^4.2.8",
|
||||||
|
|||||||
@@ -66,9 +66,6 @@ class ListActivityHelper
|
|||||||
->leftJoin('activity.location', 'location')
|
->leftJoin('activity.location', 'location')
|
||||||
->addSelect('location.name AS locationName')
|
->addSelect('location.name AS locationName')
|
||||||
->addSelect('activity.sentReceived')
|
->addSelect('activity.sentReceived')
|
||||||
->addSelect('activity.comment.comment AS commentText')
|
|
||||||
->addSelect('activity.comment.date AS commentDate')
|
|
||||||
->addSelect('JSON_BUILD_OBJECT(\'uid\', activity.comment.userId, \'d\', activity.comment.date) AS commentUser')
|
|
||||||
->addSelect('JSON_BUILD_OBJECT(\'uid\', IDENTITY(activity.createdBy), \'d\', activity.createdAt) AS createdBy')
|
->addSelect('JSON_BUILD_OBJECT(\'uid\', IDENTITY(activity.createdBy), \'d\', activity.createdAt) AS createdBy')
|
||||||
->addSelect('activity.createdAt')
|
->addSelect('activity.createdAt')
|
||||||
->addSelect('JSON_BUILD_OBJECT(\'uid\', IDENTITY(activity.updatedBy), \'d\', activity.updatedAt) AS updatedBy')
|
->addSelect('JSON_BUILD_OBJECT(\'uid\', IDENTITY(activity.updatedBy), \'d\', activity.updatedAt) AS updatedBy')
|
||||||
@@ -90,8 +87,6 @@ class ListActivityHelper
|
|||||||
'createdAt', 'updatedAt' => $this->dateTimeHelper->getLabel($key),
|
'createdAt', 'updatedAt' => $this->dateTimeHelper->getLabel($key),
|
||||||
'createdBy', 'updatedBy' => $this->userHelper->getLabel($key, $values, $key),
|
'createdBy', 'updatedBy' => $this->userHelper->getLabel($key, $values, $key),
|
||||||
'date' => $this->dateTimeHelper->getLabel(self::MSG_KEY.$key),
|
'date' => $this->dateTimeHelper->getLabel(self::MSG_KEY.$key),
|
||||||
'commentDate' => $this->dateTimeHelper->getLabel(self::MSG_KEY.'comment_date'),
|
|
||||||
'commentUser' => $this->userHelper->getLabel($key, $values, self::MSG_KEY.'comment_user'),
|
|
||||||
'attendeeName' => function ($value) {
|
'attendeeName' => function ($value) {
|
||||||
if ('_header' === $value) {
|
if ('_header' === $value) {
|
||||||
return 'Attendee';
|
return 'Attendee';
|
||||||
@@ -181,9 +176,6 @@ class ListActivityHelper
|
|||||||
'usersNames',
|
'usersNames',
|
||||||
'thirdPartiesIds',
|
'thirdPartiesIds',
|
||||||
'thirdPartiesNames',
|
'thirdPartiesNames',
|
||||||
'commentText',
|
|
||||||
'commentDate',
|
|
||||||
'commentUser',
|
|
||||||
'createdBy',
|
'createdBy',
|
||||||
'createdAt',
|
'createdAt',
|
||||||
'updatedBy',
|
'updatedBy',
|
||||||
|
|||||||
@@ -90,9 +90,7 @@ class ActivityReasonFilter implements ExportElementValidatedInterface, FilterInt
|
|||||||
|
|
||||||
public function getFormDefaultData(): array
|
public function getFormDefaultData(): array
|
||||||
{
|
{
|
||||||
return [
|
return [];
|
||||||
'reasons' => [],
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function describeAction($data, ExportGenerationContext $context): string|\Symfony\Contracts\Translation\TranslatableInterface|array
|
public function describeAction($data, ExportGenerationContext $context): string|\Symfony\Contracts\Translation\TranslatableInterface|array
|
||||||
|
|||||||
@@ -42,8 +42,6 @@ final readonly class PersonHavingActivityBetweenDateFilter implements ExportElem
|
|||||||
|
|
||||||
public function alterQuery(QueryBuilder $qb, $data, ExportGenerationContext $exportGenerationContext): void
|
public function alterQuery(QueryBuilder $qb, $data, ExportGenerationContext $exportGenerationContext): void
|
||||||
{
|
{
|
||||||
error_log('alterQuery called with data: '.json_encode(array_keys($data)));
|
|
||||||
|
|
||||||
// create a subquery for activity
|
// create a subquery for activity
|
||||||
$sqb = $qb->getEntityManager()->createQueryBuilder();
|
$sqb = $qb->getEntityManager()->createQueryBuilder();
|
||||||
$sqb->select('1')
|
$sqb->select('1')
|
||||||
@@ -61,6 +59,7 @@ final readonly class PersonHavingActivityBetweenDateFilter implements ExportElem
|
|||||||
if (\in_array('activity', $qb->getAllAliases(), true)) {
|
if (\in_array('activity', $qb->getAllAliases(), true)) {
|
||||||
$sqb->andWhere('activity_person_having_activity.id = activity.id');
|
$sqb->andWhere('activity_person_having_activity.id = activity.id');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($data['reasons']) && [] !== $data['reasons']) {
|
if (isset($data['reasons']) && [] !== $data['reasons']) {
|
||||||
// add clause activity reason
|
// add clause activity reason
|
||||||
$sqb->join('activity_person_having_activity.reasons', 'reasons_person_having_activity');
|
$sqb->join('activity_person_having_activity.reasons', 'reasons_person_having_activity');
|
||||||
@@ -125,38 +124,12 @@ final readonly class PersonHavingActivityBetweenDateFilter implements ExportElem
|
|||||||
|
|
||||||
public function normalizeFormData(array $formData): array
|
public function normalizeFormData(array $formData): array
|
||||||
{
|
{
|
||||||
$normalized = [
|
return ['date_from_rolling' => $formData['date_from_rolling']->normalize(), 'date_to_rolling' => $formData['date_to_rolling']->normalize()];
|
||||||
'date_from_rolling' => $formData['date_from_rolling']->normalize(),
|
|
||||||
'date_to_rolling' => $formData['date_to_rolling']->normalize(),
|
|
||||||
'reasons' => [],
|
|
||||||
];
|
|
||||||
|
|
||||||
if (isset($formData['reasons']) && [] !== $formData['reasons']) {
|
|
||||||
$normalized['reasons'] = array_map(
|
|
||||||
fn (ActivityReason $reason) => $reason->getId(),
|
|
||||||
$formData['reasons']
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $normalized;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function denormalizeFormData(array $formData, int $fromVersion): array
|
public function denormalizeFormData(array $formData, int $fromVersion): array
|
||||||
{
|
{
|
||||||
$denormalized = [
|
return ['date_from_rolling' => RollingDate::fromNormalized($formData['date_from_rolling']), 'date_to_rolling' => RollingDate::fromNormalized($formData['date_to_rolling'])];
|
||||||
'date_from_rolling' => RollingDate::fromNormalized($formData['date_from_rolling']),
|
|
||||||
'date_to_rolling' => RollingDate::fromNormalized($formData['date_to_rolling']),
|
|
||||||
'reasons' => [],
|
|
||||||
];
|
|
||||||
|
|
||||||
if (isset($formData['reasons']) && [] !== $formData['reasons']) {
|
|
||||||
$denormalized['reasons'] = array_map(
|
|
||||||
fn ($id) => $this->activityReasonRepository->find($id),
|
|
||||||
$formData['reasons']
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $denormalized;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getFormDefaultData(): array
|
public function getFormDefaultData(): array
|
||||||
@@ -170,12 +143,10 @@ final readonly class PersonHavingActivityBetweenDateFilter implements ExportElem
|
|||||||
|
|
||||||
public function describeAction($data, ExportGenerationContext $context): array
|
public function describeAction($data, ExportGenerationContext $context): array
|
||||||
{
|
{
|
||||||
$reasons = $data['reasons'] ?? [];
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
[] === $reasons ?
|
[] === $data['reasons'] ?
|
||||||
'export.filter.activity.describe_action_with_no_subject'
|
'export.filter.person_between_dates.describe_action_with_no_subject'
|
||||||
: 'export.filter.activity.describe_action_with_subject',
|
: 'export.filter.person_between_dates.describe_action_with_subject',
|
||||||
[
|
[
|
||||||
'date_from' => $this->rollingDateConverter->convert($data['date_from_rolling']),
|
'date_from' => $this->rollingDateConverter->convert($data['date_from_rolling']),
|
||||||
'date_to' => $this->rollingDateConverter->convert($data['date_to_rolling']),
|
'date_to' => $this->rollingDateConverter->convert($data['date_to_rolling']),
|
||||||
@@ -183,7 +154,7 @@ final readonly class PersonHavingActivityBetweenDateFilter implements ExportElem
|
|||||||
', ',
|
', ',
|
||||||
array_map(
|
array_map(
|
||||||
fn (ActivityReason $r): string => '"'.$this->translatableStringHelper->localize($r->getName()).'"',
|
fn (ActivityReason $r): string => '"'.$this->translatableStringHelper->localize($r->getName()).'"',
|
||||||
$reasons
|
$data['reasons']
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -197,7 +168,6 @@ final readonly class PersonHavingActivityBetweenDateFilter implements ExportElem
|
|||||||
|
|
||||||
public function validateForm($data, ExecutionContextInterface $context): void
|
public function validateForm($data, ExecutionContextInterface $context): void
|
||||||
{
|
{
|
||||||
error_log('validateForm called with data: '.json_encode(array_keys($data)));
|
|
||||||
if ($this->rollingDateConverter->convert($data['date_from_rolling'])
|
if ($this->rollingDateConverter->convert($data['date_from_rolling'])
|
||||||
>= $this->rollingDateConverter->convert($data['date_to_rolling'])) {
|
>= $this->rollingDateConverter->convert($data['date_to_rolling'])) {
|
||||||
$context->buildViolation('export.filter.activity.person_between_dates.date mismatch')
|
$context->buildViolation('export.filter.activity.person_between_dates.date mismatch')
|
||||||
|
|||||||
@@ -136,14 +136,8 @@ export default {
|
|||||||
issueIsLoading: false,
|
issueIsLoading: false,
|
||||||
actionIsLoading: false,
|
actionIsLoading: false,
|
||||||
actionAreLoaded: false,
|
actionAreLoaded: false,
|
||||||
socialIssuesClassList: {
|
socialIssuesClassList: `col-form-label ${document.querySelector("input#chill_activitybundle_activity_socialIssues").getAttribute("required") ? "required" : ""}`,
|
||||||
"col-form-label": true,
|
socialActionsClassList: `col-form-label ${document.querySelector("input#chill_activitybundle_activity_socialActions").getAttribute("required") ? "required" : ""}`,
|
||||||
required: false,
|
|
||||||
},
|
|
||||||
socialActionsClassList: {
|
|
||||||
"col-form-label": true,
|
|
||||||
required: false,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -164,21 +158,6 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
/* Load classNames after element is present */
|
|
||||||
const socialActionsEl = document.querySelector(
|
|
||||||
"input#chill_activitybundle_activity_socialActions",
|
|
||||||
);
|
|
||||||
if (socialActionsEl && socialActionsEl.hasAttribute("required")) {
|
|
||||||
this.socialActionsClassList.required = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const socialIssuesEl = document.querySelector(
|
|
||||||
"input#chill_activitybundle_activity_socialIssues",
|
|
||||||
);
|
|
||||||
if (socialIssuesEl && socialIssuesEl.hasAttribute("required")) {
|
|
||||||
this.socialIssuesClassList.required = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Load other issues in multiselect */
|
/* Load other issues in multiselect */
|
||||||
this.issueIsLoading = true;
|
this.issueIsLoading = true;
|
||||||
this.actionAreLoaded = false;
|
this.actionAreLoaded = false;
|
||||||
|
|||||||
@@ -43,23 +43,11 @@ export default {
|
|||||||
span.badge {
|
span.badge {
|
||||||
@include badge_social($social-action-color);
|
@include badge_social($social-action-color);
|
||||||
font-size: 95%;
|
font-size: 95%;
|
||||||
white-space: normal;
|
|
||||||
word-wrap: break-word;
|
|
||||||
word-break: break-word;
|
|
||||||
display: inline-block;
|
|
||||||
max-width: 100%;
|
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
margin-right: 1em;
|
margin-right: 1em;
|
||||||
text-align: left;
|
max-width: 100%; /* Adjust as needed */
|
||||||
line-height: 1.2em;
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
&::before {
|
white-space: nowrap;
|
||||||
position: absolute;
|
|
||||||
left: 11px;
|
|
||||||
top: 0;
|
|
||||||
margin: 0 0.3em 0 -0.75em;
|
|
||||||
}
|
|
||||||
position: relative;
|
|
||||||
padding-left: 1.5em;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -43,22 +43,7 @@ export default {
|
|||||||
span.badge {
|
span.badge {
|
||||||
@include badge_social($social-issue-color);
|
@include badge_social($social-issue-color);
|
||||||
font-size: 95%;
|
font-size: 95%;
|
||||||
white-space: normal;
|
|
||||||
word-wrap: break-word;
|
|
||||||
word-break: break-word;
|
|
||||||
display: inline-block;
|
|
||||||
max-width: 100%;
|
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
margin-right: 1em;
|
margin-right: 1em;
|
||||||
text-align: left;
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
position: absolute;
|
|
||||||
left: 11px;
|
|
||||||
top: 0;
|
|
||||||
margin: 0 0.3em 0 -0.75em;
|
|
||||||
}
|
|
||||||
position: relative;
|
|
||||||
padding-left: 1.5em;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ Attendee: Présence de l'usager
|
|||||||
attendee: présence de l'usager
|
attendee: présence de l'usager
|
||||||
list_reasons: liste des sujets
|
list_reasons: liste des sujets
|
||||||
user_username: nom de l'utilisateur
|
user_username: nom de l'utilisateur
|
||||||
circle_name: nom du service
|
circle_name: nom du cercle
|
||||||
Remark: Commentaire
|
Remark: Commentaire
|
||||||
No comments: Aucun commentaire
|
No comments: Aucun commentaire
|
||||||
Add a new activity: Ajouter une nouvel échange
|
Add a new activity: Ajouter une nouvel échange
|
||||||
@@ -20,7 +20,7 @@ not present: absent
|
|||||||
Delete: Supprimer
|
Delete: Supprimer
|
||||||
Update: Mettre à jour
|
Update: Mettre à jour
|
||||||
Update activity: Modifier l'échange
|
Update activity: Modifier l'échange
|
||||||
Scope: Service
|
Scope: Cercle
|
||||||
Activity data: Données de l'échange
|
Activity data: Données de l'échange
|
||||||
Activity location: Localisation de l'échange
|
Activity location: Localisation de l'échange
|
||||||
No reason associated: Aucun sujet
|
No reason associated: Aucun sujet
|
||||||
@@ -398,15 +398,13 @@ export:
|
|||||||
sent received: Envoyé ou reçu
|
sent received: Envoyé ou reçu
|
||||||
emergency: Urgence
|
emergency: Urgence
|
||||||
accompanying course id: Identifiant du parcours
|
accompanying course id: Identifiant du parcours
|
||||||
course circles: Services du parcours
|
course circles: Cercles du parcours
|
||||||
travelTime: Durée de déplacement
|
travelTime: Durée de déplacement
|
||||||
durationTime: Durée
|
durationTime: Durée
|
||||||
id: Identifiant
|
id: Identifiant
|
||||||
List activities linked to an accompanying course: Liste les échanges liés à un parcours en fonction de différents filtres.
|
List activities linked to an accompanying course: Liste les échanges liés à un parcours en fonction de différents filtres.
|
||||||
List activity linked to a course: Liste des échanges liés à un parcours
|
List activity linked to a course: Liste des échanges liés à un parcours
|
||||||
commentText: Commentaire
|
|
||||||
comment_date: Date de la dernière édition du commentaire
|
|
||||||
comment_user: Dernière édition par
|
|
||||||
|
|
||||||
filter:
|
filter:
|
||||||
activity:
|
activity:
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ final class ChillAsideActivityExtension extends Extension implements PrependExte
|
|||||||
$config = $this->processConfiguration($configuration, $configs);
|
$config = $this->processConfiguration($configuration, $configs);
|
||||||
|
|
||||||
$container->setParameter('chill_aside_activity.form.time_duration', $config['form']['time_duration']);
|
$container->setParameter('chill_aside_activity.form.time_duration', $config['form']['time_duration']);
|
||||||
$container->setParameter('chill_aside_activity.show_concerned_persons_count', 'visible' === $config['show_concerned_persons_count']);
|
|
||||||
|
|
||||||
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../config'));
|
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../config'));
|
||||||
$loader->load('services.yaml');
|
$loader->load('services.yaml');
|
||||||
@@ -39,24 +38,6 @@ final class ChillAsideActivityExtension extends Extension implements PrependExte
|
|||||||
{
|
{
|
||||||
$this->prependRoute($container);
|
$this->prependRoute($container);
|
||||||
$this->prependCruds($container);
|
$this->prependCruds($container);
|
||||||
$this->prependTwigConfig($container);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function prependTwigConfig(ContainerBuilder $container)
|
|
||||||
{
|
|
||||||
// Get the configuration for this bundle
|
|
||||||
$chillAsideActivityConfig = $container->getExtensionConfig($this->getAlias());
|
|
||||||
$config = $this->processConfiguration($this->getConfiguration($chillAsideActivityConfig, $container), $chillAsideActivityConfig);
|
|
||||||
|
|
||||||
// Add configuration to twig globals
|
|
||||||
$twigConfig = [
|
|
||||||
'globals' => [
|
|
||||||
'chill_aside_activity_config' => [
|
|
||||||
'show_concerned_persons_count' => 'visible' === $config['show_concerned_persons_count'],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
];
|
|
||||||
$container->prependExtensionConfig('twig', $twigConfig);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function prependCruds(ContainerBuilder $container)
|
protected function prependCruds(ContainerBuilder $container)
|
||||||
|
|||||||
@@ -141,12 +141,6 @@ class Configuration implements ConfigurationInterface
|
|||||||
->end()
|
->end()
|
||||||
->end()
|
->end()
|
||||||
->end()
|
->end()
|
||||||
->end()
|
|
||||||
->enumNode('show_concerned_persons_count')
|
|
||||||
->values(['hidden', 'visible'])
|
|
||||||
->defaultValue('hidden')
|
|
||||||
->info('Show the concerned persons count field in aside activity forms and views')
|
|
||||||
->end()
|
|
||||||
->end();
|
->end();
|
||||||
|
|
||||||
return $treeBuilder;
|
return $treeBuilder;
|
||||||
|
|||||||
@@ -62,10 +62,6 @@ class AsideActivity implements TrackCreationInterface, TrackUpdateInterface
|
|||||||
#[ORM\ManyToOne(targetEntity: User::class)]
|
#[ORM\ManyToOne(targetEntity: User::class)]
|
||||||
private User $updatedBy;
|
private User $updatedBy;
|
||||||
|
|
||||||
#[Assert\GreaterThanOrEqual(0)]
|
|
||||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::INTEGER, nullable: true)]
|
|
||||||
private ?int $concernedPersonsCount = 0;
|
|
||||||
|
|
||||||
public function getAgent(): ?User
|
public function getAgent(): ?User
|
||||||
{
|
{
|
||||||
return $this->agent;
|
return $this->agent;
|
||||||
@@ -190,16 +186,4 @@ class AsideActivity implements TrackCreationInterface, TrackUpdateInterface
|
|||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getConcernedPersonsCount(): ?int
|
|
||||||
{
|
|
||||||
return $this->concernedPersonsCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setConcernedPersonsCount(?int $concernedPersonsCount): self
|
|
||||||
{
|
|
||||||
$this->concernedPersonsCount = $concernedPersonsCount;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,86 +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\AsideActivityBundle\Export\Aggregator;
|
|
||||||
|
|
||||||
use Chill\AsideActivityBundle\Export\Declarations;
|
|
||||||
use Chill\MainBundle\Export\AggregatorInterface;
|
|
||||||
use Doctrine\ORM\QueryBuilder;
|
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
|
||||||
|
|
||||||
class ByConcernedPersonsCountAggregator implements AggregatorInterface
|
|
||||||
{
|
|
||||||
public function addRole(): ?string
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function alterQuery(QueryBuilder $qb, $data, \Chill\MainBundle\Export\ExportGenerationContext $exportGenerationContext): void
|
|
||||||
{
|
|
||||||
$qb->addSelect('aside.concernedPersonsCount AS by_concerned_persons_count_aggregator')
|
|
||||||
->addGroupBy('by_concerned_persons_count_aggregator');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function applyOn(): string
|
|
||||||
{
|
|
||||||
return Declarations::ASIDE_ACTIVITY_TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder): void
|
|
||||||
{
|
|
||||||
// No form needed
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getNormalizationVersion(): int
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function normalizeFormData(array $formData): array
|
|
||||||
{
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function denormalizeFormData(array $formData, int $fromVersion): array
|
|
||||||
{
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getFormDefaultData(): array
|
|
||||||
{
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getLabels($key, array $values, $data): callable
|
|
||||||
{
|
|
||||||
return function ($value): string {
|
|
||||||
if ('_header' === $value) {
|
|
||||||
return 'export.aggregator.Concerned persons count';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (null === $value) {
|
|
||||||
return 'export.aggregator.No concerned persons count specified';
|
|
||||||
}
|
|
||||||
|
|
||||||
return (string) $value;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getQueryKeys($data): array
|
|
||||||
{
|
|
||||||
return ['by_concerned_persons_count_aggregator'];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getTitle(): string
|
|
||||||
{
|
|
||||||
return 'export.aggregator.Group by concerned persons count';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,116 +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\AsideActivityBundle\Export\Export;
|
|
||||||
|
|
||||||
use Chill\AsideActivityBundle\Export\Declarations;
|
|
||||||
use Chill\AsideActivityBundle\Repository\AsideActivityRepository;
|
|
||||||
use Chill\AsideActivityBundle\Security\AsideActivityVoter;
|
|
||||||
use Chill\MainBundle\Export\ExportInterface;
|
|
||||||
use Chill\MainBundle\Export\FormatterInterface;
|
|
||||||
use Chill\MainBundle\Export\GroupedExportInterface;
|
|
||||||
use Doctrine\ORM\Query;
|
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
|
||||||
|
|
||||||
class SumConcernedPersonsCountAsideActivity implements ExportInterface, GroupedExportInterface
|
|
||||||
{
|
|
||||||
public function __construct(private readonly AsideActivityRepository $repository) {}
|
|
||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder) {}
|
|
||||||
|
|
||||||
public function getNormalizationVersion(): int
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function normalizeFormData(array $formData): array
|
|
||||||
{
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function denormalizeFormData(array $formData, int $fromVersion): array
|
|
||||||
{
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getFormDefaultData(): array
|
|
||||||
{
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAllowedFormattersTypes(): array
|
|
||||||
{
|
|
||||||
return [FormatterInterface::TYPE_TABULAR];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getDescription(): string
|
|
||||||
{
|
|
||||||
return 'export.Sum concerned persons count for aside activities';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getGroup(): string
|
|
||||||
{
|
|
||||||
return 'export.Exports of aside activities';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getLabels($key, array $values, $data)
|
|
||||||
{
|
|
||||||
if ('export_sum_concerned_persons_count' !== $key) {
|
|
||||||
throw new \LogicException("the key {$key} is not used by this export");
|
|
||||||
}
|
|
||||||
|
|
||||||
$labels = array_combine($values, $values);
|
|
||||||
$labels['_header'] = $this->getTitle();
|
|
||||||
|
|
||||||
return static fn ($value) => $labels[$value];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getQueryKeys($data): array
|
|
||||||
{
|
|
||||||
return ['export_sum_concerned_persons_count'];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getResult($query, $data, \Chill\MainBundle\Export\ExportGenerationContext $context): array
|
|
||||||
{
|
|
||||||
return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getTitle(): string
|
|
||||||
{
|
|
||||||
return 'export.Sum concerned persons count for aside activities';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getType(): string
|
|
||||||
{
|
|
||||||
return Declarations::ASIDE_ACTIVITY_TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function initiateQuery(array $requiredModifiers, array $acl, array $data, \Chill\MainBundle\Export\ExportGenerationContext $context): \Doctrine\ORM\QueryBuilder
|
|
||||||
{
|
|
||||||
$qb = $this->repository->createQueryBuilder('aside');
|
|
||||||
|
|
||||||
$qb->select('SUM(COALESCE(aside.concernedPersonsCount, 0)) as export_sum_concerned_persons_count');
|
|
||||||
|
|
||||||
return $qb;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function requiredRole(): string
|
|
||||||
{
|
|
||||||
return AsideActivityVoter::STATS;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function supportsModifiers(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
Declarations::ASIDE_ACTIVITY_TYPE,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -21,7 +21,6 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
|||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToTimestampTransformer;
|
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToTimestampTransformer;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
|
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Component\Form\FormEvent;
|
use Symfony\Component\Form\FormEvent;
|
||||||
use Symfony\Component\Form\FormEvents;
|
use Symfony\Component\Form\FormEvents;
|
||||||
@@ -30,13 +29,11 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
|
|||||||
final class AsideActivityFormType extends AbstractType
|
final class AsideActivityFormType extends AbstractType
|
||||||
{
|
{
|
||||||
private readonly array $timeChoices;
|
private readonly array $timeChoices;
|
||||||
private readonly bool $showConcernedPersonsCount;
|
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
ParameterBagInterface $parameterBag,
|
ParameterBagInterface $parameterBag,
|
||||||
) {
|
) {
|
||||||
$this->timeChoices = $parameterBag->get('chill_aside_activity.form.time_duration');
|
$this->timeChoices = $parameterBag->get('chill_aside_activity.form.time_duration');
|
||||||
$this->showConcernedPersonsCount = $parameterBag->get('chill_aside_activity.show_concerned_persons_count');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
@@ -79,16 +76,6 @@ final class AsideActivityFormType extends AbstractType
|
|||||||
->add('location', PickUserLocationType::class)
|
->add('location', PickUserLocationType::class)
|
||||||
;
|
;
|
||||||
|
|
||||||
if ($this->showConcernedPersonsCount) {
|
|
||||||
$builder->add('concernedPersonsCount', IntegerType::class, [
|
|
||||||
'label' => 'Concerned persons count',
|
|
||||||
'required' => false,
|
|
||||||
'attr' => [
|
|
||||||
'min' => 0,
|
|
||||||
],
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (['duration'] as $fieldName) {
|
foreach (['duration'] as $fieldName) {
|
||||||
$builder->get($fieldName)
|
$builder->get($fieldName)
|
||||||
->addModelTransformer($durationTimeTransformer);
|
->addModelTransformer($durationTimeTransformer);
|
||||||
|
|||||||
@@ -42,11 +42,6 @@
|
|||||||
{%- if entity.location.name is defined -%}
|
{%- if entity.location.name is defined -%}
|
||||||
<div><i class="fa fa-fw fa-map-marker"></i>{{ entity.location.name }}</div>
|
<div><i class="fa fa-fw fa-map-marker"></i>{{ entity.location.name }}</div>
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
|
|
||||||
{%- if entity.concernedPersonsCount > 0 -%}
|
|
||||||
<div><i class="fa fa-fw fa-user"></i>{{ entity.concernedPersonsCount }}</div>
|
|
||||||
{%- endif -%}
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="item-col" style="justify-content: flex-end;">
|
<div class="item-col" style="justify-content: flex-end;">
|
||||||
<div class="box">
|
<div class="box">
|
||||||
|
|||||||
@@ -38,11 +38,6 @@
|
|||||||
<dt class="inline">{{ 'Duration'|trans }}</dt>
|
<dt class="inline">{{ 'Duration'|trans }}</dt>
|
||||||
<dd>{{ entity.duration|date('H:i') }}</dd>
|
<dd>{{ entity.duration|date('H:i') }}</dd>
|
||||||
|
|
||||||
{% if chill_aside_activity_config.show_concerned_persons_count == 'visible' %}
|
|
||||||
<dt class="inline">{{ 'Concerned persons count'|trans }}</dt>
|
|
||||||
<dd>{{ entity.concernedPersonsCount }}</dd>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<dt class="inline">{{ 'Remark'|trans }}</dt>
|
<dt class="inline">{{ 'Remark'|trans }}</dt>
|
||||||
{%- if entity.note is empty -%}
|
{%- if entity.note is empty -%}
|
||||||
<dd>
|
<dd>
|
||||||
@@ -60,6 +55,5 @@
|
|||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block content_view_actions_duplicate_link %}{% endblock %}
|
|
||||||
{% endembed %}
|
{% endembed %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -1,49 +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\AsideActivityBundle\Tests\Export\Aggregator;
|
|
||||||
|
|
||||||
use Chill\AsideActivityBundle\Entity\AsideActivity;
|
|
||||||
use Chill\AsideActivityBundle\Export\Aggregator\ByConcernedPersonsCountAggregator;
|
|
||||||
use Chill\MainBundle\Test\Export\AbstractAggregatorTest;
|
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*
|
|
||||||
* @coversNothing
|
|
||||||
*/
|
|
||||||
class ByConcernedPersonsCountAggregatorTest extends AbstractAggregatorTest
|
|
||||||
{
|
|
||||||
public function getAggregator()
|
|
||||||
{
|
|
||||||
return new ByConcernedPersonsCountAggregator();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getFormData(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
[],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getQueryBuilders(): iterable
|
|
||||||
{
|
|
||||||
self::bootKernel();
|
|
||||||
$em = self::getContainer()->get(EntityManagerInterface::class);
|
|
||||||
|
|
||||||
return [
|
|
||||||
$em->createQueryBuilder()
|
|
||||||
->select('count(aside.id)')
|
|
||||||
->from(AsideActivity::class, 'aside'),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,50 +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\AsideActivityBundle\Tests\Export\Export;
|
|
||||||
|
|
||||||
use Chill\AsideActivityBundle\Export\Export\SumConcernedPersonsCountAsideActivity;
|
|
||||||
use Chill\AsideActivityBundle\Repository\AsideActivityRepository;
|
|
||||||
use Chill\MainBundle\Test\Export\AbstractExportTest;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*
|
|
||||||
* @coversNothing
|
|
||||||
*/
|
|
||||||
final class SumConcernedPersonsCountAsideActivityTest extends AbstractExportTest
|
|
||||||
{
|
|
||||||
protected function setUp(): void
|
|
||||||
{
|
|
||||||
self::bootKernel();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getExport()
|
|
||||||
{
|
|
||||||
$repository = self::getContainer()->get(AsideActivityRepository::class);
|
|
||||||
|
|
||||||
yield new SumConcernedPersonsCountAsideActivity($repository);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getFormData(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
[],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getModifiersCombination(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
['aside_activity'],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -20,10 +20,6 @@ services:
|
|||||||
tags:
|
tags:
|
||||||
- { name: chill.export, alias: 'avg_aside_activity_duration' }
|
- { name: chill.export, alias: 'avg_aside_activity_duration' }
|
||||||
|
|
||||||
Chill\AsideActivityBundle\Export\Export\SumConcernedPersonsCountAsideActivity:
|
|
||||||
tags:
|
|
||||||
- { name: chill.export, alias: 'sum_aside_activity_concerned_persons_count' }
|
|
||||||
|
|
||||||
## Filters
|
## Filters
|
||||||
chill.aside_activity.export.date_filter:
|
chill.aside_activity.export.date_filter:
|
||||||
class: Chill\AsideActivityBundle\Export\Filter\ByDateFilter
|
class: Chill\AsideActivityBundle\Export\Filter\ByDateFilter
|
||||||
@@ -74,7 +70,3 @@ services:
|
|||||||
Chill\AsideActivityBundle\Export\Aggregator\ByLocationAggregator:
|
Chill\AsideActivityBundle\Export\Aggregator\ByLocationAggregator:
|
||||||
tags:
|
tags:
|
||||||
- { name: chill.export_aggregator, alias: 'aside_activity_location_aggregator' }
|
- { name: chill.export_aggregator, alias: 'aside_activity_location_aggregator' }
|
||||||
|
|
||||||
Chill\AsideActivityBundle\Export\Aggregator\ByConcernedPersonsCountAggregator:
|
|
||||||
tags:
|
|
||||||
- { name: chill.export_aggregator, alias: 'aside_activity_concerned_persons_count_aggregator' }
|
|
||||||
|
|||||||
@@ -1,33 +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\Migrations\AsideActivity;
|
|
||||||
|
|
||||||
use Doctrine\DBAL\Schema\Schema;
|
|
||||||
use Doctrine\Migrations\AbstractMigration;
|
|
||||||
|
|
||||||
final class Version20251006113048 extends AbstractMigration
|
|
||||||
{
|
|
||||||
public function getDescription(): string
|
|
||||||
{
|
|
||||||
return 'Add concernedPersonsCount property to AsideActivity entity';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function up(Schema $schema): void
|
|
||||||
{
|
|
||||||
$this->addSql('ALTER TABLE chill_asideactivity.asideactivity ADD concernedPersonsCount INT DEFAULT 0');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function down(Schema $schema): void
|
|
||||||
{
|
|
||||||
$this->addSql('ALTER TABLE chill_asideactivity.AsideActivity DROP concernedPersonsCount');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -27,7 +27,6 @@ Emergency: Urgent
|
|||||||
by: "Par "
|
by: "Par "
|
||||||
location: Lieu
|
location: Lieu
|
||||||
Asideactivity location: Localisation de l'activité
|
Asideactivity location: Localisation de l'activité
|
||||||
Concerned persons count: Nombre d'usager concernés
|
|
||||||
|
|
||||||
# Crud
|
# Crud
|
||||||
crud:
|
crud:
|
||||||
@@ -178,7 +177,7 @@ export:
|
|||||||
agent_id: Utilisateur
|
agent_id: Utilisateur
|
||||||
creator_id: Créateur
|
creator_id: Créateur
|
||||||
main_scope: Service principal de l'utilisateur
|
main_scope: Service principal de l'utilisateur
|
||||||
main_center: Territoire principal de l'utilisateur
|
main_center: Centre principal de l'utilisateur
|
||||||
aside_activity_type: Catégorie d'activité annexe
|
aside_activity_type: Catégorie d'activité annexe
|
||||||
date: Date
|
date: Date
|
||||||
duration: Durée
|
duration: Durée
|
||||||
@@ -191,7 +190,6 @@ export:
|
|||||||
Count aside activities by various parameters.: Compte le nombre d'activités annexes selon divers critères
|
Count aside activities by various parameters.: Compte le nombre d'activités annexes selon divers critères
|
||||||
Average aside activities duration: Durée moyenne des activités annexes
|
Average aside activities duration: Durée moyenne des activités annexes
|
||||||
Sum aside activities duration: Durée des activités annexes
|
Sum aside activities duration: Durée des activités annexes
|
||||||
Sum concerned persons count for aside activities: Nombre d'usager concernés par les activités annexes
|
|
||||||
filter:
|
filter:
|
||||||
Filter by aside activity date: Filtrer les activités annexes par date
|
Filter by aside activity date: Filtrer les activités annexes par date
|
||||||
Filter by aside activity type: Filtrer les activités annexes par type d'activité
|
Filter by aside activity type: Filtrer les activités annexes par type d'activité
|
||||||
@@ -212,8 +210,6 @@ export:
|
|||||||
'Filtered by aside activity location: only %location%': "Filtré par localisation: uniquement %location%"
|
'Filtered by aside activity location: only %location%': "Filtré par localisation: uniquement %location%"
|
||||||
aggregator:
|
aggregator:
|
||||||
Group by aside activity type: Grouper les activités annexes par type d'activité
|
Group by aside activity type: Grouper les activités annexes par type d'activité
|
||||||
Group by concerned persons count: Grouper les activités annexes par nombre d'usagers conernés
|
|
||||||
Concerned persons count: Nombre d'usagers concernés
|
|
||||||
Aside activity type: Type d'activité annexe
|
Aside activity type: Type d'activité annexe
|
||||||
by_user_job:
|
by_user_job:
|
||||||
Aggregate by user job: Grouper les activités annexes par métier des utilisateurs
|
Aggregate by user job: Grouper les activités annexes par métier des utilisateurs
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ namespace Chill\CalendarBundle\Controller;
|
|||||||
|
|
||||||
use Chill\CalendarBundle\Entity\Calendar;
|
use Chill\CalendarBundle\Entity\Calendar;
|
||||||
use Chill\CalendarBundle\Form\CalendarType;
|
use Chill\CalendarBundle\Form\CalendarType;
|
||||||
use Chill\CalendarBundle\Form\CancelType;
|
|
||||||
use Chill\CalendarBundle\RemoteCalendar\Connector\RemoteCalendarConnectorInterface;
|
use Chill\CalendarBundle\RemoteCalendar\Connector\RemoteCalendarConnectorInterface;
|
||||||
use Chill\CalendarBundle\Repository\CalendarACLAwareRepositoryInterface;
|
use Chill\CalendarBundle\Repository\CalendarACLAwareRepositoryInterface;
|
||||||
use Chill\CalendarBundle\Security\Voter\CalendarVoter;
|
use Chill\CalendarBundle\Security\Voter\CalendarVoter;
|
||||||
@@ -31,7 +30,6 @@ use Chill\PersonBundle\Repository\PersonRepository;
|
|||||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
|
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
|
||||||
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
|
||||||
use http\Exception\UnexpectedValueException;
|
use http\Exception\UnexpectedValueException;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
@@ -62,7 +60,6 @@ class CalendarController extends AbstractController
|
|||||||
private readonly UserRepositoryInterface $userRepository,
|
private readonly UserRepositoryInterface $userRepository,
|
||||||
private readonly TranslatorInterface $translator,
|
private readonly TranslatorInterface $translator,
|
||||||
private readonly \Doctrine\Persistence\ManagerRegistry $managerRegistry,
|
private readonly \Doctrine\Persistence\ManagerRegistry $managerRegistry,
|
||||||
private readonly EntityManagerInterface $em,
|
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -114,55 +111,6 @@ class CalendarController extends AbstractController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Route(path: '/{_locale}/calendar/calendar/{id}/cancel', name: 'chill_calendar_calendar_cancel')]
|
|
||||||
public function cancelAction(Calendar $calendar, Request $request): Response
|
|
||||||
{
|
|
||||||
// Deal with sms being sent or not
|
|
||||||
// Communicate cancellation with the remote calendar.
|
|
||||||
|
|
||||||
$this->denyAccessUnlessGranted(CalendarVoter::EDIT, $calendar);
|
|
||||||
|
|
||||||
[$person, $accompanyingPeriod] = [$calendar->getPerson(), $calendar->getAccompanyingPeriod()];
|
|
||||||
|
|
||||||
$form = $this->createForm(CancelType::class, $calendar);
|
|
||||||
$form->add('submit', SubmitType::class);
|
|
||||||
|
|
||||||
if ($accompanyingPeriod instanceof AccompanyingPeriod) {
|
|
||||||
$view = '@ChillCalendar/Calendar/cancelCalendarByAccompanyingCourse.html.twig';
|
|
||||||
$redirectRoute = $this->generateUrl('chill_calendar_calendar_list_by_period', ['id' => $accompanyingPeriod->getId()]);
|
|
||||||
} elseif ($person instanceof Person) {
|
|
||||||
$view = '@ChillCalendar/Calendar/cancelCalendarByPerson.html.twig';
|
|
||||||
$redirectRoute = $this->generateUrl('chill_calendar_calendar_list_by_person', ['id' => $person->getId()]);
|
|
||||||
} else {
|
|
||||||
throw new \RuntimeException('nor person or accompanying period');
|
|
||||||
}
|
|
||||||
|
|
||||||
$form->handleRequest($request);
|
|
||||||
|
|
||||||
if ($form->isSubmitted() && $form->isValid()) {
|
|
||||||
|
|
||||||
$this->logger->notice('A calendar event has been cancelled', [
|
|
||||||
'by_user' => $this->getUser()->getUsername(),
|
|
||||||
'calendar_id' => $calendar->getId(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
$calendar->setStatus($calendar::STATUS_CANCELED);
|
|
||||||
$calendar->setSmsStatus($calendar::SMS_CANCEL_PENDING);
|
|
||||||
$this->em->flush();
|
|
||||||
|
|
||||||
$this->addFlash('success', $this->translator->trans('chill_calendar.calendar_canceled'));
|
|
||||||
|
|
||||||
return new RedirectResponse($redirectRoute);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->render($view, [
|
|
||||||
'calendar' => $calendar,
|
|
||||||
'form' => $form->createView(),
|
|
||||||
'accompanyingCourse' => $accompanyingPeriod,
|
|
||||||
'person' => $person,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Edit a calendar item.
|
* Edit a calendar item.
|
||||||
*/
|
*/
|
||||||
@@ -318,7 +266,7 @@ class CalendarController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!$this->getUser() instanceof User) {
|
if (!$this->getUser() instanceof User) {
|
||||||
throw new UnauthorizedHttpException('you are not a user');
|
throw new UnauthorizedHttpException('you are not an user');
|
||||||
}
|
}
|
||||||
|
|
||||||
$view = '@ChillCalendar/Calendar/listByUser.html.twig';
|
$view = '@ChillCalendar/Calendar/listByUser.html.twig';
|
||||||
|
|||||||
@@ -1,58 +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\CalendarBundle\Controller;
|
|
||||||
|
|
||||||
use Chill\CalendarBundle\Entity\Calendar;
|
|
||||||
use Chill\CalendarBundle\Repository\InviteRepository;
|
|
||||||
use Chill\DocGeneratorBundle\Repository\DocGeneratorTemplateRepositoryInterface;
|
|
||||||
use Chill\MainBundle\Entity\User;
|
|
||||||
use Chill\MainBundle\Pagination\PaginatorFactory;
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
|
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
|
||||||
|
|
||||||
class MyInvitationsController extends AbstractController
|
|
||||||
{
|
|
||||||
public function __construct(private readonly InviteRepository $inviteRepository, private readonly PaginatorFactory $paginator, private readonly DocGeneratorTemplateRepositoryInterface $docGeneratorTemplateRepository) {}
|
|
||||||
|
|
||||||
#[Route(path: '/{_locale}/calendar/invitations/my', name: 'chill_calendar_invitations_list_my')]
|
|
||||||
public function myInvitations(Request $request): Response
|
|
||||||
{
|
|
||||||
$this->denyAccessUnlessGranted('ROLE_USER');
|
|
||||||
|
|
||||||
$user = $this->getUser();
|
|
||||||
|
|
||||||
if (!$user instanceof User) {
|
|
||||||
throw new UnauthorizedHttpException('you are not a user');
|
|
||||||
}
|
|
||||||
|
|
||||||
$total = count($this->inviteRepository->findBy(['user' => $user]));
|
|
||||||
$paginator = $this->paginator->create($total);
|
|
||||||
|
|
||||||
$invitations = $this->inviteRepository->findBy(
|
|
||||||
['user' => $user],
|
|
||||||
['createdAt' => 'DESC'],
|
|
||||||
$paginator->getItemsPerPage(),
|
|
||||||
$paginator->getCurrentPageFirstItemNumber()
|
|
||||||
);
|
|
||||||
|
|
||||||
$view = '@ChillCalendar/Invitations/listByUser.html.twig';
|
|
||||||
|
|
||||||
return $this->render($view, [
|
|
||||||
'invitations' => $invitations,
|
|
||||||
'paginator' => $paginator,
|
|
||||||
'templates' => $this->docGeneratorTemplateRepository->findByEntity(Calendar::class),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -35,7 +35,7 @@ class LoadCancelReason extends Fixture implements FixtureGroupInterface
|
|||||||
$arr = [
|
$arr = [
|
||||||
['name' => CancelReason::CANCELEDBY_USER],
|
['name' => CancelReason::CANCELEDBY_USER],
|
||||||
['name' => CancelReason::CANCELEDBY_PERSON],
|
['name' => CancelReason::CANCELEDBY_PERSON],
|
||||||
['name' => CancelReason::CANCELEDBY_OTHER],
|
['name' => CancelReason::CANCELEDBY_DONOTCOUNT],
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach ($arr as $a) {
|
foreach ($arr as $a) {
|
||||||
|
|||||||
@@ -269,11 +269,6 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface, HasCente
|
|||||||
return $this->cancelReason;
|
return $this->cancelReason;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isCanceled(): bool
|
|
||||||
{
|
|
||||||
return null !== $this->cancelReason;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getCenters(): ?iterable
|
public function getCenters(): ?iterable
|
||||||
{
|
{
|
||||||
return match ($this->getContext()) {
|
return match ($this->getContext()) {
|
||||||
|
|||||||
@@ -18,14 +18,14 @@ use Doctrine\ORM\Mapping as ORM;
|
|||||||
#[ORM\Table(name: 'chill_calendar.cancel_reason')]
|
#[ORM\Table(name: 'chill_calendar.cancel_reason')]
|
||||||
class CancelReason
|
class CancelReason
|
||||||
{
|
{
|
||||||
final public const CANCELEDBY_OTHER = 'CANCELEDBY_OTHER';
|
final public const CANCELEDBY_DONOTCOUNT = 'CANCELEDBY_DONOTCOUNT';
|
||||||
|
|
||||||
final public const CANCELEDBY_PERSON = 'CANCELEDBY_PERSON';
|
final public const CANCELEDBY_PERSON = 'CANCELEDBY_PERSON';
|
||||||
|
|
||||||
final public const CANCELEDBY_USER = 'CANCELEDBY_USER';
|
final public const CANCELEDBY_USER = 'CANCELEDBY_USER';
|
||||||
|
|
||||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::BOOLEAN, options: ['default' => true])]
|
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::BOOLEAN)]
|
||||||
private bool $active = true;
|
private ?bool $active = null;
|
||||||
|
|
||||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 255)]
|
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 255)]
|
||||||
private ?string $canceledBy = null;
|
private ?string $canceledBy = null;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ use Chill\CalendarBundle\Entity\CancelReason;
|
|||||||
use Chill\MainBundle\Form\Type\TranslatableStringFormType;
|
use Chill\MainBundle\Form\Type\TranslatableStringFormType;
|
||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
|
||||||
@@ -28,14 +28,7 @@ class CancelReasonType extends AbstractType
|
|||||||
->add('active', CheckboxType::class, [
|
->add('active', CheckboxType::class, [
|
||||||
'required' => false,
|
'required' => false,
|
||||||
])
|
])
|
||||||
->add('canceledBy', ChoiceType::class, [
|
->add('canceledBy', TextType::class);
|
||||||
'choices' => [
|
|
||||||
'chill_calendar.canceled_by.user' => CancelReason::CANCELEDBY_USER,
|
|
||||||
'chill_calendar.canceled_by.person' => CancelReason::CANCELEDBY_PERSON,
|
|
||||||
'chill_calendar.canceled_by.other' => CancelReason::CANCELEDBY_OTHER,
|
|
||||||
],
|
|
||||||
'required' => true,
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function configureOptions(OptionsResolver $resolver)
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
|
|||||||
@@ -1,42 +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\CalendarBundle\Form;
|
|
||||||
|
|
||||||
use Chill\CalendarBundle\Entity\Calendar;
|
|
||||||
use Chill\CalendarBundle\Entity\CancelReason;
|
|
||||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
|
||||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
|
||||||
use Symfony\Component\Form\AbstractType;
|
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
|
||||||
|
|
||||||
class CancelType extends AbstractType
|
|
||||||
{
|
|
||||||
public function __construct(private readonly TranslatableStringHelperInterface $translatableStringHelper) {}
|
|
||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
|
||||||
{
|
|
||||||
$builder->add('cancelReason', EntityType::class, [
|
|
||||||
'class' => CancelReason::class,
|
|
||||||
'required' => true,
|
|
||||||
'choice_label' => fn (CancelReason $cancelReason) => $this->translatableStringHelper->localize($cancelReason->getName()),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function configureOptions(OptionsResolver $resolver)
|
|
||||||
{
|
|
||||||
$resolver->setDefaults([
|
|
||||||
'data_class' => Calendar::class,
|
|
||||||
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -25,13 +25,6 @@ class UserMenuBuilder implements LocalMenuBuilderInterface
|
|||||||
if ($this->security->isGranted('ROLE_USER')) {
|
if ($this->security->isGranted('ROLE_USER')) {
|
||||||
$menu->addChild('My calendar list', [
|
$menu->addChild('My calendar list', [
|
||||||
'route' => 'chill_calendar_calendar_list_my',
|
'route' => 'chill_calendar_calendar_list_my',
|
||||||
])
|
|
||||||
->setExtras([
|
|
||||||
'order' => 8,
|
|
||||||
'icon' => 'tasks',
|
|
||||||
]);
|
|
||||||
$menu->addChild('invite.list.title', [
|
|
||||||
'route' => 'chill_calendar_invitations_list_my',
|
|
||||||
])
|
])
|
||||||
->setExtras([
|
->setExtras([
|
||||||
'order' => 9,
|
'order' => 9,
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ namespace Chill\CalendarBundle\Messenger\Doctrine;
|
|||||||
use Chill\CalendarBundle\Entity\Calendar;
|
use Chill\CalendarBundle\Entity\Calendar;
|
||||||
use Chill\CalendarBundle\Messenger\Message\CalendarMessage;
|
use Chill\CalendarBundle\Messenger\Message\CalendarMessage;
|
||||||
use Chill\CalendarBundle\Messenger\Message\CalendarRemovedMessage;
|
use Chill\CalendarBundle\Messenger\Message\CalendarRemovedMessage;
|
||||||
use Chill\MainBundle\Entity\User;
|
|
||||||
use Doctrine\ORM\Event\PostPersistEventArgs;
|
use Doctrine\ORM\Event\PostPersistEventArgs;
|
||||||
use Doctrine\ORM\Event\PostRemoveEventArgs;
|
use Doctrine\ORM\Event\PostRemoveEventArgs;
|
||||||
use Doctrine\ORM\Event\PostUpdateEventArgs;
|
use Doctrine\ORM\Event\PostUpdateEventArgs;
|
||||||
@@ -32,17 +31,6 @@ class CalendarEntityListener
|
|||||||
{
|
{
|
||||||
public function __construct(private readonly MessageBusInterface $messageBus, private readonly Security $security) {}
|
public function __construct(private readonly MessageBusInterface $messageBus, private readonly Security $security) {}
|
||||||
|
|
||||||
private function getAuthenticatedUser(): User
|
|
||||||
{
|
|
||||||
$user = $this->security->getUser();
|
|
||||||
|
|
||||||
if (!$user instanceof User) {
|
|
||||||
throw new \LogicException('Expected an instance of User.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function postPersist(Calendar $calendar, PostPersistEventArgs $args): void
|
public function postPersist(Calendar $calendar, PostPersistEventArgs $args): void
|
||||||
{
|
{
|
||||||
if (!$calendar->preventEnqueueChanges) {
|
if (!$calendar->preventEnqueueChanges) {
|
||||||
@@ -50,7 +38,7 @@ class CalendarEntityListener
|
|||||||
new CalendarMessage(
|
new CalendarMessage(
|
||||||
$calendar,
|
$calendar,
|
||||||
CalendarMessage::CALENDAR_PERSIST,
|
CalendarMessage::CALENDAR_PERSIST,
|
||||||
$this->getAuthenticatedUser()
|
$this->security->getUser()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -62,7 +50,7 @@ class CalendarEntityListener
|
|||||||
$this->messageBus->dispatch(
|
$this->messageBus->dispatch(
|
||||||
new CalendarRemovedMessage(
|
new CalendarRemovedMessage(
|
||||||
$calendar,
|
$calendar,
|
||||||
$this->getAuthenticatedUser()
|
$this->security->getUser()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -70,19 +58,12 @@ class CalendarEntityListener
|
|||||||
|
|
||||||
public function postUpdate(Calendar $calendar, PostUpdateEventArgs $args): void
|
public function postUpdate(Calendar $calendar, PostUpdateEventArgs $args): void
|
||||||
{
|
{
|
||||||
if ($calendar->getStatus() === $calendar::STATUS_CANCELED) {
|
if (!$calendar->preventEnqueueChanges) {
|
||||||
$this->messageBus->dispatch(
|
|
||||||
new CalendarRemovedMessage(
|
|
||||||
$calendar,
|
|
||||||
$this->getAuthenticatedUser()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
} elseif (!$calendar->preventEnqueueChanges) {
|
|
||||||
$this->messageBus->dispatch(
|
$this->messageBus->dispatch(
|
||||||
new CalendarMessage(
|
new CalendarMessage(
|
||||||
$calendar,
|
$calendar,
|
||||||
CalendarMessage::CALENDAR_UPDATE,
|
CalendarMessage::CALENDAR_UPDATE,
|
||||||
$this->getAuthenticatedUser()
|
$this->security->getUser()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,8 +70,6 @@ class CalendarRemovedMessage
|
|||||||
|
|
||||||
public function getRemoteId(): string
|
public function getRemoteId(): string
|
||||||
{
|
{
|
||||||
dump($this->remoteId);
|
|
||||||
|
|
||||||
return $this->remoteId;
|
return $this->remoteId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -191,7 +191,6 @@ class CalendarRepository implements ObjectRepository
|
|||||||
$qb->expr()->eq('c.mainUser', ':user'),
|
$qb->expr()->eq('c.mainUser', ':user'),
|
||||||
$qb->expr()->gte('c.startDate', ':startDate'),
|
$qb->expr()->gte('c.startDate', ':startDate'),
|
||||||
$qb->expr()->lte('c.endDate', ':endDate'),
|
$qb->expr()->lte('c.endDate', ':endDate'),
|
||||||
$qb->expr()->isNull('c.cancelReason'),
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
->setParameters([
|
->setParameters([
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ class InviteRepository implements ObjectRepository
|
|||||||
/**
|
/**
|
||||||
* @return array|Invite[]
|
* @return array|Invite[]
|
||||||
*/
|
*/
|
||||||
public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array
|
public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null)
|
||||||
{
|
{
|
||||||
return $this->entityRepository->findBy($criteria, $orderBy, $limit, $offset);
|
return $this->entityRepository->findBy($criteria, $orderBy, $limit, $offset);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
services:
|
services:
|
||||||
Chill\CalendarBundle\Controller\:
|
Chill\CalendarBundle\Controller\:
|
||||||
autowire: true
|
autowire: true
|
||||||
autoconfigure: true
|
|
||||||
resource: '../../../Controller'
|
resource: '../../../Controller'
|
||||||
tags: ['controller.service_arguments']
|
tags: ['controller.service_arguments']
|
||||||
|
|||||||
@@ -104,8 +104,7 @@
|
|||||||
event.title
|
event.title
|
||||||
}}</b>
|
}}</b>
|
||||||
<b v-else-if="event.extendedProps.is === 'range'"
|
<b v-else-if="event.extendedProps.is === 'range'"
|
||||||
>{{ formatDate(event.startStr, "time") }} -
|
>{{ formatDate(event.startStr) }} - {{ formatDate(event.endStr, 'time') }}:
|
||||||
{{ formatDate(event.endStr, "time") }}:
|
|
||||||
{{ event.extendedProps.locationName }}</b
|
{{ event.extendedProps.locationName }}</b
|
||||||
>
|
>
|
||||||
<b v-else-if="event.extendedProps.is === 'local'">{{
|
<b v-else-if="event.extendedProps.is === 'local'">{{
|
||||||
@@ -297,25 +296,25 @@ const nextWeeks = computed((): Weeks[] =>
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
const formatDate = (datetime: string, format: null | "time" = null) => {
|
const formatDate = (datetime: string, format: null | 'time' = null) => {
|
||||||
const date = ISOToDate(datetime);
|
const date = ISOToDate(datetime);
|
||||||
if (!date) return "";
|
if (!date) return '';
|
||||||
|
|
||||||
if (format === "time") {
|
if (format === 'time') {
|
||||||
return date.toLocaleTimeString("fr-FR", {
|
return date.toLocaleTimeString('fr-FR', {
|
||||||
hour: "2-digit",
|
hour: '2-digit',
|
||||||
minute: "2-digit",
|
minute: '2-digit'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// French date formatting
|
// French date formatting
|
||||||
return date.toLocaleDateString("fr-FR", {
|
return date.toLocaleDateString('fr-FR', {
|
||||||
weekday: "short",
|
weekday: 'short',
|
||||||
year: "numeric",
|
year: 'numeric',
|
||||||
month: "short",
|
month: 'short',
|
||||||
day: "numeric",
|
day: 'numeric',
|
||||||
hour: "2-digit",
|
hour: '2-digit',
|
||||||
minute: "2-digit",
|
minute: '2-digit'
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,17 @@
|
|||||||
{# list used in context of person, accompanyingPeriod or user #}
|
{# list used in context of person or accompanyingPeriod #}
|
||||||
|
|
||||||
<div class="item-bloc">
|
{% if calendarItems|length > 0 %}
|
||||||
<div class="item-row main">
|
<div class="flex-table list-records context-accompanyingCourse">
|
||||||
<div class="item-col">
|
|
||||||
<div class="wrap-header">
|
{% for calendar in calendarItems %}
|
||||||
<div class="wl-row">
|
|
||||||
{% if calendar.status == 'canceled' %}
|
<div class="item-bloc">
|
||||||
<div class="badge rounded-pill bg-danger">
|
<div class="item-row main">
|
||||||
<span>{{ 'chill_calendar.canceled'|trans }}: </span>
|
<div class="item-col">
|
||||||
<span>{{ calendar.cancelReason.name|localize_translatable_string }}</span>
|
<div class="wrap-header">
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
<div class="wl-row">
|
<div class="wl-row">
|
||||||
<div class="wl-col title">
|
<div class="wl-col title">
|
||||||
<p class="date-label">
|
<p class="date-label">
|
||||||
{% if calendar.status == 'canceled' %}
|
|
||||||
<del>
|
|
||||||
{% endif %}
|
|
||||||
{% if context == 'person' and calendar.context == 'accompanying_period' %}
|
{% if context == 'person' and calendar.context == 'accompanying_period' %}
|
||||||
<a href="{{ chill_path_add_return_path('chill_person_accompanying_course_index', {'accompanying_period_id': calendar.accompanyingPeriod.id}) }}" style="text-decoration: none;">
|
<a href="{{ chill_path_add_return_path('chill_person_accompanying_course_index', {'accompanying_period_id': calendar.accompanyingPeriod.id}) }}" style="text-decoration: none;">
|
||||||
<span class="badge bg-primary">
|
<span class="badge bg-primary">
|
||||||
@@ -25,9 +19,6 @@
|
|||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if calendar.status == 'canceled' %}
|
|
||||||
<del>
|
|
||||||
{% endif %}
|
|
||||||
{% if calendar.endDate.diff(calendar.startDate).days >= 1 %}
|
{% if calendar.endDate.diff(calendar.startDate).days >= 1 %}
|
||||||
{{ calendar.startDate|format_datetime('short', 'short') }}
|
{{ calendar.startDate|format_datetime('short', 'short') }}
|
||||||
- {{ calendar.endDate|format_datetime('short', 'short') }}
|
- {{ calendar.endDate|format_datetime('short', 'short') }}
|
||||||
@@ -35,46 +26,44 @@
|
|||||||
{{ calendar.startDate|format_datetime('short', 'short') }}
|
{{ calendar.startDate|format_datetime('short', 'short') }}
|
||||||
- {{ calendar.endDate|format_datetime('none', 'short') }}
|
- {{ calendar.endDate|format_datetime('none', 'short') }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if calendar.status == 'canceled' %}
|
</p>
|
||||||
</del>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<div class="duration short-message">
|
<div class="duration short-message">
|
||||||
<i class="fa fa-fw fa-hourglass-end"></i>
|
<i class="fa fa-fw fa-hourglass-end"></i>
|
||||||
{{ calendar.duration|date('%H:%I') }}
|
{{ calendar.duration|date('%H:%I') }}
|
||||||
{% if false == calendar.sendSMS or null == calendar.sendSMS %}
|
{% if false == calendar.sendSMS or null == calendar.sendSMS %}
|
||||||
<!-- no sms will be sent -->
|
<!-- no sms will be send -->
|
||||||
{% else %}
|
{% else %}
|
||||||
{% if calendar.smsStatus == 'sms_sent' %}
|
{% if calendar.smsStatus == 'sms_sent' %}
|
||||||
<span title="{{ 'SMS already sent'|trans }}" class="badge bg-info">
|
<span title="{{ 'SMS already sent'|trans }}" class="badge bg-info">
|
||||||
<i class="fa fa-check "></i>
|
<i class="fa fa-check "></i>
|
||||||
<i class="fa fa-envelope "></i>
|
<i class="fa fa-envelope "></i>
|
||||||
</span>
|
</span>
|
||||||
{% else %}
|
{% else %}
|
||||||
<span title="{{ 'Will send SMS'|trans }}" class="badge bg-info">
|
<span title="{{ 'Will send SMS'|trans }}" class="badge bg-info">
|
||||||
<i class="fa fa-envelope "></i>
|
<i class="fa fa-envelope "></i>
|
||||||
<i class="fa fa-hourglass-end "></i>
|
<i class="fa fa-hourglass-end "></i>
|
||||||
</span>
|
</span>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="item-col">
|
||||||
|
<ul class="list-content">
|
||||||
|
{% if calendar.mainUser is not empty %}
|
||||||
|
<span class="badge-user">{{ calendar.mainUser|chill_entity_render_box({'at_date': calendar.startDate}) }}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="item-col">
|
{% if calendar.comment.comment is not empty
|
||||||
<ul class="list-content">
|
|
||||||
{% if calendar.mainUser is not empty %}
|
|
||||||
<span class="badge-user">{{ calendar.mainUser|chill_entity_render_box({'at_date': calendar.startDate}) }}</span>
|
|
||||||
{% endif %}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% if calendar.comment.comment is not empty
|
|
||||||
or calendar.users|length > 0
|
or calendar.users|length > 0
|
||||||
or calendar.thirdParties|length > 0
|
or calendar.thirdParties|length > 0
|
||||||
or calendar.users|length > 0 %}
|
or calendar.users|length > 0 %}
|
||||||
@@ -87,133 +76,131 @@
|
|||||||
} %}
|
} %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if calendar.comment.comment is not empty %}
|
|
||||||
<div class="item-row details separator">
|
|
||||||
<div class="item-col comment">
|
|
||||||
{{ calendar.comment|chill_entity_render_box( { 'limit_lines': 3, 'metadata': false } ) }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if calendar.location is not empty %}
|
|
||||||
<div class="item-row separator">
|
|
||||||
<div>
|
|
||||||
{% if calendar.location.address is not same as(null) and calendar.location.name is not empty %}
|
|
||||||
<i class="fa fa-map-marker"></i>{% endif %}
|
|
||||||
{% if calendar.location.name is not empty %}{{ calendar.location.name }}{% endif %}
|
|
||||||
{% if calendar.location.address is not same as(null) %}{{ calendar.location.address|chill_entity_render_box({'multiline': false, 'with_picto': (calendar.location.name is empty)}) }}{% else %}
|
|
||||||
<i class="fa fa-map-marker"></i>{% endif %}
|
|
||||||
{% if calendar.location.phonenumber1 is not empty %}<i
|
|
||||||
class="fa fa-phone"></i> {{ calendar.location.phonenumber1|chill_format_phonenumber }}{% endif %}
|
|
||||||
{% if calendar.location.phonenumber2 is not empty %}<i
|
|
||||||
class="fa fa-phone"></i> {{ calendar.location.phonenumber2|chill_format_phonenumber }}{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if calendar.documents is not empty %}
|
|
||||||
<div class="item-row separator column">
|
|
||||||
<div>
|
|
||||||
{{ include('@ChillCalendar/Calendar/_documents.twig.html') }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if calendar.activity is not null %}
|
|
||||||
<div class="item-row separator">
|
|
||||||
<div class="item-col">
|
|
||||||
<div class="wrap-list">
|
|
||||||
<div class="wl-row">
|
|
||||||
<div class="wl-col title"><h3>{{ 'Activity'|trans }}</h3></div>
|
|
||||||
<div class="wl-col list activity-linked">
|
|
||||||
<h2 class="badge-title">
|
|
||||||
<span class="title_label"></span>
|
|
||||||
<span class="title_action">
|
|
||||||
{{ calendar.activity.type.name | localize_translatable_string }}
|
|
||||||
|
|
||||||
{% if calendar.activity.emergency %}
|
|
||||||
<span class="badge bg-danger rounded-pill fs-6 float-end">{{ 'Emergency'|trans|upper }}</span>
|
|
||||||
{% endif %}
|
|
||||||
</span>
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<ul class="record_actions">
|
|
||||||
<li class="cancel">
|
|
||||||
<span class="createdBy">
|
|
||||||
{{ 'Created by'|trans }}
|
|
||||||
<b>{{ calendar.activity.createdBy|chill_entity_render_string({'at_date': calendar.activity.createdAt}) }}</b>, {{ 'on'|trans }} {{ calendar.activity.createdAt|format_datetime('short', 'short') }}
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
{% if is_granted('CHILL_ACTIVITY_SEE', calendar.activity) %}
|
|
||||||
<li>
|
|
||||||
<a href="{{ chill_path_add_return_path('chill_activity_activity_show', {'id': calendar.activity.id}) }}" class="btn btn-sm btn-show" ></a>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
|
{% if calendar.comment.comment is not empty %}
|
||||||
|
<div class="item-row details separator">
|
||||||
|
<div class="item-col comment">
|
||||||
|
{{ calendar.comment|chill_entity_render_box( { 'limit_lines': 3, 'metadata': false } ) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<div class="item-row separator">
|
|
||||||
<ul class="record_actions">
|
|
||||||
{% if is_granted('CHILL_CALENDAR_DOC_EDIT', calendar) and calendar.status is not constant('STATUS_CANCELED', calendar) %}
|
|
||||||
{% if templates|length == 0 %}
|
|
||||||
<li>
|
|
||||||
<a class="btn btn-create"
|
|
||||||
href="{{ chill_path_add_return_path('chill_calendar_calendardoc_new', {'id': calendar.id }) }}">
|
|
||||||
{{ 'chill_calendar.Add a document'|trans }}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{% else %}
|
|
||||||
<li>
|
|
||||||
<div class="dropdown">
|
|
||||||
<button class="btn btn-create dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
|
||||||
{{ 'chill_calendar.Add a document'|trans }}
|
|
||||||
</button>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item"
|
|
||||||
href="{{ chill_path_add_return_path('chill_calendar_calendardoc_new', {'id': calendar.id }) }}">
|
|
||||||
{{ 'chill_calendar.Upload a document'|trans }}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{% for template in templates %}
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item"
|
|
||||||
href="{{ chill_path_add_return_path('chill_docgenerator_generate_from_template', {'template': template.id, 'entityClassName': 'Chill\\CalendarBundle\\Entity\\Calendar', 'entityId': calendar.id}) }}"
|
|
||||||
>
|
|
||||||
{{ template.name|localize_translatable_string }}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if calendar.activity is null and (
|
|
||||||
(calendar.context == 'accompanying_period' and is_granted('CHILL_ACTIVITY_CREATE', calendar.accompanyingPeriod))
|
|
||||||
or
|
|
||||||
(calendar.context == 'person' and is_granted('CHILL_ACTIVITY_CREATE', calendar.person))
|
|
||||||
)
|
|
||||||
and calendar.status is not constant('STATUS_CANCELED', calendar)
|
|
||||||
%}
|
|
||||||
<li>
|
|
||||||
<a class="btn btn-create"
|
|
||||||
href="{{ chill_path_add_return_path('chill_calendar_calendar_to_activity', { 'id': calendar.id }) }}">
|
|
||||||
{{ 'Transform to activity'|trans }}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if calendar.isInvited(app.user) and not calendar.isCanceled %}
|
{% if calendar.location is not empty %}
|
||||||
|
<div class="item-row separator">
|
||||||
|
<div>
|
||||||
|
{% if calendar.location.address is not same as(null) and calendar.location.name is not empty %}
|
||||||
|
<i class="fa fa-map-marker"></i>{% endif %}
|
||||||
|
{% if calendar.location.name is not empty %}{{ calendar.location.name }}{% endif %}
|
||||||
|
{% if calendar.location.address is not same as(null) %}{{ calendar.location.address|chill_entity_render_box({'multiline': false, 'with_picto': (calendar.location.name is empty)}) }}{% else %}
|
||||||
|
<i class="fa fa-map-marker"></i>{% endif %}
|
||||||
|
{% if calendar.location.phonenumber1 is not empty %}<i
|
||||||
|
class="fa fa-phone"></i> {{ calendar.location.phonenumber1|chill_format_phonenumber }}{% endif %}
|
||||||
|
{% if calendar.location.phonenumber2 is not empty %}<i
|
||||||
|
class="fa fa-phone"></i> {{ calendar.location.phonenumber2|chill_format_phonenumber }}{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div class="item-row separator column">
|
||||||
|
<div>
|
||||||
|
|
||||||
|
{{ include('@ChillCalendar/Calendar/_documents.twig.html') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% if calendar.activity is not null %}
|
||||||
|
<div class="item-row separator">
|
||||||
|
<div class="item-col">
|
||||||
|
<div class="wrap-list">
|
||||||
|
<div class="wl-row">
|
||||||
|
<div class="wl-col title"><h3>{{ 'Activity'|trans }}</h3></div>
|
||||||
|
<div class="wl-col list activity-linked">
|
||||||
|
<h2 class="badge-title">
|
||||||
|
<span class="title_label"></span>
|
||||||
|
<span class="title_action">
|
||||||
|
{{ calendar.activity.type.name | localize_translatable_string }}
|
||||||
|
|
||||||
|
{% if calendar.activity.emergency %}
|
||||||
|
<span class="badge bg-danger rounded-pill fs-6 float-end">{{ 'Emergency'|trans|upper }}</span>
|
||||||
|
{% endif %}
|
||||||
|
</span>
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<ul class="record_actions">
|
||||||
|
<li class="cancel">
|
||||||
|
<span class="createdBy">
|
||||||
|
{{ 'Created by'|trans }}
|
||||||
|
<b>{{ calendar.activity.createdBy|chill_entity_render_string({'at_date': calendar.activity.createdAt}) }}</b>, {{ 'on'|trans }} {{ calendar.activity.createdAt|format_datetime('short', 'short') }}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
{% if is_granted('CHILL_ACTIVITY_SEE', calendar.activity) %}
|
||||||
|
<li>
|
||||||
|
<a href="{{ chill_path_add_return_path('chill_activity_activity_show', {'id': calendar.activity.id}) }}" class="btn btn-sm btn-show" ></a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div class="item-row separator">
|
||||||
|
<ul class="record_actions">
|
||||||
|
{% if is_granted('CHILL_CALENDAR_DOC_EDIT', calendar) %}
|
||||||
|
{% if templates|length == 0 %}
|
||||||
|
<li>
|
||||||
|
<a class="btn btn-create"
|
||||||
|
href="{{ chill_path_add_return_path('chill_calendar_calendardoc_new', {'id': calendar.id }) }}">
|
||||||
|
{{ 'chill_calendar.Add a document'|trans }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% else %}
|
||||||
|
<li>
|
||||||
|
<div class="dropdown">
|
||||||
|
<button class="btn btn-create dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
|
{{ 'chill_calendar.Add a document'|trans }}
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<li>
|
||||||
|
<a class="dropdown-item"
|
||||||
|
href="{{ chill_path_add_return_path('chill_calendar_calendardoc_new', {'id': calendar.id }) }}">
|
||||||
|
{{ 'chill_calendar.Upload a document'|trans }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% for template in templates %}
|
||||||
|
<li>
|
||||||
|
<a class="dropdown-item"
|
||||||
|
href="{{ chill_path_add_return_path('chill_docgenerator_generate_from_template', {'template': template.id, 'entityClassName': 'Chill\\CalendarBundle\\Entity\\Calendar', 'entityId': calendar.id}) }}"
|
||||||
|
>
|
||||||
|
{{ template.name|localize_translatable_string }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if calendar.activity is null and (
|
||||||
|
(calendar.context == 'accompanying_period' and is_granted('CHILL_ACTIVITY_CREATE', calendar.accompanyingPeriod))
|
||||||
|
or
|
||||||
|
(calendar.context == 'person' and is_granted('CHILL_ACTIVITY_CREATE', calendar.person))
|
||||||
|
)
|
||||||
|
%}
|
||||||
|
<li>
|
||||||
|
<a class="btn btn-create"
|
||||||
|
href="{{ chill_path_add_return_path('chill_calendar_calendar_to_activity', { 'id': calendar.id }) }}">
|
||||||
|
{{ 'Transform to activity'|trans }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if (calendar.isInvited(app.user)) %}
|
||||||
{% set invite = calendar.inviteForUser(app.user) %}
|
{% set invite = calendar.inviteForUser(app.user) %}
|
||||||
<li>
|
<li>
|
||||||
<div invite-answer data-status="{{ invite.status|e('html_attr') }}"
|
<div invite-answer data-status="{{ invite.status|e('html_attr') }}"
|
||||||
@@ -226,18 +213,12 @@
|
|||||||
class="btn btn-show "></a>
|
class="btn btn-show "></a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if is_granted('CHILL_CALENDAR_CALENDAR_EDIT', calendar) %}
|
||||||
{% if is_granted('CHILL_CALENDAR_CALENDAR_EDIT', calendar) and calendar.status is not constant('STATUS_CANCELED', calendar) %}
|
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ chill_path_add_return_path('chill_calendar_calendar_edit', { 'id': calendar.id }) }}"
|
<a href="{{ chill_path_add_return_path('chill_calendar_calendar_edit', { 'id': calendar.id }) }}"
|
||||||
class="btn btn-update "></a>
|
class="btn btn-update "></a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
|
||||||
<a href="{{ chill_path_add_return_path('chill_calendar_calendar_cancel', { 'id': calendar.id } ) }}"
|
|
||||||
class="btn btn-action"><i class="bi bi-x-circle"></i> {{ 'Cancel'|trans }}</a>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if is_granted('CHILL_CALENDAR_CALENDAR_DELETE', calendar) %}
|
{% if is_granted('CHILL_CALENDAR_CALENDAR_DELETE', calendar) %}
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ chill_path_add_return_path('chill_calendar_calendar_delete', { 'id': calendar.id } ) }}"
|
<a href="{{ chill_path_add_return_path('chill_calendar_calendar_delete', { 'id': calendar.id } ) }}"
|
||||||
@@ -246,8 +227,14 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% if calendarItems|length < paginator.getTotalItems %}
|
||||||
|
{{ chill_pagination(paginator) }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
{% endif %}
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
{% extends "@ChillPerson/AccompanyingCourse/layout.html.twig" %}
|
|
||||||
|
|
||||||
{% set activeRouteKey = 'chill_calendar_calendar_list' %}
|
|
||||||
|
|
||||||
{% block title 'chill_calendar.cancel_calendar_item'|trans %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
|
|
||||||
{{ form_start(form) }}
|
|
||||||
|
|
||||||
{{ form_row(form.cancelReason) }}
|
|
||||||
|
|
||||||
<ul class="record_actions sticky-form-buttons">
|
|
||||||
<li class="cancel">
|
|
||||||
<a
|
|
||||||
class="btn btn-cancel"
|
|
||||||
href="{{ chill_return_path_or('chill_calendar_calendar_list', { 'id': accompanyingCourse.id } )}}"
|
|
||||||
>
|
|
||||||
{{ 'Cancel'|trans|chill_return_path_label }}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
{{ form_widget(form.submit, { 'attr' : { 'class': 'btn btn-save' }, 'label': 'Save' } ) }}
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
{{ form_end(form) }}
|
|
||||||
|
|
||||||
{% endblock %}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
{% extends "@ChillPerson/Person/layout.html.twig" %}
|
|
||||||
|
|
||||||
{% set activeRouteKey = 'chill_calendar_calendar_list' %}
|
|
||||||
|
|
||||||
{% block title 'chill_calendar.cancel_calendar_item'|trans %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
|
|
||||||
{{ form_start(form) }}
|
|
||||||
|
|
||||||
{{ form_row(form.cancelReason) }}
|
|
||||||
|
|
||||||
<ul class="record_actions sticky-form-buttons">
|
|
||||||
<li class="cancel">
|
|
||||||
<a
|
|
||||||
class="btn btn-cancel"
|
|
||||||
href="{{ chill_return_path_or('chill_calendar_calendar_list', { 'id': person.id } )}}"
|
|
||||||
>
|
|
||||||
{{ 'Cancel'|trans|chill_return_path_label }}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
{{ form_widget(form.submit, { 'attr' : { 'class': 'btn btn-save' }, 'label': 'Save' } ) }}
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
{{ form_end(form) }}
|
|
||||||
|
|
||||||
{% endblock %}
|
|
||||||
@@ -34,18 +34,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</p>
|
</p>
|
||||||
{% else %}
|
{% else %}
|
||||||
{% if calendarItems|length > 0 %}
|
{{ include('@ChillCalendar/Calendar/_list.html.twig', {context: 'accompanying_course'}) }}
|
||||||
<div class="flex-table list-records context-accompanyingCourse">
|
|
||||||
{% for calendar in calendarItems %}
|
|
||||||
{{ include('@ChillCalendar/Calendar/_list.html.twig', {context: 'accompanying_course'}) }}
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% if calendarItems|length < paginator.getTotalItems %}
|
|
||||||
{{ chill_pagination(paginator) }}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<ul class="record_actions sticky-form-buttons">
|
<ul class="record_actions sticky-form-buttons">
|
||||||
|
|||||||
@@ -33,17 +33,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</p>
|
</p>
|
||||||
{% else %}
|
{% else %}
|
||||||
{% if calendarItems|length > 0 %}
|
{{ include ('@ChillCalendar/Calendar/_list.html.twig', {context: 'person'}) }}
|
||||||
<div class="flex-table list-records context-person">
|
|
||||||
{% for calendar in calendarItems %}
|
|
||||||
{{ include ('@ChillCalendar/Calendar/_list.html.twig', {context: 'person'}) }}
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% if calendarItems|length < paginator.getTotalItems %}
|
|
||||||
{{ chill_pagination(paginator) }}
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<ul class="record_actions sticky-form-buttons">
|
<ul class="record_actions sticky-form-buttons">
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
{% block table_entities_thead_tr %}
|
{% block table_entities_thead_tr %}
|
||||||
<th>{{ 'Id'|trans }}</th>
|
<th>{{ 'Id'|trans }}</th>
|
||||||
<th>{{ 'Name'|trans }}</th>
|
<th>{{ 'Name'|trans }}</th>
|
||||||
<th>{{ 'Canceled by'|trans }}</th>
|
<th>{{ 'canceledBy'|trans }}</th>
|
||||||
<th>{{ 'active'|trans }}</th>
|
<th>{{ 'active'|trans }}</th>
|
||||||
<th> </th>
|
<th> </th>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
{% extends "@ChillMain/layout.html.twig" %}
|
|
||||||
|
|
||||||
{% set activeRouteKey = 'chill_calendar_invitations_list' %}
|
|
||||||
|
|
||||||
{% block title %}{{ 'invite.list.title'|trans }}{% endblock title %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
|
|
||||||
<h1>{{ 'invite.list.title'|trans }}</h1>
|
|
||||||
|
|
||||||
{% if invitations|length == 0 %}
|
|
||||||
<p class="chill-no-data-statement">
|
|
||||||
{{ "invite.list.none"|trans }}
|
|
||||||
</p>
|
|
||||||
{% else %}
|
|
||||||
<div class="flex-table list-records">
|
|
||||||
{% for invitation in invitations %}
|
|
||||||
{% set calendar = invitation.getCalendar %}
|
|
||||||
{{ include('@ChillCalendar/Calendar/_list.html.twig', {context: 'user'}) }}
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% if invitations|length < paginator.getTotalItems %}
|
|
||||||
{{ chill_pagination(paginator) }}
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block js %}
|
|
||||||
{{ parent() }}
|
|
||||||
{{ encore_entry_script_tags('mod_answer') }}
|
|
||||||
{{ encore_entry_script_tags('mod_document_action_buttons_group') }}
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block css %}
|
|
||||||
{{ parent() }}
|
|
||||||
{{ encore_entry_link_tags('mod_answer') }}
|
|
||||||
{{ encore_entry_link_tags('mod_document_action_buttons_group') }}
|
|
||||||
{% endblock %}
|
|
||||||
@@ -19,7 +19,6 @@ declare(strict_types=1);
|
|||||||
namespace Chill\CalendarBundle\Service\ShortMessageNotification;
|
namespace Chill\CalendarBundle\Service\ShortMessageNotification;
|
||||||
|
|
||||||
use Chill\CalendarBundle\Entity\Calendar;
|
use Chill\CalendarBundle\Entity\Calendar;
|
||||||
use Chill\CalendarBundle\Entity\CancelReason;
|
|
||||||
use libphonenumber\PhoneNumberFormat;
|
use libphonenumber\PhoneNumberFormat;
|
||||||
use libphonenumber\PhoneNumberUtil;
|
use libphonenumber\PhoneNumberUtil;
|
||||||
use Symfony\Component\Notifier\Message\SmsMessage;
|
use Symfony\Component\Notifier\Message\SmsMessage;
|
||||||
@@ -58,7 +57,7 @@ class DefaultShortMessageForCalendarBuilder implements ShortMessageForCalendarBu
|
|||||||
$this->phoneUtil->format($person->getMobilenumber(), PhoneNumberFormat::E164),
|
$this->phoneUtil->format($person->getMobilenumber(), PhoneNumberFormat::E164),
|
||||||
$this->engine->render('@ChillCalendar/CalendarShortMessage/short_message.txt.twig', ['calendar' => $calendar]),
|
$this->engine->render('@ChillCalendar/CalendarShortMessage/short_message.txt.twig', ['calendar' => $calendar]),
|
||||||
);
|
);
|
||||||
} elseif (Calendar::SMS_CANCEL_PENDING === $calendar->getSmsStatus() && (null === $calendar->getCancelReason() || CancelReason::CANCELEDBY_PERSON !== $calendar->getCancelReason()->getCanceledBy())) {
|
} elseif (Calendar::SMS_CANCEL_PENDING === $calendar->getSmsStatus()) {
|
||||||
$toUsers[] = new SmsMessage(
|
$toUsers[] = new SmsMessage(
|
||||||
$this->phoneUtil->format($person->getMobilenumber(), PhoneNumberFormat::E164),
|
$this->phoneUtil->format($person->getMobilenumber(), PhoneNumberFormat::E164),
|
||||||
$this->engine->render('@ChillCalendar/CalendarShortMessage/short_message_canceled.txt.twig', ['calendar' => $calendar]),
|
$this->engine->render('@ChillCalendar/CalendarShortMessage/short_message_canceled.txt.twig', ['calendar' => $calendar]),
|
||||||
|
|||||||
@@ -1,292 +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\CalendarBundle\Tests\Controller;
|
|
||||||
|
|
||||||
use Chill\CalendarBundle\Controller\MyInvitationsController;
|
|
||||||
use Chill\CalendarBundle\Entity\Calendar;
|
|
||||||
use Chill\CalendarBundle\Entity\Invite;
|
|
||||||
use Chill\CalendarBundle\Repository\InviteRepository;
|
|
||||||
use Chill\DocGeneratorBundle\Repository\DocGeneratorTemplateRepositoryInterface;
|
|
||||||
use Chill\MainBundle\Entity\User;
|
|
||||||
use Chill\MainBundle\Pagination\PaginatorFactory;
|
|
||||||
use Chill\MainBundle\Pagination\PaginatorInterface;
|
|
||||||
use PHPUnit\Framework\TestCase;
|
|
||||||
use Prophecy\PhpUnit\ProphecyTrait;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
|
||||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
|
||||||
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
|
|
||||||
use Twig\Environment;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*
|
|
||||||
* @coversNothing
|
|
||||||
*/
|
|
||||||
final class MyInvitationsControllerTest extends TestCase
|
|
||||||
{
|
|
||||||
use ProphecyTrait;
|
|
||||||
|
|
||||||
private MyInvitationsController $controller;
|
|
||||||
|
|
||||||
protected function setUp(): void
|
|
||||||
{
|
|
||||||
// Create prophecies for dependencies
|
|
||||||
$inviteRepository = $this->prophesize(InviteRepository::class);
|
|
||||||
$paginatorFactory = $this->prophesize(PaginatorFactory::class);
|
|
||||||
$docGeneratorTemplateRepository = $this->prophesize(DocGeneratorTemplateRepositoryInterface::class);
|
|
||||||
|
|
||||||
// Create controller instance
|
|
||||||
$this->controller = new MyInvitationsController(
|
|
||||||
$inviteRepository->reveal(),
|
|
||||||
$paginatorFactory->reveal(),
|
|
||||||
$docGeneratorTemplateRepository->reveal()
|
|
||||||
);
|
|
||||||
|
|
||||||
// Set up necessary services for AbstractController
|
|
||||||
$authorizationChecker = $this->prophesize(AuthorizationCheckerInterface::class);
|
|
||||||
$tokenStorage = $this->prophesize(TokenStorageInterface::class);
|
|
||||||
$twig = $this->prophesize(Environment::class);
|
|
||||||
|
|
||||||
// Use reflection to set the container
|
|
||||||
$reflection = new \ReflectionClass($this->controller);
|
|
||||||
$containerProperty = $reflection->getParentClass()->getProperty('container');
|
|
||||||
$containerProperty->setAccessible(true);
|
|
||||||
|
|
||||||
// Create a mock container
|
|
||||||
$container = $this->prophesize(\Psr\Container\ContainerInterface::class);
|
|
||||||
$container->has('security.authorization_checker')->willReturn(true);
|
|
||||||
$container->get('security.authorization_checker')->willReturn($authorizationChecker->reveal());
|
|
||||||
$container->has('security.token_storage')->willReturn(true);
|
|
||||||
$container->get('security.token_storage')->willReturn($tokenStorage->reveal());
|
|
||||||
$container->has('twig')->willReturn(true);
|
|
||||||
$container->get('twig')->willReturn($twig->reveal());
|
|
||||||
|
|
||||||
$containerProperty->setValue($this->controller, $container->reveal());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testMyInvitationsReturnsCorrectAmountOfInvitations(): void
|
|
||||||
{
|
|
||||||
// Create test user
|
|
||||||
$user = new User();
|
|
||||||
$user->setUsername('testuser');
|
|
||||||
|
|
||||||
// Create test invitations
|
|
||||||
$invite1 = new Invite();
|
|
||||||
$invite1->setUser($user);
|
|
||||||
$invite1->setStatus(Invite::PENDING);
|
|
||||||
|
|
||||||
$invite2 = new Invite();
|
|
||||||
$invite2->setUser($user);
|
|
||||||
$invite2->setStatus(Invite::ACCEPTED);
|
|
||||||
|
|
||||||
$invite3 = new Invite();
|
|
||||||
$invite3->setUser($user);
|
|
||||||
$invite3->setStatus(Invite::DECLINED);
|
|
||||||
|
|
||||||
$allInvitations = [$invite1, $invite2, $invite3];
|
|
||||||
$paginatedInvitations = [$invite1, $invite2]; // First page with 2 items per page
|
|
||||||
|
|
||||||
// Set up repository prophecies
|
|
||||||
$inviteRepository = $this->prophesize(InviteRepository::class);
|
|
||||||
$inviteRepository->findBy(['user' => $user])->willReturn($allInvitations);
|
|
||||||
$inviteRepository->findBy(
|
|
||||||
['user' => $user],
|
|
||||||
['createdAt' => 'DESC'],
|
|
||||||
2, // items per page
|
|
||||||
0 // offset
|
|
||||||
)->willReturn($paginatedInvitations);
|
|
||||||
|
|
||||||
// Set up paginator prophecies
|
|
||||||
$paginator = $this->prophesize(PaginatorInterface::class);
|
|
||||||
$paginator->getItemsPerPage()->willReturn(2);
|
|
||||||
$paginator->getCurrentPageFirstItemNumber()->willReturn(0);
|
|
||||||
|
|
||||||
$paginatorFactory = $this->prophesize(PaginatorFactory::class);
|
|
||||||
$paginatorFactory->create(3)->willReturn($paginator->reveal());
|
|
||||||
|
|
||||||
// Set up doc generator repository
|
|
||||||
$docGeneratorTemplateRepository = $this->prophesize(DocGeneratorTemplateRepositoryInterface::class);
|
|
||||||
$docGeneratorTemplateRepository->findByEntity(Calendar::class)->willReturn([]);
|
|
||||||
|
|
||||||
// Create controller with mocked dependencies
|
|
||||||
$controller = new MyInvitationsController(
|
|
||||||
$inviteRepository->reveal(),
|
|
||||||
$paginatorFactory->reveal(),
|
|
||||||
$docGeneratorTemplateRepository->reveal()
|
|
||||||
);
|
|
||||||
|
|
||||||
// Set up authorization checker to return true for ROLE_USER
|
|
||||||
$authorizationChecker = $this->prophesize(AuthorizationCheckerInterface::class);
|
|
||||||
$authorizationChecker->isGranted('ROLE_USER', null)->willReturn(true);
|
|
||||||
|
|
||||||
// Set up token storage to return user
|
|
||||||
$token = $this->prophesize(TokenInterface::class);
|
|
||||||
$token->getUser()->willReturn($user);
|
|
||||||
$tokenStorage = $this->prophesize(TokenStorageInterface::class);
|
|
||||||
$tokenStorage->getToken()->willReturn($token->reveal());
|
|
||||||
|
|
||||||
// Set up twig to return a response
|
|
||||||
$twig = $this->prophesize(Environment::class);
|
|
||||||
$twig->render('@ChillCalendar/Invitations/listByUser.html.twig', [
|
|
||||||
'invitations' => $paginatedInvitations,
|
|
||||||
'paginator' => $paginator->reveal(),
|
|
||||||
'templates' => [],
|
|
||||||
])->willReturn('rendered content');
|
|
||||||
|
|
||||||
// Set up container
|
|
||||||
$container = $this->prophesize(\Psr\Container\ContainerInterface::class);
|
|
||||||
$container->has('security.authorization_checker')->willReturn(true);
|
|
||||||
$container->get('security.authorization_checker')->willReturn($authorizationChecker->reveal());
|
|
||||||
$container->has('security.token_storage')->willReturn(true);
|
|
||||||
$container->get('security.token_storage')->willReturn($tokenStorage->reveal());
|
|
||||||
$container->has('twig')->willReturn(true);
|
|
||||||
$container->get('twig')->willReturn($twig->reveal());
|
|
||||||
|
|
||||||
// Use reflection to set the container
|
|
||||||
$reflection = new \ReflectionClass($controller);
|
|
||||||
$containerProperty = $reflection->getParentClass()->getProperty('container');
|
|
||||||
$containerProperty->setAccessible(true);
|
|
||||||
$containerProperty->setValue($controller, $container->reveal());
|
|
||||||
|
|
||||||
// Create request
|
|
||||||
$request = new Request();
|
|
||||||
|
|
||||||
// Execute the action
|
|
||||||
$response = $controller->myInvitations($request);
|
|
||||||
|
|
||||||
// Assert that response is successful
|
|
||||||
self::assertInstanceOf(Response::class, $response);
|
|
||||||
self::assertSame(200, $response->getStatusCode());
|
|
||||||
self::assertSame('rendered content', $response->getContent());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testMyInvitationsPageLoads(): void
|
|
||||||
{
|
|
||||||
// Create test user
|
|
||||||
$user = new User();
|
|
||||||
$user->setUsername('testuser');
|
|
||||||
|
|
||||||
// Set up repository prophecies - no invitations
|
|
||||||
$inviteRepository = $this->prophesize(InviteRepository::class);
|
|
||||||
$inviteRepository->findBy(['user' => $user])->willReturn([]);
|
|
||||||
$inviteRepository->findBy(
|
|
||||||
['user' => $user],
|
|
||||||
['createdAt' => 'DESC'],
|
|
||||||
20, // default items per page
|
|
||||||
0 // offset
|
|
||||||
)->willReturn([]);
|
|
||||||
|
|
||||||
// Set up paginator prophecies
|
|
||||||
$paginator = $this->prophesize(PaginatorInterface::class);
|
|
||||||
$paginator->getItemsPerPage()->willReturn(20);
|
|
||||||
$paginator->getCurrentPageFirstItemNumber()->willReturn(0);
|
|
||||||
|
|
||||||
$paginatorFactory = $this->prophesize(PaginatorFactory::class);
|
|
||||||
$paginatorFactory->create(0)->willReturn($paginator->reveal());
|
|
||||||
|
|
||||||
// Set up doc generator repository
|
|
||||||
$docGeneratorTemplateRepository = $this->prophesize(DocGeneratorTemplateRepositoryInterface::class);
|
|
||||||
$docGeneratorTemplateRepository->findByEntity(Calendar::class)->willReturn([]);
|
|
||||||
|
|
||||||
// Create controller with mocked dependencies
|
|
||||||
$controller = new MyInvitationsController(
|
|
||||||
$inviteRepository->reveal(),
|
|
||||||
$paginatorFactory->reveal(),
|
|
||||||
$docGeneratorTemplateRepository->reveal()
|
|
||||||
);
|
|
||||||
|
|
||||||
// Set up authorization checker to return true for ROLE_USER
|
|
||||||
$authorizationChecker = $this->prophesize(AuthorizationCheckerInterface::class);
|
|
||||||
$authorizationChecker->isGranted('ROLE_USER', null)->willReturn(true);
|
|
||||||
|
|
||||||
// Set up token storage to return user
|
|
||||||
$token = $this->prophesize(TokenInterface::class);
|
|
||||||
$token->getUser()->willReturn($user);
|
|
||||||
$tokenStorage = $this->prophesize(TokenStorageInterface::class);
|
|
||||||
$tokenStorage->getToken()->willReturn($token->reveal());
|
|
||||||
|
|
||||||
// Set up twig to return a response
|
|
||||||
$twig = $this->prophesize(Environment::class);
|
|
||||||
$twig->render('@ChillCalendar/Invitations/listByUser.html.twig', [
|
|
||||||
'invitations' => [],
|
|
||||||
'paginator' => $paginator->reveal(),
|
|
||||||
'templates' => [],
|
|
||||||
])->willReturn('empty page content');
|
|
||||||
|
|
||||||
// Set up container
|
|
||||||
$container = $this->prophesize(\Psr\Container\ContainerInterface::class);
|
|
||||||
$container->has('security.authorization_checker')->willReturn(true);
|
|
||||||
$container->get('security.authorization_checker')->willReturn($authorizationChecker->reveal());
|
|
||||||
$container->has('security.token_storage')->willReturn(true);
|
|
||||||
$container->get('security.token_storage')->willReturn($tokenStorage->reveal());
|
|
||||||
$container->has('twig')->willReturn(true);
|
|
||||||
$container->get('twig')->willReturn($twig->reveal());
|
|
||||||
|
|
||||||
// Use reflection to set the container
|
|
||||||
$reflection = new \ReflectionClass($controller);
|
|
||||||
$containerProperty = $reflection->getParentClass()->getProperty('container');
|
|
||||||
$containerProperty->setAccessible(true);
|
|
||||||
$containerProperty->setValue($controller, $container->reveal());
|
|
||||||
|
|
||||||
// Create request
|
|
||||||
$request = new Request();
|
|
||||||
|
|
||||||
// Execute the action
|
|
||||||
$response = $controller->myInvitations($request);
|
|
||||||
|
|
||||||
// Assert that page loads successfully
|
|
||||||
self::assertInstanceOf(Response::class, $response);
|
|
||||||
self::assertSame(200, $response->getStatusCode());
|
|
||||||
self::assertSame('empty page content', $response->getContent());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testMyInvitationsRequiresAuthentication(): void
|
|
||||||
{
|
|
||||||
// Create controller with minimal dependencies
|
|
||||||
$inviteRepository = $this->prophesize(InviteRepository::class);
|
|
||||||
$paginatorFactory = $this->prophesize(PaginatorFactory::class);
|
|
||||||
$docGeneratorTemplateRepository = $this->prophesize(DocGeneratorTemplateRepositoryInterface::class);
|
|
||||||
|
|
||||||
$controller = new MyInvitationsController(
|
|
||||||
$inviteRepository->reveal(),
|
|
||||||
$paginatorFactory->reveal(),
|
|
||||||
$docGeneratorTemplateRepository->reveal()
|
|
||||||
);
|
|
||||||
|
|
||||||
// Set up authorization checker to return false for ROLE_USER
|
|
||||||
$authorizationChecker = $this->prophesize(AuthorizationCheckerInterface::class);
|
|
||||||
$authorizationChecker->isGranted('ROLE_USER')->willReturn(false);
|
|
||||||
$authorizationChecker->isGranted('ROLE_USER', null)->willReturn(false);
|
|
||||||
|
|
||||||
// Set up container
|
|
||||||
$container = $this->prophesize(\Psr\Container\ContainerInterface::class);
|
|
||||||
$container->has('security.authorization_checker')->willReturn(true);
|
|
||||||
$container->get('security.authorization_checker')->willReturn($authorizationChecker->reveal());
|
|
||||||
|
|
||||||
// Use reflection to set the container
|
|
||||||
$reflection = new \ReflectionClass($controller);
|
|
||||||
$containerProperty = $reflection->getParentClass()->getProperty('container');
|
|
||||||
$containerProperty->setAccessible(true);
|
|
||||||
$containerProperty->setValue($controller, $container->reveal());
|
|
||||||
|
|
||||||
// Create request
|
|
||||||
$request = new Request();
|
|
||||||
|
|
||||||
// Expect AccessDeniedException
|
|
||||||
$this->expectException(\Symfony\Component\Security\Core\Exception\AccessDeniedException::class);
|
|
||||||
|
|
||||||
// Execute the action
|
|
||||||
$controller->myInvitations($request);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -31,7 +31,8 @@ Will send SMS: Un SMS de rappel sera envoyé
|
|||||||
Will not send SMS: Aucun SMS de rappel ne sera envoyé
|
Will not send SMS: Aucun SMS de rappel ne sera envoyé
|
||||||
SMS already sent: Un SMS a été envoyé
|
SMS already sent: Un SMS a été envoyé
|
||||||
|
|
||||||
Canceled by: Annulé par
|
canceledBy: supprimé par
|
||||||
|
Canceled by: supprimé par
|
||||||
Calendar configuration: Gestion des rendez-vous
|
Calendar configuration: Gestion des rendez-vous
|
||||||
|
|
||||||
crud:
|
crud:
|
||||||
@@ -43,14 +44,6 @@ crud:
|
|||||||
title_edit: Modifier le motif d'annulation
|
title_edit: Modifier le motif d'annulation
|
||||||
|
|
||||||
chill_calendar:
|
chill_calendar:
|
||||||
canceled: Annulé
|
|
||||||
cancel_reason: Raison d'annulation
|
|
||||||
cancel_calendar_item: Annuler rendez-vous
|
|
||||||
calendar_canceled: Le rendez-vous a été annulé
|
|
||||||
canceled_by:
|
|
||||||
user: Utilisateur
|
|
||||||
person: Usager
|
|
||||||
other: Autre
|
|
||||||
Document: Document d'un rendez-vous
|
Document: Document d'un rendez-vous
|
||||||
form:
|
form:
|
||||||
The main user is mandatory. He will organize the appointment.: L'utilisateur principal est obligatoire. Il est l'organisateur de l'événement.
|
The main user is mandatory. He will organize the appointment.: L'utilisateur principal est obligatoire. Il est l'organisateur de l'événement.
|
||||||
@@ -93,9 +86,6 @@ invite:
|
|||||||
declined: Refusé
|
declined: Refusé
|
||||||
pending: En attente
|
pending: En attente
|
||||||
tentative: Accepté provisoirement
|
tentative: Accepté provisoirement
|
||||||
list:
|
|
||||||
none: Il n'y aucun invitation
|
|
||||||
title: Mes invitations
|
|
||||||
|
|
||||||
# exports
|
# exports
|
||||||
Exports of calendar: Exports des rendez-vous
|
Exports of calendar: Exports des rendez-vous
|
||||||
|
|||||||
@@ -1,29 +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\CustomFieldsBundle\EntityRepository;
|
|
||||||
|
|
||||||
use Chill\CustomFieldsBundle\Entity\CustomFieldsDefaultGroup;
|
|
||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
|
||||||
|
|
||||||
class CustomFieldsDefaultGroupRepository extends ServiceEntityRepository
|
|
||||||
{
|
|
||||||
public function __construct(ManagerRegistry $registry)
|
|
||||||
{
|
|
||||||
parent::__construct($registry, CustomFieldsDefaultGroup::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function findOneByEntity(string $className): ?CustomFieldsDefaultGroup
|
|
||||||
{
|
|
||||||
return $this->findOneBy(['entity' => $className]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -127,7 +127,3 @@ services:
|
|||||||
factory: ["@doctrine", getRepository]
|
factory: ["@doctrine", getRepository]
|
||||||
arguments:
|
arguments:
|
||||||
- "Chill\\CustomFieldsBundle\\Entity\\CustomFieldLongChoice\\Option"
|
- "Chill\\CustomFieldsBundle\\Entity\\CustomFieldLongChoice\\Option"
|
||||||
|
|
||||||
Chill\CustomFieldsBundle\EntityRepository\CustomFieldsDefaultGroupRepository:
|
|
||||||
autowire: true
|
|
||||||
autoconfigure: true
|
|
||||||
|
|||||||
@@ -20,9 +20,4 @@ use Doctrine\Persistence\ObjectRepository;
|
|||||||
interface DocGeneratorTemplateRepositoryInterface extends ObjectRepository
|
interface DocGeneratorTemplateRepositoryInterface extends ObjectRepository
|
||||||
{
|
{
|
||||||
public function countByEntity(string $entity): int;
|
public function countByEntity(string $entity): int;
|
||||||
|
|
||||||
/**
|
|
||||||
* @return array|DocGeneratorTemplate[]
|
|
||||||
*/
|
|
||||||
public function findByEntity(string $entity, ?int $start = 0, ?int $limit = 50): array;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ use Chill\DocStoreBundle\Exception\StoredObjectManagerException;
|
|||||||
use Chill\DocStoreBundle\Service\Cryptography\KeyGenerator;
|
use Chill\DocStoreBundle\Service\Cryptography\KeyGenerator;
|
||||||
use Chill\DocStoreBundle\Service\StoredObjectManagerInterface;
|
use Chill\DocStoreBundle\Service\StoredObjectManagerInterface;
|
||||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||||
use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
|
|
||||||
use Symfony\Component\Filesystem\Filesystem;
|
use Symfony\Component\Filesystem\Filesystem;
|
||||||
use Symfony\Component\Filesystem\Path;
|
use Symfony\Component\Filesystem\Path;
|
||||||
|
|
||||||
@@ -148,11 +147,16 @@ class StoredObjectManager implements StoredObjectManagerInterface
|
|||||||
public function writeContent(string $filename, string $encryptedContent): void
|
public function writeContent(string $filename, string $encryptedContent): void
|
||||||
{
|
{
|
||||||
$fullPath = $this->buildPath($filename);
|
$fullPath = $this->buildPath($filename);
|
||||||
|
$dir = Path::getDirectory($fullPath);
|
||||||
|
|
||||||
try {
|
if (!$this->filesystem->exists($dir)) {
|
||||||
$this->filesystem->dumpFile($fullPath, $encryptedContent);
|
$this->filesystem->mkdir($dir);
|
||||||
} catch (IOExceptionInterface $exception) {
|
}
|
||||||
throw StoredObjectManagerException::unableToStoreDocumentOnDisk($exception);
|
|
||||||
|
$result = file_put_contents($fullPath, $encryptedContent);
|
||||||
|
|
||||||
|
if (false === $result) {
|
||||||
|
throw StoredObjectManagerException::unableToStoreDocumentOnDisk();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ final readonly class StoredObjectVersionApiController
|
|||||||
|
|
||||||
return new JsonResponse(
|
return new JsonResponse(
|
||||||
$this->serializer->serialize(
|
$this->serializer->serialize(
|
||||||
new Collection(array_values($items->toArray()), $paginator),
|
new Collection($items, $paginator),
|
||||||
'json',
|
'json',
|
||||||
[AbstractNormalizer::GROUPS => ['read', StoredObjectVersionNormalizer::WITH_POINT_IN_TIMES_CONTEXT, StoredObjectVersionNormalizer::WITH_RESTORED_CONTEXT]]
|
[AbstractNormalizer::GROUPS => ['read', StoredObjectVersionNormalizer::WITH_POINT_IN_TIMES_CONTEXT, StoredObjectVersionNormalizer::WITH_RESTORED_CONTEXT]]
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -23,14 +23,10 @@ use Random\RandomException;
|
|||||||
* Store each version of StoredObject's.
|
* Store each version of StoredObject's.
|
||||||
*
|
*
|
||||||
* A version should not be created manually: use the method @see{StoredObject::registerVersion} instead.
|
* A version should not be created manually: use the method @see{StoredObject::registerVersion} instead.
|
||||||
*
|
|
||||||
* Each filename must be unique within the same StoredObject. We add a condition on id to apply this condition only for
|
|
||||||
* newly created versions when this new index is applied.
|
|
||||||
*/
|
*/
|
||||||
#[ORM\Entity]
|
#[ORM\Entity]
|
||||||
#[ORM\Table('chill_doc.stored_object_version')]
|
#[ORM\Table('chill_doc.stored_object_version')]
|
||||||
#[ORM\UniqueConstraint(name: 'chill_doc_stored_object_version_unique_by_object', columns: ['stored_object_id', 'version'])]
|
#[ORM\UniqueConstraint(name: 'chill_doc_stored_object_version_unique_by_object', columns: ['stored_object_id', 'version'])]
|
||||||
#[ORM\UniqueConstraint(name: 'chill_doc_stored_object_version_unique_by_filename', columns: ['filename'], options: ['where' => '(id > 0)'])]
|
|
||||||
class StoredObjectVersion implements TrackCreationInterface
|
class StoredObjectVersion implements TrackCreationInterface
|
||||||
{
|
{
|
||||||
use TrackCreationTrait;
|
use TrackCreationTrait;
|
||||||
|
|||||||
@@ -1,20 +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\DocStoreBundle\Exception;
|
|
||||||
|
|
||||||
class ConversionWithSameMimeTypeException extends \RuntimeException
|
|
||||||
{
|
|
||||||
public function __construct(string $mimeType, ?\Throwable $previous = null)
|
|
||||||
{
|
|
||||||
parent::__construct("Conversion to same MIME type '{$mimeType}' is not allowed: already at the same MIME type", 0, $previous);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -25,7 +25,7 @@ export interface GenericDoc {
|
|||||||
type: "doc_store_generic_doc";
|
type: "doc_store_generic_doc";
|
||||||
uniqueKey: string;
|
uniqueKey: string;
|
||||||
key: string;
|
key: string;
|
||||||
identifiers: { id: number };
|
identifiers: object;
|
||||||
context: "person" | "accompanying-period";
|
context: "person" | "accompanying-period";
|
||||||
doc_date: DateTime;
|
doc_date: DateTime;
|
||||||
metadata: GenericDocMetadata;
|
metadata: GenericDocMetadata;
|
||||||
@@ -36,18 +36,6 @@ export interface GenericDocForAccompanyingPeriod extends GenericDoc {
|
|||||||
context: "accompanying-period";
|
context: "accompanying-period";
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isGenericDocForAccompanyingPeriod(
|
|
||||||
doc: GenericDoc,
|
|
||||||
): doc is GenericDocForAccompanyingPeriod {
|
|
||||||
return doc.context === "accompanying-period";
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isGenericDocWithStoredObject(
|
|
||||||
doc: GenericDoc,
|
|
||||||
): doc is GenericDoc & { storedObject: StoredObject } {
|
|
||||||
return doc.storedObject !== null;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface BaseMetadataWithHtml extends BaseMetadata {
|
interface BaseMetadataWithHtml extends BaseMetadata {
|
||||||
html: string;
|
html: string;
|
||||||
}
|
}
|
||||||
@@ -56,33 +44,28 @@ export interface GenericDocForAccompanyingCourseDocument
|
|||||||
extends GenericDocForAccompanyingPeriod {
|
extends GenericDocForAccompanyingPeriod {
|
||||||
key: "accompanying_course_document";
|
key: "accompanying_course_document";
|
||||||
metadata: BaseMetadataWithHtml;
|
metadata: BaseMetadataWithHtml;
|
||||||
storedObject: StoredObject;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GenericDocForAccompanyingCourseActivityDocument
|
export interface GenericDocForAccompanyingCourseActivityDocument
|
||||||
extends GenericDocForAccompanyingPeriod {
|
extends GenericDocForAccompanyingPeriod {
|
||||||
key: "accompanying_course_activity_document";
|
key: "accompanying_course_activity_document";
|
||||||
metadata: BaseMetadataWithHtml;
|
metadata: BaseMetadataWithHtml;
|
||||||
storedObject: StoredObject;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GenericDocForAccompanyingCourseCalendarDocument
|
export interface GenericDocForAccompanyingCourseCalendarDocument
|
||||||
extends GenericDocForAccompanyingPeriod {
|
extends GenericDocForAccompanyingPeriod {
|
||||||
key: "accompanying_course_calendar_document";
|
key: "accompanying_course_calendar_document";
|
||||||
metadata: BaseMetadataWithHtml;
|
metadata: BaseMetadataWithHtml;
|
||||||
storedObject: StoredObject;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GenericDocForAccompanyingCoursePersonDocument
|
export interface GenericDocForAccompanyingCoursePersonDocument
|
||||||
extends GenericDocForAccompanyingPeriod {
|
extends GenericDocForAccompanyingPeriod {
|
||||||
key: "person_document";
|
key: "person_document";
|
||||||
metadata: BaseMetadataWithHtml;
|
metadata: BaseMetadataWithHtml;
|
||||||
storedObject: StoredObject;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GenericDocForAccompanyingCourseWorkEvaluationDocument
|
export interface GenericDocForAccompanyingCourseWorkEvaluationDocument
|
||||||
extends GenericDocForAccompanyingPeriod {
|
extends GenericDocForAccompanyingPeriod {
|
||||||
key: "accompanying_period_work_evaluation_document";
|
key: "accompanying_period_work_evaluation_document";
|
||||||
metadata: BaseMetadataWithHtml;
|
metadata: BaseMetadataWithHtml;
|
||||||
storedObject: StoredObject;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import { StoredObject, StoredObjectVersion } from "../../types";
|
|||||||
import DropFileWidget from "ChillDocStoreAssets/vuejs/DropFileWidget/DropFileWidget.vue";
|
import DropFileWidget from "ChillDocStoreAssets/vuejs/DropFileWidget/DropFileWidget.vue";
|
||||||
import { computed, reactive } from "vue";
|
import { computed, reactive } from "vue";
|
||||||
import { useToast } from "vue-toast-notification";
|
import { useToast } from "vue-toast-notification";
|
||||||
import { DOCUMENT_ADD, trans } from "translator";
|
|
||||||
|
|
||||||
interface DropFileConfig {
|
interface DropFileConfig {
|
||||||
allowRemove: boolean;
|
allowRemove: boolean;
|
||||||
@@ -76,9 +75,11 @@ function closeModal(): void {
|
|||||||
@click="openModal"
|
@click="openModal"
|
||||||
class="btn btn-create"
|
class="btn btn-create"
|
||||||
>
|
>
|
||||||
{{ trans(DOCUMENT_ADD) }}
|
Ajouter un document
|
||||||
|
</button>
|
||||||
|
<button v-else @click="openModal" class="btn btn-edit">
|
||||||
|
Remplacer le document
|
||||||
</button>
|
</button>
|
||||||
<button v-else @click="openModal" class="btn btn-edit"></button>
|
|
||||||
<modal
|
<modal
|
||||||
v-if="state.showModal"
|
v-if="state.showModal"
|
||||||
:modal-dialog-class="modalClasses"
|
:modal-dialog-class="modalClasses"
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ import {
|
|||||||
StoredObject,
|
StoredObject,
|
||||||
StoredObjectPointInTime,
|
StoredObjectPointInTime,
|
||||||
StoredObjectVersionWithPointInTime,
|
StoredObjectVersionWithPointInTime,
|
||||||
} from "ChillDocStoreAssets/types";
|
} from "./../../../types";
|
||||||
import UserRenderBoxBadge from "ChillMainAssets/vuejs/_components/Entity/UserRenderBoxBadge.vue";
|
import UserRenderBoxBadge from "ChillMainAssets/vuejs/_components/Entity/UserRenderBoxBadge.vue";
|
||||||
import { ISOToDatetime } from "ChillMainAssets/chill/js/date";
|
import { ISOToDatetime } from "./../../../../../../ChillMainBundle/Resources/public/chill/js/date";
|
||||||
import FileIcon from "ChillDocStoreAssets/vuejs/FileIcon.vue";
|
import FileIcon from "ChillDocStoreAssets/vuejs/FileIcon.vue";
|
||||||
import RestoreVersionButton from "ChillDocStoreAssets/vuejs/StoredObjectButton/HistoryButton/RestoreVersionButton.vue";
|
import RestoreVersionButton from "ChillDocStoreAssets/vuejs/StoredObjectButton/HistoryButton/RestoreVersionButton.vue";
|
||||||
import DownloadButton from "ChillDocStoreAssets/vuejs/StoredObjectButton/DownloadButton.vue";
|
import DownloadButton from "ChillDocStoreAssets/vuejs/StoredObjectButton/DownloadButton.vue";
|
||||||
|
|||||||
@@ -46,16 +46,6 @@ abstract class AbstractStoredObjectVoter implements StoredObjectVoterInterface
|
|||||||
|
|
||||||
public function voteOnAttribute(StoredObjectRoleEnum $attribute, StoredObject $subject, TokenInterface $token): bool
|
public function voteOnAttribute(StoredObjectRoleEnum $attribute, StoredObject $subject, TokenInterface $token): bool
|
||||||
{
|
{
|
||||||
// we first try to get the permission from the workflow, as attachement (this is the less intensive query)
|
|
||||||
$workflowPermissionAsAttachment = match ($attribute) {
|
|
||||||
StoredObjectRoleEnum::SEE => $this->workflowDocumentService->isAllowedByWorkflowForReadOperation($subject),
|
|
||||||
StoredObjectRoleEnum::EDIT => $this->workflowDocumentService->isAllowedByWorkflowForWriteOperation($subject),
|
|
||||||
};
|
|
||||||
|
|
||||||
if (WorkflowRelatedEntityPermissionHelper::FORCE_DENIED === $workflowPermissionAsAttachment) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve the related entity
|
// Retrieve the related entity
|
||||||
$entity = $this->getRepository()->findAssociatedEntityToStoredObject($subject);
|
$entity = $this->getRepository()->findAssociatedEntityToStoredObject($subject);
|
||||||
|
|
||||||
@@ -76,7 +66,7 @@ abstract class AbstractStoredObjectVoter implements StoredObjectVoterInterface
|
|||||||
return match ($workflowPermission) {
|
return match ($workflowPermission) {
|
||||||
WorkflowRelatedEntityPermissionHelper::FORCE_GRANT => true,
|
WorkflowRelatedEntityPermissionHelper::FORCE_GRANT => true,
|
||||||
WorkflowRelatedEntityPermissionHelper::FORCE_DENIED => false,
|
WorkflowRelatedEntityPermissionHelper::FORCE_DENIED => false,
|
||||||
WorkflowRelatedEntityPermissionHelper::ABSTAIN => WorkflowRelatedEntityPermissionHelper::FORCE_GRANT === $workflowPermissionAsAttachment || $regularPermission,
|
WorkflowRelatedEntityPermissionHelper::ABSTAIN => $regularPermission,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,12 +14,6 @@ namespace Chill\DocStoreBundle\Security\Authorization;
|
|||||||
use Chill\DocStoreBundle\Entity\StoredObject;
|
use Chill\DocStoreBundle\Entity\StoredObject;
|
||||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface for voting on stored object permissions.
|
|
||||||
*
|
|
||||||
* Each time a stored object is attached to a document, the voter is responsible for determining
|
|
||||||
* whether the user has the necessary permissions to access or modify the stored object.
|
|
||||||
*/
|
|
||||||
interface StoredObjectVoterInterface
|
interface StoredObjectVoterInterface
|
||||||
{
|
{
|
||||||
public function supports(StoredObjectRoleEnum $attribute, StoredObject $subject): bool;
|
public function supports(StoredObjectRoleEnum $attribute, StoredObject $subject): bool;
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ use Chill\DocStoreBundle\Entity\StoredObject;
|
|||||||
use Chill\DocStoreBundle\Entity\StoredObjectPointInTime;
|
use Chill\DocStoreBundle\Entity\StoredObjectPointInTime;
|
||||||
use Chill\DocStoreBundle\Entity\StoredObjectPointInTimeReasonEnum;
|
use Chill\DocStoreBundle\Entity\StoredObjectPointInTimeReasonEnum;
|
||||||
use Chill\DocStoreBundle\Entity\StoredObjectVersion;
|
use Chill\DocStoreBundle\Entity\StoredObjectVersion;
|
||||||
use Chill\DocStoreBundle\Exception\ConversionWithSameMimeTypeException;
|
|
||||||
use Chill\DocStoreBundle\Exception\StoredObjectManagerException;
|
use Chill\DocStoreBundle\Exception\StoredObjectManagerException;
|
||||||
use Chill\WopiBundle\Service\WopiConverter;
|
use Chill\WopiBundle\Service\WopiConverter;
|
||||||
use Symfony\Component\Mime\MimeTypesInterface;
|
use Symfony\Component\Mime\MimeTypesInterface;
|
||||||
@@ -42,10 +41,9 @@ class StoredObjectToPdfConverter
|
|||||||
*
|
*
|
||||||
* @return array{0: StoredObjectPointInTime, 1: StoredObjectVersion, 2?: string} contains the point in time before conversion and the new version of the stored object. The converted content is included in the response if $includeConvertedContent is true
|
* @return array{0: StoredObjectPointInTime, 1: StoredObjectVersion, 2?: string} contains the point in time before conversion and the new version of the stored object. The converted content is included in the response if $includeConvertedContent is true
|
||||||
*
|
*
|
||||||
* @throws \UnexpectedValueException if the preferred mime type for the conversion is not found
|
* @throws \UnexpectedValueException if the preferred mime type for the conversion is not found
|
||||||
* @throws \RuntimeException if the conversion or storage of the new version fails
|
* @throws \RuntimeException if the conversion or storage of the new version fails
|
||||||
* @throws StoredObjectManagerException
|
* @throws StoredObjectManagerException
|
||||||
* @throws ConversionWithSameMimeTypeException if the document has already the same mime type79*
|
|
||||||
*/
|
*/
|
||||||
public function addConvertedVersion(StoredObject $storedObject, string $lang, $convertTo = 'pdf', bool $includeConvertedContent = false): array
|
public function addConvertedVersion(StoredObject $storedObject, string $lang, $convertTo = 'pdf', bool $includeConvertedContent = false): array
|
||||||
{
|
{
|
||||||
@@ -58,7 +56,7 @@ class StoredObjectToPdfConverter
|
|||||||
$currentVersion = $storedObject->getCurrentVersion();
|
$currentVersion = $storedObject->getCurrentVersion();
|
||||||
|
|
||||||
if ($currentVersion->getType() === $newMimeType) {
|
if ($currentVersion->getType() === $newMimeType) {
|
||||||
throw new ConversionWithSameMimeTypeException($newMimeType);
|
throw new \UnexpectedValueException('Already at the same mime type');
|
||||||
}
|
}
|
||||||
|
|
||||||
$content = $this->storedObjectManager->read($currentVersion);
|
$content = $this->storedObjectManager->read($currentVersion);
|
||||||
|
|||||||
@@ -40,10 +40,6 @@ class StoredObjectVersionApiControllerTest extends \PHPUnit\Framework\TestCase
|
|||||||
$storedObject->registerVersion();
|
$storedObject->registerVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove one version in the history
|
|
||||||
$v5 = $storedObject->getVersions()->get(5);
|
|
||||||
$storedObject->removeVersion($v5);
|
|
||||||
|
|
||||||
$security = $this->prophesize(Security::class);
|
$security = $this->prophesize(Security::class);
|
||||||
$security->isGranted(StoredObjectRoleEnum::SEE->value, $storedObject)
|
$security->isGranted(StoredObjectRoleEnum::SEE->value, $storedObject)
|
||||||
->willReturn(true)
|
->willReturn(true)
|
||||||
@@ -57,7 +53,6 @@ class StoredObjectVersionApiControllerTest extends \PHPUnit\Framework\TestCase
|
|||||||
self::assertEquals($response->getStatusCode(), 200);
|
self::assertEquals($response->getStatusCode(), 200);
|
||||||
self::assertIsArray($body);
|
self::assertIsArray($body);
|
||||||
self::assertArrayHasKey('results', $body);
|
self::assertArrayHasKey('results', $body);
|
||||||
self::assertIsList($body['results']);
|
|
||||||
self::assertCount(10, $body['results']);
|
self::assertCount(10, $body['results']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -86,165 +86,9 @@ class AbstractStoredObjectVoterTest extends TestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider dataProviderVoteOnAttributeWithStoredObjectPermission
|
* @dataProvider dataProviderVoteOnAttribute
|
||||||
*/
|
*/
|
||||||
public function testVoteOnAttributeWithStoredObjectPermission(
|
public function testVoteOnAttribute(
|
||||||
StoredObjectRoleEnum $attribute,
|
|
||||||
bool $expected,
|
|
||||||
bool $isGrantedRegularPermission,
|
|
||||||
string $isGrantedWorkflowPermission,
|
|
||||||
string $isGrantedStoredObjectAttachment,
|
|
||||||
): void {
|
|
||||||
$storedObject = new StoredObject();
|
|
||||||
$repository = new DummyRepository($related = new \stdClass());
|
|
||||||
$token = new UsernamePasswordToken(new User(), 'dummy');
|
|
||||||
|
|
||||||
$security = $this->prophesize(Security::class);
|
|
||||||
$security->isGranted('SOME_ROLE', $related)->willReturn($isGrantedRegularPermission);
|
|
||||||
|
|
||||||
$workflowRelatedEntityPermissionHelper = $this->prophesize(WorkflowRelatedEntityPermissionHelper::class);
|
|
||||||
|
|
||||||
$security = $this->prophesize(Security::class);
|
|
||||||
$security->isGranted('SOME_ROLE', $related)->willReturn($isGrantedRegularPermission);
|
|
||||||
|
|
||||||
if (StoredObjectRoleEnum::SEE === $attribute) {
|
|
||||||
$workflowRelatedEntityPermissionHelper->isAllowedByWorkflowForReadOperation($storedObject)
|
|
||||||
->shouldBeCalled()
|
|
||||||
->willReturn($isGrantedStoredObjectAttachment);
|
|
||||||
$workflowRelatedEntityPermissionHelper->isAllowedByWorkflowForReadOperation($related)
|
|
||||||
->willReturn($isGrantedWorkflowPermission);
|
|
||||||
} elseif (StoredObjectRoleEnum::EDIT === $attribute) {
|
|
||||||
$workflowRelatedEntityPermissionHelper->isAllowedByWorkflowForWriteOperation($storedObject)
|
|
||||||
->shouldBeCalled()
|
|
||||||
->willReturn($isGrantedStoredObjectAttachment);
|
|
||||||
$workflowRelatedEntityPermissionHelper->isAllowedByWorkflowForWriteOperation($related)
|
|
||||||
->willReturn($isGrantedWorkflowPermission);
|
|
||||||
} else {
|
|
||||||
throw new \LogicException('Invalid attribute for StoredObjectVoter');
|
|
||||||
}
|
|
||||||
|
|
||||||
$storedObjectVoter = new class ($repository, $workflowRelatedEntityPermissionHelper->reveal(), $security->reveal()) extends AbstractStoredObjectVoter {
|
|
||||||
public function __construct(private $repository, $helper, $security)
|
|
||||||
{
|
|
||||||
parent::__construct($security, $helper);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getRepository(): AssociatedEntityToStoredObjectInterface
|
|
||||||
{
|
|
||||||
return $this->repository;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getClass(): string
|
|
||||||
{
|
|
||||||
return \stdClass::class;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function attributeToRole(StoredObjectRoleEnum $attribute): string
|
|
||||||
{
|
|
||||||
return 'SOME_ROLE';
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function canBeAssociatedWithWorkflow(): bool
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$actual = $storedObjectVoter->voteOnAttribute($attribute, $storedObject, $token);
|
|
||||||
|
|
||||||
self::assertEquals($expected, $actual);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function dataProviderVoteOnAttributeWithStoredObjectPermission(): iterable
|
|
||||||
{
|
|
||||||
foreach (['read' => StoredObjectRoleEnum::SEE, 'write' => StoredObjectRoleEnum::EDIT] as $action => $attribute) {
|
|
||||||
yield 'Not related to any workflow nor attachment ('.$action.')' => [
|
|
||||||
$attribute,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
WorkflowRelatedEntityPermissionHelper::ABSTAIN,
|
|
||||||
WorkflowRelatedEntityPermissionHelper::ABSTAIN,
|
|
||||||
];
|
|
||||||
|
|
||||||
yield 'Not related to any workflow nor attachment (refuse) ('.$action.')' => [
|
|
||||||
$attribute,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
WorkflowRelatedEntityPermissionHelper::ABSTAIN,
|
|
||||||
WorkflowRelatedEntityPermissionHelper::ABSTAIN,
|
|
||||||
];
|
|
||||||
|
|
||||||
yield 'Is granted by a workflow takes precedence (workflow) ('.$action.')' => [
|
|
||||||
$attribute,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
WorkflowRelatedEntityPermissionHelper::FORCE_DENIED,
|
|
||||||
WorkflowRelatedEntityPermissionHelper::ABSTAIN,
|
|
||||||
];
|
|
||||||
|
|
||||||
yield 'Is granted by a workflow takes precedence (stored object) ('.$action.')' => [
|
|
||||||
$attribute,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
WorkflowRelatedEntityPermissionHelper::ABSTAIN,
|
|
||||||
WorkflowRelatedEntityPermissionHelper::FORCE_DENIED,
|
|
||||||
];
|
|
||||||
|
|
||||||
yield 'Is granted by a workflow takes precedence (workflow) although grant ('.$action.')' => [
|
|
||||||
$attribute,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
WorkflowRelatedEntityPermissionHelper::FORCE_DENIED,
|
|
||||||
WorkflowRelatedEntityPermissionHelper::FORCE_GRANT,
|
|
||||||
];
|
|
||||||
|
|
||||||
yield 'Is granted by a workflow takes precedence (stored object) although grant ('.$action.')' => [
|
|
||||||
$attribute,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
WorkflowRelatedEntityPermissionHelper::FORCE_GRANT,
|
|
||||||
WorkflowRelatedEntityPermissionHelper::FORCE_DENIED,
|
|
||||||
];
|
|
||||||
|
|
||||||
yield 'Is granted by a workflow takes precedence (initially refused) (workflow) although grant ('.$action.')' => [
|
|
||||||
$attribute,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
WorkflowRelatedEntityPermissionHelper::FORCE_DENIED,
|
|
||||||
WorkflowRelatedEntityPermissionHelper::FORCE_GRANT,
|
|
||||||
];
|
|
||||||
|
|
||||||
yield 'Is granted by a workflow takes precedence (initially refused) (stored object) although grant ('.$action.')' => [
|
|
||||||
$attribute,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
WorkflowRelatedEntityPermissionHelper::FORCE_GRANT,
|
|
||||||
WorkflowRelatedEntityPermissionHelper::FORCE_DENIED,
|
|
||||||
];
|
|
||||||
|
|
||||||
yield 'Force grant inverse the regular permission (workflow) ('.$action.')' => [
|
|
||||||
$attribute,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
WorkflowRelatedEntityPermissionHelper::FORCE_GRANT,
|
|
||||||
WorkflowRelatedEntityPermissionHelper::ABSTAIN,
|
|
||||||
];
|
|
||||||
|
|
||||||
yield 'Force grant inverse the regular permission (so) ('.$action.')' => [
|
|
||||||
$attribute,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
WorkflowRelatedEntityPermissionHelper::ABSTAIN,
|
|
||||||
WorkflowRelatedEntityPermissionHelper::FORCE_GRANT,
|
|
||||||
];
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dataProvider dataProviderVoteOnAttributeWithoutStoredObjectPermission
|
|
||||||
*/
|
|
||||||
public function testVoteOnAttributeWithoutStoredObjectPermission(
|
|
||||||
StoredObjectRoleEnum $attribute,
|
StoredObjectRoleEnum $attribute,
|
||||||
bool $expected,
|
bool $expected,
|
||||||
bool $canBeAssociatedWithWorkflow,
|
bool $canBeAssociatedWithWorkflow,
|
||||||
@@ -261,10 +105,6 @@ class AbstractStoredObjectVoterTest extends TestCase
|
|||||||
$security->isGranted('SOME_ROLE', $related)->willReturn($isGrantedRegularPermission);
|
$security->isGranted('SOME_ROLE', $related)->willReturn($isGrantedRegularPermission);
|
||||||
|
|
||||||
$workflowRelatedEntityPermissionHelper = $this->prophesize(WorkflowRelatedEntityPermissionHelper::class);
|
$workflowRelatedEntityPermissionHelper = $this->prophesize(WorkflowRelatedEntityPermissionHelper::class);
|
||||||
|
|
||||||
$workflowRelatedEntityPermissionHelper->isAllowedByWorkflowForReadOperation($storedObject)->willReturn(WorkflowRelatedEntityPermissionHelper::ABSTAIN);
|
|
||||||
$workflowRelatedEntityPermissionHelper->isAllowedByWorkflowForWriteOperation($storedObject)->willReturn(WorkflowRelatedEntityPermissionHelper::ABSTAIN);
|
|
||||||
|
|
||||||
if (null !== $isGrantedWorkflowPermissionRead) {
|
if (null !== $isGrantedWorkflowPermissionRead) {
|
||||||
$workflowRelatedEntityPermissionHelper->isAllowedByWorkflowForReadOperation($related)
|
$workflowRelatedEntityPermissionHelper->isAllowedByWorkflowForReadOperation($related)
|
||||||
->willReturn($isGrantedWorkflowPermissionRead)->shouldBeCalled();
|
->willReturn($isGrantedWorkflowPermissionRead)->shouldBeCalled();
|
||||||
@@ -283,7 +123,7 @@ class AbstractStoredObjectVoterTest extends TestCase
|
|||||||
self::assertEquals($expected, $voter->voteOnAttribute($attribute, $storedObject, $token), $message);
|
self::assertEquals($expected, $voter->voteOnAttribute($attribute, $storedObject, $token), $message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function dataProviderVoteOnAttributeWithoutStoredObjectPermission(): iterable
|
public static function dataProviderVoteOnAttribute(): iterable
|
||||||
{
|
{
|
||||||
// not associated on a workflow
|
// not associated on a workflow
|
||||||
yield [StoredObjectRoleEnum::SEE, true, false, true, null, null, 'not associated on a workflow, granted by regular access, must not rely on helper'];
|
yield [StoredObjectRoleEnum::SEE, true, false, true, null, null, 'not associated on a workflow, granted by regular access, must not rely on helper'];
|
||||||
|
|||||||
@@ -1,63 +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\Migrations\DocStore;
|
|
||||||
|
|
||||||
use Doctrine\DBAL\Schema\Schema;
|
|
||||||
use Doctrine\Migrations\AbstractMigration;
|
|
||||||
|
|
||||||
final class Version20251013094414 extends AbstractMigration
|
|
||||||
{
|
|
||||||
public function getDescription(): string
|
|
||||||
{
|
|
||||||
return 'DocStore: Enforce filename uniqueness on chill_doc.stored_object_version; clean duplicates and add partial unique index on filename (for new rows only).';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function up(Schema $schema): void
|
|
||||||
{
|
|
||||||
// 1) Clean duplicates: for each (stored_object_id, filename, key, iv), keep only the last inserted row
|
|
||||||
// and delete all others. Use ROW_NUMBER over id DESC to define the last one.
|
|
||||||
$this->addSql(<<<'SQL'
|
|
||||||
WITH ranked AS (
|
|
||||||
SELECT id,
|
|
||||||
rank() OVER (
|
|
||||||
PARTITION BY stored_object_id, filename, "key"::jsonb, iv::jsonb
|
|
||||||
ORDER BY id DESC
|
|
||||||
) AS rn
|
|
||||||
FROM chill_doc.stored_object_version
|
|
||||||
)
|
|
||||||
DELETE FROM chill_doc.stored_object_version sov
|
|
||||||
USING ranked r
|
|
||||||
WHERE sov.id = r.id
|
|
||||||
AND r.rn > 1
|
|
||||||
SQL);
|
|
||||||
|
|
||||||
// 2) Create a partial unique index on filename that applies only to subsequently inserted rows.
|
|
||||||
// Per user's instruction, compute the cutoff using the stored_object_id sequence value.
|
|
||||||
$nextVal = (int) $this->connection->fetchOne("SELECT nextval('chill_doc.stored_object_version_id_seq')");
|
|
||||||
|
|
||||||
// Safety: if somehow sequence is not available, fallback to current max id from the table
|
|
||||||
if ($nextVal <= 0) {
|
|
||||||
$nextVal = (int) $this->connection->fetchOne('SELECT COALESCE(MAX(id), 0) FROM chill_doc.stored_object_version');
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->addSql(sprintf(
|
|
||||||
'CREATE UNIQUE INDEX chill_doc_stored_object_version_unique_by_filename ON chill_doc.stored_object_version (filename) WHERE id > %d',
|
|
||||||
$nextVal
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function down(Schema $schema): void
|
|
||||||
{
|
|
||||||
// Drop the partial unique index; data cleanup is irreversible.
|
|
||||||
$this->addSql('DROP INDEX IF EXISTS chill_doc_stored_object_version_unique_by_filename');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -23,8 +23,6 @@ See the document: Voir le document
|
|||||||
|
|
||||||
document:
|
document:
|
||||||
Any title: Aucun titre
|
Any title: Aucun titre
|
||||||
replace: Remplacer
|
|
||||||
Add: Ajouter un document
|
|
||||||
|
|
||||||
generic_doc:
|
generic_doc:
|
||||||
filter:
|
filter:
|
||||||
|
|||||||
@@ -1,28 +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\EventBundle\Controller\Admin;
|
|
||||||
|
|
||||||
use Chill\MainBundle\CRUD\Controller\CRUDController;
|
|
||||||
use Chill\MainBundle\Pagination\PaginatorInterface;
|
|
||||||
use Doctrine\ORM\QueryBuilder;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
|
|
||||||
class EventBudgetKindController extends CRUDController
|
|
||||||
{
|
|
||||||
protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator)
|
|
||||||
{
|
|
||||||
/* @var QueryBuilder $query */
|
|
||||||
$query->addOrderBy('e.type', 'ASC');
|
|
||||||
|
|
||||||
return parent::orderQuery($action, $query, $request, $paginator);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -23,11 +23,11 @@ use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
|
|||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
use Chill\PersonBundle\Form\Type\PickPersonDynamicType;
|
use Chill\PersonBundle\Form\Type\PickPersonDynamicType;
|
||||||
use Chill\PersonBundle\Privacy\PrivacyEvent;
|
use Chill\PersonBundle\Privacy\PrivacyEvent;
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
|
||||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||||
use PhpOffice\PhpSpreadsheet\Writer\Csv;
|
use PhpOffice\PhpSpreadsheet\Writer\Csv;
|
||||||
use PhpOffice\PhpSpreadsheet\Writer\Ods;
|
use PhpOffice\PhpSpreadsheet\Writer\Ods;
|
||||||
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
||||||
|
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
|
||||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||||
@@ -41,8 +41,6 @@ use Symfony\Component\HttpFoundation\Response;
|
|||||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||||
use Symfony\Component\Security\Core\Security;
|
use Symfony\Component\Security\Core\Security;
|
||||||
use Symfony\Component\Serializer\Exception\ExceptionInterface;
|
|
||||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -60,8 +58,7 @@ final class EventController extends AbstractController
|
|||||||
private readonly TranslatorInterface $translator,
|
private readonly TranslatorInterface $translator,
|
||||||
private readonly PaginatorFactory $paginator,
|
private readonly PaginatorFactory $paginator,
|
||||||
private readonly Security $security,
|
private readonly Security $security,
|
||||||
private readonly ManagerRegistry $managerRegistry,
|
private readonly \Doctrine\Persistence\ManagerRegistry $managerRegistry,
|
||||||
private readonly NormalizerInterface $normalizer,
|
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/event/event/{event_id}/delete', name: 'chill_event__event_delete', requirements: ['event_id' => '\d+'], methods: ['GET', 'POST', 'DELETE'])]
|
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/event/event/{event_id}/delete', name: 'chill_event__event_delete', requirements: ['event_id' => '\d+'], methods: ['GET', 'POST', 'DELETE'])]
|
||||||
@@ -78,7 +75,6 @@ final class EventController extends AbstractController
|
|||||||
|
|
||||||
/** @var array $participations */
|
/** @var array $participations */
|
||||||
$participations = $event->getParticipations();
|
$participations = $event->getParticipations();
|
||||||
$budgetElements = $event->getBudgetElements();
|
|
||||||
|
|
||||||
$form = $this->createDeleteForm($event_id);
|
$form = $this->createDeleteForm($event_id);
|
||||||
|
|
||||||
@@ -90,10 +86,6 @@ final class EventController extends AbstractController
|
|||||||
$em->remove($participation);
|
$em->remove($participation);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($budgetElements as $e) {
|
|
||||||
$em->remove($e);
|
|
||||||
}
|
|
||||||
|
|
||||||
$em->remove($event);
|
$em->remove($event);
|
||||||
$em->flush();
|
$em->flush();
|
||||||
|
|
||||||
@@ -111,7 +103,7 @@ final class EventController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
return $this->render('@ChillEvent/Event/confirm_delete.html.twig', [
|
return $this->render('@ChillEvent/Event/confirm_delete.html.twig', [
|
||||||
'id' => $event->getId(),
|
'event_id' => $event->getId(),
|
||||||
'delete_form' => $form->createView(),
|
'delete_form' => $form->createView(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -177,8 +169,6 @@ final class EventController extends AbstractController
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays a form to create a new Event entity.
|
* Displays a form to create a new Event entity.
|
||||||
*
|
|
||||||
* @throws ExceptionInterface
|
|
||||||
*/
|
*/
|
||||||
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/event/event/new', name: 'chill_event__event_new', methods: ['GET', 'POST'])]
|
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/event/event/new', name: 'chill_event__event_new', methods: ['GET', 'POST'])]
|
||||||
public function newAction(?Center $center, Request $request): Response
|
public function newAction(?Center $center, Request $request): Response
|
||||||
@@ -209,23 +199,26 @@ final class EventController extends AbstractController
|
|||||||
$this->addFlash('success', $this->translator
|
$this->addFlash('success', $this->translator
|
||||||
->trans('The event was created'));
|
->trans('The event was created'));
|
||||||
|
|
||||||
return $this->redirectToRoute('chill_event__event_show', ['id' => $entity->getId()]);
|
return $this->redirectToRoute('chill_event__event_show', ['event_id' => $entity->getId()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$entity_array = $this->normalizer->normalize($entity, 'json', ['groups' => 'read']);
|
|
||||||
|
|
||||||
return $this->render('@ChillEvent/Event/new.html.twig', [
|
return $this->render('@ChillEvent/Event/new.html.twig', [
|
||||||
'entity' => $entity,
|
'entity' => $entity,
|
||||||
'form' => $form->createView(),
|
'form' => $form->createView(),
|
||||||
'entity_json' => $entity_array,
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* First step of new Event form.
|
||||||
|
*/
|
||||||
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/event/event/new/pick-center', name: 'chill_event__event_new_pickcenter', options: [null])]
|
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/event/event/new/pick-center', name: 'chill_event__event_new_pickcenter', options: [null])]
|
||||||
public function newPickCenterAction(): Response
|
public function newPickCenterAction(): Response
|
||||||
{
|
{
|
||||||
$role = 'CHILL_EVENT_CREATE';
|
$role = 'CHILL_EVENT_CREATE';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Center $centers
|
||||||
|
*/
|
||||||
$centers = $this->authorizationHelper->getReachableCenters($this->getUser(), $role);
|
$centers = $this->authorizationHelper->getReachableCenters($this->getUser(), $role);
|
||||||
|
|
||||||
if (1 === \count($centers)) {
|
if (1 === \count($centers)) {
|
||||||
@@ -245,8 +238,8 @@ final class EventController extends AbstractController
|
|||||||
->add('center_id', EntityType::class, [
|
->add('center_id', EntityType::class, [
|
||||||
'class' => Center::class,
|
'class' => Center::class,
|
||||||
'choices' => $centers,
|
'choices' => $centers,
|
||||||
'placeholder' => $this->translator->trans('Pick a center'),
|
'placeholder' => '',
|
||||||
'label' => 'To which territory should the event be associated ?',
|
'label' => 'To which centre should the event be associated ?',
|
||||||
])
|
])
|
||||||
->add('submit', SubmitType::class, [
|
->add('submit', SubmitType::class, [
|
||||||
'label' => 'Next step',
|
'label' => 'Next step',
|
||||||
@@ -258,7 +251,16 @@ final class EventController extends AbstractController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/event/event/{id}/show', name: 'chill_event__event_show')]
|
/**
|
||||||
|
* Finds and displays a Event entity.
|
||||||
|
*
|
||||||
|
* @ParamConverter("event", options={"id": "event_id"})
|
||||||
|
*
|
||||||
|
* @return Response
|
||||||
|
*
|
||||||
|
* @throws \PhpOffice\PhpSpreadsheet\Exception
|
||||||
|
*/
|
||||||
|
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/event/event/{event_id}/show', name: 'chill_event__event_show')]
|
||||||
public function showAction(Event $event, Request $request)
|
public function showAction(Event $event, Request $request)
|
||||||
{
|
{
|
||||||
if (!$event) {
|
if (!$event) {
|
||||||
@@ -315,7 +317,7 @@ final class EventController extends AbstractController
|
|||||||
|
|
||||||
$this->addFlash('success', $this->translator->trans('The event was updated'));
|
$this->addFlash('success', $this->translator->trans('The event was updated'));
|
||||||
|
|
||||||
return $this->redirectToRoute('chill_event__event_show', ['id' => $event_id]);
|
return $this->redirectToRoute('chill_event__event_show', ['event_id' => $event_id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->render('@ChillEvent/Event/edit.html.twig', [
|
return $this->render('@ChillEvent/Event/edit.html.twig', [
|
||||||
|
|||||||
@@ -15,15 +15,11 @@ use Chill\EventBundle\Entity\Event;
|
|||||||
use Chill\EventBundle\Entity\EventType;
|
use Chill\EventBundle\Entity\EventType;
|
||||||
use Chill\EventBundle\Repository\EventACLAwareRepositoryInterface;
|
use Chill\EventBundle\Repository\EventACLAwareRepositoryInterface;
|
||||||
use Chill\EventBundle\Repository\EventTypeRepository;
|
use Chill\EventBundle\Repository\EventTypeRepository;
|
||||||
use Chill\EventBundle\Security\EventVoter;
|
|
||||||
use Chill\MainBundle\Entity\Center;
|
|
||||||
use Chill\MainBundle\Pagination\PaginatorFactoryInterface;
|
use Chill\MainBundle\Pagination\PaginatorFactoryInterface;
|
||||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
|
||||||
use Chill\MainBundle\Templating\Listing\FilterOrderHelper;
|
use Chill\MainBundle\Templating\Listing\FilterOrderHelper;
|
||||||
use Chill\MainBundle\Templating\Listing\FilterOrderHelperFactory;
|
use Chill\MainBundle\Templating\Listing\FilterOrderHelperFactory;
|
||||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||||
use Chill\PersonBundle\Form\Type\PickPersonDynamicType;
|
use Chill\PersonBundle\Form\Type\PickPersonDynamicType;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|
||||||
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
|
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
|
||||||
use Symfony\Component\Form\FormFactoryInterface;
|
use Symfony\Component\Form\FormFactoryInterface;
|
||||||
@@ -33,18 +29,17 @@ use Symfony\Component\Routing\Annotation\Route;
|
|||||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||||
use Twig\Environment;
|
use Twig\Environment;
|
||||||
|
|
||||||
final class EventListController extends AbstractController
|
final readonly class EventListController
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly Environment $environment,
|
private Environment $environment,
|
||||||
private readonly EventACLAwareRepositoryInterface $eventACLAwareRepository,
|
private EventACLAwareRepositoryInterface $eventACLAwareRepository,
|
||||||
private readonly EventTypeRepository $eventTypeRepository,
|
private EventTypeRepository $eventTypeRepository,
|
||||||
private readonly FilterOrderHelperFactory $filterOrderHelperFactory,
|
private FilterOrderHelperFactory $filterOrderHelperFactory,
|
||||||
private readonly FormFactoryInterface $formFactory,
|
private FormFactoryInterface $formFactory,
|
||||||
private readonly PaginatorFactoryInterface $paginatorFactory,
|
private PaginatorFactoryInterface $paginatorFactory,
|
||||||
private readonly TranslatableStringHelperInterface $translatableStringHelper,
|
private TranslatableStringHelperInterface $translatableStringHelper,
|
||||||
private readonly UrlGeneratorInterface $urlGenerator,
|
private UrlGeneratorInterface $urlGenerator,
|
||||||
private readonly AuthorizationHelper $authorizationHelper,
|
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
#[Route(path: '{_locale}/event/event/list', name: 'chill_event_event_list')]
|
#[Route(path: '{_locale}/event/event/list', name: 'chill_event_event_list')]
|
||||||
@@ -55,8 +50,6 @@ final class EventListController extends AbstractController
|
|||||||
'q' => (string) $filter->getQueryString(),
|
'q' => (string) $filter->getQueryString(),
|
||||||
'dates' => $filter->getDateRangeData('dates'),
|
'dates' => $filter->getDateRangeData('dates'),
|
||||||
'event_types' => $filter->getEntityChoiceData('event_types'),
|
'event_types' => $filter->getEntityChoiceData('event_types'),
|
||||||
'responsables' => $filter->getUserPickerData('responsables'),
|
|
||||||
'centers' => $filter->getEntityChoiceData('centers'),
|
|
||||||
];
|
];
|
||||||
$total = $this->eventACLAwareRepository->countAllViewable($filterData);
|
$total = $this->eventACLAwareRepository->countAllViewable($filterData);
|
||||||
$pagination = $this->paginatorFactory->create($total);
|
$pagination = $this->paginatorFactory->create($total);
|
||||||
@@ -80,7 +73,6 @@ final class EventListController extends AbstractController
|
|||||||
private function buildFilterOrder(): FilterOrderHelper
|
private function buildFilterOrder(): FilterOrderHelper
|
||||||
{
|
{
|
||||||
$types = $this->eventTypeRepository->findAllActive();
|
$types = $this->eventTypeRepository->findAllActive();
|
||||||
$centers = $this->authorizationHelper->getReachableCenters($this->getUser(), EventVoter::SEE);
|
|
||||||
|
|
||||||
$builder = $this->filterOrderHelperFactory->create(__METHOD__);
|
$builder = $this->filterOrderHelperFactory->create(__METHOD__);
|
||||||
$builder
|
$builder
|
||||||
@@ -88,16 +80,6 @@ final class EventListController extends AbstractController
|
|||||||
->addSearchBox(['name'])
|
->addSearchBox(['name'])
|
||||||
->addEntityChoice('event_types', 'event.filter.event_types', EventType::class, $types, [
|
->addEntityChoice('event_types', 'event.filter.event_types', EventType::class, $types, [
|
||||||
'choice_label' => fn (EventType $e) => $this->translatableStringHelper->localize($e->getName()),
|
'choice_label' => fn (EventType $e) => $this->translatableStringHelper->localize($e->getName()),
|
||||||
'expanded' => false,
|
|
||||||
'required' => false,
|
|
||||||
'attr' => ['class' => 'select2'],
|
|
||||||
])
|
|
||||||
->addUserPicker('responsables', 'event.filter.pick_responsable', ['multiple' => true, 'required' => false])
|
|
||||||
->addEntityChoice('centers', 'event.filter.center', Center::class, $centers, [
|
|
||||||
'choice_label' => fn (Center $c) => $c->getName(),
|
|
||||||
'expanded' => false,
|
|
||||||
'required' => false,
|
|
||||||
'attr' => ['class' => 'select2'],
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return $builder->build();
|
return $builder->build();
|
||||||
|
|||||||
@@ -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\EventBundle\Controller;
|
|
||||||
|
|
||||||
use Chill\MainBundle\CRUD\Controller\CRUDController;
|
|
||||||
use Chill\MainBundle\Pagination\PaginatorInterface;
|
|
||||||
use Doctrine\ORM\QueryBuilder;
|
|
||||||
use Symfony\Component\Form\FormInterface;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
|
|
||||||
class EventThemeController extends CRUDController
|
|
||||||
{
|
|
||||||
protected function createFormFor(string $action, $entity, ?string $formClass = null, array $formOptions = []): FormInterface
|
|
||||||
{
|
|
||||||
if ('new' === $action) {
|
|
||||||
return parent::createFormFor($action, $entity, $formClass, ['step' => 'create']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('edit' === $action) {
|
|
||||||
return parent::createFormFor($action, $entity, $formClass, ['step' => 'edit']);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new \LogicException('action is not supported: '.$action);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param QueryBuilder|mixed $query
|
|
||||||
*/
|
|
||||||
protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator): QueryBuilder
|
|
||||||
{
|
|
||||||
/* @var QueryBuilder $query */
|
|
||||||
return $query->orderBy('e.ordering', 'ASC')
|
|
||||||
->addOrderBy('e.id', 'ASC');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -228,7 +228,7 @@ final class ParticipationController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
return $this->redirectToRoute('chill_event__event_show', [
|
return $this->redirectToRoute('chill_event__event_show', [
|
||||||
'id' => $participation->getEvent()->getId(),
|
'event_id' => $participation->getEvent()->getId(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,7 +242,7 @@ final class ParticipationController extends AbstractController
|
|||||||
/**
|
/**
|
||||||
* @param int $participation_id
|
* @param int $participation_id
|
||||||
*/
|
*/
|
||||||
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/event/participation/{participation_id}/delete', name: 'chill_event_participation_delete', requirements: ['participation_id' => '\d+'])]
|
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/event/participation/{participation_id}/delete', name: 'chill_event_participation_delete', requirements: ['participation_id' => '\d+'], methods: ['GET', 'DELETE'])]
|
||||||
public function deleteAction($participation_id, Request $request): Response|\Symfony\Component\HttpFoundation\RedirectResponse
|
public function deleteAction($participation_id, Request $request): Response|\Symfony\Component\HttpFoundation\RedirectResponse
|
||||||
{
|
{
|
||||||
$em = $this->managerRegistry->getManager();
|
$em = $this->managerRegistry->getManager();
|
||||||
@@ -273,7 +273,7 @@ final class ParticipationController extends AbstractController
|
|||||||
);
|
);
|
||||||
|
|
||||||
return $this->redirectToRoute('chill_event__event_show', [
|
return $this->redirectToRoute('chill_event__event_show', [
|
||||||
'id' => $event->getId(),
|
'event_id' => $event->getId(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -442,7 +442,7 @@ final class ParticipationController extends AbstractController
|
|||||||
));
|
));
|
||||||
|
|
||||||
return $this->redirectToRoute('chill_event__event_show', [
|
return $this->redirectToRoute('chill_event__event_show', [
|
||||||
'id' => $participation->getEvent()->getId(),
|
'event_id' => $participation->getEvent()->getId(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,12 +11,6 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Chill\EventBundle\DependencyInjection;
|
namespace Chill\EventBundle\DependencyInjection;
|
||||||
|
|
||||||
use Chill\EventBundle\Controller\Admin\EventBudgetKindController;
|
|
||||||
use Chill\EventBundle\Controller\EventThemeController;
|
|
||||||
use Chill\EventBundle\Entity\EventBudgetKind;
|
|
||||||
use Chill\EventBundle\Entity\EventTheme;
|
|
||||||
use Chill\EventBundle\Form\EventBudgetKindType;
|
|
||||||
use Chill\EventBundle\Form\EventThemeType;
|
|
||||||
use Chill\EventBundle\Security\EventVoter;
|
use Chill\EventBundle\Security\EventVoter;
|
||||||
use Chill\EventBundle\Security\ParticipationVoter;
|
use Chill\EventBundle\Security\ParticipationVoter;
|
||||||
use Symfony\Component\Config\FileLocator;
|
use Symfony\Component\Config\FileLocator;
|
||||||
@@ -32,10 +26,7 @@ use Symfony\Component\HttpKernel\DependencyInjection\Extension;
|
|||||||
*/
|
*/
|
||||||
class ChillEventExtension extends Extension implements PrependExtensionInterface
|
class ChillEventExtension extends Extension implements PrependExtensionInterface
|
||||||
{
|
{
|
||||||
/**
|
public function load(array $configs, ContainerBuilder $container)
|
||||||
* @throws \Exception
|
|
||||||
*/
|
|
||||||
public function load(array $configs, ContainerBuilder $container): void
|
|
||||||
{
|
{
|
||||||
$configuration = new Configuration();
|
$configuration = new Configuration();
|
||||||
$config = $this->processConfiguration($configuration, $configs);
|
$config = $this->processConfiguration($configuration, $configs);
|
||||||
@@ -54,17 +45,16 @@ class ChillEventExtension extends Extension implements PrependExtensionInterface
|
|||||||
/** (non-PHPdoc).
|
/** (non-PHPdoc).
|
||||||
* @see \Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface::prepend()
|
* @see \Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface::prepend()
|
||||||
*/
|
*/
|
||||||
public function prepend(ContainerBuilder $container): void
|
public function prepend(ContainerBuilder $container)
|
||||||
{
|
{
|
||||||
$this->prependAuthorization($container);
|
$this->prependAuthorization($container);
|
||||||
$this->prependCruds($container);
|
|
||||||
$this->prependRoute($container);
|
$this->prependRoute($container);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* add authorization hierarchy.
|
* add authorization hierarchy.
|
||||||
*/
|
*/
|
||||||
protected function prependAuthorization(ContainerBuilder $container): void
|
protected function prependAuthorization(ContainerBuilder $container)
|
||||||
{
|
{
|
||||||
$container->prependExtensionConfig('security', [
|
$container->prependExtensionConfig('security', [
|
||||||
'role_hierarchy' => [
|
'role_hierarchy' => [
|
||||||
@@ -80,7 +70,7 @@ class ChillEventExtension extends Extension implements PrependExtensionInterface
|
|||||||
/**
|
/**
|
||||||
* add route to route loader for chill.
|
* add route to route loader for chill.
|
||||||
*/
|
*/
|
||||||
protected function prependRoute(ContainerBuilder $container): void
|
protected function prependRoute(ContainerBuilder $container)
|
||||||
{
|
{
|
||||||
// add routes for custom bundle
|
// add routes for custom bundle
|
||||||
$container->prependExtensionConfig('chill_main', [
|
$container->prependExtensionConfig('chill_main', [
|
||||||
@@ -91,54 +81,4 @@ class ChillEventExtension extends Extension implements PrependExtensionInterface
|
|||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function prependCruds(ContainerBuilder $container): void
|
|
||||||
{
|
|
||||||
$container->prependExtensionConfig('chill_main', [
|
|
||||||
'cruds' => [
|
|
||||||
[
|
|
||||||
'class' => EventTheme::class,
|
|
||||||
'name' => 'event_theme',
|
|
||||||
'base_path' => '/admin/event/theme',
|
|
||||||
'form_class' => EventThemeType::class,
|
|
||||||
'controller' => EventThemeController::class,
|
|
||||||
'actions' => [
|
|
||||||
'index' => [
|
|
||||||
'template' => '@ChillEvent/Admin/EventTheme/index.html.twig',
|
|
||||||
'role' => 'ROLE_ADMIN',
|
|
||||||
],
|
|
||||||
'new' => [
|
|
||||||
'role' => 'ROLE_ADMIN',
|
|
||||||
'template' => '@ChillEvent/Admin/EventTheme/new.html.twig',
|
|
||||||
],
|
|
||||||
'edit' => [
|
|
||||||
'role' => 'ROLE_ADMIN',
|
|
||||||
'template' => '@ChillEvent/Admin/EventTheme/edit.html.twig',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'class' => EventBudgetKind::class,
|
|
||||||
'name' => 'event_budget_kind',
|
|
||||||
'base_path' => '/admin/event/budget',
|
|
||||||
'form_class' => EventBudgetKindType::class,
|
|
||||||
'controller' => EventBudgetKindController::class,
|
|
||||||
'actions' => [
|
|
||||||
'index' => [
|
|
||||||
'template' => '@ChillEvent/Admin/BudgetKind/index.html.twig',
|
|
||||||
'role' => 'ROLE_ADMIN',
|
|
||||||
],
|
|
||||||
'new' => [
|
|
||||||
'role' => 'ROLE_ADMIN',
|
|
||||||
'template' => '@ChillEvent/Admin/BudgetKind/new.html.twig',
|
|
||||||
],
|
|
||||||
'edit' => [
|
|
||||||
'role' => 'ROLE_ADMIN',
|
|
||||||
'template' => '@ChillEvent/Admin/BudgetKind/edit.html.twig',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +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\EventBundle\Entity;
|
|
||||||
|
|
||||||
enum BudgetTypeEnum: string
|
|
||||||
{
|
|
||||||
case CHARGE = 'Charge';
|
|
||||||
case RESOURCE = 'Resource';
|
|
||||||
}
|
|
||||||
@@ -23,13 +23,10 @@ use Chill\MainBundle\Entity\HasScopeInterface;
|
|||||||
use Chill\MainBundle\Entity\Location;
|
use Chill\MainBundle\Entity\Location;
|
||||||
use Chill\MainBundle\Entity\Scope;
|
use Chill\MainBundle\Entity\Scope;
|
||||||
use Chill\MainBundle\Entity\User;
|
use Chill\MainBundle\Entity\User;
|
||||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
use Doctrine\Common\Collections\Collection;
|
use Doctrine\Common\Collections\Collection;
|
||||||
use Doctrine\DBAL\Types\Types;
|
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
use Symfony\Component\Validator\Constraints as Assert;
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
use Symfony\Component\Serializer\Annotation as Serializer;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Event.
|
* Class Event.
|
||||||
@@ -49,63 +46,35 @@ class Event implements HasCenterInterface, HasScopeInterface, TrackCreationInter
|
|||||||
#[ORM\ManyToOne(targetEntity: Scope::class)]
|
#[ORM\ManyToOne(targetEntity: Scope::class)]
|
||||||
private ?Scope $circle = null;
|
private ?Scope $circle = null;
|
||||||
|
|
||||||
#[ORM\Column(type: Types::DATETIME_MUTABLE)]
|
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::DATETIME_MUTABLE)]
|
||||||
private ?\DateTime $date = null;
|
private ?\DateTime $date = null;
|
||||||
|
|
||||||
#[ORM\Id]
|
#[ORM\Id]
|
||||||
#[ORM\Column(name: 'id', type: Types::INTEGER)]
|
#[ORM\Column(name: 'id', type: \Doctrine\DBAL\Types\Types::INTEGER)]
|
||||||
#[ORM\GeneratedValue(strategy: 'AUTO')]
|
#[ORM\GeneratedValue(strategy: 'AUTO')]
|
||||||
private ?int $id = null;
|
private ?int $id = null;
|
||||||
|
|
||||||
#[ORM\ManyToOne(targetEntity: User::class)]
|
#[ORM\ManyToOne(targetEntity: User::class)]
|
||||||
private ?User $moderator = null;
|
private ?User $moderator = null;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var Collection<int, User>
|
|
||||||
*/
|
|
||||||
#[ORM\ManyToMany(targetEntity: User::class)]
|
|
||||||
#[Serializer\Groups(['read'])]
|
|
||||||
#[ORM\JoinTable('chill_event_animatorsintern')]
|
|
||||||
private Collection $animatorsIntern;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var Collection<int, ThirdParty>
|
|
||||||
*/
|
|
||||||
#[ORM\ManyToMany(targetEntity: ThirdParty::class)]
|
|
||||||
#[Serializer\Groups(['read'])]
|
|
||||||
#[ORM\JoinTable('chill_event_animatorsextern')]
|
|
||||||
private Collection $animatorsExtern;
|
|
||||||
|
|
||||||
#[Assert\NotBlank]
|
#[Assert\NotBlank]
|
||||||
#[Serializer\Groups(['read'])]
|
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 150)]
|
||||||
#[ORM\Column(type: Types::STRING, length: 150)]
|
|
||||||
private ?string $name = null;
|
private ?string $name = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Collection<int, Participation>
|
* @var Collection<int, Participation>
|
||||||
*/
|
*/
|
||||||
#[ORM\OneToMany(mappedBy: 'event', targetEntity: Participation::class)]
|
#[ORM\OneToMany(mappedBy: 'event', targetEntity: Participation::class)]
|
||||||
#[Serializer\Groups(['read'])]
|
|
||||||
private Collection $participations;
|
private Collection $participations;
|
||||||
|
|
||||||
#[Assert\NotNull]
|
#[Assert\NotNull]
|
||||||
#[Serializer\Groups(['read'])]
|
|
||||||
#[ORM\ManyToOne(targetEntity: EventType::class)]
|
#[ORM\ManyToOne(targetEntity: EventType::class)]
|
||||||
private ?EventType $type = null;
|
private ?EventType $type = null;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var Collection<int, EventTheme>
|
|
||||||
*/
|
|
||||||
#[ORM\ManyToMany(targetEntity: EventTheme::class)]
|
|
||||||
#[Serializer\Groups(['read'])]
|
|
||||||
#[ORM\JoinTable('chill_event_eventtheme')]
|
|
||||||
private Collection $themes;
|
|
||||||
|
|
||||||
#[ORM\Embedded(class: CommentEmbeddable::class, columnPrefix: 'comment_')]
|
#[ORM\Embedded(class: CommentEmbeddable::class, columnPrefix: 'comment_')]
|
||||||
private CommentEmbeddable $comment;
|
private CommentEmbeddable $comment;
|
||||||
|
|
||||||
#[ORM\ManyToOne(targetEntity: Location::class)]
|
#[ORM\ManyToOne(targetEntity: Location::class)]
|
||||||
#[Serializer\Groups(['read'])]
|
|
||||||
#[ORM\JoinColumn(nullable: true)]
|
#[ORM\JoinColumn(nullable: true)]
|
||||||
private ?Location $location = null;
|
private ?Location $location = null;
|
||||||
|
|
||||||
@@ -116,17 +85,7 @@ class Event implements HasCenterInterface, HasScopeInterface, TrackCreationInter
|
|||||||
#[ORM\JoinTable('chill_event_event_documents')]
|
#[ORM\JoinTable('chill_event_event_documents')]
|
||||||
private Collection $documents;
|
private Collection $documents;
|
||||||
|
|
||||||
/**
|
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::DECIMAL, precision: 10, scale: 4, nullable: true, options: ['default' => '0.0'])]
|
||||||
* @var Collection<int, EventBudgetElement>
|
|
||||||
*/
|
|
||||||
#[ORM\OneToMany(mappedBy: 'event', targetEntity: EventBudgetElement::class, cascade: ['persist'])]
|
|
||||||
#[Serializer\Groups(['read'])]
|
|
||||||
private Collection $budgetElements;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated use budgetElements instead
|
|
||||||
*/
|
|
||||||
#[ORM\Column(type: Types::DECIMAL, precision: 10, scale: 4, nullable: true, options: ['default' => '0.0'])]
|
|
||||||
private string $organizationCost = '0.0';
|
private string $organizationCost = '0.0';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -137,20 +96,6 @@ class Event implements HasCenterInterface, HasScopeInterface, TrackCreationInter
|
|||||||
$this->participations = new ArrayCollection();
|
$this->participations = new ArrayCollection();
|
||||||
$this->documents = new ArrayCollection();
|
$this->documents = new ArrayCollection();
|
||||||
$this->comment = new CommentEmbeddable();
|
$this->comment = new CommentEmbeddable();
|
||||||
$this->themes = new ArrayCollection();
|
|
||||||
$this->budgetElements = new ArrayCollection();
|
|
||||||
$this->animatorsIntern = new ArrayCollection();
|
|
||||||
$this->animatorsExtern = new ArrayCollection();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addBudgetElement(EventBudgetElement $budgetElement)
|
|
||||||
{
|
|
||||||
if (!$this->budgetElements->contains($budgetElement)) {
|
|
||||||
$this->budgetElements[] = $budgetElement;
|
|
||||||
$budgetElement->setEvent($this);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -181,79 +126,38 @@ class Event implements HasCenterInterface, HasScopeInterface, TrackCreationInter
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getThemes(): Collection
|
/**
|
||||||
{
|
* @return Center
|
||||||
return $this->themes;
|
*/
|
||||||
}
|
public function getCenter()
|
||||||
|
|
||||||
public function addTheme(EventTheme $theme): self
|
|
||||||
{
|
|
||||||
$this->themes->add($theme);
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function removeTheme(EventTheme $theme): void
|
|
||||||
{
|
|
||||||
$this->themes->removeElement($theme);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAnimatorsIntern(): Collection
|
|
||||||
{
|
|
||||||
return $this->animatorsIntern;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAnimatorsExtern(): Collection
|
|
||||||
{
|
|
||||||
return $this->animatorsExtern;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addAnimatorsIntern(User $ai): self
|
|
||||||
{
|
|
||||||
$this->animatorsIntern->add($ai);
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function removeAnimatorsIntern(User $ai): void
|
|
||||||
{
|
|
||||||
$this->animatorsIntern->removeElement($ai);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addAnimatorsExtern(ThirdParty $ae): self
|
|
||||||
{
|
|
||||||
$this->animatorsExtern->add($ae);
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function removeAnimatorsExtern(ThirdParty $ae): void
|
|
||||||
{
|
|
||||||
$this->animatorsExtern->removeElement($ae);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getCenter(): Center
|
|
||||||
{
|
{
|
||||||
return $this->center;
|
return $this->center;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getCircle(): ?Scope
|
/**
|
||||||
|
* @return Scope
|
||||||
|
*/
|
||||||
|
public function getCircle()
|
||||||
{
|
{
|
||||||
return $this->circle;
|
return $this->circle;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get date.
|
* Get date.
|
||||||
|
*
|
||||||
|
* @return \DateTime
|
||||||
*/
|
*/
|
||||||
public function getDate(): ?\DateTime
|
public function getDate()
|
||||||
{
|
{
|
||||||
return $this->date;
|
return $this->date;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get id.
|
* Get id.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function getId(): ?int
|
public function getId()
|
||||||
{
|
{
|
||||||
return $this->id;
|
return $this->id;
|
||||||
}
|
}
|
||||||
@@ -265,20 +169,14 @@ class Event implements HasCenterInterface, HasScopeInterface, TrackCreationInter
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get label.
|
* Get label.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getName(): ?string
|
public function getName()
|
||||||
{
|
{
|
||||||
return $this->name;
|
return $this->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Collection<int, EventBudgetElement>
|
|
||||||
*/
|
|
||||||
public function getBudgetElements(): Collection
|
|
||||||
{
|
|
||||||
return $this->budgetElements;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Collection<int, Participation>
|
* @return Collection<int, Participation>
|
||||||
*/
|
*/
|
||||||
@@ -301,26 +199,26 @@ class Event implements HasCenterInterface, HasScopeInterface, TrackCreationInter
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated
|
* @deprecated
|
||||||
|
*
|
||||||
|
* @return Scope
|
||||||
*/
|
*/
|
||||||
public function getScope(): Scope
|
public function getScope()
|
||||||
{
|
{
|
||||||
return $this->getCircle();
|
return $this->getCircle();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getType(): ?EventType
|
/**
|
||||||
|
* @return EventType
|
||||||
|
*/
|
||||||
|
public function getType()
|
||||||
{
|
{
|
||||||
return $this->type;
|
return $this->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function removeBudgetElement(EventBudgetElement $budgetElement): void
|
|
||||||
{
|
|
||||||
$this->budgetElements->removeElement($budgetElement);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove participation.
|
* Remove participation.
|
||||||
*/
|
*/
|
||||||
public function removeParticipation(Participation $participation): void
|
public function removeParticipation(Participation $participation)
|
||||||
{
|
{
|
||||||
$this->participations->removeElement($participation);
|
$this->participations->removeElement($participation);
|
||||||
}
|
}
|
||||||
@@ -416,17 +314,11 @@ class Event implements HasCenterInterface, HasScopeInterface, TrackCreationInter
|
|||||||
$this->documents = $documents;
|
$this->documents = $documents;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated
|
|
||||||
*/
|
|
||||||
public function getOrganizationCost(): string
|
public function getOrganizationCost(): string
|
||||||
{
|
{
|
||||||
return $this->organizationCost;
|
return $this->organizationCost;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated
|
|
||||||
*/
|
|
||||||
public function setOrganizationCost(string $organizationCost): void
|
public function setOrganizationCost(string $organizationCost): void
|
||||||
{
|
{
|
||||||
$this->organizationCost = $organizationCost;
|
$this->organizationCost = $organizationCost;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user