From 8e0d144dd17e768e06b497e498fee5d30e78d63a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Mon, 6 Mar 2023 15:41:13 +0100
Subject: [PATCH 01/46] Feature: add columns into Address to track the matching
with AddressReference
---
src/Bundle/ChillMainBundle/Entity/Address.php | 40 ++++++++++++++++++-
.../migrations/Version20230306142148.php | 31 ++++++++++++++
2 files changed, 69 insertions(+), 2 deletions(-)
create mode 100644 src/Bundle/ChillMainBundle/migrations/Version20230306142148.php
diff --git a/src/Bundle/ChillMainBundle/Entity/Address.php b/src/Bundle/ChillMainBundle/Entity/Address.php
index 9a0f8b7b3..29c9eb14e 100644
--- a/src/Bundle/ChillMainBundle/Entity/Address.php
+++ b/src/Bundle/ChillMainBundle/Entity/Address.php
@@ -12,6 +12,10 @@ declare(strict_types=1);
namespace Chill\MainBundle\Entity;
use Chill\MainBundle\Doctrine\Model\Point;
+use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
+use Chill\MainBundle\Doctrine\Model\TrackCreationTrait;
+use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface;
+use Chill\MainBundle\Doctrine\Model\TrackUpdateTrait;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use DateTime;
use DateTimeInterface;
@@ -28,8 +32,28 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface;
* @ORM\Table(name="chill_main_address")
* @ORM\HasLifecycleCallbacks
*/
-class Address
+class Address implements TrackCreationInterface, TrackUpdateInterface
{
+ use TrackCreationTrait;
+ use TrackUpdateTrait;
+
+ /**
+ * When an Address does match with the AddressReference
+ */
+ public const ADDR_REFERENCE_STATUS_MATCH = 'match';
+
+ /**
+ * When an Address does not match with the AddressReference, and
+ * is pending for a review
+ */
+ public const ADDR_REFERENCE_STATUS_TO_REVIEW = 'to_review';
+
+ /**
+ * When an Address does not match with the AddressReference, but
+ * is reviewed
+ */
+ public const ADDR_REFERENCE_STATUS_REVIEWED = 'reviewed';
+
/**
* @ORM\ManyToOne(targetEntity=AddressReference::class)
* @Groups({"write"})
@@ -42,7 +66,7 @@ class Address
* @ORM\Column(type="string", length=255, nullable=true)
* @Groups({"write"})
*/
- private $buildingName;
+ private string $buildingName = '';
/**
* @ORM\Column(type="boolean")
@@ -165,6 +189,17 @@ class Address
*/
private ?PostalCode $postcode = null;
+ /**
+ * @var self::ADDR_REFERENCE_STATUS_*
+ * @ORM\Column(type="text", nullable=false, options={"default": self::ADDR_REFERENCE_STATUS_MATCH})
+ */
+ private string $refStatus = self::ADDR_REFERENCE_STATUS_MATCH;
+
+ /**
+ * @ORM\Column(type="datetime_immutable", nullable=false, options={"default": "CURRENT_TIMESTAMP"})
+ */
+ private \DateTimeImmutable $refStatusLastUpdate;
+
/**
* @var string|null
*
@@ -210,6 +245,7 @@ class Address
public function __construct()
{
$this->validFrom = new DateTime();
+ $this->refStatusLastUpdate = new \DateTimeImmutable('now');
$this->geographicalUnits = new ArrayCollection();
}
diff --git a/src/Bundle/ChillMainBundle/migrations/Version20230306142148.php b/src/Bundle/ChillMainBundle/migrations/Version20230306142148.php
new file mode 100644
index 000000000..760d8c826
--- /dev/null
+++ b/src/Bundle/ChillMainBundle/migrations/Version20230306142148.php
@@ -0,0 +1,31 @@
+addSql('ALTER TABLE chill_main_address ADD refStatus TEXT DEFAULT \'match\' NOT NULL');
+ $this->addSql('ALTER TABLE chill_main_address ADD refStatusLastUpdate TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL');
+
+ // we must set the last status update to the address reference date to avoid inconsistencies
+ $this->addSql('UPDATE chill_main_address a SET refStatusLastUpdate = COALESCE(r.updatedat, r.createdat, \'1970-01-01\'::timestamp) FROM chill_main_address_reference r WHERE a.addressreference_id = r.id');
+ }
+
+ public function down(Schema $schema): void
+ {
+ $this->addSql('ALTER TABLE chill_main_address DROP refStatus');
+ $this->addSql('ALTER TABLE chill_main_address DROP refStatusLastUpdate');
+ }
+}
From c9fe5a393f33818b34cc8bfb2726a393123d32ed Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Mon, 6 Mar 2023 16:18:15 +0100
Subject: [PATCH 02/46] DX: [Address] fix inconsistencies between doctrine
mapping and sql schema
DX: [Address] fix inconsistencies between doctrine mapping and sql schema
Fixed: Address vue module do now set empty value to empty string instead of null
DX: fixed AddressReferenceBaseImporterTest
---
src/Bundle/ChillMainBundle/Entity/Address.php | 174 ++++++++----------
.../Entity/AddressReference.php | 46 ++---
.../vuejs/Address/components/AddAddress.vue | 30 +--
.../_components/Entity/AddressRenderBox.vue | 6 +-
.../Templating/Entity/AddressRender.php | 37 ++--
.../AddressReferenceBaseImporterTest.php | 2 +-
.../migrations/Version20230306145728.php | 109 +++++++++++
.../migrations/Version20230306151218.php | 58 ++++++
8 files changed, 305 insertions(+), 157 deletions(-)
create mode 100644 src/Bundle/ChillMainBundle/migrations/Version20230306145728.php
create mode 100644 src/Bundle/ChillMainBundle/migrations/Version20230306151218.php
diff --git a/src/Bundle/ChillMainBundle/Entity/Address.php b/src/Bundle/ChillMainBundle/Entity/Address.php
index 29c9eb14e..23b0f971c 100644
--- a/src/Bundle/ChillMainBundle/Entity/Address.php
+++ b/src/Bundle/ChillMainBundle/Entity/Address.php
@@ -61,67 +61,48 @@ class Address implements TrackCreationInterface, TrackUpdateInterface
private ?AddressReference $addressReference = null;
/**
- * @var string|null
- *
- * @ORM\Column(type="string", length=255, nullable=true)
+ * @ORM\Column(type="text", nullable=false, options={"default": ""})
* @Groups({"write"})
*/
private string $buildingName = '';
/**
- * @ORM\Column(type="boolean")
+ * @ORM\Column(type="boolean", options={"default": false})
* @Groups({"write"})
*/
private bool $confidential = false;
/**
- * @var string|null
- *
- * @ORM\Column(type="string", length=255, nullable=true)
+ * @ORM\Column(type="text", nullable=false, options={"default": ""})
* @Groups({"write"})
*/
- private $corridor;
+ private string $corridor = '';
/**
- * A list of metadata, added by customizable fields.
- *
- * @var array
- */
- private $customs = [];
-
- /**
- * @var string|null
- *
* used for the CEDEX information
*
- * @ORM\Column(type="string", length=255, nullable=true)
+ * @ORM\Column(type="text", nullable=false, options={"default": ""})
* @Groups({"write"})
*/
- private $distribution;
+ private string $distribution = '';
/**
- * @var string|null
- *
- * @ORM\Column(type="string", length=255, nullable=true)
+ * @ORM\Column(type="text", nullable=false, options={"default": ""})
* @Groups({"write"})
*/
- private $extra;
+ private string $extra = '';
/**
- * @var string|null
- *
- * @ORM\Column(type="string", length=255, nullable=true)
+ * @ORM\Column(type="text", nullable=false, options={"default": ""})
* @Groups({"write"})
*/
- private $flat;
+ private string $flat = '';
/**
- * @var string|null
- *
- * @ORM\Column(type="string", length=255, nullable=true)
+ * @ORM\Column(type="text", nullable=false, options={"default": ""})
* @Groups({"write"})
*/
- private $floor;
+ private string $floor = '';
/**
* List of geographical units and addresses.
@@ -155,11 +136,9 @@ class Address implements TrackCreationInterface, TrackUpdateInterface
* True if the address is a "no address", aka homeless person, ...
*
* @Groups({"write"})
- * @ORM\Column(type="boolean")
- *
- * @var bool
+ * @ORM\Column(type="boolean", options={"default": false})
*/
- private $isNoAddress = false;
+ private bool $isNoAddress = false;
/**
* A ThirdParty reference for person's addresses that are linked to a third party.
@@ -170,7 +149,7 @@ class Address implements TrackCreationInterface, TrackUpdateInterface
* @Groups({"write"})
* @ORM\JoinColumn(nullable=true, onDelete="SET NULL")
*/
- private $linkedToThirdParty;
+ private ?ThirdParty $linkedToThirdParty;
/**
* A geospatial field storing the coordinates of the Address.
@@ -180,7 +159,7 @@ class Address implements TrackCreationInterface, TrackUpdateInterface
* @ORM\Column(type="point", nullable=true)
* @Groups({"write"})
*/
- private $point;
+ private ?Point $point = null;
/**
* @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\PostalCode")
@@ -201,28 +180,25 @@ class Address implements TrackCreationInterface, TrackUpdateInterface
private \DateTimeImmutable $refStatusLastUpdate;
/**
- * @var string|null
*
- * @ORM\Column(type="string", length=255, nullable=true)
+ * @ORM\Column(type="text", nullable=false, options={"default": ""})
* @Groups({"write"})
*/
- private $steps;
+ private string $steps = '';
/**
- * @var string
*
- * @ORM\Column(type="string", length=255)
+ * @ORM\Column(type="text", nullable=false, options={"default": ""})
* @Groups({"write"})
*/
- private $street = '';
+ private string $street = '';
/**
- * @var string
*
- * @ORM\Column(type="string", length=255)
+ * @ORM\Column(type="text", nullable=false, options={"default": ""})
* @Groups({"write"})
*/
- private $streetNumber = '';
+ private string $streetNumber = '';
/**
* Indicates when the address starts validation. Used to build an history
@@ -256,7 +232,6 @@ class Address implements TrackCreationInterface, TrackUpdateInterface
->setBuildingName($original->getBuildingName())
->setConfidential($original->getConfidential())
->setCorridor($original->getCorridor())
- ->setCustoms($original->getCustoms())
->setDistribution($original->getDistribution())
->setExtra($original->getExtra())
->setFlat($original->getFlat())
@@ -287,7 +262,7 @@ class Address implements TrackCreationInterface, TrackUpdateInterface
return $this->addressReference;
}
- public function getBuildingName(): ?string
+ public function getBuildingName(): string
{
return $this->buildingName;
}
@@ -297,35 +272,27 @@ class Address implements TrackCreationInterface, TrackUpdateInterface
return $this->confidential;
}
- public function getCorridor(): ?string
+ public function getCorridor(): string
{
return $this->corridor;
}
- /**
- * Get customs informations in the address.
- */
- public function getCustoms(): array
- {
- return $this->customs;
- }
-
- public function getDistribution(): ?string
+ public function getDistribution(): string
{
return $this->distribution;
}
- public function getExtra(): ?string
+ public function getExtra(): string
{
return $this->extra;
}
- public function getFlat(): ?string
+ public function getFlat(): string
{
return $this->flat;
}
- public function getFloor(): ?string
+ public function getFloor(): string
{
return $this->floor;
}
@@ -376,12 +343,22 @@ class Address implements TrackCreationInterface, TrackUpdateInterface
return $this->postcode;
}
- public function getSteps(): ?string
+ public function getRefStatus(): string
+ {
+ return $this->refStatus;
+ }
+
+ public function getRefStatusLastUpdate(): \DateTimeImmutable
+ {
+ return $this->refStatusLastUpdate;
+ }
+
+ public function getSteps(): string
{
return $this->steps;
}
- public function getStreet(): ?string
+ public function getStreet(): string
{
return $this->street;
}
@@ -390,6 +367,7 @@ class Address implements TrackCreationInterface, TrackUpdateInterface
* Get streetAddress1 (legacy function).
*
* @return string
+ * @deprecated
*/
public function getStreetAddress1()
{
@@ -400,13 +378,14 @@ class Address implements TrackCreationInterface, TrackUpdateInterface
* Get streetAddress2 (legacy function).
*
* @return string
+ * @deprecated
*/
public function getStreetAddress2()
{
return $this->streetNumber;
}
- public function getStreetNumber(): ?string
+ public function getStreetNumber(): string
{
return $this->streetNumber;
}
@@ -414,7 +393,7 @@ class Address implements TrackCreationInterface, TrackUpdateInterface
/**
* @return DateTime
*/
- public function getValidFrom()
+ public function getValidFrom(): DateTime
{
return $this->validFrom;
}
@@ -443,7 +422,7 @@ class Address implements TrackCreationInterface, TrackUpdateInterface
public function setBuildingName(?string $buildingName): self
{
- $this->buildingName = $buildingName;
+ $this->buildingName = (string) $buildingName;
return $this;
}
@@ -457,47 +436,35 @@ class Address implements TrackCreationInterface, TrackUpdateInterface
public function setCorridor(?string $corridor): self
{
- $this->corridor = $corridor;
-
- return $this;
- }
-
- /**
- * Store custom informations in the address.
- *
- * @return $this
- */
- public function setCustoms(array $customs): self
- {
- $this->customs = $customs;
+ $this->corridor = (string) $corridor;
return $this;
}
public function setDistribution(?string $distribution): self
{
- $this->distribution = $distribution;
+ $this->distribution = (string) $distribution;
return $this;
}
public function setExtra(?string $extra): self
{
- $this->extra = $extra;
+ $this->extra = (string) $extra;
return $this;
}
public function setFlat(?string $flat): self
{
- $this->flat = $flat;
+ $this->flat = (string) $flat;
return $this;
}
public function setFloor(?string $floor): self
{
- $this->floor = $floor;
+ $this->floor = (string) $floor;
return $this;
}
@@ -544,19 +511,40 @@ class Address implements TrackCreationInterface, TrackUpdateInterface
return $this;
}
+ /**
+ * Update the ref status
+ *
+ * @param Address::ADDR_REFERENCE_STATUS_* $refStatus
+ * @param bool|null $updateLastUpdate Also update the "refStatusLastUpdate"
+ */
+ public function setRefStatus(string $refStatus, ?bool $updateLastUpdate = true): self
+ {
+ $this->refStatus = $refStatus;
+
+ if ($updateLastUpdate) {
+ $this->setRefStatusLastUpdate(new \DateTimeImmutable('now'));
+ }
+
+ return $this;
+ }
+
+ public function setRefStatusLastUpdate(\DateTimeImmutable $refStatusLastUpdate): self
+ {
+ $this->refStatusLastUpdate = $refStatusLastUpdate;
+
+ return $this;
+ }
+
public function setSteps(?string $steps): self
{
- $this->steps = $steps;
+ $this->steps = (string) $steps;
return $this;
}
public function setStreet(?string $street): self
{
- if (null === $street) {
- $street = '';
- }
- $this->street = $street;
+ $this->street = (string) $street;
return $this;
}
@@ -567,6 +555,7 @@ class Address implements TrackCreationInterface, TrackUpdateInterface
* @param string $streetAddress1
*
* @return Address
+ * @deprecated
*/
public function setStreetAddress1($streetAddress1)
{
@@ -579,7 +568,7 @@ class Address implements TrackCreationInterface, TrackUpdateInterface
* Set streetAddress2 (legacy function).
*
* @param string $streetAddress2
- *
+ * @deprecated
* @return Address
*/
public function setStreetAddress2($streetAddress2)
@@ -591,10 +580,7 @@ class Address implements TrackCreationInterface, TrackUpdateInterface
public function setStreetNumber(?string $streetNumber): self
{
- if (null === $streetNumber) {
- $streetNumber = '';
- }
- $this->streetNumber = $streetNumber;
+ $this->streetNumber = (string) $streetNumber;
return $this;
}
@@ -641,7 +627,7 @@ class Address implements TrackCreationInterface, TrackUpdateInterface
return;
}
- if (empty($this->getStreetAddress1())) {
+ if ('' === $this->getStreet()) {
$context
->buildViolation('address.street1-should-be-set')
->atPath('streetAddress1')
diff --git a/src/Bundle/ChillMainBundle/Entity/AddressReference.php b/src/Bundle/ChillMainBundle/Entity/AddressReference.php
index 68cc32186..57421749f 100644
--- a/src/Bundle/ChillMainBundle/Entity/AddressReference.php
+++ b/src/Bundle/ChillMainBundle/Entity/AddressReference.php
@@ -55,13 +55,13 @@ class AddressReference
* @ORM\Column(type="integer")
* @groups({"read"})
*/
- private $id;
+ private ?int $id;
/**
- * @ORM\Column(type="string", length=255, nullable=true)
+ * @ORM\Column(type="text", nullable=false, options={"default": ""})
* @groups({"read"})
*/
- private $municipalityCode;
+ private string $municipalityCode = '';
/**
* A geospatial field storing the coordinates of the Address.
@@ -71,7 +71,7 @@ class AddressReference
* @ORM\Column(type="point")
* @groups({"read"})
*/
- private $point;
+ private ?Point $point = null;
/**
* @var PostalCode
@@ -79,31 +79,31 @@ class AddressReference
* @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\PostalCode")
* @groups({"read"})
*/
- private $postcode;
+ private ?PostalCode $postcode;
/**
- * @ORM\Column(type="string", length=255)
+ * @ORM\Column(type="text", nullable=false, options={"default": ""})
* @groups({"read"})
*/
- private $refId;
+ private string $refId = '';
/**
- * @ORM\Column(type="string", length=255, nullable=true)
+ * @ORM\Column(type="text", nullable=false, options={"default": ""})
* @groups({"read"})
*/
- private $source;
+ private string $source = '';
/**
- * @ORM\Column(type="string", length=255, nullable=true)
+ * @ORM\Column(type="text", nullable=false, options={"default": ""})
* @groups({"read"})
*/
- private $street;
+ private string $street = '';
/**
- * @ORM\Column(type="string", length=255, nullable=true)
+ * @ORM\Column(type="text", nullable=false, options={"default": ""})
* @groups({"read"})
*/
- private $streetNumber;
+ private string $streetNumber = '';
/**
* @ORM\Column(type="datetime_immutable", nullable=true)
@@ -126,7 +126,7 @@ class AddressReference
return $this->id;
}
- public function getMunicipalityCode(): ?string
+ public function getMunicipalityCode(): string
{
return $this->municipalityCode;
}
@@ -141,27 +141,27 @@ class AddressReference
*
* @return PostalCode
*/
- public function getPostcode()
+ public function getPostcode(): ?PostalCode
{
return $this->postcode;
}
- public function getRefId(): ?string
+ public function getRefId(): string
{
return $this->refId;
}
- public function getSource(): ?string
+ public function getSource(): string
{
return $this->source;
}
- public function getStreet(): ?string
+ public function getStreet(): string
{
return $this->street;
}
- public function getStreetNumber(): ?string
+ public function getStreetNumber(): string
{
return $this->streetNumber;
}
@@ -192,7 +192,7 @@ class AddressReference
public function setMunicipalityCode(?string $municipalityCode): self
{
- $this->municipalityCode = $municipalityCode;
+ $this->municipalityCode = (string) $municipalityCode;
return $this;
}
@@ -227,21 +227,21 @@ class AddressReference
public function setSource(?string $source): self
{
- $this->source = $source;
+ $this->source = (string) $source;
return $this;
}
public function setStreet(?string $street): self
{
- $this->street = $street;
+ $this->street = (string) $street;
return $this;
}
public function setStreetNumber(?string $streetNumber): self
{
- $this->streetNumber = $streetNumber;
+ $this->streetNumber = (string) $streetNumber;
return $this;
}
diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue
index 21ab5e3d0..41279771f 100644
--- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue
+++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue
@@ -59,7 +59,7 @@
v-bind:insideModal="false"
@pick-address="this.pickAddress"
ref="suggestAddress">
-
+
{{ $t('action.cancel') }}
@@ -73,7 +73,7 @@
-
+
@@ -133,7 +133,7 @@
v-bind:insideModal="false"
@getCities="getCities"
@getReferenceAddresses="getReferenceAddresses">
-
+
{{ $t('action.cancel') }}
@@ -152,7 +152,7 @@
-
+
@@ -206,7 +206,7 @@
v-bind:flag="this.flag"
v-bind:insideModal="false"
ref="dateAddress">
-
+
@@ -220,7 +220,7 @@
-
+
@@ -580,15 +580,15 @@ export default {
this.entity.selected.city = this.context.edit ? this.entity.address.postcode : {};
this.entity.selected.address = {};
- this.entity.selected.address.street = this.context.edit ? this.entity.address.street: null;
- this.entity.selected.address.streetNumber = this.context.edit ? this.entity.address.streetNumber: null;
- this.entity.selected.address.floor = this.context.edit ? this.entity.address.floor: null;
- this.entity.selected.address.corridor = this.context.edit ? this.entity.address.corridor: null;
- this.entity.selected.address.steps = this.context.edit ? this.entity.address.steps: null;
- this.entity.selected.address.flat = this.context.edit ? this.entity.address.flat: null;
- this.entity.selected.address.buildingName = this.context.edit ? this.entity.address.buildingName: null;
- this.entity.selected.address.distribution = this.context.edit ? this.entity.address.distribution: null;
- this.entity.selected.address.extra = this.context.edit ? this.entity.address.extra: null;
+ this.entity.selected.address.street = this.context.edit ? this.entity.address.street: '';
+ this.entity.selected.address.streetNumber = this.context.edit ? this.entity.address.streetNumber: '';
+ this.entity.selected.address.floor = this.context.edit ? this.entity.address.floor: '';
+ this.entity.selected.address.corridor = this.context.edit ? this.entity.address.corridor: '';
+ this.entity.selected.address.steps = this.context.edit ? this.entity.address.steps: '';
+ this.entity.selected.address.flat = this.context.edit ? this.entity.address.flat: '';
+ this.entity.selected.address.buildingName = this.context.edit ? this.entity.address.buildingName: '';
+ this.entity.selected.address.distribution = this.context.edit ? this.entity.address.distribution: '';
+ this.entity.selected.address.extra = this.context.edit ? this.entity.address.extra: '';
this.entity.selected.writeNew.address = this.context.edit && this.entity.address.addressReference === null && this.entity.address.street.length > 0
this.entity.selected.writeNew.postcode = false // NB: this used to be this.context.edit, but think it was erroneous;
diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/Entity/AddressRenderBox.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/Entity/AddressRenderBox.vue
index 2e88bc1cb..2352e394a 100644
--- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/Entity/AddressRenderBox.vue
+++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/Entity/AddressRenderBox.vue
@@ -13,15 +13,15 @@
-
{{ address.text }}
-
{{ address.postcode.code }} {{ address.postcode.name }}
-
{{ address.country.name.fr }}
diff --git a/src/Bundle/ChillMainBundle/Templating/Entity/AddressRender.php b/src/Bundle/ChillMainBundle/Templating/Entity/AddressRender.php
index 4db8abe9b..62362956b 100644
--- a/src/Bundle/ChillMainBundle/Templating/Entity/AddressRender.php
+++ b/src/Bundle/ChillMainBundle/Templating/Entity/AddressRender.php
@@ -60,9 +60,6 @@ class AddressRender implements ChillEntityRenderInterface
}
/**
- * @param Address addr
- * @param mixed $addr
- *
* @return string[]
*/
public function renderLines(Address $addr, bool $includeCityLine = true, bool $includeCountry = true): array
@@ -98,18 +95,18 @@ class AddressRender implements ChillEntityRenderInterface
}
}
- return array_values(array_filter($lines, static fn ($l) => null !== $l));
+ return array_values(array_filter($lines, static fn ($l) => '' !== (string) $l));
}
public function renderStreetLine(Address $addr): ?string
{
- if (null !== $addr->getStreet() && $addr->getStreet() !== '') {
+ if ('' !== $addr->getStreet()) {
$street = $addr->getStreet();
} else {
$street = '';
}
- if (null !== $addr->getStreetNumber() && $addr->getStreetNumber() !== '') {
+ if ('' !== $addr->getStreetNumber()) {
$streetNumber = $addr->getStreetNumber();
} else {
$streetNumber = '';
@@ -146,7 +143,7 @@ class AddressRender implements ChillEntityRenderInterface
private function renderBuildingLine(Address $addr): ?string
{
- if (null !== $addr->getBuildingName() && $addr->getBuildingName() !== '') {
+ if ($addr->getBuildingName() !== '') {
$building = $addr->getBuildingName();
} else {
$building = '';
@@ -172,7 +169,7 @@ class AddressRender implements ChillEntityRenderInterface
return $res;
}
- private function renderCityLine($addr): string
+ private function renderCityLine(Address $addr): string
{
if (null !== $addr->getPostcode()) {
$res = strtr('{postcode} {label}', [
@@ -180,11 +177,9 @@ class AddressRender implements ChillEntityRenderInterface
'{label}' => $addr->getPostcode()->getName(),
]);
- if (null !== $addr->getPostCode()->getCountry()->getCountryCode()) {
- if ($addr->getPostCode()->getCountry()->getCountryCode() === 'FR') {
- if ($addr->getDistribution()) {
- $res = $res . ' ' . $addr->getDistribution();
- }
+ if ($addr->getPostcode()->getCountry()->getCountryCode() === 'FR') {
+ if ('' !== $addr->getDistribution()) {
+ $res = $res . ' ' . $addr->getDistribution();
}
}
}
@@ -192,35 +187,35 @@ class AddressRender implements ChillEntityRenderInterface
return $res ?? '';
}
- private function renderCountryLine($addr): ?string
+ private function renderCountryLine(Address $addr): ?string
{
return $this->translatableStringHelper->localize(
- $addr->getPostCode()->getCountry()->getName()
+ $addr->getPostcode()->getCountry()->getName()
);
}
- private function renderDeliveryLine($addr): ?string
+ private function renderDeliveryLine(Address $addr): string
{
return $addr->getExtra();
}
- private function renderIntraBuildingLine($addr): ?string
+ private function renderIntraBuildingLine(Address $addr): ?string
{
$arr = [];
- if ($addr->getFlat()) {
+ if ('' !== $addr->getFlat()) {
$arr[] = 'appart ' . $addr->getFlat();
}
- if ($addr->getFloor()) {
+ if ('' !== $addr->getFloor()) {
$arr[] = 'ét ' . $addr->getFloor();
}
- if ($addr->getCorridor()) {
+ if ('' !== $addr->getCorridor()) {
$arr[] = 'coul ' . $addr->getCorridor();
}
- if ($addr->getSteps()) {
+ if ('' !== $addr->getSteps()) {
$arr[] = 'esc ' . $addr->getSteps();
}
diff --git a/src/Bundle/ChillMainBundle/Tests/Services/Import/AddressReferenceBaseImporterTest.php b/src/Bundle/ChillMainBundle/Tests/Services/Import/AddressReferenceBaseImporterTest.php
index 3c14020d5..2ef7f0143 100644
--- a/src/Bundle/ChillMainBundle/Tests/Services/Import/AddressReferenceBaseImporterTest.php
+++ b/src/Bundle/ChillMainBundle/Tests/Services/Import/AddressReferenceBaseImporterTest.php
@@ -99,7 +99,7 @@ final class AddressReferenceBaseImporterTest extends KernelTestCase
'abcc guessed fixed'
);
- $this->assertCount('1', $addresses);
+ $this->assertCount(1, $addresses);
$this->assertEquals('Rue test abccc guessed fixed', $addresses[0]->getStreet());
$this->assertEquals($previousAddressId, $addresses[0]->getId());
}
diff --git a/src/Bundle/ChillMainBundle/migrations/Version20230306145728.php b/src/Bundle/ChillMainBundle/migrations/Version20230306145728.php
new file mode 100644
index 000000000..a5e1ffa6f
--- /dev/null
+++ b/src/Bundle/ChillMainBundle/migrations/Version20230306145728.php
@@ -0,0 +1,109 @@
+addSql('ALTER TABLE chill_main_address ADD createdAt TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL');
+ $this->addSql('ALTER TABLE chill_main_address ADD updatedAt TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL');
+ $this->addSql('ALTER TABLE chill_main_address ADD createdBy_id INT DEFAULT NULL');
+ $this->addSql('ALTER TABLE chill_main_address ADD updatedBy_id INT DEFAULT NULL');
+ $this->addSql('ALTER TABLE chill_main_address ALTER street TYPE TEXT');
+ $this->addSql('UPDATE chill_main_address SET street=\'\' WHERE street IS NULL');
+ $this->addSql('ALTER TABLE chill_main_address ALTER street SET DEFAULT \'\'');
+ $this->addSql('ALTER TABLE chill_main_address ALTER streetnumber TYPE TEXT');
+ $this->addSql('UPDATE chill_main_address SET streetnumber=\'\' WHERE streetnumber IS NULL');
+ $this->addSql('ALTER TABLE chill_main_address ALTER streetnumber SET DEFAULT \'\'');
+ $this->addSql('ALTER TABLE chill_main_address ALTER floor SET DEFAULT \'\'');
+ $this->addSql('UPDATE chill_main_address SET floor=\'\' WHERE floor IS NULL');
+ $this->addSql('ALTER TABLE chill_main_address ALTER floor SET NOT NULL');
+ $this->addSql('ALTER TABLE chill_main_address ALTER corridor SET DEFAULT \'\'');
+ $this->addSql('UPDATE chill_main_address SET corridor=\'\' WHERE corridor IS NULL');
+ $this->addSql('ALTER TABLE chill_main_address ALTER corridor SET NOT NULL');
+ $this->addSql('ALTER TABLE chill_main_address ALTER steps SET DEFAULT \'\'');
+ $this->addSql('UPDATE chill_main_address SET steps=\'\' WHERE steps IS NULL');
+ $this->addSql('ALTER TABLE chill_main_address ALTER steps SET NOT NULL');
+ $this->addSql('ALTER TABLE chill_main_address ALTER buildingname TYPE TEXT');
+ $this->addSql('ALTER TABLE chill_main_address ALTER buildingname SET DEFAULT \'\'');
+ $this->addSql('UPDATE chill_main_address SET buildingname=\'\' WHERE buildingname IS NULL');
+ $this->addSql('ALTER TABLE chill_main_address ALTER buildingname SET NOT NULL');
+ $this->addSql('ALTER TABLE chill_main_address ALTER flat SET DEFAULT \'\'');
+ $this->addSql('UPDATE chill_main_address SET flat=\'\' WHERE flat IS NULL');
+ $this->addSql('ALTER TABLE chill_main_address ALTER flat SET NOT NULL');
+ $this->addSql('ALTER TABLE chill_main_address ALTER distribution TYPE TEXT');
+ $this->addSql('ALTER TABLE chill_main_address ALTER distribution SET DEFAULT \'\'');
+ $this->addSql('UPDATE chill_main_address SET distribution=\'\' WHERE distribution IS NULL');
+ $this->addSql('ALTER TABLE chill_main_address ALTER distribution SET NOT NULL');
+ $this->addSql('ALTER TABLE chill_main_address ALTER extra TYPE TEXT');
+ $this->addSql('ALTER TABLE chill_main_address ALTER extra SET DEFAULT \'\'');
+ $this->addSql('UPDATE chill_main_address SET extra=\'\' WHERE extra IS NULL');
+ $this->addSql('ALTER TABLE chill_main_address ALTER extra SET NOT NULL');
+ $this->addSql('UPDATE chill_main_address SET confidential=FALSE WHERE confidential IS NULL');
+ $this->addSql('ALTER TABLE chill_main_address ALTER confidential SET NOT NULL');
+ $this->addSql('ALTER TABLE chill_main_address ALTER refstatuslastupdate TYPE TIMESTAMP(0) WITHOUT TIME ZONE');
+ $this->addSql('COMMENT ON COLUMN chill_main_address.point IS \'(DC2Type:point)\'');
+ $this->addSql('COMMENT ON COLUMN chill_main_address.createdAt IS \'(DC2Type:datetime_immutable)\'');
+ $this->addSql('COMMENT ON COLUMN chill_main_address.updatedAt IS \'(DC2Type:datetime_immutable)\'');
+ $this->addSql('COMMENT ON COLUMN chill_main_address.refStatusLastUpdate IS \'(DC2Type:datetime_immutable)\'');
+ $this->addSql('ALTER TABLE chill_main_address ADD CONSTRAINT FK_165051F63174800F FOREIGN KEY (createdBy_id) REFERENCES users (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('ALTER TABLE chill_main_address ADD CONSTRAINT FK_165051F665FF1AEC FOREIGN KEY (updatedBy_id) REFERENCES users (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
+ $this->addSql('CREATE INDEX IDX_165051F63174800F ON chill_main_address (createdBy_id)');
+ $this->addSql('CREATE INDEX IDX_165051F665FF1AEC ON chill_main_address (updatedBy_id)');
+ $this->addSql('COMMENT ON COLUMN chill_main_address_reference.point IS \'(DC2Type:point)\'');
+
+ }
+
+ public function down(Schema $schema): void
+ {
+ $this->throwIrreversibleMigrationException('down method is not double-checked');
+
+ $this->addSql('ALTER TABLE chill_main_address DROP CONSTRAINT FK_165051F63174800F');
+ $this->addSql('ALTER TABLE chill_main_address DROP CONSTRAINT FK_165051F665FF1AEC');
+ $this->addSql('DROP INDEX IDX_165051F63174800F');
+ $this->addSql('DROP INDEX IDX_165051F665FF1AEC');
+ $this->addSql('ALTER TABLE chill_main_address ADD customs JSONB DEFAULT \'[]\'');
+ $this->addSql('ALTER TABLE chill_main_address DROP createdAt');
+ $this->addSql('ALTER TABLE chill_main_address DROP updatedAt');
+ $this->addSql('ALTER TABLE chill_main_address DROP createdBy_id');
+ $this->addSql('ALTER TABLE chill_main_address DROP updatedBy_id');
+ $this->addSql('ALTER TABLE chill_main_address ALTER buildingName TYPE VARCHAR(255)');
+ $this->addSql('ALTER TABLE chill_main_address ALTER buildingName DROP DEFAULT');
+ $this->addSql('ALTER TABLE chill_main_address ALTER buildingName DROP NOT NULL');
+ $this->addSql('ALTER TABLE chill_main_address ALTER confidential SET DEFAULT false');
+ $this->addSql('ALTER TABLE chill_main_address ALTER confidential DROP NOT NULL');
+ $this->addSql('ALTER TABLE chill_main_address ALTER corridor DROP DEFAULT');
+ $this->addSql('ALTER TABLE chill_main_address ALTER corridor DROP NOT NULL');
+ $this->addSql('ALTER TABLE chill_main_address ALTER distribution TYPE VARCHAR(255)');
+ $this->addSql('ALTER TABLE chill_main_address ALTER distribution DROP DEFAULT');
+ $this->addSql('ALTER TABLE chill_main_address ALTER distribution DROP NOT NULL');
+ $this->addSql('ALTER TABLE chill_main_address ALTER extra TYPE VARCHAR(255)');
+ $this->addSql('ALTER TABLE chill_main_address ALTER extra DROP DEFAULT');
+ $this->addSql('ALTER TABLE chill_main_address ALTER extra DROP NOT NULL');
+ $this->addSql('ALTER TABLE chill_main_address ALTER flat DROP DEFAULT');
+ $this->addSql('ALTER TABLE chill_main_address ALTER flat DROP NOT NULL');
+ $this->addSql('ALTER TABLE chill_main_address ALTER floor DROP DEFAULT');
+ $this->addSql('ALTER TABLE chill_main_address ALTER floor DROP NOT NULL');
+ $this->addSql('ALTER TABLE chill_main_address ALTER isNoAddress SET DEFAULT false');
+ $this->addSql('ALTER TABLE chill_main_address ALTER point TYPE VARCHAR(255)');
+ $this->addSql('ALTER TABLE chill_main_address ALTER refStatusLastUpdate TYPE TIMESTAMP(0) WITHOUT TIME ZONE');
+ $this->addSql('ALTER TABLE chill_main_address ALTER steps DROP DEFAULT');
+ $this->addSql('ALTER TABLE chill_main_address ALTER steps DROP NOT NULL');
+ $this->addSql('ALTER TABLE chill_main_address ALTER street TYPE VARCHAR(255)');
+ $this->addSql('ALTER TABLE chill_main_address ALTER street DROP DEFAULT');
+ $this->addSql('ALTER TABLE chill_main_address ALTER streetNumber TYPE VARCHAR(255)');
+ $this->addSql('ALTER TABLE chill_main_address ALTER streetNumber DROP DEFAULT');
+ $this->addSql('COMMENT ON COLUMN chill_main_address.refstatuslastupdate IS NULL');
+ }
+}
diff --git a/src/Bundle/ChillMainBundle/migrations/Version20230306151218.php b/src/Bundle/ChillMainBundle/migrations/Version20230306151218.php
new file mode 100644
index 000000000..d3d467bea
--- /dev/null
+++ b/src/Bundle/ChillMainBundle/migrations/Version20230306151218.php
@@ -0,0 +1,58 @@
+addSql('ALTER TABLE chill_main_address_reference ALTER refid TYPE TEXT');
+ $this->addSql('ALTER TABLE chill_main_address_reference ALTER refid SET DEFAULT \'\'');
+ $this->addSql('ALTER TABLE chill_main_address_reference ALTER street TYPE TEXT');
+ $this->addSql('ALTER TABLE chill_main_address_reference ALTER street SET DEFAULT \'\'');
+ $this->addSql('UPDATE chill_main_address_reference SET street = \'\' WHERE street IS NULL');
+ $this->addSql('ALTER TABLE chill_main_address_reference ALTER street SET NOT NULL');
+ $this->addSql('ALTER TABLE chill_main_address_reference ALTER streetnumber TYPE TEXT');
+ $this->addSql('ALTER TABLE chill_main_address_reference ALTER streetnumber SET DEFAULT \'\'');
+ $this->addSql('UPDATE chill_main_address_reference SET streetnumber = \'\' WHERE streetnumber IS NULL');
+ $this->addSql('ALTER TABLE chill_main_address_reference ALTER streetnumber SET NOT NULL');
+ $this->addSql('ALTER TABLE chill_main_address_reference ALTER municipalitycode TYPE TEXT');
+ $this->addSql('ALTER TABLE chill_main_address_reference ALTER municipalitycode SET DEFAULT \'\'');
+ $this->addSql('UPDATE chill_main_address_reference SET municipalitycode = \'\' WHERE municipalitycode IS NULL');
+ $this->addSql('ALTER TABLE chill_main_address_reference ALTER municipalitycode SET NOT NULL');
+ $this->addSql('ALTER TABLE chill_main_address_reference ALTER source TYPE TEXT');
+ $this->addSql('ALTER TABLE chill_main_address_reference ALTER source SET DEFAULT \'\'');
+ $this->addSql('UPDATE chill_main_address_reference SET source = \'\' WHERE source IS NULL');
+ $this->addSql('ALTER TABLE chill_main_address_reference ALTER source SET NOT NULL');
+ }
+
+ public function down(Schema $schema): void
+ {
+ $this->throwIrreversibleMigrationException('not double-checked');
+
+ $this->addSql('ALTER TABLE chill_main_address_reference ALTER municipalityCode TYPE VARCHAR(255)');
+ $this->addSql('ALTER TABLE chill_main_address_reference ALTER municipalityCode DROP DEFAULT');
+ $this->addSql('ALTER TABLE chill_main_address_reference ALTER municipalityCode DROP NOT NULL');
+ $this->addSql('ALTER TABLE chill_main_address_reference ALTER refId TYPE VARCHAR(255)');
+ $this->addSql('ALTER TABLE chill_main_address_reference ALTER refId DROP DEFAULT');
+ $this->addSql('ALTER TABLE chill_main_address_reference ALTER source TYPE VARCHAR(255)');
+ $this->addSql('ALTER TABLE chill_main_address_reference ALTER source DROP DEFAULT');
+ $this->addSql('ALTER TABLE chill_main_address_reference ALTER source DROP NOT NULL');
+ $this->addSql('ALTER TABLE chill_main_address_reference ALTER street TYPE VARCHAR(255)');
+ $this->addSql('ALTER TABLE chill_main_address_reference ALTER street DROP DEFAULT');
+ $this->addSql('ALTER TABLE chill_main_address_reference ALTER street DROP NOT NULL');
+ $this->addSql('ALTER TABLE chill_main_address_reference ALTER streetNumber TYPE VARCHAR(255)');
+ $this->addSql('ALTER TABLE chill_main_address_reference ALTER streetNumber DROP DEFAULT');
+ $this->addSql('ALTER TABLE chill_main_address_reference ALTER streetNumber DROP NOT NULL');
+ }
+}
From c56ae08faefaa02e5488dbc32d7fac40779a6baf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Tue, 7 Mar 2023 22:16:16 +0100
Subject: [PATCH 03/46] Feature: [address reference] write logic to match
existing addresses with updates
Feature: [address reference] match addresses with reference after import
fix sql query for address reference matcher
---
.../AddressReferenceBEFromBestAddress.php | 16 ++-
.../Import/AddressReferenceFromBano.php | 7 +-
.../Import/AddressToReferenceMatcher.php | 87 ++++++++++++
.../Import/AddressToReferenceMatcherTest.php | 127 ++++++++++++++++++
4 files changed, 232 insertions(+), 5 deletions(-)
create mode 100644 src/Bundle/ChillMainBundle/Service/Import/AddressToReferenceMatcher.php
create mode 100644 src/Bundle/ChillMainBundle/Tests/Services/Import/AddressToReferenceMatcherTest.php
diff --git a/src/Bundle/ChillMainBundle/Service/Import/AddressReferenceBEFromBestAddress.php b/src/Bundle/ChillMainBundle/Service/Import/AddressReferenceBEFromBestAddress.php
index 8dfc84bc3..88a9cb4c5 100644
--- a/src/Bundle/ChillMainBundle/Service/Import/AddressReferenceBEFromBestAddress.php
+++ b/src/Bundle/ChillMainBundle/Service/Import/AddressReferenceBEFromBestAddress.php
@@ -24,12 +24,18 @@ class AddressReferenceBEFromBestAddress
private AddressReferenceBaseImporter $baseImporter;
+ private AddressToReferenceMatcher $addressToReferenceMatcher;
+
private HttpClientInterface $client;
- public function __construct(HttpClientInterface $client, AddressReferenceBaseImporter $baseImporter)
- {
+ public function __construct(
+ HttpClientInterface $client,
+ AddressReferenceBaseImporter $baseImporter,
+ AddressToReferenceMatcher $addressToReferenceMatcher
+ ) {
$this->client = $client;
$this->baseImporter = $baseImporter;
+ $this->addressToReferenceMatcher = $addressToReferenceMatcher;
}
public function import(string $lang, array $lists): void
@@ -89,16 +95,18 @@ class AddressReferenceBEFromBestAddress
$record['municipality_objectid'],
$record['postal_info_objectid'],
$record['streetname'],
- $record['housenumber'] . $record['boxnumber'],
+ $record['housenumber'] .($record['boxnumber'] !== '' ? ' bte '. $record['boxnumber'] : ''),
'bestaddress.' . $list,
- (float) $record['X'],
(float) $record['Y'],
+ (float) $record['X'],
3812
);
}
$this->baseImporter->finalize();
+ $this->addressToReferenceMatcher->checkAddressesMatchingReferences();
+
gzclose($uncompressedStream);
}
}
diff --git a/src/Bundle/ChillMainBundle/Service/Import/AddressReferenceFromBano.php b/src/Bundle/ChillMainBundle/Service/Import/AddressReferenceFromBano.php
index 7a9659884..d02a846ec 100644
--- a/src/Bundle/ChillMainBundle/Service/Import/AddressReferenceFromBano.php
+++ b/src/Bundle/ChillMainBundle/Service/Import/AddressReferenceFromBano.php
@@ -22,12 +22,15 @@ class AddressReferenceFromBano
{
private AddressReferenceBaseImporter $baseImporter;
+ private AddressToReferenceMatcher $addressToReferenceMatcher;
+
private HttpClientInterface $client;
- public function __construct(HttpClientInterface $client, AddressReferenceBaseImporter $baseImporter)
+ public function __construct(HttpClientInterface $client, AddressReferenceBaseImporter $baseImporter, AddressToReferenceMatcher $addressToReferenceMatcher)
{
$this->client = $client;
$this->baseImporter = $baseImporter;
+ $this->addressToReferenceMatcher = $addressToReferenceMatcher;
}
public function import(string $departementNo): void
@@ -82,6 +85,8 @@ class AddressReferenceFromBano
$this->baseImporter->finalize();
+ $this->addressToReferenceMatcher->checkAddressesMatchingReferences();
+
fclose($file);
}
}
diff --git a/src/Bundle/ChillMainBundle/Service/Import/AddressToReferenceMatcher.php b/src/Bundle/ChillMainBundle/Service/Import/AddressToReferenceMatcher.php
new file mode 100644
index 000000000..de37cfc15
--- /dev/null
+++ b/src/Bundle/ChillMainBundle/Service/Import/AddressToReferenceMatcher.php
@@ -0,0 +1,87 @@
+= NOW())
+ -- only addresses that are marked matching or "to review", but before the update
+ AND
+ (a.refstatus LIKE '{{ matching }}'
+ OR (a.refstatus LIKE '{{ reviewed }}' AND a.refstatuslastupdate < ar.updatedat))
+ AND (
+ a.postcode_id != ar.postcode_id
+ OR a.street != ar.street
+ OR a.streetnumber != ar.streetnumber
+ OR ROUND(ST_X(a.point) * 1000000) <> ROUND(ST_X(ar.point) * 1000000)
+ OR ROUND(ST_Y(a.point) * 1000000) <> ROUND(ST_Y(ar.point) * 1000000)
+ )
+ SQL;
+
+ private const SQL_MARK_MATCHING_ADDRESSES_REVIEWED_OR_TO_REVIEW = <<= NOW())
+ AND a.refstatus IN ('{{ to_review }}', '{{ reviewed }}')
+ AND a.postcode_id = ar.postcode_id
+ AND a.street = ar.street
+ AND a.streetnumber = ar.streetnumber
+ AND ROUND(ST_X(a.point) * 1000000) = ROUND(ST_X(ar.point) * 1000000)
+ AND ROUND(ST_Y(a.point) * 1000000) = ROUND(ST_Y(ar.point) * 1000000)
+ SQL;
+
+ private const SUBSTITUTES = [
+ '{{ to_review }}' => Address::ADDR_REFERENCE_STATUS_TO_REVIEW,
+ '{{ matching }}' => Address::ADDR_REFERENCE_STATUS_MATCH,
+ '{{ reviewed }}' => Address::ADDR_REFERENCE_STATUS_REVIEWED
+ ];
+
+ public function __construct(Connection $connection, LoggerInterface $logger)
+ {
+ $this->connection = $connection;
+ $this->logger = $logger;
+ }
+
+ public function checkAddressesMatchingReferences(): void
+ {
+ $this->logger->notice(self::LOG_PREFIX.'Starting addresses matching');
+
+ $this->connection->transactional(function () {
+ $markedAsMatching = $this->connection->executeStatement(
+ strtr(self::SQL_MARK_MATCHING_ADDRESSES_REVIEWED_OR_TO_REVIEW, self::SUBSTITUTES)
+ );
+
+ $markedAsToReview = $this->connection->executeStatement(
+ strtr(self::SQL_MARK_TO_REVIEW_ADDRESS_UNMATCHING, self::SUBSTITUTES)
+ );
+
+ $this->logger->info(self::LOG_PREFIX.'Executed address matching', [
+ 'marked_as_matching' => $markedAsMatching,
+ 'marked_as_to_review' => $markedAsToReview,
+ ]);
+ });
+ }
+}
diff --git a/src/Bundle/ChillMainBundle/Tests/Services/Import/AddressToReferenceMatcherTest.php b/src/Bundle/ChillMainBundle/Tests/Services/Import/AddressToReferenceMatcherTest.php
new file mode 100644
index 000000000..ad2324012
--- /dev/null
+++ b/src/Bundle/ChillMainBundle/Tests/Services/Import/AddressToReferenceMatcherTest.php
@@ -0,0 +1,127 @@
+addressToReferenceMatcher = self::$container->get(AddressToReferenceMatcher::class);
+ $this->addressReferenceRepository = self::$container->get(AddressReferenceRepository::class);
+ $this->countryRepository = self::$container->get(CountryRepository::class);
+ $this->addressReferenceBaseImporter = self::$container->get(AddressReferenceBaseImporter::class);
+ $this->entityManager = self::$container->get(EntityManagerInterface::class);
+ }
+
+ public function testCheckAddressesMatchingReferences(): void
+ {
+ if (null === $belgium = $this->countryRepository->findOneBy(['countryCode' => 'BE'])) {
+ throw new \RuntimeException('Belgium not found');
+ }
+
+ $postalCode = (new PostalCode())
+ ->setName('test for matcher')
+ ->setPostalCodeSource('test for matcher')
+ ->setCode('78910')
+ ->setRefPostalCodeId($refPostalCodeId = '78910'.uniqid())
+ ->setCountry($belgium)
+ ;
+ $this->entityManager->persist($postalCode);
+ $this->entityManager->flush();
+
+ $this->addressReferenceBaseImporter->importAddress(
+ $refAddress = '010203_test'.uniqid(),
+ $refPostalCodeId,
+ '78910',
+ $street = 'Rue Poulet',
+ $streetNumber = '14',
+ 'test_matcher',
+ $lat = 50.0123456789,
+ $lon = 5.0123456789,
+ 4326
+ );
+ $this->addressReferenceBaseImporter->finalize();
+
+ if (null === $addressReference = $this->addressReferenceRepository->findOneBy(['refId' => $refAddress])) {
+ throw new \RuntimeException('address reference not created');
+ }
+
+ $address = Address::createFromAddressReference($addressReference);
+
+ $this->assertEquals('Rue Poulet', $address->getStreet());
+
+ $this->entityManager->persist($address);
+ $this->entityManager->flush();
+
+ // we update the address
+ $this->addressReferenceBaseImporter->importAddress(
+ $refAddress,
+ $refPostalCodeId,
+ '78910',
+ 'Rue Poulet aux amandes',
+ '14',
+ 'test_matcher',
+ 50.01234456789,
+ 5.0123456789,
+ 4326
+ );
+ $this->addressReferenceBaseImporter->finalize();
+
+ $this->entityManager->flush();
+
+ $this->addressToReferenceMatcher->checkAddressesMatchingReferences();
+
+ $this->entityManager->refresh($address);
+
+ $this->assertEquals('to_review', $address->getRefStatus());
+
+ // we update the address
+ $this->addressReferenceBaseImporter->importAddress(
+ $refAddress,
+ $refPostalCodeId,
+ '78910',
+ $street,
+ $streetNumber,
+ 'test_matcher',
+ $lat,
+ $lon,
+ 4326
+ );
+ $this->addressReferenceBaseImporter->finalize();
+
+ $this->addressToReferenceMatcher->checkAddressesMatchingReferences();
+
+ $this->entityManager->refresh($address);
+
+ $this->assertEquals('Rue Poulet', $address->getStreet());
+ $this->assertEquals('match', $address->getRefStatus());
+ }
+}
From b740a88ae3f00c380a380aa40f1a01c75b4bce7f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Tue, 14 Mar 2023 22:12:30 +0100
Subject: [PATCH 04/46] Feature: bootstrapping an app to show a modal for
address details and showing it inside twig address's render box
Feature: showing map and link to external map, and address details inside address details modal
Feature: AddressDetailsMap show a warning if the address is incomplete
---
package.json | 7 +-
.../Resources/public/lib/api/address.ts | 14 +++
.../public/module/address-details/index.ts | 25 +++++
.../ChillMainBundle/Resources/public/types.ts | 9 ++
.../Resources/public/vuejs/Address/api.js | 10 +-
.../AddressDetails/AddressDetailsButton.vue | 45 +++++++++
.../AddressDetails/AddressDetailsContent.vue | 22 +++++
.../AddressDetails/AddressModal.vue | 49 ++++++++++
.../Parts/AddressDetailsMap.vue | 91 +++++++++++++++++++
.../Resources/views/Entity/address.html.twig | 4 +
.../Resources/views/layout.html.twig | 2 +
.../Normalizer/AddressNormalizer.php | 4 +
.../Templating/Entity/AddressRender.php | 6 +-
.../Templating/Entity/AddressRenderTest.php | 1 +
.../ChillMainBundle/chill.webpack.config.js | 1 +
src/Bundle/import-png.d.ts | 4 +
16 files changed, 283 insertions(+), 11 deletions(-)
create mode 100644 src/Bundle/ChillMainBundle/Resources/public/lib/api/address.ts
create mode 100644 src/Bundle/ChillMainBundle/Resources/public/module/address-details/index.ts
create mode 100644 src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/AddressDetailsButton.vue
create mode 100644 src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/AddressDetailsContent.vue
create mode 100644 src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/AddressModal.vue
create mode 100644 src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/Parts/AddressDetailsMap.vue
create mode 100644 src/Bundle/import-png.d.ts
diff --git a/package.json b/package.json
index 17b02c63a..bb4889983 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
- "name": "chill",
- "version": "2.0.0",
- "devDependencies": {
+ "name": "chill",
+ "version": "2.0.0",
+ "devDependencies": {
"@alexlafroscia/yaml-merge": "^4.0.0",
"@apidevtools/swagger-cli": "^4.0.4",
"@babel/core": "^7.20.5",
@@ -41,6 +41,7 @@
"@fullcalendar/timegrid": "^5.11.0",
"@fullcalendar/vue3": "^5.11.1",
"@popperjs/core": "^2.9.2",
+ "@types/leaflet": "^1.9.3",
"dropzone": "^5.7.6",
"es6-promise": "^4.2.8",
"leaflet": "^1.7.1",
diff --git a/src/Bundle/ChillMainBundle/Resources/public/lib/api/address.ts b/src/Bundle/ChillMainBundle/Resources/public/lib/api/address.ts
new file mode 100644
index 000000000..d039daf12
--- /dev/null
+++ b/src/Bundle/ChillMainBundle/Resources/public/lib/api/address.ts
@@ -0,0 +1,14 @@
+import {Address} from "../../types";
+
+export const getAddressById = async (address_id: number): Promise =>
+{
+ const url = `/api/1.0/main/address/${address_id}.json`;
+
+ const response = await fetch(url);
+
+ if (response.ok) {
+ return response.json();
+ }
+
+ throw Error('Error with request resource response');
+};
diff --git a/src/Bundle/ChillMainBundle/Resources/public/module/address-details/index.ts b/src/Bundle/ChillMainBundle/Resources/public/module/address-details/index.ts
new file mode 100644
index 000000000..aa843bca8
--- /dev/null
+++ b/src/Bundle/ChillMainBundle/Resources/public/module/address-details/index.ts
@@ -0,0 +1,25 @@
+import AddressDetailsButton from "../../vuejs/_components/AddressDetails/AddressDetailsButton.vue";
+import {createApp} from "vue";
+import {createI18n} from "vue-i18n";
+import {_createI18n} from "../../vuejs/_js/i18n";
+
+const i18n = _createI18n({});
+
+document.querySelectorAll('span[data-address-details]').forEach((el) => {
+ const dataset = el.dataset as {
+ addressId: string
+ };
+
+ const app = createApp({
+ components: {AddressDetailsButton},
+ data() {
+ return {
+ addressId: Number.parseInt(dataset.addressId),
+ }
+ },
+ template: ' '
+ });
+
+ app.use(i18n);
+ app.mount(el);
+});
diff --git a/src/Bundle/ChillMainBundle/Resources/public/types.ts b/src/Bundle/ChillMainBundle/Resources/public/types.ts
index 9453c89b0..3deb1d229 100644
--- a/src/Bundle/ChillMainBundle/Resources/public/types.ts
+++ b/src/Bundle/ChillMainBundle/Resources/public/types.ts
@@ -70,6 +70,8 @@ export interface Country {
code: string;
}
+export type AddressRefStatus = 'match'|'to_review'|'reviewed';
+
export interface Address {
type: "address";
address_id: number;
@@ -90,6 +92,13 @@ export interface Address {
addressReference: AddressReference | null;
validFrom: DateTime;
validTo: DateTime | null;
+ point: Point | null;
+ refStatus: AddressRefStatus;
+ isNoAddress: boolean;
+}
+
+export interface AddressWithPoint extends Address {
+ point: Point
}
export interface AddressReference {
diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/api.js b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/api.js
index b1489bfb6..294ea9480 100644
--- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/api.js
+++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/api.js
@@ -1,3 +1,5 @@
+import {getAddressById} from 'ChillMainAssets/lib/api/address';
+
/**
* Endpoint chill_api_single_country__index
* method GET, get Country Object
@@ -188,13 +190,7 @@ const postPostalCode = (postalCode) => { //<--
* @returns {Promise} a promise containing a Address object
*/
const getAddress = (id) => {
- //console.log('<< get address');
- const url = `/api/1.0/main/address/${id}.json`;
- return fetch(url)
- .then(response => {
- if (response.ok) { return response.json(); }
- throw Error('Error with request resource response');
- });
+ return getAddressById(id);
};
export {
diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/AddressDetailsButton.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/AddressDetailsButton.vue
new file mode 100644
index 000000000..8b1f9d869
--- /dev/null
+++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/AddressDetailsButton.vue
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/AddressDetailsContent.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/AddressDetailsContent.vue
new file mode 100644
index 000000000..95378b543
--- /dev/null
+++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/AddressDetailsContent.vue
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/AddressModal.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/AddressModal.vue
new file mode 100644
index 000000000..154273a27
--- /dev/null
+++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/AddressModal.vue
@@ -0,0 +1,49 @@
+
+
+
+
+ Détails d'une adresse
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/Parts/AddressDetailsMap.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/Parts/AddressDetailsMap.vue
new file mode 100644
index 000000000..967b16d8c
--- /dev/null
+++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/Parts/AddressDetailsMap.vue
@@ -0,0 +1,91 @@
+
+
+ Cette adresse est incomplète. La position géographique est approximative.
+
+
+ Google Maps
+ OSM
+
+
+
+
+
diff --git a/src/Bundle/ChillMainBundle/Resources/views/Entity/address.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Entity/address.html.twig
index eef84b8a2..9ad2b0a12 100644
--- a/src/Bundle/ChillMainBundle/Resources/views/Entity/address.html.twig
+++ b/src/Bundle/ChillMainBundle/Resources/views/Entity/address.html.twig
@@ -69,6 +69,7 @@
{% endif %}
{{ _self.inline(address, options, streetLine, lines) }}
+
{%- endif -%}
@@ -78,6 +79,7 @@
{% endif %}
{{ _self.inline(address, options, streetLine, lines) }}
+
{%- endif -%}
@@ -102,6 +104,7 @@
{{ 'address.consider homeless'|trans }}
+
{% else %}
@@ -109,6 +112,7 @@
{% endif %}
{{ _self.raw(lines) }}
+
{% endif %}
{{ _self.validity(address, options) }}
diff --git a/src/Bundle/ChillMainBundle/Resources/views/layout.html.twig b/src/Bundle/ChillMainBundle/Resources/views/layout.html.twig
index 92454be35..8a64c9543 100644
--- a/src/Bundle/ChillMainBundle/Resources/views/layout.html.twig
+++ b/src/Bundle/ChillMainBundle/Resources/views/layout.html.twig
@@ -20,6 +20,7 @@
{{ encore_entry_link_tags('chill') }}
{{ encore_entry_link_tags('mod_blur') }}
{{ encore_entry_link_tags('vue_onthefly') }}
+ {{ encore_entry_link_tags('mod_address_details') }}
{% block css %}{% endblock %}
@@ -112,6 +113,7 @@
{{ encore_entry_script_tags('mod_blur') }}
{{ encore_entry_script_tags('chill') }}
{{ encore_entry_script_tags('vue_onthefly') }}
+ {{ encore_entry_script_tags('mod_address_details') }}
+
+
diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/Parts/AddressDetailsMap.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/Parts/AddressDetailsMap.vue
index 967b16d8c..35a2bbc33 100644
--- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/Parts/AddressDetailsMap.vue
+++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/Parts/AddressDetailsMap.vue
@@ -3,8 +3,7 @@
Cette adresse est incomplète. La position géographique est approximative.
- Google Maps
- OSM
+ Voir sur Google Maps OSM
-
diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/AddressDetailsContent.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/AddressDetailsContent.vue
index 5a9a97b46..d56ad303d 100644
--- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/AddressDetailsContent.vue
+++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/AddressDetailsContent.vue
@@ -1,5 +1,6 @@
+
@@ -9,6 +10,7 @@ import {Address} from "../../../types";
import AddressDetailsMap from "./Parts/AddressDetailsMap.vue";
import AddressRenderBox from "../Entity/AddressRenderBox.vue";
import AddressDetailsGeographicalLayers from "./Parts/AddressDetailsGeographicalLayers.vue";
+import AddressDetailsRefMatching from "./Parts/AddressDetailsRefMatching.vue";
interface AddressModalContentProps {
address: Address,
@@ -16,6 +18,15 @@ interface AddressModalContentProps {
const props = defineProps();
+const emit = defineEmits<{
+ (e: 'update-address', value: Address): void
+}>();
+
+const onUpdateAddress = (address: Address): void => {
+ console.log('from details content', address);
+ emit('update-address', address);
+}
+
diff --git a/src/Bundle/ChillMainBundle/Resources/views/Entity/address.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Entity/address.html.twig
index 9ad2b0a12..7592e9a9a 100644
--- a/src/Bundle/ChillMainBundle/Resources/views/Entity/address.html.twig
+++ b/src/Bundle/ChillMainBundle/Resources/views/Entity/address.html.twig
@@ -69,7 +69,7 @@
{% endif %}
{{ _self.inline(address, options, streetLine, lines) }}
-
+
{%- endif -%}
@@ -79,7 +79,7 @@
{% endif %}
{{ _self.inline(address, options, streetLine, lines) }}
-
+
{%- endif -%}
@@ -104,7 +104,7 @@
{{ 'address.consider homeless'|trans }}
-
+
{% else %}
@@ -112,7 +112,7 @@
{% endif %}
{{ _self.raw(lines) }}
-
+
{% endif %}
{{ _self.validity(address, options) }}
diff --git a/src/Bundle/ChillMainBundle/Tests/Controller/AddressToReferenceMatcherControllerTest.php b/src/Bundle/ChillMainBundle/Tests/Controller/AddressToReferenceMatcherControllerTest.php
new file mode 100644
index 000000000..5c51910dc
--- /dev/null
+++ b/src/Bundle/ChillMainBundle/Tests/Controller/AddressToReferenceMatcherControllerTest.php
@@ -0,0 +1,114 @@
+addressRepository = self::$container->get(AddressRepository::class);
+ }
+
+ /**
+ * @dataProvider addressToReviewProvider
+ */
+ public function testMarkAddressAsReviewed(int $addressId): void
+ {
+ $client = $this->getClientAuthenticated();
+
+ $client->request('POST', "/api/1.0/main/address/reference-match/${addressId}/set/reviewed");
+
+ $this->assertResponseIsSuccessful();
+
+ $address = $this->addressRepository->find($addressId);
+
+ $this->assertEquals(Address::ADDR_REFERENCE_STATUS_REVIEWED, $address->getRefStatus());
+ }
+
+ /**
+ * @dataProvider addressUnsyncedProvider
+ */
+ public function testSyncAddressWithReference(int $addressId): void
+ {
+ $client = $this->getClientAuthenticated();
+
+ $client->request('POST', "/api/1.0/main/address/reference-match/${addressId}/sync-with-reference");
+
+ $this->assertResponseIsSuccessful();
+
+ $address = $this->addressRepository->find($addressId);
+
+ $this->assertEquals(Address::ADDR_REFERENCE_STATUS_MATCH, $address->getRefStatus());
+ $this->assertEquals($address->getAddressReference()->getStreet(), $address->getStreet());
+ $this->assertEquals($address->getAddressReference()->getStreetNumber(), $address->getStreetNumber());
+ $this->assertEquals($address->getAddressReference()->getPoint()->toWKT(), $address->getPoint()->toWKT());
+ }
+
+ public static function addressToReviewProvider(): iterable
+ {
+ self::bootKernel();
+ $em = self::$container->get(EntityManagerInterface::class);
+
+ $nb = $em->createQuery('SELECT count(a) FROM '.Address::class.' a')
+ ->getSingleScalarResult();
+
+ if (0 === $nb) {
+ throw new \RuntimeException("There aren't any address with a ref status 'matched'");
+ }
+
+ /** @var Address $address */
+ $address = $em->createQuery('SELECT a FROM '.Address::class.' a')
+ ->setFirstResult(rand(0, $nb))
+ ->setMaxResults(1)
+ ->getSingleResult();
+
+ $address->setRefStatus(Address::ADDR_REFERENCE_STATUS_TO_REVIEW);
+ $em->flush();
+
+ yield [$address->getId()];
+ }
+
+ public static function addressUnsyncedProvider(): iterable
+ {
+ self::bootKernel();
+ $em = self::$container->get(EntityManagerInterface::class);
+
+ $nb = $em->createQuery('SELECT count(a) FROM '.AddressReference::class.' a')
+ ->getSingleScalarResult();
+
+ if (0 === $nb) {
+ throw new \RuntimeException("There isn't any address reference");
+ }
+
+ $ref = $em->createQuery('SELECT a FROM '.AddressReference::class.' a')
+ ->setMaxResults(1)
+ ->setFirstResult(rand(0, $nb))
+ ->getSingleResult();
+
+ $address = Address::createFromAddressReference($ref);
+
+ // make the address dirty
+ $address->setStreet('tagada')
+ ->setStreetNumber('-250')
+ ->setPoint(Point::fromLonLat(0, 0))
+ ->setRefStatus(Address::ADDR_REFERENCE_STATUS_TO_REVIEW);
+
+ $em->persist($address);
+ $em->flush();
+
+ yield [$address->getId()];
+ }
+}
From f256dda6fe69c642fff13f5af689d686dcda46e7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Mon, 20 Mar 2023 18:27:18 +0100
Subject: [PATCH 08/46] Feature: [address] apply details button on
address-render-box
---
.../AddressToReferenceMatcherController.php | 27 +++++++++++++++++++
.../Resources/public/lib/api/address.ts | 4 +++
.../public/module/address-details/index.ts | 4 +++
.../AddressDetails/AddressDetailsButton.vue | 1 -
.../AddressDetails/AddressDetailsContent.vue | 3 +--
.../AddressDetails/AddressModal.vue | 1 -
.../Parts/AddressDetailsMap.vue | 3 ++-
.../Parts/AddressDetailsRefMatching.vue | 18 +++++++++----
.../_components/Entity/AddressRenderBox.vue | 12 +++++++--
.../_components/Entity/PersonRenderBox.vue | 1 +
10 files changed, 62 insertions(+), 12 deletions(-)
diff --git a/src/Bundle/ChillMainBundle/Controller/AddressToReferenceMatcherController.php b/src/Bundle/ChillMainBundle/Controller/AddressToReferenceMatcherController.php
index a601df13d..7e0debe4d 100644
--- a/src/Bundle/ChillMainBundle/Controller/AddressToReferenceMatcherController.php
+++ b/src/Bundle/ChillMainBundle/Controller/AddressToReferenceMatcherController.php
@@ -51,6 +51,33 @@ class AddressToReferenceMatcherController
);
}
+ /**
+ * Set an address back to "to review". Only if the address is in "reviewed" state.
+ *
+ * @Route("/api/1.0/main/address/reference-match/{id}/set/to_review", methods={"POST"})
+ */
+ public function markAddressAsToReview(Address $address): JsonResponse
+ {
+ if (!$this->security->isGranted('ROLE_USER')) {
+ throw new AccessDeniedHttpException();
+ }
+
+ if (Address::ADDR_REFERENCE_STATUS_REVIEWED !== $address->getRefStatus()) {
+ throw new AccessDeniedHttpException("forbidden to mark a matching address to 'to review'");
+ }
+
+ $address->setRefStatus(Address::ADDR_REFERENCE_STATUS_TO_REVIEW);
+
+ $this->entityManager->flush();
+
+ return new JsonResponse(
+ $this->serializer->serialize($address, 'json', [AbstractNormalizer::GROUPS => ['read']]),
+ JsonResponse::HTTP_OK,
+ [],
+ true
+ );
+ }
+
/**
* @Route("/api/1.0/main/address/reference-match/{id}/sync-with-reference", methods={"POST"})
*/
diff --git a/src/Bundle/ChillMainBundle/Resources/public/lib/api/address.ts b/src/Bundle/ChillMainBundle/Resources/public/lib/api/address.ts
index 66e90a194..1499f4a6a 100644
--- a/src/Bundle/ChillMainBundle/Resources/public/lib/api/address.ts
+++ b/src/Bundle/ChillMainBundle/Resources/public/lib/api/address.ts
@@ -29,3 +29,7 @@ export const syncAddressWithReference = async (address: Address): Promise => {
return makeFetch("POST", `/api/1.0/main/address/reference-match/${address.address_id}/set/reviewed`);
}
+
+export const markAddressToReview = async (address: Address): Promise => {
+ return makeFetch("POST", `/api/1.0/main/address/reference-match/${address.address_id}/set/to_review`);
+}
diff --git a/src/Bundle/ChillMainBundle/Resources/public/module/address-details/index.ts b/src/Bundle/ChillMainBundle/Resources/public/module/address-details/index.ts
index 4f74c6205..9bc2409ee 100644
--- a/src/Bundle/ChillMainBundle/Resources/public/module/address-details/index.ts
+++ b/src/Bundle/ChillMainBundle/Resources/public/module/address-details/index.ts
@@ -23,6 +23,10 @@ document.querySelectorAll('span[data-address-details]').forEach
template: ' ',
methods: {
onUpdateAddress: (address: Address): void => {
+ if (address.refStatus === 'to_review' || address.refStatus === 'reviewed') {
+ // in this two case, the address content do not change
+ return;
+ }
if (window.confirm("L'adresse a été modifiée. Vous pouvez continuer votre travail. Cependant, pour afficher les données immédiatement, veuillez recharger la page. \n\n Voulez-vous recharger la page immédiatement ?")) {
window.location.reload();
}
diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/AddressDetailsButton.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/AddressDetailsButton.vue
index b34b1a374..7e060de4c 100644
--- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/AddressDetailsButton.vue
+++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/AddressDetailsButton.vue
@@ -53,7 +53,6 @@ async function clickOrOpen(): Promise {
}
const onUpdateAddress = (address: Address): void => {
- console.log('from details button', address);
data.working_address = address;
data.working_ref_status = address.refStatus;
emit('update-address', address);
diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/AddressDetailsContent.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/AddressDetailsContent.vue
index d56ad303d..3f6495b0a 100644
--- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/AddressDetailsContent.vue
+++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/AddressDetailsContent.vue
@@ -1,5 +1,5 @@
-
+
@@ -23,7 +23,6 @@ const emit = defineEmits<{
}>();
const onUpdateAddress = (address: Address): void => {
- console.log('from details content', address);
emit('update-address', address);
}
diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/AddressModal.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/AddressModal.vue
index d5f69d4ae..6b341d861 100644
--- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/AddressModal.vue
+++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/AddressModal.vue
@@ -42,7 +42,6 @@ const close = (): void => {
}
const onUpdateAddress = (address: Address): void => {
- console.log('from details modal', address);
emit('update-address', address);
}
diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/Parts/AddressDetailsMap.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/Parts/AddressDetailsMap.vue
index 35a2bbc33..fd652a5f9 100644
--- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/Parts/AddressDetailsMap.vue
+++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/Parts/AddressDetailsMap.vue
@@ -29,7 +29,8 @@ let marker: L.Marker|null = null;
onMounted(() => {
if (map_div.value === null) {
- throw new Error('map div not found');
+ // there is no map div when the address does not have any Point
+ return;
}
if (props.address.point !== null) {
diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/Parts/AddressDetailsRefMatching.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/Parts/AddressDetailsRefMatching.vue
index 5b1454ab7..cbeb9e9e9 100644
--- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/Parts/AddressDetailsRefMatching.vue
+++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/Parts/AddressDetailsRefMatching.vue
@@ -1,7 +1,8 @@
-
-
L'adresse de référence a été modifiée.
+
+
L'adresse de référence a été modifiée.
+
L'adresse est conservée, mais diffère de l'adresse de référence.
@@ -33,8 +34,9 @@
- Appliquer les modifications
- Conserver
+ Appliquer les modifications
+ Conserver
+ Ré-examiner
@@ -43,7 +45,7 @@
diff --git a/src/Bundle/ChillThirdPartyBundle/Resources/public/vuejs/_components/Entity/ThirdPartyRenderBox.vue b/src/Bundle/ChillThirdPartyBundle/Resources/public/vuejs/_components/Entity/ThirdPartyRenderBox.vue
index 49066a082..0a3831df7 100644
--- a/src/Bundle/ChillThirdPartyBundle/Resources/public/vuejs/_components/Entity/ThirdPartyRenderBox.vue
+++ b/src/Bundle/ChillThirdPartyBundle/Resources/public/vuejs/_components/Entity/ThirdPartyRenderBox.vue
@@ -1,100 +1,100 @@
-
+
-
@@ -104,75 +104,78 @@ import Confidential from 'ChillMainAssets/vuejs/_components/Confidential.vue';
import BadgeEntity from 'ChillMainAssets/vuejs/_components/BadgeEntity.vue';
export default {
- name: "ThirdPartyRenderBox",
- components: {
- AddressRenderBox,
- Confidential,
- BadgeEntity,
- },
- // To avoid components recursively invoking eachother resolve OnTheFly component here
- beforeCreate() {
- this.$options.components.OnTheFly = require('ChillMainAssets/vuejs/OnTheFly/components/OnTheFly').default;
- },
- i18n: {
- messages: {
- fr: {
- children: "Personnes de contact: ",
- child_of: "Contact de: ",
- }}
- },
- props: ['thirdparty', 'options'],
- computed: {
- isMultiline: function() {
- if (this.options.isMultiline){
- return this.options.isMultiline
- } else {
- return false
- }
- },
- hasParent() {
- return !(this.thirdparty.parent === null || this.thirdparty.parent === undefined);
- },
- getProfession() {
- let profession = []
- if (this.hasParent && this.thirdparty.profession) {
- profession.push(this.thirdparty.profession)
- return profession;
- }
-
- if (!this.hasParent && this.thirdparty.category) {
- profession = this.thirdparty.category.map((category) => category.text);
- }
-
- return profession;
- }
- /* TODO need backend normalizer to serve children without circular reference
- hasChildren() {
- //console.log(this.thirdparty.activeChildren.length > 0)
- return false
- } */
+ name: "ThirdPartyRenderBox",
+ components: {
+ AddressRenderBox,
+ Confidential,
+ BadgeEntity,
+ },
+ // To avoid components recursively invoking eachother resolve OnTheFly component here
+ beforeCreate() {
+ this.$options.components.OnTheFly = require('ChillMainAssets/vuejs/OnTheFly/components/OnTheFly').default;
+ },
+ i18n: {
+ messages: {
+ fr: {
+ children: "Personnes de contact: ",
+ child_of: "Contact de: ",
+ }
}
+ },
+ props: ['thirdparty', 'options'],
+ computed: {
+ isMultiline: function () {
+ if (this.options.isMultiline) {
+ return this.options.isMultiline
+ } else {
+ return false
+ }
+ },
+ hasParent() {
+ return !(this.thirdparty.parent === null || this.thirdparty.parent === undefined);
+ },
+ getProfession() {
+ let profession = []
+ if (this.hasParent && this.thirdparty.profession) {
+ profession.push(this.thirdparty.profession)
+ return profession;
+ }
+
+ if (!this.hasParent && this.thirdparty.category) {
+ profession = this.thirdparty.category.map((category) => category.text);
+ }
+
+ return profession;
+ }
+ /* TODO need backend normalizer to serve children without circular reference
+ hasChildren() {
+ //console.log(this.thirdparty.activeChildren.length > 0)
+ return false
+ } */
+ }
}
From 99cdf0ebaf8beeca1362277cbb909f8f38c340e5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Wed, 22 Mar 2023 11:05:52 +0100
Subject: [PATCH 11/46] Feature: [update accompanying course] do not show
"locate to person" button if the person is already locating the course
---
.../components/PersonsAssociated/ParticipationItem.vue | 7 +++++--
.../public/vuejs/AccompanyingCourse/store/index.js | 7 +++++++
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/PersonsAssociated/ParticipationItem.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/PersonsAssociated/ParticipationItem.vue
index 5bd7551d5..155fd6c46 100644
--- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/PersonsAssociated/ParticipationItem.vue
+++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/PersonsAssociated/ParticipationItem.vue
@@ -19,7 +19,7 @@
@@ -109,9 +109,12 @@ export default {
},
getCurrentHouseholdUrl() {
return `/fr/person/household/${this.participation.person.current_household_id}/summary?returnPath=${this.getAccompanyingCourseReturnPath}`
- }
+ },
},
methods: {
+ isPersonLocatingCourse(person) {
+ return this.$store.getters.isPersonLocatingCourse(person);
+ },
saveFormOnTheFly(payload) {
console.log('saveFormOnTheFly: type', payload.type, ', data', payload.data);
payload.target = 'participation';
diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/store/index.js b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/store/index.js
index c2ded503b..0b7b78420 100644
--- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/store/index.js
+++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/store/index.js
@@ -49,6 +49,13 @@ let initPromise = (root) => Promise.all([getScopesPromise(root), accompanyingCou
postFirstPinnedCommentResponse: null,
},
getters: {
+ isPersonLocatingCourse: (state) => (person) => {
+ if (state.accompanyingCourse.locationStatus !== 'person') {
+ return false;
+ }
+
+ return state.accompanyingCourse.personLocation.id === person.id;
+ },
isParticipationValid(state) {
return state.accompanyingCourse.participations.length > 0;
},
From 48772efd548a6fbcfbbba967608c2bccee6e53b5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Tue, 28 Mar 2023 22:32:08 +0200
Subject: [PATCH 12/46] DX: fix phpstan issues
---
phpstan.neon.dist | 2 +-
.../Filter/ACPFilters/LocationFilter.php | 7 -
.../src/Export/Export/ListAsideActivity.php | 6 +-
.../Controller/ElementController.php | 12 -
.../Repository/ChargeKindRepository.php | 8 +-
.../ChargeKindRepositoryInterface.php | 12 +-
.../Repository/ResourceKindRepository.php | 8 +-
.../ResourceKindRepositoryInterface.php | 12 +-
.../Controller/CalendarController.php | 15 -
.../ChillCalendarBundle/Entity/Calendar.php | 5 +-
.../Export/Export/CountCalendars.php | 2 +-
.../Doctrine/Type/NativeDateIntervalType.php | 3 -
.../Export/ExportInterface.php | 8 +-
.../DataMapper/ExportPickCenterDataMapper.php | 24 +-
.../EntityWorkflowHandlerInterface.php | 1 +
.../Command/ImportPeopleFromCSVCommand.php | 1183 -----------------
.../Controller/HouseholdController.php | 2 +-
.../Entity/AccompanyingPeriod.php | 18 +-
.../Entity/Household/Household.php | 13 +-
.../Form/Type/PickPersonDynamicType.php | 8 +-
.../AccompanyingPeriodContext.php | 5 +-
.../AccompanyingPeriodWorkWorkflowHandler.php | 4 +-
.../Export/Export/ReportList.php | 2 +-
.../DataFixtures/ORM/LoadThirdParty.php | 16 -
.../Entity/ThirdParty.php | 5 +-
.../src/Controller/Convert.php | 2 +-
tests/app | 2 +-
27 files changed, 76 insertions(+), 1309 deletions(-)
delete mode 100644 src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php
diff --git a/phpstan.neon.dist b/phpstan.neon.dist
index 611f6d71e..56b7c2228 100644
--- a/phpstan.neon.dist
+++ b/phpstan.neon.dist
@@ -3,7 +3,7 @@ parameters:
paths:
- src/
tmpDir: .cache/
- reportUnmatchedIgnoredErrors: true
+ reportUnmatchedIgnoredErrors: false
excludePaths:
- .php_cs*
- docs/
diff --git a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/LocationFilter.php b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/LocationFilter.php
index 5cdce5b31..3d69d1633 100644
--- a/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/LocationFilter.php
+++ b/src/Bundle/ChillActivityBundle/Export/Filter/ACPFilters/LocationFilter.php
@@ -20,13 +20,6 @@ use Symfony\Component\Form\FormBuilderInterface;
class LocationFilter implements FilterInterface
{
- private TranslatableStringHelper $translatableStringHelper;
-
- public function __construct(TranslatableStringHelper $translatableStringHelper)
- {
- $this->translatableStringHelper = $translatableStringHelper;
- }
-
public function addRole(): ?string
{
return null;
diff --git a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/ListAsideActivity.php b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/ListAsideActivity.php
index 976f4171c..aee168174 100644
--- a/src/Bundle/ChillAsideActivityBundle/src/Export/Export/ListAsideActivity.php
+++ b/src/Bundle/ChillAsideActivityBundle/src/Export/Export/ListAsideActivity.php
@@ -160,8 +160,8 @@ final class ListAsideActivity implements ListInterface, GroupedExportInterface
return 'export.aside_activity.main_center';
}
- /** @var Center $c */
if (null === $value || '' === $value || null === $c = $this->centerRepository->find($value)) {
+ /** @var Center $c */
return '';
}
@@ -190,10 +190,6 @@ final class ListAsideActivity implements ListInterface, GroupedExportInterface
];
}
- /**
- * @param QueryBuilder $query
- * @param array $data
- */
public function getResult($query, $data): array
{
return $query->getQuery()->getResult(AbstractQuery::HYDRATE_ARRAY);
diff --git a/src/Bundle/ChillBudgetBundle/Controller/ElementController.php b/src/Bundle/ChillBudgetBundle/Controller/ElementController.php
index 70730e5c9..b5db3cd30 100644
--- a/src/Bundle/ChillBudgetBundle/Controller/ElementController.php
+++ b/src/Bundle/ChillBudgetBundle/Controller/ElementController.php
@@ -33,27 +33,15 @@ class ElementController extends AbstractController
{
private CalculatorManager $calculator;
- private LoggerInterface $chillMainLogger;
-
- private EntityManagerInterface $em;
-
private ResourceRepository $resourceRepository;
private ChargeRepository $chargeRepository;
- private TranslatorInterface $translator;
-
public function __construct(
- EntityManagerInterface $em,
- TranslatorInterface $translator,
- LoggerInterface $chillMainLogger,
CalculatorManager $calculator,
ResourceRepository $resourceRepository,
ChargeRepository $chargeRepository,
) {
- $this->em = $em;
- $this->translator = $translator;
- $this->chillMainLogger = $chillMainLogger;
$this->calculator = $calculator;
$this->resourceRepository = $resourceRepository;
$this->chargeRepository = $chargeRepository;
diff --git a/src/Bundle/ChillBudgetBundle/Repository/ChargeKindRepository.php b/src/Bundle/ChillBudgetBundle/Repository/ChargeKindRepository.php
index 01f5cd737..9aaf68ddf 100644
--- a/src/Bundle/ChillBudgetBundle/Repository/ChargeKindRepository.php
+++ b/src/Bundle/ChillBudgetBundle/Repository/ChargeKindRepository.php
@@ -30,7 +30,7 @@ final class ChargeKindRepository implements ChargeKindRepositoryInterface
}
/**
- * @return ChargeType[]
+ * @return array
*/
public function findAll(): array
{
@@ -38,7 +38,7 @@ final class ChargeKindRepository implements ChargeKindRepositoryInterface
}
/**
- * @return ChargeType[]
+ * @return array
*/
public function findAllActive(): array
{
@@ -53,7 +53,7 @@ final class ChargeKindRepository implements ChargeKindRepositoryInterface
}
/**
- * @return ChargeType[]
+ * @return array
*/
public function findAllByType(string $type): array
{
@@ -64,7 +64,7 @@ final class ChargeKindRepository implements ChargeKindRepositoryInterface
* @param mixed|null $limit
* @param mixed|null $offset
*
- * @return ChargeType[]
+ * @return array
*/
public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array
{
diff --git a/src/Bundle/ChillBudgetBundle/Repository/ChargeKindRepositoryInterface.php b/src/Bundle/ChillBudgetBundle/Repository/ChargeKindRepositoryInterface.php
index fb8c9dc35..f92851eba 100644
--- a/src/Bundle/ChillBudgetBundle/Repository/ChargeKindRepositoryInterface.php
+++ b/src/Bundle/ChillBudgetBundle/Repository/ChargeKindRepositoryInterface.php
@@ -19,25 +19,25 @@ interface ChargeKindRepositoryInterface extends ObjectRepository
public function find($id): ?ChargeKind;
/**
- * @return ChargeType[]
+ * @return array
*/
public function findAll(): array;
/**
- * @return ChargeType[]
+ * @return array
*/
public function findAllActive(): array;
/**
- * @return ChargeType[]
+ * @return array
*/
public function findAllByType(string $type): array;
/**
- * @param mixed|null $limit
- * @param mixed|null $offset
+ * @param int|null $limit
+ * @param int|null $offset
*
- * @return ChargeType[]
+ * @return array
*/
public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array;
diff --git a/src/Bundle/ChillBudgetBundle/Repository/ResourceKindRepository.php b/src/Bundle/ChillBudgetBundle/Repository/ResourceKindRepository.php
index 42e5418fc..1f9f99753 100644
--- a/src/Bundle/ChillBudgetBundle/Repository/ResourceKindRepository.php
+++ b/src/Bundle/ChillBudgetBundle/Repository/ResourceKindRepository.php
@@ -30,7 +30,7 @@ final class ResourceKindRepository implements ResourceKindRepositoryInterface
}
/**
- * @return ResourceType[]
+ * @return list
*/
public function findAll(): array
{
@@ -38,7 +38,7 @@ final class ResourceKindRepository implements ResourceKindRepositoryInterface
}
/**
- * @return ResourceType[]
+ * @return list
*/
public function findAllActive(): array
{
@@ -58,7 +58,7 @@ final class ResourceKindRepository implements ResourceKindRepositoryInterface
}
/**
- * @return ResourceType[]
+ * @return list
*/
public function findAllByType(string $type): array
{
@@ -69,7 +69,7 @@ final class ResourceKindRepository implements ResourceKindRepositoryInterface
* @param mixed|null $limit
* @param mixed|null $offset
*
- * @return ResourceType[]
+ * @return list
*/
public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array
{
diff --git a/src/Bundle/ChillBudgetBundle/Repository/ResourceKindRepositoryInterface.php b/src/Bundle/ChillBudgetBundle/Repository/ResourceKindRepositoryInterface.php
index 658a87a3d..dac46ff35 100644
--- a/src/Bundle/ChillBudgetBundle/Repository/ResourceKindRepositoryInterface.php
+++ b/src/Bundle/ChillBudgetBundle/Repository/ResourceKindRepositoryInterface.php
@@ -19,25 +19,25 @@ interface ResourceKindRepositoryInterface extends ObjectRepository
public function find($id): ?ResourceKind;
/**
- * @return ResourceType[]
+ * @return list
*/
public function findAll(): array;
/**
- * @return ResourceType[]
+ * @return list
*/
public function findAllActive(): array;
/**
- * @return ResourceType[]
+ * @return list
*/
public function findAllByType(string $type): array;
/**
- * @param mixed|null $limit
- * @param mixed|null $offset
+ * @param int|null $limit
+ * @param int|null $offset
*
- * @return ResourceType[]
+ * @return list
*/
public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array;
diff --git a/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php b/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php
index 550c6e984..47883702f 100644
--- a/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php
+++ b/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php
@@ -544,21 +544,6 @@ class CalendarController extends AbstractController
return $filterOrder->build();
}
- private function buildParamsToUrl(?User $user, ?AccompanyingPeriod $accompanyingPeriod): array
- {
- $params = [];
-
- if (null !== $user) {
- $params['user_id'] = $user->getId();
- }
-
- if (null !== $accompanyingPeriod) {
- $params['id'] = $accompanyingPeriod->getId();
- }
-
- return $params;
- }
-
/**
* Creates a form to delete a Calendar entity by id.
*/
diff --git a/src/Bundle/ChillCalendarBundle/Entity/Calendar.php b/src/Bundle/ChillCalendarBundle/Entity/Calendar.php
index 56373ca17..66e6a6d69 100644
--- a/src/Bundle/ChillCalendarBundle/Entity/Calendar.php
+++ b/src/Bundle/ChillCalendarBundle/Entity/Calendar.php
@@ -29,6 +29,7 @@ use DateTimeImmutable;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria;
+use Doctrine\Common\Collections\ReadableCollection;
use Doctrine\ORM\Mapping as ORM;
use LogicException;
use Symfony\Component\Serializer\Annotation as Serializer;
@@ -507,10 +508,10 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface, HasCente
}
/**
- * @return Collection|User[]
+ * @return ReadableCollection<(int|string), User>
* @Serializer\Groups({"calendar:read", "read"})
*/
- public function getUsers(): Collection
+ public function getUsers(): ReadableCollection
{
return $this->getInvites()->map(static function (Invite $i) {
return $i->getUser();
diff --git a/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php b/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php
index 06d6defca..f3bf79547 100644
--- a/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php
+++ b/src/Bundle/ChillCalendarBundle/Export/Export/CountCalendars.php
@@ -52,7 +52,7 @@ class CountCalendars implements ExportInterface, GroupedExportInterface
return 'Exports of calendar';
}
- public function getLabels($key, array $values, $data): Closure
+ public function getLabels($key, array $values, $data)
{
if ('export_result' !== $key) {
throw new LogicException("the key {$key} is not used by this export");
diff --git a/src/Bundle/ChillMainBundle/Doctrine/Type/NativeDateIntervalType.php b/src/Bundle/ChillMainBundle/Doctrine/Type/NativeDateIntervalType.php
index 1d4cd104c..896ddb600 100644
--- a/src/Bundle/ChillMainBundle/Doctrine/Type/NativeDateIntervalType.php
+++ b/src/Bundle/ChillMainBundle/Doctrine/Type/NativeDateIntervalType.php
@@ -31,9 +31,6 @@ class NativeDateIntervalType extends DateIntervalType
{
public const FORMAT = '%rP%YY%MM%DDT%HH%IM%SS';
- /**
- * @param DateInterval|null $value
- */
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
if (null === $value) {
diff --git a/src/Bundle/ChillMainBundle/Export/ExportInterface.php b/src/Bundle/ChillMainBundle/Export/ExportInterface.php
index 95122ec0a..d4e456ca6 100644
--- a/src/Bundle/ChillMainBundle/Export/ExportInterface.php
+++ b/src/Bundle/ChillMainBundle/Export/ExportInterface.php
@@ -11,6 +11,7 @@ declare(strict_types=1);
namespace Chill\MainBundle\Export;
+use Doctrine\ORM\NativeQuery;
use Doctrine\ORM\QueryBuilder;
/**
@@ -23,6 +24,7 @@ use Doctrine\ORM\QueryBuilder;
* aggregation, use `ListInterface`.
*
* @example Chill\PersonBundle\Export\CountPerson an example of implementation
+ * @template Q of QueryBuilder|NativeQuery
*/
interface ExportInterface extends ExportElementInterface
{
@@ -84,7 +86,7 @@ interface ExportInterface extends ExportElementInterface
* @param mixed[] $values The values from the result. if there are duplicates, those might be given twice. Example: array('FR', 'BE', 'CZ', 'FR', 'BE', 'FR')
* @param mixed $data The data from the export's form (as defined in `buildForm`)
*
- * @return pure-callable(null|string|int|float|'_header' $value):string|int|\DateTimeInterface where the first argument is the value, and the function should return the label to show in the formatted file. Example : `function($countryCode) use ($countries) { return $countries[$countryCode]->getName(); }`
+ * @return callable(null|string|int|float|'_header' $value): string|int|\DateTimeInterface where the first argument is the value, and the function should return the label to show in the formatted file. Example : `function($countryCode) use ($countries) { return $countries[$countryCode]->getName(); }`
*/
public function getLabels($key, array $values, $data);
@@ -102,7 +104,7 @@ interface ExportInterface extends ExportElementInterface
/**
* Return the results of the query builder.
*
- * @param \Doctrine\ORM\NativeQuery|QueryBuilder $query
+ * @param Q $query
* @param mixed[] $data the data from the export's fomr (added by self::buildForm)
*
* @return mixed[] an array of results
@@ -132,7 +134,7 @@ interface ExportInterface extends ExportElementInterface
* @param array $acl an array where each row has a `center` key containing the Chill\MainBundle\Entity\Center, and `circles` keys containing the reachable circles. Example: `array( array('center' => $centerA, 'circles' => array($circleA, $circleB) ) )`
* @param array $data the data from the form, if any
*
- * @return \Doctrine\ORM\NativeQuery|QueryBuilder the query to execute.
+ * @return Q the query to execute.
*/
public function initiateQuery(array $requiredModifiers, array $acl, array $data = []);
diff --git a/src/Bundle/ChillMainBundle/Form/DataMapper/ExportPickCenterDataMapper.php b/src/Bundle/ChillMainBundle/Form/DataMapper/ExportPickCenterDataMapper.php
index 549805fc5..52e053795 100644
--- a/src/Bundle/ChillMainBundle/Form/DataMapper/ExportPickCenterDataMapper.php
+++ b/src/Bundle/ChillMainBundle/Form/DataMapper/ExportPickCenterDataMapper.php
@@ -24,15 +24,7 @@ class ExportPickCenterDataMapper implements DataMapperInterface
{
protected RegroupmentRepository $regroupmentRepository;
- /**
- * @param array|Center[] $data
- * @param $forms
- *
- * @throws Exception
- *
- * @return void
- */
- public function mapDataToForms($data, $forms)
+ public function mapDataToForms($data, $forms): void
{
if (null === $data) {
return;
@@ -44,7 +36,9 @@ class ExportPickCenterDataMapper implements DataMapperInterface
$pickedRegroupment = [];
foreach ($this->regroupmentRepository->findAll() as $regroupment) {
- [$contained, $notContained] = $regroupment->getCenters()->partition(static function (Center $center) {
+ /** @phpstan-ignore-next-line */
+ [$contained, $notContained] = $regroupment->getCenters()->partition(static function (Center $center): bool {
+ return false;
});
if (0 === count($notContained)) {
@@ -56,13 +50,7 @@ class ExportPickCenterDataMapper implements DataMapperInterface
$form['centers']->setData($data);
}
- /**
- * @param iterable $forms
- * @param array $data
- *
- * @return void
- */
- public function mapFormsToData($forms, &$data)
+ public function mapFormsToData($forms, &$data): void
{
/** @var array $forms */
$forms = iterator_to_array($forms);
@@ -74,8 +62,8 @@ class ExportPickCenterDataMapper implements DataMapperInterface
}
if (array_key_exists('regroupment', $forms)) {
+ /** @var Regroupment $regroupment */
foreach ($forms['regroupment']->getData() as $regroupment) {
- /** @var Regroupment $regroupment */
foreach ($regroupment->getCenters() as $center) {
$centers[spl_object_hash($center)] = $center;
}
diff --git a/src/Bundle/ChillMainBundle/Workflow/EntityWorkflowHandlerInterface.php b/src/Bundle/ChillMainBundle/Workflow/EntityWorkflowHandlerInterface.php
index 73e260c37..1d185ba0e 100644
--- a/src/Bundle/ChillMainBundle/Workflow/EntityWorkflowHandlerInterface.php
+++ b/src/Bundle/ChillMainBundle/Workflow/EntityWorkflowHandlerInterface.php
@@ -11,6 +11,7 @@ declare(strict_types=1);
namespace Chill\MainBundle\Workflow;
+use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
interface EntityWorkflowHandlerInterface
diff --git a/src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php b/src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php
deleted file mode 100644
index 139305a0d..000000000
--- a/src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php
+++ /dev/null
@@ -1,1183 +0,0 @@
-logger = $logger;
- $this->helper = $helper;
- $this->em = $em;
- $this->customFieldProvider = $customFieldProvider;
- $this->eventDispatcher = $eventDispatcher;
- $this->formFactory = $formFactory;
-
- parent::__construct('chill:person:import');
- }
-
- /**
- * This function is a shortcut to addOption.
- *
- * @param string $name
- * @param string $description
- * @param string $default
- *
- * @return ImportPeopleFromCSVCommand
- */
- protected function addOptionShortcut($name, $description, $default)
- {
- $this->addOption($name, null, InputOption::VALUE_OPTIONAL, $description, $default);
-
- return $this;
- }
-
- protected function configure()
- {
- $this
- ->addArgument('csv_file', InputArgument::REQUIRED, 'The CSV file to import')
- ->setDescription('Import people from a csv file')
- ->setHelp(
- <<<'EOF'
- Import people from a csv file. The first row must contains the header column and will determines where the value will be matched.
-
- Date format: the possible date format may be separatedby an |. The possible format will be tryed from the first to the last. The format should be explained as http://php.net/manual/en/function.strftime.php
-
- php app/console chill:person:import /tmp/hepc.csv fr_FR.utf8 \
- --firstname="Prénom" --lastname="Nom" \
- --birthdate="D.N." --birthdate_format="%d/%m/%Y" \
- --opening_date_format="%B %Y|%Y" --closing_date="der.contact" \
- --closing_date_format="%Y" --custom-field="3=code" -vvv
- EOF
- )
- ->addArgument(
- 'locale',
- InputArgument::REQUIRED,
- 'The locale to use in displaying translatable strings from entities'
- )
- ->addOption(
- 'force-center',
- null,
- InputOption::VALUE_REQUIRED,
- 'The id of the center'
- )
- ->addOption(
- 'force',
- null,
- InputOption::VALUE_NONE,
- 'Persist people in the database (default is not to persist people)'
- )
- ->addOption(
- 'delimiter',
- 'd',
- InputOption::VALUE_OPTIONAL,
- 'The delimiter character of the csv file',
- ','
- )
- ->addOption(
- 'enclosure',
- null,
- InputOption::VALUE_OPTIONAL,
- 'The enclosure character of the csv file',
- '"'
- )
- ->addOption(
- 'escape',
- null,
- InputOption::VALUE_OPTIONAL,
- 'The escape character of the csv file',
- '\\'
- )
- ->addOption(
- 'length',
- null,
- InputOption::VALUE_OPTIONAL,
- 'The length of line to read. 0 means unlimited.',
- 0
- )
- ->addOption(
- 'dump-choice-matching',
- null,
- InputOption::VALUE_REQUIRED,
- 'The path of the file to dump the matching between label in CSV and answers'
- )
- ->addOption(
- 'load-choice-matching',
- null,
- InputOption::VALUE_OPTIONAL,
- 'The path of the file to load the matching between label in CSV and answers'
- );
-
- // mapping columns
- foreach (self::$mapping as $m) {
- $this->addOptionShortcut($m[0], $m[1], $m[2]);
- }
-
- // other information
- $this->addOptionShortcut(
- 'birthdate_format',
- 'Format preference for '
- . 'birthdate. See help for date formats preferences.',
- self::$defaultDateInterpreter
- );
- $this->addOptionShortcut(
- 'opening_date_format',
- 'Format preference for '
- . 'opening date. See help for date formats preferences.',
- self::$defaultDateInterpreter
- );
- $this->addOptionShortcut(
- 'closing_date_format',
- 'Format preference for '
- . 'closing date. See help for date formats preferences.',
- self::$defaultDateInterpreter
- );
-
- // mapping column to custom fields
- $this->addOption(
- 'custom-field',
- null,
- InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
- 'Mapping a column to a custom fields key. Example: 1=cf_slug'
- );
- $this->addOption(
- 'skip-interactive-field-mapping',
- null,
- InputOption::VALUE_NONE,
- 'Do not ask for interactive mapping'
- );
- }
-
- /**
- * @param array $headers the processed header : an array as prepared by self::processingHeaders
- *
- * @throws Exception
- */
- protected function createPerson(array $row, array $headers): Person
- {
- // trying to get the opening date
- $openingDateString = trim($row[array_search('opening_date', $headers, true)]);
- $openingDate = $this->processDate($openingDateString, $this->input->getOption('opening_date_format'));
-
- $person = new Person();
- // add the center
- $center = $this->getCenter($row, $headers);
-
- if (null === $center) {
- throw new Exception('center not found');
- }
-
- $person->setCenter($center);
-
- foreach ($headers as $column => $info) {
- $value = trim($row[$column]);
-
- switch ($info) {
- case 'firstname':
- $person->setFirstName($value);
-
- break;
-
- case 'lastname':
- $person->setLastName($value);
-
- break;
-
- case 'birthdate':
- $this->processBirthdate($person, $value);
-
- break;
-
- case 'gender':
- $person->setGender($value);
-
- break;
-
- case 'opening_date':
- // we have processed this when creating the person object, skipping;
- break;
-
- case 'closing_date':
- $this->processClosingDate($person, $value);
-
- break;
-
- case 'memo':
- $person->setMemo($value);
-
- break;
-
- case 'email':
- $person->setEmail($value);
-
- break;
-
- case 'phonenumber':
- $person->setPhonenumber($value);
-
- break;
-
- case 'mobilenumber':
- $person->setMobilenumber($value);
-
- break;
- // we just keep the column number for those data
- case 'postalcode':
- $postalCodeValue = $value;
-
- break;
-
- case 'street1':
- $street1Value = $value;
-
- break;
-
- case 'locality':
- $localityValue = $value;
-
- break;
- }
- }
-
- // handle address
- if (in_array('postalcode', $headers, true)) {
- if (!empty($postalCodeValue)) {
- $address = new Address();
- $postalCode = $this->guessPostalCode($postalCodeValue, $localityValue ?? '');
-
- if (null === $postalCode) {
- throw new Exception('The locality is not found');
- }
-
- $address->setPostcode($postalCode);
-
- if (in_array('street1', $headers, true)) {
- /** @phpstan-ignore-next-line as this command is deprecated */
- $address->setStreetAddress1($street1Value);
- }
- $address->setValidFrom(new DateTime('today'));
-
- $person->addAddress($address);
- }
- }
-
- return $person;
- }
-
- protected function dumpAnswerMatching()
- {
- if ($this->input->hasOption('dump-choice-matching') && !empty($this->input->getOption('dump-choice-matching'))) {
- $this->logger->debug('Dump the matching between answer and choices');
- $str = json_encode($this->cacheAnswersMapping, JSON_PRETTY_PRINT);
-
- $fs = new Filesystem();
- $filename = $this->input->getOption('dump-choice-matching');
-
- $fs->dumpFile($filename, $str);
- }
- }
-
- /**
- * @throws Exception
- *
- * @return int|void|null
- */
- protected function execute(InputInterface $input, OutputInterface $output)
- {
- $headers = $rawHeaders = [];
- $this->input = $input;
- $this->output = $output;
-
- $this->logger->debug('Setting locale to ' . $input->getArgument('locale'));
- setlocale(LC_TIME, $input->getArgument('locale'));
-
- // opening csv as resource
- $csv = $this->openCSV();
-
- $num = 0;
- $line = $this->line = 1;
-
- try {
- while (
- false !== ($row = fgetcsv(
- $csv,
- $input->getOption('length'),
- $input->getOption('delimiter'),
- $input->getOption('enclosure'),
- $input->getOption('escape')
- ))
- ) {
- $this->logger->debug('Processing line ' . $this->line);
-
- if (1 === $line) {
- $this->logger->debug('Processing line 1, headers');
- $rawHeaders = $row;
- $headers = $this->processingHeaders($row);
- } else {
- $person = $this->createPerson($row, $headers);
-
- if (count($this->customFieldMapping) > 0) {
- $this->processingCustomFields($person, $row);
- }
-
- $event = new Event();
- $event->person = $person;
- $event->rawHeaders = $rawHeaders;
- $event->row = $row;
- $event->headers = $headers;
- $event->skipPerson = false;
- $event->force = $this->input->getOption('force');
- $event->input = $this->input;
- $event->output = $this->output;
- $event->helperSet = $this->getHelperSet();
-
- $this->eventDispatcher->dispatch('chill_person.person_import', $event);
-
- if (
- $this->input->getOption('force') === true
- && false === $event->skipPerson
- ) {
- $this->em->persist($person);
- }
-
- ++$num;
- }
-
- ++$line;
- ++$this->line;
- }
-
- if ($this->input->getOption('force') === true) {
- $this->logger->debug('persisting entitites');
- $this->em->flush();
- }
- } finally {
- $this->logger->debug('closing csv', ['method' => __METHOD__]);
- fclose($csv);
- // dump the matching between answer and choices
- $this->dumpAnswerMatching();
- }
- }
-
- /**
- * @return Center|mixed|object|null
- */
- protected function getCenter(array $row, array $headers)
- {
- if ($this->input->hasOption('force-center') && !empty($this->input->getOption('force-center'))) {
- return $this->em->getRepository(Center::class)->find($this->input->getOption('force-center'));
- }
-
- $columnCenter = array_search('center', $headers, true);
- $centerName = trim($row[$columnCenter]);
-
- try {
- return $this
- ->em
- ->createQuery('SELECT c FROM ChillMainBundle:Center c WHERE c.name = :center_name')
- ->setParameter('center_name', $centerName)
- ->getSingleResult();
- } catch (NonUniqueResultException $e) {
- return $this->guessCenter($centerName);
- } catch (NoResultException $e) {
- return $this->guessCenter($centerName);
- }
- }
-
- /**
- * @param $centerName
- *
- * @return Center|mixed|object|null
- */
- protected function guessCenter($centerName)
- {
- if (!array_key_exists('_center_picked', $this->cacheAnswersMapping)) {
- $this->cacheAnswersMapping['_center_picked'] = [];
- }
-
- if (array_key_exists($centerName, $this->cacheAnswersMapping['_center_picked'])) {
- $id = $this->cacheAnswersMapping['_center_picked'][$centerName];
-
- return $this->em->getRepository(Center::class)
- ->find($id);
- }
-
- $centers = $this->em->createQuery('SELECT c FROM ChillMainBundle:Center c '
- . 'ORDER BY SIMILARITY(c.name, :center_name) DESC')
- ->setParameter('center_name', $centerName)
- ->setMaxResults(10)
- ->getResult();
-
- if (count($centers) > 1) {
- if (strtolower($centers[0]->getName()) === strtolower($centerName)) {
- return $centers[0];
- }
- }
-
- $centersByName = [];
- $names = array_map(static function (Center $c) use (&$centersByName) {
- $n = $c->getName();
- $centersByName[$n] = $c;
-
- return $n;
- }, $centers);
- $names[] = 'none of them';
-
- $helper = $this->getHelper('question');
- $question = new ChoiceQuestion(
- sprintf('Which center match the name "%s" ? (default to "%s")', $centerName, $names[0]),
- $names,
- 0
- );
-
- $answer = $helper->ask($this->input, $this->output, $question);
-
- if ('none of them' === $answer) {
- $questionCreate = new ConfirmationQuestion('Would you like to create it ?', false);
- $create = $helper->ask($this->input, $this->output, $questionCreate);
-
- if ($create) {
- $center = (new Center())
- ->setName($centerName);
-
- if ($this->input->getOption('force') === true) {
- $this->em->persist($center);
- $this->em->flush();
- }
-
- return $center;
- }
- }
-
- $center = $centersByName[$answer];
-
- $this->cacheAnswersMapping['_center_picked'][$centerName] = $center->getId();
-
- return $center;
- }
-
- /**
- * @param $postalCode
- * @param $locality
- *
- * @return mixed|null
- */
- protected function guessPostalCode($postalCode, $locality)
- {
- if (!array_key_exists('_postal_code_picked', $this->cacheAnswersMapping)) {
- $this->cacheAnswersMapping['_postal_code_picked'] = [];
- }
-
- if (array_key_exists($postalCode, $this->cacheAnswersMapping['_postal_code_picked'])) {
- if (array_key_exists($locality, $this->cacheAnswersMapping['_postal_code_picked'][$postalCode])) {
- $id = $this->cacheAnswersMapping['_postal_code_picked'][$postalCode][$locality];
-
- return $this->em->getRepository(PostalCode::class)->find($id);
- }
- }
-
- $postalCodes = $this->em->createQuery(
- 'SELECT pc FROM ' . PostalCode::class . ' pc '
- . 'WHERE pc.code = :postal_code '
- . 'ORDER BY SIMILARITY(pc.name, :locality) DESC '
- )
- ->setMaxResults(10)
- ->setParameter('postal_code', $postalCode)
- ->setParameter('locality', $locality)
- ->getResult();
-
- if (count($postalCodes) >= 1) {
- if (
- $postalCodes[0]->getCode() === $postalCode
- && $postalCodes[0]->getName() === $locality
- ) {
- return $postalCodes[0];
- }
- }
-
- if (count($postalCodes) === 0) {
- return null;
- }
-
- $postalCodeByName = [];
- $names = array_map(static function (PostalCode $pc) use (&$postalCodeByName) {
- $n = $pc->getName();
- $postalCodeByName[$n] = $pc;
-
- return $n;
- }, $postalCodes);
- $names[] = 'none of them';
-
- $helper = $this->getHelper('question');
- $question = new ChoiceQuestion(
- sprintf(
- 'Which postal code match the '
- . 'name "%s" with postal code "%s" ? (default to "%s")',
- $locality,
- $postalCode,
- $names[0]
- ),
- $names,
- 0
- );
-
- $answer = $helper->ask($this->input, $this->output, $question);
-
- if ('none of them' === $answer) {
- return null;
- }
-
- $pc = $postalCodeByName[$answer];
-
- $this->cacheAnswersMapping['_postal_code_picked'][$postalCode][$locality] =
- $pc->getId();
-
- return $pc;
- }
-
- protected function interact(InputInterface $input, OutputInterface $output)
- {
- // preparing the basic
- $this->input = $input;
- $this->output = $output;
- $this->logger = new ConsoleLogger($output);
-
- $csv = $this->openCSV();
-
- // getting the first row
- if (
- false !== ($row = fgetcsv(
- $csv,
- $input->getOption('length'),
- $input->getOption('delimiter'),
- $input->getOption('enclosure'),
- $input->getOption('escape')
- ))
- ) {
- try {
- $this->matchColumnToCustomField($row);
- } finally {
- $this->logger->debug('closing csv', ['method' => __METHOD__]);
- fclose($csv);
- }
- }
-
- // load the matching between csv and label
- $this->loadAnswerMatching();
- }
-
- /**
- * Load the mapping between answer in CSV and value in choices from a json file.
- */
- protected function loadAnswerMatching()
- {
- if ($this->input->hasOption('load-choice-matching')) {
- $fs = new Filesystem();
- $filename = $this->input->getOption('load-choice-matching');
-
- if (!$fs->exists($filename)) {
- $this->logger->warning("The file {$filename} is not found. Choice matching not loaded");
- } else {
- $this->logger->debug("Loading {$filename} as choice matching");
- $this->cacheAnswersMapping = json_decode(file_get_contents($filename), true);
- }
- }
- }
-
- /**
- * @param $row
- */
- protected function matchColumnToCustomField($row)
- {
- $cfMappingsOptions = $this->input->getOption('custom-field');
- /** @var \Doctrine\Persistence\ObjectManager $em */
- $em = $this->em;
-
- foreach ($cfMappingsOptions as $cfMappingStringOption) {
- [$rowNumber, $cfSlug] = preg_split('|=|', $cfMappingStringOption);
-
- // check that the column exists, getting the column name
- $column = $row[$rowNumber];
-
- if (empty($column)) {
- $message = "The column with row {$rowNumber} is empty.";
- $this->logger->error($message);
-
- throw new RuntimeException($message);
- }
-
- // check a custom field exists
- try {
- $customField = $em->createQuery('SELECT cf '
- . 'FROM ChillCustomFieldsBundle:CustomField cf '
- . 'JOIN cf.customFieldGroup g '
- . 'WHERE cf.slug = :slug '
- . 'AND g.entity = :entity')
- ->setParameters([
- 'slug' => $cfSlug,
- 'entity' => Person::class,
- ])
- ->getSingleResult();
- } catch (\Doctrine\ORM\NoResultException $e) {
- $message = sprintf(
- "The customfield with slug '%s' does not exists. It was associated with column number %d",
- $cfSlug,
- $rowNumber
- );
- $this->logger->error($message);
-
- throw new RuntimeException($message);
- }
- // skip if custom field does not exists
- if (null === $customField) {
- $this->logger->error("The custom field with slug {$cfSlug} could not be found. "
- . 'Stopping this command.');
-
- throw new RuntimeException("The custom field with slug {$cfSlug} could not be found. "
- . 'Stopping this command.');
- }
-
- $this->logger->notice(sprintf(
- "Matched custom field %s (question : '%s') on column %d (displayed in the file as '%s')",
- $customField->getSlug(),
- $this->helper->localize($customField->getName()),
- $rowNumber,
- $column
- ));
-
- $this->customFieldMapping[$rowNumber] = $customField;
- }
- }
-
- /**
- * @throws RuntimeException
- *
- * @return resource
- */
- protected function openCSV()
- {
- $fs = new Filesystem();
- $filename = $this->input->getArgument('csv_file');
-
- if (!$fs->exists($filename)) {
- throw new RuntimeException('The file does not exists or you do not '
- . 'have the right to read it.');
- }
-
- $resource = fopen($filename, 'rb');
-
- if (false === $resource) {
- throw new RuntimeException("The file '{$filename}' could not be opened.");
- }
-
- return $resource;
- }
-
- /**
- * @param $value
- *
- * @throws Exception
- */
- protected function processBirthdate(Person $person, $value)
- {
- if (empty($value)) {
- return;
- }
-
- $date = $this->processDate($value, $this->input->getOption('birthdate_format'));
-
- if ($date instanceof DateTime) {
- // we correct birthdate if the date is in the future
- // the most common error is to set date 100 years to late (ex. 2063 instead of 1963)
- if ($date > new DateTime('yesterday')) {
- $date = $date->sub(new DateInterval('P100Y'));
- }
-
- $person->setBirthdate($date);
-
- return;
- }
-
- // if we arrive here, we could not process the date
- $this->logger->warning(sprintf(
- 'Line %d : the birthdate could not be interpreted. Was %s.',
- $this->line,
- $value
- ));
- }
-
- /**
- * Process a custom field choice.
- *
- * The method try to guess if the result exists amongst the text of the possible
- * choices. If the texts exists, then this is picked. Else, ask the user.
- *
- * @param string $value
- *
- * @throws Exception
- *
- * @return string
- */
- protected function processChoiceType(
- $value,
- \Symfony\Component\Form\FormInterface $form,
- \Chill\CustomFieldsBundle\Entity\CustomField $cf
- ) {
- // getting the possible answer and their value :
- $view = $form->get($cf->getSlug())->createView();
- $answers = $this->collectChoicesAnswers($view->vars['choices']);
-
- // if we do not have any answer on the question, throw an error.
- if (count($answers) === 0) {
- $message = sprintf(
- "The question '%s' with slug '%s' does not count any answer.",
- $this->helper->localize($cf->getName()),
- $cf->getSlug()
- );
-
- $this->logger->error($message, [
- 'method' => __METHOD__,
- 'slug' => $cf->getSlug(),
- 'question' => $this->helper->localize($cf->getName()),
- ]);
-
- throw new RuntimeException($message);
- }
-
- if (false === $view->vars['required']) {
- $answers[null] = '** no answer';
- }
-
- // the answer does not exists in cache. Try to find it, or asks the user
- if (!isset($this->cacheAnswersMapping[$cf->getSlug()][$value])) {
- // try to find the answer (with array_keys and a search value
- $values = array_keys(
- array_map(static function ($label) {
- return trim(strtolower($label));
- }, $answers),
- trim(strtolower($value)),
- true
- );
-
- if (count($values) === 1) {
- // we could guess an answer !
- $this->logger->info('This question accept multiple answers');
- $this->cacheAnswersMapping[$cf->getSlug()][$value] =
- false === $view->vars['multiple'] ? $values[0] : [$values[0]];
- $this->logger->info(sprintf(
- "Guessed that value '%s' match with key '%s' "
- . 'because the CSV and the label are equals.',
- $value,
- $values[0]
- ));
- } else {
- // we could nog guess an answer. Asking the user.
- $this->output->writeln('I do not know the answer to this question : ');
- $this->output->writeln($this->helper->localize($cf->getName()));
-
- // printing the possible answers
- /** @var \Symfony\Component\Console\Helper\Table $table */
- $table = new Table($this->output);
- $table->setHeaders(['#', 'label', 'value']);
- $i = 0;
-
- $matchingTableRowAnswer = [];
-
- foreach ($answers as $key => $answer) {
- $table->addRow([
- $i, $answer, $key,
- ]);
- $matchingTableRowAnswer[$i] = $key;
- ++$i;
- }
- $table->render($this->output);
-
- $question = new ChoiceQuestion(
- sprintf('Please pick your choice for the value "%s"', $value),
- array_keys($matchingTableRowAnswer)
- );
- $question->setErrorMessage('This choice is not possible');
-
- if ($view->vars['multiple']) {
- $this->logger->debug('this question is multiple');
- $question->setMultiselect(true);
- }
-
- $selected = $this->getHelper('question')->ask($this->input, $this->output, $question);
-
- $this->output->writeln(
- sprintf(
- 'You have selected "%s"',
- is_array($answers[$matchingTableRowAnswer[$selected]]) ?
- implode(',', $answers[$matchingTableRowAnswer[$selected]]) :
- $answers[$matchingTableRowAnswer[$selected]]
- )
- );
-
- // recording value in cache
- $this->cacheAnswersMapping[$cf->getSlug()][$value] = $matchingTableRowAnswer[$selected];
- $this->logger->debug(sprintf(
- "Setting the value '%s' in cache for customfield '%s' and answer '%s'",
- is_array($this->cacheAnswersMapping[$cf->getSlug()][$value]) ?
- implode(', ', $this->cacheAnswersMapping[$cf->getSlug()][$value]) :
- $this->cacheAnswersMapping[$cf->getSlug()][$value],
- $cf->getSlug(),
- $value
- ));
- }
- }
-
- $form->submit([$cf->getSlug() => $this->cacheAnswersMapping[$cf->getSlug()][$value]]);
- $value = $form->getData()[$cf->getSlug()];
-
- $this->logger->debug(
- sprintf(
- "Found value : %s for custom field with question '%s'",
- is_array($value) ? implode(',', $value) : $value,
- $this->helper->localize($cf->getName())
- )
- );
-
- return $value;
- }
-
- /**
- * @param $value
- *
- * @throws Exception
- */
- protected function processClosingDate(Person $person, $value)
- {
- if (empty($value)) {
- return;
- }
-
- // we skip if the opening date is now (or after yesterday)
- /** @var \Chill\PersonBundle\Entity\AccompanyingPeriod $period */
- $period = $person->getCurrentAccompanyingPeriod();
-
- if ($period->getOpeningDate() > new DateTime('yesterday')) {
- $this->logger->debug(sprintf(
- 'skipping a closing date because opening date is after yesterday (%s)',
- $period->getOpeningDate()->format('Y-m-d')
- ));
-
- return;
- }
-
- $date = $this->processDate($value, $this->input->getOption('closing_date_format'));
-
- if ($date instanceof DateTime) {
- // we correct birthdate if the date is in the future
- // the most common error is to set date 100 years to late (ex. 2063 instead of 1963)
- if ($date > new DateTime('yesterday')) {
- $date = $date->sub(new DateInterval('P100Y'));
- }
-
- $period->setClosingDate($date);
- $person->close();
-
- return;
- }
-
- // if we arrive here, we could not process the date
- $this->logger->warning(sprintf(
- 'Line %d : the closing date could not be interpreted. Was %s.',
- $this->line,
- $value
- ));
- }
-
- /**
- * @param $value
- * @param $formats
- *
- * @return bool|DateTime
- */
- protected function processDate($value, $formats)
- {
- $possibleFormats = explode('|', $formats);
-
- foreach ($possibleFormats as $format) {
- $this->logger->debug("Trying format {$format}", [__METHOD__]);
- $dateR = strptime($value, $format);
-
- if (is_array($dateR) && '' === $dateR['unparsed']) {
- $string = sprintf(
- '%04d-%02d-%02d %02d:%02d:%02d',
- ($dateR['tm_year'] + 1900),
- ($dateR['tm_mon'] + 1),
- ($dateR['tm_mday']),
- ($dateR['tm_hour']),
- ($dateR['tm_min']),
- ($dateR['tm_sec'])
- );
- $date = DateTime::createFromFormat('Y-m-d H:i:s', $string);
- $this->logger->debug(sprintf('Interpreting %s as date %s', $value, $date->format('Y-m-d H:i:s')));
-
- return $date;
- }
- }
-
- // if we arrive here, we could not process the date
- $this->logger->debug(sprintf(
- 'Line %d : a date could not be interpreted. Was %s.',
- $this->line,
- $value
- ));
-
- return false;
- }
-
- /**
- * @param $row
- *
- * @throws Exception
- */
- protected function processingCustomFields(Person $person, $row)
- {
- /** @var \Chill\CustomFieldsBundle\Service\CustomFieldProvider $cfProvider */
- $cfProvider = $this->customFieldProvider;
- $cfData = [];
-
- /** @var \Chill\CustomFieldsBundle\Entity\CustomField $$customField */
- foreach ($this->customFieldMapping as $rowNumber => $customField) {
- $builder = $this->formFactory->createBuilder();
- $cfProvider->getCustomFieldByType($customField->getType())
- ->buildForm($builder, $customField);
- $form = $builder->getForm();
-
- // get the type of the form
- $type = get_class($form->get($customField->getSlug())
- ->getConfig()->getType()->getInnerType());
- $this->logger->debug(sprintf(
- 'Processing a form of type %s',
- $type
- ));
-
- switch ($type) {
- case \Symfony\Component\Form\Extension\Core\Type\TextType::class:
- $cfData[$customField->getSlug()] =
- $this->processTextType($row[$rowNumber], $form, $customField);
-
- break;
-
- case \Symfony\Component\Form\Extension\Core\Type\ChoiceType::class:
- case \Chill\MainBundle\Form\Type\Select2ChoiceType::class:
- $cfData[$customField->getSlug()] =
- $this->processChoiceType($row[$rowNumber], $form, $customField);
- }
- }
-
- $person->setCFData($cfData);
- }
-
- /**
- * @return array where keys are column number, and value is information mapped
- */
- protected function processingHeaders(array $firstRow): array
- {
- $availableOptions = array_map(
- static fn (array $m) => $m[0],
- self::$mapping
- );
- $matchedColumnHeaders = $headers = [];
-
- foreach ($availableOptions as $option) {
- $matchedColumnHeaders[$option] = $this->input->getOption($option);
- }
-
- foreach ($firstRow as $key => $content) {
- $content = trim($content);
-
- if (in_array($content, $matchedColumnHeaders, true)) {
- $information = array_search($content, $matchedColumnHeaders, true);
- $headers[$key] = $information;
- $this->logger->notice("Matched {$information} on column {$key} (displayed in the file as '{$content}')");
- } else {
- $this->logger->notice("Column with content '{$content}' is ignored");
- }
- }
-
- return $headers;
- }
-
- /**
- * Process a text type on a custom field.
- *
- * @param type $value
- *
- * @return type
- */
- protected function processTextType(
- $value,
- \Symfony\Component\Form\FormInterface $form,
- \Chill\CustomFieldsBundle\Entity\CustomField $cf
- ) {
- $form->submit([$cf->getSlug() => $value]);
-
- $value = $form->getData()[$cf->getSlug()];
-
- $this->logger->debug(sprintf('Found value : %s for custom field with question '
- . "'%s'", $value, $this->helper->localize($cf->getName())));
-
- return $value;
- }
-
- /**
- * Recursive method to collect the possibles answer from a ChoiceType (or
- * its inherited types).
- *
- * @param mixed $choices
- *
- * @throws Exception
- *
- * @return array where
- */
- private function collectChoicesAnswers($choices)
- {
- $answers = [];
-
- /** @var \Symfony\Component\Form\ChoiceList\View\ChoiceView $choice */
- foreach ($choices as $choice) {
- if ($choice instanceof \Symfony\Component\Form\ChoiceList\View\ChoiceView) {
- $answers[$choice->value] = $choice->label;
- } elseif ($choice instanceof \Symfony\Component\Form\ChoiceList\View\ChoiceGroupView) {
- $answers = $answers + $this->collectChoicesAnswers($choice->choices);
- } else {
- throw new Exception(sprintf(
- "The choice type is not know. Expected '%s' or '%s', get '%s'",
- \Symfony\Component\Form\ChoiceList\View\ChoiceView::class,
- \Symfony\Component\Form\ChoiceList\View\ChoiceGroupView::class,
- get_class($choice)
- ));
- }
- }
-
- return $answers;
- }
-}
diff --git a/src/Bundle/ChillPersonBundle/Controller/HouseholdController.php b/src/Bundle/ChillPersonBundle/Controller/HouseholdController.php
index ba7c78f65..7b9eb0084 100644
--- a/src/Bundle/ChillPersonBundle/Controller/HouseholdController.php
+++ b/src/Bundle/ChillPersonBundle/Controller/HouseholdController.php
@@ -82,7 +82,7 @@ class HouseholdController extends AbstractController
}
usort($accompanyingPeriods, static function ($a, $b) {
- return $b->getOpeningDate() > $a->getOpeningDate();
+ return $b->getOpeningDate() <=> $a->getOpeningDate();
});
$oldMembers = $household->getNonCurrentMembers();
diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php
index 4dd297b9f..510e1c327 100644
--- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php
+++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php
@@ -42,6 +42,7 @@ use DateTimeInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria;
+use Doctrine\Common\Collections\ReadableCollection;
use Doctrine\ORM\Mapping as ORM;
use Iterator;
use LogicException;
@@ -615,9 +616,9 @@ class AccompanyingPeriod implements
/**
* Get a list of person which have an adresse available for a valid location.
*
- * @return Collection|Person[]
+ * @return ReadableCollection<(int|string), Person>
*/
- public function getAvailablePersonLocation(): Collection
+ public function getAvailablePersonLocation(): ReadableCollection
{
return $this->getOpenParticipations()
->filter(
@@ -675,8 +676,9 @@ class AccompanyingPeriod implements
/**
* @Groups({"read"})
+ * @return ReadableCollection<(int|string), Comment>
*/
- public function getComments(): Collection
+ public function getComments(): ReadableCollection
{
$pinnedComment = $this->pinnedComment;
@@ -700,7 +702,7 @@ class AccompanyingPeriod implements
/**
* @Groups({"docgen:read"})
*/
- public function getCurrentParticipations(): Collection
+ public function getCurrentParticipations(): ReadableCollection
{
return $this->getOpenParticipations();
}
@@ -834,7 +836,10 @@ class AccompanyingPeriod implements
return $collection->count() > 0 ? $collection->first() : null;
}
- public function getOpenParticipations(): Collection
+ /**
+ * @return ReadableCollection<(int|string), AccompanyingPeriodParticipation>
+ */
+ public function getOpenParticipations(): ReadableCollection
{
return $this
->getParticipations()
@@ -860,8 +865,9 @@ class AccompanyingPeriod implements
/**
* Get the participation containing a person.
+ * @return ReadableCollection<(int|string), AccompanyingPeriodParticipation>
*/
- public function getParticipationsContainsPerson(Person $person): Collection
+ public function getParticipationsContainsPerson(Person $person): ReadableCollection
{
return $this
->getParticipations()
diff --git a/src/Bundle/ChillPersonBundle/Entity/Household/Household.php b/src/Bundle/ChillPersonBundle/Entity/Household/Household.php
index a544bd6a4..b463312c8 100644
--- a/src/Bundle/ChillPersonBundle/Entity/Household/Household.php
+++ b/src/Bundle/ChillPersonBundle/Entity/Household/Household.php
@@ -22,6 +22,7 @@ use DateTimeInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria;
+use Doctrine\Common\Collections\ReadableCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation as Serializer;
use Symfony\Component\Validator\Constraints as Assert;
@@ -265,7 +266,7 @@ class Household
* @Serializer\Groups({"read"})
* @Serializer\SerializedName("current_members_id")
*/
- public function getCurrentMembersIds(?DateTimeImmutable $now = null): Collection
+ public function getCurrentMembersIds(?DateTimeImmutable $now = null): ReadableCollection
{
return $this->getCurrentMembers($now)->map(
static fn (HouseholdMember $m) => $m->getId()
@@ -332,9 +333,9 @@ class Household
*
* Return a list of Person, instead of a list of HouseholdMembers
*
- * @return Person[]
+ * @return ReadableCollection<(int|string), Person>
*/
- public function getCurrentPersons(?DateTimeImmutable $now = null): Collection
+ public function getCurrentPersons(?DateTimeImmutable $now = null): ReadableCollection
{
return $this->getCurrentMembers($now)
->map(static function (HouseholdMember $m) {
@@ -358,9 +359,9 @@ class Household
/**
* get all the members during a given membership.
*
- * @return Collection|HouseholdMember[]
+ * @return ReadableCollection<(int|string), HouseholdMember>
*/
- public function getMembersDuringMembership(HouseholdMember $membership): Collection
+ public function getMembersDuringMembership(HouseholdMember $membership): ReadableCollection
{
return $this->getMembersOnRange(
$membership->getStartDate(),
@@ -384,7 +385,7 @@ class Household
return $this->getMembers()->matching($criteria);
}
- public function getMembersOnRange(DateTimeImmutable $from, ?DateTimeImmutable $to): Collection
+ public function getMembersOnRange(DateTimeImmutable $from, ?DateTimeImmutable $to): ReadableCollection
{
return $this->getMembers()->filter(static function (HouseholdMember $m) use ($from, $to) {
if (null === $m->getEndDate() && null !== $to) {
diff --git a/src/Bundle/ChillPersonBundle/Form/Type/PickPersonDynamicType.php b/src/Bundle/ChillPersonBundle/Form/Type/PickPersonDynamicType.php
index 76891a74d..78e382f68 100644
--- a/src/Bundle/ChillPersonBundle/Form/Type/PickPersonDynamicType.php
+++ b/src/Bundle/ChillPersonBundle/Form/Type/PickPersonDynamicType.php
@@ -28,11 +28,15 @@ class PickPersonDynamicType extends AbstractType
{
private DenormalizerInterface $denormalizer;
- private DenormalizerInterface $normalizer;
+ private NormalizerInterface $normalizer;
private SerializerInterface $serializer;
- public function __construct(DenormalizerInterface $denormalizer, SerializerInterface $serializer, NormalizerInterface $normalizer)
+ public function __construct(
+ DenormalizerInterface $denormalizer,
+ SerializerInterface $serializer,
+ NormalizerInterface $normalizer
+ )
{
$this->denormalizer = $denormalizer;
$this->serializer = $serializer;
diff --git a/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodContext.php b/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodContext.php
index 3a92df3a4..4a08eff08 100644
--- a/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodContext.php
+++ b/src/Bundle/ChillPersonBundle/Service/DocGenerator/AccompanyingPeriodContext.php
@@ -27,6 +27,7 @@ use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Repository\PersonRepository;
use Chill\PersonBundle\Templating\Entity\PersonRenderInterface;
use DateTime;
+use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
@@ -159,9 +160,9 @@ class AccompanyingPeriodContext implements
public function buildPublicForm(FormBuilderInterface $builder, DocGeneratorTemplate $template, mixed $entity): void
{
$options = $template->getOptions();
- $persons = $entity->getCurrentParticipations()->map(static function (AccompanyingPeriodParticipation $p) {
+ $persons = new ArrayCollection($entity->getCurrentParticipations()->map(static function (AccompanyingPeriodParticipation $p) {
return $p->getPerson();
- });
+ })->toArray());
foreach ($entity->getCurrentParticipations() as $p) {
foreach ($p->getPerson()->getResources() as $r) {
diff --git a/src/Bundle/ChillPersonBundle/Workflow/AccompanyingPeriodWorkWorkflowHandler.php b/src/Bundle/ChillPersonBundle/Workflow/AccompanyingPeriodWorkWorkflowHandler.php
index 75ad04cfb..3cdf23f88 100644
--- a/src/Bundle/ChillPersonBundle/Workflow/AccompanyingPeriodWorkWorkflowHandler.php
+++ b/src/Bundle/ChillPersonBundle/Workflow/AccompanyingPeriodWorkWorkflowHandler.php
@@ -102,7 +102,9 @@ class AccompanyingPeriodWorkWorkflowHandler implements EntityWorkflowHandlerInte
->getAccompanyingPeriod()
->getUser();
- $suggestedUsers[spl_object_hash($referrer)] = $referrer;
+ if (null !== $referrer) {
+ $suggestedUsers[spl_object_hash($referrer)] = $referrer;
+ }
return $suggestedUsers;
}
diff --git a/src/Bundle/ChillReportBundle/Export/Export/ReportList.php b/src/Bundle/ChillReportBundle/Export/Export/ReportList.php
index e6289c626..21606d807 100644
--- a/src/Bundle/ChillReportBundle/Export/Export/ReportList.php
+++ b/src/Bundle/ChillReportBundle/Export/Export/ReportList.php
@@ -158,7 +158,7 @@ class ReportList implements ExportElementValidatedInterface, ListInterface
);
}
- public function getLabels($key, array $values, $data): Closure
+ public function getLabels($key, array $values, $data)
{
switch ($key) {
case 'person_birthdate':
diff --git a/src/Bundle/ChillThirdPartyBundle/DataFixtures/ORM/LoadThirdParty.php b/src/Bundle/ChillThirdPartyBundle/DataFixtures/ORM/LoadThirdParty.php
index 058fa119d..6b40f01b9 100644
--- a/src/Bundle/ChillThirdPartyBundle/DataFixtures/ORM/LoadThirdParty.php
+++ b/src/Bundle/ChillThirdPartyBundle/DataFixtures/ORM/LoadThirdParty.php
@@ -66,22 +66,6 @@ class LoadThirdParty extends Fixture implements DependentFixtureInterface
$manager->flush();
}
- private function createAddress(): ObjectSet
- {
- $loader = new NativeLoader();
-
- return $loader->loadData([
- Address::class => [
- 'address1' => [
- 'name' => '',
- 'telephone' => $this->phoneNumberUtil->getExampleNumber('FR'),
- 'email' => '',
- 'comment' => '',
- ],
- ],
- ]);
- }
-
private function getCenters(): Iterator
{
$references = array_map(
diff --git a/src/Bundle/ChillThirdPartyBundle/Entity/ThirdParty.php b/src/Bundle/ChillThirdPartyBundle/Entity/ThirdParty.php
index 966e40bd1..ca24d2442 100644
--- a/src/Bundle/ChillThirdPartyBundle/Entity/ThirdParty.php
+++ b/src/Bundle/ChillThirdPartyBundle/Entity/ThirdParty.php
@@ -23,6 +23,7 @@ use DateTimeImmutable;
use DateTimeInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
+use Doctrine\Common\Collections\ReadableCollection;
use Doctrine\ORM\Mapping as ORM;
use libphonenumber\PhoneNumber;
use Symfony\Component\Serializer\Annotation\Context;
@@ -153,7 +154,7 @@ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface
* @ORM\OneToMany(targetEntity="Chill\ThirdPartyBundle\Entity\ThirdParty", mappedBy="parent",
* cascade={"persist"}, orphanRemoval=true)
*
- * @var Collection|ThirdParty[]
+ * @var Collection<(int|string), ThirdParty>
* @Assert\Valid(traverse=true)
*/
private Collection $children;
@@ -400,7 +401,7 @@ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface
/**
* Get the children where active = true.
*/
- public function getActiveChildren(): Collection
+ public function getActiveChildren(): ReadableCollection
{
return $this->children->filter(static fn (ThirdParty $tp) => $tp->getActive());
}
diff --git a/src/Bundle/ChillWopiBundle/src/Controller/Convert.php b/src/Bundle/ChillWopiBundle/src/Controller/Convert.php
index 09fe19678..b3697aafd 100644
--- a/src/Bundle/ChillWopiBundle/src/Controller/Convert.php
+++ b/src/Bundle/ChillWopiBundle/src/Controller/Convert.php
@@ -94,7 +94,7 @@ class Convert
'Content-Type' => 'application/pdf',
]);
} catch (ClientExceptionInterface|TransportExceptionInterface|RedirectionExceptionInterface|ServerExceptionInterface $exception) {
- return $this->onConversionFailed($url, $response);
+ return $this->onConversionFailed($url, $exception->getResponse());
}
}
diff --git a/tests/app b/tests/app
index 5b35e7ccd..5e478fdfb 160000
--- a/tests/app
+++ b/tests/app
@@ -1 +1 @@
-Subproject commit 5b35e7ccd0735e5593835e28acbf82386c18e1b6
+Subproject commit 5e478fdfbf429baf3ce852ae69eb1f7101b1b416
From 4f2355b3139eb92c4b825c222e7b65bcaa50fb22 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Tue, 28 Mar 2023 22:58:13 +0200
Subject: [PATCH 13/46] DX: increase memory in phpstan execution
---
.gitlab-ci.yml | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index cea6bda87..7ce9e1835 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -69,7 +69,7 @@ phpstan_tests:
stage: Tests
image: gitea.champs-libres.be/chill-project/chill-skeleton-basic/base-image:php82
script:
- - bin/phpstan
+ - bin/phpstan analyze --memory-limit=2G
cache:
paths:
- .cache/
@@ -79,17 +79,17 @@ phpstan_tests:
- bin
- tests/app/vendor/
-psalm_tests:
- stage: Tests
- image: gitea.champs-libres.be/chill-project/chill-skeleton-basic/base-image:php82
- script:
- - bin/psalm
- allow_failure: true
- artifacts:
- expire_in: 30 min
- paths:
- - bin
- - tests/app/vendor/
+# psalm_tests:
+# stage: Tests
+# image: gitea.champs-libres.be/chill-project/chill-skeleton-basic/base-image:php82
+# script:
+# - bin/psalm
+# allow_failure: true
+# artifacts:
+# expire_in: 30 min
+# paths:
+# - bin
+# - tests/app/vendor/
unit_tests:
stage: Tests
From e935bc20aa8d6c805ddd56916682a74675731247 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Tue, 28 Mar 2023 22:58:30 +0200
Subject: [PATCH 14/46] DX: fix baseline from removed classes
---
phpstan-baseline-level-3.neon | 5 --
phpstan-baseline-level-4.neon | 105 ----------------------------------
phpstan-baseline-level-5.neon | 15 -----
phpstan-types.neon | 5 --
4 files changed, 130 deletions(-)
diff --git a/phpstan-baseline-level-3.neon b/phpstan-baseline-level-3.neon
index 1d5aa5252..0b55309e3 100644
--- a/phpstan-baseline-level-3.neon
+++ b/phpstan-baseline-level-3.neon
@@ -442,11 +442,6 @@ parameters:
count: 2
path: src/Bundle/ChillMainBundle/Workflow/Validator/StepDestValidValidator.php
- -
- message: "#^Return type \\(int\\|void\\|null\\) of method Chill\\\\PersonBundle\\\\Command\\\\ImportPeopleFromCSVCommand\\:\\:execute\\(\\) should be covariant with return type \\(int\\) of method Symfony\\\\Component\\\\Console\\\\Command\\\\Command\\:\\:execute\\(\\)$#"
- count: 1
- path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php
-
-
message: "#^Parameter \\#3 \\$query \\(Doctrine\\\\ORM\\\\QueryBuilder\\) of method Chill\\\\PersonBundle\\\\Controller\\\\HouseholdCompositionTypeApiController\\:\\:customizeQuery\\(\\) should be contravariant with parameter \\$query \\(mixed\\) of method Chill\\\\MainBundle\\\\CRUD\\\\Controller\\\\AbstractCRUDController\\:\\:customizeQuery\\(\\)$#"
count: 1
diff --git a/phpstan-baseline-level-4.neon b/phpstan-baseline-level-4.neon
index 432e06695..1b7bb5a07 100644
--- a/phpstan-baseline-level-4.neon
+++ b/phpstan-baseline-level-4.neon
@@ -3026,111 +3026,6 @@ parameters:
count: 2
path: src/Bundle/ChillPersonBundle/Command/ChillPersonMoveCommand.php
- -
- message: "#^Access to an undefined property Symfony\\\\Component\\\\EventDispatcher\\\\Event\\:\\:\\$force\\.$#"
- count: 1
- path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php
-
- -
- message: "#^Access to an undefined property Symfony\\\\Component\\\\EventDispatcher\\\\Event\\:\\:\\$headers\\.$#"
- count: 1
- path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php
-
- -
- message: "#^Access to an undefined property Symfony\\\\Component\\\\EventDispatcher\\\\Event\\:\\:\\$helperSet\\.$#"
- count: 1
- path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php
-
- -
- message: "#^Access to an undefined property Symfony\\\\Component\\\\EventDispatcher\\\\Event\\:\\:\\$input\\.$#"
- count: 1
- path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php
-
- -
- message: "#^Access to an undefined property Symfony\\\\Component\\\\EventDispatcher\\\\Event\\:\\:\\$output\\.$#"
- count: 1
- path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php
-
- -
- message: "#^Access to an undefined property Symfony\\\\Component\\\\EventDispatcher\\\\Event\\:\\:\\$person\\.$#"
- count: 1
- path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php
-
- -
- message: "#^Access to an undefined property Symfony\\\\Component\\\\EventDispatcher\\\\Event\\:\\:\\$rawHeaders\\.$#"
- count: 1
- path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php
-
- -
- message: "#^Access to an undefined property Symfony\\\\Component\\\\EventDispatcher\\\\Event\\:\\:\\$row\\.$#"
- count: 1
- path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php
-
- -
- message: "#^Access to an undefined property Symfony\\\\Component\\\\EventDispatcher\\\\Event\\:\\:\\$skipPerson\\.$#"
- count: 1
- path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php
-
- -
- message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\ObjectManager\\:\\:createQuery\\(\\)\\.$#"
- count: 1
- path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php
-
- -
- message: "#^Call to method buildForm\\(\\) on an unknown class Chill\\\\CustomFieldsBundle\\\\Service\\\\CustomFieldInterface\\.$#"
- count: 1
- path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php
-
- -
- message: "#^Else branch is unreachable because previous condition is always true\\.$#"
- count: 1
- path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php
-
- -
- message: "#^Elseif branch is unreachable because previous condition is always true\\.$#"
- count: 1
- path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php
-
- -
- message: "#^Instanceof between \\*NEVER\\* and Symfony\\\\Component\\\\Form\\\\ChoiceList\\\\View\\\\ChoiceGroupView will always evaluate to false\\.$#"
- count: 1
- path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php
-
- -
- message: "#^Instanceof between Symfony\\\\Component\\\\Form\\\\ChoiceList\\\\View\\\\ChoiceView and Symfony\\\\Component\\\\Form\\\\ChoiceList\\\\View\\\\ChoiceView will always evaluate to true\\.$#"
- count: 1
- path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php
-
- -
- message: "#^Method Chill\\\\PersonBundle\\\\Command\\\\ImportPeopleFromCSVCommand\\:\\:processTextType\\(\\) has invalid return type Chill\\\\PersonBundle\\\\Command\\\\type\\.$#"
- count: 1
- path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php
-
- -
- message: "#^Method Symfony\\\\Component\\\\Console\\\\Helper\\\\Table\\:\\:render\\(\\) invoked with 1 parameter, 0 required\\.$#"
- count: 1
- path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php
-
- -
- message: "#^Method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) invoked with 2 parameters, 1 required\\.$#"
- count: 1
- path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php
-
- -
- message: "#^PHPDoc tag @var above foreach loop does not specify variable name\\.$#"
- count: 1
- path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php
-
- -
- message: "#^Parameter \\$value of method Chill\\\\PersonBundle\\\\Command\\\\ImportPeopleFromCSVCommand\\:\\:processTextType\\(\\) has invalid type Chill\\\\PersonBundle\\\\Command\\\\type\\.$#"
- count: 1
- path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php
-
- -
- message: "#^Strict comparison using \\=\\=\\= between false and false will always evaluate to true\\.$#"
- count: 1
- path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php
-
-
message: "#^PHPDoc tag @var for property Chill\\\\PersonBundle\\\\Command\\\\ImportSocialWorkMetadata\\:\\:\\$importer with type Psr\\\\Log\\\\LoggerInterface is not subtype of native type Chill\\\\PersonBundle\\\\Service\\\\Import\\\\ChillImporter\\.$#"
count: 1
diff --git a/phpstan-baseline-level-5.neon b/phpstan-baseline-level-5.neon
index 10390e8da..23321ba68 100644
--- a/phpstan-baseline-level-5.neon
+++ b/phpstan-baseline-level-5.neon
@@ -425,21 +425,6 @@ parameters:
count: 2
path: src/Bundle/ChillPersonBundle/Actions/Remove/PersonMove.php
- -
- message: "#^Parameter \\#1 \\$event of method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) expects object, string given\\.$#"
- count: 1
- path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php
-
- -
- message: "#^Parameter \\#1 \\$mobilenumber of method Chill\\\\PersonBundle\\\\Entity\\\\Person\\:\\:setMobilenumber\\(\\) expects libphonenumber\\\\PhoneNumber\\|null, string given\\.$#"
- count: 1
- path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php
-
- -
- message: "#^Parameter \\#1 \\$phonenumber of method Chill\\\\PersonBundle\\\\Entity\\\\Person\\:\\:setPhonenumber\\(\\) expects libphonenumber\\\\PhoneNumber\\|null, string given\\.$#"
- count: 1
- path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php
-
-
message: "#^Parameter \\#1 \\$event of method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) expects object, string given\\.$#"
count: 1
diff --git a/phpstan-types.neon b/phpstan-types.neon
index d62c8bc4b..3368c94d2 100644
--- a/phpstan-types.neon
+++ b/phpstan-types.neon
@@ -310,11 +310,6 @@ parameters:
count: 1
path: src/Bundle/ChillPersonBundle/Command/ChillPersonMoveCommand.php
- -
- message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#"
- count: 6
- path: src/Bundle/ChillPersonBundle/Command/ImportPeopleFromCSVCommand.php
-
-
message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#"
count: 1
From 2a303c7ba4b50b4094d9e461303dd4de2eb41239 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Tue, 28 Mar 2023 23:01:00 +0200
Subject: [PATCH 15/46] DX: fix contravariant type-hinting on
ThirdPartyNormalizer
---
phpstan-baseline-level-3.neon | 10 ----------
.../Serializer/Normalizer/ThirdPartyNormalizer.php | 9 +++++----
2 files changed, 5 insertions(+), 14 deletions(-)
diff --git a/phpstan-baseline-level-3.neon b/phpstan-baseline-level-3.neon
index 0b55309e3..b7091f4ad 100644
--- a/phpstan-baseline-level-3.neon
+++ b/phpstan-baseline-level-3.neon
@@ -783,16 +783,6 @@ parameters:
count: 1
path: src/Bundle/ChillThirdPartyBundle/Security/Voter/ThirdPartyVoter.php
- -
- message: "#^Parameter \\#1 \\$thirdParty \\(Chill\\\\ThirdPartyBundle\\\\Entity\\\\ThirdParty\\) of method Chill\\\\ThirdPartyBundle\\\\Serializer\\\\Normalizer\\\\ThirdPartyNormalizer\\:\\:normalize\\(\\) should be contravariant with parameter \\$object \\(mixed\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:normalize\\(\\)$#"
- count: 1
- path: src/Bundle/ChillThirdPartyBundle/Serializer/Normalizer/ThirdPartyNormalizer.php
-
- -
- message: "#^Parameter \\#2 \\$format \\(string\\) of method Chill\\\\ThirdPartyBundle\\\\Serializer\\\\Normalizer\\\\ThirdPartyNormalizer\\:\\:supportsNormalization\\(\\) should be contravariant with parameter \\$format \\(string\\|null\\) of method Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\NormalizerInterface\\:\\:supportsNormalization\\(\\)$#"
- count: 1
- path: src/Bundle/ChillThirdPartyBundle/Serializer/Normalizer/ThirdPartyNormalizer.php
-
-
message: "#^Parameter \\#1 \\$document \\(Chill\\\\DocStoreBundle\\\\Entity\\\\StoredObject\\) of method Chill\\\\WopiBundle\\\\Service\\\\Wopi\\\\ChillDocumentManager\\:\\:getBasename\\(\\) should be contravariant with parameter \\$document \\(ChampsLibres\\\\WopiLib\\\\Contract\\\\Entity\\\\Document\\) of method ChampsLibres\\\\WopiLib\\\\Contract\\\\Service\\\\DocumentManagerInterface\\:\\:getBasename\\(\\)$#"
count: 1
diff --git a/src/Bundle/ChillThirdPartyBundle/Serializer/Normalizer/ThirdPartyNormalizer.php b/src/Bundle/ChillThirdPartyBundle/Serializer/Normalizer/ThirdPartyNormalizer.php
index 5f4cd1a9a..7b2721511 100644
--- a/src/Bundle/ChillThirdPartyBundle/Serializer/Normalizer/ThirdPartyNormalizer.php
+++ b/src/Bundle/ChillThirdPartyBundle/Serializer/Normalizer/ThirdPartyNormalizer.php
@@ -15,6 +15,7 @@ use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Chill\ThirdPartyBundle\Entity\ThirdPartyCategory;
use Chill\ThirdPartyBundle\Templating\Entity\ThirdPartyRender;
+use Symfony\Component\Serializer\Exception\UnexpectedValueException;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
@@ -35,12 +36,12 @@ class ThirdPartyNormalizer implements NormalizerAwareInterface, NormalizerInterf
$this->translatableStringHelper = $translatableStringHelper;
}
- /**
- * @param ThirdParty $thirdParty
- * @param string|null $format
- */
public function normalize($thirdParty, $format = null, array $context = [])
{
+ if (!$thirdParty instanceof ThirdParty) {
+ throw new UnexpectedValueException();
+ }
+
return [
'type' => 'thirdparty',
'firstname' => $thirdParty->getFirstname(),
From c5ec0e77ff9366226f2ef5e90460f0af0fbb92a9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Tue, 28 Mar 2023 23:16:03 +0200
Subject: [PATCH 16/46] DX: bootstrap rector
---
.gitlab-ci.yml | 14 ++++++++++++++
composer.json | 1 +
rector.php | 25 +++++++++++++++++++++++++
3 files changed, 40 insertions(+)
create mode 100644 rector.php
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 7ce9e1835..8fcd1a637 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -79,6 +79,20 @@ phpstan_tests:
- bin
- tests/app/vendor/
+rector_tests:
+ stage: Tests
+ image: gitea.champs-libres.be/chill-project/chill-skeleton-basic/base-image:php82
+ script:
+ - bin/rector --dry-run
+ cache:
+ paths:
+ - .cache/
+ artifacts:
+ expire_in: 30 min
+ paths:
+ - bin
+ - tests/app/vendor/
+
# psalm_tests:
# stage: Tests
# image: gitea.champs-libres.be/chill-project/chill-skeleton-basic/base-image:php82
diff --git a/composer.json b/composer.json
index 12fa59fd1..033b3f19b 100644
--- a/composer.json
+++ b/composer.json
@@ -75,6 +75,7 @@
"phpunit/phpunit": ">= 7.5",
"psalm/plugin-phpunit": "^0.18.4",
"psalm/plugin-symfony": "^4.0.2",
+ "rector/rector": "^0.15.23",
"symfony/debug-bundle": "^5.1",
"symfony/dotenv": "^4.4",
"symfony/maker-bundle": "^1.20",
diff --git a/rector.php b/rector.php
new file mode 100644
index 000000000..2c5b08bec
--- /dev/null
+++ b/rector.php
@@ -0,0 +1,25 @@
+paths([
+ __DIR__ . '/docs',
+ __DIR__ . '/src',
+ ]);
+
+ $rectorConfig->cacheClass(\Rector\Caching\ValueObject\Storage\FileCacheStorage::class);
+ $rectorConfig->cacheDirectory(__DIR__.'/.cache/rector');
+
+ // register a single rule
+ $rectorConfig->rule(InlineConstructorDefaultToPropertyRector::class);
+
+ // define sets of rules
+ // $rectorConfig->sets([
+ // LevelSetList::UP_TO_PHP_74
+ // ]);
+};
From ea10565e17c38c49cbdee4d8bb3d1c5e1d5acdc8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Tue, 28 Mar 2023 23:20:37 +0200
Subject: [PATCH 17/46] DX: [rector] apply rector rule
InlineConstructorDefaultToPropertyRector
---
src/Bundle/ChillPersonBundle/Privacy/PrivacyEvent.php | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/Bundle/ChillPersonBundle/Privacy/PrivacyEvent.php b/src/Bundle/ChillPersonBundle/Privacy/PrivacyEvent.php
index 7168a9703..b691c4e89 100644
--- a/src/Bundle/ChillPersonBundle/Privacy/PrivacyEvent.php
+++ b/src/Bundle/ChillPersonBundle/Privacy/PrivacyEvent.php
@@ -59,7 +59,7 @@ class PrivacyEvent extends Event
/**
* @var array
*/
- private $persons;
+ private $persons = [];
/**
* PrivacyEvent constructor.
@@ -68,7 +68,6 @@ class PrivacyEvent extends Event
{
$this->person = $person;
$this->args = $args;
- $this->persons = [];
}
public function addPerson(Person $person)
From 58faac5bca835bc0e7f48c67240dd362b13c6bff Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Tue, 28 Mar 2023 23:27:25 +0200
Subject: [PATCH 18/46] DX: fix cs
---
.../ChillPersonBundle/Form/Type/PickPersonDynamicType.php | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/Bundle/ChillPersonBundle/Form/Type/PickPersonDynamicType.php b/src/Bundle/ChillPersonBundle/Form/Type/PickPersonDynamicType.php
index 78e382f68..8ed0b7f37 100644
--- a/src/Bundle/ChillPersonBundle/Form/Type/PickPersonDynamicType.php
+++ b/src/Bundle/ChillPersonBundle/Form/Type/PickPersonDynamicType.php
@@ -36,8 +36,7 @@ class PickPersonDynamicType extends AbstractType
DenormalizerInterface $denormalizer,
SerializerInterface $serializer,
NormalizerInterface $normalizer
- )
- {
+ ) {
$this->denormalizer = $denormalizer;
$this->serializer = $serializer;
$this->normalizer = $normalizer;
From 40e751c783a1c499e053e3e5dac2f6af670a7390 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Wed, 29 Mar 2023 22:08:41 +0200
Subject: [PATCH 19/46] DX: clean classe
---
.../src/Form/AsideActivityFormType.php | 5 -----
1 file changed, 5 deletions(-)
diff --git a/src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityFormType.php b/src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityFormType.php
index c02e53c23..9a95a8d09 100644
--- a/src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityFormType.php
+++ b/src/Bundle/ChillAsideActivityBundle/src/Form/AsideActivityFormType.php
@@ -28,22 +28,17 @@ use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolver;
-use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use function in_array;
final class AsideActivityFormType extends AbstractType
{
- private TokenStorageInterface $storage;
-
private array $timeChoices;
public function __construct(
ParameterBagInterface $parameterBag,
- TokenStorageInterface $storage
) {
$this->timeChoices = $parameterBag->get('chill_aside_activity.form.time_duration');
- $this->storage = $storage;
}
public function buildForm(FormBuilderInterface $builder, array $options)
From a943639cf1b04bcfe83dd58e8d8536bd8a09e386 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Wed, 29 Mar 2023 22:11:45 +0200
Subject: [PATCH 20/46] Feature: [reassign] by default, see and reassign 50
courses at once
---
.../Controller/ReassignAccompanyingPeriodController.php | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php b/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php
index 91b834891..5b2de9f65 100644
--- a/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php
+++ b/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php
@@ -98,6 +98,7 @@ class ReassignAccompanyingPeriodController extends AbstractController
$total = $this->accompanyingPeriodACLAwareRepository->countByUserOpenedAccompanyingPeriod($userFrom);
$paginator = $this->paginatorFactory->create($total);
+ $paginator->setItemsPerPage(50);
$periods = $this->accompanyingPeriodACLAwareRepository
->findByUserAndPostalCodesOpenedAccompanyingPeriod(
$userFrom,
From 64b8ae3df12de8e7f34c4cffc34ab01900dab97c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Wed, 29 Mar 2023 22:15:20 +0200
Subject: [PATCH 21/46] DX: temporarily allow failure on unit tests
---
.gitlab-ci.yml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 8fcd1a637..3f1d75ed5 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -108,6 +108,8 @@ rector_tests:
unit_tests:
stage: Tests
image: gitea.champs-libres.be/chill-project/chill-skeleton-basic/base-image:php82
+ # until we fix testes
+ allow_failure: true
script:
- php tests/app/bin/console doctrine:migrations:migrate -n
- php -d memory_limit=2G tests/app/bin/console cache:clear --env=dev
From 866b92f7e5b8f95a58676c832de784ca057ea06f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Thu, 30 Mar 2023 16:29:02 +0200
Subject: [PATCH 22/46] Fixed: loading of main user through pick entity in
calendar form
---
.../ChillCalendarBundle/Entity/Calendar.php | 1 +
.../Resources/public/vuejs/Calendar/App.vue | 28 +++++++++++++++++--
.../public/vuejs/Calendar/store/actions.js | 2 ++
.../public/vuejs/Calendar/store/utils.ts | 2 +-
tests/app | 2 +-
5 files changed, 30 insertions(+), 5 deletions(-)
diff --git a/src/Bundle/ChillCalendarBundle/Entity/Calendar.php b/src/Bundle/ChillCalendarBundle/Entity/Calendar.php
index 56373ca17..cfe1fb2c3 100644
--- a/src/Bundle/ChillCalendarBundle/Entity/Calendar.php
+++ b/src/Bundle/ChillCalendarBundle/Entity/Calendar.php
@@ -92,6 +92,7 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface, HasCente
/**
* @ORM\ManyToOne(targetEntity="Chill\PersonBundle\Entity\AccompanyingPeriod", inversedBy="calendars")
+ * @Serializer\Groups({"calendar:read", "read"})
*/
private ?AccompanyingPeriod $accompanyingPeriod = null;
diff --git a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/App.vue b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/App.vue
index 32b6b569b..e09175a4b 100644
--- a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/App.vue
+++ b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/App.vue
@@ -15,6 +15,7 @@
:picked="null !== this.$store.getters.getMainUser ? [this.$store.getters.getMainUser] : []"
:removableIfSet="false"
:displayPicked="false"
+ :suggested="this.suggestedUsers"
@addNewEntity="setMainUser"
>
@@ -143,6 +144,7 @@ export default {
slotMinTime: '09:00:00',
slotMaxTime: '18:00:00',
hideWeekEnds: true,
+ previousUser: [],
}
},
computed: {
@@ -188,11 +190,23 @@ export default {
users.push(this.$store.getters.getUserDataById(id).user);
}
return users;
- }
+ },
+ suggestedUsers() {
+ const suggested = [];
+
+ this.$data.previousUser.forEach(u => {
+ if (u.id !== this.$store.getters.getMainUser.id) {
+ suggested.push(u)
+ }
+ });
+
+ return suggested;
+ },
},
methods: {
- setMainUser(user) {
- console.log('setMainUser APP', user);
+ setMainUser({entity}) {
+ const user = entity;
+ console.log('setMainUser APP', entity);
if (user.id !== this.$store.getters.getMainUser && (
this.$store.state.activity.calendarRange !== null
@@ -205,6 +219,14 @@ export default {
}
}
+ // add the previous user, if any, in the previous user list (in use for suggestion)
+ if (null !== this.$store.getters.getMainUser) {
+ const suggestedUids = new Set(this.$data.previousUser.map(u => u.id));
+ if (!suggestedUids.has(this.$store.getters.getMainUser.id)){
+ this.$data.previousUser.push(this.$store.getters.getMainUser);
+ }
+ }
+
this.$store.dispatch('setMainUser', user);
this.$store.commit('showUserOnCalendar', {user, ranges: true, remotes: true});
},
diff --git a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store/actions.js b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store/actions.js
index 1568944db..0e4d91afc 100644
--- a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store/actions.js
+++ b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store/actions.js
@@ -202,6 +202,8 @@ export default {
return dispatch('associateCalendarToRange', { range: null }).then(() => {
commit('setMainUser', mainUser);
+
+ return dispatch('fetchCalendarEvents');
});
},
diff --git a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store/utils.ts b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store/utils.ts
index 04ca26726..e9b24a1f0 100644
--- a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store/utils.ts
+++ b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/store/utils.ts
@@ -54,7 +54,7 @@ export const mapEntity = (entity: EventInput): EventInput => {
export const createUserData = (user: User, colorIndex: number): UserData => {
const colorId = colorIndex % COLORS.length;
- console.log('colorId', colorId);
+
return {
user: user,
calendarRanges: [],
diff --git a/tests/app b/tests/app
index 5b35e7ccd..5e478fdfb 160000
--- a/tests/app
+++ b/tests/app
@@ -1 +1 @@
-Subproject commit 5b35e7ccd0735e5593835e28acbf82386c18e1b6
+Subproject commit 5e478fdfbf429baf3ce852ae69eb1f7101b1b416
From 3c88630edc1e449824dd6d2cfd91699e2cb47f86 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Thu, 30 Mar 2023 17:13:25 +0200
Subject: [PATCH 23/46] fix: [calendar list on person page] add scripts to
download documents
---
.../Resources/views/Calendar/listByPerson.html.twig | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/listByPerson.html.twig b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/listByPerson.html.twig
index 7c5fdc639..9e3b59d2a 100644
--- a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/listByPerson.html.twig
+++ b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/listByPerson.html.twig
@@ -9,13 +9,13 @@
{% block js %}
{{ parent() }}
{{ encore_entry_script_tags('mod_answer') }}
- {{ encore_entry_script_tags('mod_async_upload') }}
+ {{ encore_entry_script_tags('mod_document_action_buttons_group') }}
{% endblock %}
{% block css %}
{{ parent() }}
{{ encore_entry_link_tags('mod_answer') }}
- {{ encore_entry_link_tags('mod_async_upload') }}
+ {{ encore_entry_link_tags('mod_document_action_buttons_group') }}
{% endblock %}
{% block content %}
From d290572ca8983c9cb02fb1093d5117593b72d51f Mon Sep 17 00:00:00 2001
From: Julie Lenaerts
Date: Thu, 30 Mar 2023 19:41:55 +0200
Subject: [PATCH 24/46] FIX [translation] add hardcoded text into a translation
---
.../Resources/public/vuejs/MyCalendarRange/App2.vue | 2 +-
.../Resources/public/vuejs/MyCalendarRange/i18n.ts | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/App2.vue b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/App2.vue
index fb17ba141..1d353baed 100644
--- a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/App2.vue
+++ b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/App2.vue
@@ -1,7 +1,7 @@
-
Lieu des plages de disponibilités créées
+
{{ $t('created_availabilities') }}
Date: Thu, 30 Mar 2023 20:25:59 +0200
Subject: [PATCH 25/46] =?UTF-8?q?change=20all=20translations=20using=20act?=
=?UTF-8?q?ivit=C3=A9=20to=20using=20=C3=A9change=20to=20make=20all=20chil?=
=?UTF-8?q?l=20versions=20coherent?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Controller/ActivityControllerTest.php | 8 +-
.../translations/messages.fr.yml | 68 +++++++--------
.../translations/messages.nl.yaml | 82 +++++++++----------
.../translations/validators.fr.yml | 34 ++++----
.../views/PersonDuplicate/_sidepane.html.twig | 2 +-
.../translations/messages.fr.yml | 10 +--
.../translations/validators.fr.yml | 2 +-
7 files changed, 103 insertions(+), 103 deletions(-)
diff --git a/src/Bundle/ChillActivityBundle/Tests/Controller/ActivityControllerTest.php b/src/Bundle/ChillActivityBundle/Tests/Controller/ActivityControllerTest.php
index e689e205d..e9905b171 100644
--- a/src/Bundle/ChillActivityBundle/Tests/Controller/ActivityControllerTest.php
+++ b/src/Bundle/ChillActivityBundle/Tests/Controller/ActivityControllerTest.php
@@ -121,14 +121,14 @@ final class ActivityControllerTest extends WebTestCase
$client->getResponse()->getStatusCode(),
'Unexpected HTTP status code for GET /activity/'
);
- $crawler = $client->click($crawler->selectLink('Ajouter une nouvelle activité')
+ $crawler = $client->click($crawler->selectLink('Ajouter un nouveau échange')
->link());
$reason1 = $this->getRandomActivityReason();
$reason2 = $this->getRandomActivityReason([$reason1->getId()]);
// Fill in the form and submit it
- $form = $crawler->selectButton('Ajouter une nouvelle activité')->form([
+ $form = $crawler->selectButton('Ajouter un nouveau échange')->form([
'chill_activitybundle_activity' => [
'date' => '15-01-2015',
'durationTime' => 600,
@@ -152,9 +152,9 @@ final class ActivityControllerTest extends WebTestCase
);
// Edit the entity
- $crawler = $client->click($crawler->selectLink("Modifier l'activité")->link());
+ $crawler = $client->click($crawler->selectLink("Modifier l'échange")->link());
- $form = $crawler->selectButton("Sauver l'activité")->form([
+ $form = $crawler->selectButton("Sauver l'échange")->form([
'chill_activitybundle_activity' => [
'date' => '25-01-2015',
// 'remark' => 'Foo'
diff --git a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml
index 4dd67ceb8..3fb25d2d7 100644
--- a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml
+++ b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml
@@ -1,7 +1,7 @@
#general
-Show the activity: Voir l'activité
-Edit the activity: Modifier l'activité
-Activity: Activité
+Show the activity: Voir l'échange
+Edit the activity: Modifier l'échange
+Activity: Échange
Duration time: Durée
Duration Time: Durée
durationTime: durée
@@ -13,21 +13,21 @@ user_username: nom de l'utilisateur
circle_name: nom du cercle
Remark: Commentaire
No comments: Aucun commentaire
-Add a new activity: Ajouter une nouvelle activité
-Activity list: Liste des activités
+Add a new activity: Ajouter une nouvelle échange
+Activity list: Liste des échanges
present: présent
not present: absent
Delete: Supprimer
Update: Mettre à jour
-Update activity: Modifier l'activité
+Update activity: Modifier l'échange
Scope: Cercle
-Activity data: Données de l'activité
-Activity location: Localisation de l'activité
+Activity data: Données de l'échange
+Activity location: Localisation de l'échange
No reason associated: Aucun sujet
No social issues associated: Aucune problématique sociale
No social actions associated: Aucune action d'accompagnement
-There isn't any activities.: Aucune activité enregistrée.
-type_name: type de l'activité
+There isn't any activities.: Aucun échange enregistrée.
+type_name: type de l'échange
person_firstname: prénom
person_lastname: nom de famille
person_id: identifiant de la personne
@@ -50,10 +50,10 @@ received: Reçu
#forms
-Activity creation: Nouvelle activité
+Activity creation: Nouvelle échange
Create: Créer
Back to the list: Retour à la liste
-Save activity: Sauver l'activité
+Save activity: Sauver l'échange
Reset form: Remise à zéro du formulaire
Choose the duration: Choisir la durée
Choose a type: Choisir un type
@@ -90,40 +90,40 @@ activity:
No documents: Aucun document
#timeline
-'%user% has done an %activity_type%': '%user% a effectué une activité de type "%activity_type%"'
+'%user% has done an %activity_type%': '%user% a effectué un échange de type "%activity_type%"'
#controller
-'Success : activity created!': L'activité a été créée.
-'The form is not valid. The activity has not been created !': Le formulaire est invalide. L'activité n'a pas été créée.
-'Success : activity updated!': L'activité a été mise à jour.
-'The form is not valid. The activity has not been updated !': Le formulaire est invalide. L'activité n'a pas été mise à jour.
+'Success : activity created!': L'échange a été créée.
+'The form is not valid. The activity has not been created !': Le formulaire est invalide. L'échange n'a pas été créée.
+'Success : activity updated!': L'échange a été mise à jour.
+'The form is not valid. The activity has not been updated !': Le formulaire est invalide. L'échange n'a pas été mise à jour.
# ROLES
-CHILL_ACTIVITY_CREATE: Créer une activité
-CHILL_ACTIVITY_UPDATE: Modifier une activité
-CHILL_ACTIVITY_SEE: Voir une activité
-CHILL_ACTIVITY_SEE_DETAILS: Voir le détail des activités
-CHILL_ACTIVITY_DELETE: Supprimer une activité
-CHILL_ACTIVITY_STATS: Statistique des activités
-CHILL_ACTIVITY_LIST: Liste des activités
+CHILL_ACTIVITY_CREATE: Créer un échange
+CHILL_ACTIVITY_UPDATE: Modifier un échange
+CHILL_ACTIVITY_SEE: Voir un échange
+CHILL_ACTIVITY_SEE_DETAILS: Voir le détail des échanges
+CHILL_ACTIVITY_DELETE: Supprimer un échange
+CHILL_ACTIVITY_STATS: Statistique des échanges
+CHILL_ACTIVITY_LIST: Liste des échanges
# admin
-Activities: Activités
-Activity configuration: Configuration des activités
-Activity configuration menu: Configuration des activités
-Activity types: Types d'activité
-Activity type configuration: Configuration des categories d'activités
-Activity Reasons: Sujets d'une activité
-Activity Reasons Category: Catégories de sujet d'activités
-Activity Types Categories: Catégories des types d'activité
-Activity Presences: Presences aux activités
+Activities: Échanges
+Activity configuration: Configuration des échanges
+Activity configuration menu: Configuration des échanges
+Activity types: Types d'échange
+Activity type configuration: Configuration des categories d'échanges
+Activity Reasons: Sujets d'un échange
+Activity Reasons Category: Catégories de sujet d'échanges
+Activity Types Categories: Catégories des types d'échange
+Activity Presences: Presences aux échanges
Associated activity reason category is inactive: La catégorie de sujet attachée est inactive
# Crud
crud:
activity_type:
- title_new: Nouveau type d'activité
+ title_new: Nouveau type d'échange
title_edit: Edition d'un type d'activité
activity_type_category:
title_new: Nouvelle catégorie de type d'activité
diff --git a/src/Bundle/ChillActivityBundle/translations/messages.nl.yaml b/src/Bundle/ChillActivityBundle/translations/messages.nl.yaml
index dac37fc7d..94a874b99 100644
--- a/src/Bundle/ChillActivityBundle/translations/messages.nl.yaml
+++ b/src/Bundle/ChillActivityBundle/translations/messages.nl.yaml
@@ -47,10 +47,10 @@ Reasons: Onderwerpen
#forms
-Activity creation: Nouvelle activité
+Activity creation: Nouvelle échange
Create: Créer
Back to the list: Retour à la liste
-Save activity: Sauver l'activité
+Save activity: Sauver l'échange
Reset form: Remise à zéro du formulaire
Choose the duration: Choisir la durée
Choose a type: Choisir un type
@@ -79,43 +79,43 @@ activity:
No documents: Aucun document
#timeline
-'%user% has done an %activity_type%': '%user% a effectué une activité de type "%activity_type%"'
+'%user% has done an %activity_type%': '%user% a effectué un échange de type "%activity_type%"'
#controller
-'Success : activity created!': L'activité a été créée.
-'The form is not valid. The activity has not been created !': Le formulaire est invalide. L'activité n'a pas été créée.
-'Success : activity updated!': L'activité a été mise à jour.
-'The form is not valid. The activity has not been updated !': Le formulaire est invalide. L'activité n'a pas été mise à jour.
+'Success : activity created!': L'échange a été créée.
+'The form is not valid. The activity has not been created !': Le formulaire est invalide. L'échange n'a pas été créée.
+'Success : activity updated!': L'échange a été mise à jour.
+'The form is not valid. The activity has not been updated !': Le formulaire est invalide. L'échange n'a pas été mise à jour.
# ROLES
-CHILL_ACTIVITY_CREATE: Créer une activité
-CHILL_ACTIVITY_UPDATE: Modifier une activité
-CHILL_ACTIVITY_SEE: Voir une activité
-CHILL_ACTIVITY_SEE_DETAILS: Voir le détail des activités
-CHILL_ACTIVITY_DELETE: Supprimer une activité
-CHILL_ACTIVITY_STATS: Statistique des activités
-CHILL_ACTIVITY_LIST: Liste des activités
+CHILL_ACTIVITY_CREATE: Créer un échange
+CHILL_ACTIVITY_UPDATE: Modifier un échange
+CHILL_ACTIVITY_SEE: Voir un échange
+CHILL_ACTIVITY_SEE_DETAILS: Voir le détail des échanges
+CHILL_ACTIVITY_DELETE: Supprimer un échange
+CHILL_ACTIVITY_STATS: Statistique des échanges
+CHILL_ACTIVITY_LIST: Liste des échanges
# admin
-Activities: Activités
-Activity configuration: Configuration des activités
-Activity configuration menu: Configuration des activités
-Activity types: Types d'activité
-Activity type configuration: Configuration des categories d'activités
-Activity Reasons: Sujets d'une activité
-Activity Reasons Category: Catégories de sujet d'activités
-Activity Types Categories: Catégories des types d'activité
-Activity Presences: Presences des activités
+Activities: Échanges
+Activity configuration: Configuration des échanges
+Activity configuration menu: Configuration des échanges
+Activity types: Types d'échange
+Activity type configuration: Configuration des categories d'échanges
+Activity Reasons: Sujets d'un échange
+Activity Reasons Category: Catégories de sujet d'échanges
+Activity Types Categories: Catégories des types d'échanges
+Activity Presences: Presences des échanges
# Crud
crud:
activity_type:
- title_new: Nouveau type d'activité
- title_edit: Edition d'un type d'activité
+ title_new: Nouveau type d'échange
+ title_edit: Edition d'un type d'échange
activity_type_category:
- title_new: Nouvelle catégorie de type d'activité
- title_edit: Edition d'une catégorie de type d'activité
+ title_new: Nouvelle catégorie de type d'échange
+ title_edit: Edition d'une catégorie de type d'échange
# activity reason admin
ActivityReason list: Liste des sujets
@@ -124,7 +124,7 @@ Active: Actif
Category: Catégorie
ActivityReason creation: Nouveau sujet
ActivityReason edit: Modification d'un sujet
-ActivityReason: Sujet d'activité
+ActivityReason: Sujet d'échange
The entity is inactive and won't be proposed: Le sujet est inactif et ne sera pas proposé
The entity is active and will be proposed: Le sujet est actif et sera proposé
@@ -133,13 +133,13 @@ ActivityReasonCategory list: Catégories de sujets
Create a new activity category reason: Créer une nouvelle catégorie
ActivityReasonCategory creation: Nouvelle catégorie de sujet
ActivityReasonCategory edit: Modification d'une catégorie de sujet
-ActivityReasonCategory: Catégorie de sujet d'activité
+ActivityReasonCategory: Catégorie de sujet d'échange
ActivityReasonCategory is active and will be proposed: La catégorie est active et sera proposée
ActivityReasonCategory is inactive and won't be proposed: La catégorie est inactive et ne sera pas proposée
# activity type type admin
-ActivityType list: Types d'activités
-Create a new activity type: Créer un nouveau type d'activité
+ActivityType list: Types d'échanges
+Create a new activity type: Créer un nouveau type d'échange
Persons visible: Visibilité du champ Personnes
Persons label: Libellé du champ Personnes
User visible: Visibilité du champ Utilisateur
@@ -177,20 +177,20 @@ Documents label: Libellé du champ Documents
# activity type category admin
ActivityTypeCategory list: Liste des catégories des types d'activité
-Create a new activity type category: Créer une nouvelle catégorie de type d'activité
+Create a new activity type category: Créer une nouvelle catégorie de type d'échange
# activity delete
-Remove activity: Supprimer une activité
-Are you sure you want to remove the activity about "%name%" ?: Êtes-vous sûr de vouloir supprimer une activité qui concerne "%name%" ?
-The activity has been successfully removed.: L'activité a été supprimée.
+Remove activity: Supprimer un échange
+Are you sure you want to remove the activity about "%name%" ?: Êtes-vous sûr de vouloir supprimer un échange qui concerne "%name%" ?
+The activity has been successfully removed.: L'échange a été supprimée.
# exports
-Count activities: Nombre d'activités
-Count activities by various parameters.: Compte le nombre d'activités enregistrées en fonction de différents paramètres.
-Sum activity duration: Total de la durée des activités
-Sum activities duration by various parameters.: Additionne la durée des activités en fonction de différents paramètres.
-List activities: Liste les activités
-Number of activities: Nombre d'activités
+Count activities: Nombre d'échanges
+Count activities by various parameters.: Compte le nombre d'échanges enregistrées en fonction de différents paramètres.
+Sum activity duration: Total de la durée des échanges
+Sum activities duration by various parameters.: Additionne la durée des échanges en fonction de différents paramètres.
+List activities: Liste les échanges
+Number of activities: Nombre d'échanges
#filters
Filter by reason: Filtrer par sujet d'activité
diff --git a/src/Bundle/ChillActivityBundle/translations/validators.fr.yml b/src/Bundle/ChillActivityBundle/translations/validators.fr.yml
index f2c104828..14617e752 100644
--- a/src/Bundle/ChillActivityBundle/translations/validators.fr.yml
+++ b/src/Bundle/ChillActivityBundle/translations/validators.fr.yml
@@ -1,22 +1,22 @@
The reasons's level should not be empty: Le niveau du sujet ne peut pas être vide
At least one reason must be choosen: Au moins un sujet doit être choisi
-For this type of activity, you must add at least one person: Pour ce type d'activité, vous devez ajouter au moins un usager
-For this type of activity, you must add at least one user: Pour ce type d'activité, vous devez ajouter au moins un utilisateur
-For this type of activity, you must add at least one third party: Pour ce type d'activité, vous devez ajouter au moins un tiers
-For this type of activity, user is required: Pour ce type d'activité, l'utilisateur est requis
-For this type of activity, date is required: Pour ce type d'activité, la date est requise
-For this type of activity, location is required: Pour ce type d'activité, la localisation est requise
-For this type of activity, attendee is required: Pour ce type d'activité, le champ "Présence de la personne" est requis
-For this type of activity, duration time is required: Pour ce type d'activité, la durée est requise
-For this type of activity, travel time is required: Pour ce type d'activité, la durée du trajet est requise
-For this type of activity, reasons is required: Pour ce type d'activité, le champ "sujet" est requis
-For this type of activity, comment is required: Pour ce type d'activité, un commentaire est requis
-For this type of activity, sent/received is required: Pour ce type d'activité, le champ Entrant/Sortant est requis
-For this type of activity, document is required: Pour ce type d'activité, un document est requis
-For this type of activity, emergency is required: Pour ce type d'activité, le champ "Urgent" est requis
-For this type of activity, accompanying period is required: Pour ce type d'activité, le parcours d'accompagnement est requis
-For this type of activity, you must add at least one social issue: Pour ce type d'activité, vous devez ajouter au moins une problématique sociale
-For this type of activity, you must add at least one social action: Pour ce type d'activité, vous devez indiquer au moins une action sociale
+For this type of activity, you must add at least one person: Pour ce type d'échange, vous devez ajouter au moins un usager
+For this type of activity, you must add at least one user: Pour ce type d'échange, vous devez ajouter au moins un utilisateur
+For this type of activity, you must add at least one third party: Pour ce type d'échange, vous devez ajouter au moins un tiers
+For this type of activity, user is required: Pour ce type d'échange, l'utilisateur est requis
+For this type of activity, date is required: Pour ce type d'échange, la date est requise
+For this type of activity, location is required: Pour ce type d'échange, la localisation est requise
+For this type of activity, attendee is required: Pour ce type d'échange, le champ "Présence de la personne" est requis
+For this type of activity, duration time is required: Pour ce type d'échange, la durée est requise
+For this type of activity, travel time is required: Pour ce type d'échange, la durée du trajet est requise
+For this type of activity, reasons is required: Pour ce type d'échange, le champ "sujet" est requis
+For this type of activity, comment is required: Pour ce type d'échange, un commentaire est requis
+For this type of activity, sent/received is required: Pour ce type d'échange, le champ Entrant/Sortant est requis
+For this type of activity, document is required: Pour ce type d'échange, un document est requis
+For this type of activity, emergency is required: Pour ce type d'échange, le champ "Urgent" est requis
+For this type of activity, accompanying period is required: Pour ce type d'échange, le parcours d'accompagnement est requis
+For this type of activity, you must add at least one social issue: Pour ce type d'échange, vous devez ajouter au moins une problématique sociale
+For this type of activity, you must add at least one social action: Pour ce type d'échange, vous devez indiquer au moins une action sociale
# admin
This parameter must be equal to social issue parameter: Ce paramètre doit être égal au paramètre "Visibilité du champs Problématiques sociales"
diff --git a/src/Bundle/ChillPersonBundle/Resources/views/PersonDuplicate/_sidepane.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/PersonDuplicate/_sidepane.html.twig
index f7fef7f93..660fff7a6 100644
--- a/src/Bundle/ChillPersonBundle/Resources/views/PersonDuplicate/_sidepane.html.twig
+++ b/src/Bundle/ChillPersonBundle/Resources/views/PersonDuplicate/_sidepane.html.twig
@@ -36,7 +36,7 @@
{%- macro links(person, options) -%}
- {{ person.counters.nb_activity }} {{ (person.counters.nb_activity > 1)? 'activités' : 'activité' }}
+ {{ person.counters.nb_activity }} {{ (person.counters.nb_activity > 1)? 'échanges' : 'échange' }}
{{ person.counters.nb_task }} {{ (person.counters.nb_task > 1)? 'tâches' : 'tâche' }}
{{ person.counters.nb_document }} {{ (person.counters.nb_document > 1)? 'documents' : 'document' }}
{{ person.counters.nb_event }} {{ (person.counters.nb_event > 1)? 'événements' : 'événement' }}
diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml
index 090f35c1c..b22916313 100644
--- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml
+++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml
@@ -450,8 +450,8 @@ Having an accompanying period closed after this date: Ayant une période d'accom
"Having an accompanying period closed before this date": "Ayant une période d'accompagnement fermée avant cette date"
"Filtered by accompanying period: persons having an accompanying period closed between the %date_from% and %date_to%": "Filtrer par période d'accompagnement: ayant une période fermée entre le %date_from% et le %date_to%"
-Filter by person having an activity in a period: Filtrer les personnes ayant eu une échange pendant la période donnée
-Filtered by person having an activity between %date_from% and %date_to% with reasons %reasons_name%: Uniquement les personnes associées à une échange entre %date_from% et %date_to% avec les sujets %reasons_name%
+Filter by person having an activity in a period: Filtrer les personnes ayant eu un échange pendant la période donnée
+Filtered by person having an activity between %date_from% and %date_to% with reasons %reasons_name%: Uniquement les personnes associées à un échange entre %date_from% et %date_to% avec les sujets %reasons_name%
## accompanying course filters/aggr
@@ -500,9 +500,9 @@ Evaluation: Évaluation
"Filtered by evaluations: only %evals%": "Filtré par évaluation: uniquement %evals%"
Group by evaluation: Grouper les parcours par évaluation
-Filter accompanying course by activity type: Filtrer les parcours par type d'activité
-Accepted activitytypes: Types d'activités
-"Filtered by activity types: only %activitytypes%": "Filtré par type d'activité: seulement %activitytypes%"
+Filter accompanying course by activity type: Filtrer les parcours par type d'échange
+Accepted activitytypes: Types d'échanges
+"Filtered by activity types: only %activitytypes%": "Filtré par type d'échange: seulement %activitytypes%"
Filter by origin: Filtrer les parcours par origine du parcours
Accepted origins: Origines
diff --git a/src/Bundle/ChillPersonBundle/translations/validators.fr.yml b/src/Bundle/ChillPersonBundle/translations/validators.fr.yml
index 496a84921..cda82aa89 100644
--- a/src/Bundle/ChillPersonBundle/translations/validators.fr.yml
+++ b/src/Bundle/ChillPersonBundle/translations/validators.fr.yml
@@ -53,7 +53,7 @@ household_membership:
'{{ name }} is already associated to this accompanying course.': '{{ name }} est déjà associé à ce parcours.'
A course must contains at least one social issue: 'Un parcours doit être associé à au moins une problématique sociale'
A course must be associated to at least one scope: 'Un parcours doit être associé à au moins un service'
-The social %name% issue cannot be deleted because it is associated with an activity or an action: 'La problématique sociale "%name%" ne peut pas être supprimée car elle est associée à une activité ou une action'
+The social %name% issue cannot be deleted because it is associated with an activity or an action: 'La problématique sociale "%name%" ne peut pas être supprimée car elle est associée à un échange ou une action'
A confidential parcours must have a referrer: 'Un parcours confidentiel doit avoir un référent'
Only the referrer can change the confidentiality of a parcours: 'Seul le référent peut modifier la confidentialité'
From 3ce6af4c36d2aabfe2c2b66e33349e034488a0df Mon Sep 17 00:00:00 2001
From: Julie Lenaerts
Date: Fri, 31 Mar 2023 12:01:35 +0200
Subject: [PATCH 26/46] =?UTF-8?q?FIX=20[translations]=20last=20fixes=20for?=
=?UTF-8?q?=20translations=20cr=C3=A9=C3=A9=20instead=20of=20cr=C3=A9?=
=?UTF-8?q?=C3=A9e?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/Bundle/ChillActivityBundle/translations/messages.fr.yml | 4 ++--
src/Bundle/ChillActivityBundle/translations/messages.nl.yaml | 4 ++--
.../ChillAsideActivityBundle/src/translations/messages.fr.yml | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml
index 3fb25d2d7..60fa1ba03 100644
--- a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml
+++ b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml
@@ -93,8 +93,8 @@ No documents: Aucun document
'%user% has done an %activity_type%': '%user% a effectué un échange de type "%activity_type%"'
#controller
-'Success : activity created!': L'échange a été créée.
-'The form is not valid. The activity has not been created !': Le formulaire est invalide. L'échange n'a pas été créée.
+'Success : activity created!': L'échange a été créé.
+'The form is not valid. The activity has not been created !': Le formulaire est invalide. L'échange n'a pas été créé.
'Success : activity updated!': L'échange a été mise à jour.
'The form is not valid. The activity has not been updated !': Le formulaire est invalide. L'échange n'a pas été mise à jour.
diff --git a/src/Bundle/ChillActivityBundle/translations/messages.nl.yaml b/src/Bundle/ChillActivityBundle/translations/messages.nl.yaml
index 94a874b99..24bed2c54 100644
--- a/src/Bundle/ChillActivityBundle/translations/messages.nl.yaml
+++ b/src/Bundle/ChillActivityBundle/translations/messages.nl.yaml
@@ -82,8 +82,8 @@ No documents: Aucun document
'%user% has done an %activity_type%': '%user% a effectué un échange de type "%activity_type%"'
#controller
-'Success : activity created!': L'échange a été créée.
-'The form is not valid. The activity has not been created !': Le formulaire est invalide. L'échange n'a pas été créée.
+'Success : activity created!': L'échange a été créé.
+'The form is not valid. The activity has not been created !': Le formulaire est invalide. L'échange n'a pas été créé.
'Success : activity updated!': L'échange a été mise à jour.
'The form is not valid. The activity has not been updated !': Le formulaire est invalide. L'échange n'a pas été mise à jour.
diff --git a/src/Bundle/ChillAsideActivityBundle/src/translations/messages.fr.yml b/src/Bundle/ChillAsideActivityBundle/src/translations/messages.fr.yml
index 0c807479f..362f87fe5 100644
--- a/src/Bundle/ChillAsideActivityBundle/src/translations/messages.fr.yml
+++ b/src/Bundle/ChillAsideActivityBundle/src/translations/messages.fr.yml
@@ -50,7 +50,7 @@ For agent: Pour l'utilisateur
date: Date
Duration: Durée
Note: Note
-Choose the agent for whom this activity is created: Choisissez l'agent pour qui l'activité est créée
+Choose the agent for whom this activity is created: Choisissez l'agent pour qui l'échange est créé
Choose the activity category: Choisir la catégorie
#Duration
From 94a099c30c7d64a70a357282d86e94020d7fd23c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Fri, 31 Mar 2023 12:29:00 +0000
Subject: [PATCH 27/46] =?UTF-8?q?fix=20typo=20in=20=C3=A9change=20gender?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Tests/Controller/ActivityControllerTest.php | 4 ++--
.../ChillActivityBundle/translations/messages.fr.yml | 10 +++++-----
.../ChillActivityBundle/translations/messages.nl.yaml | 6 +++---
3 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/src/Bundle/ChillActivityBundle/Tests/Controller/ActivityControllerTest.php b/src/Bundle/ChillActivityBundle/Tests/Controller/ActivityControllerTest.php
index e9905b171..8e2c219f0 100644
--- a/src/Bundle/ChillActivityBundle/Tests/Controller/ActivityControllerTest.php
+++ b/src/Bundle/ChillActivityBundle/Tests/Controller/ActivityControllerTest.php
@@ -121,14 +121,14 @@ final class ActivityControllerTest extends WebTestCase
$client->getResponse()->getStatusCode(),
'Unexpected HTTP status code for GET /activity/'
);
- $crawler = $client->click($crawler->selectLink('Ajouter un nouveau échange')
+ $crawler = $client->click($crawler->selectLink('Ajouter un nouvel échange')
->link());
$reason1 = $this->getRandomActivityReason();
$reason2 = $this->getRandomActivityReason([$reason1->getId()]);
// Fill in the form and submit it
- $form = $crawler->selectButton('Ajouter un nouveau échange')->form([
+ $form = $crawler->selectButton('Ajouter un nouvel échange')->form([
'chill_activitybundle_activity' => [
'date' => '15-01-2015',
'durationTime' => 600,
diff --git a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml
index 60fa1ba03..03ea01503 100644
--- a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml
+++ b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml
@@ -13,7 +13,7 @@ user_username: nom de l'utilisateur
circle_name: nom du cercle
Remark: Commentaire
No comments: Aucun commentaire
-Add a new activity: Ajouter une nouvelle échange
+Add a new activity: Ajouter une nouvel échange
Activity list: Liste des échanges
present: présent
not present: absent
@@ -26,7 +26,7 @@ Activity location: Localisation de l'échange
No reason associated: Aucun sujet
No social issues associated: Aucune problématique sociale
No social actions associated: Aucune action d'accompagnement
-There isn't any activities.: Aucun échange enregistrée.
+There isn't any activities.: Aucun échange enregistré.
type_name: type de l'échange
person_firstname: prénom
person_lastname: nom de famille
@@ -50,7 +50,7 @@ received: Reçu
#forms
-Activity creation: Nouvelle échange
+Activity creation: Nouvel échange
Create: Créer
Back to the list: Retour à la liste
Save activity: Sauver l'échange
@@ -95,7 +95,7 @@ No documents: Aucun document
#controller
'Success : activity created!': L'échange a été créé.
'The form is not valid. The activity has not been created !': Le formulaire est invalide. L'échange n'a pas été créé.
-'Success : activity updated!': L'échange a été mise à jour.
+'Success : activity updated!': L'échange a été mis à jour.
'The form is not valid. The activity has not been updated !': Le formulaire est invalide. L'échange n'a pas été mise à jour.
# ROLES
@@ -112,7 +112,7 @@ Activities: Échanges
Activity configuration: Configuration des échanges
Activity configuration menu: Configuration des échanges
Activity types: Types d'échange
-Activity type configuration: Configuration des categories d'échanges
+Activity type configuration: Configuration des catégories d'échanges
Activity Reasons: Sujets d'un échange
Activity Reasons Category: Catégories de sujet d'échanges
Activity Types Categories: Catégories des types d'échange
diff --git a/src/Bundle/ChillActivityBundle/translations/messages.nl.yaml b/src/Bundle/ChillActivityBundle/translations/messages.nl.yaml
index 24bed2c54..c7dc05f2b 100644
--- a/src/Bundle/ChillActivityBundle/translations/messages.nl.yaml
+++ b/src/Bundle/ChillActivityBundle/translations/messages.nl.yaml
@@ -47,7 +47,7 @@ Reasons: Onderwerpen
#forms
-Activity creation: Nouvelle échange
+Activity creation: Nouvel échange
Create: Créer
Back to the list: Retour à la liste
Save activity: Sauver l'échange
@@ -84,8 +84,8 @@ No documents: Aucun document
#controller
'Success : activity created!': L'échange a été créé.
'The form is not valid. The activity has not been created !': Le formulaire est invalide. L'échange n'a pas été créé.
-'Success : activity updated!': L'échange a été mise à jour.
-'The form is not valid. The activity has not been updated !': Le formulaire est invalide. L'échange n'a pas été mise à jour.
+'Success : activity updated!': L'échange a été mis à jour.
+'The form is not valid. The activity has not been updated !': Le formulaire est invalide. L'échange n'a pas été mis à jour.
# ROLES
CHILL_ACTIVITY_CREATE: Créer un échange
From 70141fd0e31dd61c41a63c1ad3eecc94eb65a52d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Fri, 31 Mar 2023 14:36:55 +0200
Subject: [PATCH 28/46] =?UTF-8?q?UI:=20rename=20'liste=20des=20=C3=A9chang?=
=?UTF-8?q?es'=20to=20"=C3=A9changes"=20in=20person=20menu?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/Bundle/ChillActivityBundle/Menu/PersonMenuBuilder.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Bundle/ChillActivityBundle/Menu/PersonMenuBuilder.php b/src/Bundle/ChillActivityBundle/Menu/PersonMenuBuilder.php
index 3a4da753d..03a1b09ab 100644
--- a/src/Bundle/ChillActivityBundle/Menu/PersonMenuBuilder.php
+++ b/src/Bundle/ChillActivityBundle/Menu/PersonMenuBuilder.php
@@ -48,7 +48,7 @@ final class PersonMenuBuilder implements LocalMenuBuilderInterface
if ($this->authorizationChecker->isGranted(ActivityVoter::SEE, $person)) {
$menu->addChild(
- $this->translator->trans('Activity list'),
+ $this->translator->trans('Activities'),
[
'route' => 'chill_activity_activity_list',
'routeParameters' => ['person_id' => $person->getId()],
From ee61d131ecbb39e69d2130f8a3e6e9b31b5112e7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Fri, 31 Mar 2023 14:54:02 +0200
Subject: [PATCH 29/46] UI: Replace "personne" by usager in french translation
---
.../translations/messages.fr.yml | 26 +--
.../translations/validators.fr.yml | 2 +-
.../src/translations/messages.fr.yml | 2 +-
.../translations/messages.fr.yml | 2 +-
.../translations/messages.fr.yml | 4 +-
.../translations/validators.fr.yml | 2 +-
.../translations/messages.fr.yml | 4 +-
.../translations/messages.fr.yml | 4 +-
.../translations/messages.fr.yml | 212 +++++++++---------
.../translations/validators.fr.yml | 6 +-
.../translations/messages.fr.yml | 6 +-
.../translations/messages.fr.yml | 8 +-
12 files changed, 139 insertions(+), 139 deletions(-)
diff --git a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml
index 03ea01503..63324cd0d 100644
--- a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml
+++ b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml
@@ -6,8 +6,8 @@ Duration time: Durée
Duration Time: Durée
durationTime: durée
Travel time: Durée de déplacement
-Attendee: Présence de la personne
-attendee: présence de la personne
+Attendee: Présence de l'usager
+attendee: présence de l'usager
list_reasons: liste des sujets
user_username: nom de l'utilisateur
circle_name: nom du cercle
@@ -30,12 +30,12 @@ There isn't any activities.: Aucun échange enregistré.
type_name: type de l'échange
person_firstname: prénom
person_lastname: nom de famille
-person_id: identifiant de la personne
+person_id: identifiant de l'usager
Type: Type
Invisible: Invisible
Optional: Optionnel
Required: Obligatoire
-Persons: Personnes
+Persons: Usagers
Users: Utilisateurs
Emergency: Urgent
Sent received: Entrant / Sortant
@@ -159,8 +159,8 @@ Create a new activity presence: Créer une nouvelle "Présence aux activités"
# activity type type admin
ActivityType list: Types d'activités
Create a new activity type: Créer un nouveau type d'activité
-Persons visible: Visibilité du champ Personnes
-Persons label: Libellé du champ Personnes
+Persons visible: Visibilité du champ Usagers
+Persons label: Libellé du champ Usagers
User visible: Visibilité du champ Utilisateur
User label: Libellé du champ Utilisateur
Date visible: Visibilité du champ Date
@@ -206,10 +206,10 @@ Are you sure you want to remove the activity about "%name%" ?: Êtes-vous sûr d
The activity has been successfully removed.: L'activité a été supprimée.
# exports
-Exports of activities linked to a person: Exports des activités liées à une personne
-Number of activities linked to a person: Nombre d'activités liées à une personne
+Exports of activities linked to a person: Exports des activités liées à un usager
+Number of activities linked to a person: Nombre d'activités liées à un usager
Count activities linked to a person: Nombre d'activités
-Count activities linked to a person by various parameters.: Compte le nombre d'activités enregistrées et liées à une personne en fonction de différents paramètres.
+Count activities linked to a person by various parameters.: Compte le nombre d'activités enregistrées et liées à un usager en fonction de différents paramètres.
Sum activity linked to a person duration: Durée des activités
Sum activities linked to a person duration: Durée des activités liés à un usager
Sum activities linked to a person duration by various parameters.: Additionne la durée des activités en fonction de différents paramètres.
@@ -244,10 +244,10 @@ Activities before this date: Activités avant cette date
"Filtered by date of activity: only between %date_from% and %date_to%": "Filtré par date de l'activité: uniquement entre %date_from% et %date_to%"
This date should be after the date given in "Implied in an activity after this date" field: Cette date devrait être postérieure à la date donnée dans le champ "activités après cette date"
-Filtered by person having an activity in a period: Uniquement les personnes ayant eu une activité dans la période donnée
+Filtered by person having an activity in a period: Uniquement les usagers ayant eu une activité dans la période donnée
Implied in an activity after this date: Impliqué dans une activité après cette date
Implied in an activity before this date: Impliqué dans une activité avant cette date
-Filtered by person having an activity between %date_from% and %date_to% with reasons %reasons_name%: Filtré par personnes associées à une activité entre %date_from% et %date_to% avec les sujets %reasons_name%
+Filtered by person having an activity between %date_from% and %date_to% with reasons %reasons_name%: Filtré par usager associées à une activité entre %date_from% et %date_to% avec les sujets %reasons_name%
Activity reasons for those activities: Sujets de ces activités
Filter by activity type: Filtrer les activités par type
@@ -336,8 +336,8 @@ export:
users name: Nom des utilisateurs
users ids: Identifiant des utilisateurs
third parties ids: Identifiant des tiers
- persons ids: Identifiant des personnes
- persons name: Nom des personnes
+ persons ids: Identifiant des usagers
+ persons name: Nom des usagers
thirds parties: Tiers
date: Date de l'activité
locationName: Localisation
diff --git a/src/Bundle/ChillActivityBundle/translations/validators.fr.yml b/src/Bundle/ChillActivityBundle/translations/validators.fr.yml
index 14617e752..053752854 100644
--- a/src/Bundle/ChillActivityBundle/translations/validators.fr.yml
+++ b/src/Bundle/ChillActivityBundle/translations/validators.fr.yml
@@ -6,7 +6,7 @@ For this type of activity, you must add at least one third party: Pour ce type d
For this type of activity, user is required: Pour ce type d'échange, l'utilisateur est requis
For this type of activity, date is required: Pour ce type d'échange, la date est requise
For this type of activity, location is required: Pour ce type d'échange, la localisation est requise
-For this type of activity, attendee is required: Pour ce type d'échange, le champ "Présence de la personne" est requis
+For this type of activity, attendee is required: Pour ce type d'échange, le champ "Présence de l'usager" est requis
For this type of activity, duration time is required: Pour ce type d'échange, la durée est requise
For this type of activity, travel time is required: Pour ce type d'échange, la durée du trajet est requise
For this type of activity, reasons is required: Pour ce type d'échange, le champ "sujet" est requis
diff --git a/src/Bundle/ChillAsideActivityBundle/src/translations/messages.fr.yml b/src/Bundle/ChillAsideActivityBundle/src/translations/messages.fr.yml
index 362f87fe5..cc428390c 100644
--- a/src/Bundle/ChillAsideActivityBundle/src/translations/messages.fr.yml
+++ b/src/Bundle/ChillAsideActivityBundle/src/translations/messages.fr.yml
@@ -21,7 +21,7 @@ Type: Type
Invisible: Invisible
Optional: Optionnel
Required: Obligatoire
-Persons: Personnes
+Persons: Usagers
Users: Utilisateurs
Emergency: Urgent
by: "Par "
diff --git a/src/Bundle/ChillBudgetBundle/translations/messages.fr.yml b/src/Bundle/ChillBudgetBundle/translations/messages.fr.yml
index b20477150..a5e5490a0 100644
--- a/src/Bundle/ChillBudgetBundle/translations/messages.fr.yml
+++ b/src/Bundle/ChillBudgetBundle/translations/messages.fr.yml
@@ -29,7 +29,7 @@ End of validity period: Fin de la période de validité
Total: Total
Create new resource: Créer une nouvelle ressource
Create new charge: Créer une nouvelle charge
-See person: Voir personne
+See person: Voir usagers
There isn't any element recorded: Aucun élément enregistré
No resources registered: Aucune ressource enregistrée
diff --git a/src/Bundle/ChillCalendarBundle/translations/messages.fr.yml b/src/Bundle/ChillCalendarBundle/translations/messages.fr.yml
index aa933bb63..eb02be280 100644
--- a/src/Bundle/ChillCalendarBundle/translations/messages.fr.yml
+++ b/src/Bundle/ChillCalendarBundle/translations/messages.fr.yml
@@ -132,8 +132,8 @@ docgen:
Base context for calendar: 'Rendez-vous: contexte de base'
A base context for generating document on calendar: Contexte pour générer des documents à partir des rendez-vous
Track changes on datetime and warn user if date time is updated after the doc generation: Suivre les changements sur le document et prévenir les utilisateurs que la date et l'heure ont été modifiée après la génération du document
- Ask main person: Demander de choisir une personne parmi les participants aux rendez-vous
- Main person label: Label pour choisir la personne
+ Ask main person: Demander de choisir un usager parmi les participants aux rendez-vous
+ Main person label: Label pour choisir l'usager
Ask third party: Demander de choisir un tiers parmi les participants aux rendez-vous
Third party label: Label pour choisir le tiers
Destinee: Destinataire
diff --git a/src/Bundle/ChillCalendarBundle/translations/validators.fr.yml b/src/Bundle/ChillCalendarBundle/translations/validators.fr.yml
index 7d9be7a91..03343ba8a 100644
--- a/src/Bundle/ChillCalendarBundle/translations/validators.fr.yml
+++ b/src/Bundle/ChillCalendarBundle/translations/validators.fr.yml
@@ -1,5 +1,5 @@
calendar:
- At least {{ limit }} person is required.: Au moins {{ limit }} personne doit être associée à ce rendez-vous
+ At least {{ limit }} person is required.: Au moins {{ limit }} usager doit être associée à ce rendez-vous
An end date is required: Indiquez une date et heure de fin
A start date is required: Indiquez une date et heure de début
A location is required: Indiquez un lieu
diff --git a/src/Bundle/ChillEventBundle/translations/messages.fr.yml b/src/Bundle/ChillEventBundle/translations/messages.fr.yml
index 3ca0da260..8810c040a 100644
--- a/src/Bundle/ChillEventBundle/translations/messages.fr.yml
+++ b/src/Bundle/ChillEventBundle/translations/messages.fr.yml
@@ -34,7 +34,7 @@ Edit the participation: Modifier la participation
Participation Edit: Modifier une participation
Add a participation: Ajouter un participant
Participation creation: Ajouter une participation
-Associated person: Personne associée
+Associated person: Usager associé
Associated event: Événement associé
Back to the event: Retour à l'événement
The participation was created: La participation a été créée
@@ -108,4 +108,4 @@ csv: csv
Create a new role: Créer un nouveau rôle
Create a new type: Créer un nouveau type
-Create a new status: Créer un nouveau statut
\ No newline at end of file
+Create a new status: Créer un nouveau statut
diff --git a/src/Bundle/ChillMainBundle/translations/messages.fr.yml b/src/Bundle/ChillMainBundle/translations/messages.fr.yml
index f01976e87..be02987b3 100644
--- a/src/Bundle/ChillMainBundle/translations/messages.fr.yml
+++ b/src/Bundle/ChillMainBundle/translations/messages.fr.yml
@@ -1,8 +1,8 @@
"This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License ": "Ce programme est un logiciel libre: vous pouvez le redistribuer et/ou le modifier selon les termes de la licence GNU Affero GPL "
User manual: Manuel d'utilisation
Search: Rechercher
-"Search persons, ...": "Recherche des personnes, ..."
-Person name: Nom / Prénom de la personne
+"Search persons, ...": "Recherche des usagers, ..."
+Person name: Nom / Prénom de l'usager
Login: Connexion
Logout: Se déconnecter
Bad credentials.: Le mot de passe et le nom d'utilisateur ne correspondent pas.
diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml
index b22916313..6cec9e36d 100644
--- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml
+++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml
@@ -47,8 +47,8 @@ Phonenumber: 'Numéro de téléphone'
phonenumber: numéro de téléphone
Mobilenumber: 'Numéro de téléphone portable'
mobilenumber: numéro de téléphone portable
-Accept short text message ?: La personne a donné l'autorisation d'utiliser ce no de téléphone pour l'envoi de rappel par SMS
-Accept short text message: La personne a donné l'autorisation d'utiliser ce no de téléphone pour l'envoi de rappel par SMS
+Accept short text message ?: L'usager a donné l'autorisation d'utiliser ce no de téléphone pour l'envoi de rappel par SMS
+Accept short text message: L'usager a donné l'autorisation d'utiliser ce no de téléphone pour l'envoi de rappel par SMS
Other phonenumber: Autre numéro de téléphone
Others phone numbers: Autres numéros de téléphone
No additional phone numbers: Aucun numéro de téléphone supplémentaire
@@ -85,9 +85,9 @@ Course number: Parcours n°
Civility: Civilité
choose civility: --
All genders: tous les genres
-Any person selected: Aucune personne sélectionnée
-Create a household and add an address: Ajouter une adresse pour une personne non suivie et seule dans un ménage
-A new household will be created. The person will be member of this household.: Un nouveau ménage va être créé. La personne sera membre de ce ménage.
+Any person selected: Aucun usager sélectionné
+Create a household and add an address: Ajouter une adresse pour un usager non suivie et seule dans un ménage
+A new household will be created. The person will be member of this household.: Un nouveau ménage va être créé. L'usager sera membre de ce ménage.
Comment on the gender: Commentaire sur le genre
genderComment: Commentaire sur le genre
maritalStatus: État civil
@@ -136,10 +136,10 @@ address_country_name: Pays
address_country_code: Code pays
'Alreay existing person': 'Dossiers déjà encodés'
-'Add the person': 'Ajouter la personne'
-'Add the person and create an accompanying period': "Créer la personne ET créer une période d'accompagnement"
-'Add the person and create a household': "Créer la personne ET créer un ménage"
-Show person: Voir le dossier de la personne
+'Add the person': 'Ajouter la usager'
+'Add the person and create an accompanying period': "Créer la usager ET créer une période d'accompagnement"
+'Add the person and create a household': "Créer la usager ET créer un ménage"
+Show person: Voir le dossier de l'usager
'Confirm the creation': 'Confirmer la création'
'You will create this person': 'Vous allez créer le dossier suivant'
Return: Retour
@@ -148,17 +148,17 @@ Reset: 'Remise à zéro'
'The person data has been updated': 'Les données ont été mises à jour.'
'The person data provided are not valid': 'Les données introduites ne sont pas valides'
'{1} The person field %field% is incorrect. Please check. | ]1, Inf] Several person fields are incorrect. Please check.': '{1} Le champs %field% est incorrect. Veuillez le corriger. | ]1, Inf] Plusieurs champs sont incorrects. Veuillez les vérifier.'
-'Add a person': 'Ajout d''une personne'
-'Person Menu': 'Menu personne'
+'Add a person': 'Ajout d''une usager'
+'Person Menu': 'Menu usager'
'The person data are not valid': 'Les données de votre formulaire sont invalides.'
-'%nb% person with similar name. Please verify that this is a new person': '{1} Une personne a un nom similaire. Vérifiez qu''il ne s''agit pas d''elle. | ]1, Inf] %nb% personnes ont un nom similaire. Vérifiez qu''il ne s''agit pas de l''une d''elles.'
+'%nb% person with similar name. Please verify that this is a new person': '{1} Une usager a un nom similaire. Vérifiez qu''il ne s''agit pas d''elle. | ]1, Inf] %nb% usagers ont un nom similaire. Vérifiez qu''il ne s''agit pas de l''une d''elles.'
'The person has been created': 'Le dossier a été créé'
-'Person search results': 'Recherche de personnes'
-Person search results by phonenumber: Recherche de personnes par numéro de téléphone
-'Search within persons': 'Recherche parmi les personnes'
-Open person file: Ouvrir le dossier de la personne
+'Person search results': 'Recherche de usagers'
+Person search results by phonenumber: Recherche d'usager par numéro de téléphone
+'Search within persons': 'Recherche parmi les usagers'
+Open person file: Ouvrir le dossier de l'usager
and %number% other: '{0} et aucun autre| {1} et une autre |]1, Inf] et %number% autres'
-'%total% persons matching the search pattern:': '{0} Aucune personne ne correspond aux termes de recherche : | {1} Une personne a été trouvée par la recherche : | ]1,Inf] %total% personnes correspondent aux termes de recherche :'
+'%total% persons matching the search pattern:': '{0} Aucune usager ne correspond aux termes de recherche : | {1} Une usager a été trouvée par la recherche : | ]1,Inf] %total% usagers correspondent aux termes de recherche :'
'Last opening since %last_opening%': 'Dernière ouverture le %last_opening%.'
'Person accompanying period - %name%': 'Historique du dossier - %name%'
'Opening date': 'Date d''ouverture'
@@ -185,14 +185,14 @@ Update accompanying period: Mettre à jour une période d'accompagnement
This course is closed: Ce parcours est clôturé
Close accompanying course: Clôturer le parcours
Re-open accompanying course: Ré-ouvrir le parcours
-'Person details': 'Détails de la personne'
+'Person details': 'Détails de la usager'
'Update details for %name%': 'Modifier détails de %name%'
An accompanying period ends: Une periode d'accompagnement se clôture
An accompanying period starts: Une période d'accompagnement est ouverte
Any accompanying periods are open: Aucune période d'accompagnement ouverte
An accompanying period is open: Une période d'accompagnement est ouverte
Accompanying period list: Périodes d'accompagnement
-Accompanying period list for person: Périodes d'accompagnement de la personne
+Accompanying period list for person: Périodes d'accompagnement de l'usager
Accompanying period: Parcours d'accompagnement
Any accompanying period: Aucun parcours d'accompagnement
period: Parcours
@@ -206,11 +206,11 @@ Pediod closing form is not valid: Le formulaire n'est pas valide
Accompanying user: Accompagnant
No accompanying user: Aucun accompagnant
No data given: Pas d'information
-Participants: Personnes impliquées
+Participants: Usagers impliquées
Create an accompanying course: Créer un parcours
Accompanying courses of users: Parcours des utilisateurs
This accompanying course is still a draft: Ce parcours est encore à l'état brouillon.
-Associated peoples: Personnes concernées
+Associated peoples: Usagers concernées
Resources: Interlocuteurs privilégiés
Any requestor to this accompanying course: Aucun demandeur pour ce parcours
Social action: Action d'accompagnement
@@ -229,12 +229,12 @@ See this period: Voir cette période
Requestor: Demandeur
No requestor: Pas de demandeur
No resources: "Pas d'interlocuteurs privilégiés"
-Persons associated: Personnes concernés
+Persons associated: Usagers concernés
Referrer: Référent
Referrers: Agents traitants
Referrer2: Agent traitant
No referrer: Pas d'agent traitant
-Some peoples does not belong to any household currently. Add them to an household soon: Certaines personnes n'appartiennent à aucun ménage actuellement. Renseignez leur ménage dès que possible.
+Some peoples does not belong to any household currently. Add them to an household soon: Certains usagers n'appartiennent à aucun ménage actuellement. Renseignez leur ménage dès que possible.
Add to household now: Ajouter à un ménage
Any resource for this accompanying course: Aucun interlocuteur privilégié pour ce parcours
course.draft: Brouillon
@@ -247,7 +247,7 @@ Concerned scopes: Services concernés
# person resource
person_resources_menu: "Personnes ressources"
-Person resources: "Ressources de la personne"
+Person resources: "Ressources de la usager"
Add a person resource: "Ajouter une ressource"
edit resource: "Modifier ressource"
Remove resource: "Supprimer ressource"
@@ -257,12 +257,12 @@ List of resources: "Liste des ressources"
There are no available resources: "Aucun ressource"
no comment found: "Aucun commentaire"
Select a type: "Choisissez un type"
-Select a person: "Choisissez une personne"
+Select a person: "Choisissez une usager"
Kind: "Type"
# pickAPersonType
-Pick a person: Choisir une personne
+Pick a person: Choisir un usager
# Address
No address given: Pas d'adresse renseignée
@@ -277,19 +277,19 @@ New address : Nouvelle adresse
New address for %name% : Nouvelle adresse pour %name%
The new address was created successfully: La nouvelle adresse a été créée
Add an address: Ajouter une adresse
-Back to the person details: Retour aux détails de la personne
+Back to the person details: Retour aux détails de l'usager
# Residential address
Residential addresses history for %name%: Historique des adresses de résidence de %name%
Residential addresses history: Historique des adresses de résidence
Add a residential address: Ajouter une adresse de résidence
Which kind of residential address would you create ?: Quel type d'adresse de résidence voulez-vous créer?
-The address of another person: L'adresse d'une autre personne
+The address of another person: L'adresse d'une autre usager
A new address: Une nouvelle adresse
-residential_address_person_explanation: L'adresse sera positionnée auprès d'une personne. Lorsque la personne déménage, l'adresse de résidence suivra également cette personne
+residential_address_person_explanation: L'adresse sera positionnée auprès d'un usager. Lorsque la usager déménage, l'adresse de résidence suivra également cette usager
residential_address_new_address_explanation: Créer une nouvelle adresse. L'adresse sera fixe.
New residential address: Nouvelle adresse de résidence
-Host person: Choisir l'adresse d'une personne
+Host person: Choisir l'adresse d'un usager
The new residential address was created successfully: La nouvelle adresse de résidence a été créée
Edit a residential address: Modifier l'addresse de résidence
The residential address was updated successfully: L'adresse de résidence a été mise à jour
@@ -308,12 +308,12 @@ Opening the accompanying period: Ouverture d'une période d'accompagnement
'Timeline for %name%': 'Historique de %name%'
# ROLES
-CHILL_PERSON_SEE: Voir les personnes
-CHILL_PERSON_UPDATE: Modifier les personnes
-CHILL_PERSON_CREATE: Ajouter des personnes
-CHILL_PERSON_STATS: Statistiques sur les personnes
-CHILL_PERSON_LISTS: Liste des personnes
-CHILL_PERSON_DUPLICATE: Gérer les doublons de personnes
+CHILL_PERSON_SEE: Voir les usagers
+CHILL_PERSON_UPDATE: Modifier les usagers
+CHILL_PERSON_CREATE: Ajouter des usagers
+CHILL_PERSON_STATS: Statistiques sur les usagers
+CHILL_PERSON_LISTS: Liste des usagers
+CHILL_PERSON_DUPLICATE: Gérer les doublons d'usagers
CHILL_PERSON_ACCOMPANYING_PERIOD_SEE: Vision simplifiée d'une période d'accompagnement
CHILL_PERSON_ACCOMPANYING_PERIOD_CONFIDENTIAL: Voir et modifier les périodes d'accompagnement confidentielles
@@ -348,22 +348,22 @@ Pediod closing form is not valide: Le formulaire de fermeture n'est pas valide
#widget
## widget person_list
-Accompanyied people: Personnes accompagnées
+Accompanyied people: Usagers accompagnés
## exports
-Exports of persons: Exports des personnes
-Count people by various parameters.: Compte le nombre de personnes en fonction de différents filtres.
-Count people: Nombre de personnes
-List peoples: Liste des personnes
-Create a list of people according to various filters.: Crée une liste des personnes selon différents filtres.
+Exports of persons: Exports des usagers
+Count people by various parameters.: Compte le nombre d'usagers en fonction de différents filtres.
+Count people: Nombre d'usagers
+List peoples: Liste des usagers
+Create a list of people according to various filters.: Crée une liste d'usagers selon différents filtres.
Fields to include in export: Champs à inclure dans l'export
Address valid at this date: Addresse valide à cette date
Data valid at this date: Données valides à cette date
Data regarding center, addresses, and so on will be computed at this date: Les données concernant le centre, l'adresse, le ménage, sera calculé à cette date.
List duplicates: Liste des doublons
-Create a list of duplicate people: Créer la liste des personnes détectées comme doublons.
-Count people participating in an accompanying course: Nombre de personnes concernées par un parcours
-Count people participating in an accompanying course by various parameters.: Compte le nombre de personnes concernées par un parcours
+Create a list of duplicate people: Créer la liste des usagers détectés comme doublons.
+Count people participating in an accompanying course: Nombre d'usagers concernés par un parcours
+Count people participating in an accompanying course by various parameters.: Compte le nombre d'usagers concernées par un parcours
Exports of accompanying courses: Exports des parcours d'accompagnement
Count accompanying courses: Nombre de parcours
@@ -384,33 +384,33 @@ Count evaluation by various parameters.: Compte le nombre d'évaluations selon d
Exports of households: Exports des ménages
## persons filters
-Filter by person gender: Filtrer les personnes par genre
+Filter by person gender: Filtrer les usagers par genre
Accepted genders: Genres acceptés
'Filtering by genders: only %genders%': 'Filtré par genre: seulement %genders%'
-Filter by person's nationality: Filtrer les personnes par nationalité
+Filter by person's nationality: Filtrer les usagers par nationalité
Nationalities: Nationalités
Choose countries: Choisir les nationalités
'Filtered by nationality : %nationalities%': 'Filtré par nationalité : seulement %nationalities%'
-Filter by person's birthdate: Filtrer les personnes par date de naissance
+Filter by person's birthdate: Filtrer les usagers par date de naissance
Born after this date: Nés après cette date
Born before this date: Nés avant cette date
This field should not be empty: Ce champ ne peut pas être vide
This date should be after the date given in "born after" field: Cette date doit être après la date donnée du le champ "nés après le"
-"Filtered by person's birthdate: between %date_from% and %date_to%": "Filtré par date de naissance de la personne: uniquement nés entre le %date_from% et %date_to%"
+"Filtered by person's birthdate: between %date_from% and %date_to%": "Filtré par date de naissance de l'usager: uniquement nés entre le %date_from% et %date_to%"
-Filter by person's deathdate: Filtrer les personnes par date de décès
-"Filtered by person's deathdate: between %date_from% and %date_to%": "Filtré par date de naissance de la personne: uniquement nés entre le %date_from% et %date_to%"
+Filter by person's deathdate: Filtrer les usagers par date de décès.
+"Filtered by person's deathdate: between %date_from% and %date_to%": "Filtré par date de naissance de l'usager: uniquement nés entre le %date_from% et %date_to%"
Death after this date: Décédé après cette date
Deathdate before: Décédé avant cette date
Alive: Vivant
Deceased: Décédé
Filter in relation to this date: Filtrer par rapport à cette date
-"Filtered by a state of %deadOrAlive%: at this date %date_calc%": Filtré par personnes qui sont %deadOrAlive% à cette date %date_calc%
+"Filtered by a state of %deadOrAlive%: at this date %date_calc%": Filtré par usagers qui sont %deadOrAlive% à cette date %date_calc%
-Filter by person's age: Filtrer les personnes par age
-"Filtered by person's age: between %min_age% and %max_age%": "Filtré par âge de la personne entre %min_age% et %max_age%"
+Filter by person's age: Filtrer les usagers par age.
+"Filtered by person's age: between %min_age% and %max_age%": "Filtré par âge de l'usager entre %min_age% et %max_age%"
Minimum age: Âge minimum
Maximum age: Âge maximum
The minimum age should be less than the maximum age.: L'âge minimum doit être plus bas que l'âge maximum.
@@ -420,38 +420,38 @@ Date during which residential address was valid: Date de validité
Family composition: Composition familiale
Family composition at this time: Composition familiale à cette date.
-Filter by person's marital status: Filtrer les personnes par état matrimonial
+Filter by person's marital status: Filtrer les usagers par état matrimonial
Filtered by person's marital status: Filtré par état matrimonial
Marital status at this time: État matrimonial par rapport à cette date
-Filter by entrusted child status: Filtrer les personnes "enfant confié"
-Filtered by entrusted child status: Uniquement les personnes qui sont "enfant confié"
+Filter by entrusted child status: Filtrer les usagers "enfant confié"
+Filtered by entrusted child status: Uniquement les usagers qui sont "enfant confié"
-Filter by nomadic status: Filtrer les personnes "gens du voyage"
-Filtered by nomadic status: Uniquement les personnes qui sont "gens du voyage"
+Filter by nomadic status: Filtrer les usagers "gens du voyage"
+Filtered by nomadic status: Uniquement les usagers qui sont "gens du voyage"
-"Filter by person's who have a residential address located at another user": Filtrer les personnes qui ont une addresse de résidence chez une autre personne
-"Filtered by person's who have a residential address located at another user": Uniquement les personnes qui ont une addresse de résidence chez une autre personne
+"Filter by person's who have a residential address located at another user": Filtrer les usagers qui ont une addresse de résidence chez une autre usager
+"Filtered by person's who have a residential address located at another user": Uniquement les usagers qui ont une addresse de résidence chez une autre usager
-Filter by person's that are alive or have deceased at a certain date: Filtrer les personnes qui sont décédées ou vivantes à une certaine date
-Filtered by person's that are alive or have deceased at a certain date: Uniquement les personnes qui sont décédées ou vivantes à une certaine date
+Filter by person's that are alive or have deceased at a certain date: Filtrer les usagers qui sont décédés ou vivantes à une certaine date
+Filtered by person's that are alive or have deceased at a certain date: Uniquement les usagers qui sont décédés ou vivantes à une certaine date
-"Filter by accompanying period: active period": "Filtrer les personnes par période d'accompagnement: en file active"
+"Filter by accompanying period: active period": "Filtrer les usagers par période d'accompagnement: en file active"
Having an accompanying period opened after this date: Ayant une période d'accompagnement ouverte après cette date
Having an accompanying period ending before this date, or still opened at this date: Ayant une période d'accompagnement fermée après cette date, ou toujours ouverte à cette date
-"Filtered by accompanying period: persons having an accompanying period opened after the %date_from% and closed before the %date_to% (or still opened at the %date_to%)": "Filtré par période d'accompagnement: personnes ayant une période d'accompagnement ouverte après le %date_from%, et cloturée le %date_to% (ou toujours ouverte le %date_to%)"
+"Filtered by accompanying period: persons having an accompanying period opened after the %date_from% and closed before the %date_to% (or still opened at the %date_to%)": "Filtré par période d'accompagnement: usagers ayant une période d'accompagnement ouverte après le %date_from%, et cloturée le %date_to% (ou toujours ouverte le %date_to%)"
-"Filter by accompanying period: starting between two dates": "Filtrer les personnes par période d'accompagnement: début de la période entre deux dates"
+"Filter by accompanying period: starting between two dates": "Filtrer les usagers par période d'accompagnement: début de la période entre deux dates"
"Having an accompanying period opened before this date": "Ayant une période d'accompagnement ouverte avant cette date"
"Filtered by accompanying period: persons having an accompanying period opened between the %date_from% and %date_to%": "Filtrer par période d'accompagnement: ayant une période ouverte entre le %date_from% et le %date_to%"
-"Filter by accompanying period: closed between two dates": "Filtrer les personnes par période d'accompagnement: période fermée entre deux dates"
+"Filter by accompanying period: closed between two dates": "Filtrer les usagers par période d'accompagnement: période fermée entre deux dates"
Having an accompanying period closed after this date: Ayant une période d'accompagnement fermée après cette date
"Having an accompanying period closed before this date": "Ayant une période d'accompagnement fermée avant cette date"
"Filtered by accompanying period: persons having an accompanying period closed between the %date_from% and %date_to%": "Filtrer par période d'accompagnement: ayant une période fermée entre le %date_from% et le %date_to%"
-Filter by person having an activity in a period: Filtrer les personnes ayant eu un échange pendant la période donnée
-Filtered by person having an activity between %date_from% and %date_to% with reasons %reasons_name%: Uniquement les personnes associées à un échange entre %date_from% et %date_to% avec les sujets %reasons_name%
+Filter by person having an activity in a period: Filtrer les usagers ayant eu un échange pendant la période donnée
+Filtered by person having an activity between %date_from% and %date_to% with reasons %reasons_name%: Uniquement les usagers associés à un échange entre %date_from% et %date_to% avec les sujets %reasons_name%
## accompanying course filters/aggr
@@ -483,8 +483,8 @@ acp_geog_agg_unitname: Zone géographique
acp_geog_agg_unitrefid: Clé de la zone géographique
Geographical layer: Couche géographique
Select a geographical layer: Choisir une couche géographique
-Group people by geographical unit based on his address: Grouper les personnes par zone géographique (sur base de l'adresse)
-Filter by person's geographical unit (based on address): Filter les personnes par zone géographique (sur base de l'adresse)
+Group people by geographical unit based on his address: Grouper les usagers par zone géographique (sur base de l'adresse)
+Filter by person's geographical unit (based on address): Filter les usagers par zone géographique (sur base de l'adresse)
Filter by socialaction: Filtrer les parcours par action d'accompagnement
Accepted socialactions: Actions d'accompagnement
@@ -520,12 +520,12 @@ Administrative location: Localisation administrative
"Filtered by administratives locations: only %locations%": "Filtré par localisation administrative: uniquement %locations%"
Group by administrative location: Grouper les parcours par localisation administrative
-Filter by requestor: Filtrer les parcours selon la présence du demandeur au sein des personnes concernées
+Filter by requestor: Filtrer les parcours selon la présence du demandeur au sein des usagers concernés
Accepted choices: ''
-is person concerned: Le demandeur est une personne concernée
-is other person: Le demandeur est une personne, mais n'est pas concernée
+is person concerned: Le demandeur est un usager concerné
+is other person: Le demandeur est une usager, mais n'est pas concerné
no requestor: Le parcours ne comporte pas de demandeur
-"Filtered by requestor: only %choice%": "Filtré par présence du demandeur au sein des personnes concernées: uniquement si %choice%"
+"Filtered by requestor: only %choice%": "Filtré par présence du demandeur au sein des usagers concernés: uniquement si %choice%"
Group by requestor: Grouper les parcours selon la nature du demandeur
Filter by confidential: Filtrer les parcours par confidentialité
@@ -647,24 +647,24 @@ Rounded month duration: Durée en mois (arrondie)
current duration: en cours
duration 0 month: 0 mois (<15 jours)
' months': ' mois'
-Group people by nationality: Grouper les personnes par nationalités
+Group people by nationality: Grouper les usagers par nationalités
Group by level: Grouper par niveau
Group by continents: Grouper par continent
Group by country: Grouper par pays
-Group people by gender: Grouper les personnes par genre
-Group people by their professional situation: Grouper les personnes par situation professionelle
-Group people by marital status: Grouper les personnes par état matrimonial
+Group people by gender: Grouper les usagers par genre
+Group people by their professional situation: Grouper les usagers par situation professionelle
+Group people by marital status: Grouper les usagers par état matrimonial
-Aggregate by household position: Grouper les personnes par position dans le ménage
+Aggregate by household position: Grouper les usagers par position dans le ménage
Household position in relation to this date: Position dans le ménage par rapport à cette date
Household position: Position dans le ménage
-Aggregate by age: Grouper les personnes par âge
+Aggregate by age: Grouper les usagers par âge
Calculate age in relation to this date: Calculer l'âge par rapport à cette date
-Group people by country of birth: Grouper les personnes par pays de naissance
-Similar persons: Personnes similaires
+Group people by country of birth: Grouper les usagers par pays de naissance
+Similar persons: Usagers similaires
crud:
closing_motive:
@@ -775,8 +775,8 @@ closing_motive:
any parent: Aucun parent
new child: Nouvel enfant
-Person configuration: Configuration du module "Personnes"
-Configuration of person bundle: Configuration du module "Personnes"
+Person configuration: Configuration du module "Usagers"
+Configuration of person bundle: Configuration du module "Usagers"
person_admin:
accompanying_period: Parcours d'accompagnement
What would you like to configure ?: Que souhaitez-vous configurer ?
@@ -825,11 +825,11 @@ Edit Accompanying Course: Modifier le parcours
Close Accompanying Course: Clôturer le parcours
Create Accompanying Course: Créer un nouveau parcours
Drop Accompanying Course: Supprimer le parcours
-This course is located at a temporarily address. You should locate this course to an user: Le parcours est localisé à une adresse temporaire. Il devrait être localisé auprès d'une personne concernée.
+This course is located at a temporarily address. You should locate this course to an user: Le parcours est localisé à une adresse temporaire. Il devrait être localisé auprès d'une usager concerné.
Accompanying course location: Localisation du parcours
This course is located by: Localisé auprès de
This course has a temporarily location: Localisation temporaire
-Choose a person to locate by: Localiser auprès d'une personne concernée
+Choose a person to locate by: Localiser auprès d'une usager concerné
Associate at least one member with an household, and set an address to this household: Associez au moins un membre du parcours à un ménage, et indiquez une adresse à ce ménage.
Locate by: Localiser auprès de
fix it: Compléter
@@ -916,33 +916,33 @@ Person addresses: Adresses de résidence
Household addresses: Adresses de domicile
Insert an address: Insérer une adresse
see social issues: Voir les problématiques sociales
-see persons associated: Voir les personnes concernées
+see persons associated: Voir les usagers concernés
docgen:
Accompanying Period basic: "Parcours d'accompagnement (basique)"
Accompanying period work: "Action d'accompagnement"
Accompanying period work context: "Evaluation des actions d'accompagnement"
- Main person: Personne principale
- person 1: Première personne
- person 2: Seconde personne
- Ask for main person: Demander à l'utilisateur de préciser la personne principale
- Ask for person 1: Demander à l'utilisateur de préciser la première personne
- Ask for person 2: Demander à l'utilisateur de préciser la seconde personne
+ Main person: Usager principal
+ person 1: Premièr usager
+ person 2: Second usager
+ Ask for main person: Demander à l'utilisateur de préciser l'usager principal
+ Ask for person 1: Demander à l'utilisateur de préciser le premièr usager
+ Ask for person 2: Demander à l'utilisateur de préciser le second usager
A basic context for accompanying period: Contexte pour les parcours
A context for accompanying period work: Contexte pour les actions d'accompagnement
A context for accompanying period work evaluation: Contexte pour les évaluations dans les actions d'accompagnement
- Person basic: Personne (basique)
- A basic context for person: Contexte pour les personnes
+ Person basic: Usager (basique)
+ A basic context for person: Contexte pour les usagers
Label for third party: Label à afficher aux utilisateurs
Document title: Titre du document généré
period_notification:
period_designated_subject: Vous êtes référent d'un parcours d'accompagnement
You are designated to a new period: Vous avez été désigné référent d'un parcours d'accompagnement.
- Persons are: Les personnes concernées sont les suivantes
+ Persons are: Les usagers concernés sont les suivantes
Social issues are: Les problématiques sociales renseignées sont les suivantes
See it online: Visualisez le parcours en ligne
- Person locating period has moved: La personne qui localise un parcours a déménagé
+ Person locating period has moved: L'usager qui localise un parcours a déménagé
You are getting a notification for a period which does not exists any more: Cette notification ne correspond pas à une période d'accompagnement valide.
You are getting a notification for a period you are not allowed to see: La notification fait référence à une période d'accompagnement à laquelle vous n'avez pas accès.
@@ -1010,7 +1010,7 @@ export:
person:
by_household_composition:
Household composition: Composition du ménage
- Group course by household composition: Grouper les personnes par composition familiale
+ Group course by household composition: Grouper les usagers par composition familiale
Calc date: Date de calcul de la composition du ménage
course:
by_referrer:
@@ -1054,13 +1054,13 @@ export:
Filtered by person's geographical unit (based on address) computed at %datecalc%, only %units%: Filtré par unité géographique (sur base de l'adresse), calculé le %datecalc%, seulement %units%
person:
by_composition:
- Filter by household composition: Filtrer les personnes par composition du ménage
+ Filter by household composition: Filtrer les usagers par composition du ménage
Accepted compositions: Composition de ménages
Date calc: Date de calcul
'Filtered by composition at %date%: only %compositions%': 'Filtré par composition du ménage, le %date%, seulement %compositions%'
by_no_composition:
- Filter persons without household composition: Filtrer les personnes sans composition de ménage (ni ménage)
- Persons filtered by no composition at %date%: Uniquement les personnes sans composition de ménage à la date du %date%
+ Filter persons without household composition: Filtrer les usagers sans composition de ménage (ni ménage)
+ Persons filtered by no composition at %date%: Uniquement les usagers sans composition de ménage à la date du %date%
Date calc: Date de calcul
course:
@@ -1077,8 +1077,8 @@ export:
'Filtered by creator job: only %jobs%': 'Filtré par métier du créateur: seulement %jobs%'
list:
person_with_acp:
- List peoples having an accompanying period: Liste des personnes ayant un parcours d'accompagnement
- Create a list of people having an accompaying periods, according to various filters.: Génère une liste des personnes ayant un parcours d'accompagnement, selon différents critères liés au parcours ou à l'usager
+ List peoples having an accompanying period: Liste des usagers ayant un parcours d'accompagnement
+ Create a list of people having an accompaying periods, according to various filters.: Génère une liste des usagers ayant un parcours d'accompagnement, selon différents critères liés au parcours ou à l'usager
acp:
List of accompanying periods: Liste de périodes d'accompagnements
Generate a list of accompanying periods, filtered on different parameters.: Génère une liste des périodes d'accompagnement, filtrée sur différents paramètres.
@@ -1108,8 +1108,8 @@ export:
locationPersonId: Identifiant de l'usager auprès duquel le parcours est localisé
acpaddress_fieldscountry: Pays de l'adresse
isRequestorPerson: Le demandeur est-il un usager ?
- requestorPersonId: Identifiant du demandeur personne
- acprequestorPerson: Nom du demandeur personne
+ requestorPersonId: Identifiant du demandeur usager
+ acprequestorPerson: Nom du demandeur usager
scopes: Services
socialIssues: Problématiques sociales
eval:
diff --git a/src/Bundle/ChillPersonBundle/translations/validators.fr.yml b/src/Bundle/ChillPersonBundle/translations/validators.fr.yml
index cda82aa89..f4b0c62ad 100644
--- a/src/Bundle/ChillPersonBundle/translations/validators.fr.yml
+++ b/src/Bundle/ChillPersonBundle/translations/validators.fr.yml
@@ -47,7 +47,7 @@ household:
max_holder_overflowed: Il ne peut y avoir plus de deux titulaires simultanément. Or, avec cette modification, ce nombre sera dépassé entre le {{ start }} et le {{ end }}.
household_membership:
The end date must be after start date: La date de la fin de l'appartenance doit être postérieure à la date de début.
- Person with membership covering: Une personne ne peut pas appartenir à deux ménages simultanément. Or, avec cette modification, %person_name% appartiendrait à %nbHousehold% ménages à partir du %from%.
+ Person with membership covering: Un usager ne peut pas appartenir à deux ménages simultanément. Or, avec cette modification, %person_name% appartiendrait à %nbHousehold% ménages à partir du %from%.
# Accompanying period
'{{ name }} is already associated to this accompanying course.': '{{ name }} est déjà associé à ce parcours.'
@@ -59,7 +59,7 @@ Only the referrer can change the confidentiality of a parcours: 'Seul le référ
# resource
You must associate at least one entity: Associez un usager, un tiers ou indiquez une description libre
-You cannot associate a resource with the same person: Vous ne pouvez pas ajouter la personne elle-même en tant que ressource.
+You cannot associate a resource with the same person: Vous ne pouvez pas ajouter l'usager lui-même en tant que ressource.
#location
The period must remain located: 'Un parcours doit être localisé'
@@ -67,7 +67,7 @@ The person where the course is located must be associated to the course. Change
#relationship
relationship:
- duplicate: Une relation de filiation existe déjà entre ces 2 personnes
+ duplicate: Une relation de filiation existe déjà entre ces 2 usagers
person_creation:
If you want to create an household, an address is required: Pour la création d'un ménage, une adresse est requise
diff --git a/src/Bundle/ChillReportBundle/translations/messages.fr.yml b/src/Bundle/ChillReportBundle/translations/messages.fr.yml
index 9cd2d5d8c..cfde70521 100644
--- a/src/Bundle/ChillReportBundle/translations/messages.fr.yml
+++ b/src/Bundle/ChillReportBundle/translations/messages.fr.yml
@@ -8,7 +8,7 @@
'Update the report': 'Modifier le rapport'
'Report list': 'Liste des rapports'
Details: Détails
-Person: Personne
+Person: Usager
Scope: Cercle
Date: Date
User: Utilisateur
@@ -17,7 +17,7 @@ User: Utilisateur
Report data: Données du rapport
'Report view : %name%': 'Rapport : %name%'
Report: Rapport
-No report registered for this person.: Aucun rapport pour cette personne.
+No report registered for this person.: Aucun rapport pour cet usager.
#Flash messages
'Success : report created!': "Succès : le rapport a bien été créé !"
@@ -52,4 +52,4 @@ CHILL_REPORT_LISTS: Liste des rapports
"Report's question": Question du rapport
Filter by report's date: Filtrer par date de rapport
Report is after this date: Rapports après cette date
-Report is before this date: Rapports avant cette date
\ No newline at end of file
+Report is before this date: Rapports avant cette date
diff --git a/src/Bundle/ChillTaskBundle/translations/messages.fr.yml b/src/Bundle/ChillTaskBundle/translations/messages.fr.yml
index 8d1d2b39d..d437baac2 100644
--- a/src/Bundle/ChillTaskBundle/translations/messages.fr.yml
+++ b/src/Bundle/ChillTaskBundle/translations/messages.fr.yml
@@ -14,7 +14,7 @@ Scope: Cercle
"Unit": ""
Task: Tâche
Details: Détails
-Person: Personne
+Person: Usager
Date: Date
Dates: Dates
User: Utilisateur
@@ -49,7 +49,7 @@ User: Utilisateur
"Tasks for {{ name }}": "Tâches pour {{ name }}"
"No description": "Pas de description"
"No dates specified": "Dates non spécifiées"
-"No one assignee": "Aucune personne assignée"
+"No one assignee": "Aucune usager assigné"
"Task types": Types de tâches
Days: Jour(s)
Weeks: Semaine(s)
@@ -59,7 +59,7 @@ Filter the tasks: Filtrer les tâches
Filter: Filtrer
Any user: Tous les utilisateurs
Unassigned: Non assigné
-Associated person: Personne associée
+Associated person: Usager associé
Default task: Tâche par défaut
Not assigned: Aucun utilisateur assigné
For person: Pour
@@ -117,5 +117,5 @@ CHILL_TASK_TASK_DELETE: Supprimer une tâche
CHILL_TASK_TASK_SHOW: Voir une tâche
CHILL_TASK_TASK_UPDATE: Modifier une tâche
CHILL_TASK_TASK_CREATE_FOR_COURSE: Créer une tâche pour un parcours
-CHILL_TASK_TASK_CREATE_FOR_PERSON: Créer une tâche pour une personne
+CHILL_TASK_TASK_CREATE_FOR_PERSON: Créer une tâche pour un usager
From 380ad2e2e6d1c4540cd6617f7a01c3e5267607dc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Mon, 3 Apr 2023 18:51:35 +0200
Subject: [PATCH 30/46] =?UTF-8?q?UI:=20replace=20"p=C3=A9riode"=20by=20"pa?=
=?UTF-8?q?rcours"=20in=20french?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../translations/messages.fr.yml | 4 +-
.../translations/messages.fr.yml | 152 +++++++++---------
.../translations/validators.fr.yml | 2 +-
3 files changed, 79 insertions(+), 79 deletions(-)
diff --git a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml
index 63324cd0d..18ab56dfe 100644
--- a/src/Bundle/ChillActivityBundle/translations/messages.fr.yml
+++ b/src/Bundle/ChillActivityBundle/translations/messages.fr.yml
@@ -183,8 +183,8 @@ Private comment visible: Visibilité du champ Commentaire Privé
Private comment label: Libellé du champ Commentaire Privé
Emergency visible: Visibilité du champ Urgent
Emergency label: Libellé du champ Urgent
-Accompanying period visible: Visibilité du champ Période d'accompagnement
-Accompanying period label: Libellé du champ Période d'accompagnement
+Accompanying period visible: Visibilité du champ parcours d'accompagnement
+Accompanying period label: Libellé du champ parcours d'accompagnement
Social issues visible: Visibilité du champ Problématiques sociales
Social issues label: Libellé du champ Problématiques sociales
Social actions visible: Visibilité du champ Action sociale
diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml
index 6cec9e36d..eb0c044f2 100644
--- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml
+++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml
@@ -136,9 +136,9 @@ address_country_name: Pays
address_country_code: Code pays
'Alreay existing person': 'Dossiers déjà encodés'
-'Add the person': 'Ajouter la usager'
-'Add the person and create an accompanying period': "Créer la usager ET créer une période d'accompagnement"
-'Add the person and create a household': "Créer la usager ET créer un ménage"
+'Add the person': "Ajouter l'usager"
+'Add the person and create an accompanying period': "Créer l'usager et créer un parcours d'accompagnement"
+'Add the person and create a household': "Créer l'usager et créer un ménage"
Show person: Voir le dossier de l'usager
'Confirm the creation': 'Confirmer la création'
'You will create this person': 'Vous allez créer le dossier suivant'
@@ -148,7 +148,7 @@ Reset: 'Remise à zéro'
'The person data has been updated': 'Les données ont été mises à jour.'
'The person data provided are not valid': 'Les données introduites ne sont pas valides'
'{1} The person field %field% is incorrect. Please check. | ]1, Inf] Several person fields are incorrect. Please check.': '{1} Le champs %field% est incorrect. Veuillez le corriger. | ]1, Inf] Plusieurs champs sont incorrects. Veuillez les vérifier.'
-'Add a person': 'Ajout d''une usager'
+'Add a person': 'Ajout d''un usager'
'Person Menu': 'Menu usager'
'The person data are not valid': 'Les données de votre formulaire sont invalides.'
'%nb% person with similar name. Please verify that this is a new person': '{1} Une usager a un nom similaire. Vérifiez qu''il ne s''agit pas d''elle. | ]1, Inf] %nb% usagers ont un nom similaire. Vérifiez qu''il ne s''agit pas de l''une d''elles.'
@@ -158,41 +158,41 @@ Person search results by phonenumber: Recherche d'usager par numéro de téléph
'Search within persons': 'Recherche parmi les usagers'
Open person file: Ouvrir le dossier de l'usager
and %number% other: '{0} et aucun autre| {1} et une autre |]1, Inf] et %number% autres'
-'%total% persons matching the search pattern:': '{0} Aucune usager ne correspond aux termes de recherche : | {1} Une usager a été trouvée par la recherche : | ]1,Inf] %total% usagers correspondent aux termes de recherche :'
+'%total% persons matching the search pattern:': '{0} Aucune usager ne correspond aux termes de recherche : | {1} Un usager a été trouvé par la recherche : | ]1,Inf] %total% usagers correspondent aux termes de recherche :'
'Last opening since %last_opening%': 'Dernière ouverture le %last_opening%.'
'Person accompanying period - %name%': 'Historique du dossier - %name%'
'Opening date': 'Date d''ouverture'
'Closing date': 'Date de clôture'
'Period opened': 'Période ouverte'
-'Close accompanying period': 'Clôre la période'
-'Open accompanying period': 'Ouvrir la période'
+'Close accompanying period': 'Clôre le parcours'
+'Open accompanying period': 'Ouvrir le parcours'
Period number %number%: 'Période n° %number%'
-'Add an accompanying period in the past': Ajouter une période d'accompagnement dans le passé
-Begin a new accompanying period: Commencer une nouvelle période d'accompagnement
-Create an accompanying period: Créer une période d'accompagnement
-'A period has been created.': Une période d'accompagnement a été créée.
-'Error! Period not created!': La période d'accompagnement n'a pas été créée.
-Update accompanying period: Mettre à jour une période d'accompagnement
-'An accompanying period has been updated.': Une période d'accompagnement a été mise à jour
-'Error when updating the period': Erreur pendant la mise à jour de la période d'accompagnement.
-'An accompanying period has been closed.': Une période d'accompagnement a été fermée.
-'Error! Period not closed!': "Erreur: la période d'accompagnement n'a pas été fermée."
-'An accompanying period has been opened.': Une période d'accompagnement a été ouverte.
+'Add an accompanying period in the past': Ajouter un parcours d'accompagnement dans le passé
+Begin a new accompanying period: Commencer un nouveau parcours d'accompagnement
+Create an accompanying period: Créer un parcours d'accompagnement
+'A period has been created.': Un parcours d'accompagnement a été créé.
+'Error! Period not created!': Le parcours d'accompagnement n'a pas été créé.
+Update accompanying period: Mettre à jour un parcours d'accompagnement
+'An accompanying period has been updated.': Un parcours d'accompagnement a été mise à jour
+'Error when updating the period': Erreur pendant la mise à jour du parcours d'accompagnement.
+'An accompanying period has been closed.': Un parcours d'accompagnement a été fermée.
+'Error! Period not closed!': "Erreur: le parcours d'accompagnement n'a pas été fermé."
+'An accompanying period has been opened.': Un parcours d'accompagnement a été ouvert.
'No remark': Pas de remarque
-'Period not opened': "La période d'accompagnement n'a pas été ouverte"
-"Period not opened : form is invalid": "La période n'a pas été ouverte: le formulaire est invalide."
+'Period not opened': "Le parcours d'accompagnement n'a pas été ouvert"
+"Period not opened : form is invalid": "Le parcours d'accompagnement n'a pas été ouverte: le formulaire est invalide."
'Closing motive': 'Motif de clôture'
This course is closed: Ce parcours est clôturé
Close accompanying course: Clôturer le parcours
Re-open accompanying course: Ré-ouvrir le parcours
-'Person details': 'Détails de la usager'
+'Person details': "Détails de l'usager"
'Update details for %name%': 'Modifier détails de %name%'
-An accompanying period ends: Une periode d'accompagnement se clôture
-An accompanying period starts: Une période d'accompagnement est ouverte
-Any accompanying periods are open: Aucune période d'accompagnement ouverte
-An accompanying period is open: Une période d'accompagnement est ouverte
-Accompanying period list: Périodes d'accompagnement
-Accompanying period list for person: Périodes d'accompagnement de l'usager
+An accompanying period ends: Un parcours d'accompagnement se clôture
+An accompanying period starts: Un parcours d'accompagnement est ouvert
+Any accompanying periods are open: Aucune parcours d'accompagnement ouvert
+An accompanying period is open: Un parcours d'accompagnement est ouvert
+Accompanying period list: Parcours d'accompagnement
+Accompanying period list for person: Parcours d'accompagnement de l'usager
Accompanying period: Parcours d'accompagnement
Any accompanying period: Aucun parcours d'accompagnement
period: Parcours
@@ -200,8 +200,8 @@ New accompanying course: Nouveau parcours d'accompagnement
Choose a motive: Motif de fermeture
Re-open accompanying period: Ré-ouvrir
Re-Open a period: Ré-ouvrir
-Are you sure you want to re-open this period ?: Êtes-vous sûr de vouloir ré-ouvrir cette période d'accompagnement ?
-'The period has been re-opened': La période d'accompagnement a été ré-ouverte.
+Are you sure you want to re-open this period ?: Êtes-vous sûr de vouloir ré-ouvrir cet parcours d'accompagnement ?
+'The period has been re-opened': Le parcours d'accompagnement a été ré-ouverte.
Pediod closing form is not valid: Le formulaire n'est pas valide
Accompanying user: Accompagnant
No accompanying user: Aucun accompagnant
@@ -222,10 +222,10 @@ Social issues: Problématiques sociales
Pick a social issue: Choisir une problématique sociale
Last events on accompanying course: Dernières actions de suivi
Edit & activate accompanying course: Modifier et valider
-See accompanying periods: Voir toutes les périodes d'accompagnement
-See accompanying period: Voir la période
-Edit accompanying period: Modifier la période
-See this period: Voir cette période
+See accompanying periods: Voir tous les parcours d'accompagnement
+See accompanying period: Voir le parcours
+Edit accompanying period: Modifier le parcours
+See this period: Voir cet parcours
Requestor: Demandeur
No requestor: Pas de demandeur
No resources: "Pas d'interlocuteurs privilégiés"
@@ -240,24 +240,24 @@ Any resource for this accompanying course: Aucun interlocuteur privilégié pour
course.draft: Brouillon
course.closed: Clôturé
Origin: Origine de la demande
-Delete accompanying period: Supprimer la période d'accompagnement
-Are you sure you want to remove the accompanying period "%id%" ?: Êtes-vous sûr de vouloir supprimer la période d'accompagnement %id% ?
-The accompanying course has been successfully removed.: La période d'accompagnement a été supprimée.
+Delete accompanying period: Supprimer le parcours d'accompagnement
+Are you sure you want to remove the accompanying period "%id%" ?: Êtes-vous sûr de vouloir supprimer le parcours d'accompagnement %id% ?
+The accompanying course has been successfully removed.: Le parcours d'accompagnement a été supprimé.
Concerned scopes: Services concernés
# person resource
person_resources_menu: "Personnes ressources"
-Person resources: "Ressources de la usager"
-Add a person resource: "Ajouter une ressource"
-edit resource: "Modifier ressource"
-Remove resource: "Supprimer ressource"
+Person resources: "Personnes ressources de l'usager"
+Add a person resource: "Ajouter une person ressource"
+edit resource: "Modifier la ressource"
+Remove resource: "Supprimer la ressource"
Are you sure you want to remove the resource for "%name%" ?: Étes-vous sûr de vouloir supprimer cette ressource de %name%?
The resource has been successfully removed.: "La ressource a été supprimée."
-List of resources: "Liste des ressources"
-There are no available resources: "Aucun ressource"
+List of resources: "Liste des personnes ressources"
+There are no available resources: "Aucun personne ressource"
no comment found: "Aucun commentaire"
Select a type: "Choisissez un type"
-Select a person: "Choisissez une usager"
+Select a person: "Choisissez un usager"
Kind: "Type"
@@ -286,7 +286,7 @@ Add a residential address: Ajouter une adresse de résidence
Which kind of residential address would you create ?: Quel type d'adresse de résidence voulez-vous créer?
The address of another person: L'adresse d'une autre usager
A new address: Une nouvelle adresse
-residential_address_person_explanation: L'adresse sera positionnée auprès d'un usager. Lorsque la usager déménage, l'adresse de résidence suivra également cette usager
+residential_address_person_explanation: L'adresse sera positionnée auprès d'un usager. Lorsque l'usager déménage, l'adresse de résidence suivra également cette usager
residential_address_new_address_explanation: Créer une nouvelle adresse. L'adresse sera fixe.
New residential address: Nouvelle adresse de résidence
Host person: Choisir l'adresse d'un usager
@@ -303,8 +303,8 @@ Residential address had been deleted: L'adresse de résidence a été supprimée
#timeline
Timeline: Historique
-Closing the accompanying period: Fermeture de la période d'accompagnement
-Opening the accompanying period: Ouverture d'une période d'accompagnement
+Closing the accompanying period: Fermeture du parcours d'accompagnement
+Opening the accompanying period: Ouverture d'un parcours d'accompagnement
'Timeline for %name%': 'Historique de %name%'
# ROLES
@@ -315,17 +315,17 @@ CHILL_PERSON_STATS: Statistiques sur les usagers
CHILL_PERSON_LISTS: Liste des usagers
CHILL_PERSON_DUPLICATE: Gérer les doublons d'usagers
-CHILL_PERSON_ACCOMPANYING_PERIOD_SEE: Vision simplifiée d'une période d'accompagnement
-CHILL_PERSON_ACCOMPANYING_PERIOD_CONFIDENTIAL: Voir et modifier les périodes d'accompagnement confidentielles
-CHILL_PERSON_ACCOMPANYING_PERIOD_DELETE: Supprimer une période d'accompagnement
+CHILL_PERSON_ACCOMPANYING_PERIOD_SEE: Vision simplifiée d'un parcours d'accompagnement
+CHILL_PERSON_ACCOMPANYING_PERIOD_CONFIDENTIAL: Voir et modifier les parcours d'accompagnement confidentielles
+CHILL_PERSON_ACCOMPANYING_PERIOD_DELETE: Supprimer un pacours d'accompagnement
CHILL_PERSON_ACCOMPANYING_PERIOD_RE_OPEN: Ré-ouvrir un parcours clotûré
CHILL_PERSON_ACCOMPANYING_PERIOD_TOGGLE_CONFIDENTIAL_ALL: Modifier la confidentialité de tous les parcours
-CHILL_PERSON_ACCOMPANYING_PERIOD_CRUD_CONFIDENTIAL: Voir les périodes d'accompagnement confidentielles
-CHILL_PERSON_ACCOMPANYING_PERIOD_CREATE: Créer une période d'accompagnement
-CHILL_PERSON_ACCOMPANYING_PERIOD_UPDATE: Modifier une période d'accompagnement
-CHILL_PERSON_ACCOMPANYING_PERIOD_FULL: Voir les détails, créer, supprimer et mettre à jour une période d'accompagnement
+CHILL_PERSON_ACCOMPANYING_PERIOD_CRUD_CONFIDENTIAL: Voir les parcours d'accompagnement confidentiels
+CHILL_PERSON_ACCOMPANYING_PERIOD_CREATE: Créer un parcours d'accompagnement
+CHILL_PERSON_ACCOMPANYING_PERIOD_UPDATE: Modifier un parcours d'accompagnement
+CHILL_PERSON_ACCOMPANYING_PERIOD_FULL: Voir les détails, créer, supprimer et mettre à jour un parcours d'accompagnement
CHILL_PERSON_ACCOMPANYING_COURSE_REASSIGN_BULK: Réassigner les parcours en lot
-CHILL_PERSON_ACCOMPANYING_PERIOD_SEE_DETAILS: Voir les détails d'une période d'accompagnement
+CHILL_PERSON_ACCOMPANYING_PERIOD_SEE_DETAILS: Voir les détails d'un parcours d'accompagnement
CHILL_PERSON_ACCOMPANYING_PERIOD_STATS: Statistiques sur les parcours d'accompagnement
CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_CREATE: Créer une action d'accompagnement
@@ -342,7 +342,7 @@ CHILL_PERSON_HOUSEHOLD_EDIT: Modifier les ménages
CHILL_PERSON_HOUSEHOLD_STATS: Statistiques sur les ménages
#period
-Period closed!: Période clôturée!
+Period closed!: Parcours clôturé!
Pediod closing form is not valide: Le formulaire de fermeture n'est pas valide
#widget
@@ -436,19 +436,19 @@ Filtered by nomadic status: Uniquement les usagers qui sont "gens du voyage"
Filter by person's that are alive or have deceased at a certain date: Filtrer les usagers qui sont décédés ou vivantes à une certaine date
Filtered by person's that are alive or have deceased at a certain date: Uniquement les usagers qui sont décédés ou vivantes à une certaine date
-"Filter by accompanying period: active period": "Filtrer les usagers par période d'accompagnement: en file active"
-Having an accompanying period opened after this date: Ayant une période d'accompagnement ouverte après cette date
-Having an accompanying period ending before this date, or still opened at this date: Ayant une période d'accompagnement fermée après cette date, ou toujours ouverte à cette date
-"Filtered by accompanying period: persons having an accompanying period opened after the %date_from% and closed before the %date_to% (or still opened at the %date_to%)": "Filtré par période d'accompagnement: usagers ayant une période d'accompagnement ouverte après le %date_from%, et cloturée le %date_to% (ou toujours ouverte le %date_to%)"
+"Filter by accompanying period: active period": "Filtrer les usagers par parcours d'accompagnement: en file active"
+Having an accompanying period opened after this date: Ayant un parcours d'accompagnement ouverte après cette date
+Having an accompanying period ending before this date, or still opened at this date: Ayant un parcours d'accompagnement fermée après cette date, ou toujours ouverte à cette date
+"Filtered by accompanying period: persons having an accompanying period opened after the %date_from% and closed before the %date_to% (or still opened at the %date_to%)": "Filtré par parcours d'accompagnement: usagers ayant un parcours d'accompagnement ouvert après le %date_from%, et cloturé le %date_to% (ou toujours ouvert le %date_to%)"
-"Filter by accompanying period: starting between two dates": "Filtrer les usagers par période d'accompagnement: début de la période entre deux dates"
-"Having an accompanying period opened before this date": "Ayant une période d'accompagnement ouverte avant cette date"
-"Filtered by accompanying period: persons having an accompanying period opened between the %date_from% and %date_to%": "Filtrer par période d'accompagnement: ayant une période ouverte entre le %date_from% et le %date_to%"
+"Filter by accompanying period: starting between two dates": "Filtrer les usagers par parcours d'accompagnement: début de la période entre deux dates"
+"Having an accompanying period opened before this date": "Ayant un parcours d'accompagnement ouvert avant cette date"
+"Filtered by accompanying period: persons having an accompanying period opened between the %date_from% and %date_to%": "Filtrer par parcours d'accompagnement: ayant un parcours ouvert entre le %date_from% et le %date_to%"
-"Filter by accompanying period: closed between two dates": "Filtrer les usagers par période d'accompagnement: période fermée entre deux dates"
-Having an accompanying period closed after this date: Ayant une période d'accompagnement fermée après cette date
-"Having an accompanying period closed before this date": "Ayant une période d'accompagnement fermée avant cette date"
-"Filtered by accompanying period: persons having an accompanying period closed between the %date_from% and %date_to%": "Filtrer par période d'accompagnement: ayant une période fermée entre le %date_from% et le %date_to%"
+"Filter by accompanying period: closed between two dates": "Filtrer les usagers par parcours d'accompagnement: parcours fermé entre deux dates"
+Having an accompanying period closed after this date: Ayant un parcours d'accompagnement fermé après cette date
+"Having an accompanying period closed before this date": "Ayant un parcours d'accompagnement fermé avant cette date"
+"Filtered by accompanying period: persons having an accompanying period closed between the %date_from% and %date_to%": "Filtrer par parcours d'accompagnement: ayant un parcours fermé entre le %date_from% et le %date_to%"
Filter by person having an activity in a period: Filtrer les usagers ayant eu un échange pendant la période donnée
Filtered by person having an activity between %date_from% and %date_to% with reasons %reasons_name%: Uniquement les usagers associés à un échange entre %date_from% et %date_to% avec les sujets %reasons_name%
@@ -523,7 +523,7 @@ Group by administrative location: Grouper les parcours par localisation administ
Filter by requestor: Filtrer les parcours selon la présence du demandeur au sein des usagers concernés
Accepted choices: ''
is person concerned: Le demandeur est un usager concerné
-is other person: Le demandeur est une usager, mais n'est pas concerné
+is other person: Le demandeur est un usager, mais n'est pas concerné
no requestor: Le parcours ne comporte pas de demandeur
"Filtered by requestor: only %choice%": "Filtré par présence du demandeur au sein des usagers concernés: uniquement si %choice%"
Group by requestor: Grouper les parcours selon la nature du demandeur
@@ -784,7 +784,7 @@ person_admin:
closing motives list: Liste des motifs de clotûre
closing motive explanation: >
Les motifs de clotûre donnent des indications sur la fermeture
- d'une période d'accompagnement.
+ d'un parcours d'accompagnement.
origin: Origines
marital status: États civils
marital status list: Liste des états civils
@@ -825,11 +825,11 @@ Edit Accompanying Course: Modifier le parcours
Close Accompanying Course: Clôturer le parcours
Create Accompanying Course: Créer un nouveau parcours
Drop Accompanying Course: Supprimer le parcours
-This course is located at a temporarily address. You should locate this course to an user: Le parcours est localisé à une adresse temporaire. Il devrait être localisé auprès d'une usager concerné.
+This course is located at a temporarily address. You should locate this course to an user: Le parcours est localisé à une adresse temporaire. Il devrait être localisé auprès d'un usager concerné.
Accompanying course location: Localisation du parcours
This course is located by: Localisé auprès de
This course has a temporarily location: Localisation temporaire
-Choose a person to locate by: Localiser auprès d'une usager concerné
+Choose a person to locate by: Localiser auprès d'un usager concerné
Associate at least one member with an household, and set an address to this household: Associez au moins un membre du parcours à un ménage, et indiquez une adresse à ce ménage.
Locate by: Localiser auprès de
fix it: Compléter
@@ -884,7 +884,7 @@ Household configuration: Gestion des ménages
# accompanying course work
Accompanying Course Actions: Actions d'accompagnements
Accompanying Course Action: Action d'accompagnement
-Are you sure you want to remove this work of the accompanying period %name% ?: Êtes-vous sûr de vouloir supprimer cette action de la période d'accompagnement %name% ?
+Are you sure you want to remove this work of the accompanying period %name% ?: Êtes-vous sûr de vouloir supprimer cette action du parcours d'accompagnement %name% ?
The accompanying period work has been successfully removed.: L'action d'accompagnement a été supprimée.
accompanying_course_work:
create: Créer une action
@@ -944,9 +944,9 @@ period_notification:
See it online: Visualisez le parcours en ligne
Person locating period has moved: L'usager qui localise un parcours a déménagé
-You are getting a notification for a period which does not exists any more: Cette notification ne correspond pas à une période d'accompagnement valide.
-You are getting a notification for a period you are not allowed to see: La notification fait référence à une période d'accompagnement à laquelle vous n'avez pas accès.
-This is the minimal period details: Période d'accompagnement n°
+You are getting a notification for a period which does not exists any more: Cette notification ne correspond pas à un parcours d'accompagnement valide.
+You are getting a notification for a period you are not allowed to see: La notification fait référence à un parcours d'accompagnement à laquelle vous n'avez pas accès.
+This is the minimal period details: Parcours d'accompagnement n°
household_composition:
No composition yet: Aucune composition familiale renseignée
@@ -1080,8 +1080,8 @@ export:
List peoples having an accompanying period: Liste des usagers ayant un parcours d'accompagnement
Create a list of people having an accompaying periods, according to various filters.: Génère une liste des usagers ayant un parcours d'accompagnement, selon différents critères liés au parcours ou à l'usager
acp:
- List of accompanying periods: Liste de périodes d'accompagnements
- Generate a list of accompanying periods, filtered on different parameters.: Génère une liste des périodes d'accompagnement, filtrée sur différents paramètres.
+ List of accompanying periods: Liste des parcours d'accompagnements
+ Generate a list of accompanying periods, filtered on different parameters.: Génère une liste des parcours d'accompagnement, filtrée sur différents paramètres.
Date of calculation for associated elements: Date de calcul des éléments associés
The associated referree, localisation, and other elements will be valid at this date: Les éléments associés, comme la localisation, le référent et d'autres éléments seront valides à cette date
id: Identifiant du parcours
diff --git a/src/Bundle/ChillPersonBundle/translations/validators.fr.yml b/src/Bundle/ChillPersonBundle/translations/validators.fr.yml
index f4b0c62ad..8fcda47aa 100644
--- a/src/Bundle/ChillPersonBundle/translations/validators.fr.yml
+++ b/src/Bundle/ChillPersonBundle/translations/validators.fr.yml
@@ -10,7 +10,7 @@
'Opening date can not be null': 'La date d''ouverure ne peut être nulle'
'Closing date is not valid': 'La date de fermeture n''est pas valide'
'Closing date can not be null': 'La date de fermeture ne peut être nulle'
-The date of closing is before the date of opening: La période de fermeture est avant la période d'ouverture
+The date of closing is before the date of opening: La date de fermeture est avant la date d'ouverture
The closing date must be later than the date of creation: La date de clôture doit être postérieure à la date de création du parcours
The birthdate must be before %date%: La date de naissance doit être avant le %date%
'Invalid phone number: it should begin with the international prefix starting with "+", hold only digits and be smaller than 20 characters. Ex: +33123456789': 'Numéro de téléphone invalide: il doit commencer par le préfixe international précédé de "+", ne comporter que des chiffres et faire moins de 20 caractères. Ex: +31623456789'
From 46e1891386fc1c6261a862b9e46e15b1c9a79ac2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Mon, 3 Apr 2023 19:17:30 +0200
Subject: [PATCH 31/46] Fixed: fix error when displaying calendar list with
invite in person context
---
.../Resources/views/Activity/concernedGroups.html.twig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/concernedGroups.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/concernedGroups.html.twig
index 96cfef39b..48eb839d7 100644
--- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/concernedGroups.html.twig
+++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/concernedGroups.html.twig
@@ -5,7 +5,7 @@
Maybe should we think about abstracting this file a bit more ? Moving it to PersonBundle ?
#}
-{% if context == 'calendar_accompanyingCourse' %}
+{% if context == 'calendar_accompanyingCourse' or context == 'calendar_person' %}
{% import "@ChillCalendar/_invite.html.twig" as invite %}
{% endif %}
From 4cf6721e351f5f95ea14fd3aaf05c151247db605 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Mon, 3 Apr 2023 19:54:10 +0200
Subject: [PATCH 32/46] Feature: [calendar] convert calendar to activity in the
context of a person
---
.../Controller/CalendarController.php | 22 ++++++----
.../Resources/views/Calendar/_list.html.twig | 43 ++++++++++++++++++-
2 files changed, 56 insertions(+), 9 deletions(-)
diff --git a/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php b/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php
index 550c6e984..5f1b70aa0 100644
--- a/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php
+++ b/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php
@@ -526,14 +526,20 @@ class CalendarController extends AbstractController
'comment' => $calendar->getComment()->getComment(),
];
- return $this->redirectToRoute(
- 'chill_activity_activity_new',
- [
- 'accompanying_period_id' => $calendar->getAccompanyingPeriod()->getId(),
- 'activityData' => $activityData,
- 'returnPath' => $request->query->get('returnPath', null),
- ]
- );
+ $routeParams = [
+ 'activityData' => $activityData,
+ 'returnPath' => $request->query->get('returnPath', null),
+ ];
+
+ if ($calendar->getContext() === 'accompanying_period'){
+ $routeParams['accompanying_period_id'] = $calendar->getAccompanyingPeriod()->getId();
+ } elseif ($calendar->getContext() === 'person') {
+ $routeParams['person_id'] = $calendar->getPerson()->getId();
+ } else {
+ throw new RuntimeException('context not found for this calendar');
+ }
+
+ return $this->redirectToRoute('chill_activity_activity_new', $routeParams);
}
private function buildListFilterOrder(): FilterOrderHelper
diff --git a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/_list.html.twig b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/_list.html.twig
index d6110917a..c09be27b7 100644
--- a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/_list.html.twig
+++ b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/_list.html.twig
@@ -103,6 +103,42 @@
{% endif %}
+ {% if calendar.activity is not null %}
+
+
+
+
+
{{ 'Activity'|trans }}
+
+
+
+
+ {{ calendar.activity.type.name | localize_translatable_string }}
+
+ {% if calendar.activity.emergency %}
+ {{ 'Emergency'|trans|upper }}
+ {% endif %}
+
+
+
+
+
+ {{ 'Created by'|trans }} {{ calendar.activity.createdBy|chill_entity_render_string }}, {{ 'on'|trans }} {{ calendar.activity.createdAt|format_datetime('short', 'short') }}
+
+ {% if is_granted('CHILL_ACTIVITY_SEE', calendar.activity) %}
+
+
+
+ {% endif %}
+
+
+
+
+
+
+
+ {% endif %}
+
@@ -147,7 +183,12 @@
{% endif %}
{% endif %}
- {% if accompanyingCourse is defined and is_granted('CHILL_ACTIVITY_CREATE', accompanyingCourse) and calendar.activity is null %}
+ {% if calendar.activity is null and (
+ (calendar.context == 'accompanying_period' and is_granted('CHILL_ACTIVITY_CREATE', calendar.accompanyingPeriod))
+ or
+ (calendar.context == 'person' and is_granted('CHILL_ACTIVITY_CREATE', calendar.person))
+ )
+ %}
From 907c7240471cde457361546d234f4f7ea333719b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Mon, 3 Apr 2023 21:30:50 +0200
Subject: [PATCH 33/46] Feature: [calendar doc] re-introduce button to edit
document title and remove document
---
.../Form/CalendarDocEditType.php | 3 --
.../views/Calendar/_documents.twig.html | 21 ++++++++---
.../Resources/views/Calendar/_list.html.twig | 37 ++++++++++---------
.../edit_accompanying_period.html.twig | 1 -
.../views/CalendarDoc/edit_person.html.twig | 1 -
5 files changed, 35 insertions(+), 28 deletions(-)
diff --git a/src/Bundle/ChillCalendarBundle/Form/CalendarDocEditType.php b/src/Bundle/ChillCalendarBundle/Form/CalendarDocEditType.php
index 26a9d59e2..34a501028 100644
--- a/src/Bundle/ChillCalendarBundle/Form/CalendarDocEditType.php
+++ b/src/Bundle/ChillCalendarBundle/Form/CalendarDocEditType.php
@@ -26,9 +26,6 @@ class CalendarDocEditType extends AbstractType
->add('title', TextType::class, [
'label' => 'chill_calendar.Document title',
'required' => true,
- ])
- ->add('doc', StoredObjectType::class, [
- 'label' => 'chill_calendar.Document object',
]);
}
diff --git a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/_documents.twig.html b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/_documents.twig.html
index 09824b5cc..c295d31a1 100644
--- a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/_documents.twig.html
+++ b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/_documents.twig.html
@@ -20,15 +20,24 @@
{{ d.storedObject.title }}
- {% if d.dateTimeVersion < d.calendar.dateTimeVersion %}
+
+ {% if d.dateTimeVersion < d.calendar.dateTimeVersion %}
+
{{ 'chill_calendar.Document outdated'|trans }}
- {% endif %}
-
-
- {{ mm.mimeIcon(d.storedObject.type) }}
+ {% endif %}
- {{ d.storedObject|chill_document_button_group(d.storedObject.title, is_granted('CHILL_CALENDAR_DOC_EDIT', d), {'small': true}) }}
+
+
+ {{ d.storedObject|chill_document_button_group(d.storedObject.title, is_granted('CHILL_CALENDAR_DOC_EDIT', d), {'small': true}) }}
+
+
+
+
+
+
+
+
diff --git a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/_list.html.twig b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/_list.html.twig
index c09be27b7..2c3cde01a 100644
--- a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/_list.html.twig
+++ b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/_list.html.twig
@@ -103,6 +103,13 @@
{% endif %}
+
+
+
+ {{ include('@ChillCalendar/Calendar/_documents.twig.html') }}
+
+
+
{% if calendar.activity is not null %}
@@ -121,16 +128,19 @@
-
-
- {{ 'Created by'|trans }} {{ calendar.activity.createdBy|chill_entity_render_string }}, {{ 'on'|trans }} {{ calendar.activity.createdAt|format_datetime('short', 'short') }}
+
+
+
+ {{ 'Created by'|trans }}
+ {{ calendar.activity.createdBy|chill_entity_render_string }} , {{ 'on'|trans }} {{ calendar.activity.createdAt|format_datetime('short', 'short') }}
+
+
+ {% if is_granted('CHILL_ACTIVITY_SEE', calendar.activity) %}
+
+
- {% if is_granted('CHILL_ACTIVITY_SEE', calendar.activity) %}
-
-
-
- {% endif %}
-
+ {% endif %}
+
@@ -139,14 +149,7 @@
{% endif %}
-
-
-
- {{ include('@ChillCalendar/Calendar/_documents.twig.html') }}
-
-
-
-
+
{% if is_granted('CHILL_CALENDAR_CALENDAR_SEE', calendar) %}
{% if templates|length == 0 %}
diff --git a/src/Bundle/ChillCalendarBundle/Resources/views/CalendarDoc/edit_accompanying_period.html.twig b/src/Bundle/ChillCalendarBundle/Resources/views/CalendarDoc/edit_accompanying_period.html.twig
index 9941b000a..545db7100 100644
--- a/src/Bundle/ChillCalendarBundle/Resources/views/CalendarDoc/edit_accompanying_period.html.twig
+++ b/src/Bundle/ChillCalendarBundle/Resources/views/CalendarDoc/edit_accompanying_period.html.twig
@@ -24,7 +24,6 @@
{{ form_start(form) }}
{{ form_row(form.title) }}
- {{ form_row(form.doc) }}
{% if document.course is defined %}
- {% if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_DELETE', document) %}
-
-
-
- {% endif %}
- {% if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_UPDATE', document) %}
-
-
-
- {% endif %}
+
+ {{ chill_entity_workflow_list('Chill\\DocStoreBundle\\Entity\\AccompanyingCourseDocument', document.id) }}
+
{% if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_SEE_DETAILS', document) %}
{{ document.object|chill_document_button_group(document.title, is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_UPDATE', document)) }}
@@ -69,20 +62,17 @@
{% endif %}
-
- {{ chill_entity_workflow_list('Chill\\DocStoreBundle\\Entity\\AccompanyingCourseDocument', document.id) }}
-
- {% else %}
- {% if is_granted('CHILL_PERSON_DOCUMENT_DELETE', document) %}
-
-
-
- {% endif %}
- {% if is_granted('CHILL_PERSON_DOCUMENT_UPDATE', document) %}
+ {% if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_UPDATE', document) %}
-
+
{% endif %}
+ {% if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_DELETE', document) %}
+
+
+
+ {% endif %}
+ {% else %}
{% if is_granted('CHILL_PERSON_DOCUMENT_SEE_DETAILS', document) %}
{{ document.object|chill_document_button_group(document.title, is_granted('CHILL_PERSON_DOCUMENT_UPDATE', document)) }}
@@ -91,6 +81,16 @@
{% endif %}
+ {% if is_granted('CHILL_PERSON_DOCUMENT_UPDATE', document) %}
+
+
+
+ {% endif %}
+ {% if is_granted('CHILL_PERSON_DOCUMENT_DELETE', document) %}
+
+
+
+ {% endif %}
{% endif %}
diff --git a/src/Bundle/ChillDocStoreBundle/Security/Authorization/AccompanyingCourseDocumentVoter.php b/src/Bundle/ChillDocStoreBundle/Security/Authorization/AccompanyingCourseDocumentVoter.php
index 02dfb5b64..0ef1d4d49 100644
--- a/src/Bundle/ChillDocStoreBundle/Security/Authorization/AccompanyingCourseDocumentVoter.php
+++ b/src/Bundle/ChillDocStoreBundle/Security/Authorization/AccompanyingCourseDocumentVoter.php
@@ -78,12 +78,12 @@ class AccompanyingCourseDocumentVoter extends AbstractChillVoter implements Prov
return [];
}
- protected function supports($attribute, $subject)
+ protected function supports($attribute, $subject): bool
{
return $this->voterHelper->supports($attribute, $subject);
}
- protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
+ protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool
{
if (!$token->getUser() instanceof User) {
return false;
diff --git a/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php b/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php
index 33e9a3db6..65e1cf688 100644
--- a/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php
+++ b/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php
@@ -16,7 +16,7 @@ use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Repository\UserACLAwareRepositoryInterface;
use Chill\MainBundle\Security\ParentRoleHelper;
-use Chill\MainBundle\Security\Resolver\CenterResolverDispatcherInterface;
+use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface;
use Chill\MainBundle\Security\Resolver\ScopeResolverDispatcher;
use Psr\Log\LoggerInterface;
use Symfony\Component\Security\Core\Role\Role;
@@ -34,7 +34,7 @@ use function get_class;
*/
class AuthorizationHelper implements AuthorizationHelperInterface
{
- private CenterResolverDispatcherInterface $centerResolverDispatcher;
+ private CenterResolverManagerInterface $centerResolverManager;
private LoggerInterface $logger;
@@ -45,13 +45,13 @@ class AuthorizationHelper implements AuthorizationHelperInterface
private UserACLAwareRepositoryInterface $userACLAwareRepository;
public function __construct(
- CenterResolverDispatcherInterface $centerResolverDispatcher,
+ CenterResolverManagerInterface $centerResolverManager,
LoggerInterface $logger,
ScopeResolverDispatcher $scopeResolverDispatcher,
UserACLAwareRepositoryInterface $userACLAwareRepository,
ParentRoleHelper $parentRoleHelper
) {
- $this->centerResolverDispatcher = $centerResolverDispatcher;
+ $this->centerResolverManager = $centerResolverManager;
$this->logger = $logger;
$this->scopeResolverDispatcher = $scopeResolverDispatcher;
$this->userACLAwareRepository = $userACLAwareRepository;
@@ -252,27 +252,15 @@ class AuthorizationHelper implements AuthorizationHelperInterface
*/
public function userHasAccess(User $user, $entity, $attribute)
{
- $center = $this->centerResolverDispatcher->resolveCenter($entity);
+ $centers = $this->centerResolverManager->resolveCenters($entity);
- if (is_iterable($center)) {
- foreach ($center as $c) {
- if ($this->userHasAccessForCenter($user, $c, $entity, $attribute)) {
- return true;
- }
+ foreach ($centers as $c) {
+ if ($this->userHasAccessForCenter($user, $c, $entity, $attribute)) {
+ return true;
}
-
- return false;
}
- if ($center instanceof Center) {
- return $this->userHasAccessForCenter($user, $center, $entity, $attribute);
- }
-
- if (null === $center) {
- return false;
- }
-
- throw new UnexpectedValueException('could not resolver a center');
+ return false;
}
/**
From 3df8ee6dc4209aa40147018b2d7ea4060b5892a9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Wed, 5 Apr 2023 19:31:27 +0200
Subject: [PATCH 35/46] fix cs
---
.../ChillCalendarBundle/Controller/CalendarController.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php b/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php
index 5f1b70aa0..199edf0c2 100644
--- a/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php
+++ b/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php
@@ -531,7 +531,7 @@ class CalendarController extends AbstractController
'returnPath' => $request->query->get('returnPath', null),
];
- if ($calendar->getContext() === 'accompanying_period'){
+ if ($calendar->getContext() === 'accompanying_period') {
$routeParams['accompanying_period_id'] = $calendar->getAccompanyingPeriod()->getId();
} elseif ($calendar->getContext() === 'person') {
$routeParams['person_id'] = $calendar->getPerson()->getId();
From 1c19d01b60f189c01a51a7082492d0ee4805c913 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Wed, 5 Apr 2023 20:23:43 +0200
Subject: [PATCH 36/46] Fixed: [calendar doc] Add a return path to the calendar
edit's form when the document has been generated
Fix https://gitlab.com/Chill-Projet/chill-bundles/-/issues/81
---
.../ChillCalendarBundle/Controller/CalendarController.php | 6 +++++-
.../views/CalendarDoc/new_accompanying_period.html.twig | 2 +-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php b/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php
index 199edf0c2..e97daae3f 100644
--- a/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php
+++ b/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php
@@ -207,6 +207,7 @@ class CalendarController extends AbstractController
'entityClassName' => Calendar::class,
'entityId' => $entity->getId(),
'template' => $template->getId(),
+ 'returnPath' => $request->getRequestUri(),
]);
}
}
@@ -377,7 +378,9 @@ class CalendarController extends AbstractController
$this->addFlash('success', $this->translator->trans('Success : calendar item created!'));
if ($form->get('save_and_upload_doc')->isClicked()) {
- return $this->redirectToRoute('chill_calendar_calendardoc_new', ['id' => $entity->getId()]);
+ return $this->redirectToRoute('chill_calendar_calendardoc_new', [
+ 'id' => $entity->getId()
+ ]);
}
foreach ($templates as $template) {
@@ -386,6 +389,7 @@ class CalendarController extends AbstractController
'entityClassName' => Calendar::class,
'entityId' => $entity->getId(),
'template' => $template->getId(),
+ 'returnPath' => $this->generateUrl('chill_calendar_calendar_edit', ['id' => $entity->getId()]),
]);
}
}
diff --git a/src/Bundle/ChillCalendarBundle/Resources/views/CalendarDoc/new_accompanying_period.html.twig b/src/Bundle/ChillCalendarBundle/Resources/views/CalendarDoc/new_accompanying_period.html.twig
index d397a9132..54f196622 100644
--- a/src/Bundle/ChillCalendarBundle/Resources/views/CalendarDoc/new_accompanying_period.html.twig
+++ b/src/Bundle/ChillCalendarBundle/Resources/views/CalendarDoc/new_accompanying_period.html.twig
@@ -28,7 +28,7 @@
{% endif %}
- {% if activity.user and t.userVisible %}
+ {% if activity.user is not null and t.userVisible %}
{{ 'Referrer'|trans }}
diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/show.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/show.html.twig
index acda43b97..fca6a7658 100644
--- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/show.html.twig
+++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/show.html.twig
@@ -34,10 +34,12 @@
- {{ 'Referrer'|trans|capitalize }}
-
- {{ entity.user|chill_entity_render_box }}
-
+ {%- if entity.user is not null %}
+ {{ 'Referrer'|trans|capitalize }}
+
+ {{ entity.user|chill_entity_render_box }}
+
+ {% endif %}
{%- if entity.scope -%}
{{ 'Scope'|trans }}
diff --git a/src/Bundle/ChillMainBundle/Resources/public/module/pick-entity/index.js b/src/Bundle/ChillMainBundle/Resources/public/module/pick-entity/index.js
index 6b143a11d..99f83e1e3 100644
--- a/src/Bundle/ChillMainBundle/Resources/public/module/pick-entity/index.js
+++ b/src/Bundle/ChillMainBundle/Resources/public/module/pick-entity/index.js
@@ -18,6 +18,7 @@ function loadDynamicPicker(element) {
isMultiple = parseInt(el.dataset.multiple) === 1,
uniqId = el.dataset.uniqid,
input = element.querySelector('[data-input-uniqid="'+ el.dataset.uniqid +'"]'),
+ // the "picked" will always be an array, even if multiple is false
picked = isMultiple ?
JSON.parse(input.value) : (
(input.value === '[]' || input.value === '') ?
@@ -54,15 +55,11 @@ function loadDynamicPicker(element) {
},
computed: {
notPickedSuggested() {
- if (this.multiple) {
- const pickedIds = new Set();
- for (const p of this.picked) {
- pickedIds.add(`${p.type}${p.id}`);
- }
- return this.suggested.filter(e => !pickedIds.has(`${e.type}${e.id}`))
+ const pickedIds = new Set();
+ for (const p of this.picked) {
+ pickedIds.add(`${p.type}${p.id}`);
}
-
- return this.suggested.filter(e => e.type !== this.picked.type && e.id !== e.picked.id);
+ return this.suggested.filter(e => !pickedIds.has(`${e.type}${e.id}`))
}
},
methods: {
@@ -90,7 +87,11 @@ function loadDynamicPicker(element) {
this.suggested.push(entity);
}
this.picked = this.picked.filter(e => !(e.type === entity.type && e.id === entity.id));
- input.value = JSON.stringify(this.picked);
+ if (this.multiple) {
+ input.value = JSON.stringify(this.picked);
+ } else {
+ input.value = "";
+ }
},
}
})
From 839b0fc826137ad82e49d12348834c9022ecc6c0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Fri, 7 Apr 2023 16:24:28 +0200
Subject: [PATCH 39/46] Fixed: [section] remove hardcoded link to phonecall
aside activity
---
.../src/Menu/SectionMenuBuilder.php | 11 -----------
1 file changed, 11 deletions(-)
diff --git a/src/Bundle/ChillAsideActivityBundle/src/Menu/SectionMenuBuilder.php b/src/Bundle/ChillAsideActivityBundle/src/Menu/SectionMenuBuilder.php
index d4ed7dbf9..f23fcdc8a 100644
--- a/src/Bundle/ChillAsideActivityBundle/src/Menu/SectionMenuBuilder.php
+++ b/src/Bundle/ChillAsideActivityBundle/src/Menu/SectionMenuBuilder.php
@@ -44,17 +44,6 @@ class SectionMenuBuilder implements LocalMenuBuilderInterface
'order' => 11,
'icons' => ['plus'],
]);
- $menu->addChild($this->translator->trans('Phonecall'), [
- 'route' => 'chill_crud_aside_activity_new',
- 'routeParameters' => [
- 'type' => 1,
- 'duration' => 900,
- ],
- ])
- ->setExtras([
- 'order' => 12,
- 'icons' => ['plus'],
- ]);
}
}
From a42a4ab9bd8d8c7b4a57c23b58ea1fa3856bd9a4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Fri, 7 Apr 2023 17:34:12 +0200
Subject: [PATCH 40/46] Fixed: fix empty result in household api search
fix https://gitlab.com/Chill-Projet/chill-bundles/-/issues/85
---
.../ChillMainBundle/Search/SearchApi.php | 25 ++++++++-----------
.../ChillMainBundle/Search/SearchApiQuery.php | 12 +++++++++
.../Search/SearchHouseholdApiProvider.php | 14 +++++++----
3 files changed, 32 insertions(+), 19 deletions(-)
diff --git a/src/Bundle/ChillMainBundle/Search/SearchApi.php b/src/Bundle/ChillMainBundle/Search/SearchApi.php
index 875383839..c8459dbdf 100644
--- a/src/Bundle/ChillMainBundle/Search/SearchApi.php
+++ b/src/Bundle/ChillMainBundle/Search/SearchApi.php
@@ -30,7 +30,7 @@ class SearchApi
private PaginatorFactory $paginator;
- private iterable $providers = [];
+ private iterable $providers;
public function __construct(
EntityManagerInterface $em,
@@ -42,9 +42,6 @@ class SearchApi
$this->paginator = $paginator;
}
- /**
- * @return Model/Result[]
- */
public function getResults(string $pattern, array $types, array $parameters): Collection
{
$queries = $this->findQueries($pattern, $types, $parameters);
@@ -53,10 +50,10 @@ class SearchApi
throw new SearchApiNoQueryException($pattern, $types, $parameters);
}
- $total = $this->countItems($queries, $types, $parameters);
+ $total = $this->countItems($queries);
$paginator = $this->paginator->create($total);
- $rawResults = $this->fetchRawResult($queries, $types, $parameters, $paginator);
+ $rawResults = $this->fetchRawResult($queries, $types, $paginator);
$this->prepareProviders($rawResults);
$results = $this->buildResults($rawResults);
@@ -64,7 +61,7 @@ class SearchApi
return new Collection($results, $paginator);
}
- private function buildCountQuery(array $queries, $types, $parameters)
+ private function buildCountQuery(array $queries): array
{
$query = 'SELECT SUM(c) AS count FROM ({union_unordered}) AS sq';
$unions = [];
@@ -88,7 +85,7 @@ class SearchApi
$items = [];
foreach ($rawResults as $r) {
- foreach ($this->providers as $k => $p) {
+ foreach ($this->providers as $p) {
if ($p->supportsResult($r['key'], $r['metadata'])) {
$items[] = (new SearchApiResult($r['pertinence']))
->setResult(
@@ -103,7 +100,7 @@ class SearchApi
return $items;
}
- private function buildUnionQuery(array $queries, $types, $parameters, Paginator $paginator)
+ private function buildUnionQuery(array $queries, Paginator $paginator): array
{
$query = '{unions} ORDER BY pertinence DESC LIMIT ? OFFSET ?';
$unions = [];
@@ -126,9 +123,9 @@ class SearchApi
];
}
- private function countItems($providers, $types, $parameters): int
+ private function countItems($providers): int
{
- [$countQuery, $parameters] = $this->buildCountQuery($providers, $types, $parameters);
+ [$countQuery, $parameters] = $this->buildCountQuery($providers);
$rsmCount = new ResultSetMappingBuilder($this->em);
$rsmCount->addScalarResult('count', 'count');
$countNq = $this->em->createNativeQuery($countQuery, $rsmCount);
@@ -137,9 +134,9 @@ class SearchApi
return (int) $countNq->getSingleScalarResult();
}
- private function fetchRawResult($queries, $types, $parameters, Paginator $paginator): array
+ private function fetchRawResult($queries, $types, Paginator $paginator): array
{
- [$union, $parameters] = $this->buildUnionQuery($queries, $types, $parameters, $paginator);
+ [$union, $parameters] = $this->buildUnionQuery($queries, $paginator);
$rsm = new ResultSetMappingBuilder($this->em);
$rsm->addScalarResult('key', 'key', Types::STRING)
->addScalarResult('metadata', 'metadata', Types::JSON)
@@ -172,7 +169,7 @@ class SearchApi
);
}
- private function prepareProviders(array $rawResults)
+ private function prepareProviders(array $rawResults): void
{
$metadatas = [];
$providers = [];
diff --git a/src/Bundle/ChillMainBundle/Search/SearchApiQuery.php b/src/Bundle/ChillMainBundle/Search/SearchApiQuery.php
index c7b661e4f..ad852d95a 100644
--- a/src/Bundle/ChillMainBundle/Search/SearchApiQuery.php
+++ b/src/Bundle/ChillMainBundle/Search/SearchApiQuery.php
@@ -16,6 +16,18 @@ use function count;
use function implode;
use function strtr;
+/**
+ * This create a query optimized for searching for the api response.
+ *
+ * When build, this class generate a SQL string and a list of a parameters which is suitable for running
+ * a native SQL query. This have usually the form of
+ *
+ * `SELECT '' as key, as metadata, as pertinence FROM WHERE `.
+ *
+ * The clause between `<>` are provided through the dedicated method in this class (@link{self::setSelectKey},
+ * @link{self::setFromClause}), etc.).
+ *
+ */
class SearchApiQuery
{
private ?string $fromClause = null;
diff --git a/src/Bundle/ChillPersonBundle/Search/SearchHouseholdApiProvider.php b/src/Bundle/ChillPersonBundle/Search/SearchHouseholdApiProvider.php
index 02d944d15..819554252 100644
--- a/src/Bundle/ChillPersonBundle/Search/SearchHouseholdApiProvider.php
+++ b/src/Bundle/ChillPersonBundle/Search/SearchHouseholdApiProvider.php
@@ -84,15 +84,19 @@ class SearchHouseholdApiProvider implements SearchApiInterface
count($phoneResult->getFound()) > 0 ? $phoneResult->getFound()[0] : null
);
+ $previousFrom = $query->getFromClause();
+ $previousParams = $query->getFromParams();
+
$query
- ->setDistinct(true, 'household_id')
+ ->setDistinct(true, 'cpphm.household_id')
->setFromClause(
- 'view_chill_person_household_address AS vcpha ' .
- 'JOIN chill_person_person AS person ON vcpha.person_id = person.id'
+ $previousFrom . ' '.
+ 'JOIN chill_person_household_members AS cpphm ON cpphm.person_id = person.id',
+ $previousParams
)
+ ->andWhereClause('(cpphm.startDate <= NOW() AND (cpphm.endDate IS NULL or cpphm.endDate > NOW()))')
->setSelectKey('household')
- ->andWhereClause('vcpha.validTo IS NULL', [])
- ->setSelectJsonbMetadata("jsonb_build_object('id', vcpha.household_id)");
+ ->setSelectJsonbMetadata("jsonb_build_object('id', cpphm.household_id)");
return $query;
}
From 9853845c9ce71d723e1211c101194044948fbf09 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Fri, 7 Apr 2023 17:38:57 +0200
Subject: [PATCH 41/46] Fixed: [workflow] show error message when applying a
transition and no dest users are chosen
fix https://gitlab.com/Chill-Projet/chill-bundles/-/issues/80
---
.../ChillMainBundle/Resources/views/Workflow/_decision.html.twig | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/Bundle/ChillMainBundle/Resources/views/Workflow/_decision.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Workflow/_decision.html.twig
index bd9274739..0444abc69 100644
--- a/src/Bundle/ChillMainBundle/Resources/views/Workflow/_decision.html.twig
+++ b/src/Bundle/ChillMainBundle/Resources/views/Workflow/_decision.html.twig
@@ -66,6 +66,7 @@
{{ form_row(transition_form.future_dest_users) }}
{{ form_row(transition_form.future_dest_emails) }}
+ {{ form_errors(transition_form.future_dest_users) }}
{{ form_label(transition_form.comment) }}
From ef138339660e6ed890934ae2df97964ed69e4b79 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Tue, 11 Apr 2023 10:16:09 +0200
Subject: [PATCH 42/46] Fixed: [create person] handle case when the user has
two differents groups in the same center
Fix https://gitlab.com/Chill-Projet/chill-bundles/-/issues/72
---
.../Authorization/AuthorizationHelper.php | 13 +++++-----
.../AuthorizationHelperInterface.php | 6 ++---
.../Controller/PersonController.php | 24 +++++++++----------
3 files changed, 22 insertions(+), 21 deletions(-)
diff --git a/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php b/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php
index 65e1cf688..9bb883317 100644
--- a/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php
+++ b/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php
@@ -63,7 +63,7 @@ class AuthorizationHelper implements AuthorizationHelperInterface
*
* @param User $user The user
* @param array $centers a list of centers which are going to be filtered
- * @param Center|string $role
+ * @param string $role
*/
public function filterReachableCenters(User $user, array $centers, $role): array
{
@@ -113,13 +113,14 @@ class AuthorizationHelper implements AuthorizationHelperInterface
* Get reachable Centers for the given user, role,
* and optionally Scope.
*
- * @return array|Center[]
+ * @return list
*/
public function getReachableCenters(UserInterface $user, string $role, ?Scope $scope = null): array
{
if ($role instanceof Role) {
$role = $role->getRole();
}
+ /** @var array $centers */
$centers = [];
foreach ($user->getGroupCenters() as $groupCenter) {
@@ -129,13 +130,13 @@ class AuthorizationHelper implements AuthorizationHelperInterface
//check that the role is in the reachable roles
if ($this->isRoleReached($role, $roleScope->getRole())) {
if (null === $scope) {
- $centers[] = $groupCenter->getCenter();
+ $centers[spl_object_hash($groupCenter->getCenter())] = $groupCenter->getCenter();
break;
}
if ($scope->getId() === $roleScope->getScope()->getId()) {
- $centers[] = $groupCenter->getCenter();
+ $centers[spl_object_hash($groupCenter->getCenter())] = $groupCenter->getCenter();
break;
}
@@ -143,7 +144,7 @@ class AuthorizationHelper implements AuthorizationHelperInterface
}
}
- return $centers;
+ return array_values($centers);
}
/**
@@ -194,7 +195,7 @@ class AuthorizationHelper implements AuthorizationHelperInterface
*
* @return array|Scope[]
*/
- public function getReachableScopes(UserInterface $user, string $role, $center): array
+ public function getReachableScopes(UserInterface $user, string $role, Center|array $center): array
{
if ($role instanceof Role) {
$role = $role->getRole();
diff --git a/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelperInterface.php b/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelperInterface.php
index f7c1f5b46..1176cf1fa 100644
--- a/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelperInterface.php
+++ b/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelperInterface.php
@@ -21,12 +21,12 @@ interface AuthorizationHelperInterface
* Get reachable Centers for the given user, role,
* and optionnaly Scope.
*
- * @return Center[]
+ * @return list
*/
public function getReachableCenters(UserInterface $user, string $role, ?Scope $scope = null): array;
/**
- * @param array|Center|Center[] $center
+ * @param Center|list $center
*/
- public function getReachableScopes(UserInterface $user, string $role, $center): array;
+ public function getReachableScopes(UserInterface $user, string $role, Center|array $center): array;
}
diff --git a/src/Bundle/ChillPersonBundle/Controller/PersonController.php b/src/Bundle/ChillPersonBundle/Controller/PersonController.php
index bb03a6b33..976f44703 100644
--- a/src/Bundle/ChillPersonBundle/Controller/PersonController.php
+++ b/src/Bundle/ChillPersonBundle/Controller/PersonController.php
@@ -11,6 +11,8 @@ declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
+use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
+use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
use Chill\PersonBundle\Config\ConfigPersonAltNamesHelper;
use Chill\PersonBundle\Entity\Household\Household;
use Chill\PersonBundle\Entity\Household\HouseholdMember;
@@ -20,6 +22,7 @@ use Chill\PersonBundle\Form\PersonType;
use Chill\PersonBundle\Privacy\PrivacyEvent;
use Chill\PersonBundle\Repository\PersonRepository;
use Chill\PersonBundle\Search\SimilarPersonMatcher;
+use Chill\PersonBundle\Security\Authorization\PersonVoter;
use DateTimeImmutable;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
@@ -44,6 +47,8 @@ use function is_array;
final class PersonController extends AbstractController
{
+ private AuthorizationHelperInterface $authorizationHelper;
+
/**
* @var ConfigPersonAltNamesHelper
*/
@@ -87,6 +92,7 @@ final class PersonController extends AbstractController
private $validator;
public function __construct(
+ AuthorizationHelperInterface $authorizationHelper,
SimilarPersonMatcher $similarPersonMatcher,
TranslatorInterface $translator,
EventDispatcherInterface $eventDispatcher,
@@ -97,6 +103,7 @@ final class PersonController extends AbstractController
EntityManagerInterface $em,
Security $security
) {
+ $this->authorizationHelper = $authorizationHelper;
$this->similarPersonMatcher = $similarPersonMatcher;
$this->translator = $translator;
$this->eventDispatcher = $eventDispatcher;
@@ -206,22 +213,15 @@ final class PersonController extends AbstractController
*
* The next post compare the data with previous one and, if yes, show a
* review page if there are "alternate persons".
- *
- * @return Response|\Symfony\Component\HttpFoundation\RedirectResponse
*/
- public function newAction(Request $request)
+ public function newAction(Request $request): Response
{
$person = new Person();
- if (
- 1 === count($this->security->getUser()
- ->getGroupCenters())
- ) {
- $person->setCenter(
- $this->security->getUser()
- ->getGroupCenters()[0]
- ->getCenter()
- );
+ $authorizedCenters =$this->authorizationHelper->getReachableCenters($this->getUser(), PersonVoter::CREATE);
+
+ if (1 === count($authorizedCenters)) {
+ $person->setCenter($authorizedCenters[0]);
}
$form = $this->createForm(CreationPersonType::class, $person)
From 98aad8c4b6355d90f6afef837384b9d0243d1990 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Tue, 11 Apr 2023 10:45:10 +0200
Subject: [PATCH 43/46] Fixed: [accompanying period work / edit] allow endDate
to be equal to startDate, and show validation errors to users
Fix https://gitlab.com/Chill-Projet/chill-bundles/-/issues/79
---
.../AccompanyingPeriodWork.php | 4 +--
.../AccompanyingCourseWorkCreate/index.js | 25 ++++++++++++-------
.../AccompanyingCourseWorkCreate/store.js | 6 ++++-
.../vuejs/AccompanyingCourseWorkEdit/App.vue | 9 ++++++-
.../vuejs/AccompanyingCourseWorkEdit/index.js | 2 +-
.../vuejs/AccompanyingCourseWorkEdit/store.js | 3 +--
.../translations/validators.fr.yml | 3 +++
7 files changed, 36 insertions(+), 16 deletions(-)
diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodWork.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodWork.php
index adb5ca358..5361012b3 100644
--- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodWork.php
+++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodWork.php
@@ -94,8 +94,8 @@ class AccompanyingPeriodWork implements AccompanyingPeriodLinkedWithSocialIssues
* @Serializer\Groups({"accompanying_period_work:create"})
* @Serializer\Groups({"accompanying_period_work:edit"})
* @Serializer\Groups({"read", "docgen:read", "read:accompanyingPeriodWork:light"})
- * @Assert\GreaterThan(propertyPath="startDate",
- * message="accompanying_course_work.The endDate should be greater than the start date"
+ * @Assert\GreaterThanOrEqual(propertyPath="startDate",
+ * message="accompanying_course_work.The endDate should be greater or equal than the start date"
* )
*/
private ?DateTimeImmutable $endDate = null;
diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkCreate/index.js b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkCreate/index.js
index 7e54e2b0b..1f8a25d3a 100644
--- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkCreate/index.js
+++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkCreate/index.js
@@ -1,15 +1,22 @@
-import { createApp } from 'vue';
-import { _createI18n } from 'ChillMainAssets/vuejs/_js/i18n';
-import { store } from './store';
-import { personMessages } from 'ChillPersonAssets/vuejs/_js/i18n'
+import {createApp} from 'vue';
+import {_createI18n} from 'ChillMainAssets/vuejs/_js/i18n';
+import {store} from './store';
+import {personMessages} from 'ChillPersonAssets/vuejs/_js/i18n'
import App from './App.vue';
+import VueToast from "vue-toast-notification";
const i18n = _createI18n(personMessages);
const app = createApp({
- template: ` `,
+ template: ` `,
})
-.use(store)
-.use(i18n)
-.component('app', App)
-.mount('#accompanying_course_work_create');
+ .use(store)
+ .use(i18n)
+ .use(VueToast, {
+ position: "bottom-right",
+ type: "error",
+ duration: 10000,
+ dismissible: true,
+ })
+ .component('app', App)
+ .mount('#accompanying_course_work_create');
diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkCreate/store.js b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkCreate/store.js
index 3eee7c56a..138e6f6ed 100644
--- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkCreate/store.js
+++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkCreate/store.js
@@ -107,6 +107,9 @@ const store = createStore({
setPostingWork(state) {
state.isPostingWork = true;
},
+ setPostingWorkDone(state) {
+ state.isPostingWork = false;
+ },
setStartDate(state, date) {
state.startDate = date;
},
@@ -150,11 +153,12 @@ const store = createStore({
const url = `/api/1.0/person/accompanying-course/${state.accompanyingCourse.id}/work.json`;
commit('setPostingWork');
- makeFetch('POST', url, payload)
+ return makeFetch('POST', url, payload)
.then((response) => {
window.location.assign(`/fr/person/accompanying-period/work/${response.id}/edit`)
})
.catch((error) => {
+ commit('setPostingWorkDone');
throw error;
});
},
diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue
index 9a105dd8d..755e4455c 100644
--- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue
+++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue
@@ -549,7 +549,14 @@ export default {
.catch(e => { console.log(e); throw e; });
},
submit() {
- this.$store.dispatch('submit');
+ this.$store.dispatch('submit').catch((error) => {
+ if (error.name === 'ValidationException' || error.name === 'AccessException') {
+ error.violations.forEach((violation) => this.$toast.open({message: violation}));
+ } else {
+ this.$toast.open({message: 'An error occurred'});
+ throw error;
+ }
+ });
},
saveFormOnTheFly(payload) {
console.log('saveFormOnTheFly: type', payload.type, ', data', payload.data);
diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/index.js b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/index.js
index 143d34215..b0868b48b 100644
--- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/index.js
+++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/index.js
@@ -15,7 +15,7 @@ const app = createApp({
.use(VueToast, {
position: "bottom-right",
type: "error",
- duration: 5000,
+ duration: 10000,
dismissible: true
})
.use(i18n)
diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/store.js b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/store.js
index e075e65bc..47e4b2d3f 100644
--- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/store.js
+++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/store.js
@@ -500,9 +500,8 @@ const store = createStore({
window.location.assign(`/fr/person/accompanying-period/${state.work.accompanyingPeriod.id}/work`);
}
}).catch(error => {
- console.log('error on submit', error);
commit('setIsPosting', false);
- commit('setErrors', error.violations);
+ throw error;
});
},
updateDocumentTitle({commit}, payload) {
diff --git a/src/Bundle/ChillPersonBundle/translations/validators.fr.yml b/src/Bundle/ChillPersonBundle/translations/validators.fr.yml
index 8fcda47aa..f005755b1 100644
--- a/src/Bundle/ChillPersonBundle/translations/validators.fr.yml
+++ b/src/Bundle/ChillPersonBundle/translations/validators.fr.yml
@@ -71,3 +71,6 @@ relationship:
person_creation:
If you want to create an household, an address is required: Pour la création d'un ménage, une adresse est requise
+
+accompanying_course_work:
+ The endDate should be greater or equal than the start date: La date de fin doit être égale ou supérieure à la date de début
From 841bdb0ebfe6096fc210951b58c2f7b0518c5bcd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Tue, 11 Apr 2023 11:43:01 +0200
Subject: [PATCH 44/46] fix issues from master
---
src/Bundle/ChillMainBundle/Search/SearchApi.php | 6 +++---
.../Security/Authorization/AuthorizationHelper.php | 5 -----
.../ChillPersonBundle/Controller/PersonController.php | 4 ----
3 files changed, 3 insertions(+), 12 deletions(-)
diff --git a/src/Bundle/ChillMainBundle/Search/SearchApi.php b/src/Bundle/ChillMainBundle/Search/SearchApi.php
index c8459dbdf..1fea71c46 100644
--- a/src/Bundle/ChillMainBundle/Search/SearchApi.php
+++ b/src/Bundle/ChillMainBundle/Search/SearchApi.php
@@ -11,8 +11,8 @@ declare(strict_types=1);
namespace Chill\MainBundle\Search;
-use Chill\MainBundle\Pagination\Paginator;
use Chill\MainBundle\Pagination\PaginatorFactory;
+use Chill\MainBundle\Pagination\PaginatorInterface;
use Chill\MainBundle\Serializer\Model\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\EntityManagerInterface;
@@ -100,7 +100,7 @@ class SearchApi
return $items;
}
- private function buildUnionQuery(array $queries, Paginator $paginator): array
+ private function buildUnionQuery(array $queries, PaginatorInterface $paginator): array
{
$query = '{unions} ORDER BY pertinence DESC LIMIT ? OFFSET ?';
$unions = [];
@@ -134,7 +134,7 @@ class SearchApi
return (int) $countNq->getSingleScalarResult();
}
- private function fetchRawResult($queries, $types, Paginator $paginator): array
+ private function fetchRawResult($queries, $types, PaginatorInterface $paginator): array
{
[$union, $parameters] = $this->buildUnionQuery($queries, $paginator);
$rsm = new ResultSetMappingBuilder($this->em);
diff --git a/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php b/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php
index 9bb883317..768b35a75 100644
--- a/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php
+++ b/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php
@@ -63,7 +63,6 @@ class AuthorizationHelper implements AuthorizationHelperInterface
*
* @param User $user The user
* @param array $centers a list of centers which are going to be filtered
- * @param string $role
*/
public function filterReachableCenters(User $user, array $centers, $role): array
{
@@ -197,10 +196,6 @@ class AuthorizationHelper implements AuthorizationHelperInterface
*/
public function getReachableScopes(UserInterface $user, string $role, Center|array $center): array
{
- if ($role instanceof Role) {
- $role = $role->getRole();
- }
-
return $this->getReachableCircles($user, $role, $center);
}
diff --git a/src/Bundle/ChillPersonBundle/Controller/PersonController.php b/src/Bundle/ChillPersonBundle/Controller/PersonController.php
index 976f44703..ae12c566d 100644
--- a/src/Bundle/ChillPersonBundle/Controller/PersonController.php
+++ b/src/Bundle/ChillPersonBundle/Controller/PersonController.php
@@ -64,8 +64,6 @@ final class PersonController extends AbstractController
*/
protected $personRepository;
- private Security $security;
-
/**
* @var SimilarPersonMatcher
*/
@@ -101,7 +99,6 @@ final class PersonController extends AbstractController
LoggerInterface $logger,
ValidatorInterface $validator,
EntityManagerInterface $em,
- Security $security
) {
$this->authorizationHelper = $authorizationHelper;
$this->similarPersonMatcher = $similarPersonMatcher;
@@ -112,7 +109,6 @@ final class PersonController extends AbstractController
$this->logger = $logger;
$this->validator = $validator;
$this->em = $em;
- $this->security = $security;
}
public function editAction($person_id, Request $request)
From 4db1ff405e6063176154d9cac3959b6ad2bdbf33 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Tue, 11 Apr 2023 13:04:08 +0200
Subject: [PATCH 45/46] fix new phpstan issues
---
.../ChillEventBundle/Search/EventSearch.php | 32 ++++++++-----------
.../Widget/AddWidgetConfigurationTrait.php | 2 +-
.../MultipleObjectsToIdTransformer.php | 6 +---
.../Search/SearchInterface.php | 4 +--
.../Authorization/AuthorizationHelper.php | 1 +
.../ChillPersonBundle/Search/PersonSearch.php | 25 ++++-----------
.../Search/ThirdPartySearch.php | 3 ++
7 files changed, 29 insertions(+), 44 deletions(-)
diff --git a/src/Bundle/ChillEventBundle/Search/EventSearch.php b/src/Bundle/ChillEventBundle/Search/EventSearch.php
index 90eca34bc..a7ac22592 100644
--- a/src/Bundle/ChillEventBundle/Search/EventSearch.php
+++ b/src/Bundle/ChillEventBundle/Search/EventSearch.php
@@ -113,27 +113,23 @@ class EventSearch extends AbstractSearch
]
);
}
+ // format is "json"
+ $results = [];
+ $search = $this->search($terms, $start, $limit, $options);
- if ('json' === $format) {
- $results = [];
- $search = $this->search($terms, $start, $limit, $options);
-
- foreach ($search as $item) {
- $results[] = [
- 'id' => $item->getId(),
- 'text' => $item->getDate()->format('d/m/Y, H:i') . ' → ' .
- // $item->getType()->getName()['fr'] . ': ' . // display the type of event
- $item->getName(),
- ];
- }
-
- return [
- 'results' => $results,
- 'pagination' => [
- 'more' => $paginator->hasNextPage(),
- ],
+ foreach ($search as $item) {
+ $results[] = [
+ 'id' => $item->getId(),
+ 'text' => $item->getDate()->format('d/m/Y, H:i') . ' → ' .
+ // $item->getType()->getName()['fr'] . ': ' . // display the type of event
+ $item->getName(),
];
}
+
+ return [
+ 'results' => $results,
+ 'more' => $paginator->hasNextPage(),
+ ];
}
public function supports($domain, $format)
diff --git a/src/Bundle/ChillMainBundle/DependencyInjection/Widget/AddWidgetConfigurationTrait.php b/src/Bundle/ChillMainBundle/DependencyInjection/Widget/AddWidgetConfigurationTrait.php
index a6688fca2..3cff6583e 100644
--- a/src/Bundle/ChillMainBundle/DependencyInjection/Widget/AddWidgetConfigurationTrait.php
+++ b/src/Bundle/ChillMainBundle/DependencyInjection/Widget/AddWidgetConfigurationTrait.php
@@ -211,7 +211,7 @@ trait AddWidgetConfigurationTrait
*
* @throws InvalidConfigurationException if a service's tag does not have the "alias" key
*
- * @return type
+ * @return array
*/
protected function getWidgetAliasesbyPlace($place, ContainerBuilder $containerBuilder)
{
diff --git a/src/Bundle/ChillMainBundle/Form/Type/DataTransformer/MultipleObjectsToIdTransformer.php b/src/Bundle/ChillMainBundle/Form/Type/DataTransformer/MultipleObjectsToIdTransformer.php
index aca165652..a21f49b2c 100644
--- a/src/Bundle/ChillMainBundle/Form/Type/DataTransformer/MultipleObjectsToIdTransformer.php
+++ b/src/Bundle/ChillMainBundle/Form/Type/DataTransformer/MultipleObjectsToIdTransformer.php
@@ -31,8 +31,6 @@ class MultipleObjectsToIdTransformer implements DataTransformerInterface
* Transforms a string (id) to an object (item).
*
* @param mixed $array
- *
- * @return ArrayCollection
*/
public function reverseTransform($array)
{
@@ -53,10 +51,8 @@ class MultipleObjectsToIdTransformer implements DataTransformerInterface
* Transforms an object (use) to a string (id).
*
* @param array $array
- *
- * @return ArrayCollection
*/
- public function transform($array)
+ public function transform($array): array
{
$ret = [];
diff --git a/src/Bundle/ChillMainBundle/Search/SearchInterface.php b/src/Bundle/ChillMainBundle/Search/SearchInterface.php
index 7fced2ff9..a7cd285fe 100644
--- a/src/Bundle/ChillMainBundle/Search/SearchInterface.php
+++ b/src/Bundle/ChillMainBundle/Search/SearchInterface.php
@@ -71,9 +71,9 @@ interface SearchInterface
* @param array $terms the string to search
* @param int $start the first result (for pagination)
* @param int $limit the number of result (for pagination)
- * @param string $format The format for result
+ * @param "html"|"json" $format The format for result
*
- * @return string, an HTML string
+ * @return string|array a string if format is html, an array if format is json
*/
public function renderResult(array $terms, $start = 0, $limit = 50, array $options = [], $format = 'html');
diff --git a/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php b/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php
index 768b35a75..828f53757 100644
--- a/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php
+++ b/src/Bundle/ChillMainBundle/Security/Authorization/AuthorizationHelper.php
@@ -63,6 +63,7 @@ class AuthorizationHelper implements AuthorizationHelperInterface
*
* @param User $user The user
* @param array $centers a list of centers which are going to be filtered
+ * @param mixed $role
*/
public function filterReachableCenters(User $user, array $centers, $role): array
{
diff --git a/src/Bundle/ChillPersonBundle/Search/PersonSearch.php b/src/Bundle/ChillPersonBundle/Search/PersonSearch.php
index 3de2fd4f1..7cd1849a3 100644
--- a/src/Bundle/ChillPersonBundle/Search/PersonSearch.php
+++ b/src/Bundle/ChillPersonBundle/Search/PersonSearch.php
@@ -203,15 +203,6 @@ class PersonSearch extends AbstractSearch implements HasAdvancedSearchFormInterf
return true;
}
- /**
- * (non-PHPdoc).
- *
- * @see \Chill\MainBundle\Search\SearchInterface::renderResult()
- *
- * @param mixed $start
- * @param mixed $limit
- * @param mixed $format
- */
public function renderResult(array $terms, $start = 0, $limit = 50, array $options = [], $format = 'html')
{
$terms = $this->findAdditionnalInDefault($terms);
@@ -236,15 +227,13 @@ class PersonSearch extends AbstractSearch implements HasAdvancedSearchFormInterf
]
);
}
-
- if ('json' === $format) {
- return [
- 'results' => $this->search($terms, $start, $limit, array_merge($options, ['simplify' => true])),
- 'pagination' => [
- 'more' => $paginator->hasNextPage(),
- ],
- ];
- }
+ // format is "json"
+ return [
+ 'results' => $this->search($terms, $start, $limit, array_merge($options, ['simplify' => true])),
+ 'pagination' => [
+ 'more' => $paginator->hasNextPage(),
+ ],
+ ];
}
public function supports($domain, $format)
diff --git a/src/Bundle/ChillThirdPartyBundle/Search/ThirdPartySearch.php b/src/Bundle/ChillThirdPartyBundle/Search/ThirdPartySearch.php
index 5a46edad8..ae967ea8d 100644
--- a/src/Bundle/ChillThirdPartyBundle/Search/ThirdPartySearch.php
+++ b/src/Bundle/ChillThirdPartyBundle/Search/ThirdPartySearch.php
@@ -100,6 +100,9 @@ class ThirdPartySearch implements SearchInterface
'more' => $paginator->hasNextPage(),
];
}
+ if ('html' === $format) {
+ throw new \UnexpectedValueException("format not supported");
+ }
}
public function supports($domain, $format): bool
From 8bec6feb969e1a1e700ba2a5f888e3995277b12e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Tue, 11 Apr 2023 22:01:47 +0200
Subject: [PATCH 46/46] DX: fix ci and phpstan issues
---
.../ChillActivityBundle/Tests/Form/ActivityTypeTest.php | 6 +++---
.../ChillMainBundle/CRUD/Routing/CRUDRoutesLoader.php | 2 +-
.../ChillThirdPartyBundle/Search/ThirdPartySearch.php | 5 ++---
.../migrations/Version20230215175150.php | 2 +-
4 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/src/Bundle/ChillActivityBundle/Tests/Form/ActivityTypeTest.php b/src/Bundle/ChillActivityBundle/Tests/Form/ActivityTypeTest.php
index b6cb6fc7b..df0a602a4 100644
--- a/src/Bundle/ChillActivityBundle/Tests/Form/ActivityTypeTest.php
+++ b/src/Bundle/ChillActivityBundle/Tests/Form/ActivityTypeTest.php
@@ -112,9 +112,9 @@ final class ActivityTypeTest extends KernelTestCase
'attendee' => true,
]]);
-// var_dump($form->getErrors()->count()); var_dump($form->isValid());
-// foreach($form->getErrors() as $e) { fwrite(STDOUT, var_dump($e->getMessage())); }
-// var_dump($form->getErrors());
+ // var_dump($form->getErrors()->count()); var_dump($form->isValid());
+ // foreach($form->getErrors() as $e) { fwrite(STDOUT, var_dump($e->getMessage())); }
+ // var_dump($form->getErrors());
$this->assertTrue($form->isSynchronized(), 'Test the form is synchronized');
$this->assertTrue($form->isValid(), 'test the form is valid');
diff --git a/src/Bundle/ChillMainBundle/CRUD/Routing/CRUDRoutesLoader.php b/src/Bundle/ChillMainBundle/CRUD/Routing/CRUDRoutesLoader.php
index c3197936e..76da401a3 100644
--- a/src/Bundle/ChillMainBundle/CRUD/Routing/CRUDRoutesLoader.php
+++ b/src/Bundle/ChillMainBundle/CRUD/Routing/CRUDRoutesLoader.php
@@ -101,7 +101,7 @@ class CRUDRoutesLoader extends Loader
$singleCollection = $action['single_collection'] ?? '_entity' === $name ? 'single' : null;
if ('collection' === $singleCollection) {
-// continue;
+ // continue;
}
// compute default action
diff --git a/src/Bundle/ChillThirdPartyBundle/Search/ThirdPartySearch.php b/src/Bundle/ChillThirdPartyBundle/Search/ThirdPartySearch.php
index ae967ea8d..2c7948a2d 100644
--- a/src/Bundle/ChillThirdPartyBundle/Search/ThirdPartySearch.php
+++ b/src/Bundle/ChillThirdPartyBundle/Search/ThirdPartySearch.php
@@ -100,9 +100,8 @@ class ThirdPartySearch implements SearchInterface
'more' => $paginator->hasNextPage(),
];
}
- if ('html' === $format) {
- throw new \UnexpectedValueException("format not supported");
- }
+ // format "html"
+ throw new \UnexpectedValueException("format html not supported");
}
public function supports($domain, $format): bool
diff --git a/src/Bundle/ChillThirdPartyBundle/migrations/Version20230215175150.php b/src/Bundle/ChillThirdPartyBundle/migrations/Version20230215175150.php
index 223c9aeae..fefe1c339 100644
--- a/src/Bundle/ChillThirdPartyBundle/migrations/Version20230215175150.php
+++ b/src/Bundle/ChillThirdPartyBundle/migrations/Version20230215175150.php
@@ -25,7 +25,7 @@ final class Version20230215175150 extends AbstractMigration implements Container
public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE chill_3party.third_party DROP profession');
-// $this->addSql('ALTER TABLE chill_3party.third_party ADD profession_id INT DEFAULT NULL');
+ // $this->addSql('ALTER TABLE chill_3party.third_party ADD profession_id INT DEFAULT NULL');
}
public function getDescription(): string