Compare commits

..

126 Commits

Author SHA1 Message Date
69b59d2ae2 Correct syntax in .env file for redis_url 2025-09-11 14:03:24 +02:00
90f86bf566 fix CalendarNormalizerTest.php 2025-09-11 14:03:01 +02:00
b363bd3425 fix CalendarRangeSyncerTest.php 2025-09-11 12:50:24 +02:00
6ceb1b9544 Attempt fix ActivityVoterTest.php 2025-09-11 12:44:06 +02:00
94b5c06d10 Fix TranslatableActivityTypeTest.php 2025-09-11 12:12:29 +02:00
895e1be9ef Fix fixtures
- Inject parameters directly instead of getting from container
- User PasswordHasher instead of EncoderFactory
- set parameters directly and correctly encode values to json
2025-09-11 11:44:53 +02:00
94a0eb1a0a Fix ActivityTest.php to use setParent() instead of addChild() method. Latest version of Doctrine stricter in keeping relationships synced. 2025-09-11 09:57:10 +02:00
cc8151546a Undo inadequate fix of normalizers 2025-09-11 09:40:37 +02:00
4bd9e2ba7d fix: update CRUD routing controller syntax
- Replace `:` with `::` for `_controller` to align with modern Symfony standards
2025-09-10 17:12:14 +02:00
509b2c2590 fix: circular reference problems during fetches
- Add code snippet to avoid circular reference in SocialActionNormalizer.php, AccompanyingPeriodWorkEvaluationDocumentNormalizer.php, AccompanyingPeriodWorkEvaluationNormalizer.php, and AccompanyingPeriodWorkNormalizer.php
2025-09-10 15:06:13 +02:00
3480495be1 fix: update configuration of TrackCreateUpdateSubscriber.php
- Update config to be conform with symfony 7.3
- Create unit test for TrackCreateUpdateSubscriber.php
2025-09-10 13:24:50 +02:00
4123aa6550 Merge branch 'master' into migrate_to_sf72 2025-09-09 17:42:28 +02:00
835d79a809 refactor: adjust TrackCreateUpdateSubscriber for strict types and improve user handling
- Add `readonly` class and typed method return values
- Replace `LifecycleEventArgs` with specific `PrePersistEventArgs` and `PreUpdateEventArgs`
- Simplify `DateTimeImmutable` instantiation
- Enhance user retrieval using variable assignment for type-checking
2025-09-09 17:41:03 +02:00
2a280b814f Refactor view templates: relocate 'merge' action block and standardize 'duplicate link' block handling 2025-09-09 17:36:46 +02:00
ffeba3818b refactor: improve test setup and entity references in SingleTaskControllerTest
- Remove unnecessary kernel boot in `setUp`
- Use DI container retrieval for entity manager
- Replace string class references with `::class` constants
2025-09-09 17:09:33 +02:00
f88718e263 fix: update CalendarTypeTest to use ATOM date format
- Adjust assertions to use `ATOM` date format for `startDate` and `endDate`
2025-09-09 16:08:27 +02:00
2433737df0 refactor: remove unused event arguments from entity listener methods
- Simplify method signatures by removing `$eventArgs` parameter
2025-09-09 16:01:17 +02:00
af7d635714 fix: update tests and exports to use consistent class references
- Use `NativeQuery` instead of `AbstractQuery` in `SummaryBudgetTest`
- Replace string entity reference with `Activity::class` in `ListActivity`
2025-09-09 16:00:55 +02:00
34213ac093 fix: allow null safe navigation in ByActivityTypeAggregator normalizeFormData method 2025-09-09 15:58:53 +02:00
8d6f76a8b7 Fix import of Security 2025-09-09 09:35:12 +02:00
941acea4d9 Merge branch 'master' into migrate_to_sf72
# Conflicts:
#	src/Bundle/ChillEventBundle/Controller/EventController.php
#	src/Bundle/ChillEventBundle/Controller/ParticipationController.php
#	src/Bundle/ChillEventBundle/DependencyInjection/ChillEventExtension.php
#	src/Bundle/ChillEventBundle/Entity/Event.php
#	src/Bundle/ChillEventBundle/Form/EventType.php
#	src/Bundle/ChillEventBundle/Menu/AdminMenuBuilder.php
#	src/Bundle/ChillEventBundle/config/services.yaml
#	src/Bundle/ChillEventBundle/config/services/controller.yaml
#	src/Bundle/ChillMainBundle/Resources/views/Menu/user.html.twig
#	src/Bundle/ChillPersonBundle/Controller/AccompanyingPeriodWorkDuplicateController.php
#	src/Bundle/ChillPersonBundle/Controller/PersonController.php
#	src/Bundle/ChillPersonBundle/Form/PersonType.php
2025-09-09 09:33:27 +02:00
230c758255 Update bundles to v4.3.0 2025-09-08 16:05:09 +02:00
eafda987ae Merge branch '412-absence-enddate' into 'master'
Resolve "Absence user: add end date"

Closes #412

