From 26e626074a6ae141b43b43fc1ad8c3959c957ae2 Mon Sep 17 00:00:00 2001 From: Juan Pablo Vial Date: Mon, 26 Aug 2024 15:26:10 -0400 Subject: [PATCH] Add sub Bancos to BCI and Santander --- app/setup/setups/services.php | 12 ++ app/src/Service/Contabilidad/Cartola/BCI.php | 10 +- .../Service/Contabilidad/Cartola/BCI/Mes.php | 100 ++++++++++ .../Contabilidad/Cartola/Santander.php | 62 +++++-- .../Cartola/Santander/OfficeBanking.php | 175 ++++++++++++++++++ 5 files changed, 338 insertions(+), 21 deletions(-) create mode 100644 app/src/Service/Contabilidad/Cartola/BCI/Mes.php create mode 100644 app/src/Service/Contabilidad/Cartola/Santander/OfficeBanking.php diff --git a/app/setup/setups/services.php b/app/setup/setups/services.php index db60239..3656026 100644 --- a/app/setup/setups/services.php +++ b/app/setup/setups/services.php @@ -80,5 +80,17 @@ return [ $container->get(Incoviba\Service\UF::class), $container->get(Incoviba\Service\USD::class) ); + }, + Incoviba\Service\Contabilidad\Cartola\Santander::class => function(ContainerInterface $container) { + return (new Incoviba\Service\Contabilidad\Cartola\Santander( + $container->get(Psr\Log\LoggerInterface::class), + )) + ->registerSub($container->get(Incoviba\Service\Contabilidad\Cartola\Santander\OfficeBanking::class)); + }, + Incoviba\Service\Contabilidad\Cartola\BCI::class => function(ContainerInterface $container) { + return (new Incoviba\Service\Contabilidad\Cartola\BCI( + $container->get(Psr\Log\LoggerInterface::class), + )) + ->registerSub($container->get(Incoviba\Service\Contabilidad\Cartola\BCI\Mes::class)); } ]; diff --git a/app/src/Service/Contabilidad/Cartola/BCI.php b/app/src/Service/Contabilidad/Cartola/BCI.php index 54ee427..f2fe244 100644 --- a/app/src/Service/Contabilidad/Cartola/BCI.php +++ b/app/src/Service/Contabilidad/Cartola/BCI.php @@ -7,6 +7,8 @@ use Psr\Http\Message\UploadedFileInterface; class BCI extends Banco { + use withSubBancos; + protected function columnMap(): array { return [ @@ -29,7 +31,13 @@ class BCI extends Banco } protected function parseFile(string $filename): array { - $xlsx = @PhpSpreadsheet\IOFactory::load($filename); + try { + $reader = PhpSpreadsheet\IOFactory::createReader('Xlsx'); + } catch (PhpSpreadsheet\Reader\Exception $exception) { + $this->logger->critical($exception, ['filename' => $filename]); + return []; + } + $xlsx = $reader->load($filename); $worksheet = $xlsx->getActiveSheet(); $rows = $worksheet->getRowIterator(); diff --git a/app/src/Service/Contabilidad/Cartola/BCI/Mes.php b/app/src/Service/Contabilidad/Cartola/BCI/Mes.php new file mode 100644 index 0000000..3be3ea0 --- /dev/null +++ b/app/src/Service/Contabilidad/Cartola/BCI/Mes.php @@ -0,0 +1,100 @@ +load($filename); + $sheet = $xlsx->getActiveSheet(); + $subtitle = $sheet->getCell('A2')->getCalculatedValue(); + return trim($subtitle) === 'Cartola de cuenta corriente'; + } + + protected function columnMap(): array + { + return [ + 'Fecha' => 'fecha', + 'Descripción' => 'glosa', + 'N° Documento' => 'identificador', + 'Cheques y otros cargos' => 'cargo', + 'Depósitos y Abono' => 'abono', + 'Saldo diario' => 'saldo', + 'Categoría' => 'categoria', + 'Centro costos' => 'centro_costo', + 'Detalle' => 'detalle', + 'Factura Boleta' => 'identificador', + 'RUT' => 'rut', + 'Nombres' => 'nombres', + ]; + } + protected function getFilename(UploadedFileInterface $uploadedFile): string + { + return '/tmp/cartola.xlsx'; + } + protected function parseFile(string $filename): array + { + try { + $reader = PhpSpreadsheet\IOFactory::createReader('Xlsx'); + } catch (PhpSpreadsheet\Reader\Exception $exception) { + $this->logger->critical($exception, ['filename' => $filename]); + return []; + } + $xlsx = $reader->load($filename); + $sheet = $xlsx->getActiveSheet(); + + $valueColumns = [ + 'cargo', + 'abono', + 'saldo', + ]; + $found = false; + $columns = []; + $data = []; + foreach ($sheet->getRowIterator() as $row) { + if (!$found and $sheet->getCell("A{$row->getRowIndex()}")->getCalculatedValue() === 'Fecha') { + $found = true; + foreach ($row->getColumnIterator() as $column) { + if ($column->getValue() === null) { + break; + } + $columns[$column->getColumn()] = trim($column->getValue()); + } + continue; + } + if (!$found) { + continue; + } + if ($sheet->getCell("A{$row->getRowIndex()}")->getValue() === null) { + break; + } + $rowData = []; + foreach ($columns as $columnIndex => $column) { + $value = $sheet->getCell("{$columnIndex}{$row->getRowIndex()}")->getCalculatedValue(); + $mapped = $this->columnMap()[$column] ?? $column; + if ($mapped === 'fecha') { + $value = PhpSpreadsheet\Shared\Date::excelToDateTimeObject($value)->format('Y-m-d'); + } + if (in_array($mapped, $valueColumns)) { + $value = (int) $value; + } + $rowData[$column] = $value; + } + + $data []= $rowData; + } + return $data; + } +} diff --git a/app/src/Service/Contabilidad/Cartola/Santander.php b/app/src/Service/Contabilidad/Cartola/Santander.php index d2f6d8b..477bd2c 100644 --- a/app/src/Service/Contabilidad/Cartola/Santander.php +++ b/app/src/Service/Contabilidad/Cartola/Santander.php @@ -1,34 +1,46 @@ processUploadedFile($file); + try { + $subBanco = $this->getSubBanco($filename); + $data = $subBanco->processFile($filename); + return $subBanco->mapColumns($data); + } catch (InvalidArgumentException) { + $data = parent::processFile($filename); + return $this->mapColumns($data); + } + }*/ + protected function columnMap(): array { return [ - 'cargo' => 'cargo', - 'abono' => 'abono', - 'DESCRIPCIÓN MOVIMIENTO' => 'glosa', - 'FECHA' => 'fecha', - 'N° DOCUMENTO' => 'documento', - 'SALDO' => 'saldo', 'Fecha' => 'fecha', - 'Cargo ($)' => 'cargo', - 'Abono ($)' => 'abono', - 'Descripcin' => 'glosa', - 'Saldo Diario' => 'saldo', + 'Descripción' => 'glosa', + 'Nº Docu' => 'documento', + 'Cheques y Otros Cargos' => 'cargo', + 'Depósitos y Abonos' => 'abono', + 'Saldo' => 'saldo', 'Categoría' => 'categoria', 'Centro costos' => 'centro_costo', 'Detalle' => 'detalle', - 'Factura Boleta' => 'identificador', + 'Factura o Boleta' => 'identificador', 'RUT' => 'rut', - 'Nombres' => 'nombres', + 'Nombre' => 'nombres', ]; } + protected function getFilename(UploadedFileInterface $uploadedFile): string { $start = $uploadedFile->getStream()->read(10); @@ -47,15 +59,25 @@ class Santander extends Banco } protected function parseXlsx(string $filename): array { - $reader = PhpSpreadsheet\IOFactory::createReader('Xlsx'); + try { + $reader = PhpSpreadsheet\IOFactory::createReader('Xlsx'); + } catch (PhpSpreadsheet\Reader\Exception $exception) { + $this->logger->critical($exception, ['filename' => $filename]); + return []; + } $xlsx = $reader->load($filename); $sheet = $xlsx->getActiveSheet(); + $valueColumns = [ + 'Cheques y Otros Cargos', + 'Depósitos y Abonos', + 'Saldo' + ]; $found = false; $columns = []; $data = []; foreach ($sheet->getRowIterator() as $row) { - if (!$found and $sheet->getCell("A{$row->getRowIndex()}")->getCalculatedValue() === 'MONTO') { + if (!$found and $sheet->getCell("A{$row->getRowIndex()}")->getCalculatedValue() === 'Fecha') { $found = true; foreach ($row->getColumnIterator() as $column) { if ($column->getValue() === null) { @@ -76,21 +98,21 @@ class Santander extends Banco $value = $sheet->getCell("{$columnIndex}{$row->getRowIndex()}")->getCalculatedValue(); $mapped = $this->columnMap()[$column] ?? $column; if ($mapped === 'fecha') { - $value = implode('-', array_reverse(explode('/', $value))); + $value = PhpSpreadsheet\Shared\Date::excelToDateTimeObject($value)->format('Y-m-d'); } - if ($column === 'MONTO' or $column === 'SALDO') { + if (in_array($column, $valueColumns)) { $value = (int) $value; } $rowData[$column] = $value; } - if ($rowData['CARGO/ABONO'] === 'C') { + /*if ($rowData['CARGO/ABONO'] === 'C') { $rowData['MONTO'] = -$rowData['MONTO']; $rowData['cargo'] = $rowData['MONTO']; $rowData['abono'] = 0; } else { $rowData['cargo'] = 0; $rowData['abono'] = $rowData['MONTO']; - } + }*/ $data []= $rowData; } diff --git a/app/src/Service/Contabilidad/Cartola/Santander/OfficeBanking.php b/app/src/Service/Contabilidad/Cartola/Santander/OfficeBanking.php new file mode 100644 index 0000000..15dd731 --- /dev/null +++ b/app/src/Service/Contabilidad/Cartola/Santander/OfficeBanking.php @@ -0,0 +1,175 @@ +load($filename); + $sheet = $xlsx->getActiveSheet(); + $subtitle = $sheet->getCell('A2')->getCalculatedValue(); + return $subtitle === 'Consulta de movimientos de Cuentas Corrientes'; + } + + protected function columnMap(): array + { + return [ + 'cargo' => 'cargo', + 'abono' => 'abono', + 'DESCRIPCIÓN MOVIMIENTO' => 'glosa', + 'FECHA' => 'fecha', + 'N° DOCUMENTO' => 'documento', + 'SALDO' => 'saldo', + 'Fecha' => 'fecha', + 'Cargo ($)' => 'cargo', + 'Abono ($)' => 'abono', + 'Descripcin' => 'glosa', + 'Saldo Diario' => 'saldo', + 'Categoría' => 'categoria', + 'Centro costos' => 'centro_costo', + 'Detalle' => 'detalle', + 'Factura Boleta' => 'identificador', + 'RUT' => 'rut', + 'Nombres' => 'nombres', + ]; + } + protected function getFilename(UploadedFileInterface $uploadedFile): string + { + $start = $uploadedFile->getStream()->read(10); + if (str_starts_with($start, '<')) { + return '/tmp/cartola.html'; + } + return '/tmp/cartola.xlsx'; + } + + protected function parseFile(string $filename): array + { + if (str_ends_with($filename, 'xlsx')) { + return $this->parseXlsx($filename); + } + return $this->parseHtml($filename); + } + protected function parseXlsx(string $filename): array + { + try { + $reader = PhpSpreadsheet\IOFactory::createReader('Xlsx'); + } catch (PhpSpreadsheet\Reader\Exception $exception) { + $this->logger->critical($exception, ['filename' => $filename]); + return []; + } + $xlsx = $reader->load($filename); + $sheet = $xlsx->getActiveSheet(); + + $found = false; + $columns = []; + $data = []; + foreach ($sheet->getRowIterator() as $row) { + if (!$found and $sheet->getCell("A{$row->getRowIndex()}")->getCalculatedValue() === 'MONTO') { + $found = true; + foreach ($row->getColumnIterator() as $column) { + if ($column->getValue() === null) { + break; + } + $columns[$column->getColumn()] = trim($column->getValue()); + } + continue; + } + if (!$found) { + continue; + } + if ($sheet->getCell("A{$row->getRowIndex()}")->getValue() === null) { + break; + } + $rowData = []; + foreach ($columns as $columnIndex => $column) { + $value = $sheet->getCell("{$columnIndex}{$row->getRowIndex()}")->getCalculatedValue(); + $mapped = $this->columnMap()[$column] ?? $column; + if ($mapped === 'fecha') { + $value = implode('-', array_reverse(explode('/', $value))); + } + if ($column === 'MONTO' or $column === 'SALDO') { + $value = (int) $value; + } + $rowData[$column] = $value; + } + if ($rowData['CARGO/ABONO'] === 'C') { + $rowData['MONTO'] = -$rowData['MONTO']; + $rowData['cargo'] = $rowData['MONTO']; + $rowData['abono'] = 0; + } else { + $rowData['cargo'] = 0; + $rowData['abono'] = $rowData['MONTO']; + } + $data []= $rowData; + } + + return $data; + } + protected function parseHtml(string $filename): array + { + $data = []; + $lines = explode("\r\n", file_get_contents($filename)); + $columns = []; + $found = false; + for ($rowIndex = 0; $rowIndex < count($lines); $rowIndex ++) { + if (!$found and str_contains($lines[$rowIndex], 'Cuenta Corriente: ')) { + $found = true; + $rowIndex += 2; + $columns = $this->parseHtmlRow($lines, $rowIndex); + continue; + } + if (!$found) { + continue; + } + $row = $this->parseHtmlRow($lines, $rowIndex); + if (str_contains($row[0], 'Saldo Contable')) { + break; + } + $row = array_combine($columns, $row); + $row['Fecha'] = implode('-', array_reverse(explode('-', $row['Fecha']))); + foreach (['Cargo ($)', 'Abono ($)', 'Saldo Diario'] as $column) { + $row[$column] = (int) str_replace('.', '', $row[$column]); + } + $row['N° DOCUMENTO'] = ''; + $data []= $row; + } + + return array_reverse($data); + } + protected function parseHtmlRow(array $lines, int &$rowIndex): array + { + if (!str_contains($lines[$rowIndex ++], '')) { + return []; + } + $data = []; + while (!str_contains($lines[$rowIndex], '')) { + $tags = substr_count($lines[$rowIndex], '<') - substr_count($lines[$rowIndex], '', $ini) + 1; + } + $end = strpos($lines[$rowIndex], '<', $ini + 1); + $cell = str_replace(' ', '', substr($lines[$rowIndex], $ini, $end - $ini)); + $encoding = mb_detect_encoding($cell, ['Windows-1252', 'UTF-8']); + if ($encoding !== 'UTF-8') { + $cell = mb_convert_encoding($cell, $encoding, 'UTF-8'); + $cell = str_replace('?', '', $cell); + } + $data []= $cell; + $rowIndex ++; + } + return $data; + } +}