Restructura contabilidad
This commit is contained in:
142
app/src/Service/Contabilidad/Cartola.php
Normal file
142
app/src/Service/Contabilidad/Cartola.php
Normal file
@ -0,0 +1,142 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Contabilidad;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use DateTimeInterface;
|
||||
use Incoviba\Common\Define\Cartola\Banco;
|
||||
use Incoviba\Common\Define\Contabilidad\Exporter;
|
||||
use Incoviba\Common\Ideal\Service;
|
||||
use Incoviba\Common\Implement\Exception;
|
||||
use Incoviba\Model;
|
||||
use Incoviba\Repository;
|
||||
use Psr\Http\Message\StreamFactoryInterface;
|
||||
use Psr\Http\Message\UploadedFileInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class Cartola extends Service
|
||||
{
|
||||
public function __construct(LoggerInterface $logger,
|
||||
protected StreamFactoryInterface $streamFactory, protected Exporter $exporter,
|
||||
protected Repository\Inmobiliaria $inmobiliariaRepository,
|
||||
protected Repository\Inmobiliaria\Cuenta $cuentaRepository,
|
||||
protected Repository\Contabilidad\Movimiento $movimientoRepository,
|
||||
protected Movimiento $movimientoService,
|
||||
protected Repository\Contabilidad\Cartola $cartolaRepository) {
|
||||
parent::__construct($logger);
|
||||
}
|
||||
|
||||
protected array $bancos;
|
||||
public function register(string $name, Banco $banco): Cartola
|
||||
{
|
||||
$this->bancos[$name] = $banco;
|
||||
return $this;
|
||||
}
|
||||
public function process(Model\Inmobiliaria $inmobiliaria, Model\Contabilidad\Banco $banco, DateTimeInterface $mes, UploadedFileInterface $file): array
|
||||
{
|
||||
return $this->bancos[strtolower($banco->nombre)]->process($file);
|
||||
}
|
||||
public function export(Model\Inmobiliaria $inmobiliaria, Model\Contabilidad\Banco $banco, DateTimeInterface $mes, array $movimientos): string
|
||||
{
|
||||
return $this->exporter->export($inmobiliaria, $banco, $mes, $movimientos);
|
||||
}
|
||||
public function diaria(Model\Inmobiliaria\Cuenta $cuenta, DateTimeInterface $fecha, UploadedFileInterface $file): array
|
||||
{
|
||||
$ms = $this->getMovimientosDiarios($cuenta->banco, $file);
|
||||
|
||||
$this->groupedMovimientos = [];
|
||||
$movimientos = [];
|
||||
foreach ($ms as $m) {
|
||||
$movimiento = $this->buildMovimiento($cuenta, $m);
|
||||
$movimiento = $this->movimientoService->process($movimiento);
|
||||
$this->groupMovimientoByDay($movimiento);
|
||||
if ($movimiento->fecha->getTimestamp() === $fecha->getTimestamp()) {
|
||||
$movimientos []= $movimiento;
|
||||
}
|
||||
}
|
||||
foreach ($this->groupedMovimientos as $timestamp => $movimientos) {
|
||||
$cartolaData = [
|
||||
'cargos' => 0,
|
||||
'abonos' => 0,
|
||||
'saldo' => end($movimientos)->saldo
|
||||
];
|
||||
foreach ($movimientos as $movimiento) {
|
||||
$cartolaData['cargos'] += $movimiento->cargo;
|
||||
$cartolaData['abonos'] += $movimiento->abono;
|
||||
}
|
||||
$this->buildCartola($cuenta, end($movimientos)->fecha, $cartolaData);
|
||||
}
|
||||
$cartola = $this->cartolaRepository->fetchByCuentaAndFecha($cuenta->id, $fecha);
|
||||
return compact('cartola', 'movimientos');
|
||||
}
|
||||
public function diariaManual(Model\Inmobiliaria\Cuenta $cuenta, DateTimeInterface $fecha, array $data): array
|
||||
{
|
||||
$cartolaData = [
|
||||
'cargos' => 0,
|
||||
'abonos' => 0,
|
||||
'saldos' => 0
|
||||
];
|
||||
$movimientos = [];
|
||||
foreach ($data as $row) {
|
||||
$dataMovimiento = $row;
|
||||
$dataMovimiento['fecha'] = $fecha->format('Y-m-d');
|
||||
$dataMovimiento['documento'] = '';
|
||||
$movimiento = $this->buildMovimiento($cuenta, $dataMovimiento);
|
||||
$movimiento = $this->movimientoService->process($movimiento);
|
||||
|
||||
$movimientos []= $movimiento;
|
||||
$cartolaData['cargos'] += $movimiento->cargo;
|
||||
$cartolaData['abonos'] += $movimiento->abono;
|
||||
$cartolaData['saldo'] = $movimiento->saldo;
|
||||
}
|
||||
$cartola = $this->buildCartola($cuenta, $fecha, $cartolaData);
|
||||
return compact('cartola', 'movimientos');
|
||||
}
|
||||
|
||||
protected function getMovimientosDiarios(Model\Contabilidad\Banco $banco, UploadedFileInterface $file): array
|
||||
{
|
||||
$movimientos = $this->bancos[strtolower($banco->nombre)]->process($file);
|
||||
return $this->bancos[strtolower($banco->nombre)]->processMovimientosDiarios($movimientos);
|
||||
}
|
||||
protected array $groupedMovimientos = [];
|
||||
protected function groupMovimientoByDay(Model\Contabilidad\Movimiento $movimiento): Cartola
|
||||
{
|
||||
if (!isset($this->groupedMovimientos[$movimiento->fecha->getTimestamp()])) {
|
||||
$this->groupedMovimientos[$movimiento->fecha->getTimestamp()] = [];
|
||||
}
|
||||
$this->groupedMovimientos[$movimiento->fecha->getTimestamp()] []= $movimiento;
|
||||
return $this;
|
||||
}
|
||||
protected function buildCartola(Model\Inmobiliaria\Cuenta $cuenta, DateTimeInterface $fecha, array $data): Model\Contabilidad\Cartola
|
||||
{
|
||||
try {
|
||||
return $this->cartolaRepository->fetchByCuentaAndFecha($cuenta->id, $fecha);
|
||||
} catch (Exception\EmptyResult) {
|
||||
$data['cuenta_id'] = $cuenta->id;
|
||||
$data['fecha'] = $fecha->format('Y-m-d');
|
||||
$cartola = $this->cartolaRepository->create($data);
|
||||
return $this->cartolaRepository->save($cartola);
|
||||
}
|
||||
}
|
||||
protected function buildMovimiento(Model\Inmobiliaria\Cuenta $cuenta, array $data): Model\Contabilidad\Movimiento
|
||||
{
|
||||
try {
|
||||
return $this->movimientoRepository
|
||||
->fetchByCuentaAndFechaAndCargoAndAbonoAndSaldo(
|
||||
$cuenta->id,
|
||||
new DateTimeImmutable($data['fecha']),
|
||||
$data['cargo'] ?? 0,
|
||||
$data['abono'] ?? 0,
|
||||
$data['saldo']
|
||||
);
|
||||
} catch (Exception\EmptyResult $exception) {
|
||||
$data['cuenta_id'] = $cuenta->id;
|
||||
$movimiento = $this->movimientoRepository->create($data);
|
||||
try {
|
||||
return $this->movimientoRepository->save($movimiento);
|
||||
} catch (\PDOException $exception) {
|
||||
$this->logger->critical(var_export($data,true));
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
86
app/src/Service/Contabilidad/Cartola/BCI.php
Normal file
86
app/src/Service/Contabilidad/Cartola/BCI.php
Normal 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;
|
||||
}
|
||||
}
|
166
app/src/Service/Contabilidad/Cartola/Itau.php
Normal file
166
app/src/Service/Contabilidad/Cartola/Itau.php
Normal 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();
|
||||
}
|
||||
}
|
148
app/src/Service/Contabilidad/Cartola/Santander.php
Normal file
148
app/src/Service/Contabilidad/Cartola/Santander.php
Normal 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;
|
||||
}
|
||||
}
|
128
app/src/Service/Contabilidad/Cartola/Security.php
Normal file
128
app/src/Service/Contabilidad/Cartola/Security.php
Normal 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;
|
||||
}
|
||||
}
|
@ -10,9 +10,9 @@ use PhpOffice\PhpSpreadsheet;
|
||||
|
||||
class Nubox implements Exporter
|
||||
{
|
||||
public function __construct(protected Repository\CentroCosto $centroCostoRepository, protected string $uploadFolder) {}
|
||||
public function __construct(protected Repository\Contabilidad\CentroCosto $centroCostoRepository, protected string $uploadFolder) {}
|
||||
|
||||
public function export(Model\Inmobiliaria $inmobiliaria, Model\Banco $banco, DateTimeInterface $mes, array $movimientos): string
|
||||
public function export(Model\Inmobiliaria $inmobiliaria, Model\Contabilidad\Banco $banco, DateTimeInterface $mes, array $movimientos): string
|
||||
{
|
||||
PhpSpreadsheet\Settings::setLocale('es-CL');
|
||||
$workbook = new PhpSpreadsheet\Spreadsheet();
|
||||
|
@ -1,23 +1,23 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Contabilidad\Informe;
|
||||
|
||||
use DateTimeInterface;
|
||||
use DateInterval;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use DateTimeInterface;
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Common\Implement;
|
||||
use Incoviba\Model;
|
||||
use Incoviba\Repository;
|
||||
use Incoviba\Service;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class Tesoreria extends Ideal\Service
|
||||
{
|
||||
public function __construct(LoggerInterface $logger,
|
||||
protected Repository\Inmobiliaria $inmobiliariaRepository,
|
||||
protected Service\Inmobiliaria\Cuenta $cuentaService,
|
||||
protected Repository\Deposito $depositoRepository,
|
||||
protected Repository\Cartola $cartolaRepository,
|
||||
protected Repository\Movimiento $movimientoRepository,
|
||||
protected Repository\Contabilidad\Deposito $depositoRepository,
|
||||
protected Repository\Contabilidad\Cartola $cartolaRepository,
|
||||
protected Repository\Contabilidad\Movimiento $movimientoRepository,
|
||||
protected Service\Contabilidad\Informe\Tesoreria\Excel $excelService,
|
||||
protected Service\Contabilidad\Informe\Tesoreria\PDF $pdfService)
|
||||
{
|
||||
@ -241,11 +241,11 @@ class Tesoreria extends Ideal\Service
|
||||
try {
|
||||
$movimientos = $this->movimientoRepository->fetchByCuentaAndFecha($cuenta->id, $fecha);
|
||||
$this->addMovimientos(self::INGRESOS,
|
||||
array_filter($movimientos, function(Model\Movimiento $movimiento) {
|
||||
array_filter($movimientos, function(Model\Contabilidad\Movimiento $movimiento) {
|
||||
return $movimiento->abono > 0;
|
||||
}));
|
||||
$this->addMovimientos(self::EGRESOS,
|
||||
array_filter($movimientos, function(Model\Movimiento $movimiento) {
|
||||
array_filter($movimientos, function(Model\Contabilidad\Movimiento $movimiento) {
|
||||
return $movimiento->cargo > 0;
|
||||
}));
|
||||
} catch (Implement\Exception\EmptyResult) {}
|
||||
|
43
app/src/Service/Contabilidad/Movimiento.php
Normal file
43
app/src/Service/Contabilidad/Movimiento.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Contabilidad;
|
||||
|
||||
use Incoviba\Common\Ideal\Service;
|
||||
use Incoviba\Common\Implement;
|
||||
use Incoviba\Model;
|
||||
use Incoviba\Repository;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class Movimiento extends Service
|
||||
{
|
||||
public function __construct(LoggerInterface $logger,
|
||||
protected Repository\Contabilidad\Movimiento $movimientoRepository,
|
||||
protected Repository\Movimiento\Detalle $detalleRepository)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
}
|
||||
|
||||
public function getById(int $movimiento_id): Model\Contabilidad\Movimiento
|
||||
{
|
||||
return $this->process($this->movimientoRepository->fetchById($movimiento_id));
|
||||
}
|
||||
public function setDetalles(Model\Contabilidad\Movimiento $movimiento, array $data): Model\Contabilidad\Movimiento
|
||||
{
|
||||
try {
|
||||
$detalles = $this->detalleRepository->fetchByMovimiento($movimiento->id);
|
||||
$this->detalleRepository->edit($detalles, $data);
|
||||
} catch (Implement\Exception\EmptyResult) {
|
||||
$data['movimiento_id'] = $movimiento->id;
|
||||
$detalles = $this->detalleRepository->create($data);
|
||||
$this->detalleRepository->save($detalles);
|
||||
}
|
||||
return $movimiento;
|
||||
}
|
||||
|
||||
public function process(Model\Contabilidad\Movimiento $movimiento): Model\Contabilidad\Movimiento
|
||||
{
|
||||
$movimiento->addFactory('detalles', (new Implement\Repository\Factory())->setCallable(function(int $movimiento_id) {
|
||||
return $this->detalleRepository->fetchByMovimiento($movimiento_id);
|
||||
})->setArgs(['movimiento_id' => $movimiento->id]));
|
||||
return $movimiento;
|
||||
}
|
||||
}
|
@ -2,24 +2,24 @@
|
||||
namespace Incoviba\Service\Contabilidad;
|
||||
|
||||
use DateTimeInterface;
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Common\Implement\Exception;
|
||||
use Incoviba\Repository;
|
||||
use Incoviba\Service;
|
||||
use Psr\Http\Client\ClientInterface;
|
||||
use Psr\Http\Message\RequestFactoryInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Incoviba\Common\Implement\Exception;
|
||||
use Incoviba\Repository;
|
||||
use Incoviba\Service;
|
||||
use Incoviba\Common\Ideal;
|
||||
|
||||
class Nubox extends Ideal\Service
|
||||
{
|
||||
public function __construct(protected LoggerInterface $logger,
|
||||
protected Repository\Nubox $nuboxRepository,
|
||||
protected Service\Redis $redisService,
|
||||
protected ClientInterface $client,
|
||||
protected RequestFactoryInterface $requestFactory,
|
||||
protected string $api_url)
|
||||
public function __construct(protected LoggerInterface $logger,
|
||||
protected Repository\Contabilidad\Nubox $nuboxRepository,
|
||||
protected Service\Redis $redisService,
|
||||
protected ClientInterface $client,
|
||||
protected RequestFactoryInterface $requestFactory,
|
||||
protected string $api_url)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
}
|
||||
|
Reference in New Issue
Block a user