diff --git a/backend/controllers/EventController.php b/backend/controllers/EventController.php index 3945d69..7a73aa5 100644 --- a/backend/controllers/EventController.php +++ b/backend/controllers/EventController.php @@ -110,12 +110,12 @@ class EventController extends Controller * @param integer $id * @return mixed * @throws NotFoundHttpException - * @throws \yii\db\StaleObjectException + * @throws \yii\db\Exception */ public function actionDelete($id) { - $this->findModel($id)->delete(); - + $manager = new EventRegistrationManager(); + $manager->deleteEvent($this->findModel($id)); return $this->redirect(['index']); } @@ -141,12 +141,35 @@ class EventController extends Controller throw $ex; } } + + /** + * @param $id + * @return \yii\web\Response + * @throws \yii\db\Exception + */ + public function actionDeleteRegistration($id) + { + $eventRegistrationManager = new EventRegistrationManager(); + $db = \Yii::$app->db; + $tx = $db->beginTransaction(); + try{ + $registration = $eventRegistrationManager->loadRegistration($id); + $eventRegistrationManager->deleteRegistration($registration); + $tx->commit(); + return $this->redirect(['view', 'id' => $registration->id_event]); + }catch (\Exception $ex){ + $tx->rollBack(); + throw $ex; + } + } + /** * @param $id * @return string|\yii\web\Response * @throws NotFoundHttpException + * @throws \yii\db\Exception */ - public function actionRegisterCard($id) + public function actionReserveCard($id) { $event = $this->findModel($id); diff --git a/backend/models/EventSearch.php b/backend/models/EventSearch.php index 53bc67c..2f252a2 100644 --- a/backend/models/EventSearch.php +++ b/backend/models/EventSearch.php @@ -21,16 +21,15 @@ class EventSearch extends Event public $eventTypeName; - /** * @inheritdoc */ public function rules() { return [ - [['id','roomName', 'trainerName','eventTypeName'], 'string' , 'max' => 250], - [['startDateString',], 'date', 'format' => Yii::$app->formatter->datetimeFormat, 'timestampAttribute' => 'start', 'timeZone' => 'UTC'], - [['endDateString',], 'date', 'format' => Yii::$app->formatter->datetimeFormat, 'timestampAttribute' => 'end' , 'timeZone' => 'UTC'], + [['id', 'roomName', 'trainerName', 'eventTypeName'], 'string', 'max' => 250], + [['startDateString',], 'date', 'format' => Yii::$app->formatter->datetimeFormat, 'timestampAttribute' => 'start', 'timeZone' => 'UTC'], + [['endDateString',], 'date', 'format' => Yii::$app->formatter->datetimeFormat, 'timestampAttribute' => 'end', 'timeZone' => 'UTC'], ]; } @@ -60,6 +59,8 @@ class EventSearch extends Event 'event.end as event_end', 'event.created_at as event_created_at', 'event.updated_at as event_updated_at', + 'event.deleted_at as event_deleted_at', + 'event.seat_count as event_seat_count', 'trainer.name as trainer_name', 'room.name as room_name', 'event_type.name as event_type_name', @@ -70,7 +71,7 @@ class EventSearch extends Event $query->innerJoin('trainer', 'event.id_trainer = trainer.id'); $query->innerJoin('room', 'event.id_room = room.id'); $query->innerJoin('event_type', 'event_type.id = event.id_event_type'); - $query->leftJoin('event_registration', 'event_registration.id_event = event.id' ); + $query->leftJoin('event_registration', 'event_registration.id_event = event.id'); $query->groupBy( [ 'event_id', @@ -78,6 +79,7 @@ class EventSearch extends Event 'event_end', 'event_created_at', 'event_updated_at', + 'event_deleted_at', 'trainer_name', 'room_name', 'event_type_name', @@ -100,10 +102,12 @@ class EventSearch extends Event ['customer_name'], ['event_created_at'], ['event_updated_at'], + ['event_deleted_at'], ['registration_count'], - ]), - ] - ]) ; + ['event_seat_count'], + ]), + ] + ]); $this->load($params); @@ -117,32 +121,32 @@ class EventSearch extends Event 'event.id' => $this->id, ]); $query->andFilterWhere( - [ 'room.id' => $this->roomName] + ['room.id' => $this->roomName] ); $query->andFilterWhere( - [ 'trainer.id' => $this->trainerName] + ['trainer.id' => $this->trainerName] ); $query->andFilterWhere( - [ 'event_type.id' => $this->eventTypeName] + ['event_type.id' => $this->eventTypeName] ); - if ( isset($this->start)){ + if (isset($this->start)) { $query->andWhere( [ - '>=', - 'start' , - $this->start + '>=', + 'start', + $this->start ] ); } - if ( isset($this->end)){ + if (isset($this->end)) { $query->andWhere( [ '<=', - 'end' , + 'end', $this->end ] ); diff --git a/backend/views/event/_view.php b/backend/views/event/_view.php new file mode 100644 index 0000000..a3449b5 --- /dev/null +++ b/backend/views/event/_view.php @@ -0,0 +1,74 @@ + +
+
+

Esemény

+
+
+
+
+ $model, + 'attributes' => [ + 'id', + 'created_at:datetime', + 'updated_at:datetime', + 'deleted_at:datetime', + ], + ]); + } catch (Exception $e) { + echo "failed to render event details "; + } ?> +
+
+ $model, + 'attributes' => [ + [ + 'attribute' => 'eventType.name', + 'label' => $model->getAttributeLabel('id_event_type') + ], + 'start:datetime', + 'end:datetime', + [ + 'attribute' => 'room.name', + 'label' => $model->getAttributeLabel('id_room') + ], + [ + 'attribute' => 'trainer.name', + 'label' => $model->getAttributeLabel('id_trainer') + ], + ], + ]); + } catch (Exception $e) { + echo "Failed to render view"; + } ?> +
+
+ $model, + 'attributes' => [ + 'seat_count', + 'eventRegistrationCount', + 'openSeatCount', + ], + ]); + } catch (Exception $e) { + echo "Failed to render view"; + } ?> +
+
+
+ +
diff --git a/backend/views/event/index.php b/backend/views/event/index.php index da6a166..bf310d0 100644 --- a/backend/views/event/index.php +++ b/backend/views/event/index.php @@ -38,7 +38,11 @@ $this->params['breadcrumbs'][] = $this->title; [ 'attribute' => 'event_end', 'label' => \Yii::t('event', 'End'), - 'format' => 'datetime' + 'format' => 'time' + ], + [ + 'attribute' => 'event_seat_count', + 'label' => \Yii::t('event', 'Seat Count') ], [ 'attribute' => 'registration_count', @@ -62,9 +66,14 @@ $this->params['breadcrumbs'][] = $this->title; 'label' => \Yii::t('event', 'Updated At'), 'format' => 'datetime' ], + [ + 'attribute' => 'event_deleted_at', + 'label' => \Yii::t('event', 'Deleted At'), + 'format' => 'datetime' + ], [ 'class' => 'yii\grid\ActionColumn', - 'template' => '{view} {update} {delete} {register-card}', + 'template' => '{view} {update} {reserve-card}', 'urlCreator' => function ($action, $model, $key, $index) { $params = ['id' => $model['event_id']]; $params[0] = "event" . '/' . $action; @@ -97,7 +106,7 @@ $this->params['breadcrumbs'][] = $this->title; ]; return Html::a('', $url, $options); }, - 'register-card' => function ($url, $model, $key) { + 'reserve-card' => function ($url, $model, $key) { $options = [ 'title' => Yii::t('yii', 'Register'), 'aria-label' => Yii::t('yii', 'Register'), diff --git a/backend/views/event/register_card.php b/backend/views/event/register_card.php index 9394525..3f1e473 100644 --- a/backend/views/event/register_card.php +++ b/backend/views/event/register_card.php @@ -14,30 +14,7 @@ $this->params['breadcrumbs'][] = $this->title;

title) ?>

-

Esemény

- $event, - 'attributes' => [ - 'id', - 'start:datetime', - 'end:datetime', - [ - 'attribute' => 'room.name', - 'label' => $model->getAttributeLabel('id_room') - ], - [ - 'attribute' => 'trainer.name', - 'label' => $model->getAttributeLabel('id_trainer') - ], - [ - 'attribute' => 'eventType.name', - 'label' => $model->getAttributeLabel('id_event_type') - ], - 'seat_count', - ], - ]) ?> + render('_view', ['model' => $event]); ?> render('_form_register_card', [ 'model' => $model, diff --git a/backend/views/event/view.php b/backend/views/event/view.php index 694d399..a2b5e60 100644 --- a/backend/views/event/view.php +++ b/backend/views/event/view.php @@ -6,9 +6,27 @@ use yii\widgets\DetailView; /* @var $this yii\web\View */ /* @var $model common\models\Event */ -$this->title = $model->trainer->name . "/" . $model->eventType->name . "/" . $model->room->name; +$this->title = \Yii::t('event', 'Event Details'); $this->params['breadcrumbs'][] = ['label' => Yii::t('event', 'Events'), 'url' => ['index']]; $this->params['breadcrumbs'][] = $this->title; + +function isReservationOpen($model) +{ + $canceled = isset($model['event_registration_canceled_at']); + $deleted = isset($model['event_registration_deleted_at']); + return !$canceled && !$deleted; +} + + +function getCommonColumnsHtmlOptions($model) +{ + $options = []; + if (!isReservationOpen($model)) { + $options['style'] = 'text-decoration: line-through;'; + } + return $options; +} + ?>
@@ -16,154 +34,135 @@ $this->params['breadcrumbs'][] = $this->title;

$model->id], ['class' => 'btn btn-primary']) ?> - $model->id], ['class' => 'btn btn-primary']) ?> - $model->id], [ - 'class' => 'btn btn-danger pull-right', - 'data' => [ - 'confirm' => Yii::t('event', 'Are you sure you want to delete this item?'), - 'method' => 'post', - ], - ]) ?> + canReserve()){ + echo Html::a(Yii::t('event', 'Reservation'), ['reserve-card', 'id' => $model->id], ['class' => 'btn btn-primary']); + } + ?> + canDelete()) { + echo Html::a(Yii::t('event', 'Delete'), ['delete', 'id' => $model->id], [ + 'class' => 'btn btn-danger pull-right', + 'data' => [ + 'confirm' => Yii::t('event', 'Are you sure you want to delete this item?'), + 'method' => 'post', + ], + ]); + } + ?>

