ingresos'; const DAP_EGRESOS = 'dap->egresos'; const INGRESOS = 'ingresos'; const EGRESOS = 'egresos'; const TOTAL_ANTERIOR = 'anterior'; const TOTAL_ACTUAL = 'actual'; const TOTAL_FFMM = 'ffmm'; const TOTAL_DAP = 'deposito'; protected DateTimeInterface $anterior; protected object $totales; protected object $movimientos; public function __construct(LoggerInterface $logger, protected Repository\Inmobiliaria $inmobiliariaRepository, protected Repository\Contabilidad\Deposito $depositoRepository, protected Repository\Contabilidad\Cartola $cartolaRepository, protected Repository\Contabilidad\Movimiento $movimientoRepository, protected Service\Inmobiliaria\Cuenta $cuentaService, protected Output\Excel $excelService, protected Output\PDF $pdfService) { parent::__construct($logger); $this->movimientos = new Output\Data\Movimientos(self::ORDEN_SOCIEDADES); $this->totales = new Output\Data\Totales(); } public function getAnterior(DateTimeInterface $fecha): DateTimeInterface { if (!isset($this->anterior)) { $this->anterior = $fecha->sub(new DateInterval('P1D')); if ($this->anterior->format('N') === '7') { $this->anterior = $fecha->sub(new DateInterval('P3D')); } } return $this->anterior; } public function build(DateTimeInterface $fecha): array { try { $inmobiliarias = $this->inmobiliariaRepository->fetchAll(); } catch (Implement\Exception\EmptyResult) { return []; } $data = $this->sortBySociedad($inmobiliarias); $informe = ['sociedades' => []]; foreach ($data as $sociedad) { $informe['sociedades'][$sociedad->rut] = $this->buildInmobiliaria($sociedad, $fecha); } $informe['movimientos'] = $this->buildMovimientos(); $informe['totales'] = $this->buildTotales(); //$this->buildInforme($fecha, $informe); return $informe; } public function buildInforme(DateTimeInterface $fecha, array $data, string $type = 'Xlsx', ?string $filename = 'php://output'): void { $informe = $this->excelService->build($fecha, $data); $this->excelService->save($fecha, $informe, $type, $filename); } protected function buildInmobiliaria(Model\Inmobiliaria $inmobiliaria, DateTimeInterface $fecha): object { $dataInmobiliaria = new Output\Data\Sociedad(); $dataInmobiliaria->sociedad = $inmobiliaria; try { $cuentas = $this->cuentaService->getAllActiveByInmobiliaria($inmobiliaria->rut); } catch (Read) { return $dataInmobiliaria; } foreach ($cuentas as $cuenta) { $data = new Output\Data\Cuenta(); $data->banco = $cuenta->banco->nombre; $data->numero = $cuenta->cuenta; try { $depositos = $this->depositoRepository->fetchByCuenta($cuenta->id); foreach ($depositos as $deposito) { if ($deposito->termino < $fecha) { continue; } $data->deposito += $deposito->capital; $this->addTotal(self::TOTAL_DAP, $deposito->capital); $this->totales->saldo += $deposito->capital; if ($deposito->inicio->format('Y-m-d') === $fecha->format('Y-m-d')) { $this->addMovimientos(self::DAP_EGRESOS, [(object) [ 'cuenta' => $deposito->cuenta, 'fecha' => $deposito->inicio, 'cargo' => - $deposito->capital, 'abono' => 0, 'saldo' => - $deposito->capital, 'glosa' => 'INVERSION DAP' ]]); } if ($deposito->termino->format('Y-m-d') === $fecha->format('Y-m-d')) { $data->deposito -= $deposito->capital; $this->addTotal(self::TOTAL_DAP, -$deposito->capital); $this->addMovimientos(self::DAP_INGRESOS, [(object) [ 'cuenta' => $deposito->cuenta, 'fecha' => $deposito->termino, 'cargo' => 0, 'abono' => $deposito->futuro - $deposito->capital, 'saldo' => $deposito->futuro - $deposito->capital, 'glosa' => 'RESCATE DAP', 'documento' => $deposito->id ]]); } } } catch (Implement\Exception\EmptyResult) {} $anterior = $this->getAnterior($fecha); try { $cartola = $this->cartolaRepository->fetchLastByCuentaAndFecha($cuenta->id, $fecha); $data->actual = $cartola->saldo; //$anterior = $this->getAnterior($cartola->fecha); } catch (Implement\Exception\EmptyResult) {} try { $cartola = $this->cartolaRepository->fetchLastByCuentaAndFecha($cuenta->id, $anterior); $data->anterior = $cartola->saldo; $this->totales->saldo += $cartola->saldo; } catch (Implement\Exception\EmptyResult) {} if ($data->diferencia() !== 0) { try { $movimientos = $this->movimientoRepository->fetchByCuentaAndFecha($cuenta->id, $fecha); $this->addMovimientos(self::INGRESOS, array_filter($movimientos, function(Model\Contabilidad\Movimiento $movimiento) { return $movimiento->abono > 0; })); $this->addMovimientos(self::EGRESOS, array_filter($movimientos, function(Model\Contabilidad\Movimiento $movimiento) { return $movimiento->cargo > 0; })); } catch (Implement\Exception\EmptyResult) {} } $dataInmobiliaria->cuentas []= $data; $this->addTotal( [self::TOTAL_ANTERIOR, self::TOTAL_ACTUAL], [$data->anterior, $data->actual] ); } return $dataInmobiliaria; } protected function buildMovimientos(): array { return $this->movimientos->build(); } protected function buildTotales(): object { return $this->totales; } protected function addMovimientos(string $tipo, array $movimientos): Output { if (str_starts_with($tipo, 'dap')) { list($d, $t) = explode('->', $tipo); $this->movimientos->addDap($t, $movimientos); return $this; } foreach ($movimientos as $movimiento) { if ($tipo === 'ingresos' and str_contains(strtolower($movimiento->glosa), ' dap ')) { $this->movimientos->updateDap($movimiento); continue; } $this->movimientos->{$tipo} []= $movimiento; } return $this; } protected function addTotal(string|array $tipo, int|array $total): Output { if (is_array($tipo)) { foreach ($tipo as $i => $t) { $this->addTotal($t, $total[$i]); } return $this; } $this->totales->{$tipo} += $total; return $this; } protected function sortBySociedad(array $data): array { $temp = []; foreach (self::ORDEN_SOCIEDADES as $sociedad_rut) { foreach ($data as $inmobiliaria) { if ($inmobiliaria->rut === $sociedad_rut) { $temp []= $inmobiliaria; } } } foreach ($data as $inmobiliaria) { if (!in_array($inmobiliaria, $temp)) { $temp []= $inmobiliaria; } } return $temp; } }