addresses = new ArrayCollection(); $this->members = new ArrayCollection(); $this->commentMembers = new CommentEmbeddable(); } public function getId(): ?int { return $this->id; } /** * @param Address $address * @return $this */ public function addAddress(Address $address) { foreach ($this->getAddresses() as $a) { if ($a->getValidFrom() < $address->getValidFrom() && $a->getValidTo() === NULL) { $a->setValidTo($address->getValidFrom()); } } $this->addresses[] = $address; return $this; } /** * Force an address starting at the current day * on the Household. * * This will force the startDate's address on today. * * Used on household creation. * * @Serializer\Groups({"create"}) */ public function setForceAddress(Address $address) { $address->setValidFrom(new \DateTime('today')); $this->addAddress($address); } /** * @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) * * @Assert\Callback(methods={"validate"}) * @return \Chill\MainBundle\Entity\Address[] */ public function getAddresses() { return $this->addresses; } /** * @Serializer\Groups({ "read" }) * @Serializer\SerializedName("current_address") */ public function getCurrentAddress(\DateTime $at = null): ?Address { $at = $at === null ? new \DateTime('today') : $at; $addrs = $this->getAddresses()->filter(function (Address $a) use ($at) { return $a->getValidFrom() <= $at && ( NULL === $a->getValidTo() || $at < $a->getValidTo() ); }); if ($addrs->count() > 0) { return $addrs->first(); } else { return null; } } /** * @return Collection|HouseholdMember[] */ public function getMembers(): Collection { return $this->members; } public function getMembersOnRange(\DateTimeImmutable $from, ?\DateTimeImmutable $to): Collection { $criteria = new Criteria(); $expr = Criteria::expr(); $criteria->where( $expr->gte('startDate', $from) ); if (NULL !== $to) { $criteria->andWhere( $expr->orX( $expr->lte('endDate', $to), $expr->eq('endDate', NULL) ), ); } return $this->getMembers() ->matching($criteria) ; } public function getMembersDuringMembership(HouseholdMember $membership) { return $this->getMembersOnRange( $membership->getStartDate(), $membership->getEndDate() )->filter( function(HouseholdMember $m) use ($membership) { return $m !== $membership; } ); } public function getMembersHolder(): Collection { $criteria = new Criteria(); $expr = Criteria::expr(); $criteria->where( $expr->eq('holder', true) ); return $this->getMembers()->matching($criteria); } public function getCurrentMembers(?\DateTimeImmutable $now = null): Collection { return $this->getMembers()->matching($this->buildCriteriaCurrentMembers($now)); } private function buildCriteriaCurrentMembers(?\DateTimeImmutable $now = null): Criteria { $criteria = new Criteria(); $expr = Criteria::expr(); $date = $now === null ? (new \DateTimeImmutable('today')) : $now; $criteria ->where($expr->orX( $expr->isNull('startDate'), $expr->lte('startDate', $date) )) ->andWhere($expr->orX( $expr->isNull('endDate'), $expr->gt('endDate', $date) )); return $criteria; } /** * @return HouseholdMember[] */ public function getCurrentMembersOrdered(?\DateTimeImmutable $now = null): Collection { $members = $this->getCurrentMembers($now); $members->getIterator() ->uasort( function (HouseholdMember $a, HouseholdMember $b) { if ($a->getPosition() === NULL) { if ($b->getPosition() === NULL) { return 0; } else { return -1; } } elseif ($b->getPosition() === NULL) { return 1; } if ($a->getPosition()->getOrdering() < $b->getPosition()->getOrdering()) { return -1; } if ($a->getPosition()->getOrdering() > $b->getPosition()->getOrdering()) { return 1; } if ($a->isHolder() && !$b->isHolder()) { return 1; } if (!$a->isHolder() && $b->isHolder()) { return -1; } return 0; } ); return $members; } /** * get current members ids * * Used in serialization * * @Serializer\Groups({"read"}) * @Serializer\SerializedName("current_members_id") * */ public function getCurrentMembersIds(?\DateTimeImmutable $now = null): Collection { return $this->getCurrentMembers($now)->map( fn (HouseholdMember $m) => $m->getId() ); } /** * Get the persons currently associated to the household. * * Return a list of Person, instead of a list of HouseholdMembers * * @return Person[] */ public function getCurrentPersons(?\DateTimeImmutable $now = null): Collection { return $this->getCurrentMembers($now) ->map(function(HouseholdMember $m) { return $m->getPerson(); }); } public function getNonCurrentMembers(\DateTimeImmutable $now = null): Collection { $criteria = new Criteria(); $expr = Criteria::expr(); $date = $now === null ? (new \DateTimeImmutable('today')) : $now; $criteria ->where( $expr->gt('startDate', $date) ) ->orWhere( $expr->andX( $expr->lte('endDate', $date), $expr->neq('endDate', null) ) ); return $this->getMembers()->matching($criteria); } public function getCurrentMembersByPosition(Position $position, \DateTimeInterface $now = null) { $criteria = new Criteria(); $expr = Criteria::expr(); $criteria->where($expr->eq('position', $position)); return $this->getCurrentMembers($now)->matching($criteria); } public function getNonCurrentMembersByPosition(Position $position, \DateTimeInterface $now = null) { $criteria = new Criteria(); $expr = Criteria::expr(); $criteria->where($expr->eq('position', $position)); return $this->getNonCurrentMembers($now)->matching($criteria); } public function getCurrentMembersWithoutPosition(\DateTimeInterface $now = null) { $criteria = new Criteria(); $expr = Criteria::expr(); $criteria->where($expr->isNull('position')); return $this->getCurrentMembers($now)->matching($criteria); } public function getNonCurrentMembersWithoutPosition(\DateTimeInterface $now = null) { $criteria = new Criteria(); $expr = Criteria::expr(); $criteria->where($expr->isNull('position')); return $this->getNonCurrentMembers($now)->matching($criteria); } public function addMember(HouseholdMember $member): self { if (!$this->members->contains($member)) { $this->members[] = $member; $member->setHousehold($this); } return $this; } public function removeMember(HouseholdMember $member): self { if ($this->members->removeElement($member)) { // set the owning side to null (unless already changed) if ($member->getHousehold() === $this) { $member->setHousehold(null); } } return $this; } public function getCommentMembers(): CommentEmbeddable { return $this->commentMembers; } public function setCommentMembers(CommentEmbeddable $commentMembers): self { $this->commentMembers = $commentMembers; return $this; } public function getWaitingForBirth(): bool { return $this->waitingForBirth; } public function setWaitingForBirth(bool $waitingForBirth): self { $this->waitingForBirth = $waitingForBirth; return $this; } public function getWaitingForBirthDate(): ?\DateTimeImmutable { return $this->waitingForBirthDate; } public function setWaitingForBirthDate(?\DateTimeImmutable $waitingForBirthDate): self { $this->waitingForBirthDate = $waitingForBirthDate; return $this; } public function validate(ExecutionContextInterface $context, $payload) { $addresses = $this->getAddresses(); $cond = True; for ($i=0; $i < count($addresses) - 1; $i++) { if ($addresses[$i]->getValidFrom() != $addresses[$i + 1]->getValidTo()) { $cond = False; $context->buildViolation('The address are not sequentials. The validFrom date of one address should be equal to the validTo date of the previous address.') ->atPath('addresses') ->addViolation(); } } } }