-
-
- $model, - 'attributes' => [ - 'id', - 'start:datetime', - 'end:datetime', - [ - 'attribute' => 'room.name', - 'label' => $model->getAttributeLabel('id_room') - ], - [ - 'attribute' => 'trainer.name', - 'label' => $model->getAttributeLabel('id_trainer') - ], - ], - ]); - } catch (Exception $e) { - echo "failed to render event details "; - } ?> + render('_view', ['model' => $model]); ?> + +
+
+

Foglalások

-
- $model, - 'attributes' => [ +
+ $dataProvider, + 'columns' => [ [ - 'attribute' => 'eventType.name', - 'label' => $model->getAttributeLabel('id_event_type') + 'attribute' => 'card_number', + 'label' => \Yii::t('event', 'Card Number'), + 'contentOptions' => function ($model) { + return getCommonColumnsHtmlOptions($model); + }, + 'format' => 'raw', + 'value' => function ($model, $key, $index, $column) { + return Html::a($model['card_number'], ['card/view', 'id' => $model['card_id_card']]); + } ], - 'seat_count', - 'created_at:datetime', - 'updated_at:datetime', - ], + [ + 'attribute' => 'customer_name', + 'label' => \Yii::t('event', 'Customer Name'), + 'contentOptions' => function ($model) { + return getCommonColumnsHtmlOptions($model); + }, + 'format' => 'raw', + 'value' => function ($model, $key, $index, $column) { + return Html::a($model['customer_name'], ['customer/view', 'id' => $model['customer_id_customer']]); + } + ], + [ + 'attribute' => 'customer_email', + 'label' => \Yii::t('event', 'Customer Email'), + 'contentOptions' => function ($model) { + return getCommonColumnsHtmlOptions($model); + } + ], + [ + 'attribute' => 'event_registration_created_at', + 'label' => \Yii::t('event', 'Event Registration Created At'), + 'contentOptions' => function ($model) { + return getCommonColumnsHtmlOptions($model); + } + ], + [ + 'attribute' => 'event_registration_canceled_at', + 'format' => 'datetime', + 'label' => \Yii::t('event', 'Canceled At'), + 'contentOptions' => function () { + $options = []; + return $options; + } + ], + [ + 'attribute' => 'event_registration_deleted_at', + 'format' => 'datetime', + 'label' => \Yii::t('event', 'Deleted At'), + 'contentOptions' => function () { + $options = []; + return $options; + }, + ], + [ + 'class' => 'yii\grid\ActionColumn', + 'template' => '{cancel-registration} {delete-registration}', + 'urlCreator' => function ($action, $model) { + $params = ['id' => $model['event_registration_id']]; + $params[0] = "event" . '/' . $action; + return \yii\helpers\Url::toRoute($params); + }, + 'buttons' => [ + 'cancel-registration' => function ($url, $model) { + if (isset($model['event_registration_canceled_at'])) { + return ""; + } + $options = [ + 'title' => Yii::t('event', 'Cancel'), + 'aria-label' => Yii::t('event', 'Cancel'), + 'data-confirm' => Yii::t('event', 'Are you sure you want to cancel this item? Usage count won\'t be restored!'), + 'data-method' => 'post', + 'data-pjax' => '0', + ]; + return Html::a('', $url, $options); + }, + 'delete-registration' => function ($url, $model) { + if (isset($model['event_registration_canceled_at'])) { + return ""; + } + $options = [ + 'title' => Yii::t('yii', 'Delete'), + 'aria-label' => Yii::t('yii', 'Delete'), + 'data-confirm' => Yii::t('event', 'Are you sure you want to delete this item? Usage count will be restored!'), + 'data-method' => 'post', + 'data-pjax' => '0', + ]; + return Html::a('', $url, $options); + }, + ] + + ], + ] ]); } catch (Exception $e) { - echo "Failed to render view"; - } ?> + echo "Failed to render registrations"; + } + ?>
-

Regisztrációk

- $dataProvider, - 'columns' => [ - [ - 'attribute' => 'card_number', - 'label' => \Yii::t('event', 'Card Number'), - 'contentOptions' => function ($model ) { - $options = []; - - if (isset($model['event_registration_canceled_at'])) { - $options['style'] = 'text-decoration: line-through;'; - } - - return $options; - } - ], - [ - 'attribute' => 'customer_name', - 'label' => \Yii::t('event', 'Customer Name'), - 'contentOptions' => function ($model ) { - $options = []; - - if (isset($model['event_registration_canceled_at'])) { - $options['style'] = 'text-decoration: line-through;'; - } - - return $options; - } - ], - [ - 'attribute' => 'customer_email', - 'label' => \Yii::t('event', 'Customer Email'), - 'contentOptions' => function ($model ) { - $options = []; - - if (isset($model['event_registration_canceled_at'])) { - $options['style'] = 'text-decoration: line-through;'; - } - - return $options; - } - ], - [ - 'attribute' => 'event_registration_created_at', - 'label' => \Yii::t('event', 'Event Registration Created At'), - 'contentOptions' => function ($model) { - $options = []; - - if (isset($model['event_registration_canceled_at'])) { - $options['style'] = 'text-decoration: line-through;'; - } - - return $options; - } - ], - [ - 'attribute' => 'event_registration_canceled_at', - 'label' => \Yii::t('event', 'Canceled At'), - 'contentOptions' => function () { - $options = []; - return $options; - } - ], - [ - 'class' => 'yii\grid\ActionColumn', - 'template' => '{cancel-registration}', - 'urlCreator' => function ($action, $model) { - $params = ['id' => $model['event_registration_id']]; - $params[0] = "event" . '/' . $action; - return \yii\helpers\Url::toRoute($params); - }, - 'buttons' => [ - 'cancel-registration' => function ($url, $model) { - if (isset($model['event_registration_canceled_at'])) { - return ""; - } - $options = [ - 'title' => Yii::t('yii', 'Delete'), - 'aria-label' => Yii::t('yii', 'Delete'), - 'data-confirm' => Yii::t('yii', 'Are you sure you want to delete this item?'), - 'data-method' => 'post', - 'data-pjax' => '0', - ]; - return Html::a('', $url, $options); - }, - ] - - ], - ] - ]); - } catch (Exception $e) { - echo "Failed to render registrations"; - } - ?>
diff --git a/common/manager/EventRegistrationManager.php b/common/manager/EventRegistrationManager.php index 7df85e2..c0b1564 100644 --- a/common/manager/EventRegistrationManager.php +++ b/common/manager/EventRegistrationManager.php @@ -1,5 +1,7 @@ "CARD_NOT_FOUND", + 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", @@ -37,87 +39,99 @@ class EventRegistrationManager extends \yii\base\Object self::TICKET_INSUFFICIENT => "TICKET_INSUFFICIENT", self::UNKNOWN_ERROR => "UNKNOWN_ERROR", self::MAX_SEAT_COUNT_EXCEEDED => "MAX_SEAT_COUNT_EXCEEDED", + self::EVENT_UNAVAILABLE => "EVENT_UNAVAILABLE", ]; /** * @param \common\models\CardEventRegistrationForm $cardEventForm - * @throws NotFoundHttpException - * @throws BadRequestHttpException - * @throws ServerErrorHttpException - * @throws \yii\web\HttpException + * @throws \yii\db\Exception */ - public function registerCard($cardEventForm){ + public function registerCard($cardEventForm) + { + $db = \Yii::$app->db; + $tx = $db->beginTransaction(); + try { + if ($cardEventForm->validate()) { - if ( $cardEventForm->validate() ){ + /** @var \common\models\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); + } - /** @var \common\models\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 (sizeof($activeTickets) == 0) { + throw new NotFoundHttpException("Ticket not found", self::TICKET_NOT_FOUND); + } + + /** @var \common\models\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); + } + + 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); + } + + $selectedTicket = $eventType->findTicketAllowingEventType($activeTickets); + + + if (!isset($selectedTicket)) { + throw new NotFoundHttpException("Ticket not found", self::TICKET_INSUFFICIENT); + } + + if ($selectedTicket->hasOpenReservationCount()) { + $selectedTicket->consumeReservationCount(1); + } + $selectedTicket->save(); + + $registration = new EventRegistration(); + $registration->id_event = $event->id; + $registration->id_card = $card->id_card; + $registration->id_ticket = $selectedTicket->id_ticket; + try { + $registration->save(false); + } catch (\Throwable $exception) { + throw new ServerErrorHttpException("Failed to save", self::UNKNOWN_ERROR); + } + + $cardEventForm->registration = $registration; } - - if ( $card->isFree() ){ - throw new NotFoundHttpException("Customer not found", self::CUSTOMER_NOT_FOUND); - } - - $activeTickets = $card->getActiveTickets(); - if ( sizeof($activeTickets) == 0 ){ - throw new NotFoundHttpException("Ticket not found", self::TICKET_NOT_FOUND); - } - - /** @var \common\models\Event $event */ - $event = Event::find()->andWhere(['id' => $cardEventForm->event_id])->one(); - if ( !isset($event)){ - throw new NotFoundHttpException("Event not found: " . $cardEventForm->event_id); - } - - 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); - } - - $selectedTicket = $eventType->findTicketAllowingEventType($activeTickets); - - - if ( !isset($selectedTicket) ){ - throw new NotFoundHttpException("Ticket not found", self::TICKET_INSUFFICIENT); - } - - if ( $selectedTicket->hasOpenReservationCount() ){ - $selectedTicket->consumeReservationCount(1); - } - $selectedTicket->save(); - - $registration = new EventRegistration(); - $registration->id_event = $event->id; - $registration->id_card = $card->id_card; - $registration->id_ticket = $selectedTicket->id_ticket; - try{ - $registration->save(false); - }catch (\Throwable $exception){ - throw new ServerErrorHttpException("Failed to save", self::UNKNOWN_ERROR); - } - - $cardEventForm->registration = $registration; + $tx->commit(); + } catch (\Exception $exception) { + $tx->rollBack(); } } - public function createFindRegistrationsQuery($idEvent){ + 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", - "card.number as card_number", + "customer.id_customer as customer_id_customer", "customer.name as customer_name", "customer.email as customer_email", ]); @@ -125,7 +139,7 @@ class EventRegistrationManager extends \yii\base\Object $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 ]); + $query->andWhere(["event_registration.id_event" => $idEvent]); return $query; } @@ -136,9 +150,10 @@ class EventRegistrationManager extends \yii\base\Object * @return array|EventRegistration|\yii\db\ActiveRecord|null * @throws NotFoundHttpException */ - public function loadRegistration($idRegistration) { + public function loadRegistration($idRegistration) + { - $registration = EventRegistration::find()->andWhere(['id' => $idRegistration ])->one(); + $registration = EventRegistration::find()->andWhere(['id' => $idRegistration])->one(); if ($registration == null) { throw new NotFoundHttpException('The requested registration does not exist.'); } @@ -149,21 +164,77 @@ class EventRegistrationManager extends \yii\base\Object * @param \common\models\EventRegistration $registration * @throws ServerErrorHttpException */ - public function cancelRegistration($registration){ - if ( isset($registration->canceled_at)){ + public function cancelRegistration($registration) + { + if (isset($registration->canceled_at)) { throw new ServerErrorHttpException('The registration is already canceled'); } - $ticket = Ticket::findOne(['id' => $registration->id_ticket ]); + if (isset($registration->deleted_at)) { + throw new ServerErrorHttpException('The reservation is already deleted'); + } - $ticket->restoreReservationCount(1); - $ticket->save(false); - - $registration->canceled_at = date('Y-m-d H:i:s' ); + $registration->canceled_at = date('Y-m-d H:i:s'); $registration->save(false); } + /** + * @param \common\models\EventRegistration $registration + * @throws ServerErrorHttpException + */ + public function deleteRegistration($registration) + { + if (isset($registration->deleted_at)) { + throw new ServerErrorHttpException('The reservation is already deleted'); + } + + $ticket = Ticket::findOne(['id_ticket' => $registration->id_ticket]); + + $ticket->restoreReservationCount(1); + $ticket->save(false); + + $registration->deleted_at = date('Y-m-d H:i:s'); + $registration->save(false); + + } + + /** + * Delete an event + * @param \common\models\Event $event + * @throws \yii\db\Exception + * @throws \Exception + */ + public function deleteEvent($event) + { + $db = \Yii::$app->db; + $tx = $db->beginTransaction(); + try { + + $registrations = $event->getEventRegistrations()->all(); + // //////////////////////////////// + // if even has no registrations + // we can simply delete it from db + // //////////////////////////////// + if (count($registrations) == 0) { + $event->delete(); + } else { + $event->deleted_at = date('Y-m-d H:i:s'); + $event->save(false); + foreach ($registrations as $registration) { + if (!isset($registration->deleted_at)) { + /** @var \common\models\EventRegistration $registration */ + $this->deleteRegistration($registration); + } + } + } + $tx->commit(); + } catch (\Exception $e) { + $tx->rollBack(); + throw $e; + } + + } } \ No newline at end of file diff --git a/common/messages/hu/event.php b/common/messages/hu/event.php index 11eb796..179aeda 100644 --- a/common/messages/hu/event.php +++ b/common/messages/hu/event.php @@ -39,5 +39,12 @@ return [ 'Canceled At' => 'Sztornó dátum, idő', 'Register' => 'Regisztráció', 'Event Registration Created At' => 'Regisztráció dátum, idő', - + 'Event Registration Count' => 'Foglalások száma', + 'Open Seat Count' => 'Szabad helyek száma', + 'Cancel' => 'Lemond', + 'Deleted At' => 'Törlés dátum, idő', + 'Are you sure you want to cancel this item? Usage count won\'t be restored!' => 'Biztos benne, hogy lemondja ezt az foglalást? A foglalás nem kerül vissza a bérletre!', + 'Are you sure you want to delete this item? Usage count will be restored!' => 'Biztos benne, hogy törli ezt az foglalást? A foglalás vissza fog kerülni a bérletre!', + 'Reservation' => 'Foglalás', + 'Event Details' => "Esemény részletei" ]; \ No newline at end of file diff --git a/common/models/Event.php b/common/models/Event.php index 9cb3533..65e6e11 100644 --- a/common/models/Event.php +++ b/common/models/Event.php @@ -18,6 +18,7 @@ use yii\helpers\ArrayHelper; * @property integer $seat_count * @property string $created_at * @property string $updated_at + * @property string $deleted_at * @property \common\models\EventType $eventType * @property \common\models\Trainer $trainer * @property \common\models\Room $room @@ -67,6 +68,7 @@ class Event extends \yii\db\ActiveRecord 'id_event_type' => Yii::t('event', 'Id Event Type'), 'created_at' => Yii::t('event', 'Created At'), 'updated_at' => Yii::t('event', 'Updated At'), + 'deleted_at' => Yii::t('event', 'Deleted At'), 'trainerName' => Yii::t('event', 'Trainer Name'), 'roomName' => Yii::t('event', 'Room Name'), 'eventTypeName' => Yii::t('event', 'Típus'), @@ -77,6 +79,8 @@ class Event extends \yii\db\ActiveRecord 'endDateString' => Yii::t('event', 'End'), 'status' => Yii::t('event', 'Status'), 'seat_count' => Yii::t('event', 'Seat Count'), + 'eventRegistrationCount' => Yii::t('event', 'Event Registration Count'), + 'openSeatCount' => Yii::t('event', 'Open Seat Count'), ]; } @@ -132,7 +136,16 @@ class Event extends \yii\db\ActiveRecord * @return \common\models\EventRegistration[]|\yii\db\ActiveQuery */ public function getEventRegistrationCount(){ - return sizeof($this->eventRegistrations); + return sizeof($this->getEventRegistrations() + ->andWhere( [ + 'canceled_at' => null, + 'deleted_at' => null, + ]) + ->all()); + } + + public function getOpenSeatCount(){ + return $this->seat_count - $this->getEventRegistrationCount(); } public function hasFreeSeats(){ @@ -146,4 +159,21 @@ class Event extends \yii\db\ActiveRecord return $registrationCount < $seatCount ; } + public function canReserve(){ + if ( isset($this->deleted_at)){ + return false; + } + if ( !$this->hasFreeSeats()){ + return false; + } + return true; + } + + public function canDelete(){ + if ( isset($this->deleted_at)){ + return false; + } + return true; + } + } diff --git a/common/models/EventRegistration.php b/common/models/EventRegistration.php index 4c8ed2a..2b23453 100644 --- a/common/models/EventRegistration.php +++ b/common/models/EventRegistration.php @@ -17,6 +17,7 @@ use yii\helpers\ArrayHelper; * @property string $created_at * @property string $updated_at * @property string $canceled_at + * @property string $deleted_at */ class EventRegistration extends \yii\db\ActiveRecord { @@ -50,6 +51,7 @@ class EventRegistration extends \yii\db\ActiveRecord 'created_at' => Yii::t('event-registration', 'Created At'), 'updated_at' => Yii::t('event-registration', 'Updated At'), 'canceled_at' => Yii::t('event-registration', 'Canceled At'), + 'deleted_at' => Yii::t('event-registration', 'Deleted At'), ]; } diff --git a/console/migrations/m190109_055105_alter_table_event_registration_add_column_deleted_at.php b/console/migrations/m190109_055105_alter_table_event_registration_add_column_deleted_at.php new file mode 100644 index 0000000..8a4f969 --- /dev/null +++ b/console/migrations/m190109_055105_alter_table_event_registration_add_column_deleted_at.php @@ -0,0 +1,29 @@ +addColumn("event_registration","deleted_at",$this->dateTime() ); + } + + public function down() + { + echo "m190109_055105_alter_table_event_registration_add_column_deleted_at cannot be reverted.\n"; + + return false; + } + + /* + // Use safeUp/safeDown to run migration code within a transaction + public function safeUp() + { + } + + public function safeDown() + { + } + */ +} diff --git a/console/migrations/m190109_055110_alter_table_event_add_column_deleted_at.php b/console/migrations/m190109_055110_alter_table_event_add_column_deleted_at.php new file mode 100644 index 0000000..91a0399 --- /dev/null +++ b/console/migrations/m190109_055110_alter_table_event_add_column_deleted_at.php @@ -0,0 +1,30 @@ +addColumn("event","deleted_at",$this->dateTime() ); + $this->addColumn("event","active",$this->integer()->defaultValue(1) ); + } + + public function down() + { + echo "m190109_055105_alter_table_event_registration_add_column_deleted_at cannot be reverted.\n"; + + return false; + } + + /* + // Use safeUp/safeDown to run migration code within a transaction + public function safeUp() + { + } + + public function safeDown() + { + } + */ +} diff --git a/frontend/controllers/InventoryItemController.php b/frontend/controllers/InventoryItemController.php index 86287ad..ea80565 100644 --- a/frontend/controllers/InventoryItemController.php +++ b/frontend/controllers/InventoryItemController.php @@ -32,7 +32,12 @@ class InventoryItemController extends Controller /** * Lists all InventoryItem models. + * @param $id * @return mixed + * @throws NotFoundHttpException + * @throws \PHPExcel_Exception + * @throws \PHPExcel_Reader_Exception + * @throws \PHPExcel_Writer_Exception */ public function actionIndex($id) { @@ -62,7 +67,13 @@ class InventoryItemController extends Controller ]); } - + + /** + * @param $dataProvider + * @throws \PHPExcel_Exception + * @throws \PHPExcel_Reader_Exception + * @throws \PHPExcel_Writer_Exception + */ protected function downloadIndexXls($dataProvider){ @@ -132,11 +143,12 @@ class InventoryItemController extends Controller $objWriter->save ( 'php://output' ); exit (); } - + /** * Displays a single InventoryItem model. * @param integer $id * @return mixed + * @throws NotFoundHttpException */ public function actionView($id) { @@ -149,6 +161,7 @@ class InventoryItemController extends Controller * Creates a new InventoryItem model. * If creation is successful, the browser will be redirected to the 'view' page. * @return mixed + * @throws \Exception */ public function actionCreate($id) { @@ -172,6 +185,7 @@ class InventoryItemController extends Controller * If update is successful, the browser will be redirected to the 'view' page. * @param integer $id * @return mixed + * @throws NotFoundHttpException */ public function actionUpdate($id) { @@ -200,6 +214,8 @@ class InventoryItemController extends Controller * If deletion is successful, the browser will be redirected to the 'index' page. * @param integer $id * @return mixed + * @throws NotFoundHttpException + * @throws \yii\db\StaleObjectException */ public function actionDelete($id) { diff --git a/frontend/models/EventSearch.php b/frontend/models/EventSearch.php new file mode 100644 index 0000000..484a864 --- /dev/null +++ b/frontend/models/EventSearch.php @@ -0,0 +1,157 @@ + 250], + [['startDateString',], 'date', 'format' => Yii::$app->formatter->datetimeFormat, 'timestampAttribute' => 'start', 'timeZone' => 'UTC'], + [['endDateString',], 'date', 'format' => Yii::$app->formatter->datetimeFormat, 'timestampAttribute' => 'end', 'timeZone' => 'UTC'], + ]; + } + + /** + * @inheritdoc + */ + public function scenarios() + { + // bypass scenarios() implementation in the parent class + return Model::scenarios(); + } + + /** + * Creates data provider instance with search query applied + * + * @param array $params + * + * @return ActiveDataProvider + */ + public function search($params) + { + $query = new Query(); + + $query->select([ + 'event.id as event_id', + 'event.start as event_start', + 'event.end as event_end', + 'event.created_at as event_created_at', + 'event.updated_at as event_updated_at', + 'event.deleted_at as event_deleted_at', + 'event.seat_count as event_seat_count', + 'trainer.name as trainer_name', + 'room.name as room_name', + 'event_type.name as event_type_name', + new Expression('count(event_registration.id) as registration_count') + ]); + + $query->from("event"); + $query->innerJoin('trainer', 'event.id_trainer = trainer.id'); + $query->innerJoin('room', 'event.id_room = room.id'); + $query->innerJoin('event_type', 'event_type.id = event.id_event_type'); + $query->leftJoin('event_registration', 'event_registration.id_event = event.id'); + $query->groupBy( + [ + 'event_id', + 'event_start', + 'event_end', + 'event_created_at', + 'event_updated_at', + 'event_deleted_at', + 'trainer_name', + 'room_name', + 'event_type_name', + ] + ); + + $dataProvider = new ActiveDataProvider([ + 'query' => $query, + 'sort' => [ + 'defaultOrder' => [ + 'event_start' => SORT_DESC + ], + 'attributes' => Helper::mkYiiSortItems([ + ['event_id'], + ['event_start'], + ['event_end'], + ['trainer_name'], + ['room_name'], + ['event_type_name'], + ['customer_name'], + ['event_created_at'], + ['event_updated_at'], + ['event_deleted_at'], + ['registration_count'], + ['event_seat_count'], + ]), + ] + ]); + + $this->load($params); + + if (!$this->validate()) { + // uncomment the following line if you do not want to return any records when validation fails + // $query->where('0=1'); + return $dataProvider; + } + + $query->andFilterWhere([ + 'event.id' => $this->id, + ]); + $query->andFilterWhere( + ['room.id' => $this->roomName] + ); + + $query->andFilterWhere( + ['trainer.id' => $this->trainerName] + ); + + $query->andFilterWhere( + ['event_type.id' => $this->eventTypeName] + ); + + if (isset($this->start)) { + $query->andWhere( + [ + '>=', + 'start', + $this->start + ] + ); + } + + if (isset($this->end)) { + $query->andWhere( + [ + '<=', + 'end', + $this->end + ] + ); + } + + return $dataProvider; + } +} diff --git a/rest/controllers/CustomerController.php b/rest/controllers/CustomerController.php index fcd21a8..2bb1ed7 100644 --- a/rest/controllers/CustomerController.php +++ b/rest/controllers/CustomerController.php @@ -26,28 +26,22 @@ class CustomerController extends RestController */ public function actionDiscountStatus($number, $lastXDays = null) { - $number = Helper::fixAsciiChars($number); - $query = Card::find(); $query->andWhere(['or', ['and', ['in', 'card.number', [$number]], "trim(coalesce(card.number, '')) <>'' "], ['and', ['in', 'card.rfid_key', [$number]], "trim(coalesce(card.rfid_key, '')) <>'' "], ]); - + /** @var \common\models\Card $card */ $card = $query->one(); - if (!isset($card)) { throw new NotFoundHttpException("Kártya nem található"); } - $customer = $card->customer; - if (!isset($customer)) { throw new NotFoundHttpException("Vendég nem található"); } - if (isset($lastXDays)) { if (!is_numeric($lastXDays)) { throw new BadRequestHttpException("lastXDays paraméter hibás"); @@ -56,12 +50,10 @@ class CustomerController extends RestController throw new BadRequestHttpException("lastXDays paraméter érték hibás"); } } - // check if has valid ticket today /** @var \common\models\Card $card */ $tickets = Ticket::readActive($card); $hasValidTicket = count($tickets) > 0; - if (isset($lastXDays)) { // try to find any valid ticket in the lastXDays $minusDay = 1; @@ -73,17 +65,14 @@ class CustomerController extends RestController $minusDay = $minusDay + 1; } } - $result = [ 'discount' => $hasValidTicket ]; - if (isset($customer)) { $result['card_number'] = $card->number; $result['name'] = $customer->name; $result['provider'] = \Yii::$app->id; } - return $result; }