Restructura contabilidad

This commit is contained in:
Juan Pablo Vial
2024-03-26 09:38:20 -03:00
parent 4b3397dd63
commit 5f56022109
57 changed files with 311 additions and 291 deletions

View File

@ -0,0 +1,86 @@
<?php
namespace Incoviba\Service\Contabilidad\Cartola;
use Incoviba\Common\Ideal\Cartola\Banco;
use PhpOffice\PhpSpreadsheet;
use Psr\Http\Message\UploadedFileInterface;
class BCI extends Banco
{
protected function columnMap(): array
{
return [
'Fecha Transacción' => 'fecha',
'Cargo $ (-)' => 'cargo',
'Abono $ (+)' => 'abono',
'Descripción' => 'glosa',
'Saldo' => 'saldo'
];
}
protected function getFilename(UploadedFileInterface $uploadedFile): string
{
return '/tmp/cartola.xlsx';
}
protected function parseFile(string $filename): array
{
$xlsx = @PhpSpreadsheet\IOFactory::load($filename);
$worksheet = $xlsx->getActiveSheet();
$rows = $worksheet->getRowIterator();
$rows->seek(3);
$row = $rows->current();
$columnIterator = $row->getColumnIterator();
$saldoFinal = 0;
foreach ($columnIterator as $column) {
if ($column->getValue() === null) {
continue;
}
if ($column->getCalculatedValue() === 'Saldo Contable') {
$columnIterator->next();
$column = $columnIterator->current();
$saldoFinal = (int) str_replace('.', '', $column->getCalculatedValue());
break;
}
}
$saldo = $saldoFinal;
$data = [];
$columns = [];
$dataFound = false;
foreach ($rows as $row) {
if (!$dataFound and $worksheet->getCell([1, $row->getRowIndex()])->getCalculatedValue() !== null
and trim($worksheet->getCell([1, $row->getRowIndex()])->getCalculatedValue()) === 'Fecha Contable') {
$dataFound = true;
$columns = $this->getRowData($row);
continue;
}
if (!$dataFound) {
continue;
}
if ($worksheet->getCell([1, $row->getRowIndex()])->getValue() === null) {
break;
}
$rowData = $this->getRowData($row);
$rowData = array_combine($columns, $rowData);
$rowData['Fecha Transacción'] = implode('-', array_reverse(explode('/', $rowData['Fecha Transacción'])));
$rowData['Cargo $ (-)'] = (int) str_replace('.', '', $rowData['Cargo $ (-)'] ?? 0);
$rowData['Abono $ (+)'] = (int) str_replace('.', '', $rowData['Abono $ (+)'] ?? 0);
$rowData['Saldo'] = $saldo;
$saldo = $saldo + $rowData['Cargo $ (-)'] - $rowData['Abono $ (+)'];
unset($rowData['']);
$data []= $rowData;
}
return array_reverse($data);
}
protected function getRowData(PhpSpreadsheet\Worksheet\Row $row): array
{
$data = [];
$cells = $row->getColumnIterator();
foreach ($cells as $cell) {
$data []= $cell->getCalculatedValue();
}
return $data;
}
}

View File

