diff --git a/src/Bundle/ChillMainBundle/Controller/AddressController.php b/src/Bundle/ChillMainBundle/Controller/AddressController.php new file mode 100644 index 000000000..1aeb39062 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Controller/AddressController.php @@ -0,0 +1,63 @@ +json($address); + default: + throw new BadRequestException('Unsupported format'); + } + } + + + /** + * Get API Data for showing endpoint + * + * @Route( + * "/{_locale}/main/api/1.0/address-reference/{address_reference_id}/show.{_format}", + * name="chill_main_address_reference_api_show" + * ) + * @ParamConverter("addressReference", options={"id": "address_reference_id"}) + */ + public function showAddressReference(AddressReference $addressReference, $_format): Response + { + // TODO check ACL ? + switch ($_format) { + case 'json': + return $this->json($addressReference); + default: + throw new BadRequestException('Unsupported format'); + } + + } +} diff --git a/src/Bundle/ChillMainBundle/DataFixtures/ORM/LoadAddressReferences.php b/src/Bundle/ChillMainBundle/DataFixtures/ORM/LoadAddressReferences.php new file mode 100644 index 000000000..81bd1d909 --- /dev/null +++ b/src/Bundle/ChillMainBundle/DataFixtures/ORM/LoadAddressReferences.php @@ -0,0 +1,95 @@ +faker = \Faker\Factory::create('fr_FR'); + } + + /** + * + * @var ContainerInterface + */ + private $container; + + public function setContainer(ContainerInterface $container = null) + { + $this->container = $container; + } + + public function getOrder() { + return 51; + } + + + /** + * Create a random point + * + * @return Point + */ + private function getRandomPoint() + { + $lonBrussels = 4.35243; + $latBrussels = 50.84676; + $lon = $lonBrussels + 0.01 * rand(-5, 5); + $lat = $latBrussels + 0.01 * rand(-5, 5); + return Point::fromLonLat($lon, $lat); + } + + /** + * Create a random reference address + * + * @return AddressReference + */ + private function getRandomAddressReference() + { + $ar= new AddressReference(); + + $ar->setRefId($this->faker->numerify('ref-id-######')); + $ar->setStreet($this->faker->streetName); + $ar->setStreetNumber(rand(0,199)); + $ar ->setPoint($this->getRandomPoint()); + $ar->setPostcode($this->getReference( + LoadPostalCodes::$refs[array_rand(LoadPostalCodes::$refs)] + )); + + $ar->setMunicipalityCode($ar->getPostcode()->getCode()); + + return $ar + ; + } + + public function load(ObjectManager $manager) { + + echo "loading some reference address... \n"; + + for ($i=0; $i<10; $i++) { + $ar = $this->getRandomAddressReference(); + $manager->persist($ar); + } + + $manager->flush(); + } + + +} diff --git a/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php b/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php index 00b164303..a40221263 100644 --- a/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php +++ b/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php @@ -188,7 +188,12 @@ class ChillMainExtension extends Extension implements PrependExtensionInterface, $container->prependExtensionConfig('doctrine', array( 'dbal' => [ 'types' => [ - 'dateinterval' => \Chill\MainBundle\Doctrine\Type\NativeDateIntervalType::class + 'dateinterval' => [ + 'class' => \Chill\MainBundle\Doctrine\Type\NativeDateIntervalType::class + ], + 'point' => [ + 'class' => \Chill\MainBundle\Doctrine\Type\PointType::class + ] ] ] )); diff --git a/src/Bundle/ChillMainBundle/Doctrine/Model/Point.php b/src/Bundle/ChillMainBundle/Doctrine/Model/Point.php new file mode 100644 index 000000000..43c21ae59 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Doctrine/Model/Point.php @@ -0,0 +1,103 @@ +lat = $lat; + $this->lon = $lon; + } + + public function toGeoJson(): string + { + $array = $this->toArrayGeoJson(); + return \json_encode($array); + } + + public function jsonSerialize(): array + { + return $this->toArrayGeoJson(); + } + + public function toArrayGeoJson(): array + { + return [ + "type" => "Point", + "coordinates" => [ $this->lon, $this->lat ] + ]; + } + + /** + * + * @return string + */ + public function toWKT(): string + { + return 'SRID='.self::$SRID.';POINT('.$this->lon.' '.$this->lat.')'; + } + + /** + * + * @param type $geojson + * @return Point + */ + public static function fromGeoJson(string $geojson): Point + { + $a = json_decode($geojson); + //check if the geojson string is correct + if (NULL === $a or !isset($a->type) or !isset($a->coordinates)){ + throw PointException::badJsonString($geojson); + } + + if ($a->type != 'Point'){ + throw PointException::badGeoType(); + } + + $lat = $a->coordinates[1]; + $lon = $a->coordinates[0]; + + return Point::fromLonLat($lon, $lat); + } + + public static function fromLonLat(float $lon, float $lat): Point + { + if (($lon > -180 && $lon < 180) && ($lat > -90 && $lat < 90)) + { + return new Point($lon, $lat); + } else { + throw PointException::badCoordinates($lon, $lat); + } + } + + public static function fromArrayGeoJson(array $array): Point + { + if ($array['type'] == 'Point' && + isset($array['coordinates'])) + { + return self::fromLonLat($array['coordinates'][0], $array['coordinates'][1]); + } + } + + public function getLat(): float + { + return $this->lat; + } + + public function getLon(): float + { + return $this->lon; + } +} + + diff --git a/src/Bundle/ChillMainBundle/Doctrine/Model/PointException.php b/src/Bundle/ChillMainBundle/Doctrine/Model/PointException.php new file mode 100644 index 000000000..4e3101435 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Doctrine/Model/PointException.php @@ -0,0 +1,27 @@ +toWKT(); + } + } + + public function canRequireSQLConversion() + { + return true; + } + + public function convertToPHPValueSQL($sqlExpr, $platform) + { + return 'ST_AsGeoJSON('.$sqlExpr.') '; + } + + public function convertToDatabaseValueSQL($sqlExpr, AbstractPlatform $platform) + { + return $sqlExpr; + } +} + diff --git a/src/Bundle/ChillMainBundle/Entity/Address.php b/src/Bundle/ChillMainBundle/Entity/Address.php index 69c39c7b6..36eda09c2 100644 --- a/src/Bundle/ChillMainBundle/Entity/Address.php +++ b/src/Bundle/ChillMainBundle/Entity/Address.php @@ -4,6 +4,8 @@ namespace Chill\MainBundle\Entity; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Validator\Context\ExecutionContextInterface; +use Chill\MainBundle\Doctrine\Model\Point; +use Chill\ThirdPartyBundle\Entity\ThirdParty; /** * Address @@ -28,14 +30,14 @@ class Address * * @ORM\Column(type="string", length=255) */ - private $streetAddress1 = ''; + private $street = ''; /** * @var string * * @ORM\Column(type="string", length=255) */ - private $streetAddress2 = ''; + private $streetNumber = ''; /** * @var PostalCode @@ -43,7 +45,56 @@ class Address * @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\PostalCode") */ private $postcode; - + + /** + * @var string|null + * + * @ORM\Column(type="string", length=16, nullable=true) + */ + private $floor; + + /** + * @var string|null + * + * @ORM\Column(type="string", length=16, nullable=true) + */ + private $corridor; + + /** + * @var string|null + * + * @ORM\Column(type="string", length=16, nullable=true) + */ + private $steps; + + /** + * @var string|null + * + * @ORM\Column(type="string", length=255, nullable=true) + */ + private $buildingName; + + /** + * @var string|null + * + * @ORM\Column(type="string", length=16, nullable=true) + */ + private $flat; + + /** + * @var string|null + * + * @ORM\Column(type="string", length=255, nullable=true) + */ + private $distribution; + + /** + * @var string|null + * + * @ORM\Column(type="string", length=255, nullable=true) + */ + private $extra; + /** * Indicates when the address starts validation. Used to build an history * of address. By default, the current date. @@ -53,27 +104,55 @@ class Address * @ORM\Column(type="date") */ private $validFrom; - + + /** + * Indicates when the address ends. Used to build an history + * of address. + * + * @var \DateTime|null + * + * @ORM\Column(type="date", nullable=true) + */ + private $validTo; + /** * True if the address is a "no address", aka homeless person, ... * * @var bool */ private $isNoAddress = false; - + + /** + * A geospatial field storing the coordinates of the Address + * + * @var Point|null + * + * @ORM\Column(type="point", nullable=true) + */ + private $point; + + /** + * A ThirdParty reference for person's addresses that are linked to a third party + * + * @var ThirdParty|null + * + * @ORM\ManyToOne(targetEntity="Chill\ThirdPartyBundle\Entity\ThirdParty") + * @ORM\JoinColumn(nullable=true) + */ + private $linkedToThirdParty; + /** * A list of metadata, added by customizable fields - * + * * @var array */ private $customs = []; - + public function __construct() { $this->validFrom = new \DateTime(); } - /** * Get id * @@ -85,7 +164,7 @@ class Address } /** - * Set streetAddress1 + * Set streetAddress1 (legacy function) * * @param string $streetAddress1 * @@ -93,23 +172,23 @@ class Address */ public function setStreetAddress1($streetAddress1) { - $this->streetAddress1 = $streetAddress1 === NULL ? '' : $streetAddress1; + $this->street = $streetAddress1 === NULL ? '' : $streetAddress1; return $this; } /** - * Get streetAddress1 + * Get streetAddress1 (legacy function) * * @return string */ public function getStreetAddress1() { - return $this->streetAddress1; + return $this->street; } /** - * Set streetAddress2 + * Set streetAddress2 (legacy function) * * @param string $streetAddress2 * @@ -117,19 +196,19 @@ class Address */ public function setStreetAddress2($streetAddress2) { - $this->streetAddress2 = $streetAddress2 === NULL ? '' : $streetAddress2; + $this->streetNumber = $streetAddress2 === NULL ? '' : $streetAddress2; return $this; } /** - * Get streetAddress2 + * Get streetAddress2 (legacy function) * * @return string */ public function getStreetAddress2() { - return $this->streetAddress2; + return $this->streetNumber; } /** @@ -155,7 +234,7 @@ class Address { return $this->postcode; } - + /** * @return \DateTime */ @@ -173,19 +252,19 @@ class Address $this->validFrom = $validFrom; return $this; } - + /** * Get IsNoAddress - * + * * Indicate true if the address is a fake address (homeless, ...) - * + * * @return bool */ public function getIsNoAddress(): bool { return $this->isNoAddress; } - + /** * @return bool */ @@ -196,9 +275,9 @@ class Address /** * Set IsNoAddress - * + * * Indicate true if the address is a fake address (homeless, ...) - * + * * @param bool $isNoAddress * @return $this */ @@ -207,10 +286,10 @@ class Address $this->isNoAddress = $isNoAddress; return $this; } - + /** * Get customs informations in the address - * + * * @return array */ public function getCustoms(): array @@ -220,27 +299,27 @@ class Address /** * Store custom informations in the address - * + * * @param array $customs * @return $this */ public function setCustoms(array $customs): self { $this->customs = $customs; - + return $this; } - + /** * Validate the address. - * + * * Check that: - * + * * * if the address is not home address: * * the postal code is present * * the valid from is not null * * the address street 1 is greater than 2 - * + * * @param ExecutionContextInterface $context * @param array $payload */ @@ -252,18 +331,18 @@ class Address ->atPath('validFrom') ->addViolation(); } - + if ($this->isNoAddress()) { return; } - + if (empty($this->getStreetAddress1())) { $context ->buildViolation("address.street1-should-be-set") ->atPath('streetAddress1') ->addViolation(); } - + if (!$this->getPostcode() instanceof PostalCode) { $context ->buildViolation("address.postcode-should-be-set") @@ -271,7 +350,7 @@ class Address ->addViolation(); } } - + /** * @param Address $original * @return Address @@ -286,5 +365,149 @@ class Address ; } + public function getStreet(): ?string + { + return $this->street; + } + + public function setStreet(string $street): self + { + $this->street = $street; + + return $this; + } + + public function getStreetNumber(): ?string + { + return $this->streetNumber; + } + + public function setStreetNumber(string $streetNumber): self + { + $this->streetNumber = $streetNumber; + + return $this; + } + + public function getFloor(): ?string + { + return $this->floor; + } + + public function setFloor(?string $floor): self + { + $this->floor = $floor; + + return $this; + } + + public function getCorridor(): ?string + { + return $this->corridor; + } + + public function setCorridor(?string $corridor): self + { + $this->corridor = $corridor; + + return $this; + } + + public function getSteps(): ?string + { + return $this->steps; + } + + public function setSteps(?string $steps): self + { + $this->steps = $steps; + + return $this; + } + + public function getBuildingName(): ?string + { + return $this->buildingName; + } + + public function setBuildingName(?string $buildingName): self + { + $this->buildingName = $buildingName; + + return $this; + } + + public function getFlat(): ?string + { + return $this->flat; + } + + public function setFlat(?string $flat): self + { + $this->flat = $flat; + + return $this; + } + + public function getDistribution(): ?string + { + return $this->distribution; + } + + public function setDistribution(?string $distribution): self + { + $this->distribution = $distribution; + + return $this; + } + + public function getExtra(): ?string + { + return $this->extra; + } + + public function setExtra(?string $extra): self + { + $this->extra = $extra; + + return $this; + } + + public function getValidTo(): ?\DateTimeInterface + { + return $this->validTo; + } + + public function setValidTo(\DateTimeInterface $validTo): self + { + $this->validTo = $validTo; + + return $this; + } + + public function getPoint(): ?Point + { + return $this->point; + } + + public function setPoint(?Point $point): self + { + $this->point = $point; + + return $this; + } + + public function getLinkedToThirdParty() + { + return $this->linkedToThirdParty; + } + + public function setLinkedToThirdParty($linkedToThirdParty): self + { + $this->linkedToThirdParty = $linkedToThirdParty; + + return $this; + } + } diff --git a/src/Bundle/ChillMainBundle/Entity/AddressReference.php b/src/Bundle/ChillMainBundle/Entity/AddressReference.php new file mode 100644 index 000000000..944cab81b --- /dev/null +++ b/src/Bundle/ChillMainBundle/Entity/AddressReference.php @@ -0,0 +1,165 @@ +id; + } + + public function getRefId(): ?string + { + return $this->refId; + } + + public function setRefId(string $refId): self + { + $this->refId = $refId; + + return $this; + } + + public function getStreet(): ?string + { + return $this->street; + } + + public function setStreet(?string $street): self + { + $this->street = $street; + + return $this; + } + + public function getStreetNumber(): ?string + { + return $this->streetNumber; + } + + public function setStreetNumber(?string $streetNumber): self + { + $this->streetNumber = $streetNumber; + + return $this; + } + + /** + * Set postcode + * + * @param PostalCode $postcode + * + * @return Address + */ + public function setPostcode(PostalCode $postcode = null) + { + $this->postcode = $postcode; + + return $this; + } + + /** + * Get postcode + * + * @return PostalCode + */ + public function getPostcode() + { + return $this->postcode; + } + + public function getMunicipalityCode(): ?string + { + return $this->municipalityCode; + } + + public function setMunicipalityCode(?string $municipalityCode): self + { + $this->municipalityCode = $municipalityCode; + + return $this; + } + + public function getSource(): ?string + { + return $this->source; + } + + public function setSource(?string $source): self + { + $this->source = $source; + + return $this; + } + + public function getPoint(): ?Point + { + return $this->point; + } + + public function setPoint(?Point $point): self + { + $this->point = $point; + + return $this; + } +} diff --git a/src/Bundle/ChillMainBundle/Form/Type/AddressType.php b/src/Bundle/ChillMainBundle/Form/Type/AddressType.php index 4a0e222b8..68cfdda09 100644 --- a/src/Bundle/ChillMainBundle/Form/Type/AddressType.php +++ b/src/Bundle/ChillMainBundle/Form/Type/AddressType.php @@ -33,8 +33,8 @@ use Symfony\Component\Form\Extension\Core\Type\ChoiceType; * A type to create/update Address entity * * Options: - * - * - `has_valid_from` (boolean): show if an entry "has valid from" must be + * + * - `has_valid_from` (boolean): show if an entry "has valid from" must be * shown. * - `null_if_empty` (boolean): replace the address type by null if the street * or the postCode is empty. This is useful when the address is not required and @@ -45,10 +45,10 @@ class AddressType extends AbstractType public function buildForm(FormBuilderInterface $builder, array $options) { $builder - ->add('streetAddress1', TextType::class, array( + ->add('street', TextType::class, array( 'required' => !$options['has_no_address'] // true if has no address is false )) - ->add('streetAddress2', TextType::class, array( + ->add('streetNumber', TextType::class, array( 'required' => false )) ->add('postCode', PostalCodeType::class, array( @@ -57,7 +57,7 @@ class AddressType extends AbstractType 'required' => !$options['has_no_address'] // true if has no address is false )) ; - + if ($options['has_valid_from']) { $builder ->add('validFrom', DateType::class, array( @@ -67,7 +67,7 @@ class AddressType extends AbstractType ) ); } - + if ($options['has_no_address']) { $builder ->add('isNoAddress', ChoiceType::class, [ @@ -79,12 +79,12 @@ class AddressType extends AbstractType 'label' => 'address.address_homeless' ]); } - + if ($options['null_if_empty'] === TRUE) { $builder->setDataMapper(new AddressDataMapper()); } } - + public function configureOptions(OptionsResolver $resolver) { $resolver diff --git a/src/Bundle/ChillMainBundle/Repository/AddressReferenceRepository.php b/src/Bundle/ChillMainBundle/Repository/AddressReferenceRepository.php new file mode 100644 index 000000000..208151420 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Repository/AddressReferenceRepository.php @@ -0,0 +1,50 @@ +createQueryBuilder('a') + ->andWhere('a.exampleField = :val') + ->setParameter('val', $value) + ->orderBy('a.id', 'ASC') + ->setMaxResults(10) + ->getQuery() + ->getResult() + ; + } + */ + + /* + public function findOneBySomeField($value): ?AddressReference + { + return $this->createQueryBuilder('a') + ->andWhere('a.exampleField = :val') + ->setParameter('val', $value) + ->getQuery() + ->getOneOrNullResult() + ; + } + */ +} diff --git a/src/Bundle/ChillMainBundle/Resources/views/Address/macro.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Address/macro.html.twig index 165d7c280..5de175169 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/Address/macro.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/Address/macro.html.twig @@ -6,8 +6,8 @@
{{ 'address.consider homeless'|trans }}
{% endif %}
- {% if address.streetAddress1 is not empty %}

{{ address.streetAddress1 }}

{% endif %} - {% if address.streetAddress2 is not empty %}

{{ address.streetAddress2 }}

{% endif %} + {% if address.street is not empty %}

{{ address.street }}

{% endif %} + {% if address.streetNumber is not empty %}

{{ address.streetNumber }}

{% endif %} {% if address.postCode is not empty %}

{{ address.postCode.code }} {{ address.postCode.name }}

{{ address.postCode.country.name|localize_translatable_string }}

diff --git a/src/Bundle/ChillMainBundle/Tests/Doctrine/Model/PointTest.php b/src/Bundle/ChillMainBundle/Tests/Doctrine/Model/PointTest.php new file mode 100644 index 000000000..5632bf96a --- /dev/null +++ b/src/Bundle/ChillMainBundle/Tests/Doctrine/Model/PointTest.php @@ -0,0 +1,119 @@ + + */ +class ExportControllerTest extends KernelTestCase +{ + + public function testToWKT() + { + $lon = 4.8634; + $lat = 50.47382; + $point = $this->preparePoint($lon, $lat); + + $this->assertEquals($point->toWKT(),'SRID=4326;POINT(4.8634 50.47382)'); + } + + public function testToGeojson() + { + $lon = 4.8634; + $lat = 50.47382; + $point = $this->preparePoint($lon, $lat); + + $this->assertEquals($point->toGeoJson(),'{"type":"Point","coordinates":[4.8634,50.47382]}'); + } + + public function testToArrayGeoJson() + { + $lon = 4.8634; + $lat = 50.47382; + $point = $this->preparePoint($lon, $lat); + + $this->assertEquals( + $point->toArrayGeoJson(), + [ + 'type' => 'Point', + 'coordinates' => [4.8634, 50.47382] + ] + ); + } + + public function testJsonSerialize() + { + $lon = 4.8634; + $lat = 50.47382; + $point = $this->preparePoint($lon, $lat); + + $this->assertEquals( + $point->jsonSerialize(), + [ + 'type' => 'Point', + 'coordinates' => [4.8634, 50.47382] + ] + ); + } + + public function testFromGeoJson() + { + $geojson = '{"type":"Point","coordinates":[4.8634,50.47382]}'; + $lon = 4.8634; + $lat = 50.47382; + $point = $this->preparePoint($lon, $lat);; + + $this->assertEquals($point, Point::fromGeoJson($geojson)); + } + + public function testFromLonLat() + { + $lon = 4.8634; + $lat = 50.47382; + $point = $this->preparePoint($lon, $lat);; + + $this->assertEquals($point, Point::fromLonLat($lon, $lat)); + } + + public function testFromArrayGeoJson() + { + $array = [ + 'type' => 'Point', + 'coordinates' => [4.8634, 50.47382] + ]; + $lon = 4.8634; + $lat = 50.47382; + $point = $this->preparePoint($lon, $lat);; + + $this->assertEquals($point, Point::fromArrayGeoJson($array)); + } + + public function testGetLat() + { + $lon = 4.8634; + $lat = 50.47382; + $point = $this->preparePoint($lon, $lat);; + + $this->assertEquals($lat, $point->getLat()); + } + + public function testGetLon() + { + $lon = 4.8634; + $lat = 50.47382; + $point = $this->preparePoint($lon, $lat);; + + $this->assertEquals($lon, $point->getLon()); + } + + private function preparePoint($lon, $lat) + { + return Point::fromLonLat($lon, $lat); + } + +} diff --git a/src/Bundle/ChillMainBundle/migrations/Version20210414091001.php b/src/Bundle/ChillMainBundle/migrations/Version20210414091001.php new file mode 100644 index 000000000..db207c594 --- /dev/null +++ b/src/Bundle/ChillMainBundle/migrations/Version20210414091001.php @@ -0,0 +1,32 @@ +abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.'); + + $this->addSql('CREATE EXTENSION IF NOT EXISTS postgis;'); + + } + + public function down(Schema $schema) : void + { + $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.'); + + $this->addSql('DROP EXTENSION IF NOT EXISTS postgis;'); + } + + public function getDescription(): string + { + return "Enable the postgis extension in public schema"; + } +} diff --git a/src/Bundle/ChillMainBundle/migrations/Version20210420115006.php b/src/Bundle/ChillMainBundle/migrations/Version20210420115006.php new file mode 100644 index 000000000..79dea4853 --- /dev/null +++ b/src/Bundle/ChillMainBundle/migrations/Version20210420115006.php @@ -0,0 +1,50 @@ +addSql('ALTER TABLE chill_main_address RENAME COLUMN streetaddress1 TO street;'); + $this->addSql('ALTER TABLE chill_main_address RENAME COLUMN streetaddress2 TO streetNumber;'); + $this->addSql('ALTER TABLE chill_main_address ADD floor VARCHAR(16) DEFAULT NULL'); + $this->addSql('ALTER TABLE chill_main_address ADD corridor VARCHAR(16) DEFAULT NULL'); + $this->addSql('ALTER TABLE chill_main_address ADD steps VARCHAR(16) DEFAULT NULL'); + $this->addSql('ALTER TABLE chill_main_address ADD buildingName VARCHAR(255) DEFAULT NULL'); + $this->addSql('ALTER TABLE chill_main_address ADD flat VARCHAR(16) DEFAULT NULL'); + $this->addSql('ALTER TABLE chill_main_address ADD distribution VARCHAR(255) DEFAULT NULL'); + $this->addSql('ALTER TABLE chill_main_address ADD extra VARCHAR(255) DEFAULT NULL'); + $this->addSql('ALTER TABLE chill_main_address ADD validTo DATE DEFAULT NULL'); + $this->addSql('ALTER TABLE chill_main_address ADD point geometry(POINT,4326) DEFAULT NULL'); + } + + + public function down(Schema $schema) : void + { + $this->addSql('ALTER TABLE chill_main_address RENAME COLUMN street TO streetaddress1;'); + $this->addSql('ALTER TABLE chill_main_address RENAME COLUMN streetNumber TO streetaddress2;'); + $this->addSql('ALTER TABLE chill_main_address DROP floor'); + $this->addSql('ALTER TABLE chill_main_address DROP corridor'); + $this->addSql('ALTER TABLE chill_main_address DROP steps'); + $this->addSql('ALTER TABLE chill_main_address DROP buildingName'); + $this->addSql('ALTER TABLE chill_main_address DROP flat'); + $this->addSql('ALTER TABLE chill_main_address DROP distribution'); + $this->addSql('ALTER TABLE chill_main_address DROP extra'); + $this->addSql('ALTER TABLE chill_main_address DROP validTo'); + $this->addSql('ALTER TABLE chill_main_address DROP point'); + } +} diff --git a/src/Bundle/ChillMainBundle/migrations/Version20210503085107.php b/src/Bundle/ChillMainBundle/migrations/Version20210503085107.php new file mode 100644 index 000000000..f693777a0 --- /dev/null +++ b/src/Bundle/ChillMainBundle/migrations/Version20210503085107.php @@ -0,0 +1,33 @@ +addSql('CREATE SEQUENCE chill_main_address_reference_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); + $this->addSql('CREATE TABLE chill_main_address_reference (id INT NOT NULL, postcode_id INT DEFAULT NULL, refId VARCHAR(255) NOT NULL, street VARCHAR(255) DEFAULT NULL, streetNumber VARCHAR(255) DEFAULT NULL, municipalityCode VARCHAR(255) DEFAULT NULL, source VARCHAR(255) DEFAULT NULL, point geometry(POINT,4326) NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE INDEX IDX_CA6C1BD7EECBFDF1 ON chill_main_address_reference (postcode_id)'); + $this->addSql('ALTER TABLE chill_main_address_reference ADD CONSTRAINT FK_CA6C1BD7EECBFDF1 FOREIGN KEY (postcode_id) REFERENCES chill_main_postal_code (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + } + + public function down(Schema $schema): void + { + $this->addSql('DROP SEQUENCE chill_main_address_reference_id_seq CASCADE'); + $this->addSql('DROP TABLE chill_main_address_reference'); + } +} diff --git a/src/Bundle/ChillMainBundle/migrations/Version20210505153727.php b/src/Bundle/ChillMainBundle/migrations/Version20210505153727.php new file mode 100644 index 000000000..42161ba84 --- /dev/null +++ b/src/Bundle/ChillMainBundle/migrations/Version20210505153727.php @@ -0,0 +1,58 @@ +addSql('ALTER TABLE chill_main_address ADD linkedToThirdParty_id INT DEFAULT NULL'); + $this->addSql('ALTER TABLE chill_main_address ADD CONSTRAINT FK_165051F6114B8DD9 FOREIGN KEY (linkedToThirdParty_id) REFERENCES chill_3party.third_party (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('CREATE INDEX IDX_165051F6114B8DD9 ON chill_main_address (linkedToThirdParty_id)'); + $this->addSql(' + CREATE TABLE chill_main_address_legacy AS + TABLE chill_main_address; + '); + $this->addSql(' + WITH hydrated_addresses AS ( + SELECT *, rank() OVER (PARTITION BY pa_a.person_id ORDER BY validfrom) + FROM chill_main_address AS aa JOIN chill_person_persons_to_addresses AS pa_a ON aa.id = pa_a.address_id + ) + UPDATE chill_main_address AS b + SET validto = ( + SELECT validfrom - INTERVAL \'1 DAY\' + FROM hydrated_addresses + WHERE hydrated_addresses.id = ( + SELECT a1.id + FROM hydrated_addresses AS a1 JOIN hydrated_addresses AS a2 ON a2.person_id = a1.person_id AND a2.rank = (a1.rank-1) + WHERE a2.id = b.id + ) + ); + '); + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE chill_main_address DROP CONSTRAINT FK_165051F6114B8DD9'); + $this->addSql('DROP INDEX IDX_165051F6114B8DD9'); + $this->addSql('ALTER TABLE chill_main_address DROP linkedToThirdParty_id'); + $this->addSql('DROP TABLE IF EXISTS chill_main_address_legacy'); + $this->addSql(' + UPDATE chill_main_address + SET validto = null; + '); + } +} diff --git a/src/Bundle/ChillPersonBundle/DataFixtures/ORM/LoadPeople.php b/src/Bundle/ChillPersonBundle/DataFixtures/ORM/LoadPeople.php index fa20d3457..e8697ff28 100644 --- a/src/Bundle/ChillPersonBundle/DataFixtures/ORM/LoadPeople.php +++ b/src/Bundle/ChillPersonBundle/DataFixtures/ORM/LoadPeople.php @@ -29,6 +29,7 @@ use Chill\PersonBundle\Entity\Person; use Symfony\Component\DependencyInjection\ContainerAwareInterface; use Chill\MainBundle\DataFixtures\ORM\LoadPostalCodes; use Chill\MainBundle\Entity\Address; +use Chill\MainBundle\Doctrine\Model\Point; /** * Load people into database @@ -37,17 +38,17 @@ use Chill\MainBundle\Entity\Address; * @author Marc Ducobu */ class LoadPeople extends AbstractFixture implements OrderedFixtureInterface, ContainerAwareInterface -{ - +{ + use \Symfony\Component\DependencyInjection\ContainerAwareTrait; - + protected $faker; - + public function __construct() { $this->faker = \Faker\Factory::create('fr_FR'); } - + public function prepare() { //prepare days, month, years @@ -56,57 +57,57 @@ class LoadPeople extends AbstractFixture implements OrderedFixtureInterface, Con $this->years[] = $y; $y = $y +1; } while ($y >= 1990); - + $m = 1; do { $this->month[] = $m; $m = $m +1; } while ($m >= 12); - + $d = 1; do { $this->day[] = $d; $d = $d + 1; } while ($d <= 28); } - + public function getOrder() { return 10000; } - + public function load(ObjectManager $manager) { $this->loadRandPeople($manager); $this->loadExpectedPeople($manager); - + $manager->flush(); } - + public function loadExpectedPeople(ObjectManager $manager) { echo "loading expected people...\n"; - + foreach ($this->peoples as $person) { $this->addAPerson($this->fillWithDefault($person), $manager); } } - + public function loadRandPeople(ObjectManager $manager) { echo "loading rand people...\n"; - + $this->prepare(); - + $chooseLastNameOrTri = array('tri', 'tri', 'name', 'tri'); - + $i = 0; - + do { $i++; - + $sex = $this->genders[array_rand($this->genders)]; - + if ($chooseLastNameOrTri[array_rand($chooseLastNameOrTri)] === 'tri' ) { $length = rand(2, 3); $lastName = ''; @@ -117,13 +118,13 @@ class LoadPeople extends AbstractFixture implements OrderedFixtureInterface, Con } else { $lastName = $this->lastNames[array_rand($this->lastNames)]; } - + if ($sex === Person::MALE_GENDER) { $firstName = $this->firstNamesMale[array_rand($this->firstNamesMale)]; } else { $firstName = $this->firstNamesFemale[array_rand($this->firstNamesFemale)]; } - + // add an address on 80% of the created people if (rand(0,100) < 80) { $address = $this->getRandomAddress(); @@ -137,7 +138,7 @@ class LoadPeople extends AbstractFixture implements OrderedFixtureInterface, Con } else { $address = null; } - + $person = array( 'FirstName' => $firstName, 'LastName' => $lastName, @@ -147,15 +148,15 @@ class LoadPeople extends AbstractFixture implements OrderedFixtureInterface, Con 'Address' => $address, 'maritalStatus' => $this->maritalStatusRef[array_rand($this->maritalStatusRef)] ); - + $this->addAPerson($this->fillWithDefault($person), $manager); - + } while ($i <= 100); } - + /** * fill a person array with default value - * + * * @param string[] $specific */ private function fillWithDefault(array $specific) @@ -171,10 +172,10 @@ class LoadPeople extends AbstractFixture implements OrderedFixtureInterface, Con 'Address' => null ), $specific); } - + /** * create a new person from array data - * + * * @param array $person * @param ObjectManager $manager * @throws \Exception @@ -200,35 +201,51 @@ class LoadPeople extends AbstractFixture implements OrderedFixtureInterface, Con $this->addAccompanyingPeriods($p, $value, $manager); break; } - + //try to add the data using the setSomething function, // if not possible, fallback to addSomething function if (method_exists($p, 'set'.$key)) { call_user_func(array($p, 'set'.$key), $value); } elseif (method_exists($p, 'add'.$key)) { // if we have a "addSomething", we may have multiple items to add - // so, we set the value in an array if it is not an array, and + // so, we set the value in an array if it is not an array, and // will call the function addSomething multiple times if (!is_array($value)) { $value = array($value); } - + foreach($value as $v) { if ($v !== NULL) { call_user_func(array($p, 'add'.$key), $v); } } - - } + + } } $manager->persist($p); echo "add person'".$p->__toString()."'\n"; } - + + /** - * Creata a random address - * + * Create a random point + * + * @return Point + */ + private function getRandomPoint() + { + $lonBrussels = 4.35243; + $latBrussels = 50.84676; + $lon = $lonBrussels + 0.01 * rand(-5, 5); + $lat = $latBrussels + 0.01 * rand(-5, 5); + return Point::fromLonLat($lon, $lat); + } + + + /** + * Create a random address + * * @return Address */ private function getRandomAddress() @@ -238,13 +255,16 @@ class LoadPeople extends AbstractFixture implements OrderedFixtureInterface, Con ->setStreetAddress2( rand(0,9) > 5 ? $this->faker->streetAddress : '' ) + ->setPoint( + rand(0,9) > 5 ? $this->getRandomPoint() : NULL + ) ->setPostcode($this->getReference( LoadPostalCodes::$refs[array_rand(LoadPostalCodes::$refs)] )) ->setValidFrom($this->faker->dateTimeBetween('-5 years')) ; } - + private function getCountry($countryCode) { if ($countryCode === NULL) { @@ -257,30 +277,30 @@ class LoadPeople extends AbstractFixture implements OrderedFixtureInterface, Con private $maritalStatusRef = ['ms_single', 'ms_married', 'ms_widow', 'ms_separat', 'ms_divorce', 'ms_legalco', 'ms_unknown']; - + private $firstNamesMale = array("Jean", "Mohamed", "Alfred", "Robert", "Justin", "Brian", "Compère", "Jean-de-Dieu", "Charles", "Pierre", "Luc", "Mathieu", "Alain", "Etienne", "Eric", "Corentin", "Gaston", "Spirou", "Fantasio", "Mahmadou", "Mohamidou", "Vursuv", "Youssef" ); - + private $firstNamesFemale = array("Svedana", "Sevlatina", "Irène", "Marcelle", "Corentine", "Alfonsine", "Caroline", "Solange", "Gostine", "Fatoumata", "Nicole", "Groseille", "Chana", "Oxana", "Ivana", "Julie", "Tina", "Adèle" ); - + private $lastNames = array("Diallo", "Bah", "Gaillot", "Martin"); - + private $lastNamesTrigrams = array("fas", "tré", "hu", 'blart', 'van', 'der', 'lin', 'den', 'ta', 'mi', 'net', 'gna', 'bol', 'sac', 'ré', 'jo', 'du', 'pont', 'cas', 'tor', 'rob', 'al', 'ma', 'gone', 'car',"fu", "ka", "lot", "no", "va", "du", "bu", "su", "jau", "tte", 'sir', "lo", 'to', "cho", "car", 'mo','zu', 'qi', 'mu'); - + private $genders = array(Person::MALE_GENDER, Person::FEMALE_GENDER); - + private $years = array(); - + private $month = array(); - + private $day = array(); - + private $peoples = array( array( 'LastName' => "Depardieu", @@ -362,21 +382,21 @@ class LoadPeople extends AbstractFixture implements OrderedFixtureInterface, Con 'maritalStatus' => 'ms_legalco' ), ); - - + + private function addAccompanyingPeriods(Person $person, array $periods, ObjectManager $manager) { foreach ($periods as $period) { - + echo "adding new past Accompanying Period..\n"; - + /** @var AccompanyingPeriod $accompanyingPeriod */ $accompanyingPeriod = new AccompanyingPeriod(new \DateTime($period['from'])); $accompanyingPeriod ->setClosingDate(new \DateTime($period['to'])) ->setRemark($period['remark']) ; - + $person->addAccompanyingPeriod($accompanyingPeriod); } } diff --git a/src/Bundle/ChillPersonBundle/Entity/Household/Household.php b/src/Bundle/ChillPersonBundle/Entity/Household/Household.php new file mode 100644 index 000000000..a12741dee --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Entity/Household/Household.php @@ -0,0 +1,70 @@ +id; + } + + /** + * Addresses + * @var Collection + * + * @ORM\ManyToMany( + * targetEntity="Chill\MainBundle\Entity\Address", + * cascade={"persist", "remove", "merge", "detach"}) + * @ORM\JoinTable(name="chill_person_household_to_addresses") + * @ORM\OrderBy({"validFrom" = "DESC"}) + */ + private $addresses; + + + /** + * @param Address $address + * @return $this + */ + public function addAddress(Address $address) + { + $this->addresses[] = $address; + + return $this; + } + + /** + * @param Address $address + */ + public function removeAddress(Address $address) + { + $this->addresses->removeElement($address); + } + + /** + * By default, the addresses are ordered by date, descending (the most + * recent first) + * + * @return \Chill\MainBundle\Entity\Address[] + */ + public function getAddresses() + { + return $this->addresses; + } + +} diff --git a/src/Bundle/ChillPersonBundle/Entity/Household/HouseholdMembers.php b/src/Bundle/ChillPersonBundle/Entity/Household/HouseholdMembers.php new file mode 100644 index 000000000..80864ecd0 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Entity/Household/HouseholdMembers.php @@ -0,0 +1,153 @@ +id; + } + + public function getPosition(): ?string + { + return $this->position; + } + + public function setPosition(?string $position): self + { + $this->position = $position; + + return $this; + } + + public function getStartDate(): ?\DateTimeInterface + { + return $this->startDate; + } + + public function setStartDate(\DateTimeInterface $startDate): self + { + $this->startDate = $startDate; + + return $this; + } + + public function getEndDate(): ?\DateTimeInterface + { + return $this->endDate; + } + + public function setEndDate(\DateTimeInterface $endDate): self + { + $this->endDate = $endDate; + + return $this; + } + + public function getComment(): ?string + { + return $this->comment; + } + + public function setComment(?string $comment): self + { + $this->comment = $comment; + + return $this; + } + + public function getSharedHousehold(): ?bool + { + return $this->sharedHousehold; + } + + public function setSharedHousehold(bool $sharedHousehold): self + { + $this->sharedHousehold = $sharedHousehold; + + return $this; + } + + public function getPerson(): ?Person + { + return $this->person; + } + + public function setPerson(?Person $person): self + { + $this->person = $person; + + return $this; + } + + public function getHousehold(): ?Household + { + return $this->household; + } + + public function setHousehold(?Household $household): self + { + $this->household = $household; + + return $this; + } +} diff --git a/src/Bundle/ChillPersonBundle/Repository/Household/HouseholdMembersRepository.php b/src/Bundle/ChillPersonBundle/Repository/Household/HouseholdMembersRepository.php new file mode 100644 index 000000000..feea6d44d --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Repository/Household/HouseholdMembersRepository.php @@ -0,0 +1,50 @@ +createQueryBuilder('h') + ->andWhere('h.exampleField = :val') + ->setParameter('val', $value) + ->orderBy('h.id', 'ASC') + ->setMaxResults(10) + ->getQuery() + ->getResult() + ; + } + */ + + /* + public function findOneBySomeField($value): ?HouseholdMembers + { + return $this->createQueryBuilder('h') + ->andWhere('h.exampleField = :val') + ->setParameter('val', $value) + ->getQuery() + ->getOneOrNullResult() + ; + } + */ +} diff --git a/src/Bundle/ChillPersonBundle/Repository/Household/HouseholdRepository.php b/src/Bundle/ChillPersonBundle/Repository/Household/HouseholdRepository.php new file mode 100644 index 000000000..38522806c --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Repository/Household/HouseholdRepository.php @@ -0,0 +1,50 @@ +createQueryBuilder('h') + ->andWhere('h.exampleField = :val') + ->setParameter('val', $value) + ->orderBy('h.id', 'ASC') + ->setMaxResults(10) + ->getQuery() + ->getResult() + ; + } + */ + + /* + public function findOneBySomeField($value): ?Household + { + return $this->createQueryBuilder('h') + ->andWhere('h.exampleField = :val') + ->setParameter('val', $value) + ->getQuery() + ->getOneOrNullResult() + ; + } + */ +} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/Address/edit.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/Address/edit.html.twig index eea76b5fe..b516dfb83 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/Address/edit.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/Address/edit.html.twig @@ -21,17 +21,17 @@ {% block title 'Update address for %name%'|trans({ '%name%': person.firstName ~ ' ' ~ person.lastName } ) %} {% block personcontent %} - +

{{ 'Update address for %name%'|trans({ '%name%': person.firstName ~ ' ' ~ person.lastName } ) }}

- + {{ form_start(form) }} - + {{ form_row(form.isNoAddress) }} - {{ form_row(form.streetAddress1) }} - {{ form_row(form.streetAddress2) }} + {{ form_row(form.street) }} + {{ form_row(form.streetNumber) }} {{ form_row(form.postCode) }} {{ form_row(form.validFrom) }} - + - + {{ form_end(form) }} - -{% endblock personcontent %} \ No newline at end of file + +{% endblock personcontent %} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/Address/list.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/Address/list.html.twig index 9e91e486c..8a2aeee42 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/Address/list.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/Address/list.html.twig @@ -23,9 +23,9 @@ {% block title %}{{ 'Addresses\'history for %name%'|trans({ '%name%': person.firstName ~ ' ' ~ person.lastName } ) }}{% endblock %} {% block personcontent %} - +

{{ 'Addresses\'history for %name%'|trans({ '%name%': person.firstName ~ ' ' ~ person.lastName } ) }}

- + @@ -48,11 +48,11 @@ {% for address in person.addresses %} - + - + + {% endfor %} {% endif %}
{{ 'Since %date%'|trans( { '%date%' : address.validFrom|format_date('long') } ) }} {{ address_macros._render(address, { 'with_valid_from' : false, 'has_no_address': true } ) }}
  • @@ -61,11 +61,17 @@
- + + + + + +
- -{% endblock personcontent %} \ No newline at end of file + +{% endblock personcontent %} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/Address/new.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/Address/new.html.twig index 9e94d7804..70cc51e53 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/Address/new.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/Address/new.html.twig @@ -21,21 +21,21 @@ {% block title %}{{ 'New address for %name%'|trans({ '%name%': person.firstName|capitalize ~ ' ' ~ person.lastName } )|capitalize }}{% endblock %} {% block personcontent %} - +

{{ 'New address for %name%'|trans({ '%name%': person.firstName ~ ' ' ~ person.lastName } ) }}

- + {{ form_start(form) }} - + {{ form_row(form.isNoAddress) }} - {{ form_row(form.streetAddress1) }} - {{ form_errors(form.streetAddress1) }} - {{ form_row(form.streetAddress2) }} - {{ form_errors(form.streetAddress2) }} + {{ form_row(form.street) }} + {{ form_errors(form.street) }} + {{ form_row(form.streetNumber) }} + {{ form_errors(form.streetNumber) }} {{ form_row(form.postCode) }} {{ form_errors(form.postCode) }} {{ form_row(form.validFrom) }} {{ form_errors(form.validFrom) }} - + - + {{ form_end(form) }} - -{% endblock personcontent %} \ No newline at end of file + +{% endblock personcontent %} diff --git a/src/Bundle/ChillPersonBundle/chill.webpack.config.js b/src/Bundle/ChillPersonBundle/chill.webpack.config.js index 9d7a33d02..7987ee124 100644 --- a/src/Bundle/ChillPersonBundle/chill.webpack.config.js +++ b/src/Bundle/ChillPersonBundle/chill.webpack.config.js @@ -7,6 +7,6 @@ module.exports = function(encore, entries) encore.addAliases({ ChillPersonAssets: __dirname + '/Resources/public' }); - + encore.addEntry('accompanying_course', __dirname + '/Resources/public/js/AccompanyingCourse/index.js'); }; diff --git a/src/Bundle/ChillPersonBundle/migrations/Version20210505093408.php b/src/Bundle/ChillPersonBundle/migrations/Version20210505093408.php new file mode 100644 index 000000000..cf5a93164 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/migrations/Version20210505093408.php @@ -0,0 +1,41 @@ +addSql('CREATE SEQUENCE Household_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); + $this->addSql('CREATE SEQUENCE HouseholdMembers_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); + $this->addSql('CREATE TABLE Household (id INT NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE TABLE HouseholdMembers (id INT NOT NULL, person_id INT DEFAULT NULL, household_id INT DEFAULT NULL, position VARCHAR(255) DEFAULT NULL, startDate DATE NOT NULL, endDate DATE NOT NULL, comment VARCHAR(255) DEFAULT NULL, sharedHousehold BOOLEAN NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE INDEX IDX_4D1FB288217BBB47 ON HouseholdMembers (person_id)'); + $this->addSql('CREATE INDEX IDX_4D1FB288E79FF843 ON HouseholdMembers (household_id)'); + $this->addSql('ALTER TABLE HouseholdMembers ADD CONSTRAINT FK_4D1FB288217BBB47 FOREIGN KEY (person_id) REFERENCES chill_person_person (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE HouseholdMembers ADD CONSTRAINT FK_4D1FB288E79FF843 FOREIGN KEY (household_id) REFERENCES Household (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE HouseholdMembers DROP CONSTRAINT FK_4D1FB288E79FF843'); + $this->addSql('ALTER TABLE HouseholdMembers DROP CONSTRAINT FK_4D1FB288217BBB47'); + $this->addSql('DROP SEQUENCE Household_id_seq CASCADE'); + $this->addSql('DROP SEQUENCE HouseholdMembers_id_seq CASCADE'); + $this->addSql('DROP TABLE Household'); + $this->addSql('DROP TABLE HouseholdMembers'); + } +} diff --git a/src/Bundle/ChillPersonBundle/migrations/Version20210505154316.php b/src/Bundle/ChillPersonBundle/migrations/Version20210505154316.php new file mode 100644 index 000000000..bb3a56337 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/migrations/Version20210505154316.php @@ -0,0 +1,33 @@ +addSql('CREATE TABLE chill_person_household_to_addresses (household_id INT NOT NULL, address_id INT NOT NULL, PRIMARY KEY(household_id, address_id))'); + $this->addSql('CREATE INDEX IDX_7109483E79FF843 ON chill_person_household_to_addresses (household_id)'); + $this->addSql('CREATE INDEX IDX_7109483F5B7AF75 ON chill_person_household_to_addresses (address_id)'); + $this->addSql('ALTER TABLE chill_person_household_to_addresses ADD CONSTRAINT FK_7109483E79FF843 FOREIGN KEY (household_id) REFERENCES Household (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE chill_person_household_to_addresses ADD CONSTRAINT FK_7109483F5B7AF75 FOREIGN KEY (address_id) REFERENCES chill_main_address (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + } + + public function down(Schema $schema): void + { + $this->addSql('DROP TABLE chill_person_household_to_addresses'); + } +}