doorcardpass && door move manager logging
This commit is contained in:
parent
4d44b1c2af
commit
fe0dd00145
@ -159,7 +159,6 @@ class DateUtil
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static function parseDate($dateString){
|
public static function parseDate($dateString){
|
||||||
|
|
||||||
$date = DateTime::createFromFormat('Y.m.d', $dateString, new DateTimeZone( 'UTC'));
|
$date = DateTime::createFromFormat('Y.m.d', $dateString, new DateTimeZone( 'UTC'));
|
||||||
$date->setTime(0, 0);
|
$date->setTime(0, 0);
|
||||||
return $date;
|
return $date;
|
||||||
@ -187,4 +186,22 @@ class DateUtil
|
|||||||
return $translations[$weekDay];
|
return $translations[$weekDay];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $dateTime \DateTime
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function resetSeconds($dateTime){
|
||||||
|
return $dateTime->setTime($dateTime->format("H"), $dateTime->format("i"),0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $dateTime \DateTime
|
||||||
|
* @param $minutes integer
|
||||||
|
* @return mixed
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static function addMinutes($dateTime, $minutes){
|
||||||
|
return $dateTime->add(new \DateInterval('PT' . $minutes . 'M'));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
33
common/components/DoorMoveContext.php
Normal file
33
common/components/DoorMoveContext.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
namespace common\components;
|
||||||
|
|
||||||
|
use yii\base\BaseObject;
|
||||||
|
class DoorMoveContext extends BaseObject {
|
||||||
|
|
||||||
|
public $id;
|
||||||
|
public $identifier;
|
||||||
|
public $device;
|
||||||
|
public $direction;
|
||||||
|
public $originalDirection;
|
||||||
|
|
||||||
|
public $verifyOnly;
|
||||||
|
public $created_at;
|
||||||
|
public $date;
|
||||||
|
|
||||||
|
public $card;
|
||||||
|
// todo: duplicate of card
|
||||||
|
public $cardNumber;
|
||||||
|
public $virtualKey;
|
||||||
|
public $key;
|
||||||
|
public $customer;
|
||||||
|
public $ticket;
|
||||||
|
|
||||||
|
|
||||||
|
public $kind;
|
||||||
|
public $error;
|
||||||
|
public $errorCode;
|
||||||
|
public $exception;
|
||||||
|
|
||||||
|
public $actions = [];
|
||||||
|
|
||||||
|
}
|
||||||
23
common/components/FitnessException.php
Normal file
23
common/components/FitnessException.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
namespace common\components;
|
||||||
|
|
||||||
|
class FitnessException extends \Exception {
|
||||||
|
const TYPE_BAD_REQUEST = "BAD_REQUEST";
|
||||||
|
const UNKNOWN_ERROR = "UNKNOWN_ERROR";
|
||||||
|
public $errorCode;
|
||||||
|
public $type;
|
||||||
|
public $payload;
|
||||||
|
public $originalException;
|
||||||
|
|
||||||
|
public function __construct( $message, $type = FitnessException::TYPE_BAD_REQUEST, $errorCode = null, $payload = null, $originalException= null) {
|
||||||
|
parent::__construct();
|
||||||
|
$this->message = $message;
|
||||||
|
$this->type = $type;
|
||||||
|
$this->errorCode = $errorCode;
|
||||||
|
$this->payload = $payload;
|
||||||
|
$this->originalException = $originalException;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -548,4 +548,8 @@ class Helper {
|
|||||||
return Helper::getArrayValue(\Yii::$app->params ,'door_entry_strategy','strategy_key');
|
return Helper::getArrayValue(\Yii::$app->params ,'door_entry_strategy','strategy_key');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getDoorPassValidityIntervalMinutes(){
|
||||||
|
return Helper::getArrayValue(\Yii::$app->params ,'door_pass_validity_interval_minutes','10');
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
143
common/manager/DoorCardPassManager.php
Normal file
143
common/manager/DoorCardPassManager.php
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace common\manager;
|
||||||
|
|
||||||
|
use common\components\DateUtil;
|
||||||
|
use common\components\Helper;
|
||||||
|
use common\models\Card;
|
||||||
|
use common\models\DoorCardPass;
|
||||||
|
use DateInterval;
|
||||||
|
use yii\base\BaseObject;
|
||||||
|
use yii\web\NotFoundHttpException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by IntelliJ IDEA.
|
||||||
|
* User: rocho
|
||||||
|
* Date: 2018.12.17.
|
||||||
|
* Time: 6:12
|
||||||
|
*/
|
||||||
|
class
|
||||||
|
DoorCardPassManager extends BaseObject
|
||||||
|
{
|
||||||
|
|
||||||
|
public function createNewDoorCardPass($idCard)
|
||||||
|
{
|
||||||
|
$model = new DoorCardPass();
|
||||||
|
$model->id_card = $idCard;
|
||||||
|
|
||||||
|
$validUntilTime = DateUtil::utcDateTime();
|
||||||
|
$validUntilTime->add(new DateInterval('PT' . Helper::getDoorPassValidityIntervalMinutes() . 'M'));
|
||||||
|
$validUntilTime->setTime($validUntilTime->format("H"), $validUntilTime->format("i"), 0);
|
||||||
|
$model->valid_until_at = DateUtil::formatDateTimeUtc($validUntilTime);
|
||||||
|
$model->save(false);
|
||||||
|
return $model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hardReset(){
|
||||||
|
$now = DateUtil::utcDateTime();
|
||||||
|
DoorCardPass::updateAll(
|
||||||
|
[
|
||||||
|
'invalidated_at' => DateUtil::formatDateTimeUtc($now)
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'invalidated_at' => null
|
||||||
|
]
|
||||||
|
);
|
||||||
|
\Yii::$app->db->createCommand(Card::SQL_DENY_DOOR_CARD_PASS())->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws NotFoundHttpException
|
||||||
|
*/
|
||||||
|
public function updateDoorCardPassStateForCard($idCard)
|
||||||
|
{
|
||||||
|
$now = DateUtil::utcDateTime();
|
||||||
|
$card = Card::findOne($idCard);
|
||||||
|
if (!isset($card)) {
|
||||||
|
throw new NotFoundHttpException();
|
||||||
|
}
|
||||||
|
$passes = $this->readAllNovInvalidatedAtCardPassForCard($idCard,$now);
|
||||||
|
$this->setCardFlagAndInvalidateDoorCardPasses($card, $passes,$now);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateDoorCardPassStateForAllCard(){
|
||||||
|
$passes = $this->readAllNonInvalidated();
|
||||||
|
$map = array();
|
||||||
|
foreach ($passes as $pass){
|
||||||
|
$idCard = $pass->id_card;
|
||||||
|
if ( !array_key_exists($idCard,$map)){
|
||||||
|
$map[$idCard] = array();
|
||||||
|
}
|
||||||
|
$map[$idCard][] = $pass;
|
||||||
|
}
|
||||||
|
|
||||||
|
$now = DateUtil::utcDateTime();
|
||||||
|
|
||||||
|
foreach ($map as $idCard => $passes){
|
||||||
|
$card = Card::findOne($idCard);
|
||||||
|
if (isset($card)) {
|
||||||
|
$this->setCardFlagAndInvalidateDoorCardPasses($card, $passes,$now);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function readAllNovInvalidatedAtCardPassForCard($idCard)
|
||||||
|
{
|
||||||
|
return DoorCardPass::find()
|
||||||
|
->andWhere(
|
||||||
|
[
|
||||||
|
'id_card' => $idCard,
|
||||||
|
'invalidated_at' => null,
|
||||||
|
]
|
||||||
|
)->all();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function readAllNonInvalidated()
|
||||||
|
{
|
||||||
|
return DoorCardPass::find()
|
||||||
|
->andWhere(
|
||||||
|
['invalidated_at' => null]
|
||||||
|
)->all() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function setCardFlagAndInvalidateDoorCardPasses($card, $doorCardPasses, $now)
|
||||||
|
{
|
||||||
|
$allowed = $this->hasActiveDoorCardPass($doorCardPasses, $now);
|
||||||
|
$origFlag = $card->flag;
|
||||||
|
$card->flag = Helper::setBit($card->flag, Card::$FLAG_DOOR_PASS_ALLOWED, !$allowed);
|
||||||
|
if ($card->flag !== $origFlag) {
|
||||||
|
$card->save(false);
|
||||||
|
}
|
||||||
|
$this->invalidateNonActiveDoorCardPasses($doorCardPasses, $now);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function invalidateNonActiveDoorCardPasses($doorCardPasses, $now)
|
||||||
|
{
|
||||||
|
foreach ($doorCardPasses as $pass) {
|
||||||
|
if (isset($pass->valid_until_at) && !empty($pass->valid_until_at)) {
|
||||||
|
\Yii::error( "mydate". print_r($pass->valid_until_at ,true));
|
||||||
|
|
||||||
|
$validUntilAt = DateUtil::parseDateTime($pass->valid_until_at);
|
||||||
|
$active = ($validUntilAt >= $now);
|
||||||
|
if (!$active) {
|
||||||
|
$pass->invalidated_at = DateUtil::formatDateTimeUtc($now);
|
||||||
|
$pass->save(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function hasActiveDoorCardPass($doorCardPasses, $now)
|
||||||
|
{
|
||||||
|
$active = false;
|
||||||
|
foreach ($doorCardPasses as $pass) {
|
||||||
|
if (isset($pass->valid_until_at)) {
|
||||||
|
$validUntilAt = DateUtil::parseDateTime($pass->valid_until_at);
|
||||||
|
$active |= ($validUntilAt >= $now);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $active;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -3,6 +3,8 @@
|
|||||||
namespace common\manager;
|
namespace common\manager;
|
||||||
|
|
||||||
use common\components\DateUtil;
|
use common\components\DateUtil;
|
||||||
|
use common\components\DoorMoveContext;
|
||||||
|
use common\components\FitnessException;
|
||||||
use common\components\Helper;
|
use common\components\Helper;
|
||||||
use common\components\StopWatch;
|
use common\components\StopWatch;
|
||||||
use common\models\Card;
|
use common\models\Card;
|
||||||
@ -37,108 +39,185 @@ class DoorManager extends BaseObject
|
|||||||
* @param $createdAt number unix timestamp , override createdAt for doorLogs
|
* @param $createdAt number unix timestamp , override createdAt for doorLogs
|
||||||
* @param $date number unix timestamp, override date for validation check 'now'
|
* @param $date number unix timestamp, override date for validation check 'now'
|
||||||
* @return void
|
* @return void
|
||||||
* @throws BadRequestHttpException
|
|
||||||
* @throws ServerErrorHttpException
|
|
||||||
* @throws \yii\base\InvalidConfigException
|
|
||||||
* @throws \yii\db\Exception
|
|
||||||
*/
|
*/
|
||||||
public function move($identifier, $device, $direction, $verifyOnly, $createdAt = null, $date = null)
|
public function move($identifier, $device, $direction, $verifyOnly, $createdAt = null, $date = null)
|
||||||
{
|
{
|
||||||
$requestId = uniqid("",false);
|
$requestId = uniqid("", false);
|
||||||
$stopWatch = new StopWatch();
|
$context = new DoorMoveContext([
|
||||||
|
'id' => $requestId,
|
||||||
|
'$identifier' => $identifier,
|
||||||
|
'device' => $device,
|
||||||
|
'direction' => $direction,
|
||||||
|
'originalDirection' => $direction,
|
||||||
|
'verifyOnly' => $verifyOnly
|
||||||
|
]);
|
||||||
|
try {
|
||||||
|
$stopWatch = new StopWatch();
|
||||||
|
|
||||||
// for testing purposes
|
// for testing purposes
|
||||||
if ( Helper::isRestAllowVerifyOnly() === false ){
|
if (Helper::isRestAllowVerifyOnly() === false) {
|
||||||
\Yii::info("$requestId: verifyonly not allowed");
|
\Yii::info("$requestId: verifyonly not allowed");
|
||||||
$verifyOnly = false;
|
$verifyOnly = false;
|
||||||
}
|
|
||||||
|
|
||||||
\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();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($date)) {
|
|
||||||
$date = DateUtil::parseDateTime($date);
|
|
||||||
} else {
|
|
||||||
$date = DateUtil::utcDate();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($device === 'E') {
|
|
||||||
$this->moveEmergency($requestId,$identifier, $device, $direction, $verifyOnly, $createdAt, $date);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$cardNumber = $identifier;
|
|
||||||
$virtualKey = null;
|
|
||||||
|
|
||||||
switch ($direction) {
|
|
||||||
case 'IN':
|
|
||||||
$direction = DoorLog::$DIRECTION_IN;
|
|
||||||
break;
|
|
||||||
case 'OUT':
|
|
||||||
$direction = DoorLog::$DIRECTION_OUT;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new BadRequestHttpException("$requestId: Direction not supported: " . $direction);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if device is qr code
|
|
||||||
if ($device == 'Q') {
|
|
||||||
// allow only virtual key
|
|
||||||
$virtualKey = VirtualKey::findOne(['number' => $identifier]);
|
|
||||||
if (!isset($virtualKey)) {
|
|
||||||
throw new BadRequestHttpException("$requestId: Virtual key not found: " . $identifier);
|
|
||||||
}
|
}
|
||||||
$card = Card::findOne($virtualKey->id_card);
|
|
||||||
if ($card != null) {
|
|
||||||
$card = Card::readCard($card->number);
|
|
||||||
}
|
|
||||||
if ($card == null) {
|
|
||||||
throw new BadRequestHttpException("$requestId: Card not found by virtual key: " . $identifier . '/' . $virtualKey->id_card);
|
|
||||||
}
|
|
||||||
$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 BadRequestHttpException("$requestId: Card not found with number: " . $identifier);
|
|
||||||
}
|
|
||||||
\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());
|
|
||||||
|
|
||||||
|
\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->created_at = $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;
|
||||||
|
$virtualKey = null;
|
||||||
|
|
||||||
|
switch ($direction) {
|
||||||
|
case 'IN':
|
||||||
|
$direction = DoorLog::$DIRECTION_IN;
|
||||||
|
break;
|
||||||
|
case 'OUT':
|
||||||
|
$direction = DoorLog::$DIRECTION_OUT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new BadRequestHttpException("$requestId: Direction not supported: " . $direction);
|
||||||
|
}
|
||||||
|
$context->direction = $direction;
|
||||||
|
|
||||||
|
// if device is qr code
|
||||||
|
if ($device == 'Q') {
|
||||||
|
// allow only virtual key
|
||||||
|
$virtualKey = VirtualKey::findOne(['number' => $identifier]);
|
||||||
|
|
||||||
|
if (!isset($virtualKey)) {
|
||||||
|
$context->error = true;
|
||||||
|
$context->errorCode = "VIRTUAL_KEY_NOT_FOUND";
|
||||||
|
throw new BadRequestHttpException("$requestId: Virtual key not found: " . $identifier);
|
||||||
|
}
|
||||||
|
$card = Card::findOne($virtualKey->id_card);
|
||||||
|
if ($card != null) {
|
||||||
|
$card = Card::readCard($card->number);
|
||||||
|
}
|
||||||
|
if ($card == null) {
|
||||||
|
$context->error = true;
|
||||||
|
$context->errorCode = "CARD_NOT_FOUND";
|
||||||
|
throw new BadRequestHttpException("$requestId: Card not found by virtual key: " . $identifier . '/' . $virtualKey->id_card);
|
||||||
|
}
|
||||||
|
$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)) {
|
||||||
|
$context->error = true;
|
||||||
|
$context->errorCode = "CARD_NOT_FOUND";
|
||||||
|
throw new BadRequestHttpException("$requestId: Card not found with number: " . $identifier);
|
||||||
|
}
|
||||||
|
\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;
|
||||||
|
|
||||||
|
\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;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$context->error = true;
|
||||||
|
$context->exception = $e;
|
||||||
|
$context->errorCode = "UNKNOWN";
|
||||||
|
} finally {
|
||||||
|
// do logging
|
||||||
|
$this->logContext($context);
|
||||||
}
|
}
|
||||||
|
|
||||||
\Yii::info("$requestId: Card number " . $card->number);
|
|
||||||
|
|
||||||
if ($card->type == Card::TYPE_EMPLOYEE) {
|
|
||||||
$this->moveEmployee($identifier, $device, $direction, $verifyOnly, $createdAt, $date, $card, $cardNumber, $virtualKey);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->moveCustomer($requestId, $identifier, $device, $direction, $verifyOnly, $createdAt, $date, $card, $cardNumber, $virtualKey);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function moveEmergency($requestId,$identifier, $device, $direction, $verifyOnly, $createdAt, $date)
|
/**
|
||||||
|
* @param $ctx DoorMoveContext
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function logContext($ctx){
|
||||||
|
try{
|
||||||
|
$result = [
|
||||||
|
'requestId' => $ctx->id,
|
||||||
|
'identifier' => $ctx->identifier,
|
||||||
|
'verifyOnly' => $ctx->verifyOnly,
|
||||||
|
'device' => $ctx->device,
|
||||||
|
'direction' => $ctx->direction,
|
||||||
|
'originalDirection' => $ctx->originalDirection,
|
||||||
|
'idCard' => isset($ctx->card)? $ctx->card->id_card : null,
|
||||||
|
'cardNumber' => isset($ctx->card) ? $ctx->card->number : null,
|
||||||
|
'idTicket' => isset($ctx->ticket) ? $ctx->ticket->id_ticket : null,
|
||||||
|
'ticketType' => isset($ctx->ticket) ? $ctx->ticket->ticketType->name : null,
|
||||||
|
'ticketUsageCount' => isset($ctx->ticket) ? $ctx->ticket->usage_count : null,
|
||||||
|
'idCustomer' => isset($ctx->customer) ? $ctx->customer->id_customer : null,
|
||||||
|
'customerName' => isset($ctx->customer) ? $ctx->customer->name : null,
|
||||||
|
'customerEmail' => isset($ctx->customer) ? $ctx->customer->email : null,
|
||||||
|
'key' => isset($ctx->key) ? $ctx->key->name : null,
|
||||||
|
'idVirtualKey' => isset($ctx->virtualKey) ? $ctx->virtualKey->idVirtualKey : null,
|
||||||
|
'kind' => $ctx->kind,
|
||||||
|
'actions' => implode(",",$ctx->actions),
|
||||||
|
'error' => $ctx->error,
|
||||||
|
'errorCode' => $ctx->errorCode,
|
||||||
|
'ticketUsage' => 1,
|
||||||
|
];
|
||||||
|
|
||||||
|
if ( $ctx->error === true ){
|
||||||
|
if ( isset($ctx->exception )){
|
||||||
|
$result['errorMessage'] = substr( $ctx->exception->message,0,100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
\Yii::info("door log: " . implode(";", $result));
|
||||||
|
|
||||||
|
}catch (\Exception $e){
|
||||||
|
\Yii::error("Failed to log door context");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function moveEmergency($ctx)
|
||||||
{
|
{
|
||||||
\Yii::info("$requestId: emergency move");
|
$ctx->kind = "EMERGENCY";
|
||||||
|
\Yii::info("$ctx->requestId: emergency move");
|
||||||
try {
|
try {
|
||||||
$createdAtStr = DateUtil::formatDateTimeUtc($createdAt);
|
$createdAtStr = DateUtil::formatDateTimeUtc($ctx->createdAt);
|
||||||
\Yii::$app->db->beginTransaction();
|
\Yii::$app->db->beginTransaction();
|
||||||
|
|
||||||
$doorLog = new DoorLog();
|
$doorLog = new DoorLog();
|
||||||
$doorLog->version = 2;
|
$doorLog->version = 2;
|
||||||
$doorLog->direction = DoorLog::$DIRECTION_ALL_EMERGENCY;
|
$doorLog->direction = DoorLog::$DIRECTION_ALL_EMERGENCY;
|
||||||
$doorLog->source_app = $device;
|
$doorLog->source_app = $ctx->device;
|
||||||
$doorLog->created_at = $createdAtStr;
|
$doorLog->created_at = $createdAtStr;
|
||||||
|
|
||||||
$doorLog->save(false);
|
$doorLog->save(false);
|
||||||
@ -150,33 +229,42 @@ class DoorManager extends BaseObject
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$ctx->actions[] = "EMERGENCY_MOVE";
|
||||||
|
|
||||||
\Yii::$app->db->transaction->commit();
|
\Yii::$app->db->transaction->commit();
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
\Yii::$app->db->transaction->rollBack();
|
\Yii::$app->db->transaction->rollBack();
|
||||||
throw $e;
|
throw new FitnessException(
|
||||||
|
"unknowon error",
|
||||||
|
FitnessException::UNKNOWN_ERROR,
|
||||||
|
"EMERGENCY_OPEN_FAILED",
|
||||||
|
$ctx,
|
||||||
|
$e
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function moveEmployee($identifier, $device, $direction, $verifyOnly, $createdAt, $date, $card, $cardNumber, $virtualKey)
|
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.
|
* if the card type is employee, neither customer nor ticket is needed.
|
||||||
* Free to enter/leave
|
* Free to enter/leave
|
||||||
*/
|
*/
|
||||||
\Yii::info("employee move");
|
\Yii::info("employee move");
|
||||||
try {
|
try {
|
||||||
$createdAtStr = DateUtil::formatDateTimeUtc($createdAt);
|
$createdAtStr = DateUtil::formatDateTimeUtc($ctx->createdAt);
|
||||||
\Yii::$app->db->beginTransaction();
|
\Yii::$app->db->beginTransaction();
|
||||||
|
|
||||||
$doorLog = new DoorLog();
|
$doorLog = new DoorLog();
|
||||||
$doorLog->version = 2;
|
$doorLog->version = 2;
|
||||||
$doorLog->direction = $direction;
|
$doorLog->direction = $ctx->direction;
|
||||||
$doorLog->source_app = $device;
|
$doorLog->source_app = $ctx->device;
|
||||||
$doorLog->created_at = $createdAtStr;
|
$doorLog->created_at = $createdAtStr;
|
||||||
$doorLog->id_card = $card->id_card;
|
$doorLog->id_card = $ctx->card->id_card;
|
||||||
$doorLog->card_flag = $card->flag;
|
$doorLog->card_flag = $ctx->card->flag;
|
||||||
|
|
||||||
if (!$verifyOnly) {
|
if (!$ctx->verifyOnly) {
|
||||||
|
|
||||||
$doorLog->save(false);
|
$doorLog->save(false);
|
||||||
Log::log(
|
Log::log(
|
||||||
@ -188,52 +276,53 @@ class DoorManager extends BaseObject
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$ctx->actions[] = "EMPLOYEE_" . $ctx->originalDirection;
|
||||||
|
|
||||||
\Yii::$app->db->transaction->commit();
|
\Yii::$app->db->transaction->commit();
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
\Yii::$app->db->transaction->rollBack();
|
\Yii::$app->db->transaction->rollBack();
|
||||||
throw $e;
|
throw new FitnessException(
|
||||||
|
"unknowon error",
|
||||||
|
FitnessException::UNKNOWN_ERROR,
|
||||||
|
"EMPLOYEE_FAILED",
|
||||||
|
$ctx,
|
||||||
|
$e
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $requestId
|
* @param $ctx
|
||||||
* @param $identifier string virtual key id, card rfid or card number
|
*
|
||||||
* @param $device string device
|
|
||||||
* @param $direction number direction
|
|
||||||
* @param $verifyOnly boolean only check or real move
|
|
||||||
* @param $createdAt
|
|
||||||
* @param $date
|
|
||||||
* @param $card
|
|
||||||
* @param $cardNumber
|
|
||||||
* @param $virtualKey
|
|
||||||
* @return void
|
* @return void
|
||||||
* @throws BadRequestHttpException
|
* @throws BadRequestHttpException
|
||||||
* @throws ServerErrorHttpException
|
* @throws ServerErrorHttpException
|
||||||
* @throws InvalidConfigException
|
* @throws InvalidConfigException
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
function moveCustomer($requestId, $identifier, $device, $direction, $verifyOnly, $createdAt, $date, $card, $cardNumber, $virtualKey)
|
function moveCustomer($ctx/* $requestId, $identifier, $device, $direction, $verifyOnly, $createdAt, $date, $card, $cardNumber, $virtualKey*/)
|
||||||
{
|
{
|
||||||
\Yii::info("$requestId: move customer");
|
$ctx->kind = "CUSTOMER";
|
||||||
|
\Yii::info("$ctx->requestId: move customer");
|
||||||
$stopWatch = new StopWatch();
|
$stopWatch = new StopWatch();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$createdAtStr = DateUtil::formatDateTimeUtc($createdAt);
|
$createdAtStr = DateUtil::formatDateTimeUtc($ctx->createdAt);
|
||||||
\Yii::info("$requestId: crated at str: ". $createdAtStr);
|
\Yii::info("$ctx->requestId: crated at str: " . $createdAtStr);
|
||||||
\Yii::$app->db->beginTransaction();
|
\Yii::$app->db->beginTransaction();
|
||||||
|
|
||||||
$doorLog = new DoorLog();
|
$doorLog = new DoorLog();
|
||||||
$doorLog->version = 2;
|
$doorLog->version = 2;
|
||||||
$doorLog->direction = $direction;
|
$doorLog->direction = $ctx->direction;
|
||||||
$doorLog->source_app = $device;
|
$doorLog->source_app = $ctx->device;
|
||||||
$doorLog->created_at = $createdAtStr;
|
$doorLog->created_at = $createdAtStr;
|
||||||
$doorLog->id_card = $card->id_card;
|
$doorLog->id_card = $ctx->card->id_card;
|
||||||
$doorLog->card_flag = $card->flag;
|
$doorLog->card_flag = $ctx->card->flag;
|
||||||
|
|
||||||
|
|
||||||
$activeTickets = Ticket::readActive($card, clone $date);
|
$activeTickets = Ticket::readActive($ctx->card, clone $ctx->date);
|
||||||
\Yii::info("$requestId: active ticket count:" . count($activeTickets));
|
\Yii::info("$ctx->requestId: active ticket count:" . count($activeTickets));
|
||||||
/** @var Ticket $ticket */
|
/** @var Ticket $ticket */
|
||||||
$ticket = null;
|
$ticket = null;
|
||||||
if (isset($activeTickets) && count($activeTickets) > 0) {
|
if (isset($activeTickets) && count($activeTickets) > 0) {
|
||||||
@ -241,69 +330,104 @@ class DoorManager extends BaseObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isset($ticket)) {
|
if (!isset($ticket)) {
|
||||||
throw new BadRequestHttpException("$requestId: No active ticket found for:" . $card->number);
|
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("$requestId: ticket {$ticket->id_ticket} loaded in sec " . $stopWatch->split());
|
\Yii::info("$ctx->requestId: ticket {$ticket->id_ticket} loaded in sec " . $stopWatch->split());
|
||||||
|
|
||||||
$doorLog->id_ticket_current = $ticket->id_ticket;
|
$doorLog->id_ticket_current = $ticket->id_ticket;
|
||||||
|
|
||||||
// customer is also required
|
// customer is also required
|
||||||
$customer = $card->customer;
|
$customer = $ctx->card->customer;
|
||||||
if (!isset($customer)) {
|
if (!isset($customer)) {
|
||||||
throw new BadRequestHttpException("$requestId: Customer not found for:" . $card->number);
|
throw new FitnessException(
|
||||||
|
"$ctx->requestId: Customer not found for:" . $ctx->card->number,
|
||||||
|
FitnessException::TYPE_BAD_REQUEST,
|
||||||
|
"NOT_FOUND_CUSTOMER",
|
||||||
|
$ctx
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$doorLog->id_customer = $customer->id_customer;
|
$ctx->customer = $customer;
|
||||||
\Yii::info("$requestId: customer {$customer->id_customer} loaded in sec " . $stopWatch->split());
|
|
||||||
|
|
||||||
if (!$verifyOnly) {
|
$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
|
// save the door log
|
||||||
$doorLog->save(false);
|
$doorLog->save(false);
|
||||||
}
|
}
|
||||||
\Yii::info("$requestId: door log {$doorLog->id_door_log} saved in sec " . $stopWatch->split());
|
\Yii::info("$ctx->requestId: door log {$doorLog->id_door_log} saved in sec " . $stopWatch->split());
|
||||||
|
|
||||||
// if direction is in
|
// if direction is in, check if usage count must be increased
|
||||||
if ($direction == DoorLog::$DIRECTION_IN) {
|
if ($ctx->direction == DoorLog::$DIRECTION_IN) {
|
||||||
|
|
||||||
if ($card->isFlagDoor()) {
|
if ($ctx->card->isFlagDoor()) {
|
||||||
throw new BadRequestHttpException("$requestId: Card already 'IN': " . $card->id_card);
|
throw new FitnessException(
|
||||||
|
"$ctx->requestId: Card already 'IN': " . $ctx->card->id_card,
|
||||||
|
FitnessException::TYPE_BAD_REQUEST,
|
||||||
|
"ALREADY_IN",
|
||||||
|
$ctx
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($card->isFlagKey()) {
|
if ($ctx->card->isFlagKey()) {
|
||||||
throw new BadRequestHttpException("$requestId: Key required: " . $card->id_card);
|
throw new FitnessException(
|
||||||
|
"$ctx->requestId: Key required: " . $ctx->card->id_card,
|
||||||
|
FitnessException::TYPE_BAD_REQUEST,
|
||||||
|
"REQUIRED_KEY",
|
||||||
|
$ctx
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($card->isFlagStatus()) {
|
if ($ctx->card->isFlagStatus()) {
|
||||||
throw new BadRequestHttpException("$requestId: Card has no active status: " . $card->id_card);
|
throw new FitnessException(
|
||||||
|
"$ctx->requestId: Card has no active status: " . $ctx->card->id_card,
|
||||||
|
FitnessException::TYPE_BAD_REQUEST,
|
||||||
|
"CARD_STATUS_NOT_ACTIVE",
|
||||||
|
$ctx
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($virtualKey)) {
|
if (isset($ctx->virtualKey)) {
|
||||||
|
|
||||||
if (isset($virtualKey->direction_in_at)) {
|
if (isset($ctx->virtualKey->direction_in_at)) {
|
||||||
throw new BadRequestHttpException("$requestId: Virtual key - already moved in: " . $identifier . '/' . $virtualKey->id_card);
|
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
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$virtualKey->direction_in_at = Helper::getDateTimeString();
|
$ctx->virtualKey->direction_in_at = Helper::getDateTimeString();
|
||||||
\Yii::info("$requestId: Setting virtual key direction_in_at");
|
\Yii::info("$ctx->requestId: Setting virtual key direction_in_at");
|
||||||
|
|
||||||
if (!$verifyOnly) {
|
$ctx->actions[] = "VIRTUAL_KEY_MOVE_IN";
|
||||||
\Yii::info("$requestId: Updating virtual key");
|
|
||||||
$virtualKey->save(false);
|
if (!$ctx->verifyOnly) {
|
||||||
|
\Yii::info("$ctx->requestId: Updating virtual key");
|
||||||
|
$ctx->virtualKey->save(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// detect if need to increase usage count for ticket
|
// detect if need to increase usage count for ticket
|
||||||
if (!$verifyOnly) {
|
if (!$ctx->verifyOnly) {
|
||||||
// if not verifyonly, check, if ticket usage count must be increased
|
// if not verifyonly, check, if ticket usage count must be increased
|
||||||
$countDoorLogsForTicketSince = $this->getCountDoorLogsForTicketSince($ticket->id_ticket, DateUtil::utcDate(clone $date));
|
$countDoorLogsForTicketSince = $this->getCountDoorLogsForTicketSince($ticket->id_ticket, DateUtil::utcDate(clone $ctx->date));
|
||||||
\Yii::info("$requestId: getCountDoorLogsForTicketSince: " . $countDoorLogsForTicketSince);
|
\Yii::info("$ctx->requestId: getCountDoorLogsForTicketSince: " . $countDoorLogsForTicketSince);
|
||||||
|
|
||||||
if (!isset($countDoorLogsForTicketSince)) {
|
if (!isset($countDoorLogsForTicketSince)) {
|
||||||
$countDoorLogsForTicketSince = 0;
|
$countDoorLogsForTicketSince = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
\Yii::info("$requestId: count of door logs '{$countDoorLogsForTicketSince}' loaded in sec " . $stopWatch->split());
|
\Yii::info("$ctx->requestId: count of door logs '{$countDoorLogsForTicketSince}' loaded in sec " . $stopWatch->split());
|
||||||
|
|
||||||
// if the current event is the first door log today
|
// if the current event is the first door log today
|
||||||
if ($countDoorLogsForTicketSince == 1) {
|
if ($countDoorLogsForTicketSince == 1) {
|
||||||
@ -311,7 +435,7 @@ class DoorManager extends BaseObject
|
|||||||
$usageCount = $ticket->usage_count;
|
$usageCount = $ticket->usage_count;
|
||||||
$ticket->usage_count += 1;
|
$ticket->usage_count += 1;
|
||||||
$ticket->save(false);
|
$ticket->save(false);
|
||||||
\Yii::info("$requestId: First ticket usage today, increasing usage count for card: " . $card->id_card);
|
\Yii::info("$ctx->requestId: First ticket usage today, increasing usage count for card: " . $ctx->card->id_card);
|
||||||
Log::log(
|
Log::log(
|
||||||
[
|
[
|
||||||
'type' => Log::$TYPE_TICKET_USAGE_FIRST,
|
'type' => Log::$TYPE_TICKET_USAGE_FIRST,
|
||||||
@ -320,18 +444,19 @@ class DoorManager extends BaseObject
|
|||||||
'id_door_log' => $doorLog->id_door_log
|
'id_door_log' => $doorLog->id_door_log
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
\Yii::info("$requestId: Ticket usage count increased after first doorlog of day in sec " . $stopWatch->split());
|
\Yii::info("$ctx->requestId: Ticket usage count increased after first doorlog of day in sec " . $stopWatch->split());
|
||||||
|
$ctx->actions[] = "TICKET_FIRST_USAGE_TODAY";
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
\Yii::info("$requestId: more then one door log today for card: " . $card->id_card);
|
\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
|
// 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.
|
// 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
|
// If the actual event happens in an interval, in which still now doorlog event happend, we increase
|
||||||
// the usage count with 1
|
// the usage count with 1
|
||||||
// 3 óránként 1-et levonunk
|
// 3 óránként 1-et levonunk
|
||||||
|
|
||||||
$startOfDay = DateUtil::utcDate(clone $date);
|
$startOfDay = DateUtil::utcDate(clone $ctx->date);
|
||||||
$startOfTomorrow = DateUtil::tomorrowStart(clone $date);
|
$startOfTomorrow = DateUtil::tomorrowStart(clone $ctx->date);
|
||||||
|
|
||||||
$allDoorLogToday = DoorLog::find()
|
$allDoorLogToday = DoorLog::find()
|
||||||
->andWhere(['>=', 'door_log.created_at', DateUtil::formatDateUtc($startOfDay)])
|
->andWhere(['>=', 'door_log.created_at', DateUtil::formatDateUtc($startOfDay)])
|
||||||
@ -340,9 +465,9 @@ class DoorManager extends BaseObject
|
|||||||
->andWhere(['in', 'direction', [DoorLog::$DIRECTION_IN_WITHOUT_MOVE, DoorLog::$DIRECTION_IN]])
|
->andWhere(['in', 'direction', [DoorLog::$DIRECTION_IN_WITHOUT_MOVE, DoorLog::$DIRECTION_IN]])
|
||||||
->orderBy(['door_log.created_at' => SORT_ASC])
|
->orderBy(['door_log.created_at' => SORT_ASC])
|
||||||
->all();
|
->all();
|
||||||
\Yii::info("$requestId: All door logs for today loaded in sec " . $stopWatch->split());
|
\Yii::info("$ctx->requestId: All door logs for today loaded in sec " . $stopWatch->split());
|
||||||
|
|
||||||
\Yii::info("$requestId: allDoorLogToday", print_r($allDoorLogToday, true));
|
\Yii::info("$ctx->requestId: allDoorLogToday", print_r($allDoorLogToday, true));
|
||||||
|
|
||||||
|
|
||||||
if (isset($allDoorLogToday) && count($allDoorLogToday) > 0) {
|
if (isset($allDoorLogToday) && count($allDoorLogToday) > 0) {
|
||||||
@ -351,7 +476,7 @@ class DoorManager extends BaseObject
|
|||||||
|
|
||||||
if (isset($firstInToday)) {
|
if (isset($firstInToday)) {
|
||||||
|
|
||||||
\Yii::info("$requestId: first in today for card: " . $card->id_card . " was at " . $firstInToday->created_at);
|
\Yii::info("$ctx->requestId: first in today for card: " . $ctx->card->id_card . " was at " . $firstInToday->created_at);
|
||||||
|
|
||||||
$firstEntryDateTimeToday = DateUtil::parseDateTime($firstInToday->created_at);
|
$firstEntryDateTimeToday = DateUtil::parseDateTime($firstInToday->created_at);
|
||||||
|
|
||||||
@ -371,9 +496,9 @@ class DoorManager extends BaseObject
|
|||||||
$intervals[] = $this->createTicketUsageInterval($intervalStart, $startOfTomorrow, $allDoorLogToday, $doorLog);
|
$intervals[] = $this->createTicketUsageInterval($intervalStart, $startOfTomorrow, $allDoorLogToday, $doorLog);
|
||||||
}
|
}
|
||||||
|
|
||||||
$activeInterval = $this->getActiveInterval($intervals, $createdAt);
|
$activeInterval = $this->getActiveInterval($intervals, $ctx->createdAt);
|
||||||
if (!isset($activeInterval)) {
|
if (!isset($activeInterval)) {
|
||||||
throw new ServerErrorHttpException("$requestId: Active Interval not found");
|
throw new ServerErrorHttpException("$ctx->requestId: Active Interval not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
$logCountInActiveInterval = count($activeInterval['logs']);
|
$logCountInActiveInterval = count($activeInterval['logs']);
|
||||||
@ -381,82 +506,120 @@ class DoorManager extends BaseObject
|
|||||||
if ($logCountInActiveInterval == 1) {
|
if ($logCountInActiveInterval == 1) {
|
||||||
$ticket->usage_count = $ticket->usage_count + 1;
|
$ticket->usage_count = $ticket->usage_count + 1;
|
||||||
$ticket->save(false);
|
$ticket->save(false);
|
||||||
\Yii::info("$requestId: Ticket usage count increased after first IN after first door_log in interval in sec " . $stopWatch->split());
|
\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 ($direction == DoorLog::$DIRECTION_OUT || $direction == DoorLog::$DIRECTION_OUT_WITHOUT_MOVE) {
|
if ($ctx->direction == DoorLog::$DIRECTION_OUT || $ctx->direction == DoorLog::$DIRECTION_OUT_WITHOUT_MOVE) {
|
||||||
|
|
||||||
if ($card->isFlagOutKey()) {
|
if ($ctx->card->isFlagOutKey()) {
|
||||||
throw new BadRequestHttpException("$requestId: Can't exit with card has a key assigned");
|
throw new FitnessException(
|
||||||
|
"$ctx->requestId: Can't exit with card has a key assigned",
|
||||||
|
FitnessException::TYPE_BAD_REQUEST,
|
||||||
|
"CARD_LOCKER_KEY_ASSIGNED_FLAG",
|
||||||
|
$ctx
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($card->isFlagStatus()) {
|
if ($ctx->card->isFlagStatus()) {
|
||||||
throw new BadRequestHttpException("$requestId: Can't exit with card has inactive status");
|
throw new FitnessException(
|
||||||
|
"$ctx->requestId: Can't exit with card has inactive status",
|
||||||
|
FitnessException::TYPE_BAD_REQUEST,
|
||||||
|
"CARD_STATUS_INACTIVE",
|
||||||
|
$ctx
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$keyAssigned = CardKeyAssignment::findOne(['id_card' => $card->id_card]);
|
$keyAssigned = CardKeyAssignment::findOne(['id_card' => $ctx->card->id_card]);
|
||||||
|
|
||||||
if (isset($keyAssigned)) {
|
if (isset($keyAssigned)) {
|
||||||
throw new BadRequestHttpException("$requestId: Can't exit with card has a key assigned");
|
throw new FitnessException(
|
||||||
|
"$ctx->requestId: Can't exit with card has a key assigned",
|
||||||
|
FitnessException::TYPE_BAD_REQUEST,
|
||||||
|
"CARD_LOCKER_KEY_ASSIGNED_KEY",
|
||||||
|
$ctx
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($virtualKey)) {
|
if (isset($virtualKey)) {
|
||||||
|
|
||||||
if (!isset($virtualKey->direction_in_at)) {
|
if (!isset($virtualKey->direction_in_at)) {
|
||||||
throw new BadRequestHttpException("$requestId: Virtual key: move out without move in");
|
throw new FitnessException(
|
||||||
|
"$ctx->requestId: Virtual key: move out without move in",
|
||||||
|
FitnessException::TYPE_BAD_REQUEST,
|
||||||
|
"VIRTUAL_KEY_MOVE_OUT_WITHOUT_MOVE_IN",
|
||||||
|
$ctx
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($virtualKey->direction_out_at)) {
|
if (isset($virtualKey->direction_out_at)) {
|
||||||
throw new BadRequestHttpException("$requestId: Virtual key: already move out");
|
throw new FitnessException(
|
||||||
|
"$ctx->requestId: Virtual key: already move out",
|
||||||
|
FitnessException::TYPE_BAD_REQUEST,
|
||||||
|
"VIRTUAL_KEY_ALREADY_OUT",
|
||||||
|
$ctx
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$virtualKey->direction_out_at = Helper::getDateTimeString();
|
$virtualKey->direction_out_at = Helper::getDateTimeString();
|
||||||
|
|
||||||
if (!$verifyOnly) {
|
if (!$ctx->verifyOnly) {
|
||||||
$virtualKey->save(false);
|
$virtualKey->save(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$ticket->count_move_out = $ticket->usage_count;
|
$ticket->count_move_out = $ticket->usage_count;
|
||||||
if (!$verifyOnly) {
|
if (!$ctx->verifyOnly) {
|
||||||
$ticket->save(false);
|
$ticket->save(false);
|
||||||
}
|
}
|
||||||
\Yii::info("$requestId: direction_out: ticket count_move_out set after direction_out in sec " . $stopWatch->split());
|
$ctx->actions[] = "MOVE_OUT";
|
||||||
|
\Yii::info("$ctx->requestId: direction_out: ticket count_move_out set after direction_out in sec " . $stopWatch->split());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$verifyOnly) {
|
if (!$ctx->verifyOnly) {
|
||||||
Card::updateCardFlagTicket($ticket->id_ticket);
|
Card::updateCardFlagTicket($ticket->id_ticket);
|
||||||
\Yii::info("$requestId: updateCardFlagTicket: card flag updated in sec " . $stopWatch->split());
|
\Yii::info("$ctx->requestId: updateCardFlagTicket: card flag updated in sec " . $stopWatch->split());
|
||||||
|
|
||||||
// reload card after flag is set
|
// reload card after flag is set
|
||||||
$card = Card::readCard($cardNumber);
|
$ctx->card = Card::readCard($ctx->cardNumber);
|
||||||
if ($direction == DoorLog::$DIRECTION_OUT_WITHOUT_MOVE || $direction == DoorLog::$DIRECTION_OUT) {
|
if ($ctx->direction == DoorLog::$DIRECTION_OUT_WITHOUT_MOVE || $ctx->direction == DoorLog::$DIRECTION_OUT) {
|
||||||
$card->flag_out = Helper::setBit($card->flag_out, Card::$FLAG_DOOR, true);
|
$ctx->card->flag_out = Helper::setBit($ctx->card->flag_out, Card::$FLAG_DOOR, true);
|
||||||
$card->flag = Helper::setBit($card->flag, Card::$FLAG_DOOR, false);
|
$ctx->card->flag = Helper::setBit($ctx->card->flag, Card::$FLAG_DOOR, false);
|
||||||
$card->save(false);
|
$ctx->card->save(false);
|
||||||
\Yii::info("$requestId: direction_out: Door flag updated in sec " . $stopWatch->split());
|
\Yii::info("$ctx->requestId: direction_out: Door flag updated in sec " . $stopWatch->split());
|
||||||
|
|
||||||
} else if ($direction == DoorLog::$DIRECTION_IN || $direction == DoorLog::$DIRECTION_IN_WITHOUT_MOVE) {
|
} else if ($ctx->direction == DoorLog::$DIRECTION_IN || $ctx->direction == DoorLog::$DIRECTION_IN_WITHOUT_MOVE) {
|
||||||
$card->flag_out = Helper::setBit($card->flag_out, Card::$FLAG_DOOR, false);
|
$ctx->card->flag_out = Helper::setBit($ctx->card->flag_out, Card::$FLAG_DOOR, false);
|
||||||
$card->flag = Helper::setBit($card->flag, Card::$FLAG_DOOR, true);
|
$ctx->card->flag = Helper::setBit($ctx->card->flag, Card::$FLAG_DOOR, true);
|
||||||
$card->save(false);
|
$ctx->card->save(false);
|
||||||
\Yii::info("$requestId: direction_in: Card flag updated in sec " . $stopWatch->split());
|
\Yii::info("$ctx->requestId: direction_in: Card flag updated in sec " . $stopWatch->split());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$stopWatch->stop();
|
$stopWatch->stop();
|
||||||
\Yii::info("$requestId: finished in sec " . $stopWatch->getTotal());
|
\Yii::info("$ctx->requestId: finished in sec " . $stopWatch->getTotal());
|
||||||
\Yii::$app->db->transaction->commit();
|
\Yii::$app->db->transaction->commit();
|
||||||
\Yii::info("$requestId: Commited");
|
\Yii::info("$ctx->requestId: Commited");
|
||||||
|
} catch (FitnessException $fe) {
|
||||||
|
\Yii::$app->db->transaction->rollBack();
|
||||||
|
\Yii::info("$ctx->requestId: rollbacked");
|
||||||
|
throw $fe;
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
\Yii::$app->db->transaction->rollBack();
|
\Yii::$app->db->transaction->rollBack();
|
||||||
\Yii::info("$requestId: rollbacked");
|
\Yii::info("$ctx->requestId: rollbacked");
|
||||||
throw $e;
|
throw new FitnessException(
|
||||||
|
"UNKNOWN_ERROR",
|
||||||
|
FitnessException::UNKNOWN_ERROR,
|
||||||
|
"CUSTOMER_UNKNOWN_ERROR",
|
||||||
|
$ctx,
|
||||||
|
$e
|
||||||
|
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,6 +18,8 @@ use Yii;
|
|||||||
* @property integer $id_user
|
* @property integer $id_user
|
||||||
* @property integer $created_at
|
* @property integer $created_at
|
||||||
* @property integer $updated_at
|
* @property integer $updated_at
|
||||||
|
* @property integer $valid_until_at
|
||||||
|
* @property integer $invalidated_at
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class DoorCardPass extends \yii\db\ActiveRecord
|
class DoorCardPass extends \yii\db\ActiveRecord
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace console\controllers;
|
namespace console\controllers;
|
||||||
|
|
||||||
|
use common\manager\DoorCardPassManager;
|
||||||
use common\models\Card;
|
use common\models\Card;
|
||||||
use /** @noinspection PhpUnusedAliasInspection */
|
use /** @noinspection PhpUnusedAliasInspection */
|
||||||
Yii;
|
Yii;
|
||||||
@ -8,9 +9,11 @@ use yii\console\Controller;
|
|||||||
|
|
||||||
class DoorCardPassController extends Controller{
|
class DoorCardPassController extends Controller{
|
||||||
|
|
||||||
public function actionDenyAllCard( )
|
public function actionHardReset( )
|
||||||
{
|
{
|
||||||
\Yii::$app->db->createCommand(Card::SQL_DENY_DOOR_CARD_PASS())->execute();
|
// \Yii::$app->db->createCommand(Card::SQL_DENY_DOOR_CARD_PASS())->execute();
|
||||||
|
$manager = new DoorCardPassManager();
|
||||||
|
$manager->hardReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function actionAllowAllCard( )
|
public function actionAllowAllCard( )
|
||||||
@ -18,12 +21,10 @@ class DoorCardPassController extends Controller{
|
|||||||
\Yii::$app->db->createCommand(Card::SQL_ALLOW_DOOR_CARD_PASS())->execute();
|
\Yii::$app->db->createCommand(Card::SQL_ALLOW_DOOR_CARD_PASS())->execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function actionDenyExpiredCard( )
|
public function actionInvalidate( )
|
||||||
{
|
{
|
||||||
$now = date('Y-m-d H:i:s' );
|
$manager = new DoorCardPassManager();
|
||||||
$now = time();
|
$manager->updateDoorCardPassStateForAllCard();
|
||||||
\Yii::$app->db->createCommand(Card::SQL_DENY_DOOR_CARD_PASS_EXPIRED() ,['datetime'=> $now] )
|
|
||||||
->execute();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use yii\db\Migration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class m230126_202055_create_table_door_card_pass
|
||||||
|
*/
|
||||||
|
class m230209_200000_alter_table_door_card_pass_add_column_valid_until extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function safeUp()
|
||||||
|
{
|
||||||
|
$this->addColumn("door_card_pass","valid_until_at",$this->dateTime());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function safeDown()
|
||||||
|
{
|
||||||
|
echo "m230126_202055_create_table_door_card_pass cannot be reverted.\n";
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Use up()/down() to run migration code without a transaction.
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
echo "m230126_202055_create_table_door_card_pass cannot be reverted.\n";
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use yii\db\Migration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class m230126_202055_create_table_door_card_pass
|
||||||
|
*/
|
||||||
|
class m230209_200010_alter_table_door_card_pass_add_column_invalidated_at extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function safeUp()
|
||||||
|
{
|
||||||
|
$this->addColumn("door_card_pass","invalidated_at",$this->dateTime());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function safeDown()
|
||||||
|
{
|
||||||
|
echo "m230126_202055_create_table_door_card_pass cannot be reverted.\n";
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Use up()/down() to run migration code without a transaction.
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
echo "m230126_202055_create_table_door_card_pass cannot be reverted.\n";
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
@ -1 +1,2 @@
|
|||||||
FITNESS_REST_ALLOW_VERIFY_ONLY=true
|
FITNESS_REST_ALLOW_VERIFY_ONLY=true
|
||||||
|
DOOR_ENTRY_STRATEGY=door_pass
|
||||||
@ -22,7 +22,8 @@ services:
|
|||||||
FITNESS_MAIL_PORT: 1025
|
FITNESS_MAIL_PORT: 1025
|
||||||
FITNESS_MAIL_USERNAME: test
|
FITNESS_MAIL_USERNAME: test
|
||||||
FITNESS_MAIL_PASSWORD: test
|
FITNESS_MAIL_PASSWORD: test
|
||||||
FITNESS_REST_ALLOW_VERIFY_ONLY: $FITNESS_REST_ALLOW_VERIFY_ONLY
|
FITNESS_REST_ALLOW_VERIFY_ONLY: "$FITNESS_REST_ALLOW_VERIFY_ONLY"
|
||||||
|
DOOR_ENTRY_STRATEGY: "$DOOR_ENTRY_STRATEGY"
|
||||||
|
|
||||||
cutlerdb:
|
cutlerdb:
|
||||||
image: mariadb:10.1
|
image: mariadb:10.1
|
||||||
|
|||||||
@ -2,18 +2,17 @@
|
|||||||
|
|
||||||
namespace frontend\controllers;
|
namespace frontend\controllers;
|
||||||
|
|
||||||
|
use common\components\DateUtil;
|
||||||
|
use common\components\Helper;
|
||||||
|
use common\manager\DoorCardPassManager;
|
||||||
use common\models\Card;
|
use common\models\Card;
|
||||||
use common\models\DoorCardPass;
|
use common\models\DoorCardPass;
|
||||||
use Yii;
|
use Yii;
|
||||||
use common\models\City;
|
use common\models\City;
|
||||||
use backend\models\CitySearch;
|
|
||||||
use yii\web\BadRequestHttpException;
|
use yii\web\BadRequestHttpException;
|
||||||
use yii\web\Controller;
|
use yii\web\Controller;
|
||||||
use yii\web\NotFoundHttpException;
|
use yii\web\NotFoundHttpException;
|
||||||
use yii\filters\VerbFilter;
|
use yii\filters\VerbFilter;
|
||||||
use yii\base\BaseObject;
|
|
||||||
use yii\db\Query;
|
|
||||||
use yii\helpers\Json;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CityController implements the CRUD actions for City model.
|
* CityController implements the CRUD actions for City model.
|
||||||
@ -39,11 +38,12 @@ class DoorCardPassController extends Controller
|
|||||||
if (!isset($card)){
|
if (!isset($card)){
|
||||||
throw new BadRequestHttpException("card id not found");
|
throw new BadRequestHttpException("card id not found");
|
||||||
}
|
}
|
||||||
$model = new DoorCardPass();
|
|
||||||
$model->id_card = $idCard;
|
|
||||||
$model->save(false);
|
|
||||||
|
|
||||||
$this->redirect('customer/reception');
|
$doorCardPassManager = new DoorCardPassManager();
|
||||||
|
$doorCardPassManager->createNewDoorCardPass($idCard);
|
||||||
|
$doorCardPassManager->updateDoorCardPassStateForCard($idCard);
|
||||||
|
|
||||||
|
$this->redirect(['customer/reception', 'number' => $card->number]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -10,8 +10,53 @@ use frontend\components\HtmlHelper;
|
|||||||
/* @var $model frontend\models\ReceptionForm */
|
/* @var $model frontend\models\ReceptionForm */
|
||||||
/* @var $form yii\widgets\ActiveForm */
|
/* @var $form yii\widgets\ActiveForm */
|
||||||
?>
|
?>
|
||||||
<?php $form = ActiveForm::begin([
|
<?php
|
||||||
'action' => ['door-card-pass/allow', 'number' => $model->getCardNumber()],
|
|
||||||
|
if (! ( isset($model) && isset($model->card))){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$activeCardPasses = \common\models\DoorCardPass::find()
|
||||||
|
->andWhere(
|
||||||
|
[
|
||||||
|
'id_card' => $model->card->id_card,
|
||||||
|
'invalidated_at' => null ,
|
||||||
|
|
||||||
|
// [ '>=', $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];
|
||||||
|
?>
|
||||||
|
<div>
|
||||||
|
<?php
|
||||||
|
echo "Forgó kapun beléphet eddig: " ;
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
?>
|
||||||
|
<div>
|
||||||
|
<?php
|
||||||
|
echo $cardPass->valid_until_at ;
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}else {
|
||||||
|
?>
|
||||||
|
<div>
|
||||||
|
Nincs érvényes forgó kapu belépő
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$form = ActiveForm::begin([
|
||||||
|
'action' => ['door-card-pass/allow-card', 'idCard' => $model->card->id_card],
|
||||||
'method' => 'post',
|
'method' => 'post',
|
||||||
]); ?>
|
]); ?>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user