@ -0,0 +1,166 @@
<?php
namespace Incoviba\Service\Contabilidad\Cartola;
use DateTimeImmutable;
use Incoviba\Common\Ideal\Cartola\Banco;
use PhpOffice\PhpSpreadsheet;
use Psr\Http\Message\UploadedFileInterface;
class Itau extends Banco
{
const CUENTA_CORRIENTE = 0;
const ULTIMOS_MOVIMIENTOS = 1;
public function processMovimientosDiarios(array $movimientos): array
{
return array_reverse($movimientos);
}
protected function columnMap(): array
{
return [
'Fecha' => 'fecha',
'Número de operación' => 'documento',
'Descripción' => 'glosa',
'Depósitos o abonos' => 'abono',
'Giros o cargos' => 'cargo',
'Documentos' => 'documento',
'Movimientos' => 'glosa',
'Saldos' => 'saldo'
];
}
protected function getFilename(UploadedFileInterface $uploadedFile): string
{
return '/tmp/cartola.xls';
}
protected function parseFile(string $filename): array
{
$reader = PhpSpreadsheet\IOFactory::createReader('Xls');
$xlsx = $reader->load($filename);
$sheet = $xlsx->getActiveSheet();
$data = [];
try {
switch ($this->identifySheet($sheet)) {
case self::CUENTA_CORRIENTE:
$data = $this->parseCuentaCorriente($sheet);
break;
case self::ULTIMOS_MOVIMIENTOS:
$data = $this->parseUltimosMovimientos($sheet);
break;
}
} catch (PhpSpreadsheet\Exception $exception) {
$this->logger->critical($exception);
}
return $data;
}
protected function parseCuentaCorriente(PhpSpreadsheet\Worksheet\Worksheet $sheet): array
{
$found = false;
$year = 0;
$columns = [];
$data = [];
foreach ($sheet->getRowIterator() as $row) {
if (!$found and $sheet->getCell("A{$row->getRowIndex()}")->getCalculatedValue() === 'Cartola Histórica') {
$columnIndex = 'A';
foreach ($row->getColumnIterator() as $column) {
if ($column->getValue() !== 'Periodo') {
continue;
}
$columnIndex = $column->getColumn();
break;
}
$dates = explode(' - ', $sheet->getCell("{$columnIndex}{$row->getRowIndex()}")->getCalculatedValue());
$date = DateTimeImmutable::createFromFormat('d/m/Y', $dates[0]);
$year = $date->format('Y');
}
if (!$found and $sheet->getCell("A{$row->getRowIndex()}")->getCalculatedValue() === 'Movimientos') {
$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];
if ($mapped === 'fecha') {
list($d, $m) = explode('/', $value);
$value = "{$year}-{$m}-{$d}";
}
if (in_array($mapped, ['cargo', 'abono', 'saldo'])) {
$value = (int) $value;
}
$rowData[$column] = $value;
}
$data []= $rowData;
}
return $data;
}
protected function parseUltimosMovimientos(PhpSpreadsheet\Worksheet\Worksheet $sheet): array
{
$found = false;
$data = [];
$columns = [];
foreach ($sheet->getRowIterator() as $row) {
if (!$found and $sheet->getCell("A{$row->getRowIndex()}")->getCalculatedValue() === 'Últimos Movimientos') {
$found = true;
continue;
}
if (!$found) {
continue;
}
if (count($columns) === 0) {
foreach ($row->getColumnIterator() as $cell) {
if ($cell->getValue() === null) {
break;
}
$columns[$cell->getColumn()] = trim($cell->getValue());
}
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, 'America/Santiago')->format('Y-m-d');
}
if (in_array($mapped, ['abono', 'cargo', 'saldo'])) {
$value = (int) $value;
}
$rowData[$column] = $value;
}
$data []= $rowData;
}
return $data;
}
protected function identifySheet(PhpSpreadsheet\Worksheet\Worksheet $sheet): int
{
foreach ($sheet->getRowIterator(1, 10) as $row) {
$value = $sheet->getCell("A{$row->getRowIndex()}")->getValue();
if ($value === 'Estado de Cuenta Corriente') {
return self::CUENTA_CORRIENTE;
}
if ($value === 'Consulta Saldos y Últimos movimientos') {
return self::ULTIMOS_MOVIMIENTOS;
}
}
throw new PhpSpreadsheet\Exception();
}
}

View File

