Reservations

This commit is contained in:
Juan Pablo Vial
2025-08-08 17:04:50 -04:00
parent 62aa6a08a0
commit 42336133cd
6 changed files with 210 additions and 6 deletions

View File

@ -11,7 +11,8 @@ class Reservations
{ {
use withJson; use withJson;
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, Service\Venta\Reservation $reservationService): ResponseInterface public function __invoke(ServerRequestInterface $request, ResponseInterface $response,
Service\Venta\Reservation $reservationService): ResponseInterface
{ {
$reservations = []; $reservations = [];
try { try {
@ -22,6 +23,18 @@ class Reservations
return $this->withJson($response, compact('reservations')); return $this->withJson($response, compact('reservations'));
} }
public function getByProject(ServerRequestInterface $request, ResponseInterface $response,
Service\Venta\Reservation $reservationService, int $project_id): ResponseInterface
{
$reservations = [];
try {
$reservations = $reservationService->getByProject($project_id);
} catch (ServiceAction\Read $exception) {
return $this->withError($response, $exception);
}
return $this->withJson($response, compact('reservations'));
}
public function get(ServerRequestInterface $request, ResponseInterface $response, Service\Venta\Reservation $reservationService, int $reservation_id): ResponseInterface public function get(ServerRequestInterface $request, ResponseInterface $response, Service\Venta\Reservation $reservationService, int $reservation_id): ResponseInterface
{ {
$output = [ $output = [
@ -100,4 +113,47 @@ class Reservations
return $this->withJson($response, $output); return $this->withJson($response, $output);
} }
public function active(ServerRequestInterface $request, ResponseInterface $response,
Service\Venta\Reservation $reservationService, int $project_id): ResponseInterface
{
$output = [
'project_id' => $project_id,
'reservations' => [],
'success' => false,
];
try {
$output['reservations'] = $reservationService->getActive($project_id);
$output['success'] = true;
} catch (ServiceAction\Read) {}
return $this->withJson($response, $output);
}
public function pending(ServerRequestInterface $request, ResponseInterface $response,
Service\Venta\Reservation $reservationService, int $project_id): ResponseInterface
{
$output = [
'project_id' => $project_id,
'reservations' => [],
'success' => false,
];
try {
$output['reservations'] = $reservationService->getPending($project_id);
$output['success'] = true;
} catch (ServiceAction\Read) {}
return $this->withJson($response, $output);
}
public function rejected(ServerRequestInterface $request, ResponseInterface $response,
Service\Venta\Reservation $reservationService, int $project_id): ResponseInterface
{
$output = [
'project_id' => $project_id,
'reservations' => [],
'success' => false,
];
try {
$output['reservations'] = $reservationService->getRejected($project_id);
$output['success'] = true;
} catch (ServiceAction\Read) {}
return $this->withJson($response, $output);
}
} }

View File

@ -0,0 +1,13 @@
<?php
namespace Incoviba\Exception\Model;
use Throwable;
use Exception;
class InvalidState extends Exception
{
public function __construct(string $message = "Invalid state", int $code = 505, ?Throwable $previous = null)
{
parent::__construct($message, $code, $previous);
}
}

View File

@ -14,4 +14,8 @@ enum Type: int
'description' => $this->name 'description' => $this->name
]; ];
} }
public static function getTypes(): array
{
return [self::ACTIVE->value, self::INACTIVE->value, self::REJECTED->value];
}
} }

View File

