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/11] 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/11] 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">
-
+
-
+
@@ -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/11] 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/11] 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/11] 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 @@
-
-
+
+
+
@@ -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/11] 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;
},