= curdate() and ticket.status = 10 and ticket.count_move_out < ticket.max_usage_count group by id_card order by id_card desc ) as t on t.id_card = c1.id_card -- first bit is 0 , when there is a valid ticket or the card is 'employee' => 0000 0000 -- first bit is 1, when card is not employee and there is no valid card => 0000 0001 SET c1.validity = case when c1.type = 50 then ( c1.validity & ~(1 << 0) ) when t.id_card is null then ( c1.validity | 1 << 0 ) else ( c1.validity & ~(1 << 0) ) end -- first bit is 0 when there is a ticket or 'employee' card 0000 0000 -- first bit is 1 when there is no ticket and card type is not 'employee' , c1.flag = case when c1.type = 50 then ( c1.flag & ~(1 << 0) ) 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.status = 10"; public static $SQL_UPDATE_CARD = "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 = :id group by id_card order by id_card desc ) as t on t.id_card = c1.id_card SET c1.validity = case when c1.type = 50 then ( c1.validity & ~(1 << 0) ) when t.id_card is null then ( c1.validity | 1 << 0 ) else ( c1.validity & ~(1 << 0) ) end ,c1.flag = case when c1.type = 50 then ( c1.flag & ~(1 << 0) ) 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.status = 10 and c1.id_card = :id"; public static $SQL_UPDATE_TICKETS_END_DATE_ON_CARD_ACTIVATION = "UPDATE ticket t inner join card c on t.id_card = c.id_card SET end = date_add( end, INTERVAL datediff(current_date, c.inactivated_at) DAY ) where c.status = 20 and c.inactivated_at is not null and ((t.start <= c.inactivated_at and t.end >= c.inactivated_at) ) "; public static $SQL_UPDATE_TICKETS_END_DATE_ON_CARD_ACTIVATION_SINGLE_CARD = "UPDATE ticket t inner join card c on t.id_card = c.id_card SET end = date_add( end, INTERVAL datediff(current_date, c.inactivated_at) DAY ) where c.status = 20 and c.inactivated_at is not null and ((t.start <= c.inactivated_at and t.end >= c.inactivated_at) ) and c.id_card = :id_card "; public static function SQL_UPDATE_DOOR_ALLOWED_FLAG(){ return " UPDATE card c LEFT JOIN ticket t on c.id_ticket_current = t.id_ticket LEFT JOIN ticket_type tt on t.id_ticket_type = tt.id_ticket_type set c.flag = case when tt.door_allowed <> 1 then ( c.flag | 1 << 4 ) else ( c.flag & ~(1 << 4) ) end WHERE c.type <> 50 "; } public static function SQL_UPDATE_DOOR_ALLOWED_FLAG_FOR_CARD(){ return Ticket::SQL_UPDATE_DOOR_ALLOWED_FLAG() . " and c.id_card = :id"; } /** * @inheritdoc */ public static function tableName() { return 'ticket'; } /** * @inheritdoc */ public function rules() { return [ [[ 'id_user', 'id_ticket_type', 'id_account', 'id_discount', 'max_usage_count', 'usage_count', 'status', 'price_brutto'], 'integer'], [['start', 'end', 'created_at', 'updated_at'], 'safe'], [['comment'], 'required'], [['comment'], 'string', 'max' => 255], [[ 'start', ], 'date' , 'timestampAttribute' => 'timestampStart' ,'timestampAttributeFormat' => 'yyyy-MM-dd' ], [[ 'end' , ], 'date' , 'timestampAttribute' => 'timestampEnd' ,'timestampAttributeFormat' => 'yyyy-MM-dd' ], ]; } /** * @inheritdoc */ public function attributeLabels() { return [ 'id_ticket' => Yii::t('common/ticket', 'Bérlet azonosító'), 'id_user' => Yii::t('common/ticket', 'Id User'), 'id_ticket_type' => Yii::t('common/ticket', 'Id Ticket Type'), 'id_account' => Yii::t('common/ticket', 'Id Account'), 'id_discount' => Yii::t('common/ticket', 'Id Discount'), 'start' => Yii::t('common/ticket', 'Start'), 'end' => Yii::t('common/ticket', 'End'), 'max_usage_count' => Yii::t('common/ticket', 'Max Usage Count'), 'usage_count' => Yii::t('common/ticket', 'Usage Count'), 'status' => Yii::t('common/ticket', 'Status'), 'price_brutto' => Yii::t('common/ticket', 'Price Brutto'), 'comment' => Yii::t('common/ticket', 'Comment'), 'created_at' => Yii::t('common/ticket', 'Created At'), 'updated_at' => Yii::t('common/ticket', 'Updated At'), 'id_card' => Yii::t('backend/ticket','Card'), 'id_customer' => Yii::t('backend/ticket','Customer'), 'payment_method' => Yii::t('common/transfer', 'Fizetési mód'), 'original_price' => Yii::t('common/transfer', 'Eredeti ár'), 'original_end' => Yii::t('common/transfer', 'Eredeti érvényesség vége'), ]; } public function getCard(){ return $this->hasOne( Card::className(), ["id_card" =>"id_card" ] ); } public function getContract(){ return $this->hasOne( Contract::className(), ["id_contract" =>"id_contract" ] ); } public function getTransfer(){ return $this->hasOne( Transfer::className(), ["id_object" =>"id_ticket"] )->andWhere(['transfer.type' => Transfer::TYPE_TICKET]); } public function getCardNumber(){ $result = ""; /** @noinspection PhpUndefinedFieldInspection */ $card = $this->card; if ( isset($card)){ $result = $card->number; } return $result; } public function getCustomer(){ return $this->hasOne( Customer::className(), ["id_customer_card" =>"id_card" ] )->via('card'); } public function getCustomerName(){ $result = ""; /** @noinspection PhpUndefinedFieldInspection */ $customer = $this->customer; if ( isset($customer)){ $result = $customer->name; } return $result; } public function getUser(){ return $this->hasOne( User::className(), ["id" =>"id_user" ] ); } public function getTicketType(){ return $this->hasOne( TicketType::className(), ["id_ticket_type" =>"id_ticket_type" ] ); } public function getDiscount(){ return $this->hasOne( Discount::className(), ["id_discount" =>"id_discount" ] ); } public function getAccount() { return $this->hasOne ( Account::className (), [ 'id_account' => 'id_account' ] ); } public function getAccountName() { $result = ""; /** @noinspection PhpUndefinedFieldInspection */ /** @var \common\models\Account $account */ $account = $this->account; if ( isset($account) ){ $result = $account->name; } return $result; } public function getDiscountName() { $result = ""; /** @noinspection PhpUndefinedFieldInspection */ /** @var \common\models\Discount $discount */ $discount = $this->discount; if ( isset($discount) ){ $result = $discount->name; } return $result; } public function getTicketTypeName() { $result = ""; /** @noinspection PhpUndefinedFieldInspection */ $ticketType = $this->ticketType; if ( isset($ticketType) ){ $result = $ticketType->name; } return $result; } public function getUserName() { $result = ""; /** @noinspection PhpUndefinedFieldInspection */ $user = $this->user; if ( isset($user) ){ $result = $user->username; } return $result; } /** * @param \common\models\Card $card the card to which we are looking for * * @param \DateTime $validOnDay on which day must be the ticket valid * @return array|\yii\db\ActiveRecord[] */ public static function readActive($card, $validOnDay = null){ if ( $card == null ) return []; $query = Ticket::find(); if (!isset( $validOnDay ) ){ $today = date('Y-m-d'); }else{ $today = $validOnDay->format('Y-m-d'); } $query->andWhere(['ticket.id_card' => $card->id_card]); $query->andWhere( 'ticket.start <= :today' ,[ 'today' => $today] ); $query->andWhere( 'ticket.end >= :today' ,[ 'today' => $today] ); $query->andWhere( 'ticket.status = :status' ,[ 'status' => Ticket::STATUS_ACTIVE] ); $query->orderBy([ "ticket.created_at" =>SORT_DESC] ); $result = $query->all(); return $result; } /** * @param \common\models\Card $card the card to which we are looking for * * @return array|\yii\db\ActiveRecord[] */ public static function readUnpaid($card){ if ( $card == null ) return []; $query = Ticket::find(); $query->innerJoin("transfer", "transfer.id_object = ticket.id_ticket "); $today = date('Y-m-d'); $query->andWhere(['ticket.id_card' => $card->id_card]); $query->andWhere( 'ticket.start <= :today' ,[ 'today' => $today] ); $query->andWhere( 'ticket.end >= :today' ,[ 'today' => $today] ); $query->andWhere( ['in' ,'ticket.status' ,[ Ticket::STATUS_INACTIVE, Ticket::STATUS_ACTIVE] ]); $query->andWhere( ["transfer.type" => Transfer::TYPE_TICKET] ); $query->andWhere( [ "transfer.status" => Transfer::STATUS_NOT_PAID ]); $query->orderBy([ "ticket.created_at" =>SORT_DESC] ); $result = $query->all(); return $result; } public static function mkStatisticQuery($start,$end,$id_card = null){ $query = new Query(); $query->addSelect( [ new Expression( 'ticket_type.id_ticket_type as id'), new Expression( 'ticket_type.name as name'), new Expression( 'coalesce( count(ticket.id_ticket),0) as total'), new Expression( "coalesce( sum( case when ticket.status <> " .Ticket::STATUS_DELETED ." AND ". Helper::sqlValidRule('ticket.start', 'ticket.end', ':start', ':end') . " then 1 else 0 end) , 0) as valid" ), //valid new Expression( "coalesce( sum( case when ticket.status <> " .Ticket::STATUS_DELETED ." AND ". Helper::sqlInIntervalRule('ticket.created_at', ':start', ':end') . " then 1 else 0 end) , 0) as created" ),//created new Expression( "coalesce( sum( case when ticket.status <> " .Ticket::STATUS_DELETED ." AND ". Helper::sqlInIntervalRule('ticket.created_at', ':start', ':end') . " then transfer.money else 0 end) , 0) as created_money" ),//created_money new Expression( "coalesce( sum( case when ticket.status <> " .Ticket::STATUS_DELETED ." AND " . Helper::sqlExpireRule('ticket.start', 'ticket.end', ':start', ":end") . " then 1 else 0 end) , 0) as expired" ), ]); $query->from('ticket_type'); $query->innerJoin('ticket', 'ticket.id_ticket_type = ticket_type.id_ticket_type'); $query->innerJoin('transfer', 'ticket.id_ticket = transfer.id_object and transfer.type = '. Transfer::TYPE_TICKET ); Helper::queryAccountConstraint($query, 'ticket.id_account'); $query->andFilterWhere(['id_card' =>$id_card]); $query->andWhere( [ 'or', Helper::queryInIntervalRule('ticket.created_at', $start, $end), Helper::queryValidRule('ticket.start', 'ticket.end', $start, $end), Helper::queryExpireRule('ticket.start', 'ticket.end', $start, $end), ] ); $query->groupBy("ticket_type.id_ticket_type, ticket_type.name"); $query->params([':start' => $start, ':end' => $end]); return $query; } public static function statuses( ) { return [ Ticket::STATUS_ACTIVE => 'Aktív', Ticket::STATUS_DELETED => 'Törölve', Ticket::STATUS_INACTIVE => 'Inaktív', ]; } public static function toStatusName($id_status){ $result = "Ismeretlen"; $statuses = Ticket::statuses(); if ( array_key_exists($id_status, $statuses)){ $result = $statuses[$id_status]; } return $result; } public function getStatusName(){ return static::toStatusName($this->status); } public function isDeleted(){ return $this->status == Ticket::STATUS_DELETED; } /**csoportos beszedéses a bérlet*/ public function isInstallmentTicket(){ return ( isset($this->part_count) && $this->part_count > 0 ); } /** * Apply request * * @var \common\models\TicketInstallmentRequest $request megbízás * */ public function applyTicketInstallmentRequest( $request ) { //ha csoportos beszedéses if ( $this->isInstallmentTicket() ){ if ( $request->isStatusAccepted() ){ if ( $this->part_paid < $request->priority ){ $this->part_paid = $request->priority; } $this->recalclulate(); }else if ( $request->isStatusRejected() ){ $this->status = static::STATUS_INACTIVE; } } } /* * * * @param common\models\TicketInstallmentRequest $request megbízás */ public function setPartRequired($request){ // ha keveseb a részlet sorszám mint a bérlet max sorszáma if ( $request->priority <= $this->part_count ){ //ha az aktuális elvárt részlet kisebb , mint a megbízása if ( $this->part < $request-> priority ){ $this->part = $request->priority; } } } /** * Csoportos beszedéses bérlet érvényességének újraszámolása * */ public function recalclulate( ) { if ( $this->isInstallmentTicket() ){ $enabled = $this->part_paid >= $this->part; if ( $enabled == true ){ $this->status = static::STATUS_ACTIVE; }else{ $this->status = static::STATUS_INACTIVE; } } } public function hasOpenReservationCount(){ return $this->reservation_count < $this->max_reservation_count; } /** * @param $count * @throws HttpException */ public function consumeReservationCount($count){ $newReservationCount = $this->reservation_count + $count; if ( $newReservationCount > $this->max_reservation_count ){ throw new HttpException(406,"Max ticket seat count exceeded",EventRegistrationManager::MAX_SEAT_COUNT_EXCEEDED); } $this->reservation_count = $newReservationCount; } public function restoreReservationCount($usagesToRestore){ $this->reservation_count = $this->reservation_count - $usagesToRestore; if ( $this->usage_count < 0 ){ $this->usage_count = 0; } } public function afterSave($insert, $changedAttributes) { Card::updateCardFlagTicket($this->id_card);; } public function afterDelete(){ Card::updateCardFlagTicket($this->id_card);; } /** * @throws \Exception */ public function getMinutesUntilExpire(){ $end = new \DateTime( $this->end ); $today = new \DateTime(); $today->setTime(0,0); if ( $today > $end ){ return -1; } $seconds = $end->getTimestamp() - $today->getTimestamp(); $minutes = $seconds /60; return $minutes; } /** * @throws \Exception */ public function getDaysUntilExpire(){ $minutes = $this->getMinutesUntilExpire(); $days = $minutes / 60 /24; $days = ceil($days); return $days; } /** * Get free usage count. * @return bool|int */ public function getOpenUsageCount(){ if ( !isset($this->max_usage_count) || $this->max_usage_count <= 0){ return false; } $usageCount = $this->usage_count; if ( !isset($usageCount) ){ $usageCount = 0; } return max($this->max_usage_count - $usageCount,0); } }