From dc217d876a91c51fdf687502781bb536bb9610e0 Mon Sep 17 00:00:00 2001 From: Aldarien Date: Thu, 19 Oct 2023 20:46:52 -0300 Subject: [PATCH] Redis service --- app/common/Implement/Exception/EmptyRedis.php | 15 +++ app/composer.json | 1 + app/setup/setups/services.php | 7 ++ app/src/Controller/API/Ventas.php | 90 +++++++++------ app/src/Controller/API/Ventas/Cuotas.php | 103 +++++++++++------- app/src/Controller/API/Ventas/Unidades.php | 52 +++++---- app/src/Controller/API/withJson.php | 2 +- app/src/Controller/API/withRedis.php | 24 ++++ app/src/Service/Redis.php | 18 +++ docker-compose.yml | 13 +++ 10 files changed, 228 insertions(+), 97 deletions(-) create mode 100644 app/common/Implement/Exception/EmptyRedis.php create mode 100644 app/src/Controller/API/withRedis.php create mode 100644 app/src/Service/Redis.php diff --git a/app/common/Implement/Exception/EmptyRedis.php b/app/common/Implement/Exception/EmptyRedis.php new file mode 100644 index 0000000..cc6ac45 --- /dev/null +++ b/app/common/Implement/Exception/EmptyRedis.php @@ -0,0 +1,15 @@ +register('uf', $mindicador) ->register('ipc', $mindicador); }, + Predis\Client::class => function(ContainerInterface $container) { + return new Predis\Client([ + 'scheme' => 'tcp', + 'host' => $container->get('REDIS_HOST'), + 'port' => $container->get('REDIS_PORT') + ]); + } ]; diff --git a/app/src/Controller/API/Ventas.php b/app/src/Controller/API/Ventas.php index bdfc853..87deea0 100644 --- a/app/src/Controller/API/Ventas.php +++ b/app/src/Controller/API/Ventas.php @@ -1,6 +1,8 @@ withJson($response, $output); } - public function porFirmar(ServerRequestInterface $request, ResponseInterface $response, Service\Venta $ventaService): ResponseInterface + public function porFirmar(ServerRequestInterface $request, ResponseInterface $response, Service\Venta $ventaService, Service\Redis $redisService): ResponseInterface { $body = $request->getBody(); $json = json_decode($body->getContents()); $proyecto_id = $json->proyecto_id; + $today = new DateTimeImmutable(); + $redisKey = "promesas_por_firmar-{$proyecto_id}-{$today->format('Y-m-d')}"; + $output = [ 'proyecto_id' => $proyecto_id, 'promesas' => 0 ]; try { - $ventas = $ventaService->getByProyecto($proyecto_id); - $promesas = array_filter($ventas, function(Model\Venta $venta) { - return $venta->currentEstado()->tipoEstadoVenta->descripcion === 'vigente'; - }); - $output['promesas'] = count($promesas); - } catch (EmptyResult) {} + $output = $this->fetchRedis($redisService, $redisKey); + } catch (EmptyRedis) { + try { + $ventas = $ventaService->getByProyecto($proyecto_id); + $promesas = array_filter($ventas, function(Model\Venta $venta) { + return $venta->currentEstado()->tipoEstadoVenta->descripcion === 'vigente'; + }); + $output['promesas'] = count($promesas); + $this->saveRedis($redisService, $redisKey, $output); + } catch (EmptyResult) {} + } return $this->withJson($response, $output); } - public function escrituras(ServerRequestInterface $request, ResponseInterface $response, Service\Venta $ventaService, Service\Venta\Pago $pagoService): ResponseInterface + public function escrituras(ServerRequestInterface $request, ResponseInterface $response, Service\Venta $ventaService, Service\Venta\Pago $pagoService, Service\Redis $redisService): ResponseInterface { $body = $request->getBody(); $json = json_decode($body->getContents()); $proyecto_id = $json->proyecto_id; + $today = new DateTimeImmutable(); + $redisKey = "escrituras-{$proyecto_id}-{$today->format('Y-m-d')}"; + $output = [ 'proyecto_id' => $proyecto_id, 'escrituras' => [ @@ -78,35 +91,40 @@ class Ventas ] ]; try { - $ventas = $ventaService->getEscriturasByProyecto($proyecto_id); - $porFirmar = array_filter($ventas, function(Model\Venta $venta) { - return $venta->currentEstado()->tipoEstadoVenta->descripcion === 'escriturando'; - }); - $output['escrituras']['firmar'] = count($porFirmar); - unset($porFirmar); - $escrituras = array_filter($ventas, function(Model\Venta $venta) { - return $venta->currentEstado()->tipoEstadoVenta->descripcion === 'firmado por inmobiliaria'; - }); - unset($ventas); - $porPagar = array_filter($escrituras, function(Model\Venta $venta) use ($pagoService) { - $pagos = $pagoService->getByVenta($venta->id); - $porPagar = array_filter($pagos, function(Model\Venta\Pago $pago) { - return $pago->currentEstado->tipoEstadoPago->descripcion === 'no pagado'; + $output = $this->fetchRedis($redisService, $redisKey); + } catch (EmptyRedis) { + try { + $ventas = $ventaService->getEscriturasByProyecto($proyecto_id); + $porFirmar = array_filter($ventas, function(Model\Venta $venta) { + return $venta->currentEstado()->tipoEstadoVenta->descripcion === 'escriturando'; }); - return count($porPagar) > 0; - }); - $output['escrituras']['pagar'] = count($porPagar); - unset($porPagar); - $porAbonar = array_filter($escrituras, function(Model\Venta $venta) use ($pagoService) { - $pagos = $pagoService->getByVenta($venta->id); - $porPagar = array_filter($pagos, function(Model\Venta\Pago $pago) { - return $pago->currentEstado->tipoEstadoPago->descripcion === 'depositado'; + $output['escrituras']['firmar'] = count($porFirmar); + unset($porFirmar); + $escrituras = array_filter($ventas, function(Model\Venta $venta) { + return $venta->currentEstado()->tipoEstadoVenta->descripcion === 'firmado por inmobiliaria'; }); - return count($porPagar) > 0; - }); - $output['escrituras']['abonar'] = count($porAbonar); - unset($porAbonar); - } catch (EmptyResult) {} + unset($ventas); + $porPagar = array_filter($escrituras, function(Model\Venta $venta) use ($pagoService) { + $pagos = $pagoService->getByVenta($venta->id); + $porPagar = array_filter($pagos, function(Model\Venta\Pago $pago) { + return $pago->currentEstado->tipoEstadoPago->descripcion === 'no pagado'; + }); + return count($porPagar) > 0; + }); + $output['escrituras']['pagar'] = count($porPagar); + unset($porPagar); + $porAbonar = array_filter($escrituras, function(Model\Venta $venta) use ($pagoService) { + $pagos = $pagoService->getByVenta($venta->id); + $porPagar = array_filter($pagos, function(Model\Venta\Pago $pago) { + return $pago->currentEstado->tipoEstadoPago->descripcion === 'depositado'; + }); + return count($porPagar) > 0; + }); + $output['escrituras']['abonar'] = count($porAbonar); + unset($porAbonar); + $this->saveRedis($redisService, $redisKey, $output); + } catch (EmptyResult) {} + } return $this->withJson($response, $output); } public function comentarios(ServerRequestInterface $request, ResponseInterface $response, Service\Venta $service, Repository\Venta\Comentario $comentarioRepository, int $venta_id): ResponseInterface diff --git a/app/src/Controller/API/Ventas/Cuotas.php b/app/src/Controller/API/Ventas/Cuotas.php index 25a8545..32e8da5 100644 --- a/app/src/Controller/API/Ventas/Cuotas.php +++ b/app/src/Controller/API/Ventas/Cuotas.php @@ -3,71 +3,94 @@ namespace Incoviba\Controller\API\Ventas; use DateTimeImmutable; use DateInterval; -use Incoviba\Common\Implement\Exception\EmptyResult; -use Incoviba\Controller\API\withJson; +use Incoviba\Controller\API\withRedis; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; +use Incoviba\Common\Implement\Exception\EmptyRedis; +use Incoviba\Common\Implement\Exception\EmptyResult; +use Incoviba\Controller\API\withJson; use Incoviba\Repository; use Incoviba\Service; class Cuotas { - use withJson; - public function hoy(ServerRequestInterface $request, ResponseInterface $response, Repository\Venta\Cuota $cuotaRepository): ResponseInterface + use withJson, withRedis; + public function hoy(ServerRequestInterface $request, ResponseInterface $response, Repository\Venta\Cuota $cuotaRepository, Service\Redis $redisService): ResponseInterface { + $today = new DateTimeImmutable(); + $redisKey = "cuotas_hoy-{$today->format('Y-m-d')}"; $output = [ 'cuotas' => 0 ]; try { - $output['cuotas'] = count($cuotaRepository->fetchHoy()); - } catch (EmptyResult) {} + $output['cuotas'] = $this->fetchRedis($redisService, $redisKey); + } catch (EmptyRedis) { + try { + $output['cuotas'] = count($cuotaRepository->fetchHoy()); + $this->saveRedis($redisService, $redisKey, $output['cuotas']); + } catch (EmptyResult) {} + } return $this->withJson($response, $output); } - public function pendiente(ServerRequestInterface $request, ResponseInterface $response, Repository\Venta\Cuota $cuotaRepository): ResponseInterface + public function pendiente(ServerRequestInterface $request, ResponseInterface $response, Repository\Venta\Cuota $cuotaRepository, Service\Redis $redisService): ResponseInterface { + $today = new DateTimeImmutable(); + $redisKey = "cuotas_pendientes-{$today->format('Y-m-d')}"; $output = [ 'cuotas' => 0 ]; try { - $output['cuotas'] = count($cuotaRepository->fetchPendientes()); - } catch (EmptyResult) {} + $output['cuotas'] = $this->fetchRedis($redisService, $redisKey); + } catch (EmptyRedis) { + try { + $output['cuotas'] = count($cuotaRepository->fetchPendientes()); + $this->saveRedis($redisService, $redisKey, $output['cuotas']); + } catch (EmptyResult) {} + } return $this->withJson($response, $output); } - public function porVencer(ServerRequestInterface $request, ResponseInterface $response, Repository\Venta\Cuota $cuotaRepository, Service\Format $formatService): ResponseInterface + public function porVencer(ServerRequestInterface $request, ResponseInterface $response, Repository\Venta\Cuota $cuotaRepository, Service\Redis $redisService, Service\Format $formatService): ResponseInterface { - $output = []; + $today = new DateTimeImmutable(); + $redisKey = "cuotas_por_vencer-{$today->format('Y-m-d')}"; try { - $benchmark = [ - 'start' => microtime(true) - ]; - $cuotas = $cuotaRepository->fetchDatosPorVencer(); - $benchmark['cuotas'] = microtime(true) - $benchmark['start']; - foreach ($cuotas as $row) { - $fecha = $row['Fecha']; - $date = new DateTimeImmutable($fecha); - if (($weekday = $date->format('N')) > 5) { - $day_diff = 7 - $weekday + 1; - $date = $date->add(new DateInterval("P{$day_diff}D")); - $fecha = $date->format('Y-m-d'); + $output = $this->fetchRedis($redisService, $redisKey); + } catch (EmptyRedis) { + $output = []; + try { + $benchmark = [ + 'start' => microtime(true) + ]; + $cuotas = $cuotaRepository->fetchDatosPorVencer(); + $benchmark['cuotas'] = microtime(true) - $benchmark['start']; + foreach ($cuotas as $row) { + $fecha = $row['Fecha']; + $date = new DateTimeImmutable($fecha); + if (($weekday = $date->format('N')) > 5) { + $day_diff = 7 - $weekday + 1; + $date = $date->add(new DateInterval("P{$day_diff}D")); + $fecha = $date->format('Y-m-d'); + } + $key = $formatService->localDate($fecha, "EEE. dd 'de' MMMM 'de' yyyy", true); + if (!isset($output[$key])) { + $output[$key] = []; + } + if (!isset($output[$key][$row['Proyecto']])) { + $output[$key][$row['Proyecto']] = 0; + } + $output[$key][$row['Proyecto']] += $row['Cantidad']; } - $key = $formatService->localDate($fecha, "EEE. dd 'de' MMMM 'de' yyyy", true); - if (!isset($output[$key])) { - $output[$key] = []; + foreach ($output as $key => $day) { + uksort($day, function($a, $b) { + return strcmp($a, $b); + }); + $output[$key] = $day; } - if (!isset($output[$key][$row['Proyecto']])) { - $output[$key][$row['Proyecto']] = 0; - } - $output[$key][$row['Proyecto']] += $row['Cantidad']; - } - foreach ($output as $key => $day) { - uksort($day, function($a, $b) { - return strcmp($a, $b); - }); - $output[$key] = $day; - } - $benchmark['run'] = microtime(true) - $benchmark['start']; - error_log(var_export($benchmark,true)); - } catch (EmptyResult) {} + $benchmark['run'] = microtime(true) - $benchmark['start']; + error_log(var_export($benchmark,true)); + $this->saveRedis($redisService, $redisKey, $output); + } catch (EmptyResult) {} + } return $this->withJson($response, ['cuotas' => $output]); } } diff --git a/app/src/Controller/API/Ventas/Unidades.php b/app/src/Controller/API/Ventas/Unidades.php index f04deeb..398f3af 100644 --- a/app/src/Controller/API/Ventas/Unidades.php +++ b/app/src/Controller/API/Ventas/Unidades.php @@ -1,22 +1,29 @@ getBody(); $json = json_decode($body->getContents()); $proyecto_id = $json->proyecto_id; + $today = new DateTimeImmutable(); + $redisKey = "unidades_disponibles-{$proyecto_id}-{$today->format('Y-m-d')}"; + $output = [ 'proyecto_id' => $proyecto_id, 'unidades' => [ @@ -31,26 +38,31 @@ class Unidades ] ]; try { - $totalUnidades = $unidadRepository->fetchByProyecto($proyecto_id); - $unidades = $unidadRepository->fetchDisponiblesByProyecto($proyecto_id); + $output = $this->fetchRedis($redisService, $redisKey); + } catch (EmptyRedis) { + try { + $totalUnidades = $unidadRepository->fetchByProyecto($proyecto_id); + $unidades = $unidadRepository->fetchDisponiblesByProyecto($proyecto_id); - $tiposUnidades = $tipoUnidadRepository->fetchAll(); - foreach ($tiposUnidades as $tipoUnidad) { - $tempUnidades = array_filter($totalUnidades, function(Model\Venta\Unidad $unidad) use ($tipoUnidad) { - return $unidad->proyectoTipoUnidad->tipoUnidad->id === $tipoUnidad->id; - }); - if (count($tempUnidades) > 0) { - $output['unidades']['total']["{$tipoUnidad->descripcion}s"] = count($tempUnidades); + $tiposUnidades = $tipoUnidadRepository->fetchAll(); + foreach ($tiposUnidades as $tipoUnidad) { + $tempUnidades = array_filter($totalUnidades, function(Model\Venta\Unidad $unidad) use ($tipoUnidad) { + return $unidad->proyectoTipoUnidad->tipoUnidad->id === $tipoUnidad->id; + }); + if (count($tempUnidades) > 0) { + $output['unidades']['total']["{$tipoUnidad->descripcion}s"] = count($tempUnidades); + } + $tempUnidades = array_filter($unidades, function(Model\Venta\Unidad $unidad) use ($tipoUnidad) { + return $unidad->proyectoTipoUnidad->tipoUnidad->id === $tipoUnidad->id; + }); + if (count($tempUnidades) === 0) { + continue; + } + $output['unidades']["{$tipoUnidad->descripcion}s"] = count($tempUnidades); } - $tempUnidades = array_filter($unidades, function(Model\Venta\Unidad $unidad) use ($tipoUnidad) { - return $unidad->proyectoTipoUnidad->tipoUnidad->id === $tipoUnidad->id; - }); - if (count($tempUnidades) === 0) { - continue; - } - $output['unidades']["{$tipoUnidad->descripcion}s"] = count($tempUnidades); - } - } catch (EmptyResult) {} + $this->saveRedis($redisService, $redisKey, $output); + } catch (EmptyResult) {} + } return $this->withJson($response, $output); } } diff --git a/app/src/Controller/API/withJson.php b/app/src/Controller/API/withJson.php index 78aa191..1a6e2f4 100644 --- a/app/src/Controller/API/withJson.php +++ b/app/src/Controller/API/withJson.php @@ -5,7 +5,7 @@ use Psr\Http\Message\ResponseInterface; trait withJson { - public function withJson(ResponseInterface $response, array $data = []): ResponseInterface + public function withJson(ResponseInterface $response, array|object $data = []): ResponseInterface { $response->getBody()->write(json_encode($data)); return $response->withHeader('Content-Type', 'application/json'); diff --git a/app/src/Controller/API/withRedis.php b/app/src/Controller/API/withRedis.php new file mode 100644 index 0000000..0913c11 --- /dev/null +++ b/app/src/Controller/API/withRedis.php @@ -0,0 +1,24 @@ +get($redisKey); + if ($jsonString === null) { + throw new EmptyRedis($redisKey); + } + return json_decode($jsonString); + } + public function saveRedis(Service\Redis $redisService, string $redisKey, mixed $value): void + { + if (is_array($value) or is_object($value)) { + $value = json_encode($value); + } + $redisService->set($redisKey, $value); + } +} diff --git a/app/src/Service/Redis.php b/app/src/Service/Redis.php new file mode 100644 index 0000000..5a9845a --- /dev/null +++ b/app/src/Service/Redis.php @@ -0,0 +1,18 @@ +client->get($name); + } + public function set(string $name, mixed $value): void + { + $this->client->set($name, $value); + } +} diff --git a/docker-compose.yml b/docker-compose.yml index 09ec208..3e628b8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -47,6 +47,18 @@ services: - default - adminer_network + redis: + profiles: + - cache + image: redis + container_name: incoviba_redis + <<: *restart + env_file: ${APP_PATH:-.}/.redis.env + volumes: + - incoviba_redis:/data + ports: + - "63790:6379" + python: profiles: - python @@ -74,6 +86,7 @@ services: volumes: dbdata: {} + incoviba_redis: {} networks: adminer_network: {}