Fixed: [export][list person] use address from household for person list

This commit is contained in:
2022-10-25 10:23:02 +02:00
parent 4af261a366
commit 333c305eef
6 changed files with 515 additions and 237 deletions

View File

@@ -0,0 +1,247 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\MainBundle\Export\Helper;
use Chill\MainBundle\Repository\AddressRepository;
use Chill\MainBundle\Templating\Entity\AddressRender;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use LogicException;
use Symfony\Component\PropertyAccess\PropertyAccess;
use Symfony\Component\PropertyAccess\PropertyAccessor;
use function strlen;
/**
* Helps to load addresses and format them in list
*/
class ExportAddressHelper
{
public const ATTRIBUTES = 0b01000000;
public const BUILDING = 0b00001000;
public const COUNTRY = 0b00000001;
public const GEOM = 0b00100000;
public const POSTAL_CODE = 0b00000010;
public const STREET = 0b00000100;
public const STRING = 0b00010000;
private const ALL = [
'country' => self::COUNTRY,
'postal_code' => self::POSTAL_CODE,
'street' => self::STREET,
'building' => self::BUILDING,
'string' => self::STRING,
'geom' => self::GEOM,
'attributes' => self::ATTRIBUTES,
];
private const COLUMN_MAPPING = [
'country' => ['country'],
'postal_code' => ['postcode_code', 'postcode_name'],
'street' => ['street', 'streetNumber'],
'building' => ['buildingName', 'corridor', 'distribution', 'extra', 'flat', 'floor'],
'string' => ['_as_string'],
'attributes' => ['isNoAddress', 'confidential', 'id'],
'geom' => ['_lat', '_lon'],
];
private AddressRender $addressRender;
private AddressRepository $addressRepository;
private PropertyAccessor $propertyAccess;
private TranslatableStringHelperInterface $translatableStringHelper;
public function __construct(
AddressRepository $addressRepository,
TranslatableStringHelperInterface $translatableStringHelper,
AddressRender $addressRender
) {
$this->addressRepository = $addressRepository;
$this->propertyAccess = PropertyAccess::createPropertyAccessor();
$this->translatableStringHelper = $translatableStringHelper;
$this->addressRender = $addressRender;
}
/**
* @return array|string[]
*/
public function getKeys(int $params, string $prefix = ''): array
{
$prefixes = [];
foreach (self::ALL as $key => $bitmask) {
if (($params & $bitmask) === $bitmask) {
$prefixes = array_merge(
$prefixes,
array_map(
static function ($item) use ($prefix) { return $prefix . $item; },
self::COLUMN_MAPPING[$key]
)
);
}
}
return $prefixes;
}
public function getLabel($key, array $values, $data, string $prefix = '', string $translationPrefix = 'export.address_helper.'): callable
{
$sanitizedKey = substr($key, strlen($prefix));
switch ($sanitizedKey) {
case 'id':
case 'street':
case 'streetNumber':
case 'buildingName':
case 'corridor':
case 'distribution':
case 'extra':
case 'flat':
case 'floor':
return function ($value) use ($sanitizedKey, $translationPrefix) {
if ('_header' === $value) {
return $translationPrefix . $sanitizedKey;
}
if (null === $value) {
return '';
}
$address = $this->addressRepository->find($value);
return $this->propertyAccess->getValue($address, $sanitizedKey);
};
case '_lat':
case '_lon':
return function ($value) use ($sanitizedKey, $translationPrefix) {
if ('_header' === $value) {
return $translationPrefix . $sanitizedKey;
}
if (null === $value) {
return '';
}
$address = $this->addressRepository->find($value);
$geom = $address->getPoint();
if (null === $geom) {
return '';
}
switch ($sanitizedKey) {
case '_lat':
return $geom->getLat();
case '_lon':
return $geom->getLon();
default:
throw new LogicException('only _lat or _lon accepted, given: ' . $sanitizedKey);
}
};
case 'isNoAddress':
case 'confidential':
return function ($value) use ($sanitizedKey, $translationPrefix) {
if ('_header' === $value) {
return $translationPrefix . $sanitizedKey;
}
if (null === $value) {
return '';
}
$address = $this->addressRepository->find($value);
switch ($val = $this->propertyAccess->getValue($address, $sanitizedKey)) {
case null:
return '';
case true:
return 1;
case false:
return 0;
default:
throw new LogicException('this value is not supported for ' . $sanitizedKey . ': ' . $val);
}
};
case 'country':
return function ($value) use ($sanitizedKey, $translationPrefix) {
if ('_header' === $value) {
return $translationPrefix . $sanitizedKey;
}
if (null === $value) {
return '';
}
$address = $this->addressRepository->find($value);
return $this->translatableStringHelper->localize($address->getPostcode()->getCountry()->getName());
};
case '_as_string':
return function ($value) use ($sanitizedKey, $translationPrefix) {
if ('_header' === $value) {
return $translationPrefix . $sanitizedKey;
}
if (null === $value) {
return '';
}
$address = $this->addressRepository->find($value);
return $this->addressRender->renderString($address, []);
};
case 'postcode_code':
case 'postcode_name':
return function ($value) use ($sanitizedKey, $translationPrefix) {
if ('_header' === $value) {
return $translationPrefix . $sanitizedKey;
}
if (null === $value) {
return '';
}
$address = $this->addressRepository->find($value);
switch ($sanitizedKey) {
case 'postcode_code':
return $address->getPostcode()->getCode();
case 'postcode_name':
return $address->getPostcode()->getName();
default:
throw new LogicException('this key is not supported: ' . $sanitizedKey);
}
};
default:
throw new LogicException('this key is not supported: ' . $sanitizedKey);
}
}
}