diff --git a/.env.sample b/.env.sample index 31fe938..76074d2 100644 --- a/.env.sample +++ b/.env.sample @@ -1,2 +1,3 @@ +COMPOSE_PROFILES= BASE_URL= MYSQL_HOST= diff --git a/Dockerfile b/Dockerfile index 1189fae..33834f0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,10 @@ -FROM php:7.4-fpm +FROM php:8.1-fpm -RUN apt-get update && apt-get install -y libzip-dev libicu-dev git +RUN apt-get update && apt-get install -y libzip-dev libicu-dev git libpng-dev unzip -RUN docker-php-ext-install pdo pdo_mysql zip intl +RUN docker-php-ext-install pdo pdo_mysql zip intl gd -RUN pecl install xdebug-3.0.3 \ +RUN pecl install xdebug-3.1.3 \ && docker-php-ext-enable xdebug COPY --from=composer /usr/bin/composer /usr/bin/composer diff --git a/app/Controller/Informes.php b/app/Controller/Informes.php index 67cb000..43862a2 100644 --- a/app/Controller/Informes.php +++ b/app/Controller/Informes.php @@ -1,10 +1,12 @@ findOne($id); $fecha = get('fecha'); + + $service = new Resumen(); + $service->build($id, new \DateTimeImmutable($fecha)); + + return; + + $proyecto = model(Proyecto::class)->findOne($id); $mes = null; if ($fecha != null) { $mes = Carbon::parse($fecha)->addMonths(1)->subDays(1); diff --git a/app/Service/Informe/Contabilidad/Resumen.php b/app/Service/Informe/Contabilidad/Resumen.php new file mode 100644 index 0000000..cad97df --- /dev/null +++ b/app/Service/Informe/Contabilidad/Resumen.php @@ -0,0 +1,155 @@ +separator = $separator; + } + + protected function getVentas($id_proyecto) + { + $proyecto = model(Proyecto::class)->findOne($id_proyecto); + return $proyecto->ventas(); + } + protected function startOfYear(DateTimeInterface $up_to) + { + return new DateTimeImmutable(DateTimeImmutable::createFromInterface($up_to)->format('1-1-Y')); + } + protected function defaultValueDate(DateTimeInterface $up_to) + { + return (object) ['fecha' => $this->startOfYear($up_to), 'valor' => 0]; + } + protected function extractValueDate(Pago $pago) + { + return (object) ['fecha' => $pago->fecha(), 'valor' => $pago->valor]; + } + protected function getAnticipos(Venta $venta, DateTimeInterface $up_to) + { + $cuotas = $venta->pie()->cuotas('fecha', $up_to); + $ly = $this->startOfYear($up_to); + $older = array_reduce($cuotas, function($sum, $item) use ($ly) { + if ($item->pago()->estado()->tipo()->active != 1) { + return $sum; + } + if ($item->pago()->fecha() >= $ly) { + return $sum; + } + return $sum + $item->pago()->valor; + }); + $current = array_map([$this, 'extractValueDate'], array_filter($cuotas, function($item) use ($ly) { + return $item->pago()->fecha() >= $ly; + })); + return array_merge([(object) ['fecha' => $ly, 'valor' => $older]], $current); + } + protected function getReajuste(Venta $venta, DateTimeInterface $up_to) + { + if ($venta->pie()->reajuste == null) { + return $this->defaultValueDate($up_to); + } + return $this->extractValueDate($venta->pie()->reajuste()); + } + protected function getAbono(Venta $venta, DateTimeInterface $up_to) + { + if ($venta->escritura == null) { + return $this->defaultValueDate($up_to); + } + return $this->extractValueDate($venta->escritura()->pago()); + } + protected function getBono(Venta $venta, DateTimeInterface $up_to) + { + if ($venta->bono_pie == null) { + return $this->defaultValueDate($up_to); + } + return $this->extractValueDate($venta->bonoPie()->pago()); + } + protected function getCredito(Venta $venta, DateTimeInterface $up_to) + { + if ($venta->credito == null) { + return $this->defaultValueDate($up_to); + } + return $this->extractValueDate($venta->credito()->pago()); + } + protected function getSubsidio(Venta $venta, DateTimeInterface $up_to) + { + if ($venta->subsidio == null) { + return $this->defaultValueDate($up_to); + } + return [$this->extractValueDate($venta->subsidio()->pago()), $this->extractValueDate($venta->subsidio()->subsidio())]; + } + protected function getPagos(Venta $venta, DateTimeInterface $up_to) + { + $pagos = []; + $pagos = array_merge($pagos, $this->getAnticipos($venta, $up_to)); + $pagos []= $this->getReajuste($venta, $up_to); + $pagos []= $this->getAbono($venta, $up_to); + $pagos []= $this->getBono($venta, $up_to); + $pagos []= $this->getCredito($venta, $up_to); + $pagos = array_merge($pagos, $this->getSubsidio($venta, $up_to)); + return array_filter($pagos, function($item) { + return $item->valor != 0; + }); + } + + protected function formatValue(float $value) + { + return number_format($value, 0, ',', '.'); + } + protected function buildLibro(Venta $venta, DateTimeInterface $up_to) + { + $pagos = $this->getPagos($venta, $up_to); + $output = ["Cuenta: Anticipos Dpto {$venta->unidad()->descripcion}"]; + $debe = 0; + $haber = 0; + foreach ($pagos as $pago) { + if ($pago->valor > 0) { + $output []= implode($this->separator, [$pago->fecha->format('d/m/Y'), $this->formatValue($pago->valor), '']); + $debe += $pago->valor; + } + else { + $output []= implode($this->separator, [$pago->fecha->format('d/m/Y'), '', $this->formatValue(-$pago->valor)]); + $haber -= $pago->valor; + } + } + $output []= implode($this->separator, ['', $debe, $haber]); + return $output; + } + + public function build(int $id_proyecto, DateTimeInterface $up_to) + { + $ventas = $this->getVentas($id_proyecto); + + + $output = []; + foreach ($ventas as $venta) { + $output = array_merge($output, $this->buildLibro($venta, $up_to), []); + } + + $filename = "Contabilidad - Resumen - {$venta->proyecto()->descripcion} - {$up_to->format('Y-m-d')}.csv"; + + header("Content-Type: text/csv; charset=utf-8"); + header('Content-Disposition: attachment; filename="' . $filename . '"'); + header('Cache-Control: max-age=0'); + + file_put_contents('php://output', implode(PHP_EOL, $output)); + } +} diff --git a/composer.json b/composer.json index 5b75c1b..9371935 100644 --- a/composer.json +++ b/composer.json @@ -12,9 +12,9 @@ "aldarien/url": "*", "j4mie/paris" : "^1.5", "danielstjules/stringy" : "^3.1", - "phpoffice/phpspreadsheet": "1-beta", + "phpoffice/phpspreadsheet": "^1", "nesbot/carbon": "^2", - "phpoffice/phpword": "^0.14.0", + "phpoffice/phpword": "^0", "slam/php-excel": "^4.4", "fabpot/goutte": "^3.2", "incoviba/modelos": "*", @@ -26,7 +26,7 @@ "vlucas/phpdotenv": "^5.3" }, "require-dev" : { - "phpunit/phpunit" : "^6.3", + "phpunit/phpunit" : "^8", "kint-php/kint" : "^2.1", "filp/whoops" : "^2.1" }, diff --git a/docker-compose.yml b/docker-compose.yml index df1c290..d6f865f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,21 +2,29 @@ version: '3' services: web: + profiles: + - app image: nginx:alpine container_name: web ports: - - 8080:80 + - "8080:80" volumes: - .:/code - ./nginx.conf:/etc/nginx/conf.d/default.conf php: + profiles: + - app build: . container_name: php + env_file: + - .env volumes: - .:/code db: + profiles: + - db container_name: db image: mariadb:latest restart: unless-stopped @@ -25,11 +33,13 @@ services: - dbdata:/var/lib/mysql adminer: + profiles: + - db container_name: adminer image: adminer:latest restart: unless-stopped ports: - - 8083:8080 + - "8083:8080" env_file: .adminer.env volumes: