mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Merge branch 'features/household' into 'master'
Manage household See merge request Chill-Projet/chill-bundles!70
This commit is contained in:
commit
6cbbce03c4
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\Migrations\Main;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Add extension btree_gist
|
||||
*/
|
||||
final class Version20210528090000 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'add extension btree_gist';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
$this->addSql('CREATE EXTENSION IF NOT EXISTS btree_gist');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$this->addSql('DROP EXTENSION btree_gist');
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\PersonBundle\Controller;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Serializer\Exception;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Chill\MainBundle\CRUD\Controller\ApiController;
|
||||
use Chill\PersonBundle\Household\MembersEditor;
|
||||
|
||||
class HouseholdMemberController extends ApiController
|
||||
{
|
||||
/**
|
||||
* @Route(
|
||||
* "/api/1.0/person/household/members/move.{_format}",
|
||||
* name="chill_person_household_members_move"
|
||||
* )
|
||||
*/
|
||||
public function move(Request $request, $_format): Response
|
||||
{
|
||||
try {
|
||||
$editor = $this->getSerializer()
|
||||
->deserialize($request->getContent(), MembersEditor::class,
|
||||
$_format, ['groups' => [ "read" ]]);
|
||||
} catch (Exception\InvalidArgumentException | Exception\UnexpectedValueException $e) {
|
||||
throw new BadRequestException("Deserialization error: {$e->getMessage()}", 45896, $e);
|
||||
}
|
||||
dump($editor);
|
||||
// TODO ACL
|
||||
//
|
||||
// TODO validation
|
||||
//
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
|
||||
// to ensure closing membership before creating one, we must manually open a transaction
|
||||
$em->beginTransaction();
|
||||
|
||||
foreach ($editor->getPersistable() as $el) {
|
||||
$em->persist($el);
|
||||
}
|
||||
|
||||
$em->flush();
|
||||
$em->commit();
|
||||
|
||||
|
||||
return $this->json($editor->getHousehold(), Response::HTTP_OK, ["groups" => ["read"]]);
|
||||
}
|
||||
}
|
126
src/Bundle/ChillPersonBundle/DataFixtures/ORM/LoadHousehold.php
Normal file
126
src/Bundle/ChillPersonBundle/DataFixtures/ORM/LoadHousehold.php
Normal file
@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\PersonBundle\DataFixtures\ORM;
|
||||
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Entity\Household\Household;
|
||||
use Chill\PersonBundle\Household\MembersEditorFactory;
|
||||
use Doctrine\Bundle\FixturesBundle\Fixture;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\Persistence\ObjectManager;
|
||||
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
|
||||
|
||||
class LoadHousehold extends Fixture implements DependentFixtureInterface
|
||||
{
|
||||
private MembersEditorFactory $editorFactory;
|
||||
|
||||
private EntityManagerInterface $em;
|
||||
|
||||
private CONST NUMBER_OF_HOUSEHOLD = 10;
|
||||
|
||||
public function __construct(MembersEditorFactory $editorFactory, EntityManagerInterface $em)
|
||||
{
|
||||
$this->editorFactory = $editorFactory;
|
||||
$this->em = $em;
|
||||
}
|
||||
|
||||
public function load(ObjectManager $manager)
|
||||
{
|
||||
// generate two times the participation. This will lead to
|
||||
// some movement in participation (same people in two differents
|
||||
// households)
|
||||
|
||||
$this->preparePersonIds();
|
||||
|
||||
$this->generateHousehold(
|
||||
$manager,
|
||||
\DateTimeImmutable::createFromFormat('Y-m-d', '2010-01-01')
|
||||
);
|
||||
|
||||
$this->preparePersonIds();
|
||||
|
||||
$this->generateHousehold(
|
||||
$manager,
|
||||
\DateTimeImmutable::createFromFormat('Y-m-d', '2015-01-01')
|
||||
);
|
||||
|
||||
$manager->flush();
|
||||
}
|
||||
|
||||
private function generateHousehold(ObjectManager $manager, \DateTimeImmutable $startDate)
|
||||
{
|
||||
for ($i=0; $i < self::NUMBER_OF_HOUSEHOLD; $i++) {
|
||||
$household = new Household();
|
||||
$manager->persist($household);
|
||||
|
||||
$movement = $this->editorFactory->createEditor($household);
|
||||
|
||||
// load adults
|
||||
$k = 0;
|
||||
foreach ($this->getRandomPersons(1, 3) as $person) {
|
||||
$date = $startDate->add(new \DateInterval('P'.\random_int(1, 200).'W'));
|
||||
$position = $this->getReference(LoadHouseholdPosition::ADULT);
|
||||
|
||||
$movement->addMovement($date, $person, $position, $k === 0, "self generated");
|
||||
$k++;
|
||||
}
|
||||
|
||||
// load children
|
||||
foreach ($this->getRandomPersons(0, 3) as $person) {
|
||||
$date = $startDate->add(new \DateInterval('P'.\random_int(1, 200).'W'));
|
||||
$position = $this->getReference(LoadHouseholdPosition::CHILD);
|
||||
|
||||
$movement->addMovement($date, $person, $position, $k === 0, "self generated");
|
||||
$k++;
|
||||
}
|
||||
|
||||
// load children out
|
||||
foreach ($this->getRandomPersons(0, 2) as $person) {
|
||||
$date = $startDate->add(new \DateInterval('P'.\random_int(1, 200).'W'));
|
||||
$position = $this->getReference(LoadHouseholdPosition::CHILD_OUT);
|
||||
|
||||
$movement->addMovement($date, $person, $position, $k === 0, "self generated");
|
||||
$k++;
|
||||
}
|
||||
|
||||
foreach ($movement->getPersistable() as $obj) {
|
||||
$manager->persist($obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function preparePersonIds()
|
||||
{
|
||||
$this->personIds = $this->em
|
||||
->createQuery('SELECT p.id FROM '.Person::class.' p '.
|
||||
'JOIN p.center c '.
|
||||
'WHERE c.name = :center '
|
||||
)
|
||||
->setParameter('center', 'Center A')
|
||||
->getScalarResult()
|
||||
;
|
||||
\shuffle($this->personIds);
|
||||
}
|
||||
|
||||
private function getRandomPersons(int $min, int $max)
|
||||
{
|
||||
$nb = \random_int($min, $max);
|
||||
|
||||
for ($i=0; $i < $nb; $i++) {
|
||||
$personId = \array_pop($this->personIds)['id'];
|
||||
$persons[] = $this->em->getRepository(Person::class)
|
||||
->find($personId)
|
||||
;
|
||||
}
|
||||
|
||||
return $persons ?? [];
|
||||
}
|
||||
|
||||
public function getDependencies()
|
||||
{
|
||||
return [
|
||||
LoadPeople::class,
|
||||
LoadHouseholdPosition::class
|
||||
];
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\PersonBundle\DataFixtures\ORM;
|
||||
|
||||
use Chill\PersonBundle\Entity\Household\Position;
|
||||
use Doctrine\Bundle\FixturesBundle\Fixture;
|
||||
use Doctrine\Persistence\ObjectManager;
|
||||
|
||||
class LoadHouseholdPosition extends Fixture
|
||||
{
|
||||
const POSITIONS_DATA = [
|
||||
["Adulte", true, true, 1.0, self::ADULT ],
|
||||
["Enfants", true, false, 2.0, self::CHILD ],
|
||||
["Enfants hors ménage", false, false, 3.0, self::CHILD_OUT ]
|
||||
];
|
||||
|
||||
const ADULT = "position_adulte";
|
||||
const CHILD = "position_enfant";
|
||||
const CHILD_OUT = "position_enfant_hors";
|
||||
|
||||
public function load(ObjectManager $manager)
|
||||
{
|
||||
foreach (self::POSITIONS_DATA as list($name, $share, $allowHolder,
|
||||
$ordering, $ref)) {
|
||||
$position = (new Position())
|
||||
->setLabel([ "fr" => $name ])
|
||||
->setAllowHolder($allowHolder)
|
||||
->setShareHousehold($share)
|
||||
->setOrdering($ordering)
|
||||
;
|
||||
|
||||
$manager->persist($position);
|
||||
$this->addReference($ref, $position);
|
||||
}
|
||||
|
||||
$manager->flush();
|
||||
}
|
||||
}
|
@ -74,6 +74,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
|
||||
$loader->load('services/form.yaml');
|
||||
$loader->load('services/templating.yaml');
|
||||
$loader->load('services/alt_names.yaml');
|
||||
$loader->load('services/household.yaml');
|
||||
// We can get rid of this file when the service 'chill.person.repository.person' is no more used.
|
||||
// We should use the PersonRepository service instead of a custom service name.
|
||||
$loader->load('services/repository.yaml');
|
||||
|
@ -5,9 +5,16 @@ namespace Chill\PersonBundle\Entity\Household;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Chill\MainBundle\Entity\Address;
|
||||
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
* @ORM\Table(
|
||||
* name="chill_person_household"
|
||||
* )
|
||||
* @Serializer\DiscriminatorMap(typeProperty="type", mapping={
|
||||
* "household"=Household::class
|
||||
* })
|
||||
*/
|
||||
class Household
|
||||
{
|
||||
@ -15,6 +22,7 @@ class Household
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue
|
||||
* @ORM\Column(type="integer")
|
||||
* @Serializer\Groups({"read"})
|
||||
*/
|
||||
private $id;
|
||||
|
||||
|
@ -0,0 +1,186 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\PersonBundle\Entity\Household;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Entity\Household\Household;
|
||||
use Chill\PersonBundle\Entity\Household\Position;
|
||||
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
* @ORM\Table(
|
||||
* name="chill_person_household_members"
|
||||
* )
|
||||
*/
|
||||
class HouseholdMember
|
||||
{
|
||||
/**
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity=Position::class)
|
||||
*/
|
||||
private ?Position $position = null;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="date_immutable", nullable=true, options={"default": null})
|
||||
*/
|
||||
private ?\DateTimeImmutable $startDate = null;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="date_immutable", nullable= true, options={"default": null})
|
||||
*/
|
||||
private ?\DateTimeImmutable $endDate = null;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=255, nullable=true)
|
||||
*/
|
||||
private ?string $comment = NULL;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="boolean")
|
||||
*/
|
||||
private bool $sharedHousehold = false;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="boolean", options={"default": false})
|
||||
*/
|
||||
private bool $holder = false;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Person
|
||||
* @ORM\ManyToOne(
|
||||
* targetEntity="\Chill\PersonBundle\Entity\Person"
|
||||
* )
|
||||
*/
|
||||
private ?Person $person = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Household
|
||||
* @ORM\ManyToOne(
|
||||
* targetEntity="\Chill\PersonBundle\Entity\Household\Household"
|
||||
* )
|
||||
*/
|
||||
private ?Household $household = null;
|
||||
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getPosition(): ?Position
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
public function setPosition(Position $position): self
|
||||
{
|
||||
if ($this->position instanceof Position) {
|
||||
throw new \LogicException("The position is already set. You cannot change ".
|
||||
"a position of a membership");
|
||||
}
|
||||
|
||||
$this->position = $position;
|
||||
$this->sharedHousehold = $position->getShareHousehold();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getStartDate(): ?\DateTimeImmutable
|
||||
{
|
||||
return $this->startDate;
|
||||
}
|
||||
|
||||
public function setStartDate(\DateTimeImmutable $startDate): self
|
||||
{
|
||||
$this->startDate = $startDate;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getEndDate(): ?\DateTimeImmutable
|
||||
{
|
||||
return $this->endDate;
|
||||
}
|
||||
|
||||
public function setEndDate(\DateTimeImmutable $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 getShareHousehold(): ?bool
|
||||
{
|
||||
return $this->sharedHousehold;
|
||||
}
|
||||
|
||||
|
||||
public function getPerson(): ?Person
|
||||
{
|
||||
return $this->person;
|
||||
}
|
||||
|
||||
public function setPerson(?Person $person): self
|
||||
{
|
||||
if ($this->person instanceof Person) {
|
||||
throw new \LogicException("You cannot change person ".
|
||||
"on a membership");
|
||||
}
|
||||
|
||||
$this->person = $person;
|
||||
$this->person->addHouseholdParticipation($this);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getHousehold(): ?Household
|
||||
{
|
||||
return $this->household;
|
||||
}
|
||||
|
||||
public function setHousehold(?Household $household): self
|
||||
{
|
||||
if ($this->household instanceof Household) {
|
||||
throw new \LogicException("You cannot change household ".
|
||||
"on a membership");
|
||||
}
|
||||
|
||||
$this->household = $household;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setHolder(bool $holder): self
|
||||
{
|
||||
$this->holder = $holder;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isHolder(): bool
|
||||
{
|
||||
return $this->holder;
|
||||
}
|
||||
}
|
@ -1,152 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\PersonBundle\Entity\Household;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Entity\Household\Household;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
*/
|
||||
class HouseholdMembers
|
||||
{
|
||||
/**
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=255, nullable=true)
|
||||
*/
|
||||
private $position;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="date")
|
||||
*/
|
||||
private $startDate;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="date")
|
||||
*/
|
||||
private $endDate;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=255, nullable=true)
|
||||
*/
|
||||
private $comment;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="boolean")
|
||||
*/
|
||||
private $sharedHousehold;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Person
|
||||
* @ORM\ManyToOne(
|
||||
* targetEntity="\Chill\PersonBundle\Entity\Person"
|
||||
* )
|
||||
*/
|
||||
private $person;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Household
|
||||
* @ORM\ManyToOne(
|
||||
* targetEntity="\Chill\PersonBundle\Entity\Household\Household"
|
||||
* )
|
||||
*/
|
||||
private $household;
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->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;
|
||||
}
|
||||
}
|
98
src/Bundle/ChillPersonBundle/Entity/Household/Position.php
Normal file
98
src/Bundle/ChillPersonBundle/Entity/Household/Position.php
Normal file
@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\PersonBundle\Entity\Household;
|
||||
|
||||
use Chill\PersonBundle\Repository\Household\PositionRepository;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||
|
||||
/**
|
||||
* @ORM\Entity(repositoryClass=PositionRepository::class)
|
||||
* @ORM\Table(name="chill_person_household_position")
|
||||
* @Serializer\DiscriminatorMap(typeProperty="type", mapping={
|
||||
* "household_position"=Position::class
|
||||
* })
|
||||
*/
|
||||
class Position
|
||||
{
|
||||
/**
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue
|
||||
* @ORM\Column(type="integer")
|
||||
* @Serializer\Groups({ "read" })
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="json")
|
||||
*/
|
||||
private $label = [];
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="boolean")
|
||||
*/
|
||||
private $shareHouseHold;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="boolean")
|
||||
*/
|
||||
private $allowHolder;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="float")
|
||||
*/
|
||||
private $ordering;
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getLabel(): ?array
|
||||
{
|
||||
return $this->label;
|
||||
}
|
||||
|
||||
public function setLabel(array $label): self
|
||||
{
|
||||
$this->label = $label;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getShareHousehold(): ?bool
|
||||
{
|
||||
return $this->shareHouseHold;
|
||||
}
|
||||
|
||||
public function setShareHousehold(bool $shareHouseHold): self
|
||||
{
|
||||
$this->shareHouseHold = $shareHouseHold;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getAllowHolder(): ?bool
|
||||
{
|
||||
return $this->allowHolder;
|
||||
}
|
||||
|
||||
public function setAllowHolder(bool $allowHolder): self
|
||||
{
|
||||
$this->allowHolder = $allowHolder;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getOrdering(): ?float
|
||||
{
|
||||
return $this->ordering;
|
||||
}
|
||||
|
||||
public function setOrdering(float $ordering): self
|
||||
{
|
||||
$this->ordering = $ordering;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -26,6 +26,7 @@ use ArrayIterator;
|
||||
use Chill\MainBundle\Entity\Center;
|
||||
use Chill\MainBundle\Entity\Country;
|
||||
use Chill\PersonBundle\Entity\MaritalStatus;
|
||||
use Chill\PersonBundle\Entity\Household\HouseholdMember;
|
||||
use Chill\MainBundle\Entity\HasCenterInterface;
|
||||
use Chill\MainBundle\Entity\Address;
|
||||
use DateTime;
|
||||
@ -272,6 +273,14 @@ class Person implements HasCenterInterface
|
||||
*/
|
||||
private $fullnameCanonical;
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(
|
||||
* targetEntity=HouseholdMember::class,
|
||||
* mappedBy="person"
|
||||
* )
|
||||
*/
|
||||
private Collection $householdParticipations;
|
||||
|
||||
/**
|
||||
* Person constructor.
|
||||
*
|
||||
@ -284,6 +293,7 @@ class Person implements HasCenterInterface
|
||||
$this->addresses = new ArrayCollection();
|
||||
$this->altNames = new ArrayCollection();
|
||||
$this->otherPhoneNumbers = new ArrayCollection();
|
||||
$this->householdParticipations = new ArrayCollection();
|
||||
|
||||
if ($opening === null) {
|
||||
$opening = new \DateTime();
|
||||
@ -1180,4 +1190,16 @@ class Person implements HasCenterInterface
|
||||
$this->fullnameCanonical = $fullnameCanonical;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addHouseholdParticipation(HouseholdMember $member): self
|
||||
{
|
||||
$this->householdParticipations[] = $member;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getHouseholdParticipations(): Collection
|
||||
{
|
||||
return $this->householdParticipations;
|
||||
}
|
||||
}
|
||||
|
79
src/Bundle/ChillPersonBundle/Household/MembersEditor.php
Normal file
79
src/Bundle/ChillPersonBundle/Household/MembersEditor.php
Normal file
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\PersonBundle\Household;
|
||||
|
||||
use Symfony\Component\Validator\ConstraintViolationListInterface;
|
||||
use Chill\PersonBundle\Entity\Household\HouseholdMember;
|
||||
use Chill\PersonBundle\Entity\Household\Position;
|
||||
use Chill\PersonBundle\Entity\Household\Household;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
||||
|
||||
|
||||
class MembersEditor
|
||||
{
|
||||
private ValidatorInterface $validator;
|
||||
private Household $household;
|
||||
|
||||
private array $persistables = [];
|
||||
private array $membershipsAffected = [];
|
||||
|
||||
public function __construct(ValidatorInterface $validator, Household $household)
|
||||
{
|
||||
$this->validation = $validator;
|
||||
$this->household = $household;
|
||||
}
|
||||
|
||||
public function addMovement(\DateTimeImmutable $date, Person $person, Position $position, ?bool $holder = false, ?string $comment = null): self
|
||||
{
|
||||
if (NULL === $this->household) {
|
||||
throw new \LogicException("You must define a household first");
|
||||
}
|
||||
|
||||
$membership = (new HouseholdMember())
|
||||
->setStartDate($date)
|
||||
->setPerson($person)
|
||||
->setPosition($position)
|
||||
->setHolder($holder)
|
||||
->setHousehold($this->household)
|
||||
->setComment($comment)
|
||||
;
|
||||
|
||||
if ($position->getShareHousehold()) {
|
||||
foreach ($person->getHouseholdParticipations() as $participation) {
|
||||
if (FALSE === $participation->getShareHousehold()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($participation === $membership) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($participation->getEndDate() === NULL || $participation->getEndDate() > $date) {
|
||||
$participation->setEndDate($date);
|
||||
$this->membershipsAffected[] = $participation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->membershipsAffected[] = $membership;
|
||||
$this->persistables[] = $membership;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function validate(): ConstraintViolationListInterface
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function getPersistable(): array
|
||||
{
|
||||
return $this->persistables;
|
||||
}
|
||||
|
||||
public function getHousehold(): Household
|
||||
{
|
||||
return $this->household;
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\PersonBundle\Household;
|
||||
|
||||
use Chill\PersonBundle\Household\MembersEditor;
|
||||
use Chill\PersonBundle\Entity\Household\Household;
|
||||
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
||||
|
||||
|
||||
class MembersEditorFactory
|
||||
{
|
||||
public function __construct(ValidatorInterface $validator)
|
||||
{
|
||||
$this->validator = $validator;
|
||||
}
|
||||
|
||||
public function createEditor(Household $household): MembersEditor
|
||||
{
|
||||
return new MembersEditor($this->validator, $household);
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\PersonBundle\Repository\Household;
|
||||
|
||||
use Chill\PersonBundle\Entity\Household\Position;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @method Position|null find($id, $lockMode = null, $lockVersion = null)
|
||||
* @method Position|null findOneBy(array $criteria, array $orderBy = null)
|
||||
* @method Position[] findAll()
|
||||
* @method Position[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
|
||||
*/
|
||||
class PositionRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, Position::class);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\PersonBundle\Serializer\Normalizer;
|
||||
|
||||
use Chill\PersonBundle\Entity\Household\Position;
|
||||
use Chill\PersonBundle\Entity\Household\Household;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\DenormalizerAwareTrait;
|
||||
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
||||
use Symfony\Component\Serializer\Exception;
|
||||
use Chill\PersonBundle\Household\MembersEditorFactory;
|
||||
use Chill\PersonBundle\Household\MembersEditor;
|
||||
|
||||
class MembersEditorNormalizer implements DenormalizerInterface, DenormalizerAwareInterface
|
||||
{
|
||||
private MembersEditorFactory $factory;
|
||||
|
||||
use DenormalizerAwareTrait;
|
||||
|
||||
public function __construct(MembersEditorFactory $factory)
|
||||
{
|
||||
$this->factory = $factory;
|
||||
}
|
||||
|
||||
public function denormalize($data, string $type, string $format = null, array $context = [])
|
||||
{
|
||||
$household = $this->denormalizer->denormalize($data['destination'], Household::class,
|
||||
$format, $context);
|
||||
|
||||
if (NULL === $household) {
|
||||
throw new Exception\InvalidArgumentException("household could not be denormalized. Impossible to process");
|
||||
}
|
||||
|
||||
$editor = $this->factory->createEditor($household);
|
||||
|
||||
if (NULL == $data['concerned'] ?? []
|
||||
&& FALSE === ·\is_array('concerned')) {
|
||||
throw new Exception\UnexpectedValueException("The schema does not have any key 'concerned'");
|
||||
}
|
||||
|
||||
foreach ($data['concerned'] as $key => $concerned) {
|
||||
$person = $this->denormalizer->denormalize($concerned['person'] ?? null, Person::class,
|
||||
$format, $context);
|
||||
$position = $this->denormalizer->denormalize($concerned['position'] ?? null, Position::class,
|
||||
$format, $context);
|
||||
$startDate = $this->denormalizer->denormalize($concerned['start_date'] ?? null, \DateTimeImmutable::class,
|
||||
$format, $context);
|
||||
|
||||
$holder = (bool) $concerned['holder'] ?? false;
|
||||
$comment = (string) $concerned['comment'] ?? false;
|
||||
|
||||
if (
|
||||
NULL === $person
|
||||
&& NULL === $position
|
||||
&& NULL === $startDate
|
||||
) {
|
||||
throw new Exception\InvalidArgumentException("position with ".
|
||||
"key $key could not be denormalized: missing ".
|
||||
"person, position or start_date.");
|
||||
}
|
||||
|
||||
$editor->addMovement($startDate, $person, $position, $holder,
|
||||
$comment);
|
||||
|
||||
return $editor;
|
||||
}
|
||||
}
|
||||
|
||||
public function supportsDenormalization($data, string $type, string $format = null)
|
||||
{
|
||||
return $type === MembersEditor::class;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace Bundle\ChillPersonBundle\Tests\Controller;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Chill\MainBundle\Test\PrepareClientTrait;
|
||||
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Entity\Household\Household;
|
||||
use Chill\PersonBundle\Entity\Household\Position;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
|
||||
class HouseholdMemberControllerTest extends WebTestCase
|
||||
{
|
||||
use PrepareClientTrait;
|
||||
|
||||
/**
|
||||
* @dataProvider provideValidData
|
||||
*/
|
||||
public function testMoveMember($personId, $householdId, $positionId, \DateTimeInterface $date)
|
||||
{
|
||||
$client = $this->getClientAuthenticated();
|
||||
|
||||
$client->request(
|
||||
Request::METHOD_POST,
|
||||
'/api/1.0/person/household/members/move.json',
|
||||
[], // parameters
|
||||
[], // files
|
||||
[], // server
|
||||
\json_encode(
|
||||
[
|
||||
'concerned' =>
|
||||
[
|
||||
[
|
||||
'person' =>
|
||||
[
|
||||
'type' => 'person',
|
||||
'id' => $personId
|
||||
],
|
||||
'start_date' =>
|
||||
[
|
||||
'datetime' => $date->format(\DateTimeInterface::RFC3339)
|
||||
],
|
||||
'position' =>
|
||||
[
|
||||
'type' => 'household_position',
|
||||
'id' => $positionId
|
||||
],
|
||||
'holder' => false,
|
||||
'comment' => "Introduced by automated test",
|
||||
],
|
||||
],
|
||||
'destination' =>
|
||||
[
|
||||
'type' => 'household',
|
||||
'id' => $householdId
|
||||
]
|
||||
],
|
||||
true)
|
||||
);
|
||||
|
||||
$this->assertEquals(Response::HTTP_OK,
|
||||
$client->getResponse()->getStatusCode()
|
||||
);
|
||||
}
|
||||
|
||||
public function provideValidData(): \Iterator
|
||||
{
|
||||
self::bootKernel();
|
||||
$em = self::$container->get(EntityManagerInterface::class);
|
||||
|
||||
$personIds = $em->createQuery("SELECT p.id FROM ".Person::class." p ".
|
||||
"JOIN p.center c WHERE c.name = :center")
|
||||
->setParameter('center', "Center A")
|
||||
->setMaxResults(100)
|
||||
->getScalarResult()
|
||||
;
|
||||
\shuffle($personIds);
|
||||
|
||||
$household = new Household();
|
||||
$em->persist($household);
|
||||
$em->flush();
|
||||
|
||||
$positions = $em->createQuery("SELECT pos.id FROM ".Position::class." pos ".
|
||||
"WHERE pos.shareHouseHold = TRUE")
|
||||
->getResult()
|
||||
;
|
||||
|
||||
yield [
|
||||
\array_pop($personIds)['id'],
|
||||
$household->getId(),
|
||||
$positions[\random_int(0, count($positions) - 1)]['id'],
|
||||
new \DateTimeImmutable('today')
|
||||
];
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Bundle\ChillPersonBundle\Tests\Entity\Household;
|
||||
|
||||
use Chill\PersonBundle\Entity\Household\HouseholdMember;
|
||||
use Chill\PersonBundle\Entity\Household\Position;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class HouseholdMemberTest extends TestCase
|
||||
{
|
||||
public function testPositionSharehousehold()
|
||||
{
|
||||
$position = (new Position())
|
||||
->setShareHousehold(true)
|
||||
;
|
||||
$membership = (new HouseholdMember())
|
||||
->setPosition($position)
|
||||
;
|
||||
|
||||
$this->assertTrue($membership->getShareHousehold());
|
||||
}
|
||||
|
||||
public function testPositionDoNotSharehousehold()
|
||||
{
|
||||
$position = (new Position())
|
||||
->setShareHousehold(false)
|
||||
;
|
||||
$membership = (new HouseholdMember())
|
||||
->setPosition($position)
|
||||
;
|
||||
|
||||
$this->assertFalse($membership->getShareHousehold());
|
||||
}
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\PersonBundle\Tests\Household;
|
||||
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Entity\Household\Household;
|
||||
use Chill\PersonBundle\Entity\Household\Position;
|
||||
use Chill\PersonBundle\Household\MembersEditorFactory;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
|
||||
class MembersEditorTest extends TestCase
|
||||
{
|
||||
private MembersEditorFactory $factory;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$validator = $this->createMock(ValidatorInterface::class);
|
||||
|
||||
$this->factory = new MembersEditorFactory($validator);
|
||||
}
|
||||
|
||||
public function testMovePersonWithSharedHousehold()
|
||||
{
|
||||
$person = new Person();
|
||||
$position = (new Position())
|
||||
->setShareHousehold(true)
|
||||
;
|
||||
$household1 = new Household();
|
||||
$household2 = new Household();
|
||||
$editor = $this->factory->createEditor($household1);
|
||||
|
||||
$editor->addMovement(
|
||||
\DateTimeImmutable::createFromFormat('Y-m-d', '2020-01-01'),
|
||||
$person,
|
||||
$position);
|
||||
|
||||
$persistables = $editor->getPersistable();
|
||||
$this->assertEquals(\count($persistables), 1);
|
||||
|
||||
$membership1 = $persistables[0];
|
||||
$this->assertSame($household1, $membership1->getHousehold());
|
||||
$this->assertNull($membership1->getEndDate());
|
||||
|
||||
// move to another household
|
||||
$date = \DateTimeImmutable::createFromFormat('Y-m-d', '2021-01-01');
|
||||
$editor = $this->factory->createEditor($household2);
|
||||
$editor->addMovement(
|
||||
$date,
|
||||
$person,
|
||||
$position);
|
||||
|
||||
$persistables = $editor->getPersistable();
|
||||
$this->assertEquals(1, count($persistables));
|
||||
|
||||
$membership2 = $persistables[0];
|
||||
$this->assertSame($household2, $membership2->getHousehold());
|
||||
$this->assertNull($membership2->getEndDate());
|
||||
$this->assertNotNull($membership1->getEndDate(),
|
||||
"assert that the membership1 is closed");
|
||||
$this->assertEquals($date, $membership1->getEndDate());
|
||||
}
|
||||
|
||||
public function testMovePersonWithoutSharedHousehold()
|
||||
{
|
||||
$person = new Person();
|
||||
$position = (new Position())
|
||||
->setShareHousehold(false)
|
||||
;
|
||||
$household1 = new Household();
|
||||
$household2 = new Household();
|
||||
$editor = $this->factory->createEditor($household1);
|
||||
|
||||
$editor->addMovement(
|
||||
\DateTimeImmutable::createFromFormat('Y-m-d', '2020-01-01'),
|
||||
$person,
|
||||
$position);
|
||||
|
||||
$persistables = $editor->getPersistable();
|
||||
$this->assertEquals(1, count($persistables));
|
||||
|
||||
$membership1 = $person->getHouseholdParticipations()->first();
|
||||
$this->assertSame($household1, $membership1->getHousehold());
|
||||
$this->assertNull($membership1->getEndDate());
|
||||
|
||||
// move to another household
|
||||
$date = \DateTimeImmutable::createFromFormat('Y-m-d', '2021-01-01');
|
||||
$editor = $this->factory->createEditor($household2);
|
||||
$editor->addMovement(
|
||||
$date,
|
||||
$person,
|
||||
$position);
|
||||
|
||||
$persistables = $editor->getPersistable();
|
||||
$this->assertEquals(1, count($persistables));
|
||||
|
||||
$membership2 = $person->getHouseholdParticipations()->last();
|
||||
$this->assertNull($membership2->getEndDate());
|
||||
$this->assertSame($household2, $membership2->getHousehold());
|
||||
$this->assertNull($membership1->getEndDate(),
|
||||
"assert that the membership1 is not closed");
|
||||
}
|
||||
}
|
@ -192,6 +192,25 @@ components:
|
||||
text:
|
||||
type: string
|
||||
readOnly: true
|
||||
Household:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
type:
|
||||
type: string
|
||||
enum:
|
||||
- 'household'
|
||||
HouseholdPosition:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
type:
|
||||
type: string
|
||||
enum:
|
||||
- 'household_position'
|
||||
|
||||
|
||||
paths:
|
||||
/1.0/person/person/{id}.json:
|
||||
@ -764,3 +783,46 @@ paths:
|
||||
description: "OK"
|
||||
400:
|
||||
description: "transition cannot be applyed"
|
||||
|
||||
/1.0/person/household/members/move.json:
|
||||
post:
|
||||
tags:
|
||||
- household
|
||||
summary: move one or multiple person from a household to another
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
concerned:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
person:
|
||||
$ref: '#/components/schemas/PersonById'
|
||||
start_date:
|
||||
$ref: '#/components/schemas/Date'
|
||||
position:
|
||||
$ref: '#/components/schemas/HouseholdPosition'
|
||||
holder:
|
||||
type: boolean
|
||||
comment:
|
||||
type: string
|
||||
destination:
|
||||
oneOf:
|
||||
- $ref: '#/components/schemas/Household'
|
||||
responses:
|
||||
401:
|
||||
description: "Unauthorized"
|
||||
404:
|
||||
description: "Not found"
|
||||
200:
|
||||
description: "OK"
|
||||
422:
|
||||
description: "Unprocessable entity (validation errors)"
|
||||
400:
|
||||
description: "transition cannot be applyed"
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
services:
|
||||
Chill\PersonBundle\DataFixtures\ORM\:
|
||||
autowire: true
|
||||
resource: ../../DataFixtures/ORM
|
||||
tags: [ 'doctrine.fixture.orm' ]
|
||||
|
||||
|
@ -0,0 +1,3 @@
|
||||
services:
|
||||
Chill\PersonBundle\Household\MembersEditorFactory:
|
||||
autowire: true
|
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\Migrations\Person;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* prefix table concerning household with 'chill_person' and add constraints
|
||||
*/
|
||||
final class Version20210528092625 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'prefix table concerning household with \'chill_person\' and add constraints';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// we need to rename constraint, drop them first, recreate them after
|
||||
$this->addSql('ALTER TABLE householdmembers DROP CONSTRAINT fk_4d1fb288e79ff843');
|
||||
$this->addSql('ALTER TABLE householdmembers DROP CONSTRAINT fk_4d1fb288217bbb47');
|
||||
|
||||
// rename tables
|
||||
$this->addSql('ALTER TABLE householdmembers RENAME TO chill_person_household_members');
|
||||
$this->addSql('ALTER TABLE household RENAME TO chill_person_household');
|
||||
|
||||
// rename sequences
|
||||
$this->addSql('ALTER SEQUENCE household_id_seq RENAME TO chill_person_household_id_seq');
|
||||
$this->addSql('ALTER SEQUENCE householdmembers_id_seq RENAME TO chill_person_household_members_id_seq');
|
||||
|
||||
// recreate constraints
|
||||
$this->addSql('ALTER TABLE chill_person_household_members ADD CONSTRAINT FK_EEF5DED7217BBB47 FOREIGN KEY (person_id) REFERENCES chill_person_person (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||
$this->addSql('ALTER TABLE chill_person_household_members ADD CONSTRAINT FK_EEF5DED7E79FF843 FOREIGN KEY (household_id) REFERENCES chill_person_household (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||
|
||||
// create constraint 'householdmembers not overlaps'
|
||||
$this->addSql('ALTER TABLE chill_person_household_members ADD CHECK (startdate < enddate)');
|
||||
$this->addSql('ALTER TABLE chill_person_household_members ADD CONSTRAINT '.
|
||||
"household_members_not_overlaps EXCLUDE USING GIST(
|
||||
-- extension btree_gist required to include comparaison with integer
|
||||
person_id WITH =,
|
||||
daterange(startdate, enddate) WITH &&
|
||||
) WHERE (sharedhousehold IS TRUE)
|
||||
INITIALLY DEFERRED");
|
||||
|
||||
// rename constraints
|
||||
$this->addSql('ALTER TABLE public.chill_person_household_to_addresses DROP CONSTRAINT fk_7109483e79ff843');
|
||||
$this->addSql('ALTER TABLE chill_person_household_to_addresses ADD CONSTRAINT FK_C28AF063E79FF843 FOREIGN KEY (household_id) REFERENCES chill_person_household (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||
|
||||
// rename indexes
|
||||
$this->addSql('ALTER INDEX idx_7109483e79ff843 RENAME TO IDX_C28AF063E79FF843');
|
||||
$this->addSql('ALTER INDEX idx_7109483f5b7af75 RENAME TO IDX_C28AF063F5B7AF75');
|
||||
$this->addSql('ALTER INDEX idx_4d1fb288e79ff843 RENAME TO IDX_EEF5DED7E79FF843');
|
||||
$this->addSql('ALTER INDEX idx_4d1fb288217bbb47 RENAME TO IDX_EEF5DED7217BBB47');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$this->throwIrreversibleMigrationException("the down method is not implemented");
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\Migrations\Person;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Add position to househould_member
|
||||
*/
|
||||
final class Version20210528111624 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Add position to househould_member';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
$this->addSql('CREATE SEQUENCE chill_person_household_position_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
|
||||
$this->addSql('CREATE TABLE chill_person_household_position (id INT NOT NULL, label JSON NOT NULL, shareHouseHold BOOLEAN NOT NULL, allowHolder BOOLEAN NOT NULL, ordering DOUBLE PRECISION NOT NULL, PRIMARY KEY(id))');
|
||||
|
||||
$this->addSql('ALTER TABLE chill_person_household_members ADD position_id INT DEFAULT NULL');
|
||||
$this->addSql('ALTER TABLE chill_person_household_members DROP "position"');
|
||||
$this->addSql('ALTER TABLE chill_person_household_members ADD CONSTRAINT FK_EEF5DED7DD842E46 FOREIGN KEY (position_id) REFERENCES chill_person_household_position (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||
$this->addSql('CREATE INDEX IDX_EEF5DED7DD842E46 ON chill_person_household_members (position_id)');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE chill_person_household_members DROP CONSTRAINT FK_EEF5DED7DD842E46');
|
||||
$this->addSql('DROP SEQUENCE chill_person_household_position_id_seq CASCADE');
|
||||
$this->addSql('DROP TABLE chill_person_household_position');
|
||||
$this->addSql('ALTER TABLE chill_person_household_members ADD "position" VARCHAR(255) DEFAULT NULL');
|
||||
$this->addSql('ALTER TABLE chill_person_household_members DROP position_id');
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\Migrations\Person;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Household members: allow startdate and enddate to be null
|
||||
*/
|
||||
final class Version20210528132405 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Household members: allow startdate and enddate to be null';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE chill_person_household_members ALTER startdate DROP NOT NULL');
|
||||
$this->addSql('ALTER TABLE chill_person_household_members ALTER enddate DROP NOT NULL');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE chill_person_household_members ALTER startDate SET NOT NULL');
|
||||
$this->addSql('ALTER TABLE chill_person_household_members ALTER endDate SET NOT NULL');
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\Migrations\Person;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Add house holder on membership
|
||||
*/
|
||||
final class Version20210528142121 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Add house holder on membership';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE chill_person_household_members ADD holder BOOLEAN DEFAULT FALSE NOT NULL');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE chill_person_household_members DROP COLUMN holder');
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user