door manager
This commit is contained in:
parent
fb39d6599e
commit
946799a598
@ -8,7 +8,6 @@ use backend\models\CitySearch;
|
|||||||
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\Object;
|
|
||||||
use yii\db\Query;
|
use yii\db\Query;
|
||||||
use yii\helpers\Json;
|
use yii\helpers\Json;
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,6 @@ use backend\models\CitySearch;
|
|||||||
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\Object;
|
|
||||||
use yii\db\Query;
|
use yii\db\Query;
|
||||||
use yii\helpers\Json;
|
use yii\helpers\Json;
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,6 @@ use yii\filters\AccessControl;
|
|||||||
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\Object;
|
|
||||||
use backend\models\CustomerUpdate;
|
use backend\models\CustomerUpdate;
|
||||||
use backend\models\CustomerNewsLetterModel;
|
use backend\models\CustomerNewsLetterModel;
|
||||||
use yii\db\Query;
|
use yii\db\Query;
|
||||||
|
|||||||
@ -9,7 +9,6 @@ use backend\models\UserCreate;
|
|||||||
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\Object;
|
|
||||||
use backend\models\UserUpdate;
|
use backend\models\UserUpdate;
|
||||||
use common\models\Account;
|
use common\models\Account;
|
||||||
use common\models\UserAccountAssignment;
|
use common\models\UserAccountAssignment;
|
||||||
|
|||||||
@ -18,6 +18,12 @@ use yii\i18n\Formatter;
|
|||||||
|
|
||||||
class DateUtil
|
class DateUtil
|
||||||
{
|
{
|
||||||
|
public static function fromUnixTimeStamp($timestamp){
|
||||||
|
$dt = DateUtil::utcDate();
|
||||||
|
$dt->setTimestamp($timestamp);
|
||||||
|
return $dt;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get UTC today @00:00:00 .
|
* Get UTC today @00:00:00 .
|
||||||
* Helper method to generate date for mysql
|
* Helper method to generate date for mysql
|
||||||
@ -25,13 +31,49 @@ class DateUtil
|
|||||||
* @return DateTime
|
* @return DateTime
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static function todayStart( ){
|
public static function todayStart(){
|
||||||
$d2 = new DateTime();
|
$d2 = new DateTime();
|
||||||
|
return DateUtil::utcDate($d2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $date \DateTime optional. The date to set as utc date. If not set, new DateTime() will be used
|
||||||
|
* @return DateTime the datetime object with time reset and utc timezone
|
||||||
|
*/
|
||||||
|
public static function utcDate($date = null){
|
||||||
|
$d2 = isset($date ) ? $date : new DateTime();
|
||||||
|
$d2 = DateUtil::withTimeZoneUTC($d2);
|
||||||
|
return DateUtil::resetTime($d2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $date \DateTime optional. If not set,defaults to : new DateTime() .
|
||||||
|
* @return DateTime
|
||||||
|
*/
|
||||||
|
public static function utcDateTime($date = null){
|
||||||
|
$d2 = isset($date ) ? $date : new DateTime();
|
||||||
|
return DateUtil::withTimeZoneUTC($d2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $date \DateTime
|
||||||
|
* @return DateTime
|
||||||
|
*/
|
||||||
|
public static function withTimeZoneUTC( $date = null){
|
||||||
|
$d2 = isset($date ) ? $date : new DateTime();
|
||||||
$d2->setTimezone( new DateTimeZone('UTC') );
|
$d2->setTimezone( new DateTimeZone('UTC') );
|
||||||
$d2->setTime(0, 0);
|
|
||||||
return $d2;
|
return $d2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $dateTime \DateTime
|
||||||
|
* @return \DateTime
|
||||||
|
*/
|
||||||
|
public static function resetTime($dateTime){
|
||||||
|
$dateTime->setTime(0, 0);
|
||||||
|
return $dateTime;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get UTC t @00:00:00 .
|
* Get UTC t @00:00:00 .
|
||||||
* Helper method to generate date for mysql
|
* Helper method to generate date for mysql
|
||||||
@ -39,16 +81,12 @@ class DateUtil
|
|||||||
* @return DateTime
|
* @return DateTime
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static function tomorrowStart( ){
|
public static function tomorrowStart( $date = null){
|
||||||
$d2 = new DateTime();
|
$d2 = isset($date) ? $date : new DateTime();
|
||||||
$d2->add(new DateInterval('P1D'));
|
$d2->add(new DateInterval('P1D'));
|
||||||
$d2->setTimezone( new DateTimeZone('UTC') );
|
return DateUtil::utcDate($d2);
|
||||||
$d2->setTime(0, 0);
|
|
||||||
return $d2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static function addMonth($timestamp, $monthCount = 1)
|
public static function addMonth($timestamp, $monthCount = 1)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -99,7 +137,7 @@ class DateUtil
|
|||||||
* @return string
|
* @return string
|
||||||
* @throws InvalidConfigException
|
* @throws InvalidConfigException
|
||||||
*/
|
*/
|
||||||
public static function formatUtc($dateTimeObject)
|
public static function formatDateTimeUtc($dateTimeObject)
|
||||||
{
|
{
|
||||||
$formatter = new Formatter;
|
$formatter = new Formatter;
|
||||||
$formatter->datetimeFormat = 'php:Y-m-d H:i:s';
|
$formatter->datetimeFormat = 'php:Y-m-d H:i:s';
|
||||||
@ -127,6 +165,10 @@ class DateUtil
|
|||||||
return $date;
|
return $date;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function parseDateTime($dateTimeString){
|
||||||
|
return DateTime::createFromFormat('Y-m-d H:i:s', $dateTimeString, new DateTimeZone( 'UTC'));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param integer $weekDay Numeric representation of the day of the week. @See https://www.php.net/manual/en/function.date.php
|
* @param integer $weekDay Numeric representation of the day of the week. @See https://www.php.net/manual/en/function.date.php
|
||||||
* @return string
|
* @return string
|
||||||
|
|||||||
352
common/manager/DoorManager.php
Normal file
352
common/manager/DoorManager.php
Normal file
@ -0,0 +1,352 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace common\manager;
|
||||||
|
|
||||||
|
use common\components\DateUtil;
|
||||||
|
use common\components\Helper;
|
||||||
|
use common\models\Card;
|
||||||
|
use common\models\CardEventRegistrationForm;
|
||||||
|
use common\models\Customer;
|
||||||
|
use common\models\DoorLog;
|
||||||
|
use common\models\DoorLogForTest;
|
||||||
|
use common\models\Event;
|
||||||
|
use common\models\EventRegistration;
|
||||||
|
use common\models\Log;
|
||||||
|
use common\models\MobileDevice;
|
||||||
|
use common\models\Ticket;
|
||||||
|
use customerapi\models\available\EventInterval;
|
||||||
|
use customerapi\models\registrations\EventRegistrationAvailable;
|
||||||
|
use customerapi\models\details\EventRegistrationView;
|
||||||
|
use Exception;
|
||||||
|
use Yii;
|
||||||
|
use yii\base\BaseObject;
|
||||||
|
use yii\db\ActiveRecord;
|
||||||
|
use yii\db\Query;
|
||||||
|
use yii\web\BadRequestHttpException;
|
||||||
|
use yii\web\NotFoundHttpException;
|
||||||
|
use yii\web\ServerErrorHttpException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by IntelliJ IDEA.
|
||||||
|
* User: rocho
|
||||||
|
* Date: 2018.12.17.
|
||||||
|
* Time: 6:12
|
||||||
|
*/
|
||||||
|
class DoorManager extends BaseObject
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $cardNumber
|
||||||
|
* @param $device
|
||||||
|
* @param $direction
|
||||||
|
* @param $createdAt number unix timestamp , override createdAt for doorLogs
|
||||||
|
* @param $date number unix timestamp, override date for validation check 'now'
|
||||||
|
* @return void
|
||||||
|
* @throws BadRequestHttpException
|
||||||
|
* @throws \yii\base\InvalidConfigException
|
||||||
|
*/
|
||||||
|
public function move($cardNumber, $device, $direction, $createdAt = null, $date = null )
|
||||||
|
{
|
||||||
|
if ( isset($createdAt)){
|
||||||
|
$createdAt = DateUtil::parseDateTime($createdAt);
|
||||||
|
}else{
|
||||||
|
$createdAt = DateUtil::utcDateTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
$createdAtStr = DateUtil::formatDateTimeUtc($createdAt);
|
||||||
|
|
||||||
|
if ( isset($date)){
|
||||||
|
$date = DateUtil::parseDateTime($date);
|
||||||
|
}else{
|
||||||
|
$date = DateUtil::utcDate();
|
||||||
|
}
|
||||||
|
|
||||||
|
$dateStr = DateUtil::formatDateUtc($date);
|
||||||
|
|
||||||
|
$doorLog = new DoorLog();
|
||||||
|
$doorLog->direction = $direction;
|
||||||
|
$doorLog->source_app = $device;
|
||||||
|
$doorLog->created_at = $createdAtStr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* emergency- no card needed
|
||||||
|
*/
|
||||||
|
if ($direction == DoorLog::$DIRECTION_ALL_EMERGENCY) {
|
||||||
|
$doorLog->save(false);
|
||||||
|
Log::log(
|
||||||
|
[
|
||||||
|
'type' => Log::$TYPE_INFO,
|
||||||
|
'message' => 'Ajtó nyitás: vészhelyzet',
|
||||||
|
'id_door_log' => $doorLog->id_door_log
|
||||||
|
]
|
||||||
|
);
|
||||||
|
\Yii::$app->response->statusCode = 204;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$card = Card::readCard(Helper::fixAsciiChars($cardNumber));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* in any other cases, the door needs a card
|
||||||
|
*/
|
||||||
|
if (!isset($card)) {
|
||||||
|
throw new BadRequestHttpException('Card not found with number: ' . $cardNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
$doorLog->id_card = $card->id_card;
|
||||||
|
$doorLog->card_flag = $card->flag;
|
||||||
|
/**
|
||||||
|
* if the card type is employee, neither customer nor ticket is needed.
|
||||||
|
* Free to enter/leave
|
||||||
|
*/
|
||||||
|
if ($card->type == Card::TYPE_EMPLOYEE) {
|
||||||
|
$doorLog->save(false);
|
||||||
|
\Yii::$app->response->statusCode = 204;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//otherwise ticket is required
|
||||||
|
$activeTickets = Ticket::readActive($card, clone $date);
|
||||||
|
\Yii::error('active ticket count:' . count($activeTickets));
|
||||||
|
$ticket = null;
|
||||||
|
if (isset($activeTickets) && count($activeTickets) > 0) {
|
||||||
|
$ticket = $activeTickets[0];
|
||||||
|
}
|
||||||
|
$doorLog->id_ticket_current = $ticket->id_ticket;
|
||||||
|
|
||||||
|
if (!isset($ticket)) {
|
||||||
|
throw new BadRequestHttpException("No active ticket found for:" . $card->number);
|
||||||
|
}
|
||||||
|
\Yii::error("active ticket: " . $ticket->id_ticket);
|
||||||
|
|
||||||
|
// customer is also required
|
||||||
|
$customer = $card->customer;
|
||||||
|
if (!isset($customer)) {
|
||||||
|
throw new BadRequestHttpException("Customer not found for:" . $card->number);
|
||||||
|
}
|
||||||
|
|
||||||
|
$doorLog->id_customer = $customer->id_customer;
|
||||||
|
|
||||||
|
// save the door log
|
||||||
|
$doorLog->save(false);
|
||||||
|
|
||||||
|
|
||||||
|
// if direction is in
|
||||||
|
if ($direction == DoorLog::$DIRECTION_IN || $direction == DoorLog::$DIRECTION_IN_WITHOUT_MOVE) {
|
||||||
|
$countDoorLogsForTicketSince = $this->getCountDoorLogsForTicketSince($ticket->id_ticket, DateUtil::utcDate( clone $date));
|
||||||
|
// if the current event is the first door log today
|
||||||
|
if ($countDoorLogsForTicketSince == 1) {
|
||||||
|
// increase the ticket usage count with 1
|
||||||
|
$usageCount = $ticket->usage_count;
|
||||||
|
$ticket->usage_count += 1;
|
||||||
|
$ticket->save(false);
|
||||||
|
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
|
||||||
|
]
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
$startOfDay = DateUtil::utcDate(clone $date);
|
||||||
|
$startOfTomorrow = DateUtil::tomorrowStart(clone $date);
|
||||||
|
|
||||||
|
$allDoorLogToday = DoorLog::find()
|
||||||
|
->andWhere(['>=', 'door_log.created_at', DateUtil::formatDateUtc($startOfDay)])
|
||||||
|
->andWhere(['<', 'door_log.created_at', DateUtil::formatDateUtc($startOfTomorrow)])
|
||||||
|
->andWhere(['id_ticket_current' => $ticket->id_ticket])
|
||||||
|
->andWhere(['in', 'direction', [DoorLog::$DIRECTION_IN_WITHOUT_MOVE, DoorLog::$DIRECTION_IN]])
|
||||||
|
->orderBy(['door_log.created_at' => SORT_ASC])
|
||||||
|
->all();
|
||||||
|
|
||||||
|
\Yii::error("new door log: ".$doorLog->id_door_log.";".$doorLog->created_at.";".$doorLog->type);
|
||||||
|
foreach ($allDoorLogToday as $log){
|
||||||
|
\Yii::error("all log: ".$log->id_door_log.";".$log->created_at.";".$log->type);
|
||||||
|
}
|
||||||
|
|
||||||
|
$firstInToday = $allDoorLogToday[0];
|
||||||
|
|
||||||
|
if (isset($firstInToday)) {
|
||||||
|
|
||||||
|
$firstEntryDateTimeToday = DateUtil::parseDateTime($firstInToday->created_at);
|
||||||
|
|
||||||
|
$interval = \DateInterval::createFromDateString('3 hours');
|
||||||
|
$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,$createdAt);
|
||||||
|
if ( !isset($activeInterval)){
|
||||||
|
throw new ServerErrorHttpException("Active Interval not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
$logCountInActiveInterval = count($activeInterval['logs']);
|
||||||
|
|
||||||
|
if ( $logCountInActiveInterval == 1){
|
||||||
|
$ticket->usage_count = $ticket->usage_count+1;
|
||||||
|
$ticket->save(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// select min(created_at) + INTERVAL (3 * FLOOR( ( ( HOUR( TIMEDIFF( min(created_at) , now() ) ) /3 ) ) ) ) hour as last_date
|
||||||
|
// into @p_from
|
||||||
|
// from door_log
|
||||||
|
// where created_at > CURDATE() and id_customer is not null and id_ticket_current = NEW.id_ticket_current and ( direction = 7 or direction = 3);
|
||||||
|
|
||||||
|
|
||||||
|
// select count(*) into @p_count_all_2 from door_log where created_at >= @p_from and id_ticket_current = New.id_ticket_current and ( direction = 7 or direction = 3);
|
||||||
|
|
||||||
|
// INSERT INTO devlog ( msg) values(CONCAT( 'Bel<65>p<EFBFBD>sek sz<73>ma az aktu<74>lis 3 <20>r<EFBFBD>s intervalumban: ', @p_count_all_2) );
|
||||||
|
|
||||||
|
|
||||||
|
// IF @p_count_all_2 = 1
|
||||||
|
// THEN
|
||||||
|
// INSERT INTO devlog ( msg) values( 'Az aktu<74>lis intervallumban ez az els? bel<65>p<EFBFBD>s, usage_count n<>vel<65>se' );
|
||||||
|
//
|
||||||
|
// select usage_count, max_usage_count into @p_usage_count ,@p_max_usage_count from ticket where id_ticket = NEW.id_ticket_current;
|
||||||
|
//
|
||||||
|
// update ticket set usage_count = usage_count +1 where id_ticket = New.id_ticket_current;
|
||||||
|
//
|
||||||
|
// INSERT INTO log (type,message, app, id_ticket, id_door_log,created_at, updated_at)
|
||||||
|
// values(
|
||||||
|
// 40, concat('B<>rlet haszn<7A>lat/egy nap tobbszori (elotte: ',@p_usage_count, ' > utana: ' , @p_usage_count +1 , ' max: ', @p_max_usage_count, ')' ), ' trigger_inc_ticket',New.id_ticket_current, New.id_door_log,now(),now());
|
||||||
|
// END IF;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
\Yii::error("finished");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCountDoorLogsForTicketSince($idTicket, $since)
|
||||||
|
{
|
||||||
|
\Yii::error("getting door log count for today");
|
||||||
|
return DoorLog::find()
|
||||||
|
->innerJoinWith('card')
|
||||||
|
->andWhere(['card.id_ticket_current' => $idTicket])
|
||||||
|
->andWhere(['in', 'door_log.direction', [DoorLog::$DIRECTION_IN, DoorLog::$DIRECTION_IN_WITHOUT_MOVE]])
|
||||||
|
->andWhere(['>=', 'door_log.created_at', DateUtil::formatDateUtc($since)])
|
||||||
|
->count();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function readActive($cardNumber)
|
||||||
|
{
|
||||||
|
$card = Card::readCard($cardNumber);
|
||||||
|
return Ticket::readActive($card);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function resetLogs($cardNumber)
|
||||||
|
{
|
||||||
|
$card = Card::readCard($cardNumber);
|
||||||
|
DoorLog::deleteAll(
|
||||||
|
['id_card' => $card->id_card]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 createDoorLog($direction, $idCard, $idTicket, $createdAt)
|
||||||
|
// {
|
||||||
|
// $doorLog = new DoorLog();
|
||||||
|
// $doorLog->id_card = $idCard;
|
||||||
|
// $doorLog->direction = $direction;
|
||||||
|
// $doorLog->id_ticket_current = $idTicket;
|
||||||
|
//
|
||||||
|
// $doorLog->save(false);
|
||||||
|
// // update the created at flag
|
||||||
|
// \Yii::$app->db->createCommand('update door_log set created_at = :created_at where id_door_log = :id ')
|
||||||
|
// ->bindValue("created_at", $createdAt)
|
||||||
|
// ->bindValue("id", $doorLog->id_door_log)
|
||||||
|
// ->execute();
|
||||||
|
// }
|
||||||
|
|
||||||
|
public function createLog()
|
||||||
|
{
|
||||||
|
\Yii::error("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::error("Door log saving:".$log->created_at);
|
||||||
|
$log->save(false);
|
||||||
|
return $log;
|
||||||
|
}else{
|
||||||
|
throw new BadRequestHttpException(print_r($log->getErrors(),true));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
\Yii::error("validated" . print_r($log->errors, true));
|
||||||
|
throw new BadRequestHttpException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new BadRequestHttpException('Not a Post');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -26,8 +26,24 @@ use yii\helpers\ArrayHelper;
|
|||||||
class DoorLog extends \yii\db\ActiveRecord
|
class DoorLog extends \yii\db\ActiveRecord
|
||||||
{
|
{
|
||||||
|
|
||||||
public static $SOURCE_APP_FORGO_VILLA = "forgo_villa";
|
public static $SOURCE_APP_FORGO_VILLA = "forgo_villa";
|
||||||
public static $SOURCE_APP_FITNESS_ADMIN = "fitness_admin";
|
public static $SOURCE_APP_FITNESS_ADMIN = "fitness_admin";
|
||||||
|
|
||||||
|
|
||||||
|
public static $DIRECTION_OUT_MANUAL_READ_KEY_ASSIGNED = -2; // "Kézi olvasás/Kulcs ki",
|
||||||
|
public static $DIRECTION_IN_MANUAL_READ_KEY_UNASSIGNED = -1; // "Kézi olvasás/Kulcs vissza",
|
||||||
|
public static $DIRECTION_ALL_MANUAL_READ = 0; // "Kézi olvasás",
|
||||||
|
public static $DIRECTION_OUT_WITHOUT_MOVE = 1; // "KI olvastatás mozgás nélkül",
|
||||||
|
public static $DIRECTION_IN_WITHOUT_MOVE = 3; // "BE olvastatás mozgás nélkül",
|
||||||
|
public static $DIRECTION_OUT_ = 5; // "KI mozgás",
|
||||||
|
public static $DIRECTION_IN = 7; // "BE mozgás",
|
||||||
|
public static $DIRECTION_OUT_ERROR_KEY_ASSIGNED = 9; // "KI olvastatás, van érvényes öltöző kulcs (nem enged)",
|
||||||
|
public static $DIRECTION_IN_ERROR_KEY_MISSING = 11; // "BE olvastatás, nincs érvényes öltöző kulcs (nem enged)",
|
||||||
|
public static $DIRECTION_OUT_NO_TICKET = 17; // "Bérlet érvényességi időn kívüli KI olvastatás (nem enged)",
|
||||||
|
public static $DIRECTION_IN_NO_TICKET = 19; // "Bérlet érvényességi időn kívüli BE olvastatás (nem enged)",
|
||||||
|
public static $DIRECTION_ALL_EMERGENCY = 128; // "Vésznyitás",
|
||||||
|
public static $DIRECTION_ALL_CARD_BLOCKED = 256; // "Kártya tiltva -> információ mező",
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
@ -38,13 +54,18 @@ class DoorLog extends \yii\db\ActiveRecord
|
|||||||
|
|
||||||
public function behaviors()
|
public function behaviors()
|
||||||
{
|
{
|
||||||
return ArrayHelper::merge( [
|
return ArrayHelper::merge([
|
||||||
[
|
[
|
||||||
'class' => TimestampBehavior::className(),
|
'class' => TimestampBehavior::className(),
|
||||||
'value' => function(){ return date('Y-m-d H:i:s' ); },
|
'value' => function ($event) {
|
||||||
'updatedAtAttribute' => false,
|
if ( isset($event->sender->created_at) ){
|
||||||
]
|
return $event->sender->created_at;
|
||||||
], parent::behaviors());
|
}
|
||||||
|
return date('Y-m-d H:i:s');
|
||||||
|
},
|
||||||
|
'updatedAtAttribute' => false,
|
||||||
|
]
|
||||||
|
], parent::behaviors());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -76,132 +97,146 @@ class DoorLog extends \yii\db\ActiveRecord
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getCustomer(){
|
public function getCustomer()
|
||||||
return $this->hasOne( Customer::className(), ["id_customer" =>"id_customer" ] );
|
{
|
||||||
|
return $this->hasOne(Customer::className(), ["id_customer" => "id_customer"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getCustomerName(){
|
public function getCustomerName()
|
||||||
$result = "";
|
{
|
||||||
if (isset($this->customer)){
|
$result = "";
|
||||||
$result = $this->customer->name;
|
if (isset($this->customer)) {
|
||||||
}
|
$result = $this->customer->name;
|
||||||
return $result;
|
}
|
||||||
}
|
return $result;
|
||||||
public function getCard(){
|
|
||||||
return $this->hasOne( Card::className(), ["id_card" =>"id_card" ] );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getCardNumber(){
|
public function getCard()
|
||||||
$result = "";
|
{
|
||||||
if (isset($this->card)){
|
return $this->hasOne(Card::className(), ["id_card" => "id_card"]);
|
||||||
$result = $this->card->number;
|
|
||||||
}
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
public function getKey(){
|
|
||||||
return $this->hasOne( Key::className(), ["id_key" =>"id_key" ] );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getKeyNumber(){
|
public function getCardNumber()
|
||||||
$result = "";
|
{
|
||||||
if (isset($this->key)){
|
$result = "";
|
||||||
$result = $this->key->number;
|
if (isset($this->card)) {
|
||||||
}
|
$result = $this->card->number;
|
||||||
return $result;
|
}
|
||||||
|
return $result;
|
||||||
}
|
}
|
||||||
public function getDirectionName(){
|
|
||||||
$result = "";
|
public function getKey()
|
||||||
if ( $this->source_app == 'forgo_villa'){
|
{
|
||||||
if (isset($this->direction)){
|
return $this->hasOne(Key::className(), ["id_key" => "id_key"]);
|
||||||
$result = Helper::getArrayValue(self::getDirectionTypes() , $this->direction, "-");
|
}
|
||||||
}
|
|
||||||
}else{
|
public function getKeyNumber()
|
||||||
$result = "Kézi olvasás";
|
{
|
||||||
}
|
$result = "";
|
||||||
return $result;
|
if (isset($this->key)) {
|
||||||
|
$result = $this->key->number;
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDirectionName()
|
||||||
|
{
|
||||||
|
$result = "";
|
||||||
|
if ($this->source_app == 'forgo_villa') {
|
||||||
|
if (isset($this->direction)) {
|
||||||
|
$result = Helper::getArrayValue(self::getDirectionTypes(), $this->direction, "-");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$result = "Kézi olvasás";
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static function getSourceAppName($source_app){
|
public static function getSourceAppName($source_app)
|
||||||
$result = "";
|
{
|
||||||
switch ($source_app){
|
$result = "";
|
||||||
case self::$SOURCE_APP_FITNESS_ADMIN :
|
switch ($source_app) {
|
||||||
$result = "Recepciós alkalmazás";
|
case self::$SOURCE_APP_FITNESS_ADMIN :
|
||||||
break;
|
$result = "Recepciós alkalmazás";
|
||||||
case self::$SOURCE_APP_FORGO_VILLA:
|
break;
|
||||||
$result = "Forgó villa";
|
case self::$SOURCE_APP_FORGO_VILLA:
|
||||||
break;
|
$result = "Forgó villa";
|
||||||
}
|
break;
|
||||||
return $result;
|
}
|
||||||
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getDirectionTypes( ){
|
public static function getDirectionTypes()
|
||||||
return [
|
{
|
||||||
-2 => "Kézi olvasás/Kulcs ki",
|
return [
|
||||||
-1 => "Kézi olvasás/Kulcs vissza",
|
-2 => "Kézi olvasás/Kulcs ki",
|
||||||
0 => "Kézi olvasás",
|
-1 => "Kézi olvasás/Kulcs vissza",
|
||||||
|
0 => "Kézi olvasás",
|
||||||
|
|
||||||
1 => "KI olvastatás mozgás nélkül",
|
1 => "KI olvastatás mozgás nélkül",
|
||||||
|
|
||||||
3 => "BE olvastatás mozgás nélkül",
|
3 => "BE olvastatás mozgás nélkül",
|
||||||
|
|
||||||
5 => "KI mozgás",
|
5 => "KI mozgás",
|
||||||
|
|
||||||
7 => "BE mozgás",
|
7 => "BE mozgás",
|
||||||
|
|
||||||
9 => "KI olvastatás, van érvényes öltöző kulcs (nem enged)",
|
9 => "KI olvastatás, van érvényes öltöző kulcs (nem enged)",
|
||||||
|
|
||||||
11 => "BE olvastatás, nincs érvényes öltöző kulcs (nem enged)",
|
11 => "BE olvastatás, nincs érvényes öltöző kulcs (nem enged)",
|
||||||
|
|
||||||
17 => "Bérlet érvényességi időn kívüli KI olvastatás (nem enged)",
|
17 => "Bérlet érvényességi időn kívüli KI olvastatás (nem enged)",
|
||||||
|
|
||||||
19 => "Bérlet érvényességi időn kívüli BE olvastatás (nem enged)",
|
19 => "Bérlet érvényességi időn kívüli BE olvastatás (nem enged)",
|
||||||
|
|
||||||
128 => "Vésznyitás",
|
128 => "Vésznyitás",
|
||||||
256 => "Kártya tiltva -> információ mező",
|
256 => "Kártya tiltva -> információ mező",
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getCardFlagTexts( ){
|
public static function getCardFlagTexts()
|
||||||
return [
|
{
|
||||||
0 => "Kártya érvényes bérlettel",
|
return [
|
||||||
1 => "Nincs érvényes bérlet",
|
0 => "Kártya érvényes bérlettel",
|
||||||
2 => "Kártya inaktív/Érvényes bérlet",
|
1 => "Nincs érvényes bérlet",
|
||||||
3 => "Kártya inaktív/Nincs érvényes bérlet"
|
2 => "Kártya inaktív/Érvényes bérlet",
|
||||||
|
3 => "Kártya inaktív/Nincs érvényes bérlet"
|
||||||
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function mkDoorLog($direction,$card,$customer = null,$key = null){
|
public static function mkDoorLog($direction, $card, $customer = null, $key = null)
|
||||||
|
{
|
||||||
|
|
||||||
if ( !Helper::isKeyToggleDoorLogEnabled() ){
|
if (!Helper::isKeyToggleDoorLogEnabled()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$dlog = new DoorLog();
|
$dlog = new DoorLog();
|
||||||
$dlog->id_card = $card->id_card;
|
$dlog->id_card = $card->id_card;
|
||||||
|
|
||||||
if ( isset($customer)){
|
if (isset($customer)) {
|
||||||
$dlog->id_customer = $customer->id_customer;
|
$dlog->id_customer = $customer->id_customer;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( isset($key)){
|
if (isset($key)) {
|
||||||
$dlog->id_key = $key->id_key;
|
$dlog->id_key = $key->id_key;
|
||||||
}
|
}
|
||||||
$dlog->direction = $direction;
|
$dlog->direction = $direction;
|
||||||
$dlog->type = $card->type;
|
$dlog->type = $card->type;
|
||||||
$dlog->source_app = DoorLog::$SOURCE_APP_FITNESS_ADMIN;
|
$dlog->source_app = DoorLog::$SOURCE_APP_FITNESS_ADMIN;
|
||||||
|
|
||||||
$dlog->id_account = Account::readDefault();
|
$dlog->id_account = Account::readDefault();
|
||||||
|
|
||||||
if ( $dlog->direction == 0){
|
if ($dlog->direction == 0) {
|
||||||
$dlog->card_flag = $card->validity;
|
$dlog->card_flag = $card->validity;
|
||||||
}else{
|
} else {
|
||||||
$dlog->card_flag = -1;
|
$dlog->card_flag = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
$dlog->created_at = date('Y-m-d H:i:s');
|
$dlog->created_at = date('Y-m-d H:i:s');
|
||||||
$dlog->save(false);
|
$dlog->save(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
49
common/models/DoorLogForTest.php
Normal file
49
common/models/DoorLogForTest.php
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace common\models;
|
||||||
|
|
||||||
|
use Yii;
|
||||||
|
use common\components\Helper;
|
||||||
|
use yii\behaviors\TimestampBehavior;
|
||||||
|
use yii\helpers\ArrayHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the model class for table "door_log".
|
||||||
|
*
|
||||||
|
* @property integer $id_door_log
|
||||||
|
* @property integer $id_card
|
||||||
|
* @property integer $id_customer
|
||||||
|
* @property integer $id_key
|
||||||
|
* @property integer $direction
|
||||||
|
* @property integer $type
|
||||||
|
* @property integer $id_account
|
||||||
|
* @property string $created_at
|
||||||
|
* @property string $source_app
|
||||||
|
* @property integer id_ticket_current
|
||||||
|
* @property integer card_flag
|
||||||
|
* @property integer flag_out
|
||||||
|
*/
|
||||||
|
class DoorLogForTest extends DoorLog
|
||||||
|
{
|
||||||
|
|
||||||
|
public function behaviors()
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[
|
||||||
|
['id_card', 'id_customer', 'id_key', 'direction', 'type', 'id_ticket_current'], 'integer'
|
||||||
|
],
|
||||||
|
|
||||||
|
[['created_at'], 'string'],
|
||||||
|
[['created_at'], 'required'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
138
doc/trigger.sql
Normal file
138
doc/trigger.sql
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
CREATE TRIGGER trigger_inc_ticket_usage_count AFTER INSERT ON `door_log` FOR EACH ROW
|
||||||
|
begin
|
||||||
|
|
||||||
|
DECLARE p_count_all Integer;
|
||||||
|
DECLARE p_count_all_2 Integer;
|
||||||
|
DECLARE p_from DATETIME;
|
||||||
|
DECLARE p_usage_count Integer;
|
||||||
|
DECLARE p_max_usage_count Integer;
|
||||||
|
DECLARE p_mo_ticket_id Integer;
|
||||||
|
DECLARE p_mo_ticket_max_usage_count Integer;
|
||||||
|
DECLARE p_allow_multiple_enter boolean;
|
||||||
|
DECLARE p_allow_enter boolean;
|
||||||
|
|
||||||
|
delete from devlog;
|
||||||
|
|
||||||
|
|
||||||
|
IF NEW.id_customer is not null and NEW.id_card is not null
|
||||||
|
THEN
|
||||||
|
|
||||||
|
IF (NEW.direction = 7 or New.direction = 3 ) and NEW.id_ticket_current is not null
|
||||||
|
then
|
||||||
|
INSERT INTO devlog ( msg) values('belepes feldoglozas indit');
|
||||||
|
|
||||||
|
select count(*) into @p_count_all from door_log where created_at >= CURDATE() and id_ticket_current = New.id_ticket_current and ( direction = 7 or direction = 3);
|
||||||
|
INSERT INTO devlog ( msg) values( concat( 'count all' ,@p_count_all ) );
|
||||||
|
|
||||||
|
|
||||||
|
IF @p_count_all = 1
|
||||||
|
THEN
|
||||||
|
|
||||||
|
select usage_count, max_usage_count into @p_usage_count ,@p_max_usage_count from ticket where id_ticket = NEW.id_ticket_current;
|
||||||
|
|
||||||
|
|
||||||
|
update ticket set usage_count = usage_count +1 where id_ticket = NEW.id_ticket_current;
|
||||||
|
|
||||||
|
|
||||||
|
INSERT INTO log (type,message, app, id_ticket, id_door_log,created_at, updated_at)
|
||||||
|
values(
|
||||||
|
30, concat('B<EFBFBD>rlet haszn<7A>lat (elotte: ',@p_usage_count, ' > utana: ' , @p_usage_count +1 , ' max: ', @p_max_usage_count, ')' ), ' trigger_inc_ticket',New.id_ticket_current, New.id_door_log,now(),now());
|
||||||
|
else
|
||||||
|
|
||||||
|
-- deltaElsoBelépés a napi első door log és 'most' között eltelt órák
|
||||||
|
-- HOUR( TIMEDIFF( min(created_at) , now() ) )
|
||||||
|
|
||||||
|
-- hány darab 3 órás intervallum telt el
|
||||||
|
-- floor : 2.75 -> 2
|
||||||
|
-- FLOOR( ( ( HOUR( TIMEDIFF( min(created_at) , now() ) ) /3 ) ) )
|
||||||
|
|
||||||
|
-- a napi első belépés után kiszámoljuk az aktuális n-edik 3órás intervallum kezdetét
|
||||||
|
|
||||||
|
select min(created_at) + INTERVAL (3 * FLOOR( ( ( HOUR( TIMEDIFF( min(created_at) , now() ) ) /3 ) ) ) ) hour as last_date
|
||||||
|
into @p_from
|
||||||
|
from door_log
|
||||||
|
where created_at > CURDATE() and id_customer is not null and id_ticket_current = NEW.id_ticket_current and ( direction = 7 or direction = 3);
|
||||||
|
|
||||||
|
|
||||||
|
select count(*) into @p_count_all_2 from door_log where created_at >= @p_from and id_ticket_current = New.id_ticket_current and ( direction = 7 or direction = 3);
|
||||||
|
|
||||||
|
INSERT INTO devlog ( msg) values(CONCAT( 'Bel<EFBFBD>p<EFBFBD>sek sz<73>ma az aktu<74>lis 3 <20>r<EFBFBD>s intervalumban: ', @p_count_all_2) );
|
||||||
|
|
||||||
|
|
||||||
|
IF @p_count_all_2 = 1
|
||||||
|
THEN
|
||||||
|
INSERT INTO devlog ( msg) values( 'Az aktu<74>lis intervallumban ez az els? bel<65>p<EFBFBD>s, usage_count n<>vel<65>se' );
|
||||||
|
|
||||||
|
select usage_count, max_usage_count into @p_usage_count ,@p_max_usage_count from ticket where id_ticket = NEW.id_ticket_current;
|
||||||
|
|
||||||
|
update ticket set usage_count = usage_count +1 where id_ticket = New.id_ticket_current;
|
||||||
|
|
||||||
|
INSERT INTO log (type,message, app, id_ticket, id_door_log,created_at, updated_at)
|
||||||
|
values(
|
||||||
|
40, concat('B<EFBFBD>rlet haszn<7A>lat/egy nap tobbszori (elotte: ',@p_usage_count, ' > utana: ' , @p_usage_count +1 , ' max: ', @p_max_usage_count, ')' ), ' trigger_inc_ticket',New.id_ticket_current, New.id_door_log,now(),now());
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
End IF;
|
||||||
|
|
||||||
|
|
||||||
|
IF NEW.direction = 5 or New.direction = 1
|
||||||
|
then
|
||||||
|
INSERT INTO devlog ( msg) values('Kil<EFBFBD>p<EFBFBD>s van folyamatban, kil<69>p<EFBFBD>sek sz<73>m<EFBFBD>nak be<62>ll<6C>t<EFBFBD>sa');
|
||||||
|
update ticket set count_move_out = usage_count where id_ticket = NEW.id_ticket_current;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
INSERT INTO devlog ( msg) values( 'K<EFBFBD>rtya valid<69>ci<63> m<>dos<6F>t<EFBFBD>sa' );
|
||||||
|
|
||||||
|
UPDATE card as c1
|
||||||
|
left JOIN ( select ticket.id_card as id_card , max(ticket.id_ticket) as id_ticket
|
||||||
|
from ticket
|
||||||
|
where ticket.start <= CURDATE()
|
||||||
|
and ticket.end >= curdate()
|
||||||
|
and ticket.status = 10
|
||||||
|
and ticket.count_move_out < ticket.max_usage_count
|
||||||
|
and ticket.id_card = New.id_card
|
||||||
|
group by id_card
|
||||||
|
order by id_card desc ) as t
|
||||||
|
on t.id_card = c1.id_card
|
||||||
|
SET c1.validity = case when t.id_card is null then ( c1.validity | 1 << 0 ) else ( c1.validity & ~(1 << 0) ) end
|
||||||
|
, c1.flag = case when t.id_card is null then ( c1.flag | 1 << 0 ) else ( c1.flag & ~(1 << 0) ) end
|
||||||
|
, c1.id_ticket_current = case when t.id_ticket is null then null else t.id_ticket end
|
||||||
|
WHERE c1.type <> 50 and c1.id_card = New.id_card;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
IF NEW.direction = 5 or New.direction = 1
|
||||||
|
then
|
||||||
|
|
||||||
|
select max(ticket.id_ticket) into @p_mo_ticket_id
|
||||||
|
from ticket
|
||||||
|
where ticket.start <= CURDATE()
|
||||||
|
and ticket.end >= curdate()
|
||||||
|
and ticket.status = 10
|
||||||
|
and ticket.count_move_out < ticket.max_usage_count
|
||||||
|
and ticket.id_card = New.id_card
|
||||||
|
group by id_card
|
||||||
|
order by id_card desc;
|
||||||
|
|
||||||
|
|
||||||
|
set @p_allow_enter = true;
|
||||||
|
|
||||||
|
update card set
|
||||||
|
flag_out = ( flag_out | 1 << 1 ) ,
|
||||||
|
flag = case when @p_allow_enter then ( flag & ~(1 << 1) ) else ( flag | 1 << 1 ) end
|
||||||
|
WHERE type <> 50 and id_card = New.id_card;
|
||||||
|
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
|
||||||
|
IF (NEW.direction = 7 or New.direction = 3 ) and NEW.id_ticket_current is not null
|
||||||
|
THEN
|
||||||
|
|
||||||
|
update card set
|
||||||
|
flag_out = ( flag_out & ~(1 << 1 ) ) ,
|
||||||
|
flag = ( flag | 1 << 1 )
|
||||||
|
WHERE type <> 50 and id_card = New.id_card;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
END IF;
|
||||||
|
END
|
||||||
20
docker/start2.sh
Normal file
20
docker/start2.sh
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
PROJECT_DIR=$(pwd)/..
|
||||||
|
PORT=86
|
||||||
|
HOST=localhost
|
||||||
|
|
||||||
|
docker container stop fitness-web || true
|
||||||
|
|
||||||
|
docker run \
|
||||||
|
-v ${PROJECT_DIR}:/var/www/html/fitness_web \
|
||||||
|
--rm \
|
||||||
|
-d \
|
||||||
|
-p ${PORT}:80 \
|
||||||
|
--name fitness-web \
|
||||||
|
--hostname test.fintess_web.hu \
|
||||||
|
--link mariadb1:mariadb1 \
|
||||||
|
-e XDEBUG_CONFIG="idekey=PHPSTORM" \
|
||||||
|
rocho02.ddns.net/admin/cutlergyor
|
||||||
|
|
||||||
|
echo "started http://"${HOST}:${PORT}
|
||||||
@ -9,7 +9,6 @@ use frontend\models\AccountSelect;
|
|||||||
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\Object;
|
|
||||||
use common\models\Log;
|
use common\models\Log;
|
||||||
use common\models\User;
|
use common\models\User;
|
||||||
|
|
||||||
|
|||||||
@ -13,7 +13,7 @@ use yii\helpers\Url;
|
|||||||
<?php
|
<?php
|
||||||
/** @var \common\models\Ticket $ticket */
|
/** @var \common\models\Ticket $ticket */
|
||||||
$ticket = null;
|
$ticket = null;
|
||||||
if (count($model->tickets) > 0) {
|
if ( isset($model->tickets) && count($model->tickets) > 0) {
|
||||||
$ticket = $model->tickets[0];
|
$ticket = $model->tickets[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,7 @@ $this->params['breadcrumbs'][] = $this->title;
|
|||||||
$dt->sub( new DateInterval( 'P2D') );
|
$dt->sub( new DateInterval( 'P2D') );
|
||||||
|
|
||||||
|
|
||||||
echo \common\components\DateUtil::formatUtc($dt);
|
echo \common\components\DateUtil::formatDateTimeUtc($dt);
|
||||||
|
|
||||||
echo " - ";
|
echo " - ";
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ $this->params['breadcrumbs'][] = $this->title;
|
|||||||
$ticketType->time_unit_count = 3;
|
$ticketType->time_unit_count = 3;
|
||||||
|
|
||||||
$dt2 = \common\components\Helper::getTicketExpirationDate($dt, $ticketType);
|
$dt2 = \common\components\Helper::getTicketExpirationDate($dt, $ticketType);
|
||||||
echo \common\components\DateUtil::formatUtc($dt2);
|
echo \common\components\DateUtil::formatDateTimeUtc($dt2);
|
||||||
|
|
||||||
// $dt2 = \common\components\Helper::getTicketExpirationDate($dt, $ticketType);
|
// $dt2 = \common\components\Helper::getTicketExpirationDate($dt, $ticketType);
|
||||||
// echo \common\components\DateUtil::formatUtc($dt2);
|
// echo \common\components\DateUtil::formatUtc($dt2);
|
||||||
|
|||||||
@ -48,6 +48,7 @@ class LoginController extends RestController
|
|||||||
->issuedAt($time)// Configures the time that the token was issue (iat claim)
|
->issuedAt($time)// Configures the time that the token was issue (iat claim)
|
||||||
->expiresAt($time + $validFor)// Configures the expiration time of the token (exp claim)
|
->expiresAt($time + $validFor)// Configures the expiration time of the token (exp claim)
|
||||||
->withClaim('uid', $form->getMobileDevice()->getId())// Configures a new claim, called "uid"
|
->withClaim('uid', $form->getMobileDevice()->getId())// Configures a new claim, called "uid"
|
||||||
|
->withClaim('cardId', $form->getMobileDevice()->card->number)// Configures a new claim, called "uid"
|
||||||
->getToken($signer, $key); // Retrieves the generated token
|
->getToken($signer, $key); // Retrieves the generated token
|
||||||
|
|
||||||
return $this->asJson([
|
return $this->asJson([
|
||||||
|
|||||||
49
rest/controllers/DoorController.php
Normal file
49
rest/controllers/DoorController.php
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<?php /** @noinspection PhpUnused */
|
||||||
|
|
||||||
|
namespace rest\controllers;
|
||||||
|
|
||||||
|
use common\manager\DoorManager;
|
||||||
|
use rest\models\DoorMoveForm;
|
||||||
|
use Yii;
|
||||||
|
use yii\web\BadRequestHttpException;
|
||||||
|
|
||||||
|
class DoorController extends RestController
|
||||||
|
{
|
||||||
|
|
||||||
|
public function actionMove()
|
||||||
|
{
|
||||||
|
$formModel = new DoorMoveForm();
|
||||||
|
if ($formModel->load(Yii::$app->request->post(),"") ) {
|
||||||
|
if ( !$formModel->validate()){
|
||||||
|
$keys = array_keys($formModel->getFirstErrors());
|
||||||
|
throw new BadRequestHttpException("Invalid move request:". $formModel->getFirstErrors()[$keys[0]]);
|
||||||
|
}
|
||||||
|
$doorManager = new DoorManager();
|
||||||
|
$doorManager->move($formModel->cardNumber,$formModel->device,$formModel->direction, $formModel->createdAt, $formModel->date);
|
||||||
|
}
|
||||||
|
return $formModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function actionReset($cardNumber){
|
||||||
|
$doorManager = new DoorManager();
|
||||||
|
$doorManager->resetLogs($cardNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function actionInfo($cardNumber){
|
||||||
|
$doorManager = new DoorManager();
|
||||||
|
return $doorManager->getInfo($cardNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function actionCreateDoorLog(){
|
||||||
|
$doorManager = new DoorManager();
|
||||||
|
return $doorManager->createLog();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function actionPing(){
|
||||||
|
\Yii::$app->response->statusCode = 204;
|
||||||
|
echo "hello";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
24
rest/models/DoorMoveForm.php
Normal file
24
rest/models/DoorMoveForm.php
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace rest\models;
|
||||||
|
|
||||||
|
use yii\base\Model;
|
||||||
|
|
||||||
|
class DoorMoveForm extends Model
|
||||||
|
{
|
||||||
|
|
||||||
|
public $cardNumber;
|
||||||
|
public $device;
|
||||||
|
public $direction;
|
||||||
|
public $test;
|
||||||
|
public $createdAt;
|
||||||
|
public $date;
|
||||||
|
|
||||||
|
public function rules( ) {
|
||||||
|
return [
|
||||||
|
[ ['cardNumber', 'device', 'direction' ], 'required'],
|
||||||
|
[ ['createdAt', 'date' ], 'string']
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
7715
test/package-lock.json
generated
Normal file
7715
test/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
20
test/package.json
Normal file
20
test/package.json
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"name": "rest-test",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "jest",
|
||||||
|
"test:watch": "jest --watch"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"devDependencies": {
|
||||||
|
"jest": "^27.5.1",
|
||||||
|
"supertest": "^6.2.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^0.27.0",
|
||||||
|
"node-fetch": "^3.2.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
212
test/src/rest/move.test.js
Normal file
212
test/src/rest/move.test.js
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
// const fetch = require('node-fetch');
|
||||||
|
// const {test, expect} = require('jest')
|
||||||
|
const axios = require('axios');
|
||||||
|
|
||||||
|
const url = 'http://localhost:86/fitness_web/rest/web/index.php?r=';
|
||||||
|
const auth = "Basic ZG9vcl9zeXN0ZW06ZG9vcnN5c3RlbTE=";
|
||||||
|
const TEST_CARD_NUMBER = "10WMVXMZ";
|
||||||
|
const TEST_AUTH_HEADER = {
|
||||||
|
'Authorization': auth
|
||||||
|
};
|
||||||
|
|
||||||
|
function fail(reason = "fail was called in a test.") {
|
||||||
|
throw new Error(reason);
|
||||||
|
}
|
||||||
|
function secondsSinceEpoch(d){
|
||||||
|
return Math.floor( d.getTime() / 1000 );
|
||||||
|
}
|
||||||
|
global.fail = fail;
|
||||||
|
|
||||||
|
function formatDateTime(date){
|
||||||
|
let s = date.getFullYear()
|
||||||
|
+ "-"
|
||||||
|
+ (date.getMonth() + 1+"").padStart(2,"0")
|
||||||
|
+ "-"
|
||||||
|
+ (date.getDate() +"").padStart(2,"0")
|
||||||
|
+ " "
|
||||||
|
+ (date.getHours()+"").padStart(2,"0")
|
||||||
|
+ ":"
|
||||||
|
+ (date.getMinutes()+"").padStart(2,"0")
|
||||||
|
+ ":"
|
||||||
|
+ "00";
|
||||||
|
console.info(s);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This test fails because 1 !== 2
|
||||||
|
test('Testing to see if Jest works', () => {
|
||||||
|
expect(1).toBe(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
class Client {
|
||||||
|
|
||||||
|
async reset($cardNumber) {
|
||||||
|
return await axios.get(url + 'door/reset&cardNumber=' + $cardNumber, {
|
||||||
|
headers: {...TEST_AUTH_HEADER}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async getInfo($cardNumber) {
|
||||||
|
return await axios.get(url + 'door/info&cardNumber=' + $cardNumber, {
|
||||||
|
headers: {...TEST_AUTH_HEADER}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async createDoorLog(doorlog) {
|
||||||
|
return await axios.post(url + 'door/create-door-log', doorlog,{
|
||||||
|
headers: {...TEST_AUTH_HEADER},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async move(data, headers) {
|
||||||
|
return await axios.get(url + 'door/move', {
|
||||||
|
headers: {
|
||||||
|
...TEST_AUTH_HEADER,
|
||||||
|
...headers
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
direction: 3,
|
||||||
|
device: 'QRCODE',
|
||||||
|
cardNumber: '10WMVXMZ',
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async moveWithInfo(data, headers) {
|
||||||
|
const before = await this.getInfo(data.cardNumber);
|
||||||
|
const response = await this.move(data, headers);
|
||||||
|
const after = await this.getInfo(data.cardNumber);
|
||||||
|
return {
|
||||||
|
before,
|
||||||
|
response,
|
||||||
|
after
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test('Emergency open', async () => {
|
||||||
|
try {
|
||||||
|
const client = new Client();
|
||||||
|
await client.reset(TEST_CARD_NUMBER)
|
||||||
|
let before = await client.getInfo(TEST_CARD_NUMBER);
|
||||||
|
let response = await client.move({direction: 128})
|
||||||
|
expect(response.status).toBe(204);
|
||||||
|
let after = await client.getInfo(TEST_CARD_NUMBER);
|
||||||
|
// console.info("before:after", before.data.doorLogCount, after.data.doorLogCount);
|
||||||
|
expect(after.data.doorLogs.length).toBe(0);
|
||||||
|
expect(after.data.doorLogCount).toBe("" + (parseInt(before.data.doorLogCount) + 1));
|
||||||
|
expect(after.data.lastDoorLog?.direction).toBe(128);
|
||||||
|
} catch (e) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Error if card not exists', async () => {
|
||||||
|
const client = new Client();
|
||||||
|
try {
|
||||||
|
await client.move({cardNumber: 'notexists', direction: 3});
|
||||||
|
} catch (e) {
|
||||||
|
expect(e?.response?.status).toBe(400);
|
||||||
|
|
||||||
|
}
|
||||||
|
expect.assertions(1);
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Allow card type employee', async () => {
|
||||||
|
const client = new Client();
|
||||||
|
let createdAt = new Date();
|
||||||
|
createdAt.setHours(18);
|
||||||
|
const info = await client.moveWithInfo({cardNumber: 'employee', direction: 3, createdAt: secondsSinceEpoch(createdAt)});
|
||||||
|
// console.info("employee ready");
|
||||||
|
const lastLog = info.after.data.lastDoorLog;
|
||||||
|
expect(lastLog.id_card).not.toBeNull();
|
||||||
|
expect(lastLog.direction).toBe(3);
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
test('Normal Ticket: usage count will be increased on entry', async () => {
|
||||||
|
const client = new Client();
|
||||||
|
client.reset(TEST_CARD_NUMBER);
|
||||||
|
const info = await client.moveWithInfo({cardNumber: TEST_CARD_NUMBER, direction: 3});
|
||||||
|
expect(info?.response?.status).toBe(200);
|
||||||
|
const ticketBefore = info?.before.data?.tickets[0];
|
||||||
|
const ticketAfter = info?.after.data?.tickets[0];
|
||||||
|
expect(ticketBefore.usage_count + 1).toBe(ticketAfter.usage_count);
|
||||||
|
|
||||||
|
const info2 = await client.moveWithInfo({cardNumber: TEST_CARD_NUMBER, direction: 3});
|
||||||
|
expect(info?.response?.status).toBe(200);
|
||||||
|
const ticketAfter2 = info2?.after.data?.tickets[0];
|
||||||
|
expect(ticketAfter.usage_count).toBe(ticketAfter2.usage_count);
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Normal Ticket: increase door log after 3 hours', async () => {
|
||||||
|
const client = new Client();
|
||||||
|
client.reset(TEST_CARD_NUMBER);
|
||||||
|
let info = await client.getInfo(TEST_CARD_NUMBER);
|
||||||
|
// First log on this day
|
||||||
|
let date = new Date();
|
||||||
|
date.setHours(1);
|
||||||
|
date.setMinutes(0,0,0);
|
||||||
|
await client.createDoorLog({
|
||||||
|
'created_at' : formatDateTime( date ),
|
||||||
|
'id_card': info.data.card.id_card,
|
||||||
|
'id_customer': info.data.customer.id_customer,
|
||||||
|
'id_ticket_current' : info.data.tickets[0].id_ticket,
|
||||||
|
'direction' : 3
|
||||||
|
});
|
||||||
|
// second door in @ 2:00 am. Less then 3 hours since first door log, so no
|
||||||
|
// usage_count must be consumed
|
||||||
|
let createdAt = new Date();
|
||||||
|
createdAt.setHours(2);
|
||||||
|
createdAt.setMinutes(0,0,0);
|
||||||
|
info = await client.moveWithInfo({
|
||||||
|
cardNumber: TEST_CARD_NUMBER,
|
||||||
|
direction: 3,
|
||||||
|
createdAt: formatDateTime(createdAt)
|
||||||
|
});
|
||||||
|
let ticketBefore = info?.before.data?.tickets[0];
|
||||||
|
let ticketAfter = info?.after.data?.tickets[0];
|
||||||
|
expect(ticketBefore.usage_count).toBe(ticketAfter.usage_count);
|
||||||
|
|
||||||
|
// @4:00 3 hours already passed, we need consume usage count
|
||||||
|
createdAt = new Date();
|
||||||
|
createdAt.setHours(4);
|
||||||
|
createdAt.setMinutes(0,0,0);
|
||||||
|
info = await client.moveWithInfo({
|
||||||
|
cardNumber: TEST_CARD_NUMBER,
|
||||||
|
direction: 3,
|
||||||
|
createdAt: formatDateTime(createdAt)
|
||||||
|
});
|
||||||
|
ticketBefore = info?.before.data?.tickets[0];
|
||||||
|
ticketAfter = info?.after.data?.tickets[0];
|
||||||
|
expect(ticketBefore.usage_count+1).toBe(ticketAfter.usage_count);
|
||||||
|
|
||||||
|
// @6:00 2 hours passed since 4, we don't need consume usage count
|
||||||
|
createdAt = new Date();
|
||||||
|
createdAt.setHours(5);
|
||||||
|
createdAt.setMinutes(0,0,0);
|
||||||
|
info = await client.moveWithInfo({
|
||||||
|
cardNumber: TEST_CARD_NUMBER,
|
||||||
|
direction: 3,
|
||||||
|
createdAt: formatDateTime(createdAt)
|
||||||
|
});
|
||||||
|
ticketBefore = info?.before.data?.tickets[0];
|
||||||
|
ticketAfter = info?.after.data?.tickets[0];
|
||||||
|
expect(ticketBefore.usage_count).toBe(ticketAfter.usage_count);
|
||||||
|
|
||||||
|
// @20:15 Need to consume usage count
|
||||||
|
createdAt = new Date();
|
||||||
|
createdAt.setHours(20);
|
||||||
|
createdAt.setMinutes(15,0,0);
|
||||||
|
info = await client.moveWithInfo({
|
||||||
|
cardNumber: TEST_CARD_NUMBER,
|
||||||
|
direction: 3,
|
||||||
|
createdAt: formatDateTime(createdAt)
|
||||||
|
});
|
||||||
|
ticketBefore = info?.before.data?.tickets[0];
|
||||||
|
ticketAfter = info?.after.data?.tickets[0];
|
||||||
|
expect(ticketBefore.usage_count+1).toBe(ticketAfter.usage_count);
|
||||||
|
},10000)
|
||||||
Loading…
Reference in New Issue
Block a user