From 1bd6df7ce2f6c7a2e46f79afbcc15fa641492e99 Mon Sep 17 00:00:00 2001 From: nobohan Date: Tue, 23 Nov 2021 09:13:40 +0100 Subject: [PATCH 01/24] correct deprecated activity method --- .../ChillActivityBundle/Controller/ActivityController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php index f4248b5e8..17eae166e 100644 --- a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php +++ b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php @@ -327,8 +327,8 @@ final class ActivityController extends AbstractController $entity->setAccompanyingPeriod($accompanyingPeriod); } - $entity->setType($activityType); - $entity->setDate(new DateTime('now')); + $entity->setActivityType($activityType); + $entity->setDate(new \DateTime('now')); if ($request->query->has('activityData')) { $activityData = $request->query->get('activityData'); From e3040f4bfb1f4dae6c23e316c789f586cb99d7f0 Mon Sep 17 00:00:00 2001 From: nobohan Date: Tue, 23 Nov 2021 09:26:38 +0100 Subject: [PATCH 02/24] correct deprecated activity method --- .../Controller/ActivityController.php | 80 +++++++++++++++++-- 1 file changed, 74 insertions(+), 6 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php index 17eae166e..989ce518e 100644 --- a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php +++ b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php @@ -384,8 +384,8 @@ final class ActivityController extends AbstractController $form = $this->createForm(ActivityType::class, $entity, [ 'center' => $entity->getCenter(), - 'role' => new Role('CHILL_ACTIVITY_CREATE'), - 'activityType' => $entity->getType(), + 'role' => new Role('CHILL_ACTIVITY_CREATE'), + 'activityType' => $entity->getActivityType(), 'accompanyingPeriod' => $accompanyingPeriod, ])->handleRequest($request); @@ -482,10 +482,26 @@ final class ActivityController extends AbstractController throw $this->createNotFoundException('Unable to find Activity entity.'); } - if (null !== $accompanyingPeriod) { - // @TODO: Properties created dynamically. - $entity->personsAssociated = $entity->getPersonsAssociated(); - $entity->personsNotAssociated = $entity->getPersonsNotAssociated(); + // TODO + // $this->denyAccessUnlessGranted('CHILL_ACTIVITY_UPDATE', $entity); + + $form = $this->createForm(ActivityType::class, $entity, [ + 'center' => $entity->getCenter(), + 'role' => new Role('CHILL_ACTIVITY_UPDATE'), + 'activityType' => $entity->getActivityType(), + 'accompanyingPeriod' => $accompanyingPeriod, + ])->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $this->entityManager->persist($entity); + $this->entityManager->flush(); + + $this->addFlash('success', $this->get('translator')->trans('Success : activity updated!')); + + $params = $this->buildParamsToUrl($person, $accompanyingPeriod); + $params['id'] = $entity->getId(); + + return $this->redirectToRoute('chill_activity_activity_show', $params); } // TODO revoir le Voter de Activity pour tenir compte qu'une activité peut appartenir a une période @@ -517,7 +533,59 @@ final class ActivityController extends AbstractController private function buildParamsToUrl(?Person $person, ?AccompanyingPeriod $accompanyingPeriod): array { +<<<<<<< HEAD $params = []; +======= + $view = null; + + [$person, $accompanyingPeriod] = $this->getEntity($request); + + if ($accompanyingPeriod instanceof AccompanyingPeriod) { + $view = 'ChillActivityBundle:Activity:confirm_deleteAccompanyingCourse.html.twig'; + } elseif ($person instanceof Person) { + $view = 'ChillActivityBundle:Activity:confirm_deletePerson.html.twig'; + } + + $activity = $this->activityRepository->find($id); + + if (!$activity) { + throw $this->createNotFoundException('Unable to find Activity entity.'); + } + + // TODO + // $this->denyAccessUnlessGranted('CHILL_ACTIVITY_DELETE', $activity); + + $form = $this->createDeleteForm($activity->getId(), $person, $accompanyingPeriod); + + if ($request->getMethod() === Request::METHOD_DELETE) { + $form->handleRequest($request); + + if ($form->isValid()) { + $this->logger->notice("An activity has been removed", [ + 'by_user' => $this->getUser()->getUsername(), + 'activity_id' => $activity->getId(), + 'person_id' => $activity->getPerson() ? $activity->getPerson()->getId() : null, + 'comment' => $activity->getComment()->getComment(), + 'scope_id' => $activity->getScope() ? $activity->getScope()->getId() : null, + 'reasons_ids' => $activity->getReasons() + ->map( + static fn (ActivityReason $ar): int => $ar->getId() + ) + ->toArray(), + 'type_id' => $activity->getActivityType()->getId(), + 'duration' => $activity->getDurationTime() ? $activity->getDurationTime()->format('U') : null, + 'date' => $activity->getDate()->format('Y-m-d'), + 'attendee' => $activity->getAttendee() + ]); + + $this->entityManager->remove($activity); + $this->entityManager->flush(); + + $this->addFlash('success', $this->get('translator') + ->trans("The activity has been successfully removed.")); + + $params = $this->buildParamsToUrl($person, $accompanyingPeriod); +>>>>>>> correct deprecated activity method if (null !== $person) { $params['person_id'] = $person->getId(); From 32af0769865b144fc55107607f94110fdfa73686 Mon Sep 17 00:00:00 2001 From: nobohan Date: Tue, 23 Nov 2021 10:41:27 +0100 Subject: [PATCH 03/24] main: locationType: add defaultFor property --- .../ChillMainBundle/Entity/LocationType.php | 22 +++++++++++++ .../migrations/Version20211123093355.php | 31 +++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 src/Bundle/ChillMainBundle/migrations/Version20211123093355.php diff --git a/src/Bundle/ChillMainBundle/Entity/LocationType.php b/src/Bundle/ChillMainBundle/Entity/LocationType.php index 8b171eb0f..a49bb6c1b 100644 --- a/src/Bundle/ChillMainBundle/Entity/LocationType.php +++ b/src/Bundle/ChillMainBundle/Entity/LocationType.php @@ -29,6 +29,9 @@ class LocationType public const STATUS_REQUIRED = 'required'; + const DEFAULT_FOR_PERSON = 'person'; + const DEFAULT_FOR_3PARTY = 'thirdparty'; + /** * @ORM\Column(type="boolean", nullable=true) * @Serializer\Groups({"read"}) @@ -67,6 +70,13 @@ class LocationType */ private array $title = []; + /** + * @ORM\Column(type="string", nullable=true, length=32, unique=true) + * @Serializer\Groups({"read"}) + */ + private ?string $defaultFor = null; + + public function getActive(): ?bool { return $this->active; @@ -131,4 +141,16 @@ class LocationType return $this; } + + public function getDefaultFor(): ?string + { + return $this->defaultFor; + } + + public function setDefaultFor(string $defaultFor): self + { + $this->defaultFor = $defaultFor; + + return $this; + } } diff --git a/src/Bundle/ChillMainBundle/migrations/Version20211123093355.php b/src/Bundle/ChillMainBundle/migrations/Version20211123093355.php new file mode 100644 index 000000000..1736cf857 --- /dev/null +++ b/src/Bundle/ChillMainBundle/migrations/Version20211123093355.php @@ -0,0 +1,31 @@ +addSql('ALTER TABLE chill_main_location_type ADD defaultFor VARCHAR(32) DEFAULT NULL'); + $this->addSql('CREATE UNIQUE INDEX UNIQ_A459B5CADD3E4105 ON chill_main_location_type (defaultFor)'); + } + + public function down(Schema $schema): void + { + $this->addSql('DROP INDEX UNIQ_A459B5CADD3E4105'); + $this->addSql('ALTER TABLE chill_main_location_type DROP defaultFor'); + } +} \ No newline at end of file From 7eeb2f2a7dc85a997c42749b8073af260ab454e1 Mon Sep 17 00:00:00 2001 From: nobohan Date: Tue, 23 Nov 2021 10:57:43 +0100 Subject: [PATCH 04/24] main: LocationType: add new property defaultFor in the admin --- src/Bundle/ChillMainBundle/Entity/LocationType.php | 4 ++-- .../ChillMainBundle/Form/LocationTypeType.php | 13 ++++++++++++- .../Resources/views/LocationType/index.html.twig | 2 ++ .../ChillMainBundle/translations/messages.fr.yml | 4 ++++ 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Entity/LocationType.php b/src/Bundle/ChillMainBundle/Entity/LocationType.php index a49bb6c1b..d3dff58b7 100644 --- a/src/Bundle/ChillMainBundle/Entity/LocationType.php +++ b/src/Bundle/ChillMainBundle/Entity/LocationType.php @@ -29,8 +29,8 @@ class LocationType public const STATUS_REQUIRED = 'required'; - const DEFAULT_FOR_PERSON = 'person'; - const DEFAULT_FOR_3PARTY = 'thirdparty'; + public const DEFAULT_FOR_PERSON = 'person'; + public const DEFAULT_FOR_3PARTY = 'thirdparty'; /** * @ORM\Column(type="boolean", nullable=true) diff --git a/src/Bundle/ChillMainBundle/Form/LocationTypeType.php b/src/Bundle/ChillMainBundle/Form/LocationTypeType.php index 1e4776f8f..93bc5ba0f 100644 --- a/src/Bundle/ChillMainBundle/Form/LocationTypeType.php +++ b/src/Bundle/ChillMainBundle/Form/LocationTypeType.php @@ -71,6 +71,17 @@ final class LocationTypeType extends AbstractType ], 'expanded' => true, ] - ); + ) + ->add( + 'defaultFor', + ChoiceType::class, + [ + 'choices' => [ + 'none' => null, + 'person' => LocationType::DEFAULT_FOR_PERSON, + 'thirdparty' => LocationType::DEFAULT_FOR_3PARTY, + ], + 'expanded' => true + ]); } } diff --git a/src/Bundle/ChillMainBundle/Resources/views/LocationType/index.html.twig b/src/Bundle/ChillMainBundle/Resources/views/LocationType/index.html.twig index ec617c6c0..5402d5e89 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/LocationType/index.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/LocationType/index.html.twig @@ -11,6 +11,7 @@ {{ 'Address required'|trans }} {{ 'Contact data'|trans }} {{ 'Active'|trans }} + {{ 'Default for'|trans }} @@ -33,6 +34,7 @@ {%- endif -%} + {{ entity.defaultFor|trans }}
  • diff --git a/src/Bundle/ChillMainBundle/translations/messages.fr.yml b/src/Bundle/ChillMainBundle/translations/messages.fr.yml index 210227fbe..f8c474042 100644 --- a/src/Bundle/ChillMainBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillMainBundle/translations/messages.fr.yml @@ -212,6 +212,10 @@ Location type: Type de localisation Phonenumber1: Numéro de téléphone Phonenumber2: Autre numéro de téléphone Configure location and location type: Configuration des localisations +Default for: Type de localisation par défaut pour +none: aucun +person: usager +thirdparty: tiers # circles / scopes Choose the circle: Choisir le cercle From 92e59e211d06c77e7f9b6782765e21418d13ef96 Mon Sep 17 00:00:00 2001 From: nobohan Date: Tue, 23 Nov 2021 14:19:19 +0100 Subject: [PATCH 05/24] activity: suggest location based on accompanying period (WIP) --- .../vuejs/Activity/components/Location.vue | 76 ++++++++++++------- 1 file changed, 48 insertions(+), 28 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue index 5fa3360b7..147184098 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue @@ -2,10 +2,9 @@
    - + v-model="location" + > @@ -27,49 +27,69 @@ From b808e970aba82915bd04894bbc44202b76459145 Mon Sep 17 00:00:00 2001 From: nobohan Date: Tue, 23 Nov 2021 15:03:26 +0100 Subject: [PATCH 06/24] activity: correct activityController after rebase --- .../Controller/ActivityController.php | 84 ++----------------- 1 file changed, 8 insertions(+), 76 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php index 989ce518e..0c43c4d91 100644 --- a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php +++ b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php @@ -137,7 +137,7 @@ final class ActivityController extends AbstractController static fn (ActivityReason $ar): int => $ar->getId() ) ->toArray(), - 'type_id' => $activity->getType()->getId(), + 'type_id' => $activity->getActivityType()->getId(), 'duration' => $activity->getDurationTime() ? $activity->getDurationTime()->format('U') : null, 'date' => $activity->getDate()->format('Y-m-d'), 'attendee' => $activity->getAttendee(), @@ -194,7 +194,7 @@ final class ActivityController extends AbstractController $form = $this->createForm(ActivityType::class, $entity, [ 'center' => $entity->getCenter(), 'role' => new Role('CHILL_ACTIVITY_UPDATE'), - 'activityType' => $entity->getType(), + 'activityType' => $entity->getActivityType(), 'accompanyingPeriod' => $accompanyingPeriod, ])->handleRequest($request); @@ -328,7 +328,7 @@ final class ActivityController extends AbstractController } $entity->setActivityType($activityType); - $entity->setDate(new \DateTime('now')); + $entity->setDate(new DateTime('now')); if ($request->query->has('activityData')) { $activityData = $request->query->get('activityData'); @@ -384,7 +384,7 @@ final class ActivityController extends AbstractController $form = $this->createForm(ActivityType::class, $entity, [ 'center' => $entity->getCenter(), - 'role' => new Role('CHILL_ACTIVITY_CREATE'), + 'role' => new Role('CHILL_ACTIVITY_CREATE'), 'activityType' => $entity->getActivityType(), 'accompanyingPeriod' => $accompanyingPeriod, ])->handleRequest($request); @@ -482,26 +482,10 @@ final class ActivityController extends AbstractController throw $this->createNotFoundException('Unable to find Activity entity.'); } - // TODO - // $this->denyAccessUnlessGranted('CHILL_ACTIVITY_UPDATE', $entity); - - $form = $this->createForm(ActivityType::class, $entity, [ - 'center' => $entity->getCenter(), - 'role' => new Role('CHILL_ACTIVITY_UPDATE'), - 'activityType' => $entity->getActivityType(), - 'accompanyingPeriod' => $accompanyingPeriod, - ])->handleRequest($request); - - if ($form->isSubmitted() && $form->isValid()) { - $this->entityManager->persist($entity); - $this->entityManager->flush(); - - $this->addFlash('success', $this->get('translator')->trans('Success : activity updated!')); - - $params = $this->buildParamsToUrl($person, $accompanyingPeriod); - $params['id'] = $entity->getId(); - - return $this->redirectToRoute('chill_activity_activity_show', $params); + if (null !== $accompanyingPeriod) { + // @TODO: Properties created dynamically. + $entity->personsAssociated = $entity->getPersonsAssociated(); + $entity->personsNotAssociated = $entity->getPersonsNotAssociated(); } // TODO revoir le Voter de Activity pour tenir compte qu'une activité peut appartenir a une période @@ -533,59 +517,7 @@ final class ActivityController extends AbstractController private function buildParamsToUrl(?Person $person, ?AccompanyingPeriod $accompanyingPeriod): array { -<<<<<<< HEAD $params = []; -======= - $view = null; - - [$person, $accompanyingPeriod] = $this->getEntity($request); - - if ($accompanyingPeriod instanceof AccompanyingPeriod) { - $view = 'ChillActivityBundle:Activity:confirm_deleteAccompanyingCourse.html.twig'; - } elseif ($person instanceof Person) { - $view = 'ChillActivityBundle:Activity:confirm_deletePerson.html.twig'; - } - - $activity = $this->activityRepository->find($id); - - if (!$activity) { - throw $this->createNotFoundException('Unable to find Activity entity.'); - } - - // TODO - // $this->denyAccessUnlessGranted('CHILL_ACTIVITY_DELETE', $activity); - - $form = $this->createDeleteForm($activity->getId(), $person, $accompanyingPeriod); - - if ($request->getMethod() === Request::METHOD_DELETE) { - $form->handleRequest($request); - - if ($form->isValid()) { - $this->logger->notice("An activity has been removed", [ - 'by_user' => $this->getUser()->getUsername(), - 'activity_id' => $activity->getId(), - 'person_id' => $activity->getPerson() ? $activity->getPerson()->getId() : null, - 'comment' => $activity->getComment()->getComment(), - 'scope_id' => $activity->getScope() ? $activity->getScope()->getId() : null, - 'reasons_ids' => $activity->getReasons() - ->map( - static fn (ActivityReason $ar): int => $ar->getId() - ) - ->toArray(), - 'type_id' => $activity->getActivityType()->getId(), - 'duration' => $activity->getDurationTime() ? $activity->getDurationTime()->format('U') : null, - 'date' => $activity->getDate()->format('Y-m-d'), - 'attendee' => $activity->getAttendee() - ]); - - $this->entityManager->remove($activity); - $this->entityManager->flush(); - - $this->addFlash('success', $this->get('translator') - ->trans("The activity has been successfully removed.")); - - $params = $this->buildParamsToUrl($person, $accompanyingPeriod); ->>>>>>> correct deprecated activity method if (null !== $person) { $params['person_id'] = $person->getId(); From 1519fcd4dd0c73d692bb68e9f305d1916e1615e4 Mon Sep 17 00:00:00 2001 From: nobohan Date: Tue, 23 Nov 2021 16:10:34 +0100 Subject: [PATCH 07/24] activity: add location of the accompanying course --- .../Resources/public/vuejs/Activity/api.js | 12 +++++ .../vuejs/Activity/components/Location.vue | 45 +++++++++++-------- .../components/Location/NewLocation.vue | 1 - 3 files changed, 38 insertions(+), 20 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/api.js b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/api.js index 9dab14ef1..96a8d0107 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/api.js +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/api.js @@ -36,6 +36,17 @@ const getLocationTypes = () => { }); }; + +/* +* Load Location Types by defaultFor +* @param {string} entity - can be "person" or "thirdparty" + */ +const getLocationTypesByDefaultFor = (entity) => { + return getLocationTypes().then(response => + response.results.filter(t => t.defaultFor === entity)[0] + ); +}; + /* * Post a Location */ @@ -59,5 +70,6 @@ export { getSocialActionByIssue, getLocations, getLocationTypes, + getLocationTypesByDefaultFor, postLocation }; diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue index 147184098..b64d7ccb2 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue @@ -30,7 +30,7 @@ import { mapState, mapGetters } from "vuex"; import VueMultiselect from "vue-multiselect"; import NewLocation from "./Location/NewLocation.vue"; -import { getLocations } from "../api.js"; +import { getLocations, getLocationTypesByDefaultFor } from "../api.js"; export default { name: "Location", @@ -56,22 +56,34 @@ export default { }, }, mounted() { + this.getAccompanyingPeriodLocation(); getLocations().then( (response) => new Promise((resolve) => { - console.log("getLocations", response); - this.locations = [ - ...this.getAccompanyingPeriodLocation(), - ...response.results, - ...this.createConcernedPersonsLocation(), - ]; - if (window.default_location_id) { - let location = this.locations.filter( - (l) => l.id === window.default_location_id - ); - this.$store.dispatch("updateLocation", location); - } - resolve(); + getLocationTypesByDefaultFor('person').then( + t => { + const accPeriodLocation = this.activity.accompanyingPeriod.location; + const personLocation = { + type: 'location', + name: 'XXXXXX Domicile de l\'usager du parcours', + address: { id: accPeriodLocation.address_id }, //TODO is the id sufficient? + locationType: t + } + this.locations = [ + personLocation, + ...response.results, + ]; + console.log(this.locations); + if (window.default_location_id) { + let location = this.locations.filter( + (l) => l.id === window.default_location_id + ); + this.$store.dispatch("updateLocation", location); + } + resolve(); + } + ) + }) ); }, @@ -81,13 +93,8 @@ export default { value.name ? value.name : "" }`; }, - getAccompanyingPeriodLocation() { - let location = this.activity.accompanyingPeriod.location; - return location; - }, createConcernedPersonsLocation() { let entities = this.suggestedEntities; - console.log(entities); return []; // TODO WIP }, }, diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location/NewLocation.vue b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location/NewLocation.vue index 2920e15b2..18190564d 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location/NewLocation.vue +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location/NewLocation.vue @@ -215,7 +215,6 @@ export default { }, getLocationTypesList() { getLocationTypes().then(response => new Promise(resolve => { - console.log('getLocationTypes', response); this.locationTypes = response.results.filter(t => t.availableForUsers === true); resolve(); })) From c1a2112d4828e7b93d215e721201d654ce900acd Mon Sep 17 00:00:00 2001 From: nobohan Date: Tue, 23 Nov 2021 17:24:54 +0100 Subject: [PATCH 08/24] activity: add location from concerned person and 3rd parties in the location selector --- .../Resources/public/vuejs/Activity/api.js | 6 +- .../vuejs/Activity/components/Location.vue | 94 +++++++++++++------ 2 files changed, 70 insertions(+), 30 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/api.js b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/api.js index 96a8d0107..70ba4c04e 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/api.js +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/api.js @@ -38,10 +38,10 @@ const getLocationTypes = () => { /* -* Load Location Types by defaultFor +* Load Location Type by defaultFor * @param {string} entity - can be "person" or "thirdparty" */ -const getLocationTypesByDefaultFor = (entity) => { +const getLocationTypeByDefaultFor = (entity) => { return getLocationTypes().then(response => response.results.filter(t => t.defaultFor === entity)[0] ); @@ -70,6 +70,6 @@ export { getSocialActionByIssue, getLocations, getLocationTypes, - getLocationTypesByDefaultFor, + getLocationTypeByDefaultFor, postLocation }; diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue index b64d7ccb2..6cad3dd8d 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue @@ -30,7 +30,7 @@ import { mapState, mapGetters } from "vuex"; import VueMultiselect from "vue-multiselect"; import NewLocation from "./Location/NewLocation.vue"; -import { getLocations, getLocationTypesByDefaultFor } from "../api.js"; +import { getLocations, getLocationTypeByDefaultFor } from "../api.js"; export default { name: "Location", @@ -56,34 +56,36 @@ export default { }, }, mounted() { - this.getAccompanyingPeriodLocation(); getLocations().then( (response) => new Promise((resolve) => { - getLocationTypesByDefaultFor('person').then( - t => { - const accPeriodLocation = this.activity.accompanyingPeriod.location; - const personLocation = { - type: 'location', - name: 'XXXXXX Domicile de l\'usager du parcours', - address: { id: accPeriodLocation.address_id }, //TODO is the id sufficient? - locationType: t - } - this.locations = [ - personLocation, - ...response.results, - ]; - console.log(this.locations); - if (window.default_location_id) { - let location = this.locations.filter( - (l) => l.id === window.default_location_id - ); - this.$store.dispatch("updateLocation", location); - } - resolve(); + getLocationTypeByDefaultFor('person').then( + personLocationType => { + const personLocation = this.makePersonLocation(personLocationType); + const concernedPersonsLocation = + this.makeConcernedPersonsLocation(personLocationType); + getLocationTypeByDefaultFor('thirdparty').then( + thirdpartyLocationType => { + const concernedThirdPartiesLocation = + this.makeConcernedThirdPartiesLocation(thirdpartyLocationType); + this.locations = [ + personLocation, + ...concernedPersonsLocation, + ...concernedThirdPartiesLocation, + ...response.results, + ]; + console.log(this.locations); + if (window.default_location_id) { + let location = this.locations.filter( + (l) => l.id === window.default_location_id + ); + this.$store.dispatch("updateLocation", location); + } + resolve(); + } + ) } ) - }) ); }, @@ -93,10 +95,48 @@ export default { value.name ? value.name : "" }`; }, - createConcernedPersonsLocation() { - let entities = this.suggestedEntities; - return []; // TODO WIP + makeConcernedPersonsLocation(locationType) { + let locations = []; + this.suggestedEntities.forEach( + (e) => { + if (e.type === 'person' && e.current_household_address !== null){ + locations.push({ + type: 'location', + name: e.text, + address: { id: e.current_household_address.id }, + locationType: locationType + }); + } + } + ) + return locations; }, + makeConcernedThirdPartiesLocation(locationType) { + let locations = []; + this.suggestedEntities.forEach( + (e) => { + if (e.type === 'thirdparty' && e.address !== null){ + locations.push({ + type: 'location', + name: e.text, + address: { id: e.address.id }, + locationType: locationType + }); + } + } + ) + return locations; + }, + makePersonLocation(locationType) { + console.log(this.activity) + const accPeriodLocation = this.activity.accompanyingPeriod.location; + return { + type: 'location', + name: 'Adresse du parcours', //TODO trans + address: { id: accPeriodLocation.address_id }, //TODO is the id sufficient? + locationType: locationType + } + } }, }; From 1b579f7930e839dd95007385f57783ca92d5d429 Mon Sep 17 00:00:00 2001 From: nobohan Date: Tue, 23 Nov 2021 17:32:11 +0100 Subject: [PATCH 09/24] activity: label location --- .../public/vuejs/Activity/components/Location.vue | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue index 6cad3dd8d..ccce99075 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue @@ -61,7 +61,7 @@ export default { new Promise((resolve) => { getLocationTypeByDefaultFor('person').then( personLocationType => { - const personLocation = this.makePersonLocation(personLocationType); + const personLocation = this.makeAccompanyingPeriodLocation(personLocationType); const concernedPersonsLocation = this.makeConcernedPersonsLocation(personLocationType); getLocationTypeByDefaultFor('thirdparty').then( @@ -91,9 +91,11 @@ export default { }, methods: { customLabel(value) { - return `${value.locationType.title.fr} ${ - value.name ? value.name : "" - }`; + return value.name ? + value.name === '__AccompanyingCourseLocation__' ? + 'Localisation du parcours' : + `${value.name} (${value.locationType.title.fr})` : + value.locationType.title.fr; }, makeConcernedPersonsLocation(locationType) { let locations = []; @@ -127,12 +129,12 @@ export default { ) return locations; }, - makePersonLocation(locationType) { + makeAccompanyingPeriodLocation(locationType) { console.log(this.activity) const accPeriodLocation = this.activity.accompanyingPeriod.location; return { type: 'location', - name: 'Adresse du parcours', //TODO trans + name: '__AccompanyingCourseLocation__', //TODO not perfect... address: { id: accPeriodLocation.address_id }, //TODO is the id sufficient? locationType: locationType } From a2f6f2b5cb4b4d1fcf067c6a7a94384e12bf2dfd Mon Sep 17 00:00:00 2001 From: nobohan Date: Tue, 23 Nov 2021 17:50:32 +0100 Subject: [PATCH 10/24] activity: post new location on-the-fly --- .../public/vuejs/Activity/components/Location.vue | 5 ++++- .../Activity/components/Location/NewLocation.vue | 1 - .../Resources/public/vuejs/Activity/store.js | 15 ++++++++++++++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue index ccce99075..e9f4e39e6 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue @@ -104,6 +104,7 @@ export default { if (e.type === 'person' && e.current_household_address !== null){ locations.push({ type: 'location', + onthefly: true, name: e.text, address: { id: e.current_household_address.id }, locationType: locationType @@ -120,6 +121,7 @@ export default { if (e.type === 'thirdparty' && e.address !== null){ locations.push({ type: 'location', + onthefly: true, name: e.text, address: { id: e.address.id }, locationType: locationType @@ -134,7 +136,8 @@ export default { const accPeriodLocation = this.activity.accompanyingPeriod.location; return { type: 'location', - name: '__AccompanyingCourseLocation__', //TODO not perfect... + onthefly: true, + name: '__AccompanyingCourseLocation__', //TODO not perfect... shoould show the address address: { id: accPeriodLocation.address_id }, //TODO is the id sufficient? locationType: locationType } diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location/NewLocation.vue b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location/NewLocation.vue index 18190564d..34aa607e9 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location/NewLocation.vue +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location/NewLocation.vue @@ -246,7 +246,6 @@ export default { postLocation(body) .then( location => new Promise(resolve => { - console.log('postLocation', location); this.locations.push(location); this.$store.dispatch('updateLocation', location); resolve(); diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/store.js b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/store.js index ef9cf3b1f..182a3b01a 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/store.js +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/store.js @@ -1,5 +1,6 @@ import 'es6-promise/auto'; import { createStore } from 'vuex'; +import { postLocation } from './api'; const debug = process.env.NODE_ENV !== 'production'; //console.log('window.activity', window.activity); @@ -303,7 +304,19 @@ const store = createStore({ let hiddenLocation = document.getElementById( "chill_activitybundle_activity_location" ); - hiddenLocation.value = value.id; + //TODO post the location if new location on-the-fly + if (value.onthefly) { + postLocation(value) + .then( + location => hiddenLocation.value = location.id + ).catch( + err => { + this.errors.push(err.message); + } + ); + } else { + hiddenLocation.value = value.id; + } commit("updateLocation", value); }, }, From c7f27176763274e5a566d284cd6f84a21e211c3a Mon Sep 17 00:00:00 2001 From: nobohan Date: Wed, 24 Nov 2021 11:45:29 +0100 Subject: [PATCH 11/24] activity: new activity: show address in parcours location --- .../vuejs/Activity/components/Location.vue | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue index e9f4e39e6..3a7841cd9 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue @@ -90,15 +90,19 @@ export default { ); }, methods: { + labelAccompanyingCourseLocation(value) { + return `${value.address.text} (Localisation du parcours)` + }, customLabel(value) { return value.name ? value.name === '__AccompanyingCourseLocation__' ? - 'Localisation du parcours' : + this.labelAccompanyingCourseLocation(value) : `${value.name} (${value.locationType.title.fr})` : value.locationType.title.fr; }, makeConcernedPersonsLocation(locationType) { let locations = []; + console.log(this.suggestedEntities) this.suggestedEntities.forEach( (e) => { if (e.type === 'person' && e.current_household_address !== null){ @@ -106,7 +110,9 @@ export default { type: 'location', onthefly: true, name: e.text, - address: { id: e.current_household_address.id }, + address: { + id: e.current_household_address.id, + }, locationType: locationType }); } @@ -137,8 +143,11 @@ export default { return { type: 'location', onthefly: true, - name: '__AccompanyingCourseLocation__', //TODO not perfect... shoould show the address - address: { id: accPeriodLocation.address_id }, //TODO is the id sufficient? + name: '__AccompanyingCourseLocation__', + address: { + id: accPeriodLocation.address_id, + text: `${accPeriodLocation.text} - ${accPeriodLocation.postcode.code} ${accPeriodLocation.postcode.name}` + }, //TODO is the id sufficient? locationType: locationType } } From d27f085ac9d9f341753f41b632adcdad94bc941e Mon Sep 17 00:00:00 2001 From: nobohan Date: Wed, 24 Nov 2021 14:07:02 +0100 Subject: [PATCH 12/24] location: change display in twig --- .../ChillActivityBundle/Resources/views/Activity/show.html.twig | 2 +- .../ChillCalendarBundle/Resources/views/Calendar/show.html.twig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/show.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/show.html.twig index a30034257..e9782b8e1 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/show.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/show.html.twig @@ -67,8 +67,8 @@
    {% if entity.location is not null %}

    - {{ entity.location.locationType.title|localize_translatable_string }} {{ entity.location.name }} + ({{ entity.location.locationType.title|localize_translatable_string }})

    {{ entity.location.address|chill_entity_render_box }} {% else %} diff --git a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/show.html.twig b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/show.html.twig index 5dfde6fc3..7c59996d2 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/show.html.twig +++ b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/show.html.twig @@ -41,8 +41,8 @@
    {% if entity.location is not null %}

    - {{ entity.location.locationType.title|localize_translatable_string }} {{ entity.location.name }} + ({{ entity.location.locationType.title|localize_translatable_string }})

    {{ entity.location.address|chill_entity_render_box }} {% else %} From 0bd0487801c11ed446c15de90c3caaabc7fbf15e Mon Sep 17 00:00:00 2001 From: nobohan Date: Wed, 24 Nov 2021 14:11:25 +0100 Subject: [PATCH 13/24] activity: fix the on-the-fly POSTing of the location entity --- .../vuejs/Activity/components/Location.vue | 9 +++----- .../Resources/public/vuejs/Activity/store.js | 21 +++++++++++++++---- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue index 3a7841cd9..69913323c 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue @@ -74,7 +74,6 @@ export default { ...concernedThirdPartiesLocation, ...response.results, ]; - console.log(this.locations); if (window.default_location_id) { let location = this.locations.filter( (l) => l.id === window.default_location_id @@ -102,7 +101,6 @@ export default { }, makeConcernedPersonsLocation(locationType) { let locations = []; - console.log(this.suggestedEntities) this.suggestedEntities.forEach( (e) => { if (e.type === 'person' && e.current_household_address !== null){ @@ -111,7 +109,7 @@ export default { onthefly: true, name: e.text, address: { - id: e.current_household_address.id, + id: e.current_household_address.address_id, }, locationType: locationType }); @@ -129,7 +127,7 @@ export default { type: 'location', onthefly: true, name: e.text, - address: { id: e.address.id }, + address: { id: e.address.address_id }, locationType: locationType }); } @@ -138,7 +136,6 @@ export default { return locations; }, makeAccompanyingPeriodLocation(locationType) { - console.log(this.activity) const accPeriodLocation = this.activity.accompanyingPeriod.location; return { type: 'location', @@ -147,7 +144,7 @@ export default { address: { id: accPeriodLocation.address_id, text: `${accPeriodLocation.text} - ${accPeriodLocation.postcode.code} ${accPeriodLocation.postcode.name}` - }, //TODO is the id sufficient? + }, locationType: locationType } } diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/store.js b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/store.js index 182a3b01a..5b6297553 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/store.js +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/store.js @@ -28,7 +28,6 @@ const store = createStore({ }, getters: { suggestedEntities(state) { - console.log(state.activity); if (typeof state.activity.accompanyingPeriod === "undefined") { return []; } @@ -304,14 +303,28 @@ const store = createStore({ let hiddenLocation = document.getElementById( "chill_activitybundle_activity_location" ); - //TODO post the location if new location on-the-fly if (value.onthefly) { - postLocation(value) + const body = { + "type": "location", + "name": value.name === '__AccompanyingCourseLocation__' ? null : value.name, + "locationType": { + "id": value.locationType.id, + "type": "location-type" + } + }; + if (value.address.id) { + Object.assign(body, { + "address": { + "id": value.address.id + }, + }) + } + postLocation(body) .then( location => hiddenLocation.value = location.id ).catch( err => { - this.errors.push(err.message); + console.log(err.message); } ); } else { From d13d42b9bf3db06b8d071b3cd5697efce76afcad Mon Sep 17 00:00:00 2001 From: nobohan Date: Wed, 24 Nov 2021 14:43:07 +0100 Subject: [PATCH 14/24] activity: group locations by type in the selector --- .../vuejs/Activity/components/Location.vue | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue index 69913323c..dafd3872a 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue @@ -16,6 +16,8 @@ :placeholder="$t('activity.choose_location')" :custom-label="customLabel" :options="locations" + group-values="locations" + group-label="locationGroup" v-model="location" > @@ -69,10 +71,17 @@ export default { const concernedThirdPartiesLocation = this.makeConcernedThirdPartiesLocation(thirdpartyLocationType); this.locations = [ - personLocation, - ...concernedPersonsLocation, - ...concernedThirdPartiesLocation, - ...response.results, + { + locationGroup: 'Localisation du parcours', + locations: [personLocation] + }, + { + locationGroup: 'Parties concernées', + locations: [...concernedPersonsLocation, ...concernedThirdPartiesLocation]}, + { + locationGroup: 'Autres localisations', + locations: response.results + } ]; if (window.default_location_id) { let location = this.locations.filter( @@ -90,7 +99,7 @@ export default { }, methods: { labelAccompanyingCourseLocation(value) { - return `${value.address.text} (Localisation du parcours)` + return `${value.address.text}` }, customLabel(value) { return value.name ? @@ -106,6 +115,7 @@ export default { if (e.type === 'person' && e.current_household_address !== null){ locations.push({ type: 'location', + id: -this.suggestedEntities.indexOf(e)*10, onthefly: true, name: e.text, address: { @@ -122,9 +132,11 @@ export default { let locations = []; this.suggestedEntities.forEach( (e) => { + console.log(this.suggestedEntities.indexOf(e)) if (e.type === 'thirdparty' && e.address !== null){ locations.push({ type: 'location', + id: -this.suggestedEntities.indexOf(e)*10, onthefly: true, name: e.text, address: { id: e.address.address_id }, @@ -139,6 +151,7 @@ export default { const accPeriodLocation = this.activity.accompanyingPeriod.location; return { type: 'location', + id: -1, onthefly: true, name: '__AccompanyingCourseLocation__', address: { From 220f2973911fa085ce3dd4cf8c5cd771641856db Mon Sep 17 00:00:00 2001 From: nobohan Date: Wed, 24 Nov 2021 15:11:46 +0100 Subject: [PATCH 15/24] calendar: cast collection to array --- .../ChillCalendarBundle/Controller/CalendarController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php b/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php index 0165142f7..6e6bce842 100644 --- a/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php +++ b/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php @@ -332,12 +332,12 @@ class CalendarController extends AbstractController $personsId = array_map( static fn (Person $p): int => $p->getId(), - $entity->getPersons() + $entity->getPersons()->toArray() ); $professionalsId = array_map( static fn (ThirdParty $thirdParty): ?int => $thirdParty->getId(), - $entity->getProfessionals() + $entity->getProfessionals()->toArray() ); $durationTime = $entity->getEndDate()->diff($entity->getStartDate()); From 2ee4a6b2ac54d24ca2774c05724cb7f4511f76f0 Mon Sep 17 00:00:00 2001 From: nobohan Date: Wed, 24 Nov 2021 15:12:21 +0100 Subject: [PATCH 16/24] calendar: dynamic way of creating location when creating a calendar --- .../Resources/public/vuejs/Calendar/store.js | 33 +++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store.js b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store.js index 457d31799..edfb7f236 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store.js +++ b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store.js @@ -1,5 +1,6 @@ import 'es6-promise/auto'; import { createStore } from 'vuex'; +import { postLocation } from 'ChillActivityAssets/vuejs/Activity/api'; const debug = process.env.NODE_ENV !== 'production'; @@ -33,7 +34,6 @@ const store = createStore({ }, getters: { suggestedEntities(state) { - console.log(state.activity) if (typeof(state.activity.accompanyingPeriod) === 'undefined') { return []; } @@ -189,8 +189,35 @@ const store = createStore({ updateLocation({ commit }, value) { console.log('### action: updateLocation', value); let hiddenLocation = document.getElementById("chill_calendarbundle_calendar_location"); - hiddenLocation.value = value.id; - commit('updateLocation', value); + if (value.onthefly) { + const body = { + "type": "location", + "name": value.name === '__AccompanyingCourseLocation__' ? null : value.name, + "locationType": { + "id": value.locationType.id, + "type": "location-type" + } + }; + if (value.address.id) { + Object.assign(body, { + "address": { + "id": value.address.id + }, + }) + } + postLocation(body) + .then( + location => hiddenLocation.value = location.id + ).catch( + err => { + console.log(err.message); + } + ); + } else { + hiddenLocation.value = value.id; + } + commit("updateLocation", value); + } } From e73179688ac208b34bf27768848a97e4b2e9939d Mon Sep 17 00:00:00 2001 From: nobohan Date: Wed, 24 Nov 2021 15:25:36 +0100 Subject: [PATCH 17/24] activity: format location label for parcours location --- .../Resources/public/vuejs/Activity/components/Location.vue | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue index dafd3872a..25c75ed8b 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue @@ -99,7 +99,7 @@ export default { }, methods: { labelAccompanyingCourseLocation(value) { - return `${value.address.text}` + return `${value.address.text} (${value.locationType.title.fr})` }, customLabel(value) { return value.name ? @@ -132,7 +132,6 @@ export default { let locations = []; this.suggestedEntities.forEach( (e) => { - console.log(this.suggestedEntities.indexOf(e)) if (e.type === 'thirdparty' && e.address !== null){ locations.push({ type: 'location', From 3d5db29a4c5918f4cc2e5809c65a184a49ba7aae Mon Sep 17 00:00:00 2001 From: nobohan Date: Thu, 25 Nov 2021 10:18:40 +0100 Subject: [PATCH 18/24] location: filter location api point only by active and availableForUsers --- .../Controller/LocationApiController.php | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Controller/LocationApiController.php b/src/Bundle/ChillMainBundle/Controller/LocationApiController.php index 52b6f1e81..3e4911788 100644 --- a/src/Bundle/ChillMainBundle/Controller/LocationApiController.php +++ b/src/Bundle/ChillMainBundle/Controller/LocationApiController.php @@ -21,22 +21,11 @@ class LocationApiController extends ApiController { public function customizeQuery(string $action, Request $request, $query): void { - $query->andWhere($query->expr()->orX( - $query->expr()->andX( - $query->expr()->eq('e.createdBy', ':user'), - $query->expr()->gte('e.createdAt', ':dateBefore') - ), + $query->andWhere( $query->expr()->andX( $query->expr()->eq('e.availableForUsers', "'TRUE'"), $query->expr()->eq('e.active', "'TRUE'"), - $query->expr()->isNotNull('e.name'), - $query->expr()->neq('e.name', ':emptyString'), ) - )) - ->setParameters([ - 'user' => $this->getUser(), - 'dateBefore' => (new DateTime())->sub(new DateInterval('P6M')), - 'emptyString' => '', - ]); + ); } } From 09a679ffb9574ddb05660b2ba94664f2c9fcc21a Mon Sep 17 00:00:00 2001 From: nobohan Date: Thu, 25 Nov 2021 10:34:47 +0100 Subject: [PATCH 19/24] upd CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index caf9a9249..eb3036107 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,8 @@ and this project adheres to * [list for accompanying course in person] filter list using ACL * [validation] toasts are displayed for errors when modifying accompanying course (generalization required). * add an endpoint for checking permissions. See https://gitlab.com/Chill-Projet/chill-bundles/-/merge_requests/232 +* [activity] for a new activity: suggest and create on-the-fly locations based on the accompanying course location + location of the suggested parties +* [calendar] for a new rdv: suggest and create on-the-fly locations based on the accompanying course location + location of the suggested parties ## Test releases From 3f35f0e2517d1a773ab24631ea3cae33296e25fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 25 Nov 2021 14:08:12 +0100 Subject: [PATCH 20/24] add unique constraint on property `validFor` for LocationType --- src/Bundle/ChillMainBundle/Entity/LocationType.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Bundle/ChillMainBundle/Entity/LocationType.php b/src/Bundle/ChillMainBundle/Entity/LocationType.php index d3dff58b7..9385620cd 100644 --- a/src/Bundle/ChillMainBundle/Entity/LocationType.php +++ b/src/Bundle/ChillMainBundle/Entity/LocationType.php @@ -11,6 +11,7 @@ namespace Chill\MainBundle\Entity; use Chill\MainBundle\Repository\LocationTypeRepository; use Doctrine\ORM\Mapping as ORM; +use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; use Symfony\Component\Serializer\Annotation as Serializer; use Symfony\Component\Serializer\Annotation\DiscriminatorMap; @@ -20,6 +21,7 @@ use Symfony\Component\Serializer\Annotation\DiscriminatorMap; * @DiscriminatorMap(typeProperty="type", mapping={ * "location-type": LocationType::class * }) + * @UniqueEntity({"defaultFor"}) */ class LocationType { From 36c57511e874f9f49cb7a6491f87ff5c0404aa18 Mon Sep 17 00:00:00 2001 From: nobohan Date: Thu, 25 Nov 2021 16:10:08 +0100 Subject: [PATCH 21/24] location: fix code style with phpstan --- .../Controller/LocationApiController.php | 2 - .../ChillMainBundle/Entity/LocationType.php | 44 +++++++++---------- .../ChillMainBundle/Form/LocationTypeType.php | 19 ++++---- .../migrations/Version20211123093355.php | 23 ++++++---- 4 files changed, 47 insertions(+), 41 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Controller/LocationApiController.php b/src/Bundle/ChillMainBundle/Controller/LocationApiController.php index 3e4911788..16fc414d9 100644 --- a/src/Bundle/ChillMainBundle/Controller/LocationApiController.php +++ b/src/Bundle/ChillMainBundle/Controller/LocationApiController.php @@ -10,8 +10,6 @@ namespace Chill\MainBundle\Controller; use Chill\MainBundle\CRUD\Controller\ApiController; -use DateInterval; -use DateTime; use Symfony\Component\HttpFoundation\Request; /** diff --git a/src/Bundle/ChillMainBundle/Entity/LocationType.php b/src/Bundle/ChillMainBundle/Entity/LocationType.php index 9385620cd..a9ff33414 100644 --- a/src/Bundle/ChillMainBundle/Entity/LocationType.php +++ b/src/Bundle/ChillMainBundle/Entity/LocationType.php @@ -25,15 +25,16 @@ use Symfony\Component\Serializer\Annotation\DiscriminatorMap; */ class LocationType { + public const DEFAULT_FOR_3PARTY = 'thirdparty'; + + public const DEFAULT_FOR_PERSON = 'person'; + public const STATUS_NEVER = 'never'; public const STATUS_OPTIONAL = 'optional'; public const STATUS_REQUIRED = 'required'; - public const DEFAULT_FOR_PERSON = 'person'; - public const DEFAULT_FOR_3PARTY = 'thirdparty'; - /** * @ORM\Column(type="boolean", nullable=true) * @Serializer\Groups({"read"}) @@ -58,6 +59,12 @@ class LocationType */ private string $contactData = self::STATUS_OPTIONAL; + /** + * @ORM\Column(type="string", nullable=true, length=32, unique=true) + * @Serializer\Groups({"read"}) + */ + private ?string $defaultFor = null; + /** * @ORM\Id * @ORM\GeneratedValue @@ -72,13 +79,6 @@ class LocationType */ private array $title = []; - /** - * @ORM\Column(type="string", nullable=true, length=32, unique=true) - * @Serializer\Groups({"read"}) - */ - private ?string $defaultFor = null; - - public function getActive(): ?bool { return $this->active; @@ -99,6 +99,11 @@ class LocationType return $this->contactData; } + public function getDefaultFor(): ?string + { + return $this->defaultFor; + } + public function getId(): ?int { return $this->id; @@ -137,22 +142,17 @@ class LocationType return $this; } - public function setTitle(array $title): self - { - $this->title = $title; - - return $this; - } - - public function getDefaultFor(): ?string - { - return $this->defaultFor; - } - public function setDefaultFor(string $defaultFor): self { $this->defaultFor = $defaultFor; return $this; } + + public function setTitle(array $title): self + { + $this->title = $title; + + return $this; + } } diff --git a/src/Bundle/ChillMainBundle/Form/LocationTypeType.php b/src/Bundle/ChillMainBundle/Form/LocationTypeType.php index 93bc5ba0f..41372b48e 100644 --- a/src/Bundle/ChillMainBundle/Form/LocationTypeType.php +++ b/src/Bundle/ChillMainBundle/Form/LocationTypeType.php @@ -73,15 +73,16 @@ final class LocationTypeType extends AbstractType ] ) ->add( - 'defaultFor', + 'defaultFor', ChoiceType::class, - [ - 'choices' => [ - 'none' => null, - 'person' => LocationType::DEFAULT_FOR_PERSON, - 'thirdparty' => LocationType::DEFAULT_FOR_3PARTY, - ], - 'expanded' => true - ]); + [ + 'choices' => [ + 'none' => null, + 'person' => LocationType::DEFAULT_FOR_PERSON, + 'thirdparty' => LocationType::DEFAULT_FOR_3PARTY, + ], + 'expanded' => true, + ] + ); } } diff --git a/src/Bundle/ChillMainBundle/migrations/Version20211123093355.php b/src/Bundle/ChillMainBundle/migrations/Version20211123093355.php index 1736cf857..b6618d25e 100644 --- a/src/Bundle/ChillMainBundle/migrations/Version20211123093355.php +++ b/src/Bundle/ChillMainBundle/migrations/Version20211123093355.php @@ -1,5 +1,12 @@ addSql('DROP INDEX UNIQ_A459B5CADD3E4105'); + $this->addSql('ALTER TABLE chill_main_location_type DROP defaultFor'); + } + public function getDescription(): string { return 'Add defaultFor to LocationType'; @@ -22,10 +35,4 @@ final class Version20211123093355 extends AbstractMigration $this->addSql('ALTER TABLE chill_main_location_type ADD defaultFor VARCHAR(32) DEFAULT NULL'); $this->addSql('CREATE UNIQUE INDEX UNIQ_A459B5CADD3E4105 ON chill_main_location_type (defaultFor)'); } - - public function down(Schema $schema): void - { - $this->addSql('DROP INDEX UNIQ_A459B5CADD3E4105'); - $this->addSql('ALTER TABLE chill_main_location_type DROP defaultFor'); - } -} \ No newline at end of file +} From aad4b6e5d03022f18bee837f765bd93423d8e33a Mon Sep 17 00:00:00 2001 From: nobohan Date: Thu, 25 Nov 2021 16:18:45 +0100 Subject: [PATCH 22/24] location: allow null value for defaultFor --- src/Bundle/ChillMainBundle/Entity/LocationType.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bundle/ChillMainBundle/Entity/LocationType.php b/src/Bundle/ChillMainBundle/Entity/LocationType.php index a9ff33414..b0d91a4f1 100644 --- a/src/Bundle/ChillMainBundle/Entity/LocationType.php +++ b/src/Bundle/ChillMainBundle/Entity/LocationType.php @@ -142,7 +142,7 @@ class LocationType return $this; } - public function setDefaultFor(string $defaultFor): self + public function setDefaultFor(?string $defaultFor): self { $this->defaultFor = $defaultFor; From f002d48efdd0074274c56a6a6704df734737adaa Mon Sep 17 00:00:00 2001 From: nobohan Date: Thu, 25 Nov 2021 16:53:02 +0100 Subject: [PATCH 23/24] location: fix error when there is no defaultFor defined for locationType entities --- .../vuejs/Activity/components/Location.vue | 78 +++++++++++-------- 1 file changed, 45 insertions(+), 33 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue index 25c75ed8b..012c550aa 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue @@ -63,35 +63,45 @@ export default { new Promise((resolve) => { getLocationTypeByDefaultFor('person').then( personLocationType => { - const personLocation = this.makeAccompanyingPeriodLocation(personLocationType); - const concernedPersonsLocation = - this.makeConcernedPersonsLocation(personLocationType); - getLocationTypeByDefaultFor('thirdparty').then( - thirdpartyLocationType => { - const concernedThirdPartiesLocation = - this.makeConcernedThirdPartiesLocation(thirdpartyLocationType); - this.locations = [ - { - locationGroup: 'Localisation du parcours', - locations: [personLocation] - }, - { - locationGroup: 'Parties concernées', - locations: [...concernedPersonsLocation, ...concernedThirdPartiesLocation]}, - { - locationGroup: 'Autres localisations', - locations: response.results - } - ]; - if (window.default_location_id) { - let location = this.locations.filter( - (l) => l.id === window.default_location_id - ); - this.$store.dispatch("updateLocation", location); + if (personLocationType) { + const personLocation = this.makeAccompanyingPeriodLocation(personLocationType); + const concernedPersonsLocation = + this.makeConcernedPersonsLocation(personLocationType); + getLocationTypeByDefaultFor('thirdparty').then( + thirdpartyLocationType => { + const concernedThirdPartiesLocation = + this.makeConcernedThirdPartiesLocation(thirdpartyLocationType); + this.locations = [ + { + locationGroup: 'Localisation du parcours', + locations: [personLocation] + }, + { + locationGroup: 'Parties concernées', + locations: [...concernedPersonsLocation, ...concernedThirdPartiesLocation] + }, + { + locationGroup: 'Autres localisations', + locations: response.results + } + ]; } - resolve(); - } - ) + ) + } else { + this.locations = [ + { + locationGroup: 'Localisations', + locations: response.results + } + ]; + } + if (window.default_location_id) { + let location = this.locations.filter( + (l) => l.id === window.default_location_id + ); + this.$store.dispatch("updateLocation", location); + } + resolve(); } ) }) @@ -102,11 +112,13 @@ export default { return `${value.address.text} (${value.locationType.title.fr})` }, customLabel(value) { - return value.name ? - value.name === '__AccompanyingCourseLocation__' ? - this.labelAccompanyingCourseLocation(value) : - `${value.name} (${value.locationType.title.fr})` : - value.locationType.title.fr; + return value.locationType + ? value.name + ? value.name === '__AccompanyingCourseLocation__' + ? this.labelAccompanyingCourseLocation(value) + : `${value.name} (${value.locationType.title.fr})` + : value.locationType.title.fr + : ''; }, makeConcernedPersonsLocation(locationType) { let locations = []; From 5aa5cb3e08c9bfd7e54d9bb9b75f8c3f764db94d Mon Sep 17 00:00:00 2001 From: nobohan Date: Thu, 25 Nov 2021 17:22:25 +0100 Subject: [PATCH 24/24] location: use fetchResults for getLocations and getLocationTypes --- .../Resources/public/vuejs/Activity/api.js | 33 ++------ .../vuejs/Activity/components/Location.vue | 79 +++++++++---------- .../components/Location/NewLocation.vue | 7 +- 3 files changed, 46 insertions(+), 73 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/api.js b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/api.js index 70ba4c04e..8d4bcac3b 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/api.js +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/api.js @@ -1,4 +1,5 @@ import { getSocialIssues } from 'ChillPersonAssets/vuejs/AccompanyingCourse/api.js'; +import { fetchResults } from 'ChillMainAssets/lib/api/apiMethods'; /* * Load socialActions by socialIssue (id) @@ -12,44 +13,20 @@ const getSocialActionByIssue = (id) => { }); }; -/* -* Load Locations - */ -const getLocations = () => { - const url = `/api/1.0/main/location.json`; - return fetch(url) - .then(response => { - if (response.ok) { return response.json(); } - throw Error('Error with request resource response'); - }); -}; - -/* -* Load Location Types - */ -const getLocationTypes = () => { - const url = `/api/1.0/main/location-type.json`; - return fetch(url) - .then(response => { - if (response.ok) { return response.json(); } - throw Error('Error with request resource response'); - }); -}; +const getLocations = () => fetchResults('/api/1.0/main/location.json'); +const getLocationTypes = () => fetchResults('/api/1.0/main/location-type.json'); /* * Load Location Type by defaultFor * @param {string} entity - can be "person" or "thirdparty" */ const getLocationTypeByDefaultFor = (entity) => { - return getLocationTypes().then(response => - response.results.filter(t => t.defaultFor === entity)[0] + return getLocationTypes().then(results => + results.filter(t => t.defaultFor === entity)[0] ); }; -/* -* Post a Location - */ const postLocation = (body) => { const url = `/api/1.0/main/location.json`; return fetch(url, { diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue index 012c550aa..9a4b78334 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location.vue @@ -59,53 +59,50 @@ export default { }, mounted() { getLocations().then( - (response) => - new Promise((resolve) => { - getLocationTypeByDefaultFor('person').then( - personLocationType => { - if (personLocationType) { - const personLocation = this.makeAccompanyingPeriodLocation(personLocationType); - const concernedPersonsLocation = - this.makeConcernedPersonsLocation(personLocationType); - getLocationTypeByDefaultFor('thirdparty').then( - thirdpartyLocationType => { - const concernedThirdPartiesLocation = - this.makeConcernedThirdPartiesLocation(thirdpartyLocationType); - this.locations = [ - { - locationGroup: 'Localisation du parcours', - locations: [personLocation] - }, - { - locationGroup: 'Parties concernées', - locations: [...concernedPersonsLocation, ...concernedThirdPartiesLocation] - }, - { - locationGroup: 'Autres localisations', - locations: response.results - } - ]; - } - ) - } else { - this.locations = [ - { - locationGroup: 'Localisations', - locations: response.results - } - ]; - } + (results) => { + getLocationTypeByDefaultFor('person').then( + (personLocationType) => { + if (personLocationType) { + const personLocation = this.makeAccompanyingPeriodLocation(personLocationType); + const concernedPersonsLocation = + this.makeConcernedPersonsLocation(personLocationType); + getLocationTypeByDefaultFor('thirdparty').then( + thirdpartyLocationType => { + const concernedThirdPartiesLocation = + this.makeConcernedThirdPartiesLocation(thirdpartyLocationType); + this.locations = [ + { + locationGroup: 'Localisation du parcours', + locations: [personLocation] + }, + { + locationGroup: 'Parties concernées', + locations: [...concernedPersonsLocation, ...concernedThirdPartiesLocation] + }, + { + locationGroup: 'Autres localisations', + locations: results + } + ]; + } + ) + } else { + this.locations = [ + { + locationGroup: 'Localisations', + locations: response.results + } + ]; + } if (window.default_location_id) { let location = this.locations.filter( (l) => l.id === window.default_location_id ); this.$store.dispatch("updateLocation", location); } - resolve(); - } - ) - }) - ); + } + ) + }) }, methods: { labelAccompanyingCourseLocation(value) { diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location/NewLocation.vue b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location/NewLocation.vue index 34aa607e9..35bf9a065 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location/NewLocation.vue +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location/NewLocation.vue @@ -214,10 +214,9 @@ export default { return cond; }, getLocationTypesList() { - getLocationTypes().then(response => new Promise(resolve => { - this.locationTypes = response.results.filter(t => t.availableForUsers === true); - resolve(); - })) + getLocationTypes().then(results => { + this.locationTypes = results.filter(t => t.availableForUsers === true); + }) }, openModal() { this.modal.showModal = true;