313 lines
11 KiB
PHP
313 lines
11 KiB
PHP
<?php
|
|
|
|
namespace common\manager;
|
|
|
|
use common\models\Card;
|
|
use common\models\CardEventRegistrationForm;
|
|
use common\models\Customer;
|
|
use common\models\Event;
|
|
use common\models\EventRegistration;
|
|
use common\models\Ticket;
|
|
use customerapi\models\available\EventInterval;
|
|
use customerapi\models\registrations\EventRegistrationAvailable;
|
|
use customerapi\models\details\EventRegistrationView;
|
|
use Exception;
|
|
use Yii;
|
|
use yii\base\BaseObject;
|
|
use yii\db\ActiveRecord;
|
|
use yii\db\Query;
|
|
use yii\web\BadRequestHttpException;
|
|
use yii\web\NotFoundHttpException;
|
|
use yii\web\ServerErrorHttpException;
|
|
|
|
/**
|
|
* Created by IntelliJ IDEA.
|
|
* User: rocho
|
|
* Date: 2018.12.17.
|
|
* Time: 6:12
|
|
*/
|
|
class EventRegistrationManager extends BaseObject
|
|
{
|
|
const CARD_NOT_FOUND = 1;
|
|
const CUSTOMER_NOT_FOUND = 2;
|
|
const TICKET_NOT_FOUND = 3;
|
|
const NO_FREE_SEATS = 4;
|
|
const EVENT_TYPE_NOT_FOUND = 5;
|
|
const TICKET_INSUFFICIENT = 6;
|
|
const UNKNOWN_ERROR = 7;
|
|
const MAX_SEAT_COUNT_EXCEEDED = 8;
|
|
const EVENT_UNAVAILABLE = 9;
|
|
const ALREADY_REGISTERED = 10;
|
|
const EVENT_START_DATE_IN_PAST = 11;
|
|
|
|
const EVENT_NOT_FOUND = 12;
|
|
const ALREADY_CANCELLED = 13;
|
|
const ALREADY_DELETED = 14;
|
|
const CANCEL_TIME_LIMIT_REACHED = 15;
|
|
|
|
public static $STATES = [
|
|
self::CARD_NOT_FOUND => 'CARD_NOT_FOUND',
|
|
self::CUSTOMER_NOT_FOUND => 'CUSTOMER_NOT_FOUND',
|
|
self::TICKET_NOT_FOUND => 'TICKET_NOT_FOUND',
|
|
self::NO_FREE_SEATS => 'NO_FREE_SEATS',
|
|
self::EVENT_TYPE_NOT_FOUND => 'EVENT_TYPE_NOT_FOUND',
|
|
self::TICKET_INSUFFICIENT => 'TICKET_INSUFFICIENT',
|
|
self::UNKNOWN_ERROR => 'UNKNOWN_ERROR',
|
|
self::MAX_SEAT_COUNT_EXCEEDED => 'MAX_SEAT_COUNT_EXCEEDED',
|
|
self::EVENT_UNAVAILABLE => 'EVENT_UNAVAILABLE',
|
|
self::ALREADY_REGISTERED => 'ALREADY_REGISTERED',
|
|
];
|
|
|
|
/**
|
|
* @param CardEventRegistrationForm $cardEventForm
|
|
* @throws Exception
|
|
*/
|
|
public function registerCard($cardEventForm)
|
|
{
|
|
$db = Yii::$app->db;
|
|
$tx = $db->beginTransaction();
|
|
try {
|
|
if ($cardEventForm->validate()) {
|
|
|
|
$requiresTicket = false;
|
|
|
|
/** @var Card $card */
|
|
$card = Card::readCard($cardEventForm->card_number, false);
|
|
if (!isset($card)) {
|
|
throw new NotFoundHttpException('Card not found: ' . $cardEventForm->card_number, self::CARD_NOT_FOUND);
|
|
}
|
|
|
|
if ($card->isFree()) {
|
|
throw new NotFoundHttpException('Customer not found', self::CUSTOMER_NOT_FOUND);
|
|
}
|
|
|
|
$activeTickets = $card->getActiveTickets();
|
|
if (count($activeTickets) === 0) {
|
|
throw new BadRequestHttpException('Ticket not found1', self::TICKET_NOT_FOUND);
|
|
}
|
|
|
|
/** @var Event $event */
|
|
$event = Event::find()->andWhere(['id' => $cardEventForm->event_id])->one();
|
|
if (!isset($event)) {
|
|
throw new NotFoundHttpException('Event not found: ' . $cardEventForm->event_id);
|
|
}
|
|
|
|
if (isset($event->deleted_at)) {
|
|
throw new BadRequestHttpException('Event deleted', self::EVENT_UNAVAILABLE);
|
|
}
|
|
|
|
$now = strtotime("now utc");
|
|
if ($event->start < $now) {
|
|
throw new BadRequestHttpException('Event start date in past', self::EVENT_START_DATE_IN_PAST);
|
|
}
|
|
|
|
|
|
if (!$event->hasFreeSeats()) {
|
|
throw new BadRequestHttpException('No free seats', self::NO_FREE_SEATS);
|
|
}
|
|
|
|
$eventType = $event->eventType;
|
|
|
|
if (!isset($eventType)) {
|
|
throw new ServerErrorHttpException('Event type not found', self::EVENT_TYPE_NOT_FOUND);
|
|
}
|
|
|
|
//detect if customer is already registered to event
|
|
/** @var EventRegistration[] $registrations */
|
|
$registrations = $event->getActiveEventRegistrations()->all();
|
|
|
|
foreach ($registrations as $registration) {
|
|
if ($registration->id_customer == $card->customer->id_customer) {
|
|
throw new BadRequestHttpException("Already registered", self::ALREADY_REGISTERED);
|
|
}
|
|
}
|
|
|
|
$selectedTicket = $eventType->findTicketAllowingEventType($activeTickets);
|
|
|
|
if (!isset($selectedTicket)) {
|
|
throw new BadRequestHttpException('Ticket not found2', self::TICKET_INSUFFICIENT);
|
|
}
|
|
|
|
try {
|
|
$selectedTicket->consumeReservationCount(1);
|
|
} catch (\Exception $e) {
|
|
throw new BadRequestHttpException('Max ticket seat count exceeded', self::MAX_SEAT_COUNT_EXCEEDED);
|
|
}
|
|
|
|
$selectedTicket->save(false);
|
|
|
|
$registration = new EventRegistration();
|
|
$registration->id_event = $event->id;
|
|
$registration->id_card = $card->id_card;
|
|
$registration->id_ticket = $selectedTicket->id_ticket;
|
|
$registration->id_customer = $card->customer->id_customer;
|
|
try {
|
|
$registration->save(false);
|
|
} catch (\yii\db\Exception $exception) {
|
|
throw new ServerErrorHttpException('Failed to save', self::UNKNOWN_ERROR);
|
|
}
|
|
|
|
$cardEventForm->registration = $registration;
|
|
}
|
|
$tx->commit();
|
|
} catch (Exception $exception) {
|
|
$tx->rollBack();
|
|
throw $exception;
|
|
}
|
|
|
|
}
|
|
|
|
public function createFindRegistrationsQuery($idEvent)
|
|
{
|
|
$query = new Query();
|
|
$query->select([
|
|
'event_registration.id as event_registration_id',
|
|
'event_registration.created_at as event_registration_created_at',
|
|
'event_registration.canceled_at as event_registration_canceled_at',
|
|
'event_registration.deleted_at as event_registration_deleted_at',
|
|
'card.id_card as card_id_card',
|
|
'card.number as card_number',
|
|
'customer.id_customer as customer_id_customer',
|
|
'customer.name as customer_name',
|
|
'customer.email as customer_email',
|
|
]);
|
|
$query->from(EventRegistration::tableName());
|
|
$query->innerJoin(Event::tableName(), 'event_registration.id_event = event.id');
|
|
$query->innerJoin(Card::tableName(), 'event_registration.id_card = card.id_card');
|
|
$query->innerJoin(Customer::tableName(), 'customer.id_customer_card = card.id_card');
|
|
$query->andWhere(['event_registration.id_event' => $idEvent]);
|
|
|
|
return $query;
|
|
}
|
|
|
|
|
|
/**
|
|
* @param $idRegistration
|
|
* @return array|EventRegistration|ActiveRecord|null
|
|
* @throws NotFoundHttpException
|
|
*/
|
|
public function loadRegistration($idRegistration)
|
|
{
|
|
|
|
$registration = EventRegistration::find()->andWhere(['id' => $idRegistration])->one();
|
|
if ($registration === null) {
|
|
throw new NotFoundHttpException('The requested registration does not exist.');
|
|
}
|
|
return $registration;
|
|
}
|
|
|
|
/**
|
|
* @param EventRegistration $registration
|
|
* @throws ServerErrorHttpException
|
|
*/
|
|
public function cancelRegistration($registration)
|
|
{
|
|
if (isset($registration->canceled_at)) {
|
|
throw new BadRequestHttpException('The registration is already canceled', self::ALREADY_CANCELLED);
|
|
}
|
|
|
|
if (isset($registration->deleted_at)) {
|
|
throw new BadRequestHttpException('The reservation is already deleted', self::ALREADY_DELETED);
|
|
}
|
|
|
|
$event = Event::findOne($registration->id_event);
|
|
|
|
if (!isset($event)) {
|
|
throw new BadRequestHttpException('The reservation is already deleted', self::EVENT_NOT_FOUND);
|
|
}
|
|
$tx = \Yii::$app->db->beginTransaction();
|
|
try {
|
|
$now = strtotime("now UTC");
|
|
|
|
$timeUntilEventStart = $event->start - $now;
|
|
if ( $timeUntilEventStart < 30 * 60){
|
|
throw new BadRequestHttpException('The reservation is already deleted', self::CANCEL_TIME_LIMIT_REACHED);
|
|
}
|
|
|
|
$registration->canceled_at = date('Y-m-d H:i:s', $now);
|
|
$registration->save(false);
|
|
|
|
$ticket = Ticket::findOne($registration->id_ticket);
|
|
|
|
if (!isset($ticket)) {
|
|
throw new BadRequestHttpException('The ticket is not found');
|
|
}
|
|
|
|
$ticket->restoreReservationCount(1);
|
|
$ticket->save(false);
|
|
|
|
$tx->commit();
|
|
} catch (\Exception $e) {
|
|
$tx->rollBack();
|
|
throw $e;
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* @param EventRegistration $registration
|
|
* @return bool
|
|
* @throws \yii\base\Exception
|
|
*/
|
|
public function deleteRegistration($registration)
|
|
{
|
|
if (isset($registration->deleted_at)) {
|
|
return false;
|
|
}
|
|
|
|
// $ticket = Ticket::findOne(['id_ticket' => $registration->id_ticket]);
|
|
// if( !isset($ticket ) ) {
|
|
// throw new \yii\base\Exception('Ticket not found: ' . $registration->id_ticket);
|
|
// }
|
|
//
|
|
// $ticket->restoreReservationCount(1);
|
|
// $ticket->save(false);
|
|
|
|
$registration->deleted_at = date('Y-m-d H:i:s');
|
|
return $registration->save(false);
|
|
|
|
}
|
|
|
|
/**
|
|
* Delete an event
|
|
* @param Event $event
|
|
* @throws Exception
|
|
* @throws Throwable
|
|
*/
|
|
public function deleteEvent($event)
|
|
{
|
|
$db = Yii::$app->db;
|
|
$tx = $db->beginTransaction();
|
|
try {
|
|
|
|
$registrations = $event->getEventRegistrations()->all();
|
|
// ////////////////////////////////
|
|
// if event has no registrations
|
|
// we can simply delete it from db
|
|
// ////////////////////////////////
|
|
if (count($registrations) === 0) {
|
|
$event->delete();
|
|
} else {
|
|
// /////////////////////////////
|
|
// otherwise we mark the event deleted
|
|
// and we have to delete the registrations
|
|
// /////////////////////////////
|
|
$event->deleted_at = date('Y-m-d H:i:s');
|
|
$event->save(false);
|
|
foreach ($registrations as $registration) {
|
|
if (!isset($registration->deleted_at)) {
|
|
/** @var EventRegistration $registration */
|
|
$this->deleteRegistration($registration);
|
|
}
|
|
}
|
|
}
|
|
$tx->commit();
|
|
} catch (Exception $e) {
|
|
$tx->rollBack();
|
|
throw $e;
|
|
}
|
|
|
|
}
|
|
|
|
}
|