<?php
namespace App\EventSubscriber;
use App\Event\CsvBeneficiaryNotExistsRowEvent;
use App\Event\CsvFilterFieldsErrorRowEvent;
use App\Event\CsvImportReportsFileProcessedEvent;
use App\Event\CsvNotValidHeaderFileEvent;
use App\Event\CsvResponseDataErrorRowEvent;
use App\Service\CsvGenerator;
use App\Service\FileHelper;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class FreematicaSubscriber implements EventSubscriberInterface
{
/** @var LoggerInterface $errorLogger */
private $logger;
/** @var CsvGenerator $csvGenerator */
private $csvGenerator;
/**
* @param LoggerInterface $freematicaLogger
* @param CsvGenerator $csvGenerator
*/
public function __construct(LoggerInterface $freematicaLogger, CsvGenerator $csvGenerator)
{
$this->logger = $freematicaLogger;
$this->csvGenerator = $csvGenerator;
}
/**
* @return array
*/
public static function getSubscribedEvents(): array
{
return [
CsvResponseDataErrorRowEvent::class => 'onResponseDataRowError',
CsvNotValidHeaderFileEvent::class => 'onNotValidHeaderFile',
CsvFilterFieldsErrorRowEvent::class => 'onNotValidFilterRowFields',
CsvBeneficiaryNotExistsRowEvent::class => 'onBeneficiaryNotExistsRow',
CsvImportReportsFileProcessedEvent::class => 'onImportReportsFileProcessedEvent'
];
}
/**
* @param CsvResponseDataErrorRowEvent $event
*/
public function onResponseDataRowError(CsvResponseDataErrorRowEvent $event)
{
$row = $event->getRow() + 1;
$fileName = $event->getFile();
$this->logger->error("Error en la Fila: $row del fichero: $fileName, error en la conexión con Freematica");
}
/**
* @param CsvNotValidHeaderFileEvent $event
*/
public function onNotValidHeaderFile(CsvNotValidHeaderFileEvent $event)
{
$data = $event->getData();
$this->logger->error('No se ha procesado el fichero ' . $data['file'] . ' Faltan las siguientes cabeceras:' . implode('--', $data['missingRequiredFields']));
}
/**
* @param CsvFilterFieldsErrorRowEvent $event
*/
public function onNotValidFilterRowFields(CsvFilterFieldsErrorRowEvent $event)
{
$data = $event->getData();
/* Format data */
$errorFields = $this->errorDescriptions($data, false);
$this->logger->error($this->errorDescriptionsToString($data['row'], $data['file'], $errorFields));
}
/**
* @param CsvBeneficiaryNotExistsRowEvent $event
*/
public function onBeneficiaryNotExistsRow(CsvBeneficiaryNotExistsRowEvent $event)
{
$row = $event->getRow() + 1;
$fileName = $event->getFile();
$this->logger->error("Error en la Fila: $row del fichero: $fileName, no se ha encontrado el beneficiario");
}
/**
* @param CsvImportReportsFileProcessedEvent $event
*/
public function onImportReportsFileProcessedEvent(CsvImportReportsFileProcessedEvent $event)
{
foreach ($event->getErrorsByType() as $key => $item) {
if (!empty($item)) {
if ($key === FileHelper::ERROR_DATA_DESCRIPTION_PATH) {
$data = [];
foreach ($item as $key1 => $value) {
$data[] = $this->errorDescriptionsForFile(
$key1, $event->getMovedPath(), $this->errorDescriptions($value, true)
);
}
$item = $data;
}
$errorMovedPath = $this->getErrorPath($event->getMovedPath(), $key);
$this->csvGenerator->generateFile($item, $errorMovedPath);
}
}
}
/**
* @param string $movedPath
* @param string $errorPath
* @return string
*/
private function getErrorPath(string $movedPath, string $errorPath): string
{
$delimiter = '/';
$file = str_replace(FileHelper::PROCESSED_PATH, '', $movedPath);
$fileName = explode($delimiter, $file);
// Create directory if not exists
$collectivePath = $errorPath . $delimiter . $fileName[1];
$this->csvGenerator->createDirectory($collectivePath);
return $collectivePath . $delimiter . $fileName[2];
}
/**
* @param array $data
* @param bool $fileType
* @return array
*/
private function errorDescriptions(array $data, bool $fileType): array
{
/* Format data */
if ($fileType) {
return array_map(function ($key, $value) {
return "$key: $value";
}, array_keys($data), array_values($data));
}
return array_map(function ($key, $value) {
return "< $key => $value >";
}, array_keys($data['errorFields']), array_values($data['errorFields']));
}
/**
* @param int $row
* @param string $movedPath
* @param array $errorFields
* @return string
*/
private function errorDescriptionsToString(int $row, string $movedPath, array $errorFields): string
{
$row ++;
return "Error en la Fila: $row del fichero: $movedPath, Campos con error:" . implode(' | ', $errorFields);
}
/**
* @param int $row
* @param string $movedPath
* @param array $errorFields
* @return array
*/
private function errorDescriptionsForFile(int $row, string $movedPath, array $errorFields): array
{
$row ++;
return [
'Fila' => "Error en la Fila: $row",
'Fichero' => $movedPath,
'Campos con error' => implode("\r\n", $errorFields)
];
}
}