Files
oficial/app/src/Controller/API/Ventas.php
2024-07-04 18:09:25 -04:00

374 lines
16 KiB
PHP

<?php
namespace Incoviba\Controller\API;
use PDOException;
use DateTimeImmutable;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Incoviba\Common\Ideal\Controller;
use Incoviba\Common\Implement\Exception\EmptyRedis;
use Incoviba\Common\Implement\Exception\EmptyResult;
use Incoviba\Controller\withRedis;
use Incoviba\Model;
use Incoviba\Repository;
use Incoviba\Service;
use Psr\Log\LoggerInterface;
class Ventas extends Controller
{
use withJson, withRedis;
public function proyecto(ServerRequestInterface $request, ResponseInterface $response, Service\Redis $redisService,
Repository\Proyecto $proyectoRepository, Repository\Venta $ventaRepository): ResponseInterface
{
$body = $request->getBody();
$json = json_decode($body->getContents());
$proyecto_id = $json->proyecto_id;
$output = [
'proyecto' => [
'id' => $proyecto_id
],
'total' => 0
];
$proyectosKey = "proyectos";
try {
$proyectos = $this->fetchRedis($redisService, $proyectosKey);
} catch (EmptyRedis) {
$proyectos = $proyectoRepository->fetchAllActive();
$this->saveRedis($redisService, $proyectosKey, $proyectos);
}
$proyecto = array_values(array_filter($proyectos, function($proyecto) use ($proyecto_id) {return $proyecto->id === $proyecto_id;}))[0];
$output['proyecto']['descripcion'] = $proyecto->descripcion;
$redisKey = "ventas:proyecto:{$proyecto_id}";
try {
$output['ventas'] = $this->fetchRedis($redisService, $redisKey);
$output['total'] = count($output['ventas']);
} catch (EmptyRedis) {
try {
$ventas = $ventaRepository->fetchActivaByProyecto($proyecto_id);
$output['ventas'] = array_map(function(Model\Venta $venta) {return $venta->id;}, $ventas);
$output['total'] = count($ventas);
$this->saveRedis($redisService, $redisKey, $output['ventas']);
} catch (EmptyResult) {}
}
return $this->withJson($response, $output);
}
public function get(ServerRequestInterface $request, ResponseInterface $response, Service\Redis $redisService,
Service\Venta $service, int $venta_id): ResponseInterface
{
$redisKey = "venta:{$venta_id}";
$output = [
'venta' => null
];
try {
$venta = $this->fetchRedis($redisService, $redisKey);
$output = compact('venta');
} catch (EmptyRedis) {
try {
$venta = $service->getById($venta_id);
$output = compact('venta');
$this->saveRedis($redisService, $redisKey, $venta);
} catch (EmptyResult $exception) {
$this->logger->notice($exception);
}
}
return $this->withJson($response, $output);
}
public function getMany(ServerRequestInterface $request, ResponseInterface $response, Service\Redis $redisService,
Service\Venta $service): ResponseInterface
{
$body = $request->getParsedBody();
$output = [
'input' => $body,
'ventas' => []
];
$ventas = explode(',', $body['ventas']);
foreach ($ventas as $venta_id) {
$redisKey = "venta:{$venta_id}";
try {
$venta = $this->fetchRedis($redisService, $redisKey);
$output['ventas'] []= $venta;
} catch (EmptyRedis) {
try {
$venta = $service->getById($venta_id);
$output['ventas'] []= $venta;
$this->saveRedis($redisService, $redisKey, $venta);
} catch (EmptyResult $exception) {
$this->logger->notice($exception);
}
}
}
return $this->withJson($response, $output);
}
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:{$proyecto_id}:{$today->format('Y-m-d')}";
$output = [
'proyecto_id' => $proyecto_id,
'promesas' => 0
];
try {
$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, Service\Redis $redisService): ResponseInterface
{
$body = $request->getBody();
$json = json_decode($body->getContents());
$proyecto_id = $json->proyecto_id;
$today = new DateTimeImmutable();
$redisKey = "escrituras:proyecto:{$proyecto_id}:{$today->format('Y-m-d')}";
$output = [
'proyecto_id' => $proyecto_id,
'escrituras' => [
'firmar' => 0,
'pagar' => 0,
'abonar' => 0
]
];
try {
$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';
});
$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';
});
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\Redis $redisService,
Service\Venta $service, Repository\Venta\Comentario $comentarioRepository, int $venta_id): ResponseInterface
{
$venta = $service->getById($venta_id);
$output = ['total' => 0, 'comentarios' => []];
$redisKey = "comentarios:venta:{$venta_id}";
try {
$output['comentarios'] = $this->fetchRedis($redisService, $redisKey);
$output['total'] = count($output['comentarios']);
} catch (EmptyRedis) {
try {
$comentarios = $comentarioRepository->fetchActiveByVenta($venta->id);
$output['total'] = count($comentarios);
$output['comentarios'] = $comentarios;
$this->saveRedis($redisService, $redisKey, $output['comentarios']);
} catch (EmptyResult) {}
}
return $this->withJson($response, $output);
}
public function add(ServerRequestInterface $request, ResponseInterface $response, Service\Redis $redisService,
Service\Venta $ventaService): ResponseInterface
{
$data = $request->getParsedBody();
$output = [
'status' => false,
'venta_id' => null,
'errors' => []
];
try {
$venta = $ventaService->add($data);
$this->saveRedis($redisService, "venta:{$venta->id}", $venta);
$output['venta_id'] = $venta->id;
$output['status'] = true;
} catch (EmptyResult | PDOException $exception) {
$output['errors'] = [
'code' => $exception->getCode(),
'message' => $exception->getMessage(),
'stack' => $exception->getTraceAsString()
];
}
return $this->withJson($response, $output);
}
public function edit(ServerRequestInterface $request, ResponseInterface $response, Repository\Venta $ventaRepository, int $venta_id): ResponseInterface
{
$body = $request->getParsedBody();
$output = [
'venta_id' => $venta_id,
'input' => $body,
'edited' => false
];
try {
$venta = $ventaRepository->fetchById($venta_id);
$body['valor_uf'] = $body['valor'];
$body['fecha'] = (new DateTimeImmutable($body['fecha']))->format('Y-m-d');
$ventaRepository->edit($venta, $body);
$output['edited'] = true;
} catch (EmptyResult) {}
return $this->withJson($response, $output);
}
public function unidades(ServerRequestInterface $request, ResponseInterface $response, Service\Redis $redisService,
Service\Venta\Unidad $unidadService, int $venta_id): ResponseInterface
{
$output = [
'venta_id' => $venta_id,
'unidades' => []
];
$redisKey = "unidades:venta:{$venta_id}";
try {
$output['unidades'] = $this->fetchRedis($redisService, $redisKey);
} catch (EmptyRedis) {
try {
$unidades = $unidadService->getByVenta($venta_id);
$output['unidades'] = json_decode(json_encode($unidades));
array_walk($output['unidades'], function($unidad, $index, $unidades) {
$unidad->prorrateo = $unidades[$index]->prorrateo;
$unidad->precios = $unidades[$index]->precios;
$unidad->current_precio = $unidades[$index]->currentPrecio;
}, $unidades);
$this->saveRedis($redisService, $redisKey, $output['unidades']);
} catch (EmptyResult) {}
}
return $this->withJson($response, $output);
}
public function escriturar(ServerRequestInterface $request, ResponseInterface $response, Service\Venta $ventaService, int $venta_id): ResponseInterface
{
$data = $request->getParsedBody();
$output = [
'input' => $data,
'venta_id' => $venta_id,
'status' => false
];
try {
$venta = $ventaService->getById($venta_id);
$output['status'] = $ventaService->escriturar($venta, $data);
} catch (EmptyResult) {}
return $this->withJson($response, $output);
}
public function desistir(ServerRequestInterface $request, ResponseInterface $response, Service\Venta $ventaService, int $venta_id): ResponseInterface
{
$data = $request->getParsedBody();
$output = [
'input' => $data,
'venta_id' => $venta_id,
'desistida' => false
];
try {
$venta = $ventaService->getById($venta_id);
$output['desistida'] = $ventaService->desistir($venta, $data);
} catch (EmptyResult) {}
return $this->withJson($response, $output);
}
public function insistir(ServerRequestInterface $request, ResponseInterface $response, Service\Venta $ventaService, int $venta_id): ResponseInterface
{
$output = [
'venta_id' => $venta_id,
'eliminado' => false
];
try {
$venta = $ventaService->getById($venta_id);
$output['eliminado'] = $ventaService->insistir($venta);
} catch (EmptyResult) {}
return $this->withJson($response, $output);
}
public function propietario(ServerRequestInterface $request, ResponseInterface $response,
Service\Venta\Propietario $propietarioService,
Repository\Venta $ventaRepository, int $venta_id): ResponseInterface
{
$body = $request->getBody();
$data = json_decode($body->getContents(), true);
$this->logger->error(var_export($data, true));
$output = [
'input' => $data,
'venta_id' => $venta_id,
'propietario' => false,
'edited' => false
];
try {
$venta = $ventaRepository->fetchById($venta_id);
$propietario = $propietarioService->getByRut($venta->propietario()->rut);
$output['propietario'] = $propietario;
if (isset($data['rut'])) {
try {
$propietario = $propietarioService->getByRut($data['rut']);
$propietario = $propietarioService->edit($propietario, $data);
} catch (EmptyResult) {
$propietario = $propietarioService->addPropietario($data);
}
$data = [
'propietario' => $propietario->rut
];
$ventaRepository->edit($venta, $data);
} else {
$propietario = $propietarioService->edit($propietario, $data);
}
$output['edited'] = true;
} catch (EmptyResult) {}
return $this->withJson($response, $output);
}
public function addComentario(ServerRequestInterface $request, ResponseInterface $response,
Repository\Venta $ventaRepository, Repository\Venta\Comentario $comentarioRepository,
Service\Redis $redisService,
int $venta_id): ResponseInterface
{
$body = $request->getParsedBody();
$output = [
'venta_id' => $venta_id,
'input' => $body,
'comentario' => null,
'added' => false
];
try {
$venta = $ventaRepository->fetchById($venta_id);
$body['venta'] = $venta->id;
$body['estado'] = true;
$filteredData = $comentarioRepository->filterData($body);
try {
$comentarioRepository->fetchByVentaAndFechaAndTexto($venta_id, new DateTimeImmutable($filteredData['fecha']), $filteredData['texto']);
} catch (EmptyResult) {
$redisKey = "comentarios:venta:{$venta_id}";
$comentarios = $this->fetchRedis($redisService, $redisKey);
$comentario = $comentarioRepository->create($filteredData);
$output['comentario'] = $comentarioRepository->save($comentario);
$comentarios []= $comentario;
$this->saveRedis($redisService, $redisKey, $comentarios);
}
$output['added'] = true;
} catch (EmptyResult) {}
return $this->withJson($response, $output);
}
}