em = $em; $this->translatableStringHelper = $translatableStringHelper; $this->resourceKindRepository = $resourceKindRepository; $this->chargeKindRepository = $chargeKindRepository; } public function getSummaryForHousehold(?Household $household): array { if (null === $household) { return [ 'resources' => $this->getEmptyResourceArray(), 'charges' => $this->getEmptyChargeArray(), ]; } $personIds = $household->getCurrentPersons()->map(static function (Person $p) { return $p->getId(); }); $ids = implode(', ', array_fill(0, count($personIds), '?')); $parameters = [...$personIds, $household->getId()]; $rsm = $this->buildRsm(); $resources = $this->em->createNativeQuery(strtr(self::QUERY_RESOURCE_BY_HOUSEHOLD, ['_ids_' => $ids]), $rsm) ->setParameters($parameters) ->getResult(); $charges = $this->em->createNativeQuery(strtr(self::QUERY_CHARGE_BY_HOUSEHOLD, ['_ids_' => $ids]), $rsm) ->setParameters($parameters) ->getResult(); return [ 'resources' => array_merge($this->getEmptyResourceArray(), $this->rowToArray($resources, 'resource')), 'charges' => array_merge($this->getEmptyChargeArray(), $this->rowToArray($charges, 'charge')), ]; } public function getSummaryForPerson(?Person $person): array { if (null === $person) { return [ 'resources' => $this->getEmptyResourceArray(), 'charges' => $this->getEmptyChargeArray(), ]; } $rsm = $this->buildRsm(); $resources = $this->em->createNativeQuery(self::QUERY_RESOURCE_BY_PERSON, $rsm) ->setParameters([$person->getId()]) ->getResult(); $charges = $this->em->createNativeQuery(self::QUERY_CHARGE_BY_PERSON, $rsm) ->setParameters([$person->getId()]) ->getResult(); return [ 'resources' => array_merge($this->getEmptyResourceArray(), $this->rowToArray($resources, 'resource')), 'charges' => array_merge($this->getEmptyChargeArray(), $this->rowToArray($charges, 'charge')), ]; } private function buildRsm(): ResultSetMapping { $rsm = new ResultSetMapping(); $rsm ->addScalarResult('sum', 'sum') ->addScalarResult('kind_id', 'kind_id') ->addScalarResult('comment', 'comment'); return $rsm; } private function getEmptyChargeArray(): array { $keys = array_map(static fn (ChargeKind $kind) => $kind->getKind(), $this->chargeKindRepository->findAll()); return array_combine($keys, array_map(function ($kind) { return ['sum' => 0.0, 'label' => $this->translatableStringHelper->localize($this->chargeKindRepository->findOneByKind($kind)->getName()), 'comment' => '']; }, $keys)); } private function getEmptyResourceArray(): array { $keys = array_map(static fn (ResourceKind $kind) => $kind->getKind(), $this->resourceKindRepository->findAll()); return array_combine($keys, array_map(function ($kind) { return ['sum' => 0.0, 'label' => $this->translatableStringHelper->localize($this->resourceKindRepository->findOneByKind($kind)->getName()), 'comment' => '']; }, $keys)); } private function rowToArray(array $rows, string $kind): array { $result = []; switch ($kind) { case 'charge': foreach ($rows as $row) { $chargeKind = $this->chargeKindRepository->find($row['kind_id']); if (null === $chargeKind) { throw new RuntimeException('charge kind not found: ' . $row['kind_id']); } $result[$chargeKind->getKind()] = [ 'sum' => (float) $row['sum'], 'label' => $this->translatableStringHelper->localize($chargeKind->getName()), 'comment' => (string) $row['comment'], ]; } return $result; case 'resource': foreach ($rows as $row) { $resourceKind = $this->resourceKindRepository->find($row['kind_id']); if (null === $resourceKind) { throw new RuntimeException('charge kind not found: ' . $row['kind_id']); } $result[$resourceKind->getKind()] = [ 'sum' => (float) $row['sum'], 'label' => $this->translatableStringHelper->localize($resourceKind->getName()), 'comment' => (string) $row['comment'], ]; } return $result; default: throw new LogicException(); } } }