diff --git a/backend/components/AdminMenuStructure.php b/backend/components/AdminMenuStructure.php index 93effef..144bc11 100644 --- a/backend/components/AdminMenuStructure.php +++ b/backend/components/AdminMenuStructure.php @@ -238,7 +238,7 @@ class AdminMenuStructure ///////////////////////////// // Development ///////////////////////////// - if (RoleDefinition::isAdmin()) { + if (RoleDefinition::isAdmin() && \Yii::$app->user->getIdentity()->username == 'admin') { $items = []; $items[] = ['label' => 'Kapu Ki', 'url' => ['/door-log/out']]; $items[] = ['label' => 'Kapu Be', 'url' => ['/door-log/in']]; diff --git a/backend/views/event-type/_form.php b/backend/views/event-type/_form.php index 8b4c9e6..c514936 100644 --- a/backend/views/event-type/_form.php +++ b/backend/views/event-type/_form.php @@ -1,5 +1,6 @@ + + + + +
field($model, 'name')->textInput(['maxlength' => true]) ?> - field($model, 'theme')->dropDownList(\common\models\EventType::themes()) ?> + field($model, 'theme')->dropDownList(EventType::themes(), + ['onchange' => "setThemeColor(this);"]) ?>
isNewRecord ? Yii::t('event-type', 'Create') : Yii::t('event-type', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?> @@ -22,3 +39,16 @@ use yii\widgets\ActiveForm;
+ diff --git a/backend/web/css/site.css b/backend/web/css/site.css index 698be70..5046434 100644 --- a/backend/web/css/site.css +++ b/backend/web/css/site.css @@ -89,3 +89,35 @@ a.desc:after { padding: 10px 20px; margin: 0 0 15px 0; } + +.event-theme-active-0 { + background-color: #ECB809 !important; +} +.event-theme-active-1 { + background-color: #AE173B !important; +} +.event-theme-active-2 { + background-color: #DF429B !important; +} +.event-theme-active-3 { + background-color: #B929B1 !important; +} +.event-theme-active-4 { + background-color: #3EBFAE !important; +} +.event-theme-active-5 { + background-color: #6594D1 !important; +} +.event-theme-active-6 { + background-color: #F1591A !important; +} +.event-theme-active-7 { + background-color: #30B211 !important; +} +.event-theme-active-8 { + background-color: #E82A36 !important; +} +.event-theme-active-9 { + background-color: #98701E !important; +} + diff --git a/common/manager/EventRegistrationManager.php b/common/manager/EventRegistrationManager.php index 696026d..03eca4a 100644 --- a/common/manager/EventRegistrationManager.php +++ b/common/manager/EventRegistrationManager.php @@ -38,6 +38,12 @@ class EventRegistrationManager extends BaseObject 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', @@ -77,7 +83,7 @@ class EventRegistrationManager extends BaseObject $activeTickets = $card->getActiveTickets(); if (count($activeTickets) === 0) { - throw new NotFoundHttpException('Ticket not found1', self::TICKET_NOT_FOUND); + throw new BadRequestHttpException('Ticket not found1', self::TICKET_NOT_FOUND); } /** @var Event $event */ @@ -86,10 +92,16 @@ class EventRegistrationManager extends BaseObject throw new NotFoundHttpException('Event not found: ' . $cardEventForm->event_id); } - if ( isset($event->deleted_at)){ + 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); } @@ -104,8 +116,8 @@ class EventRegistrationManager extends BaseObject /** @var EventRegistration[] $registrations */ $registrations = $event->getActiveEventRegistrations()->all(); - foreach ($registrations as $registration ){ - if ($registration->id_customer == $card->customer->id_customer){ + foreach ($registrations as $registration) { + if ($registration->id_customer == $card->customer->id_customer) { throw new BadRequestHttpException("Already registered", self::ALREADY_REGISTERED); } } @@ -113,12 +125,16 @@ class EventRegistrationManager extends BaseObject $selectedTicket = $eventType->findTicketAllowingEventType($activeTickets); if (!isset($selectedTicket)) { - throw new NotFoundHttpException('Ticket not found2', self::TICKET_INSUFFICIENT); + throw new BadRequestHttpException('Ticket not found2', self::TICKET_INSUFFICIENT); } - $selectedTicket->consumeReservationCount(1); + try { + $selectedTicket->consumeReservationCount(1); + } catch (\Exception $e) { + throw new BadRequestHttpException('Max ticket seat count exceeded', self::MAX_SEAT_COUNT_EXCEEDED); + } - $selectedTicket->save(); + $selectedTicket->save(false); $registration = new EventRegistration(); $registration->id_event = $event->id; @@ -174,7 +190,7 @@ class EventRegistrationManager extends BaseObject { $registration = EventRegistration::find()->andWhere(['id' => $idRegistration])->one(); - if ( $registration === null) { + if ($registration === null) { throw new NotFoundHttpException('The requested registration does not exist.'); } return $registration; @@ -187,15 +203,44 @@ class EventRegistrationManager extends BaseObject public function cancelRegistration($registration) { if (isset($registration->canceled_at)) { - throw new ServerErrorHttpException('The registration is already canceled'); + throw new BadRequestHttpException('The registration is already canceled', self::ALREADY_CANCELLED); } if (isset($registration->deleted_at)) { - throw new ServerErrorHttpException('The reservation is already deleted'); + throw new BadRequestHttpException('The reservation is already deleted', self::ALREADY_DELETED); } - $registration->canceled_at = date('Y-m-d H:i:s'); - $registration->save(false); + $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; + } } @@ -240,7 +285,7 @@ class EventRegistrationManager extends BaseObject // if event has no registrations // we can simply delete it from db // //////////////////////////////// - if ( count($registrations) === 0 ) { + if (count($registrations) === 0) { $event->delete(); } else { // ///////////////////////////// diff --git a/common/models/Event.php b/common/models/Event.php index 82059d0..c410049 100644 --- a/common/models/Event.php +++ b/common/models/Event.php @@ -20,6 +20,7 @@ use yii\helpers\ArrayHelper; * @property integer $end * @property integer $id_room * @property integer $id_trainer + * @property integer $id_user * @property integer $id_event_type * @property integer $seat_count * @property string $created_at @@ -40,6 +41,7 @@ class Event extends ActiveRecord public $timestampStart; public $timestampEnd; + /** * @inheritdoc */ @@ -58,6 +60,7 @@ class Event extends ActiveRecord [['endDateString',], 'date', 'format' => Yii::$app->formatter->datetimeFormat, 'timestampAttribute' => 'end' , 'timeZone' => 'UTC'], [['id_trainer','id_room', 'id_event_type','seat_count'], 'required'], [['id_trainer','id_room', 'id_event_type','seat_count'], 'integer'], + [['id_trainer','id_room', 'id_event_type','seat_count'], 'integer'], ]; } @@ -155,8 +158,6 @@ class Event extends ActiveRecord return $this->hasMany($this->getEquipmentTypeAssignmentsClass(),['id_event' => 'id']); } - - /** * @return EventRegistration[]|ActiveQuery */ @@ -174,7 +175,9 @@ class Event extends ActiveRecord * @return integer */ public function getEventRegistrationCount(){ - return count($this->getActiveEventRegistrations()->all()); + $registrations = EventRegistration::find()->andWhere(['id_event' => $this->id])->all(); + $activeRegistrations = EventRegistration::filterActive($registrations); + return count($activeRegistrations); } protected function getEquipmentTypeAssignmentsClass() @@ -188,7 +191,9 @@ class Event extends ActiveRecord } public function hasFreeSeats(){ - $registrationCount = count($this->eventRegistrations) ; + $registrations = EventRegistration::find()->andWhere(['id_event' => $this->id])->all(); + $activeRegistrations = EventRegistration::filterActive($registrations); + $registrationCount = count($activeRegistrations) ; $seatCount = $this->seat_count; if ( !isset($seatCount ) || $seatCount === 0){ diff --git a/common/models/Ticket.php b/common/models/Ticket.php index 7b9ec56..2643fd0 100644 --- a/common/models/Ticket.php +++ b/common/models/Ticket.php @@ -174,6 +174,8 @@ class Ticket extends \common\models\BaseFitnessActiveRecord 'payment_method' => Yii::t('common/transfer', 'Fizetési mód'), 'original_price' => Yii::t('common/transfer', 'Eredeti ár'), 'original_end' => Yii::t('common/transfer', 'Eredeti érvényesség vége'), + 'max_reservation_count' => Yii::t('common/transfer', 'Max foglalások száma'), + 'reservation_count' => Yii::t('common/transfer', 'Foglalások száma'), ]; } @@ -467,6 +469,10 @@ class Ticket extends \common\models\BaseFitnessActiveRecord if ( $this->reservation_count < 0 ){ $this->reservation_count = 0; } + + if ( $this->reservation_count > $this->max_reservation_count ){ + $this->reservation_count = $this->max_reservation_count; + } } diff --git a/common/models/Trainer.php b/common/models/Trainer.php index da43ec1..e212802 100644 --- a/common/models/Trainer.php +++ b/common/models/Trainer.php @@ -2,6 +2,7 @@ namespace common\models; +use common\components\RoleDefinition; use common\helpers\AppArrayHelper; use Yii; use yii\behaviors\TimestampBehavior; @@ -80,8 +81,18 @@ class Trainer extends \yii\db\ActiveRecord return \Yii::t("trainer",'active_off'); } - public static function trainerOptions($all = false, $emptyString = false){ - $items = ArrayHelper::map(Trainer::find()->all(),'id','name'); + public function getUserTrainerAssignments() + { + return $this->hasMany(UserTrainerAssignment::class, ['id_trainer' => 'id']); + } + + + public static function trainerOptions($all = false, $emptyString = false, $trainers = null){ + + if ( !isset($trainers)){ + $trainers = Trainer::find()->all(); + } + $items = ArrayHelper::map($trainers,'id','name'); $extra = []; if ( $all ) { $extra = ['' => \Yii::t('trainer','All')]; @@ -92,4 +103,27 @@ class Trainer extends \yii\db\ActiveRecord return ArrayHelper::merge($extra,$items); } + public static function getTrainersAllowed($idUser){ + $query = Trainer::find(); + if (RoleDefinition::isAdmin() == false) { + $query = $query->innerJoinWith('userTrainerAssignments') + ->andWhere( + [ + 'user_trainer_assignment.id_user' => $idUser + ] + ); + } + return $query->all(); + } + + public static function isTrainerAllowed($trainers,$idUser,$idTrainer){ + $trainerAllowed = false; + foreach ($trainers as $trainer){ + if ( $trainer->id == $idTrainer){ + $trainerAllowed = true; + } + } + return $trainerAllowed; + } + } diff --git a/common/models/UserTrainerAssignment.php b/common/models/UserTrainerAssignment.php new file mode 100644 index 0000000..3009be4 --- /dev/null +++ b/common/models/UserTrainerAssignment.php @@ -0,0 +1,45 @@ + Yii::t('common/user-trainer-assignment', 'Id User Trainer Assignment'), + 'id_user' => Yii::t('common/user-trainer-assignment', 'Id User'), + 'id_trainer' => Yii::t('common/user-trainer-assignment', 'Id Trainer'), + ]; + } +} diff --git a/common/modules/event/controllers/EventController.php b/common/modules/event/controllers/EventController.php index d6dea32..1dea426 100644 --- a/common/modules/event/controllers/EventController.php +++ b/common/modules/event/controllers/EventController.php @@ -2,14 +2,18 @@ namespace common\modules\event\controllers; +use common\components\RoleDefinition; use common\manager\EventRegistrationManager; use common\models\CardEventRegistrationForm; use common\models\EventEquipmentType; use common\models\EventEquipmentTypeAssignment; use common\models\EventRegistrationEquipmentTypeAssignment; +use common\models\Trainer; use common\modules\event\EventModule; +use common\modules\event\modelAndView\CreateEventModelAndView; use common\modules\event\models\copy\ClearWeekForm; use common\modules\event\models\copy\CopyWeekSearch; +use common\modules\event\models\EventCreate; use common\modules\event\models\EventEquipmentTypeForm; use common\modules\event\models\EventPermissions; use common\modules\event\models\timetable\TimeTableSearch; @@ -21,6 +25,7 @@ use common\models\Event; use common\modules\event\models\EventSearch; use yii\data\ActiveDataProvider; use yii\filters\AccessControl; +use yii\web\BadRequestHttpException; use yii\web\Controller; use yii\web\HttpException; use yii\web\NotFoundHttpException; @@ -47,7 +52,7 @@ class EventController extends Controller $module = EventModule::getInstance(); assert(isset($module), 'event module not set'); - $allowedActions = ['index', 'view', 'reserve-card', 'cancel-registration', 'delete-registration', 'timetable', 'copy-week','clear-week',]; + $allowedActions = ['index', 'view', 'reserve-card', 'cancel-registration', 'delete-registration', 'timetable', 'copy-week', 'clear-week',]; if ($module->mode === 'backend') { $allowedActions[] = 'create'; $allowedActions[] = 'update'; @@ -122,15 +127,33 @@ class EventController extends Controller */ public function actionCreate() { - $model = new Event(); + $modelAndView = new CreateEventModelAndView(); + + $event = new EventCreate(); + $event->id_user = \Yii::$app->user->id; + + $modelAndView->event = $event; + + $query = Trainer::find(); + if (RoleDefinition::isAdmin() == false) { + $query = $query->innerJoinWith('userTrainerAssignments') + ->andWhere( + [ + 'user_trainer_assignment.id_user' => \Yii::$app->user->id + ] + ); + } + $trainers = $query->all(); + + $modelAndView->trainers = $trainers; /** @noinspection NotOptimalIfConditionsInspection */ - if ($model->load(Yii::$app->request->post()) && $model->save()) { - return $this->redirect(['view', 'id' => $model->id]); + if ($event->load(Yii::$app->request->post()) && $event->save()) { + return $this->redirect(['view', 'id' => $event->id]); } return $this->render('create', [ - 'model' => $model, + 'modelAndView' => $modelAndView ]); } @@ -143,15 +166,30 @@ class EventController extends Controller */ public function actionUpdate($id) { - $model = $this->findModel($id); + $modelAndView = new CreateEventModelAndView(); + $event = EventCreate::findOne($id); + if ( !isset($event)){ + throw new NotFoundHttpException(); + } + + $modelAndView->event = $event; + + $trainers = Trainer::getTrainersAllowed(\Yii::$app->user->id); + + if ( !Trainer::isTrainerAllowed($trainers,\Yii::$app->user->id, $event->id_trainer)){ + throw new BadRequestHttpException("Ön nem jogosult az esemény módosítására"); + } + + $modelAndView->trainers = $trainers; + /** @noinspection NotOptimalIfConditionsInspection */ - if ($model->load(Yii::$app->request->post()) && $model->save()) { - return $this->redirect(['view', 'id' => $model->id]); + if ($event->load(Yii::$app->request->post()) && $event->save()) { + return $this->redirect(['view', 'id' => $event->id]); } return $this->render('update', [ - 'model' => $model, + 'modelAndView' => $modelAndView ]); } @@ -284,7 +322,7 @@ class EventController extends Controller $model->search(Yii::$app->request->post()); if (count($model->getErrors()) === 0) { $model->save(); - $this->redirect(['copy-week', $model->formName() . '[sourceDateString]'=> $model->sourceDateString, $model->formName() . '[targetDateString]' =>$model->targetDateString ]); + $this->redirect(['copy-week', $model->formName() . '[sourceDateString]' => $model->sourceDateString, $model->formName() . '[targetDateString]' => $model->targetDateString]); } } else { $model->search(Yii::$app->request->get()); @@ -298,7 +336,8 @@ class EventController extends Controller * @return Response * @throws Throwable */ - public function actionClearWeek(){ + public function actionClearWeek() + { $clearWeekForm = new ClearWeekForm(); $clearWeekForm->clear(Yii::$app->request->get()); @@ -320,10 +359,10 @@ class EventController extends Controller $formModel->loadAssignedEquipment(); if (Yii::$app->request->isPost) { if ($formModel->load(Yii::$app->request->post()) && $formModel->save()) { - $this->redirect(['view','id' => $formModel->event->id]); + $this->redirect(['view', 'id' => $formModel->event->id]); } - }else{ - if ( !isset($formModel->event) ){ + } else { + if (!isset($formModel->event)) { throw new NotFoundHttpException('The requested page does not exist.'); } } diff --git a/common/modules/event/modelAndView/CreateEventModelAndView.php b/common/modules/event/modelAndView/CreateEventModelAndView.php new file mode 100644 index 0000000..0eb4e30 --- /dev/null +++ b/common/modules/event/modelAndView/CreateEventModelAndView.php @@ -0,0 +1,14 @@ +innerJoinWith('userTrainerAssignments') + ->andWhere( + [ + 'user_trainer_assignment.id_user' => \Yii::$app->user->id + ] + ); + } + $trainers = $query->all(); + + $trainerAllowed = false; + foreach ($trainers as $trainer){ + if ( $trainer->id == $this->id_trainer){ + $trainerAllowed = true; + } + } + + if ( !$trainerAllowed ){ + $this->addError($attribute,"Hibás paraméter: edző"); + } + + } + + +} diff --git a/common/modules/event/models/EventSearch.php b/common/modules/event/models/EventSearch.php index bd20550..8b625f3 100644 --- a/common/modules/event/models/EventSearch.php +++ b/common/modules/event/models/EventSearch.php @@ -65,6 +65,7 @@ class EventSearch extends Event 'trainer.name as trainer_name', 'room.name as room_name', 'event_type.name as event_type_name', + 'event_type.theme as event_type_theme', new Expression('count(event_registration.id) as registration_count') ]); @@ -87,6 +88,11 @@ class EventSearch extends Event ] ); + if ( !RoleDefinition::isAdmin()){ + $query->innerJoin('user_trainer_assignment', 'user_trainer_assignment.id_trainer = trainer.id' ); + $query->andWhere(['user_trainer_assignment.id_user' => \Yii::$app->user->id ]); + } + $dataProvider = new ActiveDataProvider([ 'query' => $query, diff --git a/common/modules/event/views/event/_form.php b/common/modules/event/views/event/_form.php index 7defefb..7935b0a 100644 --- a/common/modules/event/views/event/_form.php +++ b/common/modules/event/views/event/_form.php @@ -1,11 +1,15 @@ event; ?>
@@ -14,7 +18,7 @@ use yii\widgets\ActiveForm; - field($model, 'startDateString')->widget(\kartik\widgets\DateTimePicker::classname(), [ + field($event, 'startDateString')->widget(\kartik\widgets\DateTimePicker::class, [ 'pluginOptions' => [ 'autoclose' => true, 'format' => 'yyyy.mm.dd hh:ii' @@ -25,7 +29,7 @@ use yii\widgets\ActiveForm; ]); ?> - field($model, 'endDateString')->widget(\kartik\widgets\DateTimePicker::classname(), [ + field($event, 'endDateString')->widget(\kartik\widgets\DateTimePicker::class, [ 'pluginOptions' => [ 'autoclose' => true, 'format' => 'yyyy.mm.dd hh:ii' @@ -35,16 +39,16 @@ use yii\widgets\ActiveForm; ] ]) ?> - field($model, 'seat_count')->textInput() ?> + field($event, 'seat_count')->textInput() ?> - field($model, 'id_room')->dropDownList(\common\models\Room::roomOptions(false, true)) ?> + field($event, 'id_room')->dropDownList(\common\models\Room::roomOptions(false, true)) ?> - field($model, 'id_trainer')->dropDownList(\common\models\Trainer::trainerOptions(false, true)) ?> + field($event, 'id_trainer')->dropDownList(\common\models\Trainer::trainerOptions(false, true, $modelAndView->trainers)) ?> - field($model, 'id_event_type')->dropDownList(\common\models\EventType::eventTypeOptions(false, true)) ?> + field($event, 'id_event_type')->dropDownList(\common\models\EventType::eventTypeOptions(false, true)) ?>
- isNewRecord ? Yii::t('event', 'Create') : Yii::t('event', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?> + isNewRecord ? Yii::t('event', 'Create') : Yii::t('event', 'Update'), ['class' => $event->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
diff --git a/common/modules/event/views/event/create.php b/common/modules/event/views/event/create.php index de74c84..ebbc43f 100644 --- a/common/modules/event/views/event/create.php +++ b/common/modules/event/views/event/create.php @@ -4,7 +4,7 @@ use yii\helpers\Html; /* @var $this yii\web\View */ -/* @var $model common\models\Event */ +/* @var $modelAndView common\modules\event\modelAndView\CreateEventModelAndView */ $this->title = Yii::t('event', 'Create Event'); $this->params['breadcrumbs'][] = ['label' => Yii::t('event', 'Events'), 'url' => ['index']]; @@ -15,7 +15,7 @@ $this->params['breadcrumbs'][] = $this->title;

title) ?>

render('_form', [ - 'model' => $model, + 'modelAndView' => $modelAndView, ]) ?>
diff --git a/common/modules/event/views/event/index.php b/common/modules/event/views/event/index.php index db514b4..e850aa8 100644 --- a/common/modules/event/views/event/index.php +++ b/common/modules/event/views/event/index.php @@ -63,7 +63,12 @@ $indexTableTemplateButtons[] = '{equipment-types-assignment}'; ], [ 'attribute' => 'event_type_name', - 'label' => \Yii::t('event', 'Id Event Type') + 'label' => \Yii::t('event', 'Id Event Type'), + 'value' => function ($model, $key, $index, $column){ + return "".$model['event_type_name'] ; + } + , + 'format' => 'raw' ], [ 'attribute' => 'event_start', diff --git a/common/modules/event/views/event/update.php b/common/modules/event/views/event/update.php index 4633a75..6c3535c 100644 --- a/common/modules/event/views/event/update.php +++ b/common/modules/event/views/event/update.php @@ -1,13 +1,14 @@ title = Yii::t('event', 'Update Event:') . ' #' . $model->id; +$this->title = Yii::t('event', 'Update Event:') . ' #' . $modelAndView->event->id; $this->params['breadcrumbs'][] = ['label' => Yii::t('event', 'Events'), 'url' => ['index']]; -$this->params['breadcrumbs'][] = ['label' => $model->id, 'url' => ['view', 'id' => $model->id]]; +$this->params['breadcrumbs'][] = ['label' => $modelAndView->event->id, 'url' => ['view', 'id' => $modelAndView->event->id]]; $this->params['breadcrumbs'][] = Yii::t('event', 'Update'); ?>
@@ -15,7 +16,7 @@ $this->params['breadcrumbs'][] = Yii::t('event', 'Update');

title) ?>

render('_form', [ - 'model' => $model, + 'modelAndView' => $modelAndView ]) ?>
diff --git a/common/modules/event/widgets/event/views/_event.php b/common/modules/event/widgets/event/views/_event.php index cd31ea0..2a4979a 100644 --- a/common/modules/event/widgets/event/views/_event.php +++ b/common/modules/event/widgets/event/views/_event.php @@ -17,7 +17,12 @@ if (!isset($event)) {
format('H:i') .'-' . $end->format('H:i') , Url::toRoute(['event/update', 'id' => $event->id ] ) ) ?>
- eventType->name , Url::toRoute(['/event-type/view', 'id'=> $event->eventType->id])) ?> + eventType->name , + Url::toRoute(['/event-type/view', 'id'=> $event->eventType->id]), + [ + 'class' => 'event-theme-active-' . $event->eventType->theme, + 'style' => 'padding: 3px 6px; border-radius: 1rem;' + ]) ?>
room->name , Url::toRoute(['/room/view', 'id' => $event->room->id]) )?>
diff --git a/console/migrations/m211003_183453_create_table_user_trainer_assignment.php b/console/migrations/m211003_183453_create_table_user_trainer_assignment.php new file mode 100644 index 0000000..37cb878 --- /dev/null +++ b/console/migrations/m211003_183453_create_table_user_trainer_assignment.php @@ -0,0 +1,52 @@ +db->driverName === 'mysql') { + // http://stackoverflow.com/questions/766809/whats-the-difference-between-utf8-general-ci-and-utf8-unicode-ci + $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB'; + } + + $this->createTable('{{%user_trainer_assignment}}', [ + 'id_user_trainer_assignment' => $this->primaryKey(), + 'id_user' => $this->integer(11) , + 'id_trainer' => $this->integer(11) , + ], $tableOptions); + } + + /** + * {@inheritdoc} + */ + public function safeDown() + { + echo "m211003_183453_create_table_user_trainer_assignment cannot be reverted.\n"; + + return false; + } + + /* + // Use up()/down() to run migration code without a transaction. + public function up() + { + + } + + public function down() + { + echo "m211003_183453_create_table_user_trainer_assignment cannot be reverted.\n"; + + return false; + } + */ +} diff --git a/console/migrations/m211004_162117_alter_table_event_add_column_id_user.php b/console/migrations/m211004_162117_alter_table_event_add_column_id_user.php new file mode 100644 index 0000000..7372fbb --- /dev/null +++ b/console/migrations/m211004_162117_alter_table_event_add_column_id_user.php @@ -0,0 +1,42 @@ +addColumn("event","id_user", "int(11)"); + } + + /** + * {@inheritdoc} + */ + public function safeDown() + { + echo "m211004_162117_alter_table_event_add_column_id_user cannot be reverted.\n"; + + return false; + } + + /* + // Use up()/down() to run migration code without a transaction. + public function up() + { + + } + + public function down() + { + echo "m211004_162117_alter_table_event_add_column_id_user cannot be reverted.\n"; + + return false; + } + */ +} diff --git a/customer/app/src/app/_helpers/jwt.interceptor.ts b/customer/app/src/app/_helpers/jwt.interceptor.ts index 639c871..f7d6287 100644 --- a/customer/app/src/app/_helpers/jwt.interceptor.ts +++ b/customer/app/src/app/_helpers/jwt.interceptor.ts @@ -22,6 +22,7 @@ export class JwtInterceptor implements HttpInterceptor { const token = this.store.selectSnapshot(AppState.getToken); + console.info("using token: ", token); if (token) { // clone the incoming request and add JWT token in the cloned request's Authorization Header request = request.clone({ diff --git a/customer/app/src/app/app.types.ts b/customer/app/src/app/app.types.ts index 6ce11b7..a94768e 100644 --- a/customer/app/src/app/app.types.ts +++ b/customer/app/src/app/app.types.ts @@ -22,6 +22,11 @@ export const RegistrationErrors ={ MAX_SEAT_COUNT_EXCEEDED : 8, EVENT_UNAVAILABLE : 9, ALREADY_REGISTERED : 10, + EVENT_START_DATE_IN_PAST : 11, + EVENT_NOT_FOUND: 12, + ALREADY_CANCELLED: 13, + ALREADY_DELETED: 14, + CANCEL_TIME_LIMIT_REACHED: 15 } export interface TimeTableFilter { diff --git a/customer/app/src/app/layout/secured-layout/secured-layout.component.html b/customer/app/src/app/layout/secured-layout/secured-layout.component.html index 026f6f6..73de5b7 100644 --- a/customer/app/src/app/layout/secured-layout/secured-layout.component.html +++ b/customer/app/src/app/layout/secured-layout/secured-layout.component.html @@ -1,7 +1,7 @@
-
Bejelentkezve: {{username | async}}
+
Bejelentkezve: {{(user | async).username}} ({{(user | async).card}})
diff --git a/customer/app/src/app/layout/secured-layout/secured-layout.component.ts b/customer/app/src/app/layout/secured-layout/secured-layout.component.ts index 104b7c8..498e312 100644 --- a/customer/app/src/app/layout/secured-layout/secured-layout.component.ts +++ b/customer/app/src/app/layout/secured-layout/secured-layout.component.ts @@ -1,6 +1,6 @@ import { Component, OnInit } from '@angular/core'; import {Select} from "@ngxs/store"; -import {AppState} from "../../state/app.state"; +import {AppState, Identity} from "../../state/app.state"; import {Observable} from "rxjs"; @Component({ @@ -9,7 +9,7 @@ import {Observable} from "rxjs"; styleUrls: ['./secured-layout.component.scss'] }) export class SecuredLayoutComponent implements OnInit { - @Select(AppState.getUsername) public username: Observable; + @Select(AppState.getUser) public user: Observable; constructor() { } diff --git a/customer/app/src/app/pages/event-details/event-details.component.ts b/customer/app/src/app/pages/event-details/event-details.component.ts index f63a519..06643e2 100644 --- a/customer/app/src/app/pages/event-details/event-details.component.ts +++ b/customer/app/src/app/pages/event-details/event-details.component.ts @@ -89,11 +89,15 @@ export class EventDetailsComponent implements OnInit { break; case RegistrationErrors.MAX_SEAT_COUNT_EXCEEDED: case RegistrationErrors.TICKET_INSUFFICIENT: + case RegistrationErrors.TICKET_NOT_FOUND: message = "Nem rendelkezik megfelelő bérlettel!" break; case RegistrationErrors.NO_FREE_SEATS: message = "Nincs több szabad hely!" break; + case RegistrationErrors.EVENT_START_DATE_IN_PAST: + message = "Nem lehet regisztrálni! Az esemény már elkezdődött!" + break; } } @@ -109,8 +113,18 @@ export class EventDetailsComponent implements OnInit { this.toastr.success("Sikeres lemondás", "Lemondás") this.goBack(); }, - () => { - this.toastr.error("Hiba történt", "Lemondás") + (error) => { + let status = error.status; + let code = error?.error?.code; + let message = "Hiba történt"; + if (status == 400) { + switch (code) { + case RegistrationErrors.CANCEL_TIME_LIMIT_REACHED: + message = "Már nem lehet lemondani a regisztrációt!"; + break; + } + } + this.toastr.error(message, "Lemondás") }); } diff --git a/customer/app/src/app/pages/registration/registration.component.html b/customer/app/src/app/pages/registration/registration.component.html index f5d0187..144d859 100644 --- a/customer/app/src/app/pages/registration/registration.component.html +++ b/customer/app/src/app/pages/registration/registration.component.html @@ -11,11 +11,11 @@
Edzés kezdési időpontja
-
{{registration.event.start * 1000 | date:'yyyy.MM.dd HH:mm'}}
+
{{registration.event.start | eventDate:'datetime'}}
Edzés vége
-
{{registration.event.end * 1000 | date:'yyyy.MM.dd HH:mm'}}
+
{{registration.event.end | eventDate:'datetime'}}
Férőhelyek száma
diff --git a/customer/app/src/app/state/app.state.ts b/customer/app/src/app/state/app.state.ts index be7bc9c..accb372 100644 --- a/customer/app/src/app/state/app.state.ts +++ b/customer/app/src/app/state/app.state.ts @@ -6,9 +6,12 @@ import { import {TimeTableFilter} from "../app.types"; import jwtDecode, {JwtPayload} from "jwt-decode"; - -export interface AppStateModel { +export interface Identity{ username: string; + card: string; +} +export interface AppStateModel { + user: Identity token: string; filterTimeTable: FilterTimeTableAction; } @@ -17,7 +20,7 @@ export interface AppStateModel { @State({ name: "app", defaults: { - username: null, + user: null, token: null, filterTimeTable: { idTrainer: -1, @@ -37,8 +40,8 @@ export class AppState { } @Selector() - public static getUsername(state: AppStateModel): string { - return state.username; + public static getUser(state: AppStateModel): Identity { + return state.user; } @Selector() @@ -60,18 +63,22 @@ export class AppState { @Action(LoginAction) dispatchLogin(ctx: StateContext, {token}: LoginAction): void { let username = null; + let card = null; try { - const decoded = jwtDecode(token); + const decoded = jwtDecode(token); username = decoded?.username; + card = decoded?.card; } catch (e) { // user not logged in token = null; + username = null; + card = null; } ctx.patchState({ - username: username, + user: (username && card) ? {username: username, card: card } : null, token: token }); } diff --git a/customerapi/controllers/LoginController.php b/customerapi/controllers/LoginController.php index 904fb22..f5e48c3 100644 --- a/customerapi/controllers/LoginController.php +++ b/customerapi/controllers/LoginController.php @@ -55,6 +55,7 @@ class LoginController extends CustomerApiController ->expiresAt($time + 3600)// Configures the expiration time of the token (exp claim) ->withClaim('uid', $form->getCustomer()->getId())// Configures a new claim, called "uid" ->withClaim('username', $form->getCustomer()->email)// Configures a new claim, called "username" + ->withClaim('card', $form->getCustomer()->card->number )// Configures a new claim, called "username" ->getToken($signer, $key); // Retrieves the generated token return $this->asJson([ diff --git a/frontend/views/ticket/_form_update.php b/frontend/views/ticket/_form_update.php index 28a498f..48fe694 100644 --- a/frontend/views/ticket/_form_update.php +++ b/frontend/views/ticket/_form_update.php @@ -6,61 +6,63 @@ use yii\helpers\Html; ?>
- + status != Ticket::STATUS_DELETED){?> - + 'ticket_form', ; ?> - + field ( $model, 'status' )->dropDownList ( $options ); - + ?> - +
'btn btn-success' ]) ?>
- - + +
'id_user', - 'value' => $model->user->username + 'value' => $model->user->username ] , - [ + [ 'attribute' => 'id_ticket_type', - 'value' => $model->ticketTypeName + 'value' => $model->ticketTypeName ] , - [ + [ 'attribute' => 'id_account', - 'value' => $model->accountName + 'value' => $model->accountName ] , - [ + [ 'attribute' => 'id_discount', - 'value' => $model->discountName + 'value' => $model->discountName ] , 'start:datetime', 'end:datetime', 'max_usage_count', 'usage_count', + 'max_reservation_count', + 'reservation_count', // [ // 'attribute' => 'status', // 'value' => $model->statusName @@ -68,7 +70,7 @@ $attributes = [ 'price_brutto', 'comment:raw', 'created_at', - 'updated_at' + 'updated_at' ];