See merge request Chill-Projet/chill-bundles!865
2025-09-08 13:47:14 +00:00
7db8a371fc Resolve "Absence user: add end date" 2025-09-08 13:47:14 +00:00
0d0649dd31 Change route URL to avoid clash with person duplicate controller method 2025-09-08 14:51:54 +02:00
77bccd5c4e Remove deprecated ContainerAwareTrait 2025-08-27 17:01:06 +02:00
5ffa945a84 Remove Symfony and ChampsLibres folders 2025-08-27 17:00:49 +02:00
3a85d940e9 Replace deprecated ClassUtils 2025-08-27 16:41:40 +02:00
d2e7640652 Upgrade Doctrine ORM to 3.5.2 2025-08-27 16:33:10 +02:00
979b2955f6 Rector changes return typing 2025-08-27 16:32:44 +02:00
da240f5ce5 Use WorkflowInterface instead of Workflow 2025-08-27 16:01:01 +02:00
f91ab63b3a Use $query->all() instead of ->() for non-scalar values 2025-08-27 15:59:56 +02:00
2ea8a03698 Use correct key for workflow labels 2025-08-27 15:58:48 +02:00
21e965449c refactor(config): update service definitions for autowiring and controller configuration
- Enable autowiring for Chill\EventBundle\Controller
- Add default autowire and autoconfigure settings
2025-08-05 13:49:20 +02:00
88697ae83f chore: update dependencies and configure services
- bump symfony/security-bundle to ^7.3 in composer.json
- enable autoconfigure for Chill\CalendarBundle\Controller services
2025-08-05 11:21:52 +02:00
10ba2aaea5 feat: update symfony/amqp-messenger to v7.3
- Added symfony/amqp-messenger v7.3 to dependencies
- Removed symfony/amqp-messenger v7.2 from dev dependencies
2025-08-05 11:03:43 +02:00
4b484bd16c refactor(entity): use TrackCreationTrait and TrackUpdateTrait in AsideActivity
- Replace manual tracking of createdAt, createdBy, updatedAt, updatedBy with TrackCreationTrait and TrackUpdateTrait
- Remove related properties and methods
2025-08-05 09:04:22 +02:00
4c28a4c358 refactor: improve property checks
- use ClassUtils for real class name resolution in ActivityType
2025-08-05 09:03:53 +02:00
490d546e7a ```
refactor: add type hints and improve method signatures

- add return type declarations to methods in `ExportGenerationVoter`
- add type hints to `EntityToJsonTransformer` methods
- include `ExceptionInterface` in `EntityToJsonTransformer` for better error handling
```
2025-08-04 17:16:42 +02:00
7a4416109e Replace Security component with SecurityBundle
Updated references from Symfony\Component\Security\Core\Security
to Symfony\Bundle\SecurityBundle\Security across multiple files
to align with the updated namespace and improve compatibility.
2025-08-04 17:02:23 +02:00
0e1a47a49b Merge branch 'master' into migrate_to_sf72
# Conflicts:
#	docs/source/_static/code/exports/BirthdateFilter.php
#	rector.php
#	src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByActivityTypeAggregator.php
#	src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialActionAggregator.php
#	src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/BySocialIssueAggregator.php
#	src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityLocationAggregator.php
#	src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityPresenceAggregator.php
#	src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityReasonAggregator.php
#	src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityTypeAggregator.php
#	src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUserAggregator.php
#	src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersAggregator.php
#	src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersJobAggregator.php
#	src/Bundle/ChillActivityBundle/Export/Aggregator/ActivityUsersScopeAggregator.php
#	src/Bundle/ChillActivityBundle/Export/Aggregator/ByCreatorAggregator.php
#	src/Bundle/ChillActivityBundle/Export/Aggregator/ByThirdpartyAggregator.php
#	src/Bundle/ChillActivityBundle/Export/Aggregator/CreatorJobAggregator.php
#	src/Bundle/ChillActivityBundle/Export/Aggregator/CreatorScopeAggregator.php
#	src/Bundle/ChillActivityBundle/Export/Aggregator/DateAggregator.php
#	src/Bundle/ChillActivityBundle/Export/Aggregator/LocationTypeAggregator.php
#	src/Bundle/ChillActivityBundle/Export/Aggregator/PersonAggregators/HouseholdAggregator.php
#	src/Bundle/ChillActivityBundle/Export/Aggregator/PersonAggregators/PersonAggregator.php
#	src/Bundle/ChillActivityBundle/Export/Aggregator/PersonsAggregator.php
#	src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityDuration.php
#	src/Bundle/ChillActivityBundle/Export/Export/LinkedToACP/SumActivityVisitDuration.php
#	src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/ActivityTypeFilter.php
#	src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialActionFilter.php
#	src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/BySocialIssueFilter.php
#	src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/HasNoActivityFilter.php
#	src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/PeriodHavingActivityBetweenDatesFilter.php
#	src/Bundle/ChillActivityBundle/Export/Filter/ActivityDateFilter.php
#	src/Bundle/ChillActivityBundle/Export/Filter/ActivityPresenceFilter.php
#	src/Bundle/ChillActivityBundle/Export/Filter/ActivityTypeFilter.php
#	src/Bundle/ChillActivityBundle/Export/Filter/ActivityUsersFilter.php
#	src/Bundle/ChillActivityBundle/Export/Filter/ByCreatorFilter.php
#	src/Bundle/ChillActivityBundle/Export/Filter/CreatorJobFilter.php
#	src/Bundle/ChillActivityBundle/Export/Filter/CreatorScopeFilter.php
#	src/Bundle/ChillActivityBundle/Export/Filter/EmergencyFilter.php
#	src/Bundle/ChillActivityBundle/Export/Filter/LocationFilter.php
#	src/Bundle/ChillActivityBundle/Export/Filter/LocationTypeFilter.php
#	src/Bundle/ChillActivityBundle/Export/Filter/PersonFilters/ActivityReasonFilter.php
#	src/Bundle/ChillActivityBundle/Export/Filter/PersonsFilter.php
#	src/Bundle/ChillActivityBundle/Export/Filter/SentReceivedFilter.php
#	src/Bundle/ChillActivityBundle/Export/Filter/UserFilter.php
#	src/Bundle/ChillActivityBundle/Export/Filter/UsersJobFilter.php
#	src/Bundle/ChillActivityBundle/Export/Filter/UsersScopeFilter.php
#	src/Bundle/ChillActivityBundle/Validator/Constraints/ActivityValidity.php
#	src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByActivityTypeAggregator.php
#	src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserJobAggregator.php
#	src/Bundle/ChillAsideActivityBundle/src/Export/Aggregator/ByUserScopeAggregator.php
#	src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByActivityTypeFilter.php
#	src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByDateFilter.php
#	src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserFilter.php
#	src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserJobFilter.php
#	src/Bundle/ChillAsideActivityBundle/src/Export/Filter/ByUserScopeFilter.php
#	src/Bundle/ChillCalendarBundle/Export/Aggregator/AgentAggregator.php
#	src/Bundle/ChillCalendarBundle/Export/Aggregator/CancelReasonAggregator.php
#	src/Bundle/ChillCalendarBundle/Export/Aggregator/JobAggregator.php
#	src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationAggregator.php
#	src/Bundle/ChillCalendarBundle/Export/Aggregator/LocationTypeAggregator.php
#	src/Bundle/ChillCalendarBundle/Export/Aggregator/MonthYearAggregator.php
#	src/Bundle/ChillCalendarBundle/Export/Aggregator/ScopeAggregator.php
#	src/Bundle/ChillCalendarBundle/Export/Aggregator/UrgencyAggregator.php
#	src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php
#	src/Bundle/ChillCalendarBundle/Export/Filter/BetweenDatesFilter.php
#	src/Bundle/ChillCalendarBundle/Export/Filter/CalendarRangeFilter.php
#	src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php
#	src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php
#	src/Bundle/ChillEventBundle/Export/Aggregator/EventDateAggregator.php
#	src/Bundle/ChillEventBundle/Export/Aggregator/EventTypeAggregator.php
#	src/Bundle/ChillEventBundle/Export/Aggregator/RoleAggregator.php
#	src/Bundle/ChillEventBundle/Export/Filter/EventDateFilter.php
#	src/Bundle/ChillEventBundle/Export/Filter/EventTypeFilter.php
#	src/Bundle/ChillEventBundle/Export/Filter/RoleFilter.php
#	src/Bundle/ChillMainBundle/Controller/ExportController.php
#	src/Bundle/ChillMainBundle/Controller/SavedExportController.php
#	src/Bundle/ChillMainBundle/DependencyInjection/CompilerPass/ExportsCompilerPass.php
#	src/Bundle/ChillMainBundle/Entity/Notification.php
#	src/Bundle/ChillMainBundle/Export/ExportManager.php
#	src/Bundle/ChillMainBundle/Export/Formatter/CSVFormatter.php
#	src/Bundle/ChillMainBundle/Export/Formatter/CSVListFormatter.php
#	src/Bundle/ChillMainBundle/Export/Formatter/CSVPivotedListFormatter.php
#	src/Bundle/ChillMainBundle/Export/Formatter/SpreadSheetFormatter.php
#	src/Bundle/ChillMainBundle/Export/Formatter/SpreadsheetListFormatter.php
#	src/Bundle/ChillMainBundle/Form/SavedExportType.php
#	src/Bundle/ChillMainBundle/Form/Type/DataTransformer/EntityToJsonTransformer.php
#	src/Bundle/ChillMainBundle/Tests/Export/ExportManagerTest.php
#	src/Bundle/ChillMainBundle/Tests/Export/SortExportElementTest.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/AdministrativeLocationAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ClosingDateAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ClosingMotiveAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ConfidentialAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/CreatorJobAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/DurationAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EmergencyAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/EvaluationAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/GeographicalUnitStatAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/IntensityAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/JobWorkingOnCourseAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/OpeningDateAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/OriginAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/PersonParticipatingAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ReferrerScopeAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/RequestorAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ScopeAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/ScopeWorkingOnCourseAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialActionAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/SocialIssueAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/StepAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/UserJobAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingCourseAggregators/UserWorkingOnCourseAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByClosingMotiveAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByDateAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/AccompanyingPeriodStepHistoryAggregators/ByStepAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByEndDateAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByMaxDateAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/ByStartDateAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/EvaluationTypeAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/EvaluationAggregators/HavingEndDateAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/ChildrenNumberAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/HouseholdAggregators/CompositionAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/AdministrativeStatusAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/AgeAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/ByHouseholdCompositionAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/CenterAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/EmploymentStatusAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GenderAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/HouseholdPositionAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/MaritalStatusAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/NationalityAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/PostalCodeAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ActionTypeAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/CreatorAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/CreatorJobAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/CreatorScopeAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/GoalResultAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/HandlingThirdPartyAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/JobAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ReferrerAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ResultAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Aggregator/SocialWorkAggregators/ScopeAggregator.php
#	src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActiveOnDateFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ActiveOneDayBetweenDatesFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/AdministrativeLocationFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ClosingMotiveFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ConfidentialFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/CreatorFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/CreatorJobFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/EmergencyFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/EvaluationFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/GeographicalUnitStatFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HandlingThirdPartyFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasNoReferrerFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/HasTemporaryLocationFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/IntensityFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/NotAssociatedWithAReferenceAddressFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OpenBetweenDatesFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/OriginFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ReferrerFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/ReferrerFilterBetweenDates.php
#	src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/RequestorFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialActionFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/SocialIssueFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/StepFilterBetweenDates.php
#	src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/StepFilterOnDate.php
#	src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingCourseFilters/UserJobFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingPeriodStepHistoryFilters/ByDateFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/AccompanyingPeriodStepHistoryFilters/ByStepFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/EvaluationTypeFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/EvaluationFilters/MaxDateFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AddressRefStatusFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/AgeFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/BirthdateFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ByHouseholdCompositionFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeadOrAliveFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/DeathdateFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GenderFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GeographicalUnitFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/MaritalStatusFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/NationalityFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtThirdpartyFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/ResidentialAddressAtUserFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/WithParticipationBetweenDatesFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/WithoutHouseholdComposition.php
#	src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/WithoutParticipationBetweenDatesFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/CreatorFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/CreatorJobFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/CreatorScopeFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/JobFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/ReferrerFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/ScopeFilter.php
#	src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php
#	src/Bundle/ChillPersonBundle/Export/Helper/FilterListAccompanyingPeriodHelper.php
#	src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php
#	src/Bundle/ChillPersonBundle/Tests/Export/Export/ListAccompanyingPeriodTest.php
#	src/Bundle/ChillPersonBundle/Validator/Constraints/AccompanyingPeriod/AccompanyingPeriodValidity.php
#	src/Bundle/ChillPersonBundle/Validator/Constraints/AccompanyingPeriod/ConfidentialCourseMustHaveReferrer.php
#	src/Bundle/ChillPersonBundle/Validator/Constraints/AccompanyingPeriod/LocationValidity.php
#	src/Bundle/ChillPersonBundle/Validator/Constraints/Household/MaxHolder.php
#	src/Bundle/ChillReportBundle/Export/Export/ReportList.php
#	src/Bundle/ChillReportBundle/Export/Filter/ReportDateFilter.php
2025-08-04 16:57:45 +02:00
26298c48fd Merge branch with master 2025-07-01 16:43:44 +02:00
4d4bcb44bc Merge branch 'migrate_to_sf72' of https://gitlab.com/Chill-Projet/chill-bundles into migrate_to_sf72 2025-06-05 16:31:08 +02:00
51777f7365 Some file additions after rebase on master 2025-06-05 16:29:01 +02:00
b9a9983b88 Inject services, no longer available in container by default 2025-06-05 16:23:23 +02:00
e51a3c7525 Rename key property_info.with_constructor_extractor to just enabled: true 2025-06-05 16:23:23 +02:00
9875f49374 Replace methods with injected services 2025-06-05 16:23:23 +02:00
52c3c0a565 Rector file with symfonysetlist rules up to symfony_71 2025-06-05 16:23:23 +02:00
640a7bcd0a Correct injection of services 2025-06-05 16:23:23 +02:00
13a9e14450 Run symfonysetlist up to symfony_70 2025-06-05 16:23:21 +02:00
abb786495a Run symfonysetlist symfony_62 2025-06-05 16:21:19 +02:00
8ec18a6fb8 Use [#MapEntity()] attribute to inject entity into method + for now set controller_resolver.auto_mapping to true 2025-06-05 16:21:19 +02:00
f282ffbfd4 Remove not null constraint in db on updatedat property for notification 2025-06-05 16:21:19 +02:00
27a2d8fdc8 Remove double services key: silent error triggering on this will be deprecated 2025-06-05 16:21:19 +02:00
1cb63bfe1d Use FQCN::method to build CRUD routes 2025-06-05 16:21:19 +02:00
9daa7f7c09 Update framework recipe 2025-06-05 16:21:19 +02:00
b6e780d573 Update symfony flex recipe 2025-06-05 16:21:19 +02:00
7e3618a9be Update phpunit recipe 2025-06-05 16:21:19 +02:00
61b187e340 Update doctrine/annotations recipe 2025-06-05 16:21:19 +02:00
abfdf2ec6d Inject managerRegistry and serializerInterface directly into controllers 2025-06-05 16:21:19 +02:00
cc20e8896f Use userIdentifier instead of deprecated getUsername() 2025-06-05 16:21:19 +02:00
59fe9a469a Set alias to inject container into AbstractController::setContainer() 2025-06-05 16:21:18 +02:00
228b4f0b3d set typed ?string properties to '= null' 2025-06-05 16:21:18 +02:00
b5bbf929f6 Uncomment necessary config 2025-06-05 16:21:18 +02:00
d9ce4e3ec6 Inject ManagerRegistry directly instead of getting from container 2025-06-05 16:21:18 +02:00
c08c909545 Remove NOT NULL constraint from created and updated properties 2025-06-05 16:21:18 +02:00
6cd17a8e36 Remove containerAwareInterface, no longer supported in sf72 2025-06-05 16:21:18 +02:00
e3b2b7c6d1 Make doctrine service available, no longer by default in scoped service locator 2025-06-05 16:21:18 +02:00
0337bca273 Adjust workflow config, label needs to be a string 2025-06-05 16:21:18 +02:00
8bb2e2dc37 Add missing return statement 2025-06-05 16:21:18 +02:00
cdd0372d3e Update security config (guidelines sf64) 2025-06-05 16:21:18 +02:00
1ee16d3446 Uncomment necessary controller config in mainbundle 2025-06-05 16:21:18 +02:00
bdbcb9ca4a Update symfony packages and necessary config (auto) 2025-06-05 16:21:18 +02:00
e639289130 Remove ContainerAwareInterface from CustomFieldProvider.php 2025-06-05 16:21:18 +02:00
3d3347e547 Remove config for controller; Symfony will find and load them automatically 2025-06-05 16:21:18 +02:00
3f27d9e8fc Class cannot be final if you want to use lazy proxy 2025-06-05 16:21:18 +02:00
ce98b9ae48 Use type attribute instead of annotations 2025-06-05 16:21:18 +02:00
d2bd17632f Remove ContainerAwareInterface and extend Fixture instead 2025-06-05 16:21:18 +02:00
7cef5e3a76 Get session from requestStack instead of injecting SessionInterface 2025-06-05 16:21:18 +02:00
9726844a26 Remove this config. Symfony will still find and load controllers via annotations or attributes 2025-06-05 16:21:18 +02:00
f7ce3996ef Add name argument to AsCommand attribute and replace Security service namespace with new namespace Symfony\Bundle\SecurityBundle\Security 2025-06-05 16:21:17 +02:00
6e21f2688f Add getSupportedTypes method for (de)normalizerInterface implementations 2025-06-05 16:21:17 +02:00
17db59d221 Rector changes and immplementations of required methods 2025-06-05 16:21:17 +02:00
053b92b77c Update configuration to comply with symfony 7.2 2025-06-05 16:21:17 +02:00
eab5a8be7b Do not show job menu entry if user does not have necessary permission 2025-06-05 16:21:17 +02:00
36fd6f10b2 Inject services, no longer available in container by default 2025-06-03 15:08:26 +02:00
23227add12 Rename key property_info.with_constructor_extractor to just enabled: true 2025-06-03 14:52:42 +02:00
8cbd800fb9 Replace methods with injected services 2025-06-03 14:50:58 +02:00
1f79985193 Rector file with symfonysetlist rules up to symfony_71 2025-05-28 16:10:59 +02:00
f4ed7e4254 Correct injection of services 2025-05-28 16:10:07 +02:00
382f20c6ad Run symfonysetlist up to symfony_70 2025-05-28 15:46:25 +02:00
220110a403 Run symfonysetlist symfony_62 2025-05-28 15:17:20 +02:00
3fdf494f1c Use [#MapEntity()] attribute to inject entity into method + for now set controller_resolver.auto_mapping to true 2025-05-28 14:58:59 +02:00
793dcbfa9a Remove not null constraint in db on updatedat property for notification 2025-05-28 14:54:25 +02:00
f96ed1f5eb Remove double services key: silent error triggering on this will be deprecated 2025-05-28 14:33:36 +02:00
8b9b427a1e Use FQCN::method to build CRUD routes 2025-05-28 14:32:59 +02:00
2f3caafd10 Update framework recipe 2025-05-28 12:51:53 +02:00
fde10ebe71 Update symfony flex recipe 2025-05-28 12:49:33 +02:00
b7fc85a2c9 Update phpunit recipe 2025-05-28 12:48:53 +02:00
72b79f9af5 Update doctrine/annotations recipe 2025-05-28 12:42:57 +02:00
ab15ec8a4c Inject managerRegistry and serializerInterface directly into controllers 2025-05-28 12:04:27 +02:00
c8f1e67fc7 Use userIdentifier instead of deprecated getUsername() 2025-05-28 11:23:51 +02:00
d5c09c853f Set alias to inject container into AbstractController::setContainer() 2025-05-28 11:21:55 +02:00
a79b0b85dd set typed ?string properties to '= null' 2025-05-28 10:47:23 +02:00
47c1282044 Uncomment necessary config 2025-05-27 15:19:28 +02:00
ce63506a1a Inject ManagerRegistry directly instead of getting from container 2025-05-27 15:19:15 +02:00
8ab03473b7 Remove NOT NULL constraint from created and updated properties 2025-05-27 15:18:32 +02:00
ebaff8d170 Remove containerAwareInterface, no longer supported in sf72 2025-05-27 14:06:36 +02:00
46f9e4968b Make doctrine service available, no longer by default in scoped service locator 2025-05-27 13:03:43 +02:00
344c5a1c3c Adjust workflow config, label needs to be a string 2025-05-27 12:44:03 +02:00
50b590ae34 Add missing return statement 2025-05-27 12:43:45 +02:00
74fbd6feac Update security config (guidelines sf64) 2025-05-27 12:43:35 +02:00
aa69a7ad62 Uncomment necessary controller config in mainbundle 2025-05-27 12:43:10 +02:00
bc0fae5c2e Update symfony packages and necessary config (auto) 2025-05-27 12:42:41 +02:00
1321f5c734 Remove ContainerAwareInterface from CustomFieldProvider.php 2025-05-26 14:55:39 +02:00
262b7c5db3 Remove config for controller; Symfony will find and load them automatically 2025-05-26 14:55:15 +02:00
5283eddb15 Class cannot be final if you want to use lazy proxy 2025-05-26 14:54:47 +02:00
f7b0c49124 Use type attribute instead of annotations 2025-05-26 14:54:05 +02:00
5e32375dfe Remove ContainerAwareInterface and extend Fixture instead 2025-05-26 14:32:06 +02:00
5cdfee40fb Get session from requestStack instead of injecting SessionInterface 2025-05-26 14:19:01 +02:00
6e5dbe4e58 Remove this config. Symfony will still find and load controllers via annotations or attributes 2025-05-26 14:07:23 +02:00
d884d78617 Add name argument to AsCommand attribute and replace Security service namespace with new namespace Symfony\Bundle\SecurityBundle\Security 2025-05-26 13:58:12 +02:00
a5049ddefb Add getSupportedTypes method for (de)normalizerInterface implementations 2025-05-26 13:49:05 +02:00
9fcc1634f5 Rector changes and immplementations of required methods 2025-05-22 17:47:07 +02:00
d9a47fdee9 Update configuration to comply with symfony 7.2 2025-05-22 17:45:52 +02:00
1e5d676aa5 Do not show job menu entry if user does not have necessary permission 2025-05-22 15:25:11 +02:00
1716 changed files with 31504 additions and 50184 deletions

View File

@@ -1,6 +0,0 @@
kind: Feature
body: |
Upgrade import of address list to the last version of compiled addresses of belgian-best-address
time: 2024-05-30T16:00:03.440767606+02:00
custom:
Issue: ""

View File

@@ -1,6 +0,0 @@
kind: Feature
body: |
Upgrade CKEditor and refactor configuration with use of typescript
time: 2024-05-31T19:02:42.776662753+02:00
custom:
Issue: ""

View File

@@ -1,6 +0,0 @@
kind: Feature
body: Add a command to generate a list of permissions
time: 2025-09-04T18:10:32.334524026+02:00
custom:
Issue: ""
SchemaChange: No schema change

View File

@@ -0,0 +1,6 @@
kind: Fixed
body: Fix display of 'duplicate' and 'merge' buttons in CRUD templates
time: 2025-09-09T17:36:39.960419639+02:00
custom:
Issue: ""
SchemaChange: No schema change

10
.changes/v4.3.0.md Normal file
View File

@@ -0,0 +1,10 @@
## 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

View File

@@ -19,11 +19,11 @@ max_line_length = 80
[COMMIT_EDITMSG] [COMMIT_EDITMSG]
max_line_length = 0 max_line_length = 0
[*.{js,vue,ts}] [*.{js, vue, ts}]
indent_size = 2 indent_size = 2
indent_style = space indent_style = space
[*.rst] [.rst]
indent_size = 3 ident_size = 3
indent_style = space ident_style = space

2
.env
View File

@@ -86,7 +86,7 @@ ADD_ADDRESS_MAP_CENTER_Z=15
## Redis Cache & redis database ## Redis Cache & redis database
REDIS_HOST=redis REDIS_HOST=redis
REDIS_PORT=6379 REDIS_PORT=6379
REDIS_URL=redis://${REDIS_HOST}:${REDIS_PORT} REDIS_URL="redis://${REDIS_HOST}:${REDIS_PORT}"
###< chill-project/chill-bundles ### ###< chill-project/chill-bundles ###
###> symfony/ovh-cloud-notifier ### ###> symfony/ovh-cloud-notifier ###

4
.env.dev Normal file
View File

@@ -0,0 +1,4 @@
###> symfony/framework-bundle ###
APP_SECRET=72759e571285ef25677c88f967a73386
###< symfony/framework-bundle ###

View File

@@ -1,39 +1,5 @@
# variables for .env environement # define your env variables for the test env here
# those variables suits for gitlab-ci
# Run tests from root to adapt your own environment
KERNEL_CLASS='App\Kernel' KERNEL_CLASS='App\Kernel'
APP_SECRET='$ecretf0rt3st' APP_SECRET='$ecretf0rt3st'
SYMFONY_DEPRECATIONS_HELPER=999999
ADMIN_PASSWORD=password DEFAULT_CARRIER_CODE=TEST
JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem
JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem
JWT_PASSPHRASE=2a30f6ba26521a2613821da35f28386e
TWILIO_SID=~
TWILIO_SECRET=~
DEFAULT_CARRIER_CODE=BE
ADD_ADDRESS_DEFAULT_COUNTRY=BE
ADD_ADDRESS_MAP_CENTER_X=50.8443
ADD_ADDRESS_MAP_CENTER_Y=4.3523
ADD_ADDRESS_MAP_CENTER_Z=15
SHORT_MESSAGE_DSN=null://null
MESSENGER_TRANSPORT_DSN=sync://
###> doctrine/doctrine-bundle ###
# Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
# IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml
#
DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5454/test?serverVersion=14&charset=utf8"
###< doctrine/doctrine-bundle ###
ASYNC_UPLOAD_TEMP_URL_KEY=
ASYNC_UPLOAD_TEMP_URL_BASE_PATH=
ASYNC_UPLOAD_TEMP_URL_CONTAINER=
MAILER_DSN=null://null
REDIS_HOST=127.0.0.1
REDIS_PORT=6363

2
.gitignore vendored
View File

@@ -33,7 +33,7 @@ config/packages/dev/*
###> phpunit/phpunit ### ###> phpunit/phpunit ###
/phpunit.xml /phpunit.xml
.phpunit.result.cache /.phpunit.cache/
###< phpunit/phpunit ### ###< phpunit/phpunit ###
/.php-cs-fixer.cache /.php-cs-fixer.cache

View File

@@ -234,16 +234,20 @@ This must be a decision made by a human, not by an AI. Every AI task must abort
#### Running Tests #### Running Tests
The tests are run from the project's root (not from the bundle's root: so, do not change the directory to any bundle directory before running tests). The tests are run from the project's root (not from the bundle's root).
Tests must be run using the `symfony` command:
```bash ```bash
# Run all tests
vendor/bin/phpunit
# Run tests for a specific bundle
vendor/bin/phpunit --testsuite NameBundle
# Run a specific test file # Run a specific test file
symfony composer exec phpunit -- path/to/TestFile.php vendor/bin/phpunit path/to/TestFile.php
# Run a specific test method # Run a specific test method
symfony composer exec phpunit -- --filter methodName path/to/TestFile.php vendor/bin/phpunit --filter methodName path/to/TestFile.php
``` ```
#### Test Structure #### Test Structure

View File

@@ -1,4 +0,0 @@
{
"tabWidth": 2,
"useTabs": false
}

30
.vscode/launch.json vendored
View File

@@ -1,30 +0,0 @@
{
// Use IntelliSense to learn about possible attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Chill Debug",
"type": "php",
"request": "launch",
"port": 9000,
"pathMappings": {
"/var/www/html": "${workspaceFolder}"
},
"preLaunchTask": "symfony"
},
{
"name": "Yarn Encore Dev (Watch)",
"type": "node-terminal",
"request": "launch",
"command": "yarn encore dev --watch",
"cwd": "${workspaceFolder}"
}
],
"compounds": [
{
"name": "Chill Debug + Yarn Encore Dev (Watch)",
"configurations": ["Chill Debug", "Yarn Encore Dev (Watch)"]
}
]
}

23
.vscode/tasks.json vendored
View File

@@ -1,23 +0,0 @@
{
"tasks": [
{
"type": "shell",
"command": "symfony",
"args": [
"server:start",
"--allow-http",
"--no-tls",
"--port=8000",
"--allow-all-ip",
"-d"
],
"label": "symfony"
},
{
"type": "shell",
"command": "yarn",
"args": ["encore", "dev", "--watch"],
"label": "webpack"
}
]
}

View File

@@ -6,6 +6,17 @@ 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.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 ## v4.2.1 - 2025-09-03
### Fixed ### Fixed
* Fix exports to work with DirectExportInterface * Fix exports to work with DirectExportInterface

View File

@@ -54,7 +54,7 @@ Arborescence:
- person - person
- personvendee - personvendee
- household_edit_metadata - household_edit_metadata
- index.ts - index.js
``` ```
## Organisation des feuilles de styles ## Organisation des feuilles de styles

View File

@@ -8,7 +8,7 @@
"social worker" "social worker"
], ],
"require": { "require": {
"php": "^8.2", "php": "^8.3",
"ext-dom": "*", "ext-dom": "*",
"ext-json": "*", "ext-json": "*",
"ext-openssl": "*", "ext-openssl": "*",
@@ -19,10 +19,10 @@
"doctrine/data-fixtures": "^1.8", "doctrine/data-fixtures": "^1.8",
"doctrine/doctrine-bundle": "^2.1", "doctrine/doctrine-bundle": "^2.1",
"doctrine/doctrine-migrations-bundle": "^3.0", "doctrine/doctrine-migrations-bundle": "^3.0",
"doctrine/orm": "^2.13.0", "doctrine/orm": "^3.5.2",
"erusev/parsedown": "^1.7", "erusev/parsedown": "^1.7",
"knplabs/knp-menu-bundle": "^3.0", "knplabs/knp-menu-bundle": "^3.0",
"knplabs/knp-time-bundle": "^1.12", "knplabs/knp-time-bundle": "^2.0",
"knpuniversity/oauth2-client-bundle": "^2.10", "knpuniversity/oauth2-client-bundle": "^2.10",
"league/csv": "^9.7.1", "league/csv": "^9.7.1",
"lexik/jwt-authentication-bundle": "^2.16", "lexik/jwt-authentication-bundle": "^2.16",
@@ -32,54 +32,53 @@
"ovh/ovh": "^3.0", "ovh/ovh": "^3.0",
"phpoffice/phpspreadsheet": "^1.16", "phpoffice/phpspreadsheet": "^1.16",
"ramsey/uuid-doctrine": "^1.7", "ramsey/uuid-doctrine": "^1.7",
"sensio/framework-extra-bundle": "^5.5",
"smalot/pdfparser": "^2.10", "smalot/pdfparser": "^2.10",
"spomky-labs/base64url": "^2.0", "spomky-labs/base64url": "^2.0",
"symfony/asset": "^5.4", "symfony/amqp-messenger": "^7.3",
"symfony/browser-kit": "^5.4", "symfony/asset": "^7.2",
"symfony/cache": "^5.4", "symfony/browser-kit": "^7.2",
"symfony/clock": "^6.2", "symfony/cache": "^7.2",
"symfony/config": "^5.4", "symfony/clock": "^7.2",
"symfony/console": "^5.4", "symfony/config": "^7.2",
"symfony/css-selector": "^5.4", "symfony/console": "^7.2",
"symfony/dom-crawler": "^5.4", "symfony/css-selector": "^7.2",
"symfony/error-handler": "^5.4", "symfony/dom-crawler": "^7.2",
"symfony/event-dispatcher": "^5.4", "symfony/error-handler": "^7.2",
"symfony/event-dispatcher-contracts": "^2.4", "symfony/event-dispatcher": "^7.2",
"symfony/expression-language": "^5.4", "symfony/event-dispatcher-contracts": "^3.0",
"symfony/filesystem": "^5.4", "symfony/expression-language": "^7.2",
"symfony/finder": "^5.4", "symfony/filesystem": "^7.2",
"symfony/form": "^5.4", "symfony/finder": "^7.2",
"symfony/framework-bundle": "^5.4", "symfony/form": "^7.2",
"symfony/http-client": "^5.4", "symfony/framework-bundle": "^7.2",
"symfony/http-foundation": "^5.4", "symfony/http-client": "^7.2",
"symfony/intl": "^5.4", "symfony/http-foundation": "^7.2",
"symfony/mailer": "^5.4", "symfony/intl": "^7.2",
"symfony/messenger": "^5.4", "symfony/mailer": "^7.2",
"symfony/mime": "^5.4", "symfony/messenger": "^7.2",
"symfony/mime": "^7.2",
"symfony/monolog-bundle": "^3.5", "symfony/monolog-bundle": "^3.5",
"symfony/notifier": "^5.4", "symfony/notifier": "^7.2",
"symfony/options-resolver": "^5.4", "symfony/options-resolver": "^7.2",
"symfony/ovh-cloud-notifier": "^5.4", "symfony/ovh-cloud-notifier": "^7.2",
"symfony/process": "^5.4", "symfony/polyfill-intl-messageformatter": "^1.32",
"symfony/property-access": "^5.4", "symfony/process": "^7.2",
"symfony/property-info": "^5.4", "symfony/property-access": "^7.2",
"symfony/routing": "^5.4", "symfony/property-info": "^7.2",
"symfony/security-bundle": "^5.4", "symfony/routing": "^7.2",
"symfony/security-core": "^5.4", "symfony/security-bundle": "^7.3",
"symfony/security-csrf": "^5.4", "symfony/security-core": "^7.2",
"symfony/security-guard": "^5.4", "symfony/security-csrf": "^7.2",
"symfony/security-http": "^5.4", "symfony/security-http": "^7.2",
"symfony/serializer": "^5.4", "symfony/serializer": "^7.2",
"symfony/string": "^5.4", "symfony/string": "^7.2",
"symfony/templating": "^5.4", "symfony/translation": "^7.2",
"symfony/translation": "^5.4", "symfony/twig-bundle": "^7.2",
"symfony/twig-bundle": "^5.4",
"symfony/ux-translator": "^2.22", "symfony/ux-translator": "^2.22",
"symfony/validator": "^5.4", "symfony/validator": "^7.2",
"symfony/webpack-encore-bundle": "^1.11", "symfony/webpack-encore-bundle": "^2.0",
"symfony/workflow": "^5.4", "symfony/workflow": "^7.2",
"symfony/yaml": "^5.4", "symfony/yaml": "^7.2",
"thenetworg/oauth2-azure": "^2.0", "thenetworg/oauth2-azure": "^2.0",
"twig/extra-bundle": "^3.0", "twig/extra-bundle": "^3.0",
"twig/intl-extra": "^3.0", "twig/intl-extra": "^3.0",
@@ -101,16 +100,15 @@
"phpstan/phpstan-strict-rules": "^1.0", "phpstan/phpstan-strict-rules": "^1.0",
"phpunit/phpunit": "^10.5.24", "phpunit/phpunit": "^10.5.24",
"rector/rector": "^1.1.0", "rector/rector": "^1.1.0",
"symfony/amqp-messenger": "^5.4.45", "symfony/debug-bundle": "^7.2",
"symfony/debug-bundle": "^5.4", "symfony/dotenv": "^7.2",
"symfony/dotenv": "^5.4",
"symfony/flex": "^2.4", "symfony/flex": "^2.4",
"symfony/maker-bundle": "^1.20", "symfony/maker-bundle": "^1.20",
"symfony/phpunit-bridge": "^7.1", "symfony/phpunit-bridge": "^7.1",
"symfony/runtime": "^5.4", "symfony/runtime": "^7.2",
"symfony/stopwatch": "^5.4", "symfony/stopwatch": "^7.2",
"symfony/var-dumper": "^5.4", "symfony/var-dumper": "^7.2",
"symfony/web-profiler-bundle": "^5.4" "symfony/web-profiler-bundle": "^7.2"
}, },
"conflict": { "conflict": {
"symfony/symfony": "*" "symfony/symfony": "*"
@@ -133,7 +131,6 @@
"Chill\\TaskBundle\\": "src/Bundle/ChillTaskBundle", "Chill\\TaskBundle\\": "src/Bundle/ChillTaskBundle",
"Chill\\ThirdPartyBundle\\": "src/Bundle/ChillThirdPartyBundle", "Chill\\ThirdPartyBundle\\": "src/Bundle/ChillThirdPartyBundle",
"Chill\\WopiBundle\\": "src/Bundle/ChillWopiBundle/src", "Chill\\WopiBundle\\": "src/Bundle/ChillWopiBundle/src",
"Chill\\TicketBundle\\": "src/Bundle/ChillTicketBundle/src",
"Chill\\Utils\\Rector\\": "utils/rector/src" "Chill\\Utils\\Rector\\": "utils/rector/src"
} }
}, },

View File

@@ -14,7 +14,6 @@ return [
Lexik\Bundle\JWTAuthenticationBundle\LexikJWTAuthenticationBundle::class => ['all' => true], Lexik\Bundle\JWTAuthenticationBundle\LexikJWTAuthenticationBundle::class => ['all' => true],
Nelmio\Alice\Bridge\Symfony\NelmioAliceBundle::class => ['dev' => true, 'test' => true], Nelmio\Alice\Bridge\Symfony\NelmioAliceBundle::class => ['dev' => true, 'test' => true],
Misd\PhoneNumberBundle\MisdPhoneNumberBundle::class => ['all' => true], Misd\PhoneNumberBundle\MisdPhoneNumberBundle::class => ['all' => true],
Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle::class => ['all' => true],
Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true], Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true],
Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true], Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true], Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
@@ -35,7 +34,6 @@ return [
Chill\ThirdPartyBundle\ChillThirdPartyBundle::class => ['all' => true], Chill\ThirdPartyBundle\ChillThirdPartyBundle::class => ['all' => true],
Chill\BudgetBundle\ChillBudgetBundle::class => ['all' => true], Chill\BudgetBundle\ChillBudgetBundle::class => ['all' => true],
Chill\WopiBundle\ChillWopiBundle::class => ['all' => true], Chill\WopiBundle\ChillWopiBundle::class => ['all' => true],
Chill\TicketBundle\ChillTicketBundle::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],
]; ];

View File

@@ -1,5 +1,5 @@
chill_doc_store: chill_doc_store:
use_driver: local_storage use_driver: openstack
local_storage: local_storage:
storage_path: '%kernel.project_dir%/var/storage' storage_path: '%kernel.project_dir%/var/storage'
openstack: openstack:

View File

@@ -1,5 +0,0 @@
chill_ticket:
ticket:
person_per_ticket: one # One of "one"; "many"
response_time_exceeded_delay: PT12H

11
config/packages/csrf.yaml Normal file
View File

@@ -0,0 +1,11 @@
# Enable stateless CSRF protection for forms and logins/logouts
framework:
form:
csrf_protection:
token_id: submit
csrf_protection:
stateless_token_ids:
- submit
- authenticate
- logout

View File

@@ -7,6 +7,7 @@ doctrine:
#server_version: '16' #server_version: '16'
use_savepoints: true use_savepoints: true
orm: orm:
enable_lazy_ghost_objects: true
auto_generate_proxy_classes: true auto_generate_proxy_classes: true
naming_strategy: doctrine.orm.naming_strategy.default naming_strategy: doctrine.orm.naming_strategy.default
auto_mapping: true auto_mapping: true

View File

@@ -14,7 +14,6 @@ doctrine_migrations:
'Chill\Migrations\Calendar': '@ChillCalendarBundle/migrations' 'Chill\Migrations\Calendar': '@ChillCalendarBundle/migrations'
'Chill\Migrations\Budget': '@ChillBudgetBundle/migrations' 'Chill\Migrations\Budget': '@ChillBudgetBundle/migrations'
'Chill\Migrations\Report': '@ChillReportBundle/migrations' 'Chill\Migrations\Report': '@ChillReportBundle/migrations'
'Chill\Migrations\Ticket': '@ChillTicketBundle/migrations'
all_or_nothing: all_or_nothing:
true true

View File

@@ -4,6 +4,16 @@ framework:
#csrf_protection: true #csrf_protection: true
http_method_override: false http_method_override: false
# Enable EntityValueResolver for automatic entity injection in controllers
# This replaces the functionality previously provided by SensioFrameworkExtraBundle
http_client:
enabled: true
request:
formats:
json: ['application/json']
# Enables session support. Note that the session will ONLY be started if you read or write from it. # Enables session support. Note that the session will ONLY be started if you read or write from it.
# Remove or comment this section to explicitly disable session support. # Remove or comment this section to explicitly disable session support.
session: session:

View File

@@ -1,7 +1,5 @@
framework: framework:
messenger: messenger:
# reset services after consuming messages
reset_on_message: true
# Uncomment this (and the failed transport below) to send failed messages to this transport for later handling. # Uncomment this (and the failed transport below) to send failed messages to this transport for later handling.
failure_transport: failed failure_transport: failed

View File

@@ -1,8 +1,8 @@
framework: framework:
notifier: notifier:
texter_transports: texter_transports:
#ovhcloud: '%env(OVHCLOUD_DSN)%' #ovhcloud: '%env(OVHCLOUD_DSN)%'
#ovhcloud: '%env(SHORT_MESSAGE_DSN)%' #ovhcloud: '%env(SHORT_MESSAGE_DSN)%'
channel_policy: channel_policy:
# use chat/slack, chat/telegram, sms/twilio or sms/nexmo # use chat/slack, chat/telegram, sms/twilio or sms/nexmo
urgent: ['email'] urgent: ['email']

View File

@@ -0,0 +1,3 @@
framework:
property_info:
enabled: true

View File

@@ -1,5 +1,4 @@
security: security:
enable_authenticator_manager: true
# https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords # https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
password_hashers: password_hashers:
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto' Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
@@ -28,16 +27,13 @@ security:
pattern: ^/wopi pattern: ^/wopi
provider: chill_chain_provider provider: chill_chain_provider
stateless: true stateless: true
guard: jwt: ~
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
dav: dav:
pattern: ^/dav pattern: ^/dav
provider: chill_chain_provider provider: chill_chain_provider
stateless: true stateless: true
guard: custom_authenticator:
authenticators: - Chill\DocStoreBundle\Security\Authenticator\JWTOnDavUrlAuthenticator
- Chill\DocStoreBundle\Security\Guard\JWTOnDavUrlAuthenticator
# this firewall is the main firewall for chill. It should be the last one in the stack, # this firewall is the main firewall for chill. It should be the last one in the stack,
# unless you have specific needs # unless you have specific needs
chill_main: chill_main:
@@ -63,7 +59,7 @@ security:
# Note: Only the *first* access control that matches will be used # Note: Only the *first* access control that matches will be used
access_control: access_control:
# those lines are added by chill-bundles recipes, and are requires to make chill-bundles working # those lines are added by chill-bundles recipes, and are requires to make chill-bundles working
- { path: ^/(login|logout), roles: IS_AUTHENTICATED_ANONYMOUSLY } - { path: ^/(login|logout), roles: PUBLIC_ACCESS }
- { path: ^/public, roles: IS_AUTHENTICATED_ANONYMOUSLY } - { path: ^/public, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/wopi, roles: IS_AUTHENTICATED_FULLY } - { path: ^/wopi, roles: IS_AUTHENTICATED_FULLY }
# access for homepage, the homepage redirect admin to admin section # access for homepage, the homepage redirect admin to admin section

View File

@@ -1,3 +0,0 @@
sensio_framework_extra:
router:
annotations: false

View File

@@ -7,7 +7,8 @@ framework:
- Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument - Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument
- Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork - Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork
- Chill\DocStoreBundle\Entity\AccompanyingCourseDocument - Chill\DocStoreBundle\Entity\AccompanyingCourseDocument
label: label: Suivi
translated_labels:
fr: 'Suivi' fr: 'Suivi'
support_strategy: Chill\MainBundle\Workflow\RelatedEntityWorkflowSupportsStrategy support_strategy: Chill\MainBundle\Workflow\RelatedEntityWorkflowSupportsStrategy
marking_store: marking_store:
@@ -16,11 +17,13 @@ framework:
places: places:
initial: initial:
metadata: metadata:
label: label: Étape initiale
translated_labels:
fr: Étape initiale fr: Étape initiale
attenteModification: attenteModification:
metadata: metadata:
label: label: En attente de modification du document
translated_labels:
fr: En attente de modification du document fr: En attente de modification du document
validationFilterInputLabels: validationFilterInputLabels:
forward: {fr: Modification effectuée} forward: {fr: Modification effectuée}
@@ -28,7 +31,8 @@ framework:
neutral: {fr: Autre} neutral: {fr: Autre}
attenteMiseEnForme: attenteMiseEnForme:
metadata: metadata:
label: label: En attente de mise en forme
translated_labels:
fr: En attente de mise en forme fr: En attente de mise en forme
validationFilterInputLabels: validationFilterInputLabels:
forward: {fr: Mise en forme terminée} forward: {fr: Mise en forme terminée}
@@ -36,7 +40,8 @@ framework:
neutral: {fr: Autre} neutral: {fr: Autre}
attenteVisa: attenteVisa:
metadata: metadata:
label: label: En attente de visa
translated_labels:
fr: En attente de visa fr: En attente de visa
validationFilterInputLabels: validationFilterInputLabels:
forward: {fr: Visa accordé} forward: {fr: Visa accordé}
@@ -47,7 +52,8 @@ framework:
isSignature: ['user', 'person'] isSignature: ['user', 'person']
onSignatureCompleted: onSignatureCompleted:
transitionName: signatureApplied transitionName: signatureApplied
label: label: En attente de signature
translated_labels:
fr: En attente de signature fr: En attente de signature
validationFilterInputLabels: validationFilterInputLabels:
forward: {fr: Signature accordée} forward: {fr: Signature accordée}
@@ -55,7 +61,8 @@ framework:
neutral: {fr: Autre} neutral: {fr: Autre}
postSignature: postSignature:
metadata: metadata:
label: label: Signatures traitées
translated_labels:
fr: Signatures traitées fr: Signatures traitées
validationFilterInputLabels: validationFilterInputLabels:
forward: {fr: Poursuite du traitement} forward: {fr: Poursuite du traitement}
@@ -63,7 +70,8 @@ framework:
neutral: {fr: Autre} neutral: {fr: Autre}
attenteTraitement: attenteTraitement:
metadata: metadata:
label: label: En attente de traitement
translated_labels:
fr: En attente de traitement fr: En attente de traitement
validationFilterInputLabels: validationFilterInputLabels:
forward: {fr: Traitement terminé favorablement} forward: {fr: Traitement terminé favorablement}
@@ -71,7 +79,8 @@ framework:
neutral: {fr: Autre} neutral: {fr: Autre}
attenteEnvoi: attenteEnvoi:
metadata: metadata:
label: label: En attente d'envoi
translated_labels:
fr: En attente d'envoi fr: En attente d'envoi
validationFilterInputLabels: validationFilterInputLabels:
forward: {fr: Document envoyé} forward: {fr: Document envoyé}
@@ -79,7 +88,8 @@ framework:
neutral: {fr: Autre} neutral: {fr: Autre}
attenteValidationMiseEnForme: attenteValidationMiseEnForme:
metadata: metadata:
label: label: En attente de validation de la mise en forme
translated_labels:
fr: En attente de validation de la mise en forme fr: En attente de validation de la mise en forme
validationFilterInputLabels: validationFilterInputLabels:
forward: {fr: Validation de la mise en forme} forward: {fr: Validation de la mise en forme}
@@ -89,7 +99,8 @@ framework:
metadata: metadata:
isSentExternal: true isSentExternal: true
onExternalView: clotureApresLectureEnvoiExterne onExternalView: clotureApresLectureEnvoiExterne
label: label: En attente d'ouverture par un destinataire externe
translated_labels:
fr: En attente d'ouverture par un destinataire externe fr: En attente d'ouverture par un destinataire externe
validationFilterInputLabels: validationFilterInputLabels:
forward: {fr: Document reçu par un destinataire externe} forward: {fr: Document reçu par un destinataire externe}
@@ -99,13 +110,15 @@ framework:
metadata: metadata:
isFinal: true isFinal: true
isFinalPositive: false isFinalPositive: false
label: label: Annulé
translated_labels:
fr: Annulé fr: Annulé
final: final:
metadata: metadata:
isFinal: true isFinal: true
isFinalPositive: true isFinalPositive: true
label: label: Finalisé
translated_labels:
fr: Finalisé fr: Finalisé
transitions: transitions:
# transition qui avancent # transition qui avancent
@@ -114,7 +127,8 @@ framework:
- initial - initial
to: attenteModification to: attenteModification
metadata: metadata:
label: label: Demande de modification du document
translated_labels:
fr: Demande de modification du document fr: Demande de modification du document
isForward: true isForward: true
demandeMiseEnForme: demandeMiseEnForme:
@@ -123,7 +137,8 @@ framework:
- attenteModification - attenteModification
to: attenteMiseEnForme to: attenteMiseEnForme
metadata: metadata:
label: label: Demande de mise en forme
translated_labels:
fr: Demande de mise en forme fr: Demande de mise en forme
isForward: true isForward: true
demandeValidationMiseEnForme: demandeValidationMiseEnForme:
@@ -131,7 +146,8 @@ framework:
- attenteMiseEnForme - attenteMiseEnForme
to: attenteValidationMiseEnForme to: attenteValidationMiseEnForme
metadata: metadata:
label: label: Demande de validation de la mise en forme
translated_labels:
fr: Demande de validation de la mise en forme fr: Demande de validation de la mise en forme
isForward: true isForward: true
demandeVisa: demandeVisa:
@@ -144,7 +160,8 @@ framework:
- attenteTraitement - attenteTraitement
to: attenteVisa to: attenteVisa
metadata: metadata:
label: label: Demande de visa
translated_labels:
fr: Demande de visa fr: Demande de visa
isForward: true isForward: true
demandeSignature: demandeSignature:
@@ -157,14 +174,18 @@ framework:
- attenteTraitement - attenteTraitement
to: attenteSignature to: attenteSignature
metadata: metadata:
label: {fr: Demande de signature} label: Demande de signature
translated_labels:
fr: Demande de signature
isForward: true isForward: true
signatureApplied: signatureApplied:
from: from:
- attenteSignature - attenteSignature
to: postSignature to: postSignature
metadata: metadata:
label: {fr: Signatures appliquées} label: Signatures appliquées
translated_labels:
fr: Signatures appliquées
isForward: true isForward: true
transitionGuard: 'system' # can be 'system+only-dest' or 'only-dest' (only-dest is default) transitionGuard: 'system' # can be 'system+only-dest' or 'only-dest' (only-dest is default)
demandeTraitement: demandeTraitement:
@@ -177,7 +198,9 @@ framework:
- postSignature - postSignature
to: attenteTraitement to: attenteTraitement
metadata: metadata:
label: {fr: Demande de traitement} label: Demande de traitement
translated_labels:
fr: Demande de traitement
isForward: true isForward: true
demandeEnvoi: demandeEnvoi:
from: from:
@@ -190,7 +213,9 @@ framework:
- attenteTraitement - attenteTraitement
to: attenteEnvoi to: attenteEnvoi
metadata: metadata:
label: {fr: Demande d'envoi} label: Demande d'envoi
translated_labels:
fr: Demande d'envoi
isForward: true isForward: true
demandeEnvoiExterne: demandeEnvoiExterne:
from: from:
@@ -203,7 +228,9 @@ framework:
- attenteTraitement - attenteTraitement
to: attenteReceptionExternal to: attenteReceptionExternal
metadata: metadata:
label: {fr: Envoi sécurisé par courrier électronique} label: Envoi sécurisé par courrier électronique
translated_labels:
fr: Envoi sécurisé par courrier électronique
isForward: true isForward: true
clotureApresLectureEnvoiExterne: clotureApresLectureEnvoiExterne:
from: from:
@@ -213,7 +240,9 @@ framework:
metadata: metadata:
transitionGuard: system transitionGuard: system
isForward: true isForward: true
label: {fr: Consultation de l'envoi sécurisé} label: Consultation de l'envoi sécurisé
translated_labels:
fr: Consultation de l'envoi sécurisé
annulation: annulation:
from: from:
- initial - initial
@@ -227,7 +256,9 @@ framework:
- attenteEnvoi - attenteEnvoi
to: annule to: annule
metadata: metadata:
label: {fr: Annulation} label: Annulation
translated_labels:
fr: Annulation
isForward: false isForward: false
transitionGuard: 'system+only-dest' # can be 'system+only-dest' or 'only-dest' (only-dest is default) transitionGuard: 'system+only-dest' # can be 'system+only-dest' or 'only-dest' (only-dest is default)
# transitions qui répètent l'étape # transitions qui répètent l'étape
@@ -237,27 +268,35 @@ framework:
- attenteValidationMiseEnForme - attenteValidationMiseEnForme
to: attenteMiseEnForme to: attenteMiseEnForme
metadata: metadata:
label: {fr: Demande de mise en forme supplémentaire} label: Demande de mise en forme supplémentaire
translated_labels:
fr: Demande de mise en forme supplémentaire
demandeVisaSupplementaire: demandeVisaSupplementaire:
from: from:
- attenteVisa - attenteVisa
to: attenteVisa to: attenteVisa
metadata: metadata:
label: {fr: Demande de visa supplémentaire} label: Demande de visa supplémentaire
translated_labels:
fr: Demande de visa supplémentaire
isForward: true isForward: true
demandeSignatureSupplementaire: demandeSignatureSupplementaire:
from: from:
- postSignature - postSignature
to: attenteSignature to: attenteSignature
metadata: metadata:
label: {fr: Demande de signature supplémentaire} label: Demande de signature supplémentaire
translated_labels:
fr: Demande de signature supplémentaire
isForward: true isForward: true
demandeTraitementSupplementaire: demandeTraitementSupplementaire:
from: from:
- attenteTraitement - attenteTraitement
to: attenteTraitement to: attenteTraitement
metadata: metadata:
label: {fr: Demande de traitement supplémentaire} label: Demande de traitement supplémentaire
translated_labels:
fr: Demande de traitement supplémentaire
# transitions qui renvoient vers une étape précédente # transitions qui renvoient vers une étape précédente
refusEtModificationDocument: refusEtModificationDocument:
from: from:
@@ -267,7 +306,8 @@ framework:
- attenteEnvoi - attenteEnvoi
to: attenteModification to: attenteModification
metadata: metadata:
label: label: Refus et demande de modification du document
translated_labels:
fr: Refus et demande de modification du document fr: Refus et demande de modification du document
isForward: false isForward: false
refusEtDemandeMiseEnForme: refusEtDemandeMiseEnForme:
@@ -277,7 +317,9 @@ framework:
- attenteEnvoi - attenteEnvoi
to: attenteMiseEnForme to: attenteMiseEnForme
metadata: metadata:
label: {fr: Refus et demande de mise en forme} label: Refus et demande de mise en forme
translated_labels:
fr: Refus et demande de mise en forme
isForward: false isForward: false
refusEtDemandeVisa: refusEtDemandeVisa:
from: from:
@@ -285,21 +327,27 @@ framework:
- attenteEnvoi - attenteEnvoi
to: attenteVisa to: attenteVisa
metadata: metadata:
label: {fr: Refus et demande de visa} label: Refus et demande de visa
translated_labels:
fr: Refus et demande de visa
isForward: false isForward: false
refusEtDemandeSignature: refusEtDemandeSignature:
from: from:
- attenteEnvoi - attenteEnvoi
to: attenteSignature to: attenteSignature
metadata: metadata:
label: {fr: Refus et demande de signature} label: Refus et demande de signature
translated_labels:
fr: Refus et demande de signature
isForward: false isForward: false
refusEtDemandeTraitement: refusEtDemandeTraitement:
from: from:
- attenteEnvoi - attenteEnvoi
to: attenteTraitement to: attenteTraitement
metadata: metadata:
label: {fr: Refus et demande de traitement} label: Refus et demande de traitement
translated_labels:
fr: Refus et demande de traitement
isForward: false isForward: false
# transition vers final # transition vers final
initialToFinal: initialToFinal:
@@ -307,7 +355,9 @@ framework:
- initial - initial
to: final to: final
metadata: metadata:
label: {fr: Clotûre immédiate et cloture positive} label: Clotûre immédiate et cloture positive
translated_labels:
fr: Clotûre immédiate et cloture positive
isForward: true isForward: true
attenteMiseEnFormeToFinal: attenteMiseEnFormeToFinal:
from: from:
@@ -315,33 +365,43 @@ framework:
- attenteValidationMiseEnForme - attenteValidationMiseEnForme
to: final to: final
metadata: metadata:
label: {fr: Mise en forme terminée et cloture positive} label: Mise en forme terminée et cloture positive
translated_labels:
fr: Mise en forme terminée et cloture positive
isForward: true isForward: true
attenteVisaToFinal: attenteVisaToFinal:
from: from:
- attenteVisa - attenteVisa
to: final to: final
metadata: metadata:
label: {fr: Accorde le visa et cloture positive} label: Accorde le visa et cloture positive
translated_labels:
fr: Accorde le visa et cloture positive
isForward: true isForward: true
postSignatureToFinal: postSignatureToFinal:
from: from:
- postSignature - postSignature
to: final to: final
metadata: metadata:
label: {fr: Cloture positive} label: Cloture positive
translated_labels:
fr: Cloture positive
isForward: true isForward: true
attenteTraitementToFinal: attenteTraitementToFinal:
from: from:
- attenteTraitement - attenteTraitement
to: final to: final
metadata: metadata:
label: {fr: Traitement terminé et cloture positive} label: Traitement terminé et cloture positive
translated_labels:
fr: Traitement terminé et cloture positive
isForward: true isForward: true
attenteEnvoiToFinal: attenteEnvoiToFinal:
from: from:
- attenteEnvoi - attenteEnvoi
to: final to: final
metadata: metadata:
label: {fr: Envoyé et cloture positive} label: Envoyé et cloture positive
translated_labels:
fr: Envoyé et cloture positive
isForward: true isForward: true

View File

@@ -1,3 +0,0 @@
kernel:
resource: ../../src/app/Kernel.php
type: annotation

View File

@@ -1,2 +0,0 @@
chill_ticket_bundle:
resource: '@ChillTicketBundle/config/routes.yaml'

View File

@@ -0,0 +1,3 @@
_security_logout:
resource: security.route_loader.logout
type: service

View File

@@ -6,8 +6,15 @@
parameters: parameters:
services: services:
#alias to inject container into AbstractController::setContainer
Psr\Container\ContainerInterface: '@service_container'
# default configuration for services in *this* file # default configuration for services in *this* file
_defaults: _defaults:
autowire: true # Automatically injects dependencies in your services. autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc. autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
# Custom entity value resolver to replace SensioFrameworkExtraBundle functionality
Chill\MainBundle\ArgumentResolver\EntityValueResolver:
tags:
- { name: controller.argument_value_resolver, priority: 50 }

View File

@@ -14,7 +14,6 @@ namespace Chill\PersonBundle\Export\Filter;
use Chill\MainBundle\Export\ExportElementValidatedInterface; use Chill\MainBundle\Export\ExportElementValidatedInterface;
use Chill\MainBundle\Export\ExportGenerationContext; use Chill\MainBundle\Export\ExportGenerationContext;
use Chill\MainBundle\Export\FilterInterface; use Chill\MainBundle\Export\FilterInterface;
use DateTime;
use Doctrine\ORM\Query\Expr; use Doctrine\ORM\Query\Expr;
use Symfony\Component\Form\Extension\Core\Type\DateType; use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Context\ExecutionContextInterface;
@@ -22,6 +21,7 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface;
class BirthdateFilter implements ExportElementValidatedInterface, FilterInterface class BirthdateFilter implements ExportElementValidatedInterface, FilterInterface
{ {
use \Chill\MainBundle\Export\ExportDataNormalizerTrait; use \Chill\MainBundle\Export\ExportDataNormalizerTrait;
// add specific role for this filter // add specific role for this filter
public function addRole(): ?string public function addRole(): ?string
{ {
@@ -30,7 +30,7 @@ class BirthdateFilter implements ExportElementValidatedInterface, FilterInterfac
} }
// here, we alter the query created by Export // here, we alter the query created by Export
public function alterQuery(\Doctrine\ORM\QueryBuilder $qb, $data, \Chill\MainBundle\Export\ExportGenerationContext $exportGenerationContext): void public function alterQuery(\Doctrine\ORM\QueryBuilder $qb, $data, ExportGenerationContext $exportGenerationContext): void
{ {
$where = $qb->getDQLPart('where'); $where = $qb->getDQLPart('where');
// we create the clause here // we create the clause here
@@ -76,21 +76,25 @@ class BirthdateFilter implements ExportElementValidatedInterface, FilterInterfac
'format' => 'dd-MM-yyyy', 'format' => 'dd-MM-yyyy',
]); ]);
} }
public function getNormalizationVersion(): int public function getNormalizationVersion(): int
{ {
return 1; return 1;
} }
public function normalizeFormData(array $formData): array public function normalizeFormData(array $formData): array
{ {
return ['date_from' => $this->normalizeDate($formData['date_from']), 'date_to' => $this->normalizeDate($formData['date_to'])]; return ['date_from' => $this->normalizeDate($formData['date_from']), 'date_to' => $this->normalizeDate($formData['date_to'])];
} }
public function denormalizeFormData(array $formData, int $fromVersion): array public function denormalizeFormData(array $formData, int $fromVersion): array
{ {
return ['date_from' => $this->denormalizeDate($formData['date_from']), 'date_to' => $this->denormalizeDate($formData['date_to'])]; return ['date_from' => $this->denormalizeDate($formData['date_from']), 'date_to' => $this->denormalizeDate($formData['date_to'])];
} }
public function getFormDefaultData(): array public function getFormDefaultData(): array
{ {
return ['date_from' => new DateTime(), 'date_to' => new DateTime()]; return ['date_from' => new \DateTime(), 'date_to' => new \DateTime()];
} }
// here, we create a simple string which will describe the action of // here, we create a simple string which will describe the action of
@@ -98,7 +102,7 @@ class BirthdateFilter implements ExportElementValidatedInterface, FilterInterfac
public function describeAction($data, ExportGenerationContext $context): string|\Symfony\Contracts\Translation\TranslatableInterface|array public function describeAction($data, ExportGenerationContext $context): string|\Symfony\Contracts\Translation\TranslatableInterface|array
{ {
return ['Filtered by person\'s birtdate: ' return ['Filtered by person\'s birtdate: '
. 'between %date_from% and %date_to%', [ .'between %date_from% and %date_to%', [
'%date_from%' => $data['date_from']->format('d-m-Y'), '%date_from%' => $data['date_from']->format('d-m-Y'),
'%date_to%' => $data['date_to']->format('d-m-Y'), '%date_to%' => $data['date_to']->format('d-m-Y'),
], ]; ], ];
@@ -120,13 +124,13 @@ class BirthdateFilter implements ExportElementValidatedInterface, FilterInterfac
if (null === $date_from) { if (null === $date_from) {
$context->buildViolation('The "date from" should not be empty') $context->buildViolation('The "date from" should not be empty')
//->atPath('date_from') // ->atPath('date_from')
->addViolation(); ->addViolation();
} }
if (null === $date_to) { if (null === $date_to) {
$context->buildViolation('The "date to" should not be empty') $context->buildViolation('The "date to" should not be empty')
//->atPath('date_to') // ->atPath('date_to')
->addViolation(); ->addViolation();
} }
@@ -135,7 +139,7 @@ class BirthdateFilter implements ExportElementValidatedInterface, FilterInterfac
&& $date_from >= $date_to && $date_from >= $date_to
) { ) {
$context->buildViolation('The date "date to" should be after the ' $context->buildViolation('The date "date to" should be after the '
. 'date given in "date from" field') .'date given in "date from" field')
->addViolation(); ->addViolation();
} }
} }

View File

@@ -32,7 +32,7 @@ class CountPerson implements ExportInterface
$this->entityManager = $em; $this->entityManager = $em;
} }
public function buildForm(FormBuilderInterface $builder) public function buildForm(FormBuilderInterface $builder): void
{ {
// this export does not add any form // this export does not add any form
} }

View File

@@ -11,94 +11,24 @@
Create a new bundle Create a new bundle
******************* *******************
Create your own bundle is not a trivial task.
The easiest way to achieve this is seems to be :
1. Prepare a fresh installation of the chill project, in a new directory
2. Create a new bundle in this project, in the src directory
3. Initialize a git repository **at the root bundle**, and create your initial commit.
4. Register the bundle with composer/packagist. If you do not plan to distribute your bundle with packagist, you may use a custom repository for achieve this [#f1]_
5. Move to a development installation, made as described in the :ref:`installation-for-development` section, and add your new repository to the composer.json file
6. Work as :ref:`usual <editing-code-and-commiting>`
.. warning:: .. warning::
This part of the doc is not yet tested This part of the doc is not yet tested
Create a new directory with Bundle class TODO
----------------------------------------
.. code-block:: bash
mkdir -p src/Bundle/ChillSomeBundle/src/config
mkdir -p src/Bundle/ChillSomeBundle/src/Controller
Add a bundle file
.. code-block:: php
<?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\SomeBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class ChillSomeBundle extends Bundle {}
And a route file:
.. code-block:: yaml
chill_ticket_controller:
resource: '@ChillTicketBundle/Controller/'
type: annotation
Register the new psr-4 namespace
--------------------------------
In composer.json, add the new psr4 namespace
.. code-block:: diff
{
"autoload": {
"psr-4": {
+ "Chill\\SomeBundle\\": "src/Bundle/ChillSomeBundle/src",
}
}
}
Register the bundle .. rubric:: Footnotes
-------------------
Register in the file :code:`config/bundles.php`:
.. code-block:: php
Vendor\Bundle\YourBundle\YourBundle::class => ['all' => true],
And import routes in :code:`config/routes/chill_some_bundle.yaml`:
.. code-block:: yaml
chill_ticket_bundle:
resource: '@ChillSomeBundle/config/routes.yaml'
Add the doctrine_migration namespace
------------------------------------
Add the namespace to :code:`config/packages/doctrine_migrations_chill.yaml`
.. code-block:: diff
doctrine_migrations:
migrations_paths:
+ 'Chill\Some\Ticket': '@ChillSomeBundle/migrations'
Dump autoloading
----------------
.. code-block:: bash
symfony composer dump-autoload
.. [#f1] Be aware that we use the Affero GPL Licence, which ensure that all users must have access to derivative works done with this software.

View File

@@ -18,7 +18,7 @@ class example extends \Symfony\Bundle\FrameworkBundle\Controller\AbstractControl
public function __construct(private readonly \Doctrine\Persistence\ManagerRegistry $managerRegistry) public function __construct(private readonly \Doctrine\Persistence\ManagerRegistry $managerRegistry)
{ {
} }
public function yourAction() public function yourAction(): \Symfony\Component\HttpFoundation\Response
{ {
$em = $this->managerRegistry->getManager(); $em = $this->managerRegistry->getManager();
// first, get the number of total item are available // first, get the number of total item are available

View File

@@ -28,7 +28,7 @@ class ConsultationController extends \Symfony\Bundle\FrameworkBundle\Controller\
* *
* @return \Symfony\Component\HttpFoundation\Response * @return \Symfony\Component\HttpFoundation\Response
*/ */
public function listAction($id) public function listAction($id): \Symfony\Component\HttpFoundation\Response
{ {
/** @var \Chill\PersonBundle\Entity\Person $person */ /** @var \Chill\PersonBundle\Entity\Person $person */
$person = $this->get('chill.person.repository.person') $person = $this->get('chill.person.repository.person')

View File

@@ -31,7 +31,7 @@ class ChillMainConfiguration implements ConfigurationInterface
$this->setWidgetFactories($widgetFactories); $this->setWidgetFactories($widgetFactories);
} }
public function getConfigTreeBuilder() public function getConfigTreeBuilder(): \Symfony\Component\Config\Definition\Builder\TreeBuilder
{ {
$treeBuilder = new TreeBuilder('chill_main'); $treeBuilder = new TreeBuilder('chill_main');
$rootNode = $treeBuilder->getRootNode(); $rootNode = $treeBuilder->getRootNode();

View File

@@ -27,12 +27,12 @@ class ChillMainExtension extends Extension implements Widget\HasWidgetFactoriesE
*/ */
protected $widgetFactories = []; protected $widgetFactories = [];
public function addWidgetFactory(WidgetFactoryInterface $factory) public function addWidgetFactory(WidgetFactoryInterface $factory): void
{ {
$this->widgetFactories[] = $factory; $this->widgetFactories[] = $factory;
} }
public function getConfiguration(array $config, ContainerBuilder $container) public function getConfiguration(array $config, ContainerBuilder $container): ?\Symfony\Component\Config\Definition\ConfigurationInterface
{ {
return new Configuration($this->widgetFactories, $container); return new Configuration($this->widgetFactories, $container);
} }
@@ -45,7 +45,7 @@ class ChillMainExtension extends Extension implements Widget\HasWidgetFactoriesE
return $this->widgetFactories; return $this->widgetFactories;
} }
public function load(array $configs, ContainerBuilder $container) public function load(array $configs, ContainerBuilder $container): void
{ {
// configuration for main bundle // configuration for main bundle
$configuration = $this->getConfiguration($configs, $container); $configuration = $this->getConfiguration($configs, $container);

View File

@@ -25,7 +25,7 @@ class ChillPersonAddAPersonListWidgetFactory extends AbstractWidgetFactory
* see http://symfony.com/doc/current/components/config/definition.html * see http://symfony.com/doc/current/components/config/definition.html
* *
*/ */
public function configureOptions($place, NodeBuilder $node) public function configureOptions($place, NodeBuilder $node): void
{ {
$node->booleanNode('only_active') $node->booleanNode('only_active')
->defaultTrue() ->defaultTrue()

View File

@@ -124,7 +124,7 @@ class ChillPersonAddAPersonWidget implements WidgetInterface
/** /**
* @return UserInterface * @return UserInterface
*/ */
private function getUser() private function getUser(): void
{ {
// return a user // return a user
} }

View File

@@ -22,7 +22,7 @@ use Symfony\Component\HttpKernel\DependencyInjection\Extension;
*/ */
class ChillPersonExtension extends Extension implements PrependExtensionInterface class ChillPersonExtension extends Extension implements PrependExtensionInterface
{ {
public function load(array $configs, ContainerBuilder $container) public function load(array $configs, ContainerBuilder $container): void
{ {
// ... // ...
} }
@@ -32,7 +32,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
* *
* @param \Chill\PersonBundle\DependencyInjection\containerBuilder $container * @param \Chill\PersonBundle\DependencyInjection\containerBuilder $container
*/ */
public function prepend(ContainerBuilder $container) public function prepend(ContainerBuilder $container): void
{ {
$container->prependExtensionConfig('chill_main', [ $container->prependExtensionConfig('chill_main', [
'widgets' => [ 'widgets' => [

View File

@@ -11,6 +11,7 @@
"@hotwired/stimulus": "^3.0.0", "@hotwired/stimulus": "^3.0.0",
"@luminateone/eslint-baseline": "^1.0.9", "@luminateone/eslint-baseline": "^1.0.9",
"@symfony/stimulus-bridge": "^3.2.0", "@symfony/stimulus-bridge": "^3.2.0",
"@symfony/ux-translator": "file:vendor/symfony/ux-translator/assets",
"@symfony/webpack-encore": "^4.1.0", "@symfony/webpack-encore": "^4.1.0",
"@tsconfig/node20": "^20.1.4", "@tsconfig/node20": "^20.1.4",
"@types/dompurify": "^3.0.5", "@types/dompurify": "^3.0.5",
@@ -79,12 +80,12 @@
"dev": "encore dev", "dev": "encore dev",
"watch": "encore dev --watch", "watch": "encore dev --watch",
"build": "encore production --progress", "build": "encore production --progress",
"specs-build": "yaml-merge src/Bundle/ChillMainBundle/chill.api.specs.yaml src/Bundle/ChillPersonBundle/chill.api.specs.yaml src/Bundle/ChillCalendarBundle/chill.api.specs.yaml src/Bundle/ChillThirdPartyBundle/chill.api.specs.yaml src/Bundle/ChillDocStoreBundle/chill.api.specs.yaml src/Bundle/ChillTicketBundle/chill.api.specs.yaml> templates/api/specs.yaml", "specs-build": "yaml-merge src/Bundle/ChillMainBundle/chill.api.specs.yaml src/Bundle/ChillPersonBundle/chill.api.specs.yaml src/Bundle/ChillCalendarBundle/chill.api.specs.yaml src/Bundle/ChillThirdPartyBundle/chill.api.specs.yaml src/Bundle/ChillDocStoreBundle/chill.api.specs.yaml> templates/api/specs.yaml",
"specs-validate": "swagger-cli validate templates/api/specs.yaml", "specs-validate": "swagger-cli validate templates/api/specs.yaml",
"specs-create-dir": "mkdir -p templates/api", "specs-create-dir": "mkdir -p templates/api",
"specs": "yarn run specs-create-dir && yarn run specs-build && yarn run specs-validate", "specs": "yarn run specs-create-dir && yarn run specs-build && yarn run specs-validate",
"version": "node --version", "version": "node --version",
"eslint": "eslint-baseline --fix \"src/**/*.{js,ts,vue}\"" "eslint": "npx eslint-baseline --fix \"src/**/*.{js,ts,vue}\""
}, },
"private": true "private": true
} }

View File

@@ -1,88 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- https://phpunit.readthedocs.io/en/latest/configuration.html -->
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="tests/bootstrap.php"
>
<php>
<ini name="display_errors" value="1" />
<ini name="error_reporting" value="-1"/>
<server name="APP_ENV" value="test" force="true"/>
<env name="SYMFONY_DEPRECATIONS_HELPER" value="max[direct]=93&amp;max[indirect]=999999"/>
<server name="SHELL_VERBOSITY" value="-1"/>
<server name="SYMFONY_PHPUNIT_REMOVE" value="" />
<server name="SYMFONY_PHPUNIT_VERSION" value="9.5" />
<ini name="date.timezone" value="Europe/Brussels" />
</php>
<testsuites>
<!--
<testsuite name="ActivityBundle">
<directory suffix="Test.php">src/Bundle/ChillActivityBundle/Tests/</directory>
</testsuite>
-->
<testsuite name="AsideActivityBundle">
<directory suffix="Test.php">src/Bundle/ChillAsideActivityBundle/src/Tests/</directory>
</testsuite>
<testsuite name="BudgetBundle">
<directory suffix="Test.php">src/Bundle/ChillBudgetBundle/Tests/</directory>
</testsuite>
<testsuite name="CalendarBundle">
<directory suffix="Test.php">src/Bundle/ChillCalendarBundle/Tests/</directory>
</testsuite>
<!-- Missing CustomFieldBundle -->
<testsuite name="DocGeneratorBundle">
<directory suffix="Test.php">src/Bundle/ChillDocGeneratorBundle/tests/</directory>
</testsuite>
<testsuite name="DocStoreBundle">
<directory suffix="Test.php">src/Bundle/ChillDocStoreBundle/Tests/</directory>
</testsuite>
<!--
<testsuite name="EventBundle">
<directory suffix="Test.php">src/Bundle/ChillEventBundle/tests/</directory>
</testsuite>
-->
<testsuite name="MainBundle">
<directory suffix="Test.php">src/Bundle/ChillMainBundle/Tests/</directory>
</testsuite>
<testsuite name="PersonBundle">
<directory suffix="Test.php">src/Bundle/ChillPersonBundle/Tests/</directory>
<!-- we are rewriting accompanying periods... Work in progress -->
<exclude>src/Bundle/ChillPersonBundle/Tests/Controller/AccompanyingPeriodControllerTest.php</exclude>
<!-- we are rewriting address, Work in progress -->
<exclude>src/Bundle/ChillPersonBundle/Tests/Controller/PersonAddressControllerTest.php</exclude>
<!-- find a solution to create multiple configs -->
<exclude>src/Bundle/ChillPersonBundle/Tests/Controller/PersonControllerUpdateWithHiddenFieldsTest.php</exclude>
<!-- temporarily removed, the time to find a fix -->
<exclude>src/Bundle/ChillPersonBundle/Tests/Controller/PersonDuplicateControllerViewTest.php</exclude>
</testsuite>
<testsuite name="TicketBundle"> <!-- https://phpunit.readthedocs.io/en/latest/configuration.html -->
<directory suffix="Test.php">src/Bundle/ChillTicketBundle/tests/</directory> <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
</testsuite> xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
<!-- backupGlobals="false"
<testsuite name="ReportBundle"> colors="true"
<directory suffix="Test.php">src/Bundle/ChillReportBundle/Tests/</directory> failOnNotice="true"
failOnWarning="true"
bootstrap="tests/bootstrap.php"
cacheDirectory=".phpunit.cache"
>
<php>
<ini name="display_errors" value="1" />
<ini name="error_reporting" value="-1" />
<server name="APP_ENV" value="test" force="true" />
<server name="SHELL_VERBOSITY" value="-1" />
</php>
<testsuites>
<testsuite name="Project Test Suite">
<directory>tests</directory>
</testsuite> </testsuite>
--> </testsuites>
<!--
<testsuite name="TaskBundle"> <source ignoreSuppressionOfDeprecations="true" restrictNotices="true" restrictWarnings="true">
<directory suffix="Test.php">src/Bundle/ChillTaskBundle/Tests</directory> <include>
</testsuite> <directory>src</directory>
--> </include>
<testsuite name="ThirdPartyBundle"> </source>
<directory suffix="Test.php">src/Bundle/ChillThirdPartyBundle/Tests</directory>
</testsuite>
<testsuite name="WopiBundle">
<directory suffix="Test.php">src/Bundle/ChillWopiBundle/tests/</directory>
</testsuite>
</testsuites>
<!-- Run `composer require symfony/panther` before enabling this extension -->
<!--
<extensions> <extensions>
<extension class="Symfony\Component\Panther\ServerExtension" />
</extensions> </extensions>
-->
</phpunit> </phpunit>

View File

@@ -13,23 +13,24 @@ use Rector\CodeQuality\Rector\Class_\InlineConstructorDefaultToPropertyRector;
use Rector\Config\RectorConfig; use Rector\Config\RectorConfig;
use Rector\Php80\Rector\Class_\AnnotationToAttributeRector; use Rector\Php80\Rector\Class_\AnnotationToAttributeRector;
use Rector\Set\ValueObject\LevelSetList; use Rector\Set\ValueObject\LevelSetList;
use Rector\Symfony\Set\SymfonySetList;
return static function (RectorConfig $rectorConfig): void { return static function (RectorConfig $rectorConfig): void {
$rectorConfig->paths([ $rectorConfig->paths([
__DIR__ . '/docs', __DIR__.'/docs',
__DIR__ . '/src', __DIR__.'/src',
__DIR__ . '/rector.php', __DIR__.'/rector.php',
]); ]);
$rectorConfig->skip([ $rectorConfig->skip([
\Rector\Php55\Rector\String_\StringClassNameToClassConstantRector::class => __DIR__ . 'src/Bundle/ChillMainBundle/Service/Notifier/LegacyOvhCloudFactory.php' Rector\Php55\Rector\String_\StringClassNameToClassConstantRector::class => __DIR__.'src/Bundle/ChillMainBundle/Service/Notifier/LegacyOvhCloudFactory.php',
]); ]);
//$rectorConfig->symfonyContainerXml(__DIR__ . '/var/cache/dev/test/App_KernelTestDebugContainer.xml '); // $rectorConfig->symfonyContainerXml(__DIR__ . '/var/cache/dev/test/App_KernelTestDebugContainer.xml ');
//$rectorConfig->symfonyContainerPhp(__DIR__ . '/tests/symfony-container.php'); // $rectorConfig->symfonyContainerPhp(__DIR__ . '/tests/symfony-container.php');
//$rectorConfig->cacheClass(\Rector\Caching\ValueObject\Storage\FileCacheStorage::class); // $rectorConfig->cacheClass(\Rector\Caching\ValueObject\Storage\FileCacheStorage::class);
//$rectorConfig->cacheDirectory(__DIR__ . '/.cache/rector'); // $rectorConfig->cacheDirectory(__DIR__ . '/.cache/rector');
// register a single rule // register a single rule
$rectorConfig->rule(InlineConstructorDefaultToPropertyRector::class); $rectorConfig->rule(InlineConstructorDefaultToPropertyRector::class);
@@ -37,54 +38,72 @@ return static function (RectorConfig $rectorConfig): void {
$rectorConfig->rule(Rector\TypeDeclaration\Rector\Class_\MergeDateTimePropertyTypeDeclarationRector::class); $rectorConfig->rule(Rector\TypeDeclaration\Rector\Class_\MergeDateTimePropertyTypeDeclarationRector::class);
$rectorConfig->rule(Rector\TypeDeclaration\Rector\ClassMethod\AddReturnTypeDeclarationBasedOnParentClassMethodRector::class); $rectorConfig->rule(Rector\TypeDeclaration\Rector\ClassMethod\AddReturnTypeDeclarationBasedOnParentClassMethodRector::class);
// part of the symfony 54 rules // Add return types to controller methods
$rectorConfig->rule(\Rector\Symfony\Symfony53\Rector\StaticPropertyFetch\KernelTestCaseContainerPropertyDeprecationRector::class); $rectorConfig->rule(Rector\TypeDeclaration\Rector\ClassMethod\AddVoidReturnTypeWhereNoReturnRector::class);
$rectorConfig->rule(\Rector\Symfony\Symfony60\Rector\MethodCall\GetHelperControllerToServiceRector::class); $rectorConfig->rule(Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromReturnNewRector::class);
//$rectorConfig->disableParallel(); $rectorConfig->rule(Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictTypedCallRector::class);
$rectorConfig->rule(Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictTypedPropertyRector::class);
//define sets of rules // part of the symfony 54 rules
$rectorConfig->rule(Rector\Symfony\Symfony53\Rector\StaticPropertyFetch\KernelTestCaseContainerPropertyDeprecationRector::class);
$rectorConfig->rule(Rector\Symfony\Symfony60\Rector\MethodCall\GetHelperControllerToServiceRector::class);
// $rectorConfig->disableParallel();
// define sets of rules
$rectorConfig->sets([ $rectorConfig->sets([
LevelSetList::UP_TO_PHP_82, // LevelSetList::UP_TO_PHP_82,
\Rector\Doctrine\Set\DoctrineSetList::DOCTRINE_CODE_QUALITY, // SymfonySetList::SYMFONY_60,
\Rector\PHPUnit\Set\PHPUnitSetList::PHPUNIT_90, // SymfonySetList::SYMFONY_61,
// SymfonySetList::SYMFONY_62,
// SymfonySetList::SYMFONY_63,
// SymfonySetList::SYMFONY_64,
// SymfonySetList::SYMFONY_70,
// SymfonySetList::SYMFONY_71,
Rector\Doctrine\Set\DoctrineSetList::DOCTRINE_ORM_29,
Rector\Doctrine\Set\DoctrineSetList::DOCTRINE_DBAL_30,
Rector\Doctrine\Set\DoctrineSetList::DOCTRINE_CODE_QUALITY,
Rector\Doctrine\Set\DoctrineSetList::ANNOTATIONS_TO_ATTRIBUTES,
]); ]);
$rectorConfig->ruleWithConfiguration(\Rector\Php80\Rector\Class_\AnnotationToAttributeRector::class, [ $rectorConfig->ruleWithConfiguration(AnnotationToAttributeRector::class, [
new \Rector\Php80\ValueObject\AnnotationToAttribute('Symfony\Component\Serializer\Annotation\Context'), new Rector\Php80\ValueObject\AnnotationToAttribute('Symfony\Component\Serializer\Annotation\Context'),
]); ]);
// migrate for phpunit // migrate for phpunit
$rectorConfig->rules([ $rectorConfig->rules([
\Rector\PHPUnit\PHPUnit100\Rector\Class_\StaticDataProviderClassMethodRector::class, Rector\PHPUnit\PHPUnit100\Rector\Class_\StaticDataProviderClassMethodRector::class,
\Rector\PHPUnit\PHPUnit100\Rector\Class_\PublicDataProviderClassMethodRector::class Rector\PHPUnit\PHPUnit100\Rector\Class_\PublicDataProviderClassMethodRector::class,
]); ]);
// some routes are added twice if it remains activated // some routes are added twice if it remains activated
// $rectorConfig->rule(\Rector\Symfony\Configs\Rector\ClassMethod\AddRouteAnnotationRector::class); // $rectorConfig->rule(\Rector\Symfony\Configs\Rector\ClassMethod\AddRouteAnnotationRector::class);
// chill rules
$rectorConfig->rules([
Chill\Utils\Rector\Rector\ChillBundleMakeDataProviderStaticForAbstractExportTestRector::class,
]);
// skip some path... // skip some path...
$rectorConfig->skip([ $rectorConfig->skip([
// waiting for fixing this bug: https://github.com/rectorphp/rector-doctrine/issues/342 // waiting for fixing this bug: https://github.com/rectorphp/rector-doctrine/issues/342
\Rector\Doctrine\CodeQuality\Rector\Property\ImproveDoctrineCollectionDocTypeInEntityRector::class, Rector\Doctrine\CodeQuality\Rector\Property\ImproveDoctrineCollectionDocTypeInEntityRector::class,
]); ]);
$rectorConfig->ruleWithConfiguration(AnnotationToAttributeRector::class, [ $rectorConfig->ruleWithConfiguration(AnnotationToAttributeRector::class, [
new \Rector\Php80\ValueObject\AnnotationToAttribute('Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod\AccompanyingPeriodValidity'), new Rector\Php80\ValueObject\AnnotationToAttribute('Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod\AccompanyingPeriodValidity'),
new \Rector\Php80\ValueObject\AnnotationToAttribute('Chill\PersonBundle\Validator\Constraints\Household\HouseholdMembershipSequential'), new Rector\Php80\ValueObject\AnnotationToAttribute('Chill\PersonBundle\Validator\Constraints\Household\HouseholdMembershipSequential'),
new \Rector\Php80\ValueObject\AnnotationToAttribute('Chill\PersonBundle\Validator\Constraints\Household\MaxHolder'), new Rector\Php80\ValueObject\AnnotationToAttribute('Chill\PersonBundle\Validator\Constraints\Household\MaxHolder'),
new \Rector\Php80\ValueObject\AnnotationToAttribute('Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod\ConfidentialCourseMustHaveReferrer'), new Rector\Php80\ValueObject\AnnotationToAttribute('Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod\ConfidentialCourseMustHaveReferrer'),
new \Rector\Php80\ValueObject\AnnotationToAttribute('Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod\LocationValidity'), new Rector\Php80\ValueObject\AnnotationToAttribute('Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod\LocationValidity'),
new \Rector\Php80\ValueObject\AnnotationToAttribute('Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod\ParticipationOverlap'), new Rector\Php80\ValueObject\AnnotationToAttribute('Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod\ParticipationOverlap'),
new \Rector\Php80\ValueObject\AnnotationToAttribute('Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod\ResourceDuplicateCheck'), new Rector\Php80\ValueObject\AnnotationToAttribute('Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod\ResourceDuplicateCheck'),
new \Rector\Php80\ValueObject\AnnotationToAttribute('Chill\PersonBundle\Validator\Constraints\Person\Birthdate'), new Rector\Php80\ValueObject\AnnotationToAttribute('Chill\PersonBundle\Validator\Constraints\Person\Birthdate'),
new \Rector\Php80\ValueObject\AnnotationToAttribute('Chill\PersonBundle\Validator\Constraints\Person\PersonHasCenter'), new Rector\Php80\ValueObject\AnnotationToAttribute('Chill\PersonBundle\Validator\Constraints\Person\PersonHasCenter'),
new \Rector\Php80\ValueObject\AnnotationToAttribute('Chill\PersonBundle\Validator\Constraints\Relationship\RelationshipNoDuplicate'), new Rector\Php80\ValueObject\AnnotationToAttribute('Chill\PersonBundle\Validator\Constraints\Relationship\RelationshipNoDuplicate'),
new \Rector\Php80\ValueObject\AnnotationToAttribute('Chill\ActivityBundle\Validator\Constraints\ActivityValidity'), new Rector\Php80\ValueObject\AnnotationToAttribute('Chill\ActivityBundle\Validator\Constraints\ActivityValidity'),
new \Rector\Php80\ValueObject\AnnotationToAttribute('Chill\DocStoreBundle\Validator\Constraints\AsyncFileExists'), new Rector\Php80\ValueObject\AnnotationToAttribute('Chill\DocStoreBundle\Validator\Constraints\AsyncFileExists'),
new \Rector\Php80\ValueObject\AnnotationToAttribute('Chill\MainBundle\Validation\Constraint\PhonenumberConstraint'), new Rector\Php80\ValueObject\AnnotationToAttribute('Chill\MainBundle\Validation\Constraint\PhonenumberConstraint'),
new \Rector\Php80\ValueObject\AnnotationToAttribute('Chill\MainBundle\Validator\Constraints\Entity\UserCircleConsistency'), new Rector\Php80\ValueObject\AnnotationToAttribute('Chill\MainBundle\Validator\Constraints\Entity\UserCircleConsistency'),
new \Rector\Php80\ValueObject\AnnotationToAttribute('Chill\MainBundle\Workflow\Validator\EntityWorkflowCreation'), new Rector\Php80\ValueObject\AnnotationToAttribute('Chill\MainBundle\Workflow\Validator\EntityWorkflowCreation'),
]); ]);
}; };

View File

@@ -74,8 +74,8 @@ final class ActivityController extends AbstractController
/** /**
* Deletes a Activity entity. * Deletes a Activity entity.
*/ */
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/activity/{id}/delete', name: 'chill_activity_activity_delete', methods: ['GET', 'POST', 'DELETE'])] #[\Symfony\Component\Routing\Attribute\Route(path: '/{_locale}/activity/{id}/delete', name: 'chill_activity_activity_delete', methods: ['GET', 'POST', 'DELETE'])]
public function deleteAction(Request $request, mixed $id) public function deleteAction(Request $request, mixed $id): \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
{ {
$view = null; $view = null;
@@ -104,7 +104,7 @@ final class ActivityController extends AbstractController
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
$this->logger->notice('An activity has been removed', [ $this->logger->notice('An activity has been removed', [
'by_user' => $this->getUser()->getUsername(), 'by_user' => $this->getUser()->getUserIdentifier(),
'activity_id' => $activity->getId(), 'activity_id' => $activity->getId(),
'person_id' => $activity->getPerson() ? $activity->getPerson()->getId() : null, 'person_id' => $activity->getPerson() ? $activity->getPerson()->getId() : null,
'comment' => $activity->getComment()->getComment(), 'comment' => $activity->getComment()->getComment(),
@@ -134,7 +134,7 @@ final class ActivityController extends AbstractController
return $this->render($view, [ return $this->render($view, [
'activity' => $activity, 'activity' => $activity,
'delete_form' => $form->createView(), 'delete_form' => $form,
'person' => $person, 'person' => $person,
'accompanyingCourse' => $accompanyingPeriod, 'accompanyingCourse' => $accompanyingPeriod,
]); ]);
@@ -143,7 +143,7 @@ final class ActivityController extends AbstractController
/** /**
* Displays a form to edit an existing Activity entity. * Displays a form to edit an existing Activity entity.
*/ */
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/activity/{id}/edit', name: 'chill_activity_activity_edit', methods: ['GET', 'POST', 'PUT'])] #[\Symfony\Component\Routing\Attribute\Route(path: '/{_locale}/activity/{id}/edit', name: 'chill_activity_activity_edit', methods: ['GET', 'POST', 'PUT'])]
public function editAction(int $id, Request $request): Response public function editAction(int $id, Request $request): Response
{ {
$view = null; $view = null;
@@ -226,8 +226,8 @@ final class ActivityController extends AbstractController
return $this->render($view, [ return $this->render($view, [
'entity' => $entity, 'entity' => $entity,
'edit_form' => $form->createView(), 'edit_form' => $form,
'delete_form' => $deleteForm->createView(), 'delete_form' => $deleteForm,
'person' => $person, 'person' => $person,
'accompanyingCourse' => $accompanyingPeriod, 'accompanyingCourse' => $accompanyingPeriod,
'activity_json' => $activity_array, 'activity_json' => $activity_array,
@@ -237,7 +237,7 @@ final class ActivityController extends AbstractController
/** /**
* Lists all Activity entities. * Lists all Activity entities.
*/ */
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/activity/', name: 'chill_activity_activity_list')] #[\Symfony\Component\Routing\Attribute\Route(path: '/{_locale}/activity/', name: 'chill_activity_activity_list')]
public function listAction(Request $request): Response public function listAction(Request $request): Response
{ {
$view = null; $view = null;
@@ -341,7 +341,7 @@ final class ActivityController extends AbstractController
return $filterBuilder->build(); return $filterBuilder->build();
} }
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/activity/new', name: 'chill_activity_activity_new', methods: ['POST', 'GET'])] #[\Symfony\Component\Routing\Attribute\Route(path: '/{_locale}/activity/new', name: 'chill_activity_activity_new', methods: ['POST', 'GET'])]
public function newAction(Request $request): Response public function newAction(Request $request): Response
{ {
$view = null; $view = null;
@@ -364,7 +364,7 @@ final class ActivityController extends AbstractController
$activityData = null; $activityData = null;
if ($request->query->has('activityData')) { if ($request->query->has('activityData')) {
$activityData = $request->query->get('activityData'); $activityData = $request->query->all('activityData');
} }
if ( if (
@@ -516,13 +516,13 @@ final class ActivityController extends AbstractController
'person' => $person, 'person' => $person,
'accompanyingCourse' => $accompanyingPeriod, 'accompanyingCourse' => $accompanyingPeriod,
'entity' => $entity, 'entity' => $entity,
'form' => $form->createView(), 'form' => $form,
'activity_json' => $activity_array, 'activity_json' => $activity_array,
'default_location' => $defaultLocation, 'default_location' => $defaultLocation,
]); ]);
} }
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/activity/select-type', name: 'chill_activity_activity_select_type')] #[\Symfony\Component\Routing\Attribute\Route(path: '/{_locale}/activity/select-type', name: 'chill_activity_activity_select_type')]
public function selectTypeAction(Request $request): Response public function selectTypeAction(Request $request): Response
{ {
$view = null; $view = null;
@@ -567,7 +567,7 @@ final class ActivityController extends AbstractController
]); ]);
} }
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/activity/{id}/show', name: 'chill_activity_activity_show')] #[\Symfony\Component\Routing\Attribute\Route(path: '/{_locale}/activity/{id}/show', name: 'chill_activity_activity_show')]
public function showAction(Request $request, int $id): Response public function showAction(Request $request, int $id): Response
{ {
$entity = $this->activityRepository->find($id); $entity = $this->activityRepository->find($id);
@@ -611,7 +611,7 @@ final class ActivityController extends AbstractController
'person' => $person, 'person' => $person,
'accompanyingCourse' => $accompanyingPeriod, 'accompanyingCourse' => $accompanyingPeriod,
'entity' => $entity, 'entity' => $entity,
'delete_form' => $deleteForm->createView(), 'delete_form' => $deleteForm,
]); ]);
} }

View File

@@ -27,8 +27,8 @@ class ActivityReasonCategoryController extends AbstractController
/** /**
* Creates a new ActivityReasonCategory entity. * Creates a new ActivityReasonCategory entity.
*/ */
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/admin/activityreasoncategory/create', name: 'chill_activity_activityreasoncategory_create', methods: ['POST'])] #[\Symfony\Component\Routing\Attribute\Route(path: '/{_locale}/admin/activityreasoncategory/create', name: 'chill_activity_activityreasoncategory_create', methods: ['POST'])]
public function createAction(Request $request) public function createAction(Request $request): \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
{ {
$entity = new ActivityReasonCategory(); $entity = new ActivityReasonCategory();
$form = $this->createCreateForm($entity); $form = $this->createCreateForm($entity);
@@ -44,15 +44,15 @@ class ActivityReasonCategoryController extends AbstractController
return $this->render('@ChillActivity/ActivityReasonCategory/new.html.twig', [ return $this->render('@ChillActivity/ActivityReasonCategory/new.html.twig', [
'entity' => $entity, 'entity' => $entity,
'form' => $form->createView(), 'form' => $form,
]); ]);
} }
/** /**
* Lists all ActivityReasonCategory entities. * Lists all ActivityReasonCategory entities.
*/ */
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/admin/activityreasoncategory/', name: 'chill_activity_activityreasoncategory')] #[\Symfony\Component\Routing\Attribute\Route(path: '/{_locale}/admin/activityreasoncategory/', name: 'chill_activity_activityreasoncategory')]
public function indexAction() public function indexAction(): \Symfony\Component\HttpFoundation\Response
{ {
$em = $this->managerRegistry->getManager(); $em = $this->managerRegistry->getManager();
@@ -66,23 +66,23 @@ class ActivityReasonCategoryController extends AbstractController
/** /**
* Displays a form to create a new ActivityReasonCategory entity. * Displays a form to create a new ActivityReasonCategory entity.
*/ */
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/admin/activityreasoncategory/new', name: 'chill_activity_activityreasoncategory_new')] #[\Symfony\Component\Routing\Attribute\Route(path: '/{_locale}/admin/activityreasoncategory/new', name: 'chill_activity_activityreasoncategory_new')]
public function newAction() public function newAction(): \Symfony\Component\HttpFoundation\Response
{ {
$entity = new ActivityReasonCategory(); $entity = new ActivityReasonCategory();
$form = $this->createCreateForm($entity); $form = $this->createCreateForm($entity);
return $this->render('@ChillActivity/ActivityReasonCategory/new.html.twig', [ return $this->render('@ChillActivity/ActivityReasonCategory/new.html.twig', [
'entity' => $entity, 'entity' => $entity,
'form' => $form->createView(), 'form' => $form,
]); ]);
} }
/** /**
* Edits an existing ActivityReasonCategory entity. * Edits an existing ActivityReasonCategory entity.
*/ */
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/admin/activityreasoncategory/{id}/update', name: 'chill_activity_activityreasoncategory_update')] #[\Symfony\Component\Routing\Attribute\Route(path: '/{_locale}/admin/activityreasoncategory/{id}/update', name: 'chill_activity_activityreasoncategory_update', methods: ['POST', 'PUT'])]
public function updateAction(Request $request, mixed $id) public function updateAction(Request $request, mixed $id): \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
{ {
$em = $this->managerRegistry->getManager(); $em = $this->managerRegistry->getManager();
@@ -103,7 +103,7 @@ class ActivityReasonCategoryController extends AbstractController
return $this->render('@ChillActivity/ActivityReasonCategory/edit.html.twig', [ return $this->render('@ChillActivity/ActivityReasonCategory/edit.html.twig', [
'entity' => $entity, 'entity' => $entity,
'edit_form' => $editForm->createView(), 'edit_form' => $editForm,
]); ]);
} }

View File

@@ -28,8 +28,8 @@ class ActivityReasonController extends AbstractController
/** /**
* Creates a new ActivityReason entity. * Creates a new ActivityReason entity.
*/ */
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/admin/activityreason/create', name: 'chill_activity_activityreason_create', methods: ['POST'])] #[\Symfony\Component\Routing\Attribute\Route(path: '/{_locale}/admin/activityreason/create', name: 'chill_activity_activityreason_create', methods: ['POST'])]
public function createAction(Request $request) public function createAction(Request $request): \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
{ {
$entity = new ActivityReason(); $entity = new ActivityReason();
$form = $this->createCreateForm($entity); $form = $this->createCreateForm($entity);
@@ -45,15 +45,15 @@ class ActivityReasonController extends AbstractController
return $this->render('@ChillActivity/ActivityReason/new.html.twig', [ return $this->render('@ChillActivity/ActivityReason/new.html.twig', [
'entity' => $entity, 'entity' => $entity,
'form' => $form->createView(), 'form' => $form,
]); ]);
} }
/** /**
* Lists all ActivityReason entities. * Lists all ActivityReason entities.
*/ */
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/admin/activityreason/', name: 'chill_activity_activityreason')] #[\Symfony\Component\Routing\Attribute\Route(path: '/{_locale}/admin/activityreason/', name: 'chill_activity_activityreason')]
public function indexAction() public function indexAction(): \Symfony\Component\HttpFoundation\Response
{ {
$em = $this->managerRegistry->getManager(); $em = $this->managerRegistry->getManager();
@@ -67,23 +67,23 @@ class ActivityReasonController extends AbstractController
/** /**
* Displays a form to create a new ActivityReason entity. * Displays a form to create a new ActivityReason entity.
*/ */
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/admin/activityreason/new', name: 'chill_activity_activityreason_new')] #[\Symfony\Component\Routing\Attribute\Route(path: '/{_locale}/admin/activityreason/new', name: 'chill_activity_activityreason_new')]
public function newAction() public function newAction(): \Symfony\Component\HttpFoundation\Response
{ {
$entity = new ActivityReason(); $entity = new ActivityReason();
$form = $this->createCreateForm($entity); $form = $this->createCreateForm($entity);
return $this->render('@ChillActivity/ActivityReason/new.html.twig', [ return $this->render('@ChillActivity/ActivityReason/new.html.twig', [
'entity' => $entity, 'entity' => $entity,
'form' => $form->createView(), 'form' => $form,
]); ]);
} }
/** /**
* Edits an existing ActivityReason entity. * Edits an existing ActivityReason entity.
*/ */
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/admin/activityreason/{id}/update', name: 'chill_activity_activityreason_update')] #[\Symfony\Component\Routing\Attribute\Route(path: '/{_locale}/admin/activityreason/{id}/update', name: 'chill_activity_activityreason_update', methods: ['POST', 'PUT'])]
public function updateAction(Request $request, mixed $id) public function updateAction(Request $request, mixed $id): \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
{ {
$em = $this->managerRegistry->getManager(); $em = $this->managerRegistry->getManager();
@@ -104,7 +104,7 @@ class ActivityReasonController extends AbstractController
return $this->render('@ChillActivity/ActivityReason/edit.html.twig', [ return $this->render('@ChillActivity/ActivityReason/edit.html.twig', [
'entity' => $entity, 'entity' => $entity,
'edit_form' => $editForm->createView(), 'edit_form' => $editForm,
]); ]);
} }

View File

@@ -18,15 +18,15 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
*/ */
class AdminController extends AbstractController class AdminController extends AbstractController
{ {
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/admin/activity', name: 'chill_activity_admin_index')] #[\Symfony\Component\Routing\Attribute\Route(path: '/{_locale}/admin/activity', name: 'chill_activity_admin_index')]
public function indexActivityAction() public function indexActivityAction(): \Symfony\Component\HttpFoundation\Response
{ {
return $this->render('@ChillActivity/Admin/layout_activity.html.twig'); return $this->render('@ChillActivity/Admin/layout_activity.html.twig');
} }
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/admin/activity_redirect_to_main', name: 'chill_admin_aside_activity_redirect_to_admin_index', options: [null])] #[\Symfony\Component\Routing\Attribute\Route(path: '/{_locale}/admin/activity_redirect_to_main', name: 'chill_admin_aside_activity_redirect_to_admin_index', options: [null])]
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/admin/activity_redirect_to_main', name: 'chill_admin_activity_redirect_to_admin_index')] #[\Symfony\Component\Routing\Attribute\Route(path: '/{_locale}/admin/activity_redirect_to_main', name: 'chill_admin_activity_redirect_to_admin_index')]
public function redirectToAdminIndexAction() public function redirectToAdminIndexAction(): \Symfony\Component\HttpFoundation\RedirectResponse
{ {
return $this->redirectToRoute('chill_main_admin_central'); return $this->redirectToRoute('chill_main_admin_central');
} }

View File

@@ -27,8 +27,6 @@ use Faker\Factory as FakerFactory;
class LoadActivity extends AbstractFixture implements OrderedFixtureInterface class LoadActivity extends AbstractFixture implements OrderedFixtureInterface
{ {
use \Symfony\Component\DependencyInjection\ContainerAwareTrait;
private readonly \Faker\Generator $faker; private readonly \Faker\Generator $faker;
public function __construct(private readonly EntityManagerInterface $em) public function __construct(private readonly EntityManagerInterface $em)

View File

@@ -25,7 +25,7 @@ use Symfony\Component\HttpKernel\DependencyInjection\Extension;
*/ */
class ChillActivityExtension extends Extension implements PrependExtensionInterface class ChillActivityExtension extends Extension implements PrependExtensionInterface
{ {
public function load(array $configs, ContainerBuilder $container) public function load(array $configs, ContainerBuilder $container): void
{ {
$configuration = new Configuration(); $configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs); $config = $this->processConfiguration($configuration, $configs);
@@ -44,14 +44,14 @@ class ChillActivityExtension extends Extension implements PrependExtensionInterf
$loader->load('services/doctrine.entitylistener.yaml'); $loader->load('services/doctrine.entitylistener.yaml');
} }
public function prepend(ContainerBuilder $container) public function prepend(ContainerBuilder $container): void
{ {
$this->prependRoutes($container); $this->prependRoutes($container);
$this->prependAuthorization($container); $this->prependAuthorization($container);
$this->prependCruds($container); $this->prependCruds($container);
} }
public function prependAuthorization(ContainerBuilder $container) public function prependAuthorization(ContainerBuilder $container): void
{ {
$container->prependExtensionConfig('security', [ $container->prependExtensionConfig('security', [
'role_hierarchy' => [ 'role_hierarchy' => [
@@ -71,7 +71,7 @@ class ChillActivityExtension extends Extension implements PrependExtensionInterf
/** (non-PHPdoc). /** (non-PHPdoc).
* @see \Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface::prepend() * @see \Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface::prepend()
*/ */
public function prependRoutes(ContainerBuilder $container) public function prependRoutes(ContainerBuilder $container): void
{ {
// add routes for custom bundle // add routes for custom bundle
$container->prependExtensionConfig('chill_main', [ $container->prependExtensionConfig('chill_main', [

View File

@@ -22,7 +22,7 @@ use function is_int;
*/ */
class Configuration implements ConfigurationInterface class Configuration implements ConfigurationInterface
{ {
public function getConfigTreeBuilder() public function getConfigTreeBuilder(): \Symfony\Component\Config\Definition\Builder\TreeBuilder
{ {
$treeBuilder = new TreeBuilder('chill_activity'); $treeBuilder = new TreeBuilder('chill_activity');
$rootNode = $treeBuilder->getRootNode(); $rootNode = $treeBuilder->getRootNode();

View File

@@ -40,7 +40,7 @@ class ActivityReason
* *
* @return bool * @return bool
*/ */
public function getActive() public function getActive(): bool
{ {
return $this->active; return $this->active;
} }
@@ -58,7 +58,7 @@ class ActivityReason
* *
* @return int * @return int
*/ */
public function getId() public function getId(): ?int
{ {
return $this->id; return $this->id;
} }

View File

@@ -61,7 +61,7 @@ class ActivityReasonCategory implements \Stringable
* *
* @return bool * @return bool
*/ */
public function getActive() public function getActive(): bool
{ {
return $this->active; return $this->active;
} }
@@ -71,7 +71,7 @@ class ActivityReasonCategory implements \Stringable
* *
* @return int * @return int
*/ */
public function getId() public function getId(): ?int
{ {
return $this->id; return $this->id;
} }

View File

@@ -188,7 +188,7 @@ class ActivityType
private int $userVisible = self::FIELD_REQUIRED; private int $userVisible = self::FIELD_REQUIRED;
#[Assert\Callback] #[Assert\Callback]
public function checkSocialActionsVisibility(ExecutionContextInterface $context, mixed $payload) public function checkSocialActionsVisibility(ExecutionContextInterface $context, mixed $payload): void
{ {
if ($this->socialIssuesVisible !== $this->socialActionsVisible) { if ($this->socialIssuesVisible !== $this->socialActionsVisible) {
// if social issues are invisible then social actions cannot be optional or required + if social issues are optional then social actions shouldn't be required // if social issues are invisible then social actions cannot be optional or required + if social issues are optional then social actions shouldn't be required
@@ -461,11 +461,17 @@ class ActivityType
{ {
$property = $field.'Visible'; $property = $field.'Visible';
if (!property_exists($this, $property)) { // Get the real class name (not the proxy)
$class = get_class($this);
if (str_contains($class, '__CG__')) {
$class = get_parent_class($this);
}
$realClass = $class;
if (!property_exists($realClass, $property)) {
throw new \InvalidArgumentException('Field "'.$field.'" not found'); throw new \InvalidArgumentException('Field "'.$field.'" not found');
} }
/* @phpstan-ignore-next-line */
return self::FIELD_INVISIBLE !== $this->{$property}; return self::FIELD_INVISIBLE !== $this->{$property};
} }

View File

@@ -21,7 +21,7 @@ class ActivityEntityListener
{ {
public function __construct(private readonly EntityManagerInterface $em, private readonly AccompanyingPeriodWorkRepository $workRepository) {} public function __construct(private readonly EntityManagerInterface $em, private readonly AccompanyingPeriodWorkRepository $workRepository) {}
public function persistActionToCourse(Activity $activity) public function persistActionToCourse(Activity $activity): void
{ {
if ($activity->getAccompanyingPeriod() instanceof AccompanyingPeriod) { if ($activity->getAccompanyingPeriod() instanceof AccompanyingPeriod) {
$period = $activity->getAccompanyingPeriod(); $period = $activity->getAccompanyingPeriod();

View File

@@ -53,7 +53,7 @@ final readonly class ByActivityTypeAggregator implements AggregatorInterface
public function normalizeFormData(array $formData): array public function normalizeFormData(array $formData): array
{ {
return ['after_date' => $formData['after_date']->normalize(), 'before_date' => $formData['before_date']->normalize()]; return ['after_date' => $formData['after_date']?->normalize(), 'before_date' => $formData['before_date']?->normalize()];
} }
public function denormalizeFormData(array $formData, int $fromVersion): array public function denormalizeFormData(array $formData, int $fromVersion): array

View File

@@ -42,7 +42,7 @@ class AvgActivityVisitDuration implements ExportInterface, GroupedExportInterfac
$this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center']; $this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
} }
public function buildForm(FormBuilderInterface $builder) public function buildForm(FormBuilderInterface $builder): void
{ {
// TODO: Implement buildForm() method. // TODO: Implement buildForm() method.
} }

View File

@@ -42,7 +42,7 @@ final readonly class CountHouseholdOnActivity implements ExportInterface, Groupe
$this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center']; $this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
} }
public function buildForm(FormBuilderInterface $builder) {} public function buildForm(FormBuilderInterface $builder): void {}
public function getNormalizationVersion(): int public function getNormalizationVersion(): int
{ {

View File

@@ -34,7 +34,7 @@ final readonly class ListActivity implements ListInterface, GroupedExportInterfa
private FilterListAccompanyingPeriodHelperInterface $filterListAccompanyingPeriodHelper, private FilterListAccompanyingPeriodHelperInterface $filterListAccompanyingPeriodHelper,
) {} ) {}
public function buildForm(FormBuilderInterface $builder) public function buildForm(FormBuilderInterface $builder): void
{ {
$this->helper->buildForm($builder); $this->helper->buildForm($builder);
} }
@@ -154,7 +154,7 @@ final readonly class ListActivity implements ListInterface, GroupedExportInterfa
return ActivityStatsVoter::LISTS; return ActivityStatsVoter::LISTS;
} }
public function supportsModifiers() public function supportsModifiers(): array
{ {
return array_merge( return array_merge(
$this->helper->supportsModifiers(), $this->helper->supportsModifiers(),

View File

@@ -34,7 +34,7 @@ final readonly class CountHouseholdOnActivity implements ExportInterface, Groupe
$this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center']; $this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
} }
public function buildForm(FormBuilderInterface $builder) {} public function buildForm(FormBuilderInterface $builder): void {}
public function getNormalizationVersion(): int public function getNormalizationVersion(): int
{ {

View File

@@ -11,6 +11,7 @@ declare(strict_types=1);
namespace Chill\ActivityBundle\Export\Export\LinkedToPerson; namespace Chill\ActivityBundle\Export\Export\LinkedToPerson;
use Chill\ActivityBundle\Entity\Activity;
use Chill\ActivityBundle\Entity\ActivityReason; use Chill\ActivityBundle\Entity\ActivityReason;
use Chill\ActivityBundle\Export\Declarations; use Chill\ActivityBundle\Export\Declarations;
use Chill\ActivityBundle\Repository\ActivityRepository; use Chill\ActivityBundle\Repository\ActivityRepository;
@@ -59,7 +60,7 @@ class ListActivity implements ListInterface, GroupedExportInterface
$this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center']; $this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
} }
public function buildForm(FormBuilderInterface $builder) public function buildForm(FormBuilderInterface $builder): void
{ {
$builder->add('fields', ChoiceType::class, [ $builder->add('fields', ChoiceType::class, [
'multiple' => true, 'multiple' => true,
@@ -214,7 +215,7 @@ class ListActivity implements ListInterface, GroupedExportInterface
$qb = $this->entityManager->createQueryBuilder(); $qb = $this->entityManager->createQueryBuilder();
$qb $qb
->from('ChillActivityBundle:Activity', 'activity') ->from(Activity::class, 'activity')
->join('activity.person', 'person') ->join('activity.person', 'person')
->join( ->join(
HouseholdMember::class, HouseholdMember::class,

View File

@@ -19,7 +19,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
class ActivityReasonCategoryType extends AbstractType class ActivityReasonCategoryType extends AbstractType
{ {
public function buildForm(FormBuilderInterface $builder, array $options) public function buildForm(FormBuilderInterface $builder, array $options): void
{ {
$builder $builder
->add('name', TranslatableStringFormType::class) ->add('name', TranslatableStringFormType::class)
@@ -29,7 +29,7 @@ class ActivityReasonCategoryType extends AbstractType
/** /**
* @param OptionsResolverInterface $resolver * @param OptionsResolverInterface $resolver
*/ */
public function configureOptions(OptionsResolver $resolver) public function configureOptions(OptionsResolver $resolver): void
{ {
$resolver->setDefaults([ $resolver->setDefaults([
'data_class' => \Chill\ActivityBundle\Entity\ActivityReasonCategory::class, 'data_class' => \Chill\ActivityBundle\Entity\ActivityReasonCategory::class,
@@ -39,7 +39,7 @@ class ActivityReasonCategoryType extends AbstractType
/** /**
* @return string * @return string
*/ */
public function getBlockPrefix() public function getBlockPrefix(): string
{ {
return 'chill_activitybundle_activityreasoncategory'; return 'chill_activitybundle_activityreasoncategory';
} }

View File

@@ -21,7 +21,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
class ActivityReasonType extends AbstractType class ActivityReasonType extends AbstractType
{ {
public function buildForm(FormBuilderInterface $builder, array $options) public function buildForm(FormBuilderInterface $builder, array $options): void
{ {
$builder $builder
->add('name', TranslatableStringFormType::class) ->add('name', TranslatableStringFormType::class)
@@ -29,7 +29,7 @@ class ActivityReasonType extends AbstractType
->add('category', TranslatableActivityReasonCategoryType::class); ->add('category', TranslatableActivityReasonCategoryType::class);
} }
public function configureOptions(OptionsResolver $resolver) public function configureOptions(OptionsResolver $resolver): void
{ {
$resolver->setDefaults([ $resolver->setDefaults([
'data_class' => ActivityReason::class, 'data_class' => ActivityReason::class,
@@ -39,7 +39,7 @@ class ActivityReasonType extends AbstractType
/** /**
* @return string * @return string
*/ */
public function getBlockPrefix() public function getBlockPrefix(): string
{ {
return 'chill_activitybundle_activityreason'; return 'chill_activitybundle_activityreason';
} }

View File

@@ -27,7 +27,7 @@ class ActivityTypeType extends AbstractType
{ {
public function __construct(private readonly TranslatableStringHelper $translatableStringHelper) {} public function __construct(private readonly TranslatableStringHelper $translatableStringHelper) {}
public function buildForm(FormBuilderInterface $builder, array $options) public function buildForm(FormBuilderInterface $builder, array $options): void
{ {
$builder $builder
->add('name', TranslatableStringFormType::class) ->add('name', TranslatableStringFormType::class)
@@ -67,7 +67,7 @@ class ActivityTypeType extends AbstractType
->add('commentVisible', ActivityFieldPresence::class); ->add('commentVisible', ActivityFieldPresence::class);
} }
public function configureOptions(OptionsResolver $resolver) public function configureOptions(OptionsResolver $resolver): void
{ {
$resolver->setDefaults([ $resolver->setDefaults([
'data_class' => \Chill\ActivityBundle\Entity\ActivityType::class, 'data_class' => \Chill\ActivityBundle\Entity\ActivityType::class,

View File

@@ -18,7 +18,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
class ActivityFieldPresence extends AbstractType class ActivityFieldPresence extends AbstractType
{ {
public function configureOptions(OptionsResolver $resolver) public function configureOptions(OptionsResolver $resolver): void
{ {
$resolver->setDefaults( $resolver->setDefaults(
[ [
@@ -31,7 +31,7 @@ class ActivityFieldPresence extends AbstractType
); );
} }
public function getParent() public function getParent(): ?string
{ {
return ChoiceType::class; return ChoiceType::class;
} }

View File

@@ -30,7 +30,7 @@ class PickActivityReasonType extends AbstractType
private readonly TranslatableStringHelperInterface $translatableStringHelper, private readonly TranslatableStringHelperInterface $translatableStringHelper,
) {} ) {}
public function configureOptions(OptionsResolver $resolver) public function configureOptions(OptionsResolver $resolver): void
{ {
$resolver->setDefaults( $resolver->setDefaults(
[ [
@@ -49,12 +49,12 @@ class PickActivityReasonType extends AbstractType
); );
} }
public function getBlockPrefix() public function getBlockPrefix(): string
{ {
return 'translatable_activity_reason'; return 'translatable_activity_reason';
} }
public function getParent() public function getParent(): ?string
{ {
return EntityType::class; return EntityType::class;
} }

View File

@@ -25,7 +25,7 @@ class TranslatableActivityReasonCategoryType extends AbstractType
{ {
public function __construct(private readonly TranslatableStringHelperInterface $translatableStringHelper, private readonly TranslatorInterface $translator) {} public function __construct(private readonly TranslatableStringHelperInterface $translatableStringHelper, private readonly TranslatorInterface $translator) {}
public function configureOptions(OptionsResolver $resolver) public function configureOptions(OptionsResolver $resolver): void
{ {
$resolver->setDefaults( $resolver->setDefaults(
[ [
@@ -36,7 +36,7 @@ class TranslatableActivityReasonCategoryType extends AbstractType
); );
} }
public function getParent() public function getParent(): ?string
{ {
return EntityType::class; return EntityType::class;
} }

View File

@@ -22,7 +22,7 @@ class TranslatableActivityType extends AbstractType
{ {
public function __construct(protected TranslatableStringHelperInterface $translatableStringHelper, protected ActivityTypeRepositoryInterface $activityTypeRepository) {} public function __construct(protected TranslatableStringHelperInterface $translatableStringHelper, protected ActivityTypeRepositoryInterface $activityTypeRepository) {}
public function configureOptions(OptionsResolver $resolver) public function configureOptions(OptionsResolver $resolver): void
{ {
$resolver->setDefaults( $resolver->setDefaults(
[ [
@@ -34,12 +34,12 @@ class TranslatableActivityType extends AbstractType
); );
} }
public function getBlockPrefix() public function getBlockPrefix(): string
{ {
return 'translatable_activity_type'; return 'translatable_activity_type';
} }
public function getParent() public function getParent(): ?string
{ {
return EntityType::class; return EntityType::class;
} }

View File

@@ -16,7 +16,7 @@ use Chill\ActivityBundle\Security\Authorization\ActivityVoter;
use Chill\MainBundle\Routing\LocalMenuBuilderInterface; use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Knp\Menu\MenuItem; use Knp\Menu\MenuItem;
use Symfony\Component\Security\Core\Security; use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Contracts\Translation\TranslatorInterface; use Symfony\Contracts\Translation\TranslatorInterface;
/** /**
@@ -30,7 +30,7 @@ class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface
private readonly \Doctrine\Persistence\ManagerRegistry $managerRegistry, private readonly \Doctrine\Persistence\ManagerRegistry $managerRegistry,
) {} ) {}
public function buildMenu($menuId, MenuItem $menu, array $parameters) public function buildMenu($menuId, MenuItem $menu, array $parameters): void
{ {
$period = $parameters['accompanyingCourse']; $period = $parameters['accompanyingCourse'];

View File

@@ -14,7 +14,7 @@ namespace Chill\ActivityBundle\Menu;
use Chill\ActivityBundle\Security\Authorization\ActivityVoter; use Chill\ActivityBundle\Security\Authorization\ActivityVoter;
use Chill\MainBundle\Routing\LocalMenuBuilderInterface; use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
use Knp\Menu\MenuItem; use Knp\Menu\MenuItem;
use Symfony\Component\Security\Core\Security; use Symfony\Bundle\SecurityBundle\Security;
final readonly class AccompanyingCourseQuickMenuBuilder implements LocalMenuBuilderInterface final readonly class AccompanyingCourseQuickMenuBuilder implements LocalMenuBuilderInterface
{ {
@@ -25,7 +25,7 @@ final readonly class AccompanyingCourseQuickMenuBuilder implements LocalMenuBuil
return ['accompanying_course_quick_menu']; return ['accompanying_course_quick_menu'];
} }
public function buildMenu($menuId, MenuItem $menu, array $parameters) public function buildMenu($menuId, MenuItem $menu, array $parameters): void
{ {
/** @var \Chill\PersonBundle\Entity\AccompanyingPeriod $accompanyingCourse */ /** @var \Chill\PersonBundle\Entity\AccompanyingPeriod $accompanyingCourse */
$accompanyingCourse = $parameters['accompanying-course']; $accompanyingCourse = $parameters['accompanying-course'];

View File

@@ -13,7 +13,7 @@ namespace Chill\ActivityBundle\Menu;
use Chill\MainBundle\Routing\LocalMenuBuilderInterface; use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
use Knp\Menu\MenuItem; use Knp\Menu\MenuItem;
use Symfony\Component\Security\Core\Security; use Symfony\Bundle\SecurityBundle\Security;
/** /**
* @implements LocalMenuBuilderInterface<array> * @implements LocalMenuBuilderInterface<array>
@@ -22,7 +22,7 @@ final readonly class AdminMenuBuilder implements LocalMenuBuilderInterface
{ {
public function __construct(private Security $security) {} public function __construct(private Security $security) {}
public function buildMenu($menuId, MenuItem $menu, array $parameters) public function buildMenu($menuId, MenuItem $menu, array $parameters): void
{ {
if (!$this->security->isGranted('ROLE_ADMIN')) { if (!$this->security->isGranted('ROLE_ADMIN')) {
return; return;

View File

@@ -30,7 +30,7 @@ final readonly class PersonMenuBuilder implements LocalMenuBuilderInterface
private TranslatorInterface $translator, private TranslatorInterface $translator,
) {} ) {}
public function buildMenu($menuId, MenuItem $menu, array $parameters) public function buildMenu($menuId, MenuItem $menu, array $parameters): void
{ {
/** @var Person $person */ /** @var Person $person */
$person = $parameters['person']; $person = $parameters['person'];

View File

@@ -33,7 +33,7 @@ use Doctrine\ORM\Query\Expr\Join;
use Doctrine\ORM\Query\ResultSetMappingBuilder; use Doctrine\ORM\Query\ResultSetMappingBuilder;
use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\QueryBuilder;
use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Security\Core\Security; use Symfony\Bundle\SecurityBundle\Security;
final readonly class ActivityACLAwareRepository implements ActivityACLAwareRepositoryInterface final readonly class ActivityACLAwareRepository implements ActivityACLAwareRepositoryInterface
{ {

View File

@@ -24,7 +24,7 @@ use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface;
use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Entity\Person;
use Doctrine\DBAL\Types\Types; use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Security\Core\Security; use Symfony\Bundle\SecurityBundle\Security;
final readonly class ActivityDocumentACLAwareRepository implements ActivityDocumentACLAwareRepositoryInterface final readonly class ActivityDocumentACLAwareRepository implements ActivityDocumentACLAwareRepositoryInterface
{ {

View File

@@ -1,7 +1,7 @@
<template> <template>
<concerned-groups v-if="hasPerson" /> <concerned-groups v-if="hasPerson" />
<social-issues-acc v-if="hasSocialIssues" /> <social-issues-acc v-if="hasSocialIssues" />
<location v-if="hasLocation" /> <location v-if="hasLocation" />
</template> </template>
<script> <script>
@@ -10,12 +10,12 @@ import SocialIssuesAcc from "./components/SocialIssuesAcc.vue";
import Location from "./components/Location.vue"; import Location from "./components/Location.vue";
export default { export default {
name: "App", name: "App",
props: ["hasSocialIssues", "hasLocation", "hasPerson"], props: ["hasSocialIssues", "hasLocation", "hasPerson"],
components: { components: {
ConcernedGroups, ConcernedGroups,
SocialIssuesAcc, SocialIssuesAcc,
Location, Location,
}, },
}; };
</script> </script>

View File

@@ -1,43 +1,46 @@
<template> <template>
<teleport to="#add-persons" v-if="isComponentVisible"> <teleport to="#add-persons" v-if="isComponentVisible">
<div class="flex-bloc concerned-groups" :class="getContext"> <div class="flex-bloc concerned-groups" :class="getContext">
<persons-bloc <persons-bloc
v-for="bloc in contextPersonsBlocs" v-for="bloc in contextPersonsBlocs"
:key="bloc.key" :key="bloc.key"
:bloc="bloc" :bloc="bloc"
:bloc-width="getBlocWidth" :bloc-width="getBlocWidth"
:set-persons-in-bloc="setPersonsInBloc" :set-persons-in-bloc="setPersonsInBloc"
/> />
</div> </div>
<div <div
v-if="getContext === 'accompanyingCourse' && suggestedEntities.length > 0" v-if="
> getContext === 'accompanyingCourse' &&
<ul class="list-suggest add-items inline"> suggestedEntities.length > 0
<li "
v-for="(p, i) in suggestedEntities"
@click="addSuggestedEntity(p)"
:key="`suggestedEntities-${i}`"
> >
<person-text v-if="p.type === 'person'" :person="p" /> <ul class="list-suggest add-items inline">
<span v-else>{{ p.text }}</span> <li
</li> v-for="(p, i) in suggestedEntities"
</ul> @click="addSuggestedEntity(p)"
</div> :key="`suggestedEntities-${i}`"
>
<person-text v-if="p.type === 'person'" :person="p" />
<span v-else>{{ p.text }}</span>
</li>
</ul>
</div>
<ul class="record_actions"> <ul class="record_actions">
<li class="add-persons"> <li class="add-persons">
<add-persons <add-persons
:buttonTitle="trans(ACTIVITY_ADD_PERSONS)" :buttonTitle="trans(ACTIVITY_ADD_PERSONS)"
:modalTitle="trans(ACTIVITY_ADD_PERSONS)" :modalTitle="trans(ACTIVITY_ADD_PERSONS)"
v-bind:key="addPersons.key" v-bind:key="addPersons.key"
v-bind:options="addPersonsOptions" v-bind:options="addPersonsOptions"
@addNewPersons="addNewPersons" @addNewPersons="addNewPersons"
ref="addPersons" ref="addPersons"
> >
</add-persons> </add-persons>
</li> </li>
</ul> </ul>
</teleport> </teleport>
</template> </template>
<script> <script>
@@ -46,208 +49,208 @@ import AddPersons from "ChillPersonAssets/vuejs/_components/AddPersons.vue";
import PersonsBloc from "./ConcernedGroups/PersonsBloc.vue"; import PersonsBloc from "./ConcernedGroups/PersonsBloc.vue";
import PersonText from "ChillPersonAssets/vuejs/_components/Entity/PersonText.vue"; import PersonText from "ChillPersonAssets/vuejs/_components/Entity/PersonText.vue";
import { import {
ACTIVITY_BLOC_PERSONS, ACTIVITY_BLOC_PERSONS,
ACTIVITY_BLOC_PERSONS_ASSOCIATED, ACTIVITY_BLOC_PERSONS_ASSOCIATED,
ACTIVITY_BLOC_THIRDPARTY, ACTIVITY_BLOC_THIRDPARTY,
ACTIVITY_BLOC_USERS, ACTIVITY_BLOC_USERS,
ACTIVITY_ADD_PERSONS, ACTIVITY_ADD_PERSONS,
trans, trans,
} from "translator"; } from "translator";
export default { export default {
name: "ConcernedGroups", name: "ConcernedGroups",
components: { components: {
AddPersons, AddPersons,
PersonsBloc, PersonsBloc,
PersonText, PersonText,
}, },
setup() { setup() {
return { return {
trans, trans,
ACTIVITY_ADD_PERSONS, ACTIVITY_ADD_PERSONS,
}; };
}, },
data() { data() {
return { return {
personsBlocs: [ personsBlocs: [
{ {
key: "persons", key: "persons",
title: trans(ACTIVITY_BLOC_PERSONS), title: trans(ACTIVITY_BLOC_PERSONS),
persons: [], persons: [],
included: false, included: false,
},
{
key: "personsAssociated",
title: trans(ACTIVITY_BLOC_PERSONS_ASSOCIATED),
persons: [],
included: window.activity
? window.activity.activityType.personsVisible !== 0
: true,
},
{
key: "personsNotAssociated",
title: "activity.bloc_persons_not_associated",
persons: [],
included: window.activity
? window.activity.activityType.personsVisible !== 0
: true,
},
{
key: "thirdparty",
title: trans(ACTIVITY_BLOC_THIRDPARTY),
persons: [],
included: window.activity
? window.activity.activityType.thirdPartiesVisible !== 0
: true,
},
{
key: "users",
title: trans(ACTIVITY_BLOC_USERS),
persons: [],
included: window.activity
? window.activity.activityType.usersVisible !== 0
: true,
},
],
addPersons: {
key: "activity",
},
};
},
computed: {
isComponentVisible() {
return window.activity
? window.activity.activityType.personsVisible !== 0 ||
window.activity.activityType.thirdPartiesVisible !== 0 ||
window.activity.activityType.usersVisible !== 0
: true;
}, },
{ ...mapState({
key: "personsAssociated", persons: (state) => state.activity.persons,
title: trans(ACTIVITY_BLOC_PERSONS_ASSOCIATED), thirdParties: (state) => state.activity.thirdParties,
persons: [], users: (state) => state.activity.users,
included: window.activity accompanyingCourse: (state) => state.activity.accompanyingPeriod,
? window.activity.activityType.personsVisible !== 0 }),
: true, ...mapGetters(["suggestedEntities"]),
getContext() {
return this.accompanyingCourse ? "accompanyingCourse" : "person";
}, },
{ contextPersonsBlocs() {
key: "personsNotAssociated", return this.personsBlocs.filter((bloc) => bloc.included !== false);
title: "activity.bloc_persons_not_associated",
persons: [],
included: window.activity
? window.activity.activityType.personsVisible !== 0
: true,
}, },
{ addPersonsOptions() {
key: "thirdparty", let optionsType = [];
title: trans(ACTIVITY_BLOC_THIRDPARTY), if (window.activity) {
persons: [], if (window.activity.activityType.personsVisible !== 0) {
included: window.activity optionsType.push("person");
? window.activity.activityType.thirdPartiesVisible !== 0 }
: true, if (window.activity.activityType.thirdPartiesVisible !== 0) {
optionsType.push("thirdparty");
}
if (window.activity.activityType.usersVisible !== 0) {
optionsType.push("user");
}
} else {
optionsType = ["person", "thirdparty", "user"];
}
return {
type: optionsType,
priority: null,
uniq: false,
button: {
size: "btn-sm",
},
};
}, },
{ getBlocWidth() {
key: "users", return Math.round(100 / this.contextPersonsBlocs.length) + "%";
title: trans(ACTIVITY_BLOC_USERS),
persons: [],
included: window.activity
? window.activity.activityType.usersVisible !== 0
: true,
}, },
],
addPersons: {
key: "activity",
},
};
},
computed: {
isComponentVisible() {
return window.activity
? window.activity.activityType.personsVisible !== 0 ||
window.activity.activityType.thirdPartiesVisible !== 0 ||
window.activity.activityType.usersVisible !== 0
: true;
}, },
...mapState({ mounted() {
persons: (state) => state.activity.persons, this.setPersonsInBloc();
thirdParties: (state) => state.activity.thirdParties,
users: (state) => state.activity.users,
accompanyingCourse: (state) => state.activity.accompanyingPeriod,
}),
...mapGetters(["suggestedEntities"]),
getContext() {
return this.accompanyingCourse ? "accompanyingCourse" : "person";
}, },
contextPersonsBlocs() { methods: {
return this.personsBlocs.filter((bloc) => bloc.included !== false); setPersonsInBloc() {
}, let groups;
addPersonsOptions() { if (this.accompanyingCourse) {
let optionsType = []; groups = this.splitPersonsInGroups();
if (window.activity) { }
if (window.activity.activityType.personsVisible !== 0) { this.personsBlocs.forEach((bloc) => {
optionsType.push("person"); if (this.accompanyingCourse) {
} switch (bloc.key) {
if (window.activity.activityType.thirdPartiesVisible !== 0) { case "personsAssociated":
optionsType.push("thirdparty"); bloc.persons = groups.personsAssociated;
} bloc.included = true;
if (window.activity.activityType.usersVisible !== 0) { break;
optionsType.push("user"); case "personsNotAssociated":
} bloc.persons = groups.personsNotAssociated;
} else { bloc.included = true;
optionsType = ["person", "thirdparty", "user"]; break;
} }
return { } else {
type: optionsType, switch (bloc.key) {
priority: null, case "persons":
uniq: false, bloc.persons = this.persons;
button: { bloc.included = true;
size: "btn-sm", break;
}
}
switch (bloc.key) {
case "thirdparty":
bloc.persons = this.thirdParties;
break;
case "users":
bloc.persons = this.users;
break;
}
}, groups);
},
splitPersonsInGroups() {
let personsAssociated = [];
let personsNotAssociated = this.persons;
let participations = this.getCourseParticipations();
this.persons.forEach((person) => {
participations.forEach((participation) => {
if (person.id === participation.id) {
//console.log(person.id);
personsAssociated.push(person);
personsNotAssociated = personsNotAssociated.filter(
(p) => p !== person,
);
}
});
});
return {
personsAssociated: personsAssociated,
personsNotAssociated: personsNotAssociated,
};
},
getCourseParticipations() {
let participations = [];
this.accompanyingCourse.participations.forEach((participation) => {
if (!participation.endDate) {
participations.push(participation.person);
}
});
return participations;
},
addNewPersons({ selected, modal }) {
console.log("@@@ CLICK button addNewPersons", selected);
selected.forEach((item) => {
this.$store.dispatch("addPersonsInvolved", item);
}, this);
this.$refs.addPersons.resetSearch(); // to cast child method
modal.showModal = false;
this.setPersonsInBloc();
},
addSuggestedEntity(person) {
this.$store.dispatch("addPersonsInvolved", {
result: person,
type: "person",
});
this.setPersonsInBloc();
}, },
};
}, },
getBlocWidth() {
return Math.round(100 / this.contextPersonsBlocs.length) + "%";
},
},
mounted() {
this.setPersonsInBloc();
},
methods: {
setPersonsInBloc() {
let groups;
if (this.accompanyingCourse) {
groups = this.splitPersonsInGroups();
}
this.personsBlocs.forEach((bloc) => {
if (this.accompanyingCourse) {
switch (bloc.key) {
case "personsAssociated":
bloc.persons = groups.personsAssociated;
bloc.included = true;
break;
case "personsNotAssociated":
bloc.persons = groups.personsNotAssociated;
bloc.included = true;
break;
}
} else {
switch (bloc.key) {
case "persons":
bloc.persons = this.persons;
bloc.included = true;
break;
}
}
switch (bloc.key) {
case "thirdparty":
bloc.persons = this.thirdParties;
break;
case "users":
bloc.persons = this.users;
break;
}
}, groups);
},
splitPersonsInGroups() {
let personsAssociated = [];
let personsNotAssociated = this.persons;
let participations = this.getCourseParticipations();
this.persons.forEach((person) => {
participations.forEach((participation) => {
if (person.id === participation.id) {
//console.log(person.id);
personsAssociated.push(person);
personsNotAssociated = personsNotAssociated.filter(
(p) => p !== person,
);
}
});
});
return {
personsAssociated: personsAssociated,
personsNotAssociated: personsNotAssociated,
};
},
getCourseParticipations() {
let participations = [];
this.accompanyingCourse.participations.forEach((participation) => {
if (!participation.endDate) {
participations.push(participation.person);
}
});
return participations;
},
addNewPersons({ selected, modal }) {
console.log("@@@ CLICK button addNewPersons", selected);
selected.forEach((item) => {
this.$store.dispatch("addPersonsInvolved", item);
}, this);
this.$refs.addPersons.resetSearch(); // to cast child method
modal.showModal = false;
this.setPersonsInBloc();
},
addSuggestedEntity(person) {
this.$store.dispatch("addPersonsInvolved", {
result: person,
type: "person",
});
this.setPersonsInBloc();
},
},
}; };
</script> </script>

View File

@@ -1,29 +1,29 @@
<template> <template>
<li> <li>
<span :title="person.text" @click.prevent="$emit('remove', person)"> <span :title="person.text" @click.prevent="$emit('remove', person)">
<span class="chill_denomination"> <span class="chill_denomination">
<person-text :person="person" :is-cut="true" /> <person-text :person="person" :is-cut="true" />
</span> </span>
</span> </span>
</li> </li>
</template> </template>
<script> <script>
import PersonText from "ChillPersonAssets/vuejs/_components/Entity/PersonText.vue"; import PersonText from "ChillPersonAssets/vuejs/_components/Entity/PersonText.vue";
export default { export default {
name: "PersonBadge", name: "PersonBadge",
props: ["person"], props: ["person"],
components: { components: {
PersonText, PersonText,
}, },
// computed: { // computed: {
// textCutted() { // textCutted() {
// let more = (this.person.text.length > 15) ?'…' : ''; // let more = (this.person.text.length > 15) ?'…' : '';
// return this.person.text.slice(0,15) + more; // return this.person.text.slice(0,15) + more;
// } // }
// }, // },
emits: ["remove"], emits: ["remove"],
}; };
</script> </script>

View File

@@ -1,38 +1,38 @@
<template> <template>
<div class="item-bloc" :style="{ 'flex-basis': blocWidth }"> <div class="item-bloc" :style="{ 'flex-basis': blocWidth }">
<div class="item-row"> <div class="item-row">
<div class="item-col"> <div class="item-col">
<h4>{{ $t(bloc.title) }}</h4> <h4>{{ $t(bloc.title) }}</h4>
</div> </div>
<div class="item-col"> <div class="item-col">
<ul class="list-suggest remove-items"> <ul class="list-suggest remove-items">
<person-badge <person-badge
v-for="person in bloc.persons" v-for="person in bloc.persons"
:key="person.id" :key="person.id"
:person="person" :person="person"
@remove="removePerson" @remove="removePerson"
/> />
</ul> </ul>
</div> </div>
</div>
</div> </div>
</div>
</template> </template>
<script> <script>
import PersonBadge from "./PersonBadge.vue"; import PersonBadge from "./PersonBadge.vue";
export default { export default {
name: "PersonsBloc", name: "PersonsBloc",
components: { components: {
PersonBadge, PersonBadge,
}, },
props: ["bloc", "setPersonsInBloc", "blocWidth"], props: ["bloc", "setPersonsInBloc", "blocWidth"],
methods: { methods: {
removePerson(item) { removePerson(item) {
console.log("@@ CLICK remove person: item", item); console.log("@@ CLICK remove person: item", item);
this.$store.dispatch("removePersonInvolved", item); this.$store.dispatch("removePersonInvolved", item);
this.setPersonsInBloc(); this.setPersonsInBloc();
},
}, },
},
}; };
</script> </script>

View File

@@ -1,32 +1,32 @@
<template> <template>
<teleport to="#location"> <teleport to="#location">
<div class="mb-3 row"> <div class="mb-3 row">
<label :class="locationClassList"> <label :class="locationClassList">
{{ trans(ACTIVITY_LOCATION) }} {{ trans(ACTIVITY_LOCATION) }}
</label> </label>
<div class="col-sm-8"> <div class="col-sm-8">
<VueMultiselect <VueMultiselect
name="selectLocation" name="selectLocation"
id="selectLocation" id="selectLocation"
label="name" label="name"
track-by="id" track-by="id"
open-direction="top" open-direction="top"
:multiple="false" :multiple="false"
:searchable="true" :searchable="true"
:placeholder="trans(ACTIVITY_CHOOSE_LOCATION)" :placeholder="trans(ACTIVITY_CHOOSE_LOCATION)"
:custom-label="customLabel" :custom-label="customLabel"
:select-label="trans(MULTISELECT_SELECT_LABEL)" :select-label="trans(MULTISELECT_SELECT_LABEL)"
:deselect-label="trans(MULTISELECT_DESELECT_LABEL)" :deselect-label="trans(MULTISELECT_DESELECT_LABEL)"
:selected-label="trans(MULTISELECT_SELECTED_LABEL)" :selected-label="trans(MULTISELECT_SELECTED_LABEL)"
:options="availableLocations" :options="availableLocations"
group-values="locations" group-values="locations"
group-label="locationGroup" group-label="locationGroup"
v-model="location" v-model="location"
/> />
<new-location v-bind:available-locations="availableLocations" /> <new-location v-bind:available-locations="availableLocations" />
</div> </div>
</div> </div>
</teleport> </teleport>
</template> </template>
<script> <script>
@@ -35,60 +35,60 @@ import VueMultiselect from "vue-multiselect";
import NewLocation from "./Location/NewLocation.vue"; import NewLocation from "./Location/NewLocation.vue";
import { localizeString } from "ChillMainAssets/lib/localizationHelper/localizationHelper"; import { localizeString } from "ChillMainAssets/lib/localizationHelper/localizationHelper";
import { import {
trans, trans,
ACTIVITY_LOCATION, ACTIVITY_LOCATION,
ACTIVITY_CHOOSE_LOCATION, ACTIVITY_CHOOSE_LOCATION,
MULTISELECT_SELECT_LABEL, MULTISELECT_SELECT_LABEL,
MULTISELECT_DESELECT_LABEL, MULTISELECT_DESELECT_LABEL,
MULTISELECT_SELECTED_LABEL, MULTISELECT_SELECTED_LABEL,
} from "translator"; } from "translator";
export default { export default {
name: "Location", name: "Location",
components: { components: {
NewLocation, NewLocation,
VueMultiselect, VueMultiselect,
},
setup() {
return {
trans,
ACTIVITY_LOCATION,
ACTIVITY_CHOOSE_LOCATION,
MULTISELECT_SELECT_LABEL,
MULTISELECT_DESELECT_LABEL,
MULTISELECT_SELECTED_LABEL,
};
},
data() {
return {
locationClassList: `col-form-label col-sm-4 ${document.querySelector("input#chill_activitybundle_activity_location").getAttribute("required") ? "required" : ""}`,
};
},
computed: {
...mapState(["activity", "availableLocations"]),
...mapGetters(["suggestedEntities"]),
location: {
get() {
return this.activity.location;
},
set(value) {
this.$store.dispatch("updateLocation", value);
},
}, },
}, setup() {
methods: { return {
labelAccompanyingCourseLocation(value) { trans,
return `${value.address.text} (${localizeString(value.locationType.title)})`; ACTIVITY_LOCATION,
ACTIVITY_CHOOSE_LOCATION,
MULTISELECT_SELECT_LABEL,
MULTISELECT_DESELECT_LABEL,
MULTISELECT_SELECTED_LABEL,
};
}, },
customLabel(value) { data() {
return value.locationType return {
? value.name locationClassList: `col-form-label col-sm-4 ${document.querySelector("input#chill_activitybundle_activity_location").getAttribute("required") ? "required" : ""}`,
? value.name === "__AccompanyingCourseLocation__" };
? this.labelAccompanyingCourseLocation(value) },
: `${value.name} (${localizeString(value.locationType.title)})` computed: {
: localizeString(value.locationType.title) ...mapState(["activity", "availableLocations"]),
: ""; ...mapGetters(["suggestedEntities"]),
location: {
get() {
return this.activity.location;
},
set(value) {
this.$store.dispatch("updateLocation", value);
},
},
},
methods: {
labelAccompanyingCourseLocation(value) {
return `${value.address.text} (${localizeString(value.locationType.title)})`;
},
customLabel(value) {
return value.locationType
? value.name
? value.name === "__AccompanyingCourseLocation__"
? this.labelAccompanyingCourseLocation(value)
: `${value.name} (${localizeString(value.locationType.title)})`
: localizeString(value.locationType.title)
: "";
},
}, },
},
}; };
</script> </script>

View File

@@ -1,114 +1,123 @@
<template> <template>
<div> <div>
<ul class="record_actions"> <ul class="record_actions">
<li> <li>
<a class="btn btn-sm btn-create" @click="openModal"> <a class="btn btn-sm btn-create" @click="openModal">
{{ trans(ACTIVITY_CREATE_NEW_LOCATION) }} {{ trans(ACTIVITY_CREATE_NEW_LOCATION) }}
</a> </a>
</li> </li>
</ul> </ul>
<teleport to="body"> <teleport to="body">
<modal <modal
v-if="modal.showModal" v-if="modal.showModal"
:modalDialogClass="modal.modalDialogClass" :modalDialogClass="modal.modalDialogClass"
@close="modal.showModal = false" @close="modal.showModal = false"
> >
<template #header> <template #header>
<h3 class="modal-title"> <h3 class="modal-title">
{{ trans(ACTIVITY_CREATE_NEW_LOCATION) }} {{ trans(ACTIVITY_CREATE_NEW_LOCATION) }}
</h3> </h3>
</template> </template>
<template #body> <template #body>
<form> <form>
<div class="alert alert-warning" v-if="errors.length"> <div class="alert alert-warning" v-if="errors.length">
<ul> <ul>
<li v-for="(e, i) in errors" :key="i"> <li v-for="(e, i) in errors" :key="i">
{{ e }} {{ e }}
</li> </li>
</ul> </ul>
</div> </div>
<div class="form-floating mb-3"> <div class="form-floating mb-3">
<select <select
class="form-select form-select-lg" class="form-select form-select-lg"
id="type" id="type"
required required
v-model="selectType" v-model="selectType"
> >
<option selected disabled value=""> <option selected disabled value="">
{{ trans(ACTIVITY_CHOOSE_LOCATION_TYPE) }} {{ trans(ACTIVITY_CHOOSE_LOCATION_TYPE) }}
</option> </option>
<option v-for="t in locationTypes" :value="t" :key="t.id"> <option
{{ localizeString(t.title) }} v-for="t in locationTypes"
</option> :value="t"
</select> :key="t.id"
<label>{{ trans(ACTIVITY_LOCATION_FIELDS_TYPE) }}</label> >
</div> {{ localizeString(t.title) }}
</option>
</select>
<label>{{
trans(ACTIVITY_LOCATION_FIELDS_TYPE)
}}</label>
</div>
<div class="form-floating mb-3"> <div class="form-floating mb-3">
<input <input
class="form-control form-control-lg" class="form-control form-control-lg"
id="name" id="name"
v-model="inputName" v-model="inputName"
placeholder placeholder
/> />
<label for="name">{{ <label for="name">{{
trans(ACTIVITY_LOCATION_FIELDS_NAME) trans(ACTIVITY_LOCATION_FIELDS_NAME)
}}</label> }}</label>
</div> </div>
<add-address <add-address
:context="addAddress.context" :context="addAddress.context"
:options="addAddress.options" :options="addAddress.options"
:addressChangedCallback="submitNewAddress" :addressChangedCallback="submitNewAddress"
v-if="showAddAddress" v-if="showAddAddress"
ref="addAddress" ref="addAddress"
/> />
<div class="form-floating mb-3" v-if="showContactData"> <div class="form-floating mb-3" v-if="showContactData">
<input <input
class="form-control form-control-lg" class="form-control form-control-lg"
id="phonenumber1" id="phonenumber1"
v-model="inputPhonenumber1" v-model="inputPhonenumber1"
placeholder placeholder
/> />
<label for="phonenumber1">{{ <label for="phonenumber1">{{
trans(ACTIVITY_LOCATION_FIELDS_PHONENUMBER1) trans(ACTIVITY_LOCATION_FIELDS_PHONENUMBER1)
}}</label> }}</label>
</div> </div>
<div class="form-floating mb-3" v-if="hasPhonenumber1"> <div class="form-floating mb-3" v-if="hasPhonenumber1">
<input <input
class="form-control form-control-lg" class="form-control form-control-lg"
id="phonenumber2" id="phonenumber2"
v-model="inputPhonenumber2" v-model="inputPhonenumber2"
placeholder placeholder
/> />
<label for="phonenumber2">{{ <label for="phonenumber2">{{
trans(ACTIVITY_LOCATION_FIELDS_PHONENUMBER2) trans(ACTIVITY_LOCATION_FIELDS_PHONENUMBER2)
}}</label> }}</label>
</div> </div>
<div class="form-floating mb-3" v-if="showContactData"> <div class="form-floating mb-3" v-if="showContactData">
<input <input
class="form-control form-control-lg" class="form-control form-control-lg"
id="email" id="email"
v-model="inputEmail" v-model="inputEmail"
placeholder placeholder
/> />
<label for="email">{{ <label for="email">{{
trans(ACTIVITY_LOCATION_FIELDS_EMAIL) trans(ACTIVITY_LOCATION_FIELDS_EMAIL)
}}</label> }}</label>
</div> </div>
</form> </form>
</template> </template>
<template #footer> <template #footer>
<button class="btn btn-save" @click.prevent="saveNewLocation"> <button
{{ trans(SAVE) }} class="btn btn-save"
</button> @click.prevent="saveNewLocation"
</template> >
</modal> {{ trans(SAVE) }}
</teleport> </button>
</div> </template>
</modal>
</teleport>
</div>
</template> </template>
<script> <script>
@@ -119,236 +128,237 @@ import { getLocationTypes } from "../../api";
import { makeFetch } from "ChillMainAssets/lib/api/apiMethods"; import { makeFetch } from "ChillMainAssets/lib/api/apiMethods";
import { localizeString } from "ChillMainAssets/lib/localizationHelper/localizationHelper"; import { localizeString } from "ChillMainAssets/lib/localizationHelper/localizationHelper";
import { import {
SAVE, SAVE,
ACTIVITY_LOCATION_FIELDS_EMAIL, ACTIVITY_LOCATION_FIELDS_EMAIL,
ACTIVITY_LOCATION_FIELDS_PHONENUMBER1, ACTIVITY_LOCATION_FIELDS_PHONENUMBER1,
ACTIVITY_LOCATION_FIELDS_PHONENUMBER2, ACTIVITY_LOCATION_FIELDS_PHONENUMBER2,
ACTIVITY_LOCATION_FIELDS_NAME, ACTIVITY_LOCATION_FIELDS_NAME,
ACTIVITY_LOCATION_FIELDS_TYPE, ACTIVITY_LOCATION_FIELDS_TYPE,
ACTIVITY_CHOOSE_LOCATION_TYPE, ACTIVITY_CHOOSE_LOCATION_TYPE,
ACTIVITY_CREATE_NEW_LOCATION, ACTIVITY_CREATE_NEW_LOCATION,
trans, trans,
} from "translator"; } from "translator";
export default { export default {
name: "NewLocation", name: "NewLocation",
components: { components: {
Modal, Modal,
AddAddress, AddAddress,
},
setup() {
return {
trans,
SAVE,
ACTIVITY_LOCATION_FIELDS_EMAIL,
ACTIVITY_LOCATION_FIELDS_PHONENUMBER1,
ACTIVITY_LOCATION_FIELDS_PHONENUMBER2,
ACTIVITY_LOCATION_FIELDS_NAME,
ACTIVITY_LOCATION_FIELDS_TYPE,
ACTIVITY_CHOOSE_LOCATION_TYPE,
ACTIVITY_CREATE_NEW_LOCATION,
};
},
props: ["availableLocations"],
data() {
return {
errors: [],
selected: {
type: null,
name: null,
addressId: null,
phonenumber1: null,
phonenumber2: null,
email: null,
},
locationTypes: [],
modal: {
showModal: false,
modalDialogClass: "modal-dialog-scrollable modal-xl",
},
addAddress: {
options: {
button: {
text: {
create: "activity.create_address",
edit: "activity.edit_address",
},
size: "btn-sm",
},
title: {
create: "activity.create_address",
edit: "activity.edit_address",
},
},
context: {
target: {
//name, id
},
edit: false,
addressId: null,
defaults: window.addaddress,
},
},
};
},
computed: {
...mapState(["activity"]),
selectType: {
get() {
return this.selected.type;
},
set(value) {
this.selected.type = value;
},
}, },
inputName: { setup() {
get() { return {
return this.selected.name; trans,
}, SAVE,
set(value) { ACTIVITY_LOCATION_FIELDS_EMAIL,
this.selected.name = value; ACTIVITY_LOCATION_FIELDS_PHONENUMBER1,
}, ACTIVITY_LOCATION_FIELDS_PHONENUMBER2,
}, ACTIVITY_LOCATION_FIELDS_NAME,
inputEmail: { ACTIVITY_LOCATION_FIELDS_TYPE,
get() { ACTIVITY_CHOOSE_LOCATION_TYPE,
return this.selected.email; ACTIVITY_CREATE_NEW_LOCATION,
},
set(value) {
this.selected.email = value;
},
},
inputPhonenumber1: {
get() {
return this.selected.phonenumber1;
},
set(value) {
this.selected.phonenumber1 = value;
},
},
inputPhonenumber2: {
get() {
return this.selected.phonenumber2;
},
set(value) {
this.selected.phonenumber2 = value;
},
},
hasPhonenumber1() {
return (
this.selected.phonenumber1 !== null && this.selected.phonenumber1 !== ""
);
},
showAddAddress() {
let cond = false;
if (this.selected.type) {
if (this.selected.type.addressRequired !== "never") {
cond = true;
}
}
return cond;
},
showContactData() {
let cond = false;
if (this.selected.type) {
if (this.selected.type.contactData !== "never") {
cond = true;
}
}
return cond;
},
},
mounted() {
this.getLocationTypesList();
},
methods: {
localizeString,
checkForm() {
let cond = true;
this.errors = [];
if (!this.selected.type) {
this.errors.push("Type de localisation requis");
cond = false;
} else {
if (
this.selected.type.addressRequired === "required" &&
!this.selected.addressId
) {
this.errors.push("Adresse requise");
cond = false;
}
if (
this.selected.type.contactData === "required" &&
!this.selected.phonenumber1
) {
this.errors.push("Numéro de téléphone requis");
cond = false;
}
if (
this.selected.type.contactData === "required" &&
!this.selected.email
) {
this.errors.push("Adresse email requise");
cond = false;
}
}
return cond;
},
getLocationTypesList() {
getLocationTypes().then((results) => {
this.locationTypes = results.filter(
(t) => t.availableForUsers === true,
);
});
},
openModal() {
this.modal.showModal = true;
},
saveNewLocation() {
if (this.checkForm()) {
let body = {
type: "location",
name: this.selected.name,
locationType: {
id: this.selected.type.id,
type: "location-type",
},
phonenumber1: this.selected.phonenumber1,
phonenumber2: this.selected.phonenumber2,
email: this.selected.email,
}; };
if (this.selected.addressId) { },
body = Object.assign(body, { props: ["availableLocations"],
address: { data() {
id: this.selected.addressId, return {
errors: [],
selected: {
type: null,
name: null,
addressId: null,
phonenumber1: null,
phonenumber2: null,
email: null,
}, },
}); locationTypes: [],
} modal: {
showModal: false,
makeFetch("POST", "/api/1.0/main/location.json", body) modalDialogClass: "modal-dialog-scrollable modal-xl",
.then((response) => { },
this.$store.dispatch("addAvailableLocationGroup", { addAddress: {
locationGroup: "Localisations nouvellement créées", options: {
locations: [response], button: {
}); text: {
this.$store.dispatch("updateLocation", response); create: "activity.create_address",
this.modal.showModal = false; edit: "activity.edit_address",
}) },
.catch((error) => { size: "btn-sm",
if (error.name === "ValidationException") { },
for (let v of error.violations) { title: {
this.errors.push(v); create: "activity.create_address",
} edit: "activity.edit_address",
} else { },
this.errors.push("An error occurred"); },
context: {
target: {
//name, id
},
edit: false,
addressId: null,
defaults: window.addaddress,
},
},
};
},
computed: {
...mapState(["activity"]),
selectType: {
get() {
return this.selected.type;
},
set(value) {
this.selected.type = value;
},
},
inputName: {
get() {
return this.selected.name;
},
set(value) {
this.selected.name = value;
},
},
inputEmail: {
get() {
return this.selected.email;
},
set(value) {
this.selected.email = value;
},
},
inputPhonenumber1: {
get() {
return this.selected.phonenumber1;
},
set(value) {
this.selected.phonenumber1 = value;
},
},
inputPhonenumber2: {
get() {
return this.selected.phonenumber2;
},
set(value) {
this.selected.phonenumber2 = value;
},
},
hasPhonenumber1() {
return (
this.selected.phonenumber1 !== null &&
this.selected.phonenumber1 !== ""
);
},
showAddAddress() {
let cond = false;
if (this.selected.type) {
if (this.selected.type.addressRequired !== "never") {
cond = true;
}
} }
}); return cond;
} },
showContactData() {
let cond = false;
if (this.selected.type) {
if (this.selected.type.contactData !== "never") {
cond = true;
}
}
return cond;
},
}, },
submitNewAddress(payload) { mounted() {
this.selected.addressId = payload.addressId; this.getLocationTypesList();
this.addAddress.context.addressId = payload.addressId; },
this.addAddress.context.edit = true; methods: {
localizeString,
checkForm() {
let cond = true;
this.errors = [];
if (!this.selected.type) {
this.errors.push("Type de localisation requis");
cond = false;
} else {
if (
this.selected.type.addressRequired === "required" &&
!this.selected.addressId
) {
this.errors.push("Adresse requise");
cond = false;
}
if (
this.selected.type.contactData === "required" &&
!this.selected.phonenumber1
) {
this.errors.push("Numéro de téléphone requis");
cond = false;
}
if (
this.selected.type.contactData === "required" &&
!this.selected.email
) {
this.errors.push("Adresse email requise");
cond = false;
}
}
return cond;
},
getLocationTypesList() {
getLocationTypes().then((results) => {
this.locationTypes = results.filter(
(t) => t.availableForUsers === true,
);
});
},
openModal() {
this.modal.showModal = true;
},
saveNewLocation() {
if (this.checkForm()) {
let body = {
type: "location",
name: this.selected.name,
locationType: {
id: this.selected.type.id,
type: "location-type",
},
phonenumber1: this.selected.phonenumber1,
phonenumber2: this.selected.phonenumber2,
email: this.selected.email,
};
if (this.selected.addressId) {
body = Object.assign(body, {
address: {
id: this.selected.addressId,
},
});
}
makeFetch("POST", "/api/1.0/main/location.json", body)
.then((response) => {
this.$store.dispatch("addAvailableLocationGroup", {
locationGroup: "Localisations nouvellement créées",
locations: [response],
});
this.$store.dispatch("updateLocation", response);
this.modal.showModal = false;
})
.catch((error) => {
if (error.name === "ValidationException") {
for (let v of error.violations) {
this.errors.push(v);
}
} else {
this.errors.push("An error occurred");
}
});
}
},
submitNewAddress(payload) {
this.selected.addressId = payload.addressId;
this.addAddress.context.addressId = payload.addressId;
this.addAddress.context.edit = true;
},
}, },
},
}; };
</script> </script>

View File

@@ -1,98 +1,103 @@
<template> <template>
<teleport to="#social-issues-acc"> <teleport to="#social-issues-acc">
<div class="mb-3 row"> <div class="mb-3 row">
<div class="col-4"> <div class="col-4">
<label :class="socialIssuesClassList">{{ <label :class="socialIssuesClassList">{{
trans(ACTIVITY_SOCIAL_ISSUES) trans(ACTIVITY_SOCIAL_ISSUES)
}}</label> }}</label>
</div> </div>
<div class="col-8"> <div class="col-8">
<check-social-issue <check-social-issue
v-for="issue in socialIssuesList" v-for="issue in socialIssuesList"
:key="issue.id" :key="issue.id"
:issue="issue" :issue="issue"
:selection="socialIssuesSelected" :selection="socialIssuesSelected"
@updateSelected="updateIssuesSelected" @updateSelected="updateIssuesSelected"
> >
</check-social-issue> </check-social-issue>
<div class="my-3"> <div class="my-3">
<VueMultiselect <VueMultiselect
name="otherIssues" name="otherIssues"
label="text" label="text"
track-by="id" track-by="id"
open-direction="bottom" open-direction="bottom"
:close-on-select="true" :close-on-select="true"
:preserve-search="false" :preserve-search="false"
:reset-after="true" :reset-after="true"
:hide-selected="true" :hide-selected="true"
:taggable="false" :taggable="false"
:multiple="false" :multiple="false"
:searchable="true" :searchable="true"
:allow-empty="true" :allow-empty="true"
:show-labels="false" :show-labels="false"
:loading="issueIsLoading" :loading="issueIsLoading"
:placeholder="trans(ACTIVITY_CHOOSE_OTHER_SOCIAL_ISSUE)" :placeholder="trans(ACTIVITY_CHOOSE_OTHER_SOCIAL_ISSUE)"
:options="socialIssuesOther" :options="socialIssuesOther"
@select="addIssueInList" @select="addIssueInList"
> >
</VueMultiselect> </VueMultiselect>
</div> </div>
</div> </div>
</div>
<div class="mb-3 row">
<div class="col-4">
<label :class="socialActionsClassList">{{
trans(ACTIVITY_SOCIAL_ACTIONS)
}}</label>
</div>
<div class="col-8">
<div v-if="actionIsLoading === true">
<i class="chill-green fa fa-circle-o-notch fa-spin fa-lg"></i>
</div> </div>
<span <div class="mb-3 row">
v-else-if="socialIssuesSelected.length === 0" <div class="col-4">
class="inline-choice chill-no-data-statement mt-3" <label :class="socialActionsClassList">{{
> trans(ACTIVITY_SOCIAL_ACTIONS)
{{ trans(ACTIVITY_SELECT_FIRST_A_SOCIAL_ISSUE) }} }}</label>
</span> </div>
<div class="col-8">
<div v-if="actionIsLoading === true">
<i
class="chill-green fa fa-circle-o-notch fa-spin fa-lg"
></i>
</div>
<template <span
v-else-if=" v-else-if="socialIssuesSelected.length === 0"
socialActionsList.length > 0 && class="inline-choice chill-no-data-statement mt-3"
(socialIssuesSelected.length || socialActionsSelected.length) >
" {{ trans(ACTIVITY_SELECT_FIRST_A_SOCIAL_ISSUE) }}
> </span>
<div
id="actionsList"
v-for="group in socialActionsList"
:key="group.issue"
>
<span class="badge bg-chill-l-gray text-dark">{{
group.issue
}}</span>
<check-social-action
v-for="action in group.actions"
:key="action.id"
:action="action"
:selection="socialActionsSelected"
@updateSelected="updateActionsSelected"
>
</check-social-action>
</div>
</template>
<span <template
v-else-if="actionAreLoaded && socialActionsList.length === 0" v-else-if="
class="inline-choice chill-no-data-statement mt-3" socialActionsList.length > 0 &&
> (socialIssuesSelected.length ||
{{ trans(ACTIVITY_SOCIAL_ACTION_LIST_EMPTY) }} socialActionsSelected.length)
</span> "
</div> >
</div> <div
</teleport> id="actionsList"
v-for="group in socialActionsList"
:key="group.issue"
>
<span class="badge bg-chill-l-gray text-dark">{{
group.issue
}}</span>
<check-social-action
v-for="action in group.actions"
:key="action.id"
:action="action"
:selection="socialActionsSelected"
@updateSelected="updateActionsSelected"
>
</check-social-action>
</div>
</template>
<span
v-else-if="
actionAreLoaded && socialActionsList.length === 0
"
class="inline-choice chill-no-data-statement mt-3"
>
{{ trans(ACTIVITY_SOCIAL_ACTION_LIST_EMPTY) }}
</span>
</div>
</div>
</teleport>
</template> </template>
<script> <script>
@@ -101,153 +106,154 @@ import CheckSocialIssue from "./SocialIssuesAcc/CheckSocialIssue.vue";
import CheckSocialAction from "./SocialIssuesAcc/CheckSocialAction.vue"; import CheckSocialAction from "./SocialIssuesAcc/CheckSocialAction.vue";
import { getSocialIssues, getSocialActionByIssue } from "../api.js"; import { getSocialIssues, getSocialActionByIssue } from "../api.js";
import { import {
ACTIVITY_SOCIAL_ACTION_LIST_EMPTY, ACTIVITY_SOCIAL_ACTION_LIST_EMPTY,
ACTIVITY_SELECT_FIRST_A_SOCIAL_ISSUE, ACTIVITY_SELECT_FIRST_A_SOCIAL_ISSUE,
ACTIVITY_SOCIAL_ACTIONS, ACTIVITY_SOCIAL_ACTIONS,
ACTIVITY_SOCIAL_ISSUES, ACTIVITY_SOCIAL_ISSUES,
ACTIVITY_CHOOSE_OTHER_SOCIAL_ISSUE, ACTIVITY_CHOOSE_OTHER_SOCIAL_ISSUE,
trans, trans,
} from "translator"; } from "translator";
export default { export default {
name: "SocialIssuesAcc", name: "SocialIssuesAcc",
components: { components: {
CheckSocialIssue, CheckSocialIssue,
CheckSocialAction, CheckSocialAction,
VueMultiselect, VueMultiselect,
},
setup() {
return {
trans,
ACTIVITY_SOCIAL_ACTION_LIST_EMPTY,
ACTIVITY_SELECT_FIRST_A_SOCIAL_ISSUE,
ACTIVITY_SOCIAL_ACTIONS,
ACTIVITY_SOCIAL_ISSUES,
ACTIVITY_CHOOSE_OTHER_SOCIAL_ISSUE,
};
},
data() {
return {
issueIsLoading: false,
actionIsLoading: false,
actionAreLoaded: false,
socialIssuesClassList: `col-form-label ${document.querySelector("input#chill_activitybundle_activity_socialIssues").getAttribute("required") ? "required" : ""}`,
socialActionsClassList: `col-form-label ${document.querySelector("input#chill_activitybundle_activity_socialActions").getAttribute("required") ? "required" : ""}`,
};
},
computed: {
socialIssuesList() {
return this.$store.state.activity.accompanyingPeriod.socialIssues;
}, },
socialIssuesSelected() { setup() {
return this.$store.state.activity.socialIssues; return {
trans,
ACTIVITY_SOCIAL_ACTION_LIST_EMPTY,
ACTIVITY_SELECT_FIRST_A_SOCIAL_ISSUE,
ACTIVITY_SOCIAL_ACTIONS,
ACTIVITY_SOCIAL_ISSUES,
ACTIVITY_CHOOSE_OTHER_SOCIAL_ISSUE,
};
}, },
socialIssuesOther() { data() {
return this.$store.state.socialIssuesOther; return {
issueIsLoading: false,
actionIsLoading: false,
actionAreLoaded: false,
socialIssuesClassList: `col-form-label ${document.querySelector("input#chill_activitybundle_activity_socialIssues").getAttribute("required") ? "required" : ""}`,
socialActionsClassList: `col-form-label ${document.querySelector("input#chill_activitybundle_activity_socialActions").getAttribute("required") ? "required" : ""}`,
};
}, },
socialActionsList() { computed: {
return this.$store.getters.socialActionsListSorted; socialIssuesList() {
return this.$store.state.activity.accompanyingPeriod.socialIssues;
},
socialIssuesSelected() {
return this.$store.state.activity.socialIssues;
},
socialIssuesOther() {
return this.$store.state.socialIssuesOther;
},
socialActionsList() {
return this.$store.getters.socialActionsListSorted;
},
socialActionsSelected() {
return this.$store.state.activity.socialActions;
},
}, },
socialActionsSelected() { mounted() {
return this.$store.state.activity.socialActions; /* Load other issues in multiselect */
this.issueIsLoading = true;
this.actionAreLoaded = false;
getSocialIssues().then((response) => {
/* Add issues to the store */
this.$store.commit("updateIssuesOther", response);
/* Add in list the issues already associated (if not yet listed) */
this.socialIssuesSelected.forEach((issue) => {
if (
this.socialIssuesList.filter((i) => i.id === issue.id)
.length !== 1
) {
this.$store.commit("addIssueInList", issue);
}
});
/* Remove from multiselect the issues that are not yet in the checkbox list */
this.socialIssuesList.forEach((issue) => {
this.$store.commit("removeIssueInOther", issue);
});
/* Filter issues */
this.$store.commit("filterList", "issues");
/* Add in list the actions already associated (if not yet listed) */
this.socialActionsSelected.forEach((action) => {
this.$store.commit("addActionInList", action);
});
/* Filter actions */
this.$store.commit("filterList", "actions");
this.issueIsLoading = false;
this.actionAreLoaded = true;
this.updateActionsList();
});
}, },
}, methods: {
mounted() { /* When choosing an issue in multiselect, add it in checkboxes (as selected),
/* Load other issues in multiselect */
this.issueIsLoading = true;
this.actionAreLoaded = false;
getSocialIssues().then((response) => {
/* Add issues to the store */
this.$store.commit("updateIssuesOther", response);
/* Add in list the issues already associated (if not yet listed) */
this.socialIssuesSelected.forEach((issue) => {
if (
this.socialIssuesList.filter((i) => i.id === issue.id).length !== 1
) {
this.$store.commit("addIssueInList", issue);
}
});
/* Remove from multiselect the issues that are not yet in the checkbox list */
this.socialIssuesList.forEach((issue) => {
this.$store.commit("removeIssueInOther", issue);
});
/* Filter issues */
this.$store.commit("filterList", "issues");
/* Add in list the actions already associated (if not yet listed) */
this.socialActionsSelected.forEach((action) => {
this.$store.commit("addActionInList", action);
});
/* Filter actions */
this.$store.commit("filterList", "actions");
this.issueIsLoading = false;
this.actionAreLoaded = true;
this.updateActionsList();
});
},
methods: {
/* When choosing an issue in multiselect, add it in checkboxes (as selected),
remove it from multiselect, and add socialActions concerned remove it from multiselect, and add socialActions concerned
*/ */
addIssueInList(value) { addIssueInList(value) {
//console.log('addIssueInList', value); //console.log('addIssueInList', value);
this.$store.commit("addIssueInList", value); this.$store.commit("addIssueInList", value);
this.$store.commit("removeIssueInOther", value); this.$store.commit("removeIssueInOther", value);
this.$store.dispatch("addIssueSelected", value); this.$store.dispatch("addIssueSelected", value);
this.updateActionsList(); this.updateActionsList();
}, },
/* Update value for selected issues checkboxes /* Update value for selected issues checkboxes
*/ */
updateIssuesSelected(issues) { updateIssuesSelected(issues) {
//console.log('updateIssuesSelected', issues); //console.log('updateIssuesSelected', issues);
this.$store.dispatch("updateIssuesSelected", issues); this.$store.dispatch("updateIssuesSelected", issues);
this.updateActionsList(); this.updateActionsList();
}, },
/* Update value for selected actions checkboxes /* Update value for selected actions checkboxes
*/ */
updateActionsSelected(actions) { updateActionsSelected(actions) {
//console.log('updateActionsSelected', actions); //console.log('updateActionsSelected', actions);
this.$store.dispatch("updateActionsSelected", actions); this.$store.dispatch("updateActionsSelected", actions);
}, },
/* Add socialActions concerned: after reset, loop on each issue selected /* Add socialActions concerned: after reset, loop on each issue selected
to get social actions concerned to get social actions concerned
*/ */
updateActionsList() { updateActionsList() {
this.resetActionsList(); this.resetActionsList();
this.socialIssuesSelected.forEach((item) => { this.socialIssuesSelected.forEach((item) => {
this.actionIsLoading = true; this.actionIsLoading = true;
getSocialActionByIssue(item.id).then( getSocialActionByIssue(item.id).then(
(actions) => (actions) =>
new Promise((resolve) => { new Promise((resolve) => {
actions.results.forEach((action) => { actions.results.forEach((action) => {
this.$store.commit("addActionInList", action); this.$store.commit("addActionInList", action);
}, this); }, this);
this.$store.commit("filterList", "actions"); this.$store.commit("filterList", "actions");
this.actionIsLoading = false; this.actionIsLoading = false;
this.actionAreLoaded = true; this.actionAreLoaded = true;
resolve(); resolve();
}), }),
); );
}, this); }, this);
},
/* Reset socialActions List: flush list and restore selected actions
*/
resetActionsList() {
this.$store.commit("resetActionsList");
this.actionAreLoaded = false;
this.socialActionsSelected.forEach((item) => {
this.$store.commit("addActionInList", item);
}, this);
},
}, },
/* Reset socialActions List: flush list and restore selected actions
*/
resetActionsList() {
this.$store.commit("resetActionsList");
this.actionAreLoaded = false;
this.socialActionsSelected.forEach((item) => {
this.$store.commit("addActionInList", item);
}, this);
},
},
}; };
</script> </script>
@@ -257,18 +263,18 @@ export default {
@import "ChillMainAssets/chill/scss/chill_variables"; @import "ChillMainAssets/chill/scss/chill_variables";
span.multiselect__single { span.multiselect__single {
display: none !important; display: none !important;
} }
#actionsList { #actionsList {
border-radius: 0.5rem; border-radius: 0.5rem;
padding: 1rem; padding: 1rem;
margin: 0.5rem; margin: 0.5rem;
background-color: whitesmoke; background-color: whitesmoke;
} }
span.badge { span.badge {
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
@include badge_social($social-issue-color); @include badge_social($social-issue-color);
} }
</style> </style>

View File

@@ -1,38 +1,38 @@
<template> <template>
<span class="inline-choice"> <span class="inline-choice">
<div class="form-check"> <div class="form-check">
<input <input
class="form-check-input" class="form-check-input"
type="checkbox" type="checkbox"
v-model="selected" v-model="selected"
name="action" name="action"
:id="action.id" :id="action.id"
:value="action" :value="action"
/> />
<label class="form-check-label" :for="action.id"> <label class="form-check-label" :for="action.id">
<span class="badge bg-light text-dark" :title="action.text">{{ <span class="badge bg-light text-dark" :title="action.text">{{
action.text action.text
}}</span> }}</span>
</label> </label>
</div> </div>
</span> </span>
</template> </template>
<script> <script>
export default { export default {
name: "CheckSocialAction", name: "CheckSocialAction",
props: ["action", "selection"], props: ["action", "selection"],
emits: ["updateSelected"], emits: ["updateSelected"],
computed: { computed: {
selected: { selected: {
set(value) { set(value) {
this.$emit("updateSelected", value); this.$emit("updateSelected", value);
}, },
get() { get() {
return this.selection; return this.selection;
}, },
},
}, },
},
}; };
</script> </script>
@@ -41,13 +41,13 @@ export default {
@import "ChillPersonAssets/chill/scss/mixins"; @import "ChillPersonAssets/chill/scss/mixins";
@import "ChillMainAssets/chill/scss/chill_variables"; @import "ChillMainAssets/chill/scss/chill_variables";
span.badge { span.badge {
@include badge_social($social-action-color); @include badge_social($social-action-color);
font-size: 95%; font-size: 95%;
margin-bottom: 5px; margin-bottom: 5px;
margin-right: 1em; margin-right: 1em;
max-width: 100%; /* Adjust as needed */ max-width: 100%; /* Adjust as needed */
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
} }
</style> </style>

View File

@@ -1,36 +1,38 @@
<template> <template>
<span class="inline-choice"> <span class="inline-choice">
<div class="form-check"> <div class="form-check">
<input <input
class="form-check-input" class="form-check-input"
type="checkbox" type="checkbox"
v-model="selected" v-model="selected"
name="issue" name="issue"
:id="issue.id" :id="issue.id"
:value="issue" :value="issue"
/> />
<label class="form-check-label" :for="issue.id"> <label class="form-check-label" :for="issue.id">
<span class="badge bg-chill-l-gray text-dark">{{ issue.text }}</span> <span class="badge bg-chill-l-gray text-dark">{{
</label> issue.text
</div> }}</span>
</span> </label>
</div>
</span>
</template> </template>
<script> <script>
export default { export default {
name: "CheckSocialIssue", name: "CheckSocialIssue",
props: ["issue", "selection"], props: ["issue", "selection"],
emits: ["updateSelected"], emits: ["updateSelected"],
computed: { computed: {
selected: { selected: {
set(value) { set(value) {
this.$emit("updateSelected", value); this.$emit("updateSelected", value);
}, },
get() { get() {
return this.selection; return this.selection;
}, },
},
}, },
},
}; };
</script> </script>
@@ -39,9 +41,9 @@ export default {
@import "ChillPersonAssets/chill/scss/mixins"; @import "ChillPersonAssets/chill/scss/mixins";
@import "ChillMainAssets/chill/scss/chill_variables"; @import "ChillMainAssets/chill/scss/chill_variables";
span.badge { span.badge {
@include badge_social($social-issue-color); @include badge_social($social-issue-color);
font-size: 95%; font-size: 95%;
margin-bottom: 5px; margin-bottom: 5px;
margin-right: 1em; margin-right: 1em;
} }
</style> </style>

View File

@@ -49,17 +49,17 @@ class ActivityStatsVoter extends AbstractChillVoter implements ProvideRoleHierar
return $this->getAttributes(); return $this->getAttributes();
} }
protected function supports($attribute, $subject) protected function supports(string $attribute, mixed $subject): bool
{ {
return $this->helper->supports($attribute, $subject); return $this->helper->supports($attribute, $subject);
} }
protected function voteOnAttribute($attribute, $subject, TokenInterface $token) protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
{ {
return $this->helper->voteOnAttribute($attribute, $subject, $token); return $this->helper->voteOnAttribute($attribute, $subject, $token);
} }
private function getAttributes() private function getAttributes(): array
{ {
return [self::STATS, self::LISTS]; return [self::STATS, self::LISTS];
} }

View File

@@ -17,7 +17,7 @@ use Chill\DocStoreBundle\Repository\AssociatedEntityToStoredObjectInterface;
use Chill\DocStoreBundle\Security\Authorization\StoredObjectRoleEnum; use Chill\DocStoreBundle\Security\Authorization\StoredObjectRoleEnum;
use Chill\DocStoreBundle\Security\Authorization\StoredObjectVoter\AbstractStoredObjectVoter; use Chill\DocStoreBundle\Security\Authorization\StoredObjectVoter\AbstractStoredObjectVoter;
use Chill\MainBundle\Workflow\Helper\WorkflowRelatedEntityPermissionHelper; use Chill\MainBundle\Workflow\Helper\WorkflowRelatedEntityPermissionHelper;
use Symfony\Component\Security\Core\Security; use Symfony\Bundle\SecurityBundle\Security;
class ActivityStoredObjectVoter extends AbstractStoredObjectVoter class ActivityStoredObjectVoter extends AbstractStoredObjectVoter
{ {

View File

@@ -22,7 +22,7 @@ use Chill\PersonBundle\Entity\Person;
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 Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Security; use Symfony\Bundle\SecurityBundle\Security;
class ActivityVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterface class ActivityVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterface
{ {

View File

@@ -26,7 +26,7 @@ use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
use Doctrine\DBAL\Types\Types; use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Security\Core\Security; use Symfony\Bundle\SecurityBundle\Security;
final readonly class AccompanyingPeriodActivityGenericDocProvider implements GenericDocForAccompanyingPeriodProviderInterface, GenericDocForPersonProviderInterface final readonly class AccompanyingPeriodActivityGenericDocProvider implements GenericDocForAccompanyingPeriodProviderInterface, GenericDocForPersonProviderInterface
{ {

View File

@@ -16,7 +16,7 @@ use Chill\ActivityBundle\Security\Authorization\ActivityVoter;
use Chill\DocStoreBundle\GenericDoc\FetchQueryInterface; use Chill\DocStoreBundle\GenericDoc\FetchQueryInterface;
use Chill\DocStoreBundle\GenericDoc\GenericDocForPersonProviderInterface; use Chill\DocStoreBundle\GenericDoc\GenericDocForPersonProviderInterface;
use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Entity\Person;
use Symfony\Component\Security\Core\Security; use Symfony\Bundle\SecurityBundle\Security;
final readonly class PersonActivityGenericDocProvider implements GenericDocForPersonProviderInterface final readonly class PersonActivityGenericDocProvider implements GenericDocForPersonProviderInterface
{ {

View File

@@ -25,7 +25,7 @@ trait PrepareActivityTrait
* *
* @return Activity * @return Activity
*/ */
public function prepareActivity(Scope $scope, Person $person) public function prepareActivity(Scope $scope, Person $person): \Chill\ActivityBundle\Entity\Activity
{ {
return (new Activity()) return (new Activity())
->setScope($scope) ->setScope($scope)

View File

@@ -25,7 +25,7 @@ final class ActivityControllerTest extends WebTestCase
/** /**
* @dataProvider getSecuredPagesUnauthenticated * @dataProvider getSecuredPagesUnauthenticated
*/ */
public function testAccessIsDeniedForUnauthenticated(mixed $url) public function testAccessIsDeniedForUnauthenticated(mixed $url): void
{ {
$client = $this->createClient(); $client = $this->createClient();
@@ -61,7 +61,7 @@ final class ActivityControllerTest extends WebTestCase
* @param type $client * @param type $client
* @param type $url * @param type $url
*/ */
public function testAccessIsDeniedForUnauthorized($client, $url) public function testAccessIsDeniedForUnauthorized($client, $url): void
{ {
$client->request('GET', $url); $client->request('GET', $url);
@@ -101,7 +101,7 @@ final class ActivityControllerTest extends WebTestCase
]; ];
} }
public function testCompleteScenario() public function testCompleteScenario(): void
{ {
// Create a new client to browse the application // Create a new client to browse the application
$client = $this->getAuthenticatedClient(); $client = $this->getAuthenticatedClient();
@@ -199,7 +199,7 @@ final class ActivityControllerTest extends WebTestCase
* *
* @return \Chill\MainBundle\Entity\User a fake user within a group without activity * @return \Chill\MainBundle\Entity\User a fake user within a group without activity
*/ */
private function createFakeUser() private function createFakeUser(): \Chill\MainBundle\Entity\User
{ {
$container = self::$kernel->getContainer(); $container = self::$kernel->getContainer();
$em = $container->get('doctrine.orm.entity_manager'); $em = $container->get('doctrine.orm.entity_manager');
@@ -259,7 +259,7 @@ final class ActivityControllerTest extends WebTestCase
/** /**
* @return \Symfony\Component\BrowserKit\AbstractBrowser * @return \Symfony\Component\BrowserKit\AbstractBrowser
*/ */
private function getAuthenticatedClient(mixed $username = 'center a_social') private function getAuthenticatedClient(mixed $username = 'center a_social'): \Symfony\Bundle\FrameworkBundle\KernelBrowser
{ {
return self::createClient([], [ return self::createClient([], [
'PHP_AUTH_USER' => $username, 'PHP_AUTH_USER' => $username,

View File

@@ -16,7 +16,6 @@ use Chill\PersonBundle\AccompanyingPeriod\SocialIssueConsistency\AccompanyingPer
use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\SocialWork\SocialAction; use Chill\PersonBundle\Entity\SocialWork\SocialAction;
use Chill\PersonBundle\Entity\SocialWork\SocialIssue; use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
use Doctrine\ORM\Event\LifecycleEventArgs;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use Prophecy\PhpUnit\ProphecyTrait; use Prophecy\PhpUnit\ProphecyTrait;
@@ -70,33 +69,32 @@ final class ActivityTest extends TestCase
public function testHierarchySocialIssues(): void public function testHierarchySocialIssues(): void
{ {
$listener = new AccompanyingPeriodSocialIssueConsistencyEntityListener(); $listener = new AccompanyingPeriodSocialIssueConsistencyEntityListener();
$event = $this->prophesize(LifecycleEventArgs::class)->reveal();
$parent = new SocialIssue(); $parent = new SocialIssue();
$child = new SocialIssue(); $child = new SocialIssue();
$parent->addChild($child); $child->setParent($parent);
$grandChild = new SocialIssue(); $grandChild = new SocialIssue();
$child->addChild($grandChild); $grandChild->setParent($child);
$activity = new Activity(); $activity = new Activity();
$activity->setAccompanyingPeriod(new AccompanyingPeriod()); $activity->setAccompanyingPeriod(new AccompanyingPeriod());
$activity->addSocialIssue($parent); $activity->addSocialIssue($parent);
$listener->preUpdate($activity, $event); $listener->preUpdate($activity);
$this->assertCount(1, $activity->getSocialIssues()); $this->assertCount(1, $activity->getSocialIssues());
$this->assertContains($parent, $activity->getSocialIssues()); $this->assertContains($parent, $activity->getSocialIssues());
$activity->addSocialIssue($grandChild); $activity->addSocialIssue($grandChild);
$listener->preUpdate($activity, $event); $listener->preUpdate($activity);
$this->assertCount(1, $activity->getSocialIssues()); $this->assertCount(1, $activity->getSocialIssues());
$this->assertContains($grandChild, $activity->getSocialIssues()); $this->assertContains($grandChild, $activity->getSocialIssues());
$this->assertNotContains($parent, $activity->getSocialIssues()); $this->assertNotContains($parent, $activity->getSocialIssues());
$activity->addSocialIssue($child); $activity->addSocialIssue($child);
$listener->preUpdate($activity, $event); $listener->preUpdate($activity);
$this->assertCount(1, $activity->getSocialIssues()); $this->assertCount(1, $activity->getSocialIssues());
$this->assertContains($grandChild, $activity->getSocialIssues()); $this->assertContains($grandChild, $activity->getSocialIssues());
@@ -104,7 +102,7 @@ final class ActivityTest extends TestCase
$this->assertNotContains($child, $activity->getSocialIssues()); $this->assertNotContains($child, $activity->getSocialIssues());
$activity->addSocialIssue($another = new SocialIssue()); $activity->addSocialIssue($another = new SocialIssue());
$listener->preUpdate($activity, $event); $listener->preUpdate($activity);
$this->assertCount(2, $activity->getSocialIssues()); $this->assertCount(2, $activity->getSocialIssues());
$this->assertContains($grandChild, $activity->getSocialIssues()); $this->assertContains($grandChild, $activity->getSocialIssues());

View File

@@ -41,7 +41,7 @@ class ByActivityTypeAggregatorTest extends AbstractAggregatorTest
$this->translatableStringHelper = self::getContainer()->get(TranslatableStringHelperInterface::class); $this->translatableStringHelper = self::getContainer()->get(TranslatableStringHelperInterface::class);
} }
public function getAggregator() public function getAggregator(): \Chill\ActivityBundle\Export\Aggregator\ACPAggregators\ByActivityTypeAggregator
{ {
return new ByActivityTypeAggregator( return new ByActivityTypeAggregator(
$this->rollingDateConverter, $this->rollingDateConverter,

View File

@@ -32,7 +32,7 @@ final class BySocialActionAggregatorTest extends AbstractAggregatorTest
$this->aggregator = self::getContainer()->get('chill.activity.export.bysocialaction_aggregator'); $this->aggregator = self::getContainer()->get('chill.activity.export.bysocialaction_aggregator');
} }
public function getAggregator() public function getAggregator(): \Chill\ActivityBundle\Export\Aggregator\ACPAggregators\BySocialActionAggregator
{ {
return $this->aggregator; return $this->aggregator;
} }

View File

@@ -32,7 +32,7 @@ final class BySocialIssueAggregatorTest extends AbstractAggregatorTest
$this->aggregator = self::getContainer()->get('chill.activity.export.bysocialissue_aggregator'); $this->aggregator = self::getContainer()->get('chill.activity.export.bysocialissue_aggregator');
} }
public function getAggregator() public function getAggregator(): \Chill\ActivityBundle\Export\Aggregator\ACPAggregators\BySocialIssueAggregator
{ {
return $this->aggregator; return $this->aggregator;
} }

View File

@@ -35,7 +35,7 @@ class ActivityPresenceAggregatorTest extends AbstractAggregatorTest
$this->activityPresenceRepository = self::getContainer()->get(ActivityPresenceRepositoryInterface::class); $this->activityPresenceRepository = self::getContainer()->get(ActivityPresenceRepositoryInterface::class);
} }
public function getAggregator() public function getAggregator(): \Chill\ActivityBundle\Export\Aggregator\ActivityPresenceAggregator
{ {
return new ActivityPresenceAggregator($this->activityPresenceRepository, $this->translatableStringHelper); return new ActivityPresenceAggregator($this->activityPresenceRepository, $this->translatableStringHelper);
} }

View File

@@ -44,7 +44,7 @@ final class ActivityReasonAggregatorTest extends AbstractAggregatorTest
->push($request->reveal());*/ ->push($request->reveal());*/
} }
public function getAggregator() public function getAggregator(): \Chill\ActivityBundle\Export\Aggregator\ActivityReasonAggregator
{ {
return $this->aggregator; return $this->aggregator;
} }

View File

@@ -45,7 +45,7 @@ final class ActivityTypeAggregatorTest extends AbstractAggregatorTest
->push($request->reveal()); ->push($request->reveal());
} }
public function getAggregator() public function getAggregator(): \Chill\ActivityBundle\Export\Aggregator\ActivityTypeAggregator
{ {
return $this->aggregator; return $this->aggregator;
} }

Some files were not shown because too many files have changed in this diff Show More