diff --git a/app/resources/routes/03_proyectos.php b/app/resources/routes/03_proyectos.php
index 4f31a20..7c734ea 100644
--- a/app/resources/routes/03_proyectos.php
+++ b/app/resources/routes/03_proyectos.php
@@ -5,3 +5,6 @@ $app->group('/proyectos', function($app) {
$app->get('/unidades[/]', [Proyectos::class, 'unidades']);
$app->get('[/]', Proyectos::class);
});
+$app->group('/proyecto/{proyecto_id}', function($app) {
+ $app->get('[/]', [Proyectos::class, 'show']);
+});
diff --git a/app/resources/routes/api/proyectos.php b/app/resources/routes/api/proyectos.php
index 784b0d1..3d8cca7 100644
--- a/app/resources/routes/api/proyectos.php
+++ b/app/resources/routes/api/proyectos.php
@@ -10,4 +10,11 @@ $app->group('/proyecto/{proyecto_id}', function($app) {
$app->get('/estado[/]', [Proyectos\EstadosProyectos::class, 'currentByProyecto']);
$app->get('/inicio[/]', [Proyectos\EstadosProyectos::class, 'firstByProyecto']);
$app->get('/recepcion[/]', [Proyectos\EstadosProyectos::class, 'recepcionByProyecto']);
+ $app->group('/superficies', function($app) {
+ $app->get('/vendible[/]', [Proyectos::class, 'superficies']);
+ });
+ $app->group('/unidades', function($app) {
+ $app->get('/disponibles[/]', [Proyectos::class, 'disponibles']);
+ $app->get('[/]', [Proyectos::class, 'unidades']);
+ });
});
diff --git a/app/resources/routes/api/ventas/precios.php b/app/resources/routes/api/ventas/precios.php
index 2f04166..6546f48 100644
--- a/app/resources/routes/api/ventas/precios.php
+++ b/app/resources/routes/api/ventas/precios.php
@@ -1,5 +1,5 @@
group('/precios', function($app) {
$app->post('[/]', [Precios::class, 'proyecto']);
diff --git a/app/resources/views/proyectos/list.blade.php b/app/resources/views/proyectos/list.blade.php
index 3dbdb83..98fd8c2 100644
--- a/app/resources/views/proyectos/list.blade.php
+++ b/app/resources/views/proyectos/list.blade.php
@@ -17,7 +17,11 @@
@foreach ($proyectos as $proyecto)
- {{$proyecto->descripcion}} |
+
+
+ {{$proyecto->descripcion}}
+
+ |
{{$proyecto->inmobiliaria()->nombreCompleto()}} |
|
|
diff --git a/app/resources/views/proyectos/show.blade.php b/app/resources/views/proyectos/show.blade.php
new file mode 100644
index 0000000..88986fd
--- /dev/null
+++ b/app/resources/views/proyectos/show.blade.php
@@ -0,0 +1,470 @@
+@extends('layout.base')
+
+@section('page_title')
+ Proyecto {{$proyecto->descripcion}}
+@endsection
+
+@section('page_content')
+
+
+ @php
+ $today = new DateTimeImmutable();
+ @endphp
+
+
+ Dirección |
+ {{$proyecto->direccion()}} |
+
+
+ Inmobiliaria |
+ {{$proyecto->inmobiliaria()->nombreCompleto()}} |
+
+
+ Inicio |
+
+ {{$proyecto->estados()[0]->tipoEstadoProyecto->descripcion}}
+ [{{$proyecto->estados()[0]->tipoEstadoProyecto->etapa->descripcion}}]
+ ({{$proyecto->estados()[0]->fecha->format('d-m-Y')}})
+ ({{$today->diff($proyecto->estados()[0]->fecha)->format('%y años antes')}})
+ |
+
+
+ Estado |
+
+ {{$proyecto->currentEstado()->tipoEstadoProyecto->descripcion}}
+ [{{$proyecto->currentEstado()->tipoEstadoProyecto->etapa->descripcion}}]
+ ({{$proyecto->currentEstado()->fecha->format('d-m-Y')}})
+ ({{$today->diff($proyecto->currentEstado()->fecha)->format('%y años antes')}})
+
+
+
+ |
+
+
+ Superficies |
+
+
+
+
+
+ Total
+
+ |
+
+
+ {{$format->number($proyecto->superficie->total(), 2)}}m²
+
+ |
+ |
+
+
+ Bajo Nivel |
+ {{$format->number($proyecto->superficie->bajo_nivel, 2)}}m² |
+
+
+ Sobre Nivel |
+ {{$format->number($proyecto->superficie->sobre_nivel, 2)}}m² |
+
+
+
+
+ Vendible
+
+ |
+
+
+ |
+
+
+ Vendido |
+ |
+
+
+ Por Vender |
+ |
+
+
+ |
+
+
+ Unidades |
+ |
+
+
+ Ventas |
+ |
+
+
+ Stock |
+ |
+
+
+ Proyección |
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+
+@endsection
+
+@include('layout.body.scripts.chartjs')
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/src/Controller/API/Proyectos.php b/app/src/Controller/API/Proyectos.php
index 5ed2152..2cf3608 100644
--- a/app/src/Controller/API/Proyectos.php
+++ b/app/src/Controller/API/Proyectos.php
@@ -3,13 +3,15 @@ namespace Incoviba\Controller\API;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
+use Incoviba\Common\Implement\Exception\EmptyRedis;
use Incoviba\Common\Implement\Exception\EmptyResult;
use Incoviba\Repository;
use Incoviba\Model;
+use Incoviba\Service;
class Proyectos
{
- use withJson;
+ use withJson, withRedis;
public function list(ServerRequestInterface $request, ResponseInterface $response, Repository\Proyecto $proyectoRepository): ResponseInterface
{
@@ -34,26 +36,88 @@ class Proyectos
} catch (EmptyResult) {}
return $this->withJson($response, $output);
}
- public function unidades(ServerRequestInterface $request, ResponseInterface $response, Repository\Venta\Unidad $unidadRepository, int $proyecto_id): ResponseInterface
+ public function unidades(ServerRequestInterface $request, ResponseInterface $response,
+ Repository\Venta\Unidad $unidadRepository, Service\Redis $redisService,
+ int $proyecto_id): ResponseInterface
{
$output = ['proyecto_id' => $proyecto_id, 'unidades' => [], 'total' => 0];
+ $redisKey = "unidades-proyecto-{$proyecto_id}";
try {
- $unidades = $unidadRepository->fetchDisponiblesByProyecto($proyecto_id);
- $tipos = [];
- foreach ($unidades as $unidad) {
- if (!isset($tipos[$unidad->proyectoTipoUnidad->tipoUnidad->descripcion])) {
- $tipos[$unidad->proyectoTipoUnidad->tipoUnidad->descripcion] = [];
+ $output = $this->fetchRedis($redisService, $redisKey);
+ } catch (EmptyRedis) {
+ try {
+ $unidades = $unidadRepository->fetchByProyecto($proyecto_id);
+ $tipos = [];
+ foreach ($unidades as $unidad) {
+ if (!isset($tipos[$unidad->proyectoTipoUnidad->tipoUnidad->descripcion])) {
+ $tipos[$unidad->proyectoTipoUnidad->tipoUnidad->descripcion] = [];
+ }
+ $tipos[$unidad->proyectoTipoUnidad->tipoUnidad->descripcion] []= $unidad;
}
- $tipos[$unidad->proyectoTipoUnidad->tipoUnidad->descripcion] []= $unidad;
- }
- foreach ($tipos as &$subtipo) {
- usort($subtipo, function(Model\Venta\Unidad $a, Model\Venta\Unidad $b) {
- return strcmp(str_pad($a->descripcion, 4, '0', STR_PAD_LEFT), str_pad($b->descripcion, 4, '0', STR_PAD_LEFT));
- });
- }
- $output['unidades'] = $tipos;
- $output['total'] = count($unidades);
+ foreach ($tipos as &$subtipo) {
+ usort($subtipo, function(Model\Venta\Unidad $a, Model\Venta\Unidad $b) {
+ return strcmp(str_pad($a->descripcion, 4, '0', STR_PAD_LEFT), str_pad($b->descripcion, 4, '0', STR_PAD_LEFT));
+ });
+ }
+ $output['unidades'] = $tipos;
+ $output['total'] = count($unidades);
+ $this->saveRedis($redisService, $redisKey, $output);
+ } catch (EmptyResult) {}
+ }
+ return $this->withJson($response, $output);
+ }
+ public function disponibles(ServerRequestInterface $request, ResponseInterface $response, Repository\Venta\Unidad $unidadRepository, int $proyecto_id): ResponseInterface
+ {
+ $output = [
+ 'proyecto_id' => $proyecto_id,
+ 'unidades' => []
+ ];
+ try {
+ $output['unidades'] = $unidadRepository->fetchDisponiblesByProyecto($proyecto_id);
} catch (EmptyResult) {}
return $this->withJson($response, $output);
}
+ public function superficies(ServerRequestInterface $request, ResponseInterface $response,
+ Repository\Proyecto $proyectoRepository, Repository\Venta $ventaRepository,
+ Repository\Venta\Unidad $unidadRepository, Service\Redis $redisService,
+ Service\Format $formatService, int $proyecto_id): ResponseInterface
+ {
+ $output = [
+ 'proyecto_id' => $proyecto_id,
+ 'superficies' => [
+ 'vendible' => 0,
+ 'vendido' => 0,
+ 'por_vender' => 0
+ ],
+ 'formatted' => [
+ 'vendible' => '0m²',
+ 'vendido' => '0m²',
+ 'por_vender' => '0m²'
+ ]
+ ];
+ $redisKey = "superficices-proyecto-{$proyecto_id}";
+ try {
+ $output = $this->fetchRedis($redisService, $redisKey);
+ } catch (EmptyRedis) {
+ try {
+ $ventas = $ventaRepository->fetchActivaByProyecto($proyecto_id);
+ $unidades = $unidadRepository->fetchDisponiblesByProyecto($proyecto_id);
+
+ $output['superficies']['vendido'] = array_reduce($ventas, function($sum, Model\Venta $venta) {
+ return $sum + array_reduce($venta->propiedad()->unidades, function($sum, Model\Venta\Unidad $unidad) {
+ return $sum + $unidad->proyectoTipoUnidad->vendible();
+ });
+ }, 0);
+ $output['formatted']['vendido'] = "{$formatService->number($output['superficies']['vendido'], 2)}m²";
+ $output['superficies']['por_vender'] = array_reduce($unidades, function($sum, Model\Venta\Unidad $unidad) {
+ return $sum + $unidad->proyectoTipoUnidad->vendible();
+ });
+ $output['formatted']['por_vender'] = "{$formatService->number($output['superficies']['por_vender'], 2)}m²";
+ $output['superficies']['vendible'] = $output['superficies']['vendido'] + $output['superficies']['por_vender'];
+ $output['formatted']['vendible'] = "{$formatService->number($output['superficies']['vendible'], 2)}m²";
+ $this->saveRedis($redisService, $redisKey, $output, 60 * 60);
+ } catch (EmptyResult) {}
+ }
+ return $this->withJson($response, $output);
+ }
}
diff --git a/app/src/Controller/API/Ventas.php b/app/src/Controller/API/Ventas.php
index 87deea0..2604ae1 100644
--- a/app/src/Controller/API/Ventas.php
+++ b/app/src/Controller/API/Ventas.php
@@ -54,7 +54,7 @@ class Ventas
$json = json_decode($body->getContents());
$proyecto_id = $json->proyecto_id;
$today = new DateTimeImmutable();
- $redisKey = "promesas_por_firmar-{$proyecto_id}-{$today->format('Y-m-d')}";
+ $redisKey = "promesas_por_firmar-proyecto-{$proyecto_id}-{$today->format('Y-m-d')}";
$output = [
'proyecto_id' => $proyecto_id,
@@ -80,7 +80,7 @@ class Ventas
$json = json_decode($body->getContents());
$proyecto_id = $json->proyecto_id;
$today = new DateTimeImmutable();
- $redisKey = "escrituras-{$proyecto_id}-{$today->format('Y-m-d')}";
+ $redisKey = "escrituras-proyecto-{$proyecto_id}-{$today->format('Y-m-d')}";
$output = [
'proyecto_id' => $proyecto_id,
diff --git a/app/src/Controller/API/Ventas/Precios.php b/app/src/Controller/API/Ventas/Precios.php
new file mode 100644
index 0000000..927e815
--- /dev/null
+++ b/app/src/Controller/API/Ventas/Precios.php
@@ -0,0 +1,36 @@
+getBody();
+ $json = json_decode($body->getContents());
+ $proyecto_id = $json->proyecto_id;
+ $output = ['total' => 0];
+ try {
+ $precios = $precioService->getByProyecto($proyecto_id);
+ $output['precios'] = $precios;
+ $output['total'] = count($precios);
+ } catch (EmptyResult) {}
+ return $this->withJson($response, $output);
+ }
+ public function unidad(ServerRequestInterface $request, ResponseInterface $response, Service\Venta\Precio $precioService, int $unidad_id): ResponseInterface
+ {
+ try {
+ $precio = $precioService->getVigenteByUnidad($unidad_id);
+ return $this->withJson($response, compact('precio'));
+ } catch (EmptyResult) {
+ return $this->emptyBody($response);
+ }
+ }
+}
diff --git a/app/src/Controller/API/Ventas/Unidades.php b/app/src/Controller/API/Ventas/Unidades.php
index 398f3af..9f8538f 100644
--- a/app/src/Controller/API/Ventas/Unidades.php
+++ b/app/src/Controller/API/Ventas/Unidades.php
@@ -22,7 +22,7 @@ class Unidades
$json = json_decode($body->getContents());
$proyecto_id = $json->proyecto_id;
$today = new DateTimeImmutable();
- $redisKey = "unidades_disponibles-{$proyecto_id}-{$today->format('Y-m-d')}";
+ $redisKey = "unidades_disponibles-proyecto-{$proyecto_id}-{$today->format('Y-m-d')}";
$output = [
'proyecto_id' => $proyecto_id,
diff --git a/app/src/Controller/Proyectos.php b/app/src/Controller/Proyectos.php
index 81c53b9..4f62910 100644
--- a/app/src/Controller/Proyectos.php
+++ b/app/src/Controller/Proyectos.php
@@ -4,8 +4,9 @@ namespace Incoviba\Controller;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Incoviba\Common\Alias\View;
-use Incoviba\Repository;
use Incoviba\Model;
+use Incoviba\Repository;
+use Incoviba\Service;
class Proyectos
{
@@ -29,4 +30,9 @@ class Proyectos
});
return $view->render($response, 'proyectos.unidades', compact('proyectos'));
}
+ public function show(ServerRequestInterface $request, ResponseInterface $response, View $view, Service\Proyecto $proyectoService, int $proyecto_id): ResponseInterface
+ {
+ $proyecto = $proyectoService->getById($proyecto_id);
+ return $view->render($response, 'proyectos.show', compact('proyecto'));
+ }
}
diff --git a/app/src/Controller/Ventas/Precios.php b/app/src/Controller/Ventas/Precios.php
index 6a96459..890d749 100644
--- a/app/src/Controller/Ventas/Precios.php
+++ b/app/src/Controller/Ventas/Precios.php
@@ -1,7 +1,6 @@
$proyecto->id, 'descripcion' => $proyecto->descripcion];}, $proyectoService->getVendibles());
return $view->render($response, 'ventas.precios.list', compact('proyectos'));
}
- public function proyecto(ServerRequestInterface $request, ResponseInterface $response, Service\Venta\Precio $precioService): ResponseInterface
- {
- $body = $request->getBody();
- $json = json_decode($body->getContents());
- $proyecto_id = $json->proyecto_id;
- $output = ['total' => 0];
- try {
- $precios = $precioService->getByProyecto($proyecto_id);
- $output['precios'] = $precios;
- $output['total'] = count($precios);
- } catch (EmptyResult) {}
- $response->getBody()->write(json_encode($output));
- return $response->withHeader('Content-Type', 'application/json');
- }
- public function unidad(ServerRequestInterface $request, ResponseInterface $response, Service\Venta\Precio $precioService, int $unidad_id): ResponseInterface
- {
- $precio = $precioService->getVigenteByUnidad($unidad_id);
- $response->getBody()->write(json_encode(['precio' => $precio]));
- return $response->withHeader('Content-Type', 'application/json');
- }
}
diff --git a/app/src/Model/Proyecto.php b/app/src/Model/Proyecto.php
index a0ab993..d4a2e69 100644
--- a/app/src/Model/Proyecto.php
+++ b/app/src/Model/Proyecto.php
@@ -1,6 +1,7 @@
inmobiliaria)) {
@@ -29,6 +33,20 @@ class Proyecto extends Ideal\Model
}
return $this->direccion;
}
+ public function estados(): array
+ {
+ if (!isset($this->estados)) {
+ $this->estados = $this->runFactory('estados');
+ }
+ return $this->estados;
+ }
+ public function currentEstado(): Proyecto\EstadoProyecto
+ {
+ if (!isset($this->currentEstado)) {
+ $this->currentEstado = $this->runFactory('currentEstado');
+ }
+ return $this->currentEstado;
+ }
public function jsonSerialize(): mixed
{
diff --git a/app/src/Model/Proyecto/Superficie.php b/app/src/Model/Proyecto/Superficie.php
index 72d6e5f..da7e1a9 100644
--- a/app/src/Model/Proyecto/Superficie.php
+++ b/app/src/Model/Proyecto/Superficie.php
@@ -5,4 +5,9 @@ class Superficie
{
public float $sobre_nivel;
public float $bajo_nivel;
+
+ public function total(): float
+ {
+ return $this->bajo_nivel + $this->sobre_nivel;
+ }
}
diff --git a/app/src/Model/Venta/Propiedad.php b/app/src/Model/Venta/Propiedad.php
index 0e18cea..546a984 100644
--- a/app/src/Model/Venta/Propiedad.php
+++ b/app/src/Model/Venta/Propiedad.php
@@ -9,15 +9,15 @@ class Propiedad extends Ideal\Model
public function departamentos(): array
{
- return array_filter($this->unidades, function(Unidad $unidad) {return $unidad->proyectoTipoUnidad->tipoUnidad->descripcion === 'departamento';});
+ return array_values(array_filter($this->unidades, function(Unidad $unidad) {return $unidad->proyectoTipoUnidad->tipoUnidad->descripcion === 'departamento';}));
}
public function estacionamientos(): array
{
- return array_filter($this->unidades, function(Unidad $unidad) {return $unidad->proyectoTipoUnidad->tipoUnidad->descripcion === 'estacionamiento';});
+ return array_values(array_filter($this->unidades, function(Unidad $unidad) {return $unidad->proyectoTipoUnidad->tipoUnidad->descripcion === 'estacionamiento';}));
}
public function bodegas(): array
{
- return array_filter($this->unidades, function(Unidad $unidad) {return $unidad->proyectoTipoUnidad->tipoUnidad->descripcion === 'bodega';});
+ return array_values(array_filter($this->unidades, function(Unidad $unidad) {return $unidad->proyectoTipoUnidad->tipoUnidad->descripcion === 'bodega';}));
}
protected float $vendible;
diff --git a/app/src/Repository/Proyecto.php b/app/src/Repository/Proyecto.php
index 21b1c7e..e03de3b 100644
--- a/app/src/Repository/Proyecto.php
+++ b/app/src/Repository/Proyecto.php
@@ -92,6 +92,10 @@ WHERE et.`orden` BETWEEN {$etapaRecepcion->orden} AND ({$etapaTerminado->orden}
ORDER BY a.`descripcion`";
return $this->fetchMany($query);
}
+ public function fetchSuperficieVendido(int $proyecto_id): float
+ {
+
+ }
protected function joinEstado(): string
{
diff --git a/app/src/Service/Redis.php b/app/src/Service/Redis.php
index 1d7f050..d8d61ce 100644
--- a/app/src/Service/Redis.php
+++ b/app/src/Service/Redis.php
@@ -15,8 +15,8 @@ class Redis
}
return $this->client->get($name);
}
- public function set(string $name, mixed $value): void
+ public function set(string $name, mixed $value, int $expirationTTL = 60 * 60 * 24): void
{
- $this->client->set($name, $value, 'EX', 60 * 60 * 24);
+ $this->client->set($name, $value, 'EX', $expirationTTL);
}
}