This commit is contained in:
2023-06-26 10:49:25 -04:00
parent 42a97bb074
commit 4d00f10274
20 changed files with 350 additions and 33 deletions

View File

@ -1,13 +1,17 @@
<?php
namespace Incoviba\API\Common\Controller;
use Carbon\Carbon;
use Incoviba\API\Common\Alias\Controller;
use Incoviba\Mapper\EstadoVenta;
use Incoviba\Mapper\ProyectoAgente;
use Incoviba\Mapper\TipoEstadoProyecto;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use Incoviba\API\Common\Factory\Model as Factory;
use Incoviba\Proyecto\Proyecto;
use Incoviba\Mapper\Proyecto as ProyectoMapper;
use Incoviba\Mapper\EstadoProyecto;
use Incoviba\Mapper\Venta as VentaMapper;
use Incoviba\Mapper\ProyectoTipoUnidad as TipoMapper;
use Incoviba\Mapper\Unidad as UnidadMapper;
@ -27,28 +31,10 @@ class Proyectos extends Controller {
}
return $this->withJson($response, compact('proyectos'));
}
public function show(Request $request, Response $response, Factory $factory, $proyecto_id): Response {
$proyecto = $factory->find(Proyecto::class)->one($proyecto_id);
public function show(Request $request, Response $response, $proyecto_id): Response {
$proyecto = $this->getMapper(ProyectoMapper::class)->fetchById($proyecto_id);
$output = [
'input' => $proyecto_id,
'proyecto' => $proyecto->toArray(),
'link' => [
'rel' => 'proyectos',
'title' => 'Proyectos',
'href' => str_replace("/proyecto/{$proyecto_id}", '/proyectos', $request->getUri())
]
];
$output['links'] = [
[
'rel' => 'inmobiliaria',
'title' => $proyecto->inmobiliaria()->abreviacion,
'href' => str_replace("/proyecto/{$proyecto_id}", "/inmobiliaria/{$proyecto->inmobiliaria()->rut}", $request->getUri())
],
[
'rel' => 'direccion',
'title' => $proyecto->direccion()->calle,
'href' => str_replace("/proyecto/{$proyecto_id}", "/direccion/{$proyecto->direccion}", $request->getUri())
]
'proyecto' => json_decode(json_encode($proyecto), JSON_OBJECT_AS_ARRAY)
];
return $this->withJson($response, $output);
}
@ -95,7 +81,7 @@ class Proyectos extends Controller {
return $this->withJson($response, $output);
}
public function ventas(Request $request, Response $response, $proyecto_id): Response
public function ventas(Request $request, Response $response, int $proyecto_id): Response
{
$proyecto = $this->getMapper(ProyectoMapper::class)->fetchById($proyecto_id);
$ventas = $this->getMapper(VentaMapper::class)->fetchActivaByProyecto($proyecto_id);
@ -107,7 +93,7 @@ class Proyectos extends Controller {
}
return $this->withJson($response, $output);
}
public function precios(Request $request, Response $response, Format $format, $proyecto_id): Response {
public function precios(Request $request, Response $response, Format $format, int $proyecto_id): Response {
$proyecto = $this->getMapper(ProyectoMapper::class)->fetchById($proyecto_id);
$output = json_decode(json_encode(compact('proyecto')), JSON_OBJECT_AS_ARRAY);
$tipos = $this->getMapper(TipoMapper::class)->fetchByProyecto($proyecto_id);
@ -138,4 +124,61 @@ class Proyectos extends Controller {
}
return $this->withJson($response, $output);
}
public function estado(Request $request, Response $response, int $proyecto_id): Response
{
$proyecto = $this->getMapper(ProyectoMapper::class)->fetchById($proyecto_id);
$estado = $this->getMapper(EstadoProyecto::class)->fetchLastByProyecto($proyecto_id);
$output = [
'proyecto' => $proyecto,
'estado' => json_decode(json_encode($estado), JSON_OBJECT_AS_ARRAY)
];
$output['estado']['fecha']['diff'] = Carbon::createFromTimestamp($estado->fecha->getTimestamp())->locale('es-CL')->diffForHumans();
return $this->withJson($response, $output);
}
public function inicio(Request $request, Response $response, int $proyecto_id): Response
{
$proyecto = $this->getMapper(ProyectoMapper::class)->fetchById($proyecto_id);
$estado = $this->getMapper(EstadoProyecto::class)->fetchFirstByProyecto($proyecto_id);
$output = [
'proyecto' => $proyecto,
'estado' => json_decode(json_encode($estado), JSON_OBJECT_AS_ARRAY)
];
$output['estado']['fecha']['diff'] = Carbon::createFromTimestamp($estado->fecha->getTimestamp())->locale('es-CL')->diffForHumans();
if ($estado->fecha->getTimestamp() < 0) {
$output['estado']['fecha']['diff'] = '-';
}
return $this->withJson($response, $output);
}
public function progreso(Request $request, Response $response, int $proyecto_id): Response
{
$proyecto = $this->getMapper(ProyectoMapper::class)->fetchById($proyecto_id);
$inicio = $this->getMapper(EstadoProyecto::class)->fetchFirstByProyecto($proyecto_id);
$estado = $this->getMapper(EstadoProyecto::class)->fetchLastByProyecto($proyecto_id);
$orden_tipo_estados = array_map(function($item) {
return $item->orden;
}, $this->getMapper(TipoEstadoProyecto::class)->fetchAll());
$estados = $this->getMapper(EstadoProyecto::class)->fetchByProyecto($proyecto_id);
$total = 1;
if ($estado->tipo->orden < max($orden_tipo_estados) - 1 and count($estados) > 1) {
$tf = Carbon::createFromTimestamp($estado->fecha->getTimestamp());
$t0 = Carbon::createFromTimestamp($inicio->fecha->getTimestamp());
$df = $tf->diffInSeconds($t0);
$hoy = Carbon::now();
$dh = $hoy->diffInSeconds($t0);
$total = $df / $dh;
}
$valor = round(($estado->tipo->orden + 1) / max($orden_tipo_estados) * 100 * $total);
$output = [
'proyecto' => $proyecto,
'progreso' => $valor
];
return $this->withJson($response, $output);
}
public function operadores(Request $request, Response $response, int $proyecto_id): Response
{
$proyecto = $this->getMapper(ProyectoMapper::class)->fetchById($proyecto_id);
$operadores = $this->getMapper(ProyectoAgente::class)->fetchOperadoresVigenteByProyecto($proyecto_id);
$output = compact('proyecto', 'operadores');
return $this->withJson($response, $output);
}
}

View File

@ -18,7 +18,11 @@ $app->group('/proyectos', function ($app) {
$app->group('/proyecto/{proyecto_id}', function ($app) {
$app->get('/ventas', [Proyectos::class, 'ventas']);
$app->get('/precios', [Proyectos::class, 'precios']);
$app->get('/inicio', [Proyectos::class, 'inicio']);
$app->get('/estado', [Proyectos::class, 'estado']);
$app->get('/progreso', [Proyectos::class, 'progreso']);
$app->get('/operadores', [Proyectos::class, 'operadores']);
$app->put('/edit[/]', [Proyectos::class, 'edit']);
$app->delete('/edit[/]', [Proyectos::class, 'delete']);
$app->delete('/delete[/]', [Proyectos::class, 'delete']);
$app->get('[/]', [Proyectos::class, 'show']);
});

26
src/Mapper/Agente.php Normal file
View File

@ -0,0 +1,26 @@
<?php
namespace Incoviba\Mapper;
use Incoviba\Model\Model;
use Incoviba\Model\Proyecto\Agente as BaseModel;
class Agente extends Mapper
{
protected string $table = 'agente';
protected function load(bool|array $row, bool $lazy = false): BaseModel|bool
{
$model = new BaseModel();
$model->id = $row['id'];
$model->rut = $row['rut'];
$model->descripcion = $row['descripcion'];
$model->abreviacion = $row['abreviacion'];
return $model;
}
public function save(Model $model): bool
{
// TODO: Implement save() method.
}
}

View File

@ -13,6 +13,8 @@ class AgenteTipo extends Mapper
{
$model = new AgenteModel();
$model->id = $row['id'];
$model->agente = $this->getMapper(Agente::class)->fetchById($row['agente']);
$model->tipo = $this->getMapper(TipoAgente::class)->fetchById($row['tipo']);
return $model;
}

25
src/Mapper/Comuna.php Normal file
View File

@ -0,0 +1,25 @@
<?php
namespace Incoviba\Mapper;
use Incoviba\Model\Model;
use Incoviba\Model\Common\Comuna as BaseModel;
class Comuna extends Mapper
{
protected string $table = 'comuna';
protected function load(bool|array $row, bool $lazy = false): BaseModel|bool
{
$model = new BaseModel();
$model->id = $row['id'];
$model->descripcion = $row['descripcion'];
// $model->provincia = $this->getMapper(Provincia::class)->fetchById($row['provincia']);
return $model;
}
public function save(Model $model): bool
{
// TODO: Implement save() method.
}
}

View File

@ -8,9 +8,6 @@ use Incoviba\Model\Common\Direccion as DireccionModel;
class Direccion extends Mapper
{
protected string $table = 'direccion';
/*protected array $required = [
Comuna::class
];*/
protected function load(bool|array $row, bool $lazy = false): DireccionModel|bool
{
@ -20,6 +17,7 @@ class Direccion extends Mapper
$model->calle = $row['calle'];
$model->numero = $row['numero'];
$model->extra = $row['extra'];
$model->comuna = $this->getMapper(Comuna::class)->fetchById($row['comuna']);
return $model;
}

View File

@ -0,0 +1,55 @@
<?php
namespace Incoviba\Mapper;
use Incoviba\Model\Model;
use Incoviba\Model\Proyecto\EstadoProyecto as BaseModel;
class EstadoProyecto extends Mapper
{
protected string $table = 'estado_proyecto';
protected function load(bool|array $row, bool $lazy = false): BaseModel|bool
{
$model = new BaseModel();
$model->id = $row['id'];
$model->proyecto = $this->getMapper(Proyecto::class)->fetchById($row['proyecto']);
$model->tipo = $this->getMapper(TipoEstadoProyecto::class)->fetchById($row['estado']);
$model->fecha = new \DateTimeImmutable($row['fecha']);
return $model;
}
public function save(Model $model): bool
{
// TODO: Implement save() method.
}
public function fetchByProyecto(int $proyecto_id): array
{
$qb = $this->connection->createQueryBuilder()
->select('*')
->from($this->table)
->where('proyecto = ?');
return array_map([$this, 'load'], $this->connection->executeQuery($qb, [$proyecto_id])->fetchAllAssociative());
}
public function fetchLastByProyecto(int $proyecto_id): BaseModel|bool
{
$qb = $this->connection->createQueryBuilder()
->select('*')
->from($this->table)
->where('proyecto = ?')
->setMaxResults(1)
->orderBy('id', 'desc');
return $this->load($this->connection->executeQuery($qb, [$proyecto_id])->fetchAssociative());
}
public function fetchFirstByProyecto(int $proyecto_id): BaseModel|bool
{
$qb = $this->connection->createQueryBuilder()
->select('*')
->from($this->table)
->where('proyecto = ?')
->setMaxResults(1)
->orderBy('id', 'asc');
return $this->load($this->connection->executeQuery($qb, [$proyecto_id])->fetchAssociative());
}
}

25
src/Mapper/Etapa.php Normal file
View File

@ -0,0 +1,25 @@
<?php
namespace Incoviba\Mapper;
use Incoviba\Model\Model;
use Incoviba\Model\Proyecto\Etapa as BaseModel;
class Etapa extends Mapper
{
protected string $table = 'etapa_proyecto';
protected function load(bool|array $row, bool $lazy = false): BaseModel|bool
{
$model = new BaseModel();
$model->id = $row['id'];
$model->descripcion = $row['descripcion'];
$model->orden = $row['orden'];
return $model;
}
public function save(Model $model): bool
{
// TODO: Implement save() method.
}
}

View File

@ -23,4 +23,19 @@ class ProyectoAgente extends Mapper
{
// TODO: Implement save() method.
}
public function fetchOperadoresVigenteByProyecto(int $proyecto_id): array
{
$qb = $this->connection->createQueryBuilder()
->select('pa.*')
->from($this->table, 'pa')
->innerJoin('pa', 'agente_tipo', 'at', 'at.id = pa.agente')
->innerJoin('at', 'tipo_agente', 'ta', 'ta.id = at.tipo')
->innerJoin('pa', '(SELECT e1.* FROM estado_proyecto_agente e1 JOIN (SELECT MAX(id) AS id, agente FROM estado_proyecto_agente GROUP BY agente) e0 ON e0.id = e1.id)', 'ep', 'ep.agente = pa.id')
->innerJoin('ep', 'tipo_estado_proyecto_agente', 'tep', 'tep.id = ep.tipo')
->where('pa.proyecto = ?')
->andWhere('ta.descripcion = ?')
->andWhere('tep.descripcion = ?');
return array_map([$this, 'load'], $this->connection->executeQuery($qb, [$proyecto_id, 'operador', 'vigente'])->fetchAllAssociative());
}
}

24
src/Mapper/TipoAgente.php Normal file
View File

@ -0,0 +1,24 @@
<?php
namespace Incoviba\Mapper;
use Incoviba\Model\Model;
use Incoviba\Model\Proyecto\TipoAgente as BaseModel;
class TipoAgente extends Mapper
{
protected string $table = 'tipo_agente';
protected function load(bool|array $row, bool $lazy = false): BaseModel|bool
{
$model = new BaseModel();
$model->id = $row['id'];
$model->descripcion = $row['descripcion'];
return $model;
}
public function save(Model $model): bool
{
// TODO: Implement save() method.
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace Incoviba\Mapper;
use Incoviba\Model\Model;
use Incoviba\Model\Proyecto\TipoEstadoProyecto as BaseModel;
class TipoEstadoProyecto extends Mapper
{
protected string $table = 'tipo_estado_proyecto';
protected function load(bool|array $row, bool $lazy = false): BaseModel|bool
{
$model = new BaseModel();
$model->id = $row['id'];
$model->descripcion = $row['descripcion'];
$model->orden = $row['orden'];
$model->etapa = $this->getMapper(Etapa::class)->fetchById($row['etapa']);
return $model;
}
public function save(Model $model): bool
{
// TODO: Implement save() method.
}
}

View File

@ -4,5 +4,7 @@ namespace Incoviba\Model\Common;
class Comuna extends \Incoviba\Model\Model
{
public int $id;
public string $descripcion;
// public bool|Provincia $provincia;
}

View File

@ -7,5 +7,24 @@ class Direccion extends \Incoviba\Model\Model
public string $calle;
public int $numero;
public string $extra;
public Comuna $comuna;
public bool|Comuna $comuna;
public function completa(): string
{
$str = implode(' ', [$this->calle, $this->numero]);
if ($this->extra != '') {
$str .= ' ' . $this->extra;
}
if ($this->comuna) {
$str .= ', ' . $this->comuna->descripcion;
}
return $str;
}
public function jsonSerialize(): mixed
{
$arr = parent::jsonSerialize();
$arr['completa'] = $this->completa();
return $arr;
}
}

View File

@ -0,0 +1,12 @@
<?php
namespace Incoviba\Model\Proyecto;
class Agente extends \Incoviba\Model\Model
{
public int $id;
public ?int $rut;
public string $descripcion;
public string $representante;
public string $abreviacion;
}

View File

@ -4,6 +4,6 @@ namespace Incoviba\Model\Proyecto;
class AgenteTipo extends \Incoviba\Model\Model
{
public int $id;
public Agente $agente;
public TipoAgente $tipo;
public bool|Agente $agente;
public bool|TipoAgente $tipo;
}

View File

@ -0,0 +1,11 @@
<?php
namespace Incoviba\Model\Proyecto;
class EstadoProyecto extends \Incoviba\Model\Model
{
public int $id;
public bool|Proyecto $proyecto;
public bool|TipoEstadoProyecto $tipo;
public \DateTimeInterface $fecha;
}

View File

@ -0,0 +1,10 @@
<?php
namespace Incoviba\Model\Proyecto;
class Etapa extends \Incoviba\Model\Model
{
public int $id;
public string $descripcion;
public int $orden;
}

View File

@ -9,9 +9,9 @@ use Incoviba\Model\Proyecto\Proyecto\Superficie;
class Proyecto extends Model
{
public int $id;
public Inmobiliaria $inmobiliaria;
public bool|Inmobiliaria $inmobiliaria;
public string $descripcion;
public Direccion $direccion;
public bool|Direccion $direccion;
public float $valor_terreno;
public Superficie $superficie;
public float $corredor;

View File

@ -0,0 +1,9 @@
<?php
namespace Incoviba\Model\Proyecto;
class TipoAgente extends \Incoviba\Model\Model
{
public int $id;
public string $descripcion;
}

View File

@ -0,0 +1,11 @@
<?php
namespace Incoviba\Model\Proyecto;
class TipoEstadoProyecto extends \Incoviba\Model\Model
{
public int $id;
public string $descripcion;
public int $orden;
public bool|Etapa $etapa;
}