diff --git a/common/components/DateUtil.php b/common/components/DateUtil.php index e8d9b05..c05a482 100644 --- a/common/components/DateUtil.php +++ b/common/components/DateUtil.php @@ -204,4 +204,8 @@ class DateUtil return $dateTime->add(new \DateInterval('PT' . $minutes . 'M')); } + public static function minusMinutes($dateTime, $minutes){ + return $dateTime->sub(new \DateInterval('PT' . $minutes . 'M')); + } + } diff --git a/common/manager/DoorCardPassDoorManager.php b/common/manager/DoorCardPassDoorManager.php new file mode 100644 index 0000000..4fa8264 --- /dev/null +++ b/common/manager/DoorCardPassDoorManager.php @@ -0,0 +1,729 @@ + $requestId, + 'identifier' => $identifier, + 'device' => $device, + 'direction' => $direction, + 'originalDirection' => $direction, + 'verifyOnly' => $verifyOnly + ]); + try { + $stopWatch = new StopWatch(); + + + \Yii::info("$requestId: move with next parameers:" . ";identifier" . $identifier . ";device" . $device . ";direction" . $direction . ";verifyOnly" . $verifyOnly . ";createdAt" . print_r($createdAt, true) . ";date" . print_r($date, true)); + \Yii::info("$requestId: move get request: " . print_r($_GET, true)); + \Yii::info("$requestId: move post request: " . print_r($_GET, true)); + + if (isset($createdAt)) { + $createdAt = DateUtil::parseDateTime($createdAt); + } else { + $createdAt = DateUtil::utcDateTime(); + } + + $context->createdAt = $createdAt; + + if (isset($date)) { + $date = DateUtil::parseDateTime($date); + } else { + $date = DateUtil::utcDate(); + } + + $context->date = $date; + + if ($device === 'E') { + $this->moveEmergency($context/*;$requestId,$identifier, $device, $direction, $verifyOnly, $createdAt, $date*/); + return; + } + + $cardNumber = $identifier; + + switch ($direction) { + case 'IN': + $direction = DoorLog::$DIRECTION_IN; + break; + case 'OUT': + $direction = DoorLog::$DIRECTION_OUT; + break; + default: + throw new FitnessException( + "Direction $direction not supported", + FitnessException::TYPE_BAD_REQUEST, + "INVALID_DIRECTION", + $context + ); + } + $context->direction = $direction; + + // if device is qr code + if ($device == 'Q') { + + // allow only virtual key + $virtualKey = VirtualKey::findOne(['number' => $identifier]); + + if (!isset($virtualKey)) { + throw new FitnessException( + "Virtual Key Not Found", + FitnessException::TYPE_BAD_REQUEST, + "VIRTUAL_KEY_NOT_FOUND", + $context + ); + } + $card = Card::findOne($virtualKey->id_card); + + if ($card == null) { + throw new FitnessException( + "Virtual Key Not Found", + FitnessException::TYPE_BAD_REQUEST, + "CARD_FOR_VIRTUAL_KEY_NOT_FOUND", + $context + ); + } + $cardNumber = $card->number; + \Yii::info("$requestId: virtual key and card loaded in sec " . $stopWatch->split()); + } else { + // load by rfid or card number + $card = Card::readCard(Helper::fixAsciiChars($identifier)); + \Yii::info("$requestId: Card loaded in sec " . $stopWatch->split()); + if (!isset($card)) { + throw new FitnessException( + "Virtual Key Not Found", + FitnessException::TYPE_BAD_REQUEST, + "CARD_NOT_FOUND", + $context + ); + } + \Yii::info("$requestId: card loaded in sec " . $stopWatch->split()); + $virtualKey = VirtualKey::findOne(['id_card' => $card->id_card]); + \Yii::info("$requestId: virtual key for card loaded in sec " . $stopWatch->split()); + } + + $context->virtualKey = $virtualKey; + $context->card = $card; + $context->cardNumber = $cardNumber; + + if ( $card->status != Card::STATUS_ACTIVE){ + throw new FitnessException( + "Card is not active", + FitnessException::TYPE_BAD_REQUEST, + "CARD_NOT_ACTIVE", + $context + ); + } + + \Yii::info("$requestId: Card number " . $card->number); + + if ($card->type == Card::TYPE_EMPLOYEE) { + $this->moveEmployee($context /*$identifier, $device, $direction, $verifyOnly, $createdAt, $date, $card, $cardNumber, $virtualKey*/); + return; + } + + $this->moveCustomer($context /* $requestId, $identifier, $device, $direction, $verifyOnly, $createdAt, $date, $card, $cardNumber, $virtualKey*/); + + } catch (FitnessException $e) { + $context->error = true; + $context->exception = $e->originalException; + $context->errorCode = $e->errorCode; + + if ($e->type == FitnessException::TYPE_BAD_REQUEST) { + throw new BadRequestHttpException($e->getMessage()); + } else { + throw new ServerErrorHttpException($e->getMessage()); + } + + } catch (\Exception $e) { + $context->error = true; + $context->exception = $e; + $context->errorCode = "UNKNOWN"; + throw $e; + } finally { + // do logging + $this->logContext($context); + } + + } + + /** + * @param $ctx DoorMoveContext + * @return void + */ + function logContext($ctx) + { + try { + $result = [ +//datetime $updated_at -- +//datetime $created_at -- +//string $ticket_usage + //string $request_id + 'request_id' => $ctx->requestId, + //string $identifier + 'identifier' => $ctx->identifier, + //bool $verify_only + 'verify_only' => $ctx->verifyOnly, + //string $device + 'device' => $ctx->device, + //string $direction + 'direction' => $ctx->direction, + //string $original_direction + 'original_direction' => $ctx->originalDirection, + //integer $card_id_card + 'card_id_card' => isset($ctx->card) ? $ctx->card->id_card : null, + //string $card_number + 'card_number' => isset($ctx->card) ? $ctx->card->number : null, + //string $ticket_id_ticket + 'ticket_id_ticket' => isset($ctx->ticket) ? $ctx->ticket->id_ticket : null, + //string $ticket_type_name + 'ticket_type_name' => isset($ctx->ticket) ? $ctx->ticket->ticketType->name : null, + //string $ticket_usage_count + 'ticket_usage_count' => isset($ctx->ticket) ? $ctx->ticket->usage_count : null, + //string $customer_id_customer + 'customer_id_customer' => isset($ctx->customer) ? $ctx->customer->id_customer : null, + //string $customer_name + 'customer_name' => isset($ctx->customer) ? $ctx->customer->name : null, + //string $customer_email + 'customer_email' => isset($ctx->customer) ? $ctx->customer->email : null, + //integer $key_id_key + 'key_id_key' => isset($ctx->key) ? $ctx->key->id_key : null, + //string $key_number + 'key_number' => isset($ctx->key) ? $ctx->key->number : null, + //integer $virtual_key_id + 'virtual_key_id' => isset($ctx->virtualKey) ? $ctx->virtualKey->id : null, + //string $validation_kind + 'validation_kind' => $ctx->kind, + //bool $error + 'error' => $ctx->error, + //string $error_code + 'error_code' => $ctx->errorCode, + 'ticket_usage' => $ctx->increasedTicketUsageCount, +// 'actions' => implode(",",$ctx->actions), + ]; + + if ($ctx->error === true) { + if (isset($ctx->exception)) { + // string $error_message + $result['error_message'] = substr($ctx->exception->getMessage(), 0, 100); + } + } + + \Yii::info("door log: " . implode(";", $result)); + + \Yii::$app->db->beginTransaction(); + $log = new DoorManagerLog($result); + $log->save(false); + \Yii::$app->db->transaction->commit(); + + + } catch (\Exception $e) { + \Yii::error("Failed to log door context:" . $e->getMessage()); + } + } + + function moveEmergency($ctx) + { + $ctx->kind = "EMERGENCY"; + \Yii::info("$ctx->requestId: emergency move"); + try { + $createdAtStr = DateUtil::formatDateTimeUtc($ctx->createdAt); + \Yii::$app->db->beginTransaction(); + + $doorLog = new DoorLog(); + $doorLog->version = 2; + $doorLog->direction = DoorLog::$DIRECTION_ALL_EMERGENCY; + $doorLog->source_app = $ctx->device; + $doorLog->created_at = $createdAtStr; + + $doorLog->save(false); + Log::log( + [ + 'type' => Log::$TYPE_INFO, + 'message' => 'Ajtó nyitás: vészhelyzet', + 'id_door_log' => $doorLog->id_door_log + ] + ); + + $ctx->actions[] = "EMERGENCY_MOVE"; + + \Yii::$app->db->transaction->commit(); + } catch (\Exception $e) { + \Yii::$app->db->transaction->rollBack(); + throw new FitnessException( + "unknowon error", + FitnessException::UNKNOWN_ERROR, + "EMERGENCY_OPEN_FAILED", + $ctx, + $e + ); + } + } + + function moveEmployee($ctx /*$identifier, $device, $direction, $verifyOnly, $createdAt, $date, $card, $cardNumber, $virtualKey*/) + { + $ctx->kind = "EMPLOYEE"; + /** + * if the card type is employee, neither customer nor ticket is needed. + * Free to enter/leave + */ + \Yii::info("employee move"); + try { + $createdAtStr = DateUtil::formatDateTimeUtc($ctx->createdAt); + \Yii::$app->db->beginTransaction(); + + $doorLog = new DoorLog(); + $doorLog->version = 2; + $doorLog->direction = $ctx->direction; + $doorLog->source_app = $ctx->device; + $doorLog->created_at = $createdAtStr; + $doorLog->id_card = $ctx->card->id_card; + $doorLog->card_flag = $ctx->card->flag; + + if (!$ctx->verifyOnly) { + + $doorLog->save(false); + Log::log( + [ + 'type' => Log::$TYPE_INFO, + 'message' => 'Ajtó nyitás: munkatárs', + 'id_door_log' => $doorLog->id_door_log + ] + ); + } + + $ctx->actions[] = "EMPLOYEE_" . $ctx->originalDirection; + + \Yii::$app->db->transaction->commit(); + } catch (\Exception $e) { + \Yii::$app->db->transaction->rollBack(); + throw new FitnessException( + "unknowon error", + FitnessException::UNKNOWN_ERROR, + "EMPLOYEE_FAILED", + $ctx, + $e + ); + } + + } + + /** + * @param $ctx + * + * @return void + * @throws BadRequestHttpException + * @throws ServerErrorHttpException + * @throws InvalidConfigException + * @throws Exception + */ + function moveCustomer($ctx/* $requestId, $identifier, $device, $direction, $verifyOnly, $createdAt, $date, $card, $cardNumber, $virtualKey*/) + { + $ctx->kind = "CUSTOMER"; + \Yii::info("$ctx->requestId: move customer"); + $stopWatch = new StopWatch(); + + try { + $createdAtStr = DateUtil::formatDateTimeUtc($ctx->createdAt); + \Yii::info("$ctx->requestId: crated at str: " . $createdAtStr); + \Yii::$app->db->beginTransaction(); + + $doorLog = new DoorLog(); + $doorLog->version = 2; + $doorLog->direction = $ctx->direction; + $doorLog->source_app = $ctx->device; + $doorLog->created_at = $createdAtStr; + $doorLog->id_card = $ctx->card->id_card; + $doorLog->card_flag = $ctx->card->flag; + + + $activeTickets = Ticket::readActive($ctx->card, clone $ctx->date); + \Yii::info("$ctx->requestId: active ticket count:" . count($activeTickets)); + /** @var Ticket $ticket */ + $ticket = null; + if (isset($activeTickets) && count($activeTickets) > 0) { + $ticket = $activeTickets[0]; + } + + // active ticket is required + if (!isset($ticket)) { + throw new FitnessException( + "$ctx->requestId: No active ticket found for:" . $ctx->card->number, + FitnessException::TYPE_BAD_REQUEST, + "NOT_FOUND_ACTIVE_TICKET", + $ctx + ); + } + $ctx->ticket = $ticket; + + \Yii::info("$ctx->requestId: ticket {$ticket->id_ticket} loaded in sec " . $stopWatch->split()); + + $doorLog->id_ticket_current = $ticket->id_ticket; + + // customer is required + $customer = $ctx->card->customer; + if (!isset($customer)) { + throw new FitnessException( + "$ctx->requestId: Customer not found for:" . $ctx->card->number, + FitnessException::TYPE_BAD_REQUEST, + "NOT_FOUND_CUSTOMER", + $ctx + ); + } + + $ctx->customer = $customer; + + $doorLog->id_customer = $customer->id_customer; + \Yii::info("$ctx->requestId: customer {$customer->id_customer} loaded in sec " . $stopWatch->split()); + + if (!$ctx->verifyOnly) { + // save the door log + $doorLog->save(false); + } + \Yii::info("$ctx->requestId: door log {$doorLog->id_door_log} saved in sec " . $stopWatch->split()); + + // if direction is in, check if usage count must be increased + if ($ctx->direction == DoorLog::$DIRECTION_IN) { + + /** + * Virtual key must exist + */ + if (!isset($ctx->virtualKey)) { + throw new FitnessException( + "$ctx->requestId: Customer not found for:" . $ctx->card->number, + FitnessException::TYPE_BAD_REQUEST, + "NOT_FOUND_CUSTOMER", + $ctx + ); + } + + // todo: virtual key created_at validation + + if (isset($ctx->virtualKey->direction_in_at)) { + throw new FitnessException( + "$ctx->requestId: Virtual key - already moved in: " . $ctx->identifier . '/' . $ctx->virtualKey->id_card, + FitnessException::TYPE_BAD_REQUEST, + "VIRTUAL_KEY_ALREADY_IN", + $ctx + ); + } + + + $ctx->actions[] = "VIRTUAL_KEY_MOVE_IN"; + + // detect if need to increase usage count for ticket + if (!$ctx->verifyOnly) { + + $ctx->virtualKey->direction_in_at = Helper::getDateTimeString(); + \Yii::info("$ctx->requestId: Setting virtual key direction_in_at"); + \Yii::info("$ctx->requestId: Updating virtual key"); + $ctx->virtualKey->save(false); + + $allDoorLogToday = DoorManagerLog::findAllEntryForTicketFromTime($ctx->ticket->id_ticket); + $countDoorLogsForTicketSince = count($allDoorLogToday); + + // if the current event is the first door log today + if ($countDoorLogsForTicketSince == 0) { + // increase the ticket usage count with 1 + $usageCount = $ticket->usage_count; + $ctx->increasedTicketUsageCount = true; + $ticket->usage_count += 1; + $ticket->save(false); + \Yii::info("$ctx->requestId: First ticket usage today, increasing usage count for card: " . $ctx->card->id_card); + Log::log( + [ + 'type' => Log::$TYPE_TICKET_USAGE_FIRST, + 'message' => 'Bérlet használat(előtte: ' . $usageCount . ' -> utána: ' . $ticket->usage_count, + 'id_ticket' => $ticket->id_ticket, + 'id_door_log' => $doorLog->id_door_log + ] + ); + \Yii::info("$ctx->requestId: Ticket usage count increased after first doorlog of day in sec " . $stopWatch->split()); + $ctx->actions[] = "TICKET_FIRST_USAGE_TODAY"; + + } else { + \Yii::info("$ctx->requestId: more then one door log today for card: " . $ctx->card->id_card); + // we have already a door log for today, other than this + // Now we split the day into 3hour intervalls, starting with the createdAt value of the first event. + // If the actual event happens in an interval, in which still now doorlog event happend, we increase + // the usage count with 1 + // 3 óránként 1-et levonunk + + + if (count($allDoorLogToday) == 0) { + throw new FitnessException( + "$ctx->requestId: Tried to inc ticket usage without prev entry: " . $ctx->identifier . '/' . $ctx->virtualKey->id_card, + FitnessException::TYPE_BAD_REQUEST, + "INVALID_TICKET_USAGE_INCREMENT", + $ctx + ); + } + + $firstInToday = $allDoorLogToday[0]; + \Yii::info("$ctx->requestId: first in today for card: " . $ctx->card->id_card . " was at " . $firstInToday->created_at); + $firstEntryDateTimeToday = DateUtil::parseDateTime($firstInToday->created_at); + $interval = \DateInterval::createFromDateString('3 hours'); + $startOfTomorrow = DateUtil::tomorrowStart(clone $ctx->date); + $daterange = new \DatePeriod($firstEntryDateTimeToday, $interval, $startOfTomorrow); + + $intervals = []; + $intervalStart = null; + foreach ($daterange as $intervalEnd) { + if (isset($intervalStart)) { + $intervals[] = $this->createTicketUsageInterval($intervalStart, $intervalEnd, $allDoorLogToday, $doorLog); + } + $intervalStart = clone $intervalEnd; + } + + if ($intervalStart < $startOfTomorrow) { + $intervals[] = $this->createTicketUsageInterval($intervalStart, $startOfTomorrow, $allDoorLogToday, $doorLog); + } + + $activeInterval = $this->getActiveInterval($intervals, $ctx->createdAt); + if (!isset($activeInterval)) { + throw new ServerErrorHttpException("$ctx->requestId: Active Interval not found"); + } + + $logCountInActiveInterval = count($activeInterval['logs']); + + if ($logCountInActiveInterval == 1) { + $ctx->increasedTicketUsageCount = true; + $ticket->usage_count = $ticket->usage_count + 1; + $ticket->save(false); + \Yii::info("$ctx->requestId: Ticket usage count increased after first IN after first door_log in interval in sec " . $stopWatch->split()); + $ctx->actions[] = "TICKET_INCREASE_USAGE"; + } + } + } + $ctx->actions[] = "MOVE_IN"; + } + + if ($ctx->direction == DoorLog::$DIRECTION_OUT || $ctx->direction == DoorLog::$DIRECTION_OUT_WITHOUT_MOVE) { + + // virtual key must exist + if (!isset($ctx->virtualKey)) { + throw new FitnessException( + "$ctx->requestId: Virtual key: move out without virtual key", + FitnessException::TYPE_BAD_REQUEST, + "MOVE_OUT_WITHOUT_VIRTUAL_KEY", + $ctx + ); + } + + // virtual must already be in + if (!isset($ctx->virtualKey->direction_in_at)) { + throw new FitnessException( + "$ctx->requestId: Virtual key: move out without move in", + FitnessException::TYPE_BAD_REQUEST, + "VIRTUAL_KEY_MOVE_OUT_WITHOUT_MOVE_IN", + $ctx + ); + } + + // virtual key must not be already out + if (isset($ctx->virtualKey->direction_out_at)) { + throw new FitnessException( + "$ctx->requestId: Virtual key: already move out", + FitnessException::TYPE_BAD_REQUEST, + "VIRTUAL_KEY_ALREADY_OUT", + $ctx + ); + } + + + if (!$ctx->verifyOnly) { + // set out date + $ctx->virtualKey->direction_out_at = Helper::getDateTimeString(); + $ctx->virtualKey->save(false); + } + + + if (!$ctx->verifyOnly) { + $ticket->count_move_out = $ticket->usage_count; + $ticket->save(false); + } + + $ctx->actions[] = "MOVE_OUT"; + \Yii::info("$ctx->requestId: direction_out: ticket count_move_out set after direction_out in sec " . $stopWatch->split()); + } + + $stopWatch->stop(); + \Yii::info("$ctx->requestId: finished in sec " . $stopWatch->getTotal()); + \Yii::$app->db->transaction->commit(); + \Yii::info("$ctx->requestId: Commited"); + } catch (FitnessException $fe) { + $this->doRollback(); + \Yii::info("$ctx->requestId: rollbacked"); + throw $fe; + } catch (\Exception $e) { + $this->doRollback(); + \Yii::info("$ctx->requestId: rollbacked"); + throw new FitnessException( + "UNKNOWN_ERROR", + FitnessException::UNKNOWN_ERROR, + "CUSTOMER_UNKNOWN_ERROR", + $ctx, + $e + + ); + } + } + + function doRollback() + { + if (isset(\Yii::$app->db->transaction) && \Yii::$app->db->transaction->isActive) { + \Yii::$app->db->transaction->rollBack(); + } + } + + function getActiveInterval($intervals, $date) + { + foreach ($intervals as $interval) { + $start = $interval['start']; + $end = $interval['end']; + if ($start <= $date && $date < $end) { + return $interval; + } + } + return null; + } + + function createTicketUsageInterval($start, $end, $allLogs, $actualDoorLog) + { + $result = ['start' => $start, 'end' => $end, 'logs' => []]; + foreach ($allLogs as $log) { + $createdAt = DateUtil::parseDateTime($log->created_at); + if ($createdAt >= $start && $createdAt < $end) { + $result['logs'][] = $log; + } + } + return $result; + } + + + public function readActive($cardNumber) + { + $card = Card::readCard($cardNumber); + return Ticket::readActive($card); + } + + public function resetLogs($cardNumber) + { + $card = Card::readCard($cardNumber); + $card->flag = 0; + $card->flag_out = 0; + $card->save(false); + Card::updateCardFlagTicket($card->id_card); + DoorLog::deleteAll( + ['id_card' => $card->id_card] + ); + // todo: revoke all assigned key + $this->revokeKey($cardNumber, "f100"); + } + + public function getLogs($cardNumber) + { + return DoorLog::findAll( + ['id_card' => $cardNumber] + ); + } + + public function getInfo($cardNumber) + { + $card = Card::readCard($cardNumber); + return [ + 'card' => $card, + 'customer' => $card->customer, + 'tickets' => Ticket::readActive($card), + 'doorLogs' => DoorLog::findAll( + ['id_card' => $card->id_card] + ), + 'lastDoorLog' => DoorLog::find()->orderBy(['id_door_log' => SORT_DESC])->limit(1)->one(), + 'doorLogCount' => DoorLog::find()->count() + ]; + + } + + public function createLog() + { + \Yii::info("Post create log:" . \Yii::$app->request->method); + if (\Yii::$app->request->isPost) { + $log = new DoorLogForTest(); + if ($log->load(\Yii::$app->request->post(), "")) { + if ($log->validate()) { + \Yii::info("Door log saving:" . $log->created_at); + $log->save(false); + return $log; + } else { + throw new BadRequestHttpException(print_r($log->getErrors(), true)); + } + } else { + \Yii::info("validated" . print_r($log->errors, true)); + throw new BadRequestHttpException(); + } + } + throw new BadRequestHttpException('Not a Post'); + } + + function checkoutKey($cardNumber, $keyNumber) + { + $model = new KeyToggleForm(); + $model->card = Card::readCard($cardNumber); + $model->customer = $model->card->customer; + $model->keyCard = $model->card; + $model->keyModel = $model->readKey($keyNumber); + $model->assign(); + } + + function revokeKey($cardNumber, $keyNumber) + { + $model = new KeyToggleForm(); + $model->card = Card::readCard($cardNumber); + $model->customer = $model->card->customer; + $model->keyCard = $model->card; + $model->keyModel = $model->readKey($keyNumber); + $model->revoke(); + } + +} diff --git a/common/manager/DoorManager.php b/common/manager/KeyDoorManager.php similarity index 99% rename from common/manager/DoorManager.php rename to common/manager/KeyDoorManager.php index 57eb36f..0300450 100644 --- a/common/manager/DoorManager.php +++ b/common/manager/KeyDoorManager.php @@ -29,7 +29,7 @@ use yii\web\ServerErrorHttpException; * Date: 2018.12.17. * Time: 6:12 */ -class DoorManager extends BaseObject +class KeyDoorManager extends BaseObject { /** diff --git a/common/models/DoorManagerLog.php b/common/models/DoorManagerLog.php index afeb6da..4c3dbcf 100644 --- a/common/models/DoorManagerLog.php +++ b/common/models/DoorManagerLog.php @@ -63,5 +63,22 @@ class DoorManagerLog extends \yii\db\ActiveRecord } + static function findFirstForCardFromTime($idCard,$datetime){ + return DoorManagerLog::find() + ->andWhere(['id_card' =>$idCard]) + ->andWhere(['verify_only' => false]) + ->andWhere(['>=' ,'created_at', $datetime]) + ->one(); + } + + + static function findAllEntryForTicketFromTime($idTicket, $datetime = null){ + return DoorManagerLog::find() + ->andWhere(['id_ticket' =>$idTicket]) + ->andWhere(['verify_only' => false]) + ->andWhere(['direction' => 'IN']) + ->andWhere(['>=' ,'created_at', isset( $datetime ) ? $datetime : date('Y-m-d H:i:s')]) + ->all(); + } } diff --git a/common/models/VirtualKey.php b/common/models/VirtualKey.php index 46dcc7e..2fdd51d 100644 --- a/common/models/VirtualKey.php +++ b/common/models/VirtualKey.php @@ -2,6 +2,9 @@ namespace common\models; +use common\components\DateUtil; +use common\components\Helper; +use common\helpers\AppDateTimeHelper; use Yii; use yii\behaviors\TimestampBehavior; use yii\helpers\ArrayHelper; @@ -62,10 +65,27 @@ class VirtualKey extends \yii\db\ActiveRecord [ 'class' => TimestampBehavior::className(), 'value' => function () { - return date('Y-m-d H:i:s'); + return DateUtil::formatDateTimeUtc(DateUtil::utcDateTime() ); } ] ], parent::behaviors()); } + + public static function readNotInCreatedInTheLastXMinutesByIdCard($idCard,$minutes){ + + $date = DateUtil::utcDateTime(); + $date = DateUtil::minusMinutes($date,$minutes ); + $dateStr = DateUtil::formatDateTimeUtc($date); + + $virtualKeysNotInCreatedInTheLastXMinuteForCard = VirtualKey::find() + ->andWhere(['id_card' => $idCard]) + ->andWhere([">=" ,'created_at',$dateStr]) + ->andWhere(['direction_in_at' => null]) + ->orderBy(['created_at' => SORT_DESC]) + ->all(); + return $virtualKeysNotInCreatedInTheLastXMinuteForCard; + } + + } diff --git a/docker/fitness/.env b/docker/fitness/.env index 9e81705..5d4a13c 100644 --- a/docker/fitness/.env +++ b/docker/fitness/.env @@ -1,2 +1,2 @@ FITNESS_REST_ALLOW_VERIFY_ONLY=true -DOOR_ENTRY_STRATEGY=door_pass111 \ No newline at end of file +DOOR_ENTRY_STRATEGY=door_pass \ No newline at end of file diff --git a/frontend/controllers/DoorManagerLogController.php b/frontend/controllers/DoorManagerLogController.php index a7b5a3a..31dbf07 100644 --- a/frontend/controllers/DoorManagerLogController.php +++ b/frontend/controllers/DoorManagerLogController.php @@ -2,7 +2,7 @@ namespace frontend\controllers; -use common\manager\DoorManager; +use common\manager\KeyDoorManager; use common\models\DoorManagerLog; use frontend\models\DoorManagerLogSearch; use frontend\models\InventorySearch; diff --git a/frontend/views/common/door_entry_strategy/_strategy_door_pass.php b/frontend/views/common/door_entry_strategy/_strategy_door_pass.php index dc9c8e3..ae34325 100644 --- a/frontend/views/common/door_entry_strategy/_strategy_door_pass.php +++ b/frontend/views/common/door_entry_strategy/_strategy_door_pass.php @@ -1,9 +1,8 @@ card))){ return; } - $activeCardPasses = \common\models\DoorCardPass::find() - ->andWhere( - [ - 'id_card' => $model->card->id_card, - 'invalidated_at' => null , + $virtualKeysNotInCreatedInTheLastXMinuteForCard = VirtualKey::readNotInCreatedInTheLastXMinutesByIdCard($model->card->id_card,5); -// [ '>=', $field , $start ] - - - ] - )->andWhere( - ['>=', 'valid_until_at', \common\components\DateUtil::formatDateTimeUtc(\common\components\DateUtil::utcDateTime())], - ) - ->orderBy(['valid_until_at' => SORT_DESC ])->all(); - - if (count($activeCardPasses) > 0){ - $cardPass = $activeCardPasses[0]; + if (count($virtualKeysNotInCreatedInTheLastXMinuteForCard) > 0){ + $activeVirtualKey = $virtualKeysNotInCreatedInTheLastXMinuteForCard[0]; ?>