diff --git a/app/src/Controller/API/Ventas/Reservations.php b/app/src/Controller/API/Ventas/Reservations.php index 01c65db..83fc3f7 100644 --- a/app/src/Controller/API/Ventas/Reservations.php +++ b/app/src/Controller/API/Ventas/Reservations.php @@ -11,7 +11,8 @@ class Reservations { 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 = []; try { @@ -22,6 +23,18 @@ class 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 { $output = [ @@ -100,4 +113,47 @@ class Reservations 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); + } } diff --git a/app/src/Exception/Model/InvalidState.php b/app/src/Exception/Model/InvalidState.php new file mode 100644 index 0000000..3c82782 --- /dev/null +++ b/app/src/Exception/Model/InvalidState.php @@ -0,0 +1,13 @@ + $this->name ]; } + public static function getTypes(): array + { + return [self::ACTIVE->value, self::INACTIVE->value, self::REJECTED->value]; + } } diff --git a/app/src/Repository/Venta/Reservation.php b/app/src/Repository/Venta/Reservation.php index de990b5..c967189 100644 --- a/app/src/Repository/Venta/Reservation.php +++ b/app/src/Repository/Venta/Reservation.php @@ -4,6 +4,7 @@ namespace Incoviba\Repository\Venta; use DateTimeInterface; use DateInterval; use Incoviba\Common\Define; +use Incoviba\Exception\Model\InvalidState; use PDO; use Incoviba\Common; use Incoviba\Model; @@ -31,12 +32,12 @@ class Reservation extends Common\Ideal\Repository $map = (new Common\Implement\Repository\MapperParser()) ->register('project_id', (new Common\Implement\Repository\Mapper()) ->setProperty('project') - ->setFunction(function($data) use ($data) { + ->setFunction(function($data) { return $this->proyectoRepository->fetchById($data['project_id']); })) ->register('buyer_rut', (new Common\Implement\Repository\Mapper()) ->setProperty('buyer') - ->setFunction(function($data) use ($data) { + ->setFunction(function($data) { return $this->personaRepository->fetchById($data['buyer_rut']); })) ->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'); 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 { diff --git a/app/src/Repository/Venta/Reservation/State.php b/app/src/Repository/Venta/Reservation/State.php index 0a98a6d..9a34efa 100644 --- a/app/src/Repository/Venta/Reservation/State.php +++ b/app/src/Repository/Venta/Reservation/State.php @@ -22,7 +22,7 @@ class State extends Common\Ideal\Repository $map = (new Common\Implement\Repository\MapperParser(['type'])) ->register('reservation_id', (new Common\Implement\Repository\Mapper()) ->setProperty('reservation') - ->setFunction(function($data) use ($data) { + ->setFunction(function($data) { return $this->reservationRepository->fetchById($data['reservation_id']); })) ->register('date', new Common\Implement\Repository\Mapper\DateTime('date')); diff --git a/app/src/Service/Venta/Reservation.php b/app/src/Service/Venta/Reservation.php index f5a172e..166f0d8 100644 --- a/app/src/Service/Venta/Reservation.php +++ b/app/src/Service/Venta/Reservation.php @@ -14,8 +14,8 @@ use Incoviba\Repository; class Reservation extends Ideal\Service\API { - public function __construct(LoggerInterface $logger, - protected Repository\Venta\Reservation $reservationRepository, + public function __construct(LoggerInterface $logger, + protected Repository\Venta\Reservation $reservationRepository, protected Repository\Venta\Reservation\State $stateRepository) { parent::__construct($logger); @@ -29,6 +29,14 @@ class Reservation extends Ideal\Service\API 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 { @@ -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 { try {