bug fixing

This commit is contained in:
Roland Schneider
2021-10-06 18:31:56 +02:00
parent ad2be423d9
commit d26581e338
28 changed files with 527 additions and 83 deletions

View File

@@ -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 {
// /////////////////////////////

View File

@@ -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){

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -0,0 +1,45 @@
<?php
namespace common\models;
use Yii;
/**
* This is the model class for table "user_trainer_assignment".
*
* @property integer $id_user_trainer_assignment
* @property integer $id_user
* @property integer $id_trainer
*/
class UserTrainerAssignment extends \yii\db\ActiveRecord
{
/**
* @inheritdoc
*/
public static function tableName()
{
return 'user_trainer_assignment';
}
/**
* @inheritdoc
*/
public function rules()
{
return [
[['id_user', 'id_trainer'], 'integer']
];
}
/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id_user_trainer_assignment' => 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'),
];
}
}

View File

@@ -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.');
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace common\modules\event\modelAndView;
use common\models\Trainer;
/**
* @property \common\models\Event $event
* @property Trainer[] $trainers
*/
class CreateEventModelAndView
{
public $event;
public $trainers;
}

View File

@@ -0,0 +1,49 @@
<?php
namespace common\modules\event\models;
use common\components\RoleDefinition;
use common\models\Event;
use common\models\Trainer;
class EventCreate extends Event
{
public function rules()
{
$basicRules = parent::rules();
$basicRules[] = [
['id_trainer'] ,'validateTrainers'
];
return $basicRules;
}
public function validateTrainers($attribute, $params){
$query = Trainer::find();
if (RoleDefinition::isAdmin() == false) {
$query = $query->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ő");
}
}
}

View File

@@ -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,

View File

@@ -1,11 +1,15 @@
<?php
use common\modules\event\modelAndView\CreateEventModelAndView;
use yii\helpers\Html;
use yii\widgets\ActiveForm;
/* @var $this yii\web\View */
/* @var $model common\models\Event */
/* @var $form yii\widgets\ActiveForm */
/* @var $modelAndView CreateEventModelAndView */
$event = $modelAndView->event;
?>
<div class="event-form">
@@ -14,7 +18,7 @@ use yii\widgets\ActiveForm;
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'startDateString')->widget(\kartik\widgets\DateTimePicker::classname(), [
<?= $form->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;
]);
?>
<?= $form->field($model, 'endDateString')->widget(\kartik\widgets\DateTimePicker::classname(), [
<?= $form->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;
]
])
?>
<?= $form->field($model, 'seat_count')->textInput() ?>
<?= $form->field($event, 'seat_count')->textInput() ?>
<?= $form->field($model, 'id_room')->dropDownList(\common\models\Room::roomOptions(false, true)) ?>
<?= $form->field($event, 'id_room')->dropDownList(\common\models\Room::roomOptions(false, true)) ?>
<?= $form->field($model, 'id_trainer')->dropDownList(\common\models\Trainer::trainerOptions(false, true)) ?>
<?= $form->field($event, 'id_trainer')->dropDownList(\common\models\Trainer::trainerOptions(false, true, $modelAndView->trainers)) ?>
<?= $form->field($model, 'id_event_type')->dropDownList(\common\models\EventType::eventTypeOptions(false, true)) ?>
<?= $form->field($event, 'id_event_type')->dropDownList(\common\models\EventType::eventTypeOptions(false, true)) ?>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? Yii::t('event', 'Create') : Yii::t('event', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
<?= Html::submitButton($event->isNewRecord ? Yii::t('event', 'Create') : Yii::t('event', 'Update'), ['class' => $event->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>

View File

@@ -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;
<h1><?= Html::encode($this->title) ?></h1>
<?= $this->render('_form', [
'model' => $model,
'modelAndView' => $modelAndView,
]) ?>
</div>

View File

@@ -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 "<span style='margin-right: 3px; display: inline-block; width: 1rem; height: 1rem;' class='event-theme-active-". $model['event_type_theme']."'></span>".$model['event_type_name'] ;
}
,
'format' => 'raw'
],
[
'attribute' => 'event_start',

View File

@@ -1,13 +1,14 @@
<?php
use common\modules\event\modelAndView\CreateEventModelAndView;
use yii\helpers\Html;
/* @var $this yii\web\View */
/* @var $model common\models\Event */
/* @var $modelAndView CreateEventModelAndView */
$this->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');
?>
<div class="event-update">
@@ -15,7 +16,7 @@ $this->params['breadcrumbs'][] = Yii::t('event', 'Update');
<h1><?= Html::encode($this->title) ?></h1>
<?= $this->render('_form', [
'model' => $model,
'modelAndView' => $modelAndView
]) ?>
</div>

View File

@@ -17,7 +17,12 @@ if (!isset($event)) {
<div class="alert alert-success">
<?= Html::a( $start->format('H:i') .'-' . $end->format('H:i') , Url::toRoute(['event/update', 'id' => $event->id ] ) ) ?>
<br>
<?= Html::a( $event->eventType->name , Url::toRoute(['/event-type/view', 'id'=> $event->eventType->id])) ?>
<?= Html::a( $event->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;'
]) ?>
<br>
<?= Html::a( $event->room->name , Url::toRoute(['/room/view', 'id' => $event->room->id]) )?>
<br>