@ -0,0 +1,148 @@
<?php
namespace Incoviba\Service\Contabilidad\Cartola;
use Incoviba\Common\Ideal\Cartola\Banco;
use PhpOffice\PhpSpreadsheet;
use Psr\Http\Message\UploadedFileInterface;
class Santander extends Banco
{
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'
];
}
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
{
$reader = PhpSpreadsheet\IOFactory::createReader('Xlsx');
$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 array_reverse($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 ++], '<tr>')) {
return [];
}
$data = [];
while (!str_contains($lines[$rowIndex], '</tr>')) {
$tags = substr_count($lines[$rowIndex], '<') - substr_count($lines[$rowIndex], '</');
$ini = 0;
for ($t = 0; $t < $tags; $t ++) {
$ini = strpos($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;
}
}

View File

@ -0,0 +1,128 @@
<?php
namespace Incoviba\Service\Contabilidad\Cartola;
use DateTimeImmutable;
use DOMDocument;
use Incoviba\Common\Ideal\Cartola\Banco;
use PhpOffice\PhpSpreadsheet;
use Psr\Http\Message\UploadedFileInterface;
class Security extends Banco
{
public function processMovimientosDiarios(array $movimientos): array
{
$movimientos = array_reverse($movimientos);
array_shift($movimientos);
return $movimientos;
}
protected function getFilename(UploadedFileInterface $uploadedFile): string
{
$stream = $uploadedFile->getStream();
$stream->seek(3);
if ($stream->read(strlen('table')) === 'table') {
return '/tmp/cartola.htm';
}
return '/tmp/cartola.xls';
}
protected function parseFile(string $filename): array
{
if (str_ends_with($filename, '.htm')) {
return $this->processHtm($filename);
}
return $this->processXls($filename);
}
protected function columnMap(): array
{
return [
'fecha' => 'fecha',
'descripción' => 'glosa',
'número de documentos' => 'documento',
'nº documento' => 'documento',
'cargos' => 'cargo',
'abonos' => 'abono',
'saldos' => 'saldo'
];
}
private function processXls(string $filename): array
{
$xlsx = @PhpSpreadsheet\IOFactory::load($filename);
$worksheet = $xlsx->getActiveSheet();
$rows = $worksheet->getRowIterator(3);
$dataFound = false;
$columns = [];
$data = [];
foreach ($rows as $row) {
$cells = $row->getCellIterator();
$rowData = [];
foreach ($cells as $cell) {
if ($cell->getColumn() === 'A' and $cell->getCalculatedValue() !== null and strtolower($cell->getCalculatedValue()) === "fecha ") {
$cols = $row->getColumnIterator();
foreach ($cols as $col) {
$columns[$col->getColumn()] = trim(strtolower($col->getCalculatedValue()), '  ');
}
$dataFound = true;
break;
}
if ($cell->getColumn() === 'A' and $cell->getCalculatedValue() === null) {
$dataFound = false;
break;
}
if (!$dataFound) {
break;
}
$col = $columns[$cell->getColumn()];
$value = $cell->getCalculatedValue();
if ($col === 'fecha') {
if ((int) $cell->getValue() !== $cell->getValue()) {
$value = implode('-', array_reverse(explode('-', $cell->getValue())));
} else {
$value = PhpSpreadsheet\Shared\Date::excelToDateTimeObject($cell->getValue(), 'America/Santiago')->format('Y-m-d');
}
}
$rowData[$col] = $value;
}
if (count($rowData) > 0) {
$data []= $rowData;
}
}
return $data;
}
private function processHtm(string $filename): array
{
$domDocument = new DOMDocument();
$domDocument->loadHTML('<body>' . file_get_contents($filename) . '</body>');
$tables = $domDocument->getElementsByTagName('table');
$table = $tables->item(4);
$columns = [];
$data = [];
foreach ($table->getElementsByTagName('tr')->getIterator() as $rowIndex => $row) {
if ($rowIndex === 0) {
continue;
}
if (str_contains($row->textContent, 'cargos')) {
foreach ($row->getElementsByTagName('td')->getIterator() as $cell) {
$columns []= trim($cell->textContent);
}
continue;
}
$rowData = [];
foreach ($row->getElementsByTagName('td')->getIterator() as $colIndex => $cell) {
$col = $columns[$colIndex];
$value = trim($cell->textContent);
if ($col === 'fecha') {
$value = DateTimeImmutable::createFromFormat('d/m/Y', $value)->format('Y-m-d');
}
if (in_array($col, ['cargos', 'abonos', 'saldos'])) {
$value = (float) str_replace(',', '.', $value);
}
$rowData[$col] = $value;
}
$data []= $rowData;
}
return $data;
}
}