diff --git a/.gitignore b/.gitignore index 1646ae8..d25a303 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ **/modules/ **/.idea/ **/upload?/ +**/informe?/ diff --git a/app/common/Define/Informe.php b/app/common/Define/Informe.php new file mode 100644 index 0000000..db8f511 --- /dev/null +++ b/app/common/Define/Informe.php @@ -0,0 +1,10 @@ +group('/xlsx', function($app) { + $app->get('/tesoreria/{fecha}[/]', [Informes::class, 'tesoreria']); +}); diff --git a/app/resources/views/contabilidad/informes/tesoreria.blade.php b/app/resources/views/contabilidad/informes/tesoreria.blade.php index d79bf17..18f3f82 100644 --- a/app/resources/views/contabilidad/informes/tesoreria.blade.php +++ b/app/resources/views/contabilidad/informes/tesoreria.blade.php @@ -4,144 +4,153 @@

Informe de Tesorería

{{$fecha->format('d M Y')}}

-
-
- - - - - - - - - -
Informe anterior{{$anterior->format('d/m/Y')}}
Informe actual{{$fecha->format('d/m/Y')}}
-
-
-
- - - - - - - - - -
Valor UF{{$format->pesos($UF->get($fecha), 2)}}
Valor Dólar{{$format->pesos($USD->get($fecha), 2)}}
+
- - - - - - - - - - - - - - - - - - - - @foreach ($informes['inmobiliarias'] as $inmobiliaria_rut => $informe) - @foreach ($informe->cuentas as $i => $cuenta) + +
+
+
EMPRESABancoCuentaSaldo AnteriorSaldo ActualDiferenciaFFMMDAPSaldo EmpresaTotal CuentasTotal FFMMTotal DAPCaja Total
- @if ($i === 0) - - @endif - - - - - - - - - @if ($i === 0) - - - - - @endif + + - @endforeach - @endforeach - - - - - - - - - - - - - - - - -
{{$informe->inmobiliaria->razon}}{{$cuenta->banco}}{{$cuenta->numero}}{{$format->pesos($cuenta->anterior)}}{{$format->pesos($cuenta->actual)}}{{$format->pesos($cuenta->diferencia())}}{{$format->pesos($cuenta->ffmm)}}{{$format->pesos($cuenta->deposito)}}{{$format->pesos($cuenta->saldo())}}{{$format->pesos($informe->total())}}{{$format->pesos($informe->ffmm())}}{{$format->pesos($informe->deposito())}}{{$format->pesos($informe->caja())}}Informe anterior{{$anterior->format('d/m/Y')}}
TOTAL{{$format->pesos($informes['totales']->anterior)}}{{$format->pesos($informes['totales']->actual)}}{{$format->pesos($informes['totales']->diferencia())}}{{$format->pesos($informes['totales']->ffmm)}}{{$format->pesos($informes['totales']->deposito)}}{{$format->pesos($informes['totales']->saldo())}}{{$format->pesos($informes['totales']->cuentas())}}{{$format->pesos($informes['totales']->ffmms())}}{{$format->pesos($informes['totales']->depositos())}}{{$format->pesos($informes['totales']->caja())}}
- - + + + + +
Informe actual{{$fecha->format('d/m/Y')}}
+
+
+
+ + + + + + + + + +
Valor UF{{$format->pesos($UF->get($fecha), 2)}}
Valor Dólar{{$format->pesos($USD->get($fecha), 2)}}
+
+ + + + + + + + + + + + + + + + + + + + + @foreach ($informes['inmobiliarias'] as $inmobiliaria_rut => $informe) + @foreach ($informe->cuentas as $i => $cuenta) - - - - - - - - - - @foreach ($informes['movimientos'] as $tipo => $movimientos) - @if ($tipo === 'capital dap') - @if (count($movimientos['ingresos']) === 0 and count($movimientos['egresos']) === 0) - @continue - @endif - - - - @foreach ($movimientos as $t => $ms) - @foreach ($ms as $movimiento) - - - - - - - - - @endforeach - @endforeach - @continue + @if ($i === 0) + @endif - @if (count($movimientos) === 0) + + + + + + + + + @if ($i === 0) + + + + + @endif + + @endforeach + @endforeach + + + + + + + + + + + + + + + + +
EMPRESABancoCuentaSaldo AnteriorSaldo ActualDiferenciaFFMMDAPSaldo EmpresaTotal CuentasTotal FFMMTotal DAPCaja Total
EMPRESAINGRESOSEGRESOSFECHABANCODESCRIPCIÓN
{{strtoupper($tipo)}}
{{$movimiento->cuenta->inmobiliaria->razon}}{{$format->pesos($movimiento->abono)}}{{$format->pesos($movimiento->cargo)}}{{$movimiento->fecha->format('d/m/Y')}}{{$movimiento->cuenta->banco->nombre}}{{$movimiento->glosa}}
{{$informe->inmobiliaria->razon}}{{$cuenta->banco}}{{$cuenta->numero}}{{$format->pesos($cuenta->anterior)}}{{$format->pesos($cuenta->actual)}}{{$format->pesos($cuenta->diferencia())}}{{$format->pesos($cuenta->ffmm)}}{{$format->pesos($cuenta->deposito)}}{{$format->pesos($cuenta->saldo())}}{{$format->pesos($informe->total())}}{{$format->pesos($informe->ffmm())}}{{$format->pesos($informe->deposito())}}{{$format->pesos($informe->caja())}}
TOTAL{{$format->pesos($informes['totales']->anterior)}}{{$format->pesos($informes['totales']->actual)}}{{$format->pesos($informes['totales']->diferencia())}}{{$format->pesos($informes['totales']->ffmm)}}{{$format->pesos($informes['totales']->deposito)}}{{$format->pesos($informes['totales']->saldo())}}{{$format->pesos($informes['totales']->cuentas())}}{{$format->pesos($informes['totales']->ffmms())}}{{$format->pesos($informes['totales']->depositos())}}{{$format->pesos($informes['totales']->caja())}}
+ + + + + + + + + + + + + @foreach ($informes['movimientos'] as $tipo => $movimientos) + @if ($tipo === 'capital dap') + @if (count($movimientos['ingresos']) === 0 and count($movimientos['egresos']) === 0) @continue @endif - @foreach ($movimientos as $movimiento) - - - - - - - - + @foreach ($movimientos as $ms) + @foreach ($ms as $movimiento) + + + + + + + + + @endforeach @endforeach + @continue + @endif + @if (count($movimientos) === 0) + @continue + @endif + + + + @foreach ($movimientos as $movimiento) + + + + + + + + @endforeach - -
EMPRESAINGRESOSEGRESOSFECHABANCODESCRIPCIÓN
{{strtoupper($tipo)}}
{{$movimiento->cuenta->inmobiliaria->razon}}{{$format->pesos($movimiento->abono)}}{{$format->pesos($movimiento->cargo)}}{{$movimiento->fecha->format('d/m/Y')}}{{$movimiento->cuenta->banco->nombre}}{{$movimiento->glosa}}
{{$movimiento->cuenta->inmobiliaria->razon}}{{$format->pesos($movimiento->abono)}}{{$format->pesos($movimiento->cargo)}}{{$movimiento->fecha->format('d/m/Y')}}{{$movimiento->cuenta->banco->nombre}}{{$movimiento->glosa}}
{{strtoupper($tipo)}}
{{$movimiento->cuenta->inmobiliaria->razon}}{{$format->pesos($movimiento->abono)}}{{$format->pesos($movimiento->cargo)}}{{$movimiento->fecha->format('d/m/Y')}}{{$movimiento->cuenta->banco->nombre}}{{$movimiento->glosa}}
+ @endforeach + + @endsection diff --git a/app/setup/settings/folders.php b/app/setup/settings/folders.php index e4d1e05..fdcd50d 100644 --- a/app/setup/settings/folders.php +++ b/app/setup/settings/folders.php @@ -8,7 +8,8 @@ return [ 'cache' => DI\String('{base}/cache'), 'templates' => DI\String('{resources}/views'), 'public' => DI\String('{base}/public'), - 'uploads' => DI\String('{public}/uploads') + 'uploads' => DI\String('{public}/uploads'), + 'informes' => DI\String('{public}/informes') ]); } ]; diff --git a/app/setup/setups/services.php b/app/setup/setups/services.php index 146b6f1..aaec098 100644 --- a/app/setup/setups/services.php +++ b/app/setup/setups/services.php @@ -61,5 +61,20 @@ return [ new GuzzleHttp\Client(), $container->get(Psr\Http\Message\RequestFactoryInterface::class), $container->get('nubox')->get('url')); + }, + Incoviba\Service\Informe::class => function(ContainerInterface $container) { + return (new Incoviba\Service\Informe( + $container->get(Psr\Log\LoggerInterface::class), + $container->get('folders')->get('informes')) + ) + ->register('xlsx', Incoviba\Service\Informe\Excel::class); + }, + Incoviba\Service\Contabilidad\Informe\Tesoreria\Excel::class => function(ContainerInterface $container) { + return new Incoviba\Service\Contabilidad\Informe\Tesoreria\Excel( + $container->get(Psr\Log\LoggerInterface::class), + $container->get('folders')->get('informes'), + $container->get(Incoviba\Service\UF::class), + $container->get(Incoviba\Service\USD::class) + ); } ]; diff --git a/app/src/Controller/Contabilidad.php b/app/src/Controller/Contabilidad.php index ab7cdf1..cf83532 100644 --- a/app/src/Controller/Contabilidad.php +++ b/app/src/Controller/Contabilidad.php @@ -62,12 +62,13 @@ class Contabilidad extends Controller return $view->render($response, 'contabilidad.depositos', compact('inmobiliarias', 'activos', 'vencidos')); } public function tesoreria(ServerRequestInterface $request, ResponseInterface $response, View $view, - Service\Contabilidad\Informe\Tesoreria $contabilidadService, + Service\Contabilidad\Informe\Tesoreria $contabilidadService, string $fecha = 'today'): ResponseInterface { $fecha = new DateTimeImmutable($fecha); $anterior = $contabilidadService->getAnterior($fecha); $informes = $contabilidadService->build($fecha); - return $view->render($response, 'contabilidad.informes.tesoreria', compact('fecha', 'anterior', 'informes')); + $filename = "Informe de Tesorería {$fecha->format('d.m.Y')}"; + return $view->render($response, 'contabilidad.informes.tesoreria', compact('fecha', 'anterior', 'informes', 'filename')); } } diff --git a/app/src/Controller/Contabilidad/Informes.php b/app/src/Controller/Contabilidad/Informes.php new file mode 100644 index 0000000..6f3dc14 --- /dev/null +++ b/app/src/Controller/Contabilidad/Informes.php @@ -0,0 +1,20 @@ +buildInforme($fecha, $tesoreriaService->build($fecha)); + $response->getBody()->write(file_get_contents('php://output')); + return $response; + } +} diff --git a/app/src/Service/Contabilidad/Informe/Tesoreria.php b/app/src/Service/Contabilidad/Informe/Tesoreria.php index cb8b39e..63ff55c 100644 --- a/app/src/Service/Contabilidad/Informe/Tesoreria.php +++ b/app/src/Service/Contabilidad/Informe/Tesoreria.php @@ -4,10 +4,12 @@ namespace Incoviba\Service\Contabilidad\Informe; use DateTimeInterface; use DateInterval; use Psr\Log\LoggerInterface; +use PhpOffice\PhpSpreadsheet; use Incoviba\Common\Ideal; use Incoviba\Common\Implement; -use Incoviba\Repository; use Incoviba\Model; +use Incoviba\Repository; +use Incoviba\Service; class Tesoreria extends Ideal\Service { @@ -16,7 +18,9 @@ class Tesoreria extends Ideal\Service protected Repository\Inmobiliaria\Cuenta $cuentaRepository, protected Repository\Deposito $depositoRepository, protected Repository\Cartola $cartolaRepository, - protected Repository\Movimiento $movimientoRepository) + protected Repository\Movimiento $movimientoRepository, + protected Service\Contabilidad\Informe\Tesoreria\Excel $excelService, + protected Service\Contabilidad\Informe\Tesoreria\PDF $pdfService) { parent::__construct($logger); @@ -123,8 +127,16 @@ class Tesoreria extends Ideal\Service } $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 { @@ -277,4 +289,5 @@ class Tesoreria extends Ideal\Service $this->totales->{$tipo} += $total; return $this; } + } diff --git a/app/src/Service/Contabilidad/Informe/Tesoreria/Excel.php b/app/src/Service/Contabilidad/Informe/Tesoreria/Excel.php new file mode 100644 index 0000000..080f4de --- /dev/null +++ b/app/src/Service/Contabilidad/Informe/Tesoreria/Excel.php @@ -0,0 +1,493 @@ +format('d.m.Y')}"; + $informe = new PhpSpreadsheet\Spreadsheet(); + $informe->getProperties() + ->setCompany('Incoviba') + ->setCreator('admin@incoviba.cl') + ->setTitle($title) + ->setSubject($title) + ->setCreated($fecha->getTimestamp()); + + $styles = [ + 'font' => [ + 'name' => 'Gill Sans MT', + 'size' => 12 + ] + ]; + $informe->getDefaultStyle()->applyFromArray($styles); + + $sheet = $informe->getActiveSheet(); + $sheet->setTitle($title); + + $sheet->getColumnDimension('A')->setWidth('5.43'); + + $this->fillTitle($sheet, $fecha); + $this->fillFechas($sheet, $fecha); + $this->fillMonedas($sheet, $fecha); + + $finalRow = $this->fillEmpresas($sheet, $data); + $finalRow = $this->fillCaja($sheet, $data, $finalRow + 2); + + foreach (range('B', 'V') as $columnIndex) { + $sheet->getColumnDimension($columnIndex)->setAutoSize(true); + } + + $this->setPageSetup($sheet, $finalRow); + + return $informe; + } + public function save(DateTimeInterface $fecha, PhpSpreadsheet\Spreadsheet $informe, string $type = 'Xlsx', ?string $filename = null): void + { + if ($filename === null) { + $ext = strtolower($type); + $filename = implode(DIRECTORY_SEPARATOR, [$this->folder, "{$informe->getActiveSheet()->getTitle()}.{$ext}"]); + } + $writer = PhpSpreadsheet\IOFactory::createWriter($informe, $type); + + if (str_starts_with($filename, 'php://')) { + $downloadFilename = "Informe de Tesorería {$fecha->format('d.m.Y')}.xlsx"; + // ZipStream, used by PhpSpreadsheet when saving, sends headers + header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); + header("Content-Disposition: attachment;filename=\"{$downloadFilename}\""); + header('Cache-Control: max-age=0'); + } + + $writer->save($filename); + } + + protected 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; + } + protected function fillTitle(PhpSpreadsheet\Worksheet\Worksheet $sheet, DateTimeInterface $fecha): void + { + $intl = new IntlDateFormatter('es-CL'); + $intl->setPattern('dd MMM yyyy'); + + $sheet->getCell('B2')->setValue('CONTROL DIARIO CAJA EMPRESAS'); + $sheet->mergeCells('B2:V2'); + $styles = [ + 'font' => [ + 'bold' => true, + 'size' => 18 + ], + 'fill' => [ + 'fillType' => PhpSpreadsheet\Style\Fill::FILL_SOLID, + 'startColor' => [ + 'argb' => 'FFFFC000' + ] + ], + 'alignment' => [ + 'horizontal' => PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER + ], + 'borders' => [ + 'outline' => [ + 'borderStyle' => PhpSpreadsheet\Style\Border::BORDER_THIN + ] + ] + ]; + $sheet->getStyle('B2:V2')->applyFromArray($styles); + $sheet->getCell('B3')->setValue(PhpSpreadsheet\Shared\Date::PHPToExcel($fecha)); + $styles = [ + 'font' => [ + 'size' => 18 + ], + 'alignment' => [ + 'horizontal' => PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER + ], + 'numberFormat' => [ + 'formatCode' => 'DD MMMM YYYY' + ] + ]; + $sheet->getCell('B3')->getStyle()->applyFromArray($styles); + $sheet->mergeCells('B3:V3'); + } + protected function fillFechas(PhpSpreadsheet\Worksheet\Worksheet $sheet, DateTimeInterface $fecha): void + { + $anterior = $this->getAnterior($fecha); + $sheet->getCell('B4')->setValue('Informe anterior'); + $sheet->getCell('B5')->setValue('Informe actual'); + $sheet->getCell('C4')->setValue(PhpSpreadsheet\Shared\Date::PHPToExcel($anterior)); + $sheet->getCell('C5')->setValue(PhpSpreadsheet\Shared\Date::PHPToExcel($fecha)); + $sheet->getStyle('C4:C5')->getNumberFormat()->setFormatCode(PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_DDMMYYYY); + $sheet->getStyle('B4:C5')->getBorders()->getOutline()->setBorderStyle(PhpSpreadsheet\Style\Border::BORDER_THIN); + } + protected function fillMonedas(PhpSpreadsheet\Worksheet\Worksheet $sheet, DateTimeInterface $fecha): void + { + $sheet->getCell('E4')->setValue('Valor UF'); + $sheet->getCell('E5')->setValue('Valor Dólar'); + $sheet->getCell('F4')->setValue($this->ufService->get($fecha)); + $sheet->getCell('F5')->setValue($this->usdService->get($fecha)); + $sheet->getStyle('F4:F5')->getNumberFormat()->setFormatCode("$ #,##0.00"); + $sheet->getStyle('E4:F5')->getBorders()->getOutline()->setBorderStyle(PhpSpreadsheet\Style\Border::BORDER_THIN); + } + protected function fillEmpresas(PhpSpreadsheet\Worksheet\Worksheet $sheet, array $data, int $startRow = 7): int + { + $columns = ['EMPRESA', 'Banco', 'Cuenta', 'Saldo anterior', 'Saldo actual', 'Diferencia', 'FFMM', 'DAP', + 'Saldo empresa', 'Total Cuentas', 'Total FFMM', 'Total DAP', 'Caja Total']; + $styles = [ + 'alignment' => [ + 'horizontal' => PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER + ], + 'borders' => [ + 'outline' => [ + 'borderStyle' => PhpSpreadsheet\Style\Border::BORDER_THIN + ] + ], + 'fill' => [ + 'fillType' => PhpSpreadsheet\Style\Fill::FILL_SOLID, + 'color' => [ + 'argb' => 'FF333F4F' + ] + ], + 'font' => [ + 'color' => [ + 'argb' => PhpSpreadsheet\Style\Color::COLOR_WHITE + ] + ] + ]; + $this->fillColumns($sheet, $columns, $styles, $startRow); + + $rowIndex = $startRow + 1; + foreach ($data['inmobiliarias'] as $dataInmobiliaria) { + $rowIndex += $this->fillInmobiliaria($sheet, $dataInmobiliaria, $rowIndex); + } + $finalRow = $rowIndex; + + $sheet->getStyle("B7:N{$finalRow}")->getBorders()->getAllBorders() + ->setBorderStyle(PhpSpreadsheet\Style\Border::BORDER_THIN) + ->getColor()->setARGB('FFD9D9D9'); + $sheet->getStyle("C8:D{$finalRow}")->getAlignment() + ->setHorizontal(PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER); + + $this->fillTotals($sheet, 7, $finalRow ++); + $sheet->getStyle("E8:N{$finalRow}")->getNumberFormat() + ->setFormatCode(self::CURRENCY_CODE); + + return $finalRow; + } + protected function fillCaja(PhpSpreadsheet\Worksheet\Worksheet $sheet, array $data, $startRow): int + { + $sheet->getCell("B{$startRow}")->setValue('CUADRATURA CAJA DÍA ANTERIOR'); + $sheet->mergeCells("B{$startRow}:V{$startRow}"); + + $sheet->getStyle("B{$startRow}:V{$startRow}")->applyFromArray([ + 'alignment' => [ + 'horizontal' => PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER + ], + 'borders' => [ + 'outline' => [ + 'borderStyle' => PhpSpreadsheet\Style\Border::BORDER_THIN + ] + ], + 'font' => [ + 'bold' => true + ], + 'fill' => [ + 'fillType' => PhpSpreadsheet\Style\Fill::FILL_SOLID, + 'color' => [ + 'argb' => 'FFFFC000' + ] + ] + ]); + + $rowIndex = $startRow; + + $columns = ['EMPRESA', 'INGRESOS', 'EGRESOS', 'FECHA', 'BANCO', 'DESCRIPCIÓN', '', 'CATEGORIA', '', 'CC', + 'DETALLE', '', 'N° DOC.', 'RUT', 'NOMBRES', '', '', '', '', '', '']; + $styles = [ + 'borders' => [ + 'allBorders' => [ + 'borderStyle' => PhpSpreadsheet\Style\Border::BORDER_THIN + ] + ], + 'fill' => [ + 'fillType' => PhpSpreadsheet\Style\Fill::FILL_SOLID, + 'startColor' => [ + 'argb' => 'FFD9D9D9' + ] + ] + ]; + + $this->fillColumns($sheet, $columns, $styles, ++ $rowIndex); + $sheet->mergeCells("G{$rowIndex}:H{$rowIndex}") + ->mergeCells("I{$rowIndex}:J{$rowIndex}") + ->mergeCells("L{$rowIndex}:M{$rowIndex}") + ->mergeCells("P{$rowIndex}:R{$rowIndex}") + ->mergeCells("S{$rowIndex}:V{$rowIndex}"); + + $rowIndex += 2; + $sheet->getCell("T{$rowIndex}") + ->setValue("Saldo Consolidado al") + ->getStyle()->applyFromArray([ + 'alignment' => [ + 'horizontal' => PhpSpreadsheet\Style\Alignment::HORIZONTAL_RIGHT + ], + 'font' => [ + 'bold' => true + ] + ]); + $sheet->getCell("U{$rowIndex}")->setValue("=C5") + ->getStyle()->applyFromArray([ + 'font' => [ + 'bold' => true + ], + 'numberFormat' => [ + 'formatCode' => PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_DDMMYYYY + ] + ]); + $sheet->getCell("V{$rowIndex}")->setValue(0)->getStyle()->applyFromArray([ + 'font' => [ + 'bold' => true + ], + 'numberFormat' => [ + 'formatCode' => self::CURRENCY_CODE + ] + ]); + $rowIndex ++; + + $styles = [ + 'fill' => [ + 'fillType' => PhpSpreadsheet\Style\Fill::FILL_SOLID, + 'startColor' => [ + 'argb' => 'FFD9E1F2' + ] + ], + 'font' => [ + 'bold' => true + ] + ]; + foreach ($data['movimientos'] as $tipo => $movimientos) { + if ($tipo === 'capital dap') { + $sheet->getCell("B{$rowIndex}")->setValue('CAPITAL DAP'); + $sheet->getCell("T{$rowIndex}")->setValue('SUMA DAP'); + $sheet->getStyle("B{$rowIndex}:V{$rowIndex}")->applyFromArray($styles); + $sheet->getCell("V{$rowIndex}")->getStyle()->getNumberFormat()->setFormatCode(self::CURRENCY_CODE); + $totalRow = $rowIndex; + $rowIndex ++; + if (count($movimientos['ingresos']) === 0 and count($movimientos['egresos']) === 0) { + $sheet->getCell("V{$totalRow}")->setValue(0); + continue; + } + $start = $rowIndex; + foreach ($movimientos as $ms) { + foreach ($ms as $movimiento) { + $sheet->getCell("B{$rowIndex}")->setValue($movimiento->cuenta->inmobiliaria->razon); + $sheet->getCell("C{$rowIndex}")->setValue($movimiento->abono); + $sheet->getCell("D{$rowIndex}")->setValue($movimiento->cargo); + $sheet->getCell("E{$rowIndex}")->setValue(PhpSpreadsheet\Shared\Date::PHPToExcel($movimiento->fecha)); + $sheet->getCell("F{$rowIndex}")->setValue($movimiento->cuenta->banco->nombre); + $sheet->getCell("G{$rowIndex}")->setValue($movimiento->glosa); + $rowIndex ++; + } + } + $end = $rowIndex; + $sheet->getCell("V{$totalRow}")->setValue("=SUM(C{$start}:D{$end})"); + $sheet->getStyle("C{$start}:D{$end}")->getNumberFormat()->setFormatCode(self::CURRENCY_CODE); + continue; + } + $sheet->getCell("B{$rowIndex}")->setValue(strtoupper($tipo)); + $sheet->getCell("T{$rowIndex}")->setValue('SUMA '.strtoupper($tipo)); + $sheet->getStyle("B{$rowIndex}:V{$rowIndex}")->applyFromArray($styles); + $sheet->getCell("V{$rowIndex}")->getStyle()->getNumberFormat() + ->setFormatCode(self::CURRENCY_CODE); + $totalRow = $rowIndex; + $rowIndex ++; + if (count($movimientos) === 0) { + $sheet->getCell("V{$totalRow}")->setValue(0); + continue; + } + $start = $rowIndex; + foreach ($movimientos as $movimiento) { + $sheet->getCell("B{$rowIndex}")->setValue($movimiento->cuenta->inmobiliaria->razon); + $sheet->getCell("C{$rowIndex}")->setValue($movimiento->abono); + $sheet->getCell("D{$rowIndex}")->setValue($movimiento->cargo); + $sheet->getCell("E{$rowIndex}")->setValue(PhpSpreadsheet\Shared\Date::PHPToExcel($movimiento->fecha)); + $sheet->getCell("F{$rowIndex}")->setValue($movimiento->cuenta->banco->nombre); + $sheet->getCell("G{$rowIndex}")->setValue($movimiento->glosa); + $rowIndex ++; + } + $end = $rowIndex; + $sheet->getCell("V{$totalRow}")->setValue("=SUM(C{$start}:D{$end})"); + $sheet->getStyle("C{$start}:D{$end}")->getNumberFormat() + ->setFormatCode(self::CURRENCY_CODE); + } + $end = $rowIndex; + $rowIndex ++; + + $sheet->getCell("B{$rowIndex}")->setValue('TOTAL'); + $sheet->getCell("C{$rowIndex}")->setValue("=SUM(C{$startRow}:C{$end})"); + $sheet->getCell("D{$rowIndex}")->setValue("=SUM(D{$startRow}:D{$end})"); + $sheet->getCell("T{$rowIndex}")->setValue('Saldo final al') + ->getStyle()->applyFromArray([ + 'alignment' => [ + 'horizontal' => PhpSpreadsheet\Style\Alignment::HORIZONTAL_RIGHT + ], + 'font' => [ + 'bold' => true + ] + ]); + $sheet->getCell("U{$rowIndex}")->setValue('=C5') + ->getStyle()->applyFromArray([ + 'font' => [ + 'bold' => true + ], + 'numberFormat' => [ + 'formatCode' => PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_DDMMYYYY + ] + ]); + $sheet->getCell("V{$rowIndex}")->setValue(0)->getStyle()->applyFromArray([ + 'font' => [ + 'bold' => true + ], + 'numberFormat' => [ + 'formatCode' => self::CURRENCY_CODE + ] + ]); + + $sheet->getStyle("B{$rowIndex}:V{$rowIndex}")->applyFromArray([ + 'fill' => [ + 'fillType' => PhpSpreadsheet\Style\Fill::FILL_SOLID, + 'startColor' => [ + 'argb' => 'FFD9D9D9' + ] + ], + 'font' => [ + 'bold' => true + ] + ]); + $sheet->getStyle("C{$startRow}:D{$rowIndex}")->getNumberFormat()->setFormatCode(self::CURRENCY_CODE); + $columnRanges = [ + ['B', 'B'], + ['C', 'C'], + ['D', 'D'], + ['E', 'E'], + ['F', 'F'], + ['G', 'H'], + ['I', 'J'], + ['K', 'K'], + ['L', 'M'], + ['N', 'N'], + ['O', 'O'], + ['P', 'R'], + ['S', 'V'] + ]; + foreach ($columnRanges as $range) { + $sheet->getStyle("{$range[0]}{$startRow}:{$range[1]}{$rowIndex}")->getBorders()->getOutline() + ->setBorderStyle(PhpSpreadsheet\Style\Border::BORDER_THIN); + } + + return $rowIndex; + } + protected function fillColumns(PhpSpreadsheet\Worksheet\Worksheet $sheet, array $columns, array $styles, $rowIndex): void + { + $columnIndex = 2; + foreach ($columns as $index => $column) { + $columnIndex = 2 + $index; + $sheet->getCell([$columnIndex, $rowIndex])->setValue($column); + } + $sheet->getStyle([2, $rowIndex, $columnIndex, $rowIndex])->applyFromArray($styles); + } + protected function fillInmobiliaria(PhpSpreadsheet\Worksheet\Worksheet $sheet, object $dataInmobiliaria, int $baseRowIndex): int + { + $rowIndex = $baseRowIndex; + $sheet->getCell("B{$rowIndex}")->setValue($dataInmobiliaria->inmobiliaria->razon); + foreach ($dataInmobiliaria->cuentas as $cuentaRowIndex => $cuenta) { + $this->fillCuenta($sheet, $cuenta, 3, $baseRowIndex + $cuentaRowIndex); + } + $sheet->getCell("K{$rowIndex}")->setValue($dataInmobiliaria->total()); + $sheet->getCell("L{$rowIndex}")->setValue($dataInmobiliaria->ffmm()); + $sheet->getCell("M{$rowIndex}")->setValue($dataInmobiliaria->deposito()); + $sheet->getCell("N{$rowIndex}")->setValue($dataInmobiliaria->caja()); + + if (count($dataInmobiliaria->cuentas) > 1) { + $finalRow = $rowIndex + count($dataInmobiliaria->cuentas) - 1; + $sheet->mergeCells("B{$rowIndex}:B{$finalRow}"); + $sheet->mergeCells("K{$rowIndex}:K{$finalRow}"); + $sheet->mergeCells("L{$rowIndex}:L{$finalRow}"); + $sheet->mergeCells("M{$rowIndex}:M{$finalRow}"); + $sheet->mergeCells("N{$rowIndex}:N{$finalRow}"); + } + return count($dataInmobiliaria->cuentas); + } + protected function fillCuenta(PhpSpreadsheet\Worksheet\Worksheet $sheet, object $cuenta, int $startColumnIndex, int $rowIndex): void + { + $columnIndex = $startColumnIndex; + $sheet->getCell([$columnIndex ++, $rowIndex])->setValue($cuenta->banco); + $sheet->getCell([$columnIndex ++, $rowIndex])->setValue($cuenta->numero); + $sheet->getCell([$columnIndex ++, $rowIndex])->setValue($cuenta->anterior); + $sheet->getCell([$columnIndex ++, $rowIndex])->setValue($cuenta->actual); + $sheet->getCell([$columnIndex ++, $rowIndex])->setValue("=F{$rowIndex}-E{$rowIndex}"); + $sheet->getCell([$columnIndex ++, $rowIndex])->setValue($cuenta->ffmm); + $sheet->getCell([$columnIndex ++, $rowIndex])->setValue($cuenta->deposito); + $sheet->getCell([$columnIndex, $rowIndex])->setValue("=SUM(F{$rowIndex},H{$rowIndex}:I{$rowIndex})"); + } + protected function fillTotals(PhpSpreadsheet\Worksheet\Worksheet $sheet, int $startRow, int $finalRow): void + { + $rowIndex = $finalRow + 1; + $sheet->getCell("B{$rowIndex}")->setValue('TOTAL'); + foreach (range('E', 'N') as $columnIndex) { + $sheet->getCell("{$columnIndex}{$rowIndex}")->setValue("=SUBTOTAL(109,{$columnIndex}{$startRow}:{$columnIndex}{$finalRow})"); + } + + $styles = [ + 'font' => [ + 'bold' => true + ], + 'fill' => [ + 'fillType' => PhpSpreadsheet\Style\Fill::FILL_SOLID, + 'startColor' => [ + 'argb' => 'FFD9D9D9' + ] + ], + 'borders' => [ + 'outline' => [ + 'borderStyle' => PhpSpreadsheet\Style\Border::BORDER_THIN, + 'color' => [ + 'argb' => PhpSpreadsheet\Style\Color::COLOR_BLACK + ] + ] + ] + ]; + $sheet->getStyle("B{$rowIndex}:N{$rowIndex}")->applyFromArray($styles); + } + protected function setPageSetup(PhpSpreadsheet\Worksheet\Worksheet $sheet, int $finalRow): void + { + $sheet->getPageSetup() + ->setPrintArea("B2:V{$finalRow}") + ->setFitToWidth(1) + ->setPaperSize(PhpSpreadsheet\Worksheet\PageSetup::PAPERSIZE_LEGAL) + ->setOrientation(PhpSpreadsheet\Worksheet\PageSetup::ORIENTATION_LANDSCAPE); + $sheet->setShowGridlines(false); + $sheet->getSheetView() + ->setView(PhpSpreadsheet\Worksheet\SheetView::SHEETVIEW_PAGE_BREAK_PREVIEW) + ->setZoomScale(70); + } +} diff --git a/app/src/Service/Contabilidad/Informe/Tesoreria/PDF.php b/app/src/Service/Contabilidad/Informe/Tesoreria/PDF.php new file mode 100644 index 0000000..7357299 --- /dev/null +++ b/app/src/Service/Contabilidad/Informe/Tesoreria/PDF.php @@ -0,0 +1,12 @@ +folder)) { + mkdir($this->folder); + } + } + + protected array $informes; + + public function register(string $name, string $informeClass): Informe + { + $this->informes[$name] = $informeClass; + return $this; + } + + public function build(string $type, string $filename, string $title, array $data): void + { + $informe = new $this->informes[$type](); + $filename = implode(DIRECTORY_SEPARATOR, [$this->folder, "{$filename}.xlsx"]); + $informe->setFilename($filename); + $informe->setTitle($title); + $informe->addData($data); + $informe->build(); + } +} diff --git a/app/src/Service/Informe/Excel.php b/app/src/Service/Informe/Excel.php new file mode 100644 index 0000000..f11e8a3 --- /dev/null +++ b/app/src/Service/Informe/Excel.php @@ -0,0 +1,63 @@ +title = $title; + return $this; + } + public function setFilename(string $filename): Excel + { + $this->filename = $filename; + return $this; + } + public function addData(array $rows): Excel + { + foreach ($rows as $row) { + $this->addRow($row); + } + return $this; + } + public function addRow(array $row): Excel + { + foreach ($row as $cell) { + $this->addCell($cell); + } + return $this; + } + public function addCell(PhpSpreadsheet\Cell\Cell $cell): Excel + { + $this->data []= $cell; + return $this; + } + + public function build(): void + { + $spreadsheet = new PhpSpreadsheet\Spreadsheet(); + $spreadsheet->getProperties() + ->setCreator('admin@incoviba.cl') + ->setSubject($this->title) + ->setCompany('Incoviba') + ->setTitle($this->title); + $sheet = $spreadsheet->getActiveSheet(); + $sheet->setTitle($this->title); + + foreach ($this->data as $rowIndex => $row) { + foreach ($row as $columnIndex => $cell) { + $sheet->getCell([$columnIndex + 1, $rowIndex + 1])->setValue($cell); + } + } + + $writer = PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xlsx'); + $writer->save($this->filename); + } +}