@ -4,6 +4,7 @@ namespace Incoviba\Repository\Venta;
use DateTimeInterface; use DateTimeInterface;
use DateInterval; use DateInterval;
use Incoviba\Common\Define; use Incoviba\Common\Define;
use Incoviba\Exception\Model\InvalidState;
use PDO; use PDO;
use Incoviba\Common; use Incoviba\Common;
use Incoviba\Model; use Incoviba\Model;
@ -31,12 +32,12 @@ class Reservation extends Common\Ideal\Repository
$map = (new Common\Implement\Repository\MapperParser()) $map = (new Common\Implement\Repository\MapperParser())
->register('project_id', (new Common\Implement\Repository\Mapper()) ->register('project_id', (new Common\Implement\Repository\Mapper())
->setProperty('project') ->setProperty('project')
->setFunction(function($data) use ($data) { ->setFunction(function($data) {
return $this->proyectoRepository->fetchById($data['project_id']); return $this->proyectoRepository->fetchById($data['project_id']);
})) }))
->register('buyer_rut', (new Common\Implement\Repository\Mapper()) ->register('buyer_rut', (new Common\Implement\Repository\Mapper())
->setProperty('buyer') ->setProperty('buyer')
->setFunction(function($data) use ($data) { ->setFunction(function($data) {
return $this->personaRepository->fetchById($data['buyer_rut']); return $this->personaRepository->fetchById($data['buyer_rut']);
})) }))
->register('date', new Common\Implement\Repository\Mapper\DateTime('date')); ->register('date', new Common\Implement\Repository\Mapper\DateTime('date'));
@ -98,6 +99,86 @@ class Reservation extends Common\Ideal\Repository
->where('buyer_rut = :buyer_rut AND date >= :date'); ->where('buyer_rut = :buyer_rut AND date >= :date');
return $this->fetchOne($query, ['buyer_rut' => $buyer_rut, 'date' => $date->sub(new DateInterval('P10D'))->format('Y-m-d')]); return $this->fetchOne($query, ['buyer_rut' => $buyer_rut, 'date' => $date->sub(new DateInterval('P10D'))->format('Y-m-d')]);
} }
public function fetchByProject(int $project_id): array
{
$query = $this->connection->getQueryBuilder()
->select()
->from('reservations')
->where('project_id = :project_id');
return $this->fetchMany($query, ['project_id' => $project_id]);
}
/**
* @param int $project_id
* @param int $state
* @return array
* @throws Common\Implement\Exception\EmptyResult
* @throws InvalidState
*/
public function fetchState(int $project_id, int $state): array
{
if (!in_array($state, Model\Venta\Reservation\State\Type::getTypes())) {
throw new InvalidState();
}
$sub1 = $this->connection->getQueryBuilder()
->select('MAX(id) AS id, reservation_id')
->from('reservation_states')
->group('reservation_id');
$sub2 = $this->connection->getQueryBuilder()
->select('er1.*')
->from('reservation_states er1')
->joined("INNER JOIN ({$sub1}) er0 ON er0.id = er1.id");
$query = $this->connection->getQueryBuilder()
->select()
->from('reservations')
->joined("INNER JOIN ({$sub2}) er ON er.reservation_id = reservations.id")
->where('project_id = :project_id AND er.type = :state');
return $this->fetchMany($query, ['project_id' => $project_id,
'state' => $state]);
}
/**
* @param int $project_id
* @return array
* @throws Common\Implement\Exception\EmptyResult
*/
public function fetchActive(int $project_id): array
{
try {
return $this->fetchState($project_id, Model\Venta\Reservation\State\Type::ACTIVE->value);
} catch (InvalidState $exception) {
throw new Common\Implement\Exception\EmptyResult('Select active reservations', $exception);
}
}
/**
* @param int $project_id
* @return array
* @throws Common\Implement\Exception\EmptyResult
*/
public function fetchPending(int $project_id): array
{
try {
return $this->fetchState($project_id, Model\Venta\Reservation\State\Type::INACTIVE->value);
} catch (InvalidState $exception) {
throw new Common\Implement\Exception\EmptyResult('Select pending reservations', $exception);
}
}
/**
* @param int $project_id
* @return array
* @throws Common\Implement\Exception\EmptyResult
*/
public function fetchRejected(int $project_id): array
{
try {
return $this->fetchState($project_id, Model\Venta\Reservation\State\Type::REJECTED->value);
} catch (InvalidState $exception) {
throw new Common\Implement\Exception\EmptyResult('Select rejected reservations', $exception);
}
}
protected function saveUnits(Model\Venta\Reservation $reservation): void protected function saveUnits(Model\Venta\Reservation $reservation): void
{ {

View File

@ -22,7 +22,7 @@ class State extends Common\Ideal\Repository
$map = (new Common\Implement\Repository\MapperParser(['type'])) $map = (new Common\Implement\Repository\MapperParser(['type']))
->register('reservation_id', (new Common\Implement\Repository\Mapper()) ->register('reservation_id', (new Common\Implement\Repository\Mapper())
->setProperty('reservation') ->setProperty('reservation')
->setFunction(function($data) use ($data) { ->setFunction(function($data) {
return $this->reservationRepository->fetchById($data['reservation_id']); return $this->reservationRepository->fetchById($data['reservation_id']);
})) }))
->register('date', new Common\Implement\Repository\Mapper\DateTime('date')); ->register('date', new Common\Implement\Repository\Mapper\DateTime('date'));

View File

@ -14,8 +14,8 @@ use Incoviba\Repository;
class Reservation extends Ideal\Service\API class Reservation extends Ideal\Service\API
{ {
public function __construct(LoggerInterface $logger, public function __construct(LoggerInterface $logger,
protected Repository\Venta\Reservation $reservationRepository, protected Repository\Venta\Reservation $reservationRepository,
protected Repository\Venta\Reservation\State $stateRepository) protected Repository\Venta\Reservation\State $stateRepository)
{ {
parent::__construct($logger); parent::__construct($logger);
@ -29,6 +29,14 @@ class Reservation extends Ideal\Service\API
return []; return [];
} }
} }
public function getByProject(int $project_id): array
{
try {
return array_map([$this, 'process'], $this->reservationRepository->fetchByProject($project_id));
} catch (Implement\Exception\EmptyResult $exception) {
throw new ServiceAction\Read(__CLASS__, $exception);
}
}
public function get(int $id): Model\Venta\Reservation public function get(int $id): Model\Venta\Reservation
{ {
@ -39,6 +47,48 @@ class Reservation extends Ideal\Service\API
} }
} }
/**
* @param int $project_id
* @return array
* @throws ServiceAction\Read
*/
public function getActive(int $project_id): array
{
try {
return array_map([$this, 'process'], $this->reservationRepository->fetchActive($project_id));
} catch (Implement\Exception\EmptyResult $exception) {
throw new ServiceAction\Read(__CLASS__, $exception);
}
}
/**
* @param int $project_id
* @return array
* @throws ServiceAction\Read
*/
public function getPending(int $project_id): array
{
try {
return array_map([$this, 'process'], $this->reservationRepository->fetchPending($project_id));
} catch (Implement\Exception\EmptyResult $exception) {
throw new ServiceAction\Read(__CLASS__, $exception);
}
}
/**
* @param int $project_id
* @return array
* @throws ServiceAction\Read
*/
public function getRejected(int $project_id): array
{
try {
return array_map([$this, 'process'], $this->reservationRepository->fetchRejected($project_id));
} catch (Implement\Exception\EmptyResult $exception) {
throw new ServiceAction\Read(__CLASS__, $exception);
}
}
public function add(array $data): Model\Venta\Reservation public function add(array $data): Model\Venta\Reservation
{ {
try { try {