TimestampBehavior::className(), 'value' => function(){ return date('Y-m-d H:i:s' ,\Yii::$app->formatter->asTimestamp(date('Y-d-m h:i:s')) ); } ], [ 'class' => DiscountAwareBehavior::className(), ], [ 'class' => CustomerAwareBehavior::className(), ], ], parent::behaviors()); } /** * @inheritdoc */ public static function tableName() { return 'transfer'; } /** * @inheritdoc */ public function rules() { return [ [['id_discount', 'id_currency', 'id_object', 'status', 'type', 'item_price', 'count', 'money', 'money_currency', 'rate', 'id_user'], 'integer'], [['created_at', 'updated_at'], 'safe'], [['comment'], 'string', 'max' => 255] ]; } /** * @inheritdoc */ public function attributeLabels() { return [ 'id_transfer' => Yii::t('common/transfer', 'Id Transfer'), 'id_account' => Yii::t('common/transfer', 'Account'), 'id_discount' => Yii::t('common/transfer', 'Id Discount'), 'id_currency' => Yii::t('common/transfer', 'Id Currency'), 'id_object' => Yii::t('common/transfer', 'Id Object'), 'objectName' => Yii::t('common/transfer', 'Id Object'), 'status' => Yii::t('common/transfer', 'Status'), 'type' => Yii::t('common/transfer', 'Type'), 'item_price' => Yii::t('common/transfer', 'Item Price'), 'count' => Yii::t('common/transfer', 'Count'), 'money' => Yii::t('common/transfer', 'Money'), 'money_currency' => Yii::t('common/transfer', 'Money Currency'), 'rate' => Yii::t('common/transfer', 'Rate'), 'id_user' => Yii::t('common/transfer', 'Id User'), 'id_customer' => Yii::t('common/transfer', 'Customer'), 'comment' => Yii::t('common/transfer', 'Comment'), 'created_at' => Yii::t('common/transfer', 'Created At'), 'updated_at' => Yii::t('common/transfer', 'Updated At'), 'paid_at' => Yii::t('common/transfer', 'Paid At'), 'types' => Yii::t('common/transfer', 'Types'), 'start' => Yii::t('common/transfer', 'Start'), 'end' => Yii::t('common/transfer', 'End'), ]; } public function getUser(){ return $this->hasOne( User::className(), ["id" =>"id_user" ] ); } public function getProduct(){ return $this->hasOne( Product::className(), ["id_product" =>"id_product" ] )->via('sale'); } public function getMoneyMovement(){ return $this->hasOne( MoneyMovement::className(), ["id_money_movement" =>"id_object" ] ); } public function getTicket(){ return $this->hasOne( Ticket::className(), ["id_ticket" =>"id_object", ] ) ; } public function getTicketType(){ return $this->hasOne( TicketType::className(), ["id_ticket_type" =>"id_ticket_type" ] )->via('ticket') ; } public function getAccount(){ return $this->hasOne( Account::className(), ["id_account" =>"id_account" ] ) ; } public function getCurrency(){ return $this->hasOne( Currency::className(), ["id_currency" =>"id_currency" ] ); } public function getUserSoldItem(){ return $this->hasOne( UserSoldItem::className(), ["id_transfer" =>"id_transfer" ] ); } public function getCustomerCart(){ return $this->hasOne( ShoppingCart::className(), ["id_transfer" =>"id_transfer" ] ); } public function getSale(){ return $this->hasOne( Sale::className(), ["id_sale" =>"id_object" ] ) ; } public function getObjectName(){ $result = ""; if ( $this->type == Transfer::TYPE_TICKET ){ $result = $this->ticketName; }else if ( $this->type == Transfer::TYPE_PRODUCT ){ $result = $this->productName; }else if ( $this->type == Transfer::TYPE_MONEY_MOVEMENT_OUT ){ $result = $this->moneyMovement->humanType; } return $result; } public function getUserName(){ $result = ""; $user = $this->user; if (isset($this->user)){ $result = $user->username; } return $result; } public function getProductName(){ $result = ""; $product = $this->product; if (isset($product)){ $result = $product->name; } return $result; } public function getTicketName(){ $result = ""; $ticket = $this->ticket; if (isset($ticket)){ $result = $this->ticket->ticketTypeName; } return $result; } public function getAccountName(){ $result = ""; $account = $this->account; if (isset($account)){ $result = $account->name; } return $result; } public function getTransferTypeName(){ $result = ""; if ( $this->type == Transfer::TYPE_TICKET ){ $result = Yii::t('common/transfer','Ticket'); }else if ( $this->type == Transfer::TYPE_PRODUCT ){ $result = Yii::t('common/transfer','Product'); }else if ( $this->type == Transfer::TYPE_MONEY_MOVEMENT_OUT ){ $result = Yii::t('common/transfer','Money movement'); } return $result; } public function getSaleName(){ $result = ""; $sale = $this->sale; if (isset($sale)){ $result = $sale->name; } return $result; } public function getSignedMoney(){ $m = 1; $result = $this->money; if ( $this->direction == self::DIRECTION_OUT ){ $m = -1; } $result = $result * $m; return $result; } public static function toSignedMoney($dir,$money){ $m = 1; $result = $money; if ( $dir == Transfer::DIRECTION_OUT ){ $m = -1; } $result = $result * $m; return $result; } public function toProductSoldString(){ $s = ""; $s .= $this->count; $s .= " " . Yii::t('frontend/transfer', 'pieces') . " "; $s .= $this->product->name; $s .= " - "; $s .= $this->account->name; return $s; } /** * @param $account common\models\Account * @param $discount common\models\Discount * @param $currency common\models\Currency * @param $product common\models\Product * @param $customer common\models\Customer * */ public static function createProductTransfer($sale,$account, $discount, $currency, $count,$product , $status = Transfer::STATUS_PAID,$customer = null){ $transfer = new Transfer(); $transfer->type = Transfer::TYPE_PRODUCT; $transfer->id_object = $sale->id_sale; $transfer->item_price = $product->sale_price; $totalPrice = $transfer->item_price; $transfer->count = $count; $totalPrice = $totalPrice * $count; if ( isset( $discount ) ){ $transfer->id_discount = $discount->id_discount; $totalPrice = Discount::applyDiscount( $totalPrice, $discount); } $transfer->money = $totalPrice; if ( isset( $currency ) ){ $transfer->rate = $currency->rate; $transfer->money_currency = Currency::applyCurrency($totalPrice, $currency); } $transfer->direction = Transfer::DIRECTION_IN; $transfer->status = $status; $transfer->id_account = $account->id_account; if ( isset( $customer ) ){ $transfer->id_customer = $customer->id_customer; } return $transfer; } /** * @param $account common\models\Account * @param $discount common\models\Discount * @param $currency common\models\Currency * @param $moneyMovement common\models\MoneyMovement * */ public static function createMoneyMovementOutTransfer($account , $moneyMovement ){ $transfer = new Transfer(); $transfer->type = Transfer::TYPE_MONEY_MOVEMENT_OUT; $transfer->status = Transfer::STATUS_PAID; if ( $moneyMovement->type == MoneyMovement::TYPE_OUT){ $transfer->direction = Transfer::DIRECTION_OUT; }else if ( $moneyMovement->type == MoneyMovement::TYPE_IN ){ $transfer->direction = Transfer::DIRECTION_IN; } $transfer->count = null; $transfer->id_object = $moneyMovement->id_money_movement; $transfer->money = $moneyMovement->money; $transfer->id_account = $account->id_account; $transfer->paid_at = date('Y-m-d H:i:s' ) ; return $transfer; } /** * @param $account common\models\Account * @param $discount common\models\Discount * @param $currency common\models\Currency * @param $ticket common\models\Ticket * */ public static function createTicketTransfer($account, $discount, $currency, $count,$ticket ,$status = Transfer::STATUS_NOT_PAID){ $transfer = new Transfer(); $transfer->status = $status; $transfer->type = Transfer::TYPE_TICKET; $transfer->direction = Transfer::DIRECTION_IN; $transfer->id_object = $ticket->id_ticket; $transfer->item_price = $ticket->price_brutto; $totalPrice = $transfer->item_price; $transfer->count = $count; $totalPrice = $totalPrice * $count; if ( isset( $discount ) ){ $transfer->id_discount = $discount->id_discount; $totalPrice = Discount::applyDiscount( $totalPrice, $discount); } $transfer->money = $totalPrice; if ( isset( $currency ) ){ $transfer->rate = $currency->rate; $transfer->money_currency = Currency::applyCurrency($totalPrice, $currency); } $transfer->id_account = $account->id_account; return $transfer; } public static function modelsToArray($transfers,$default = []){ if ( $transfers == null ){ return $default; } return ArrayHelper::toArray($transfers, [ 'common\models\Transfer' => [ 'id_transfer', 'item_price', 'count', 'money', 'money_currency', 'time' => function ($transfer){ return Yii::$app->formatter->asDatetime($transfer->created_at); }, 'account_name' => function ($transfer) { return $transfer->account->name; }, 'product_name' => function ($transfer) { $result = ""; if ( $transfer->type == Transfer::TYPE_TICKET ){ $result = $transfer->ticket->ticketTypeName; }else if ( $transfer->type == Transfer::TYPE_PRODUCT ){ $result = $transfer->product->name; }else if ( $transfer->type == Transfer::TYPE_MONEY_MOVEMENT_OUT ){ $result = "Pénzmozgás"; } return $result; }, 'category' => function ($transfer) { if ( $transfer->type == Transfer::TYPE_TICKET ){ return Yii::t('frontend/transfer','Ticket'); }else if ( $transfer->type == Transfer::TYPE_PRODUCT ){ return $transfer->product->productCategoryName; }else if ( $transfer->type == Transfer::TYPE_MONEY_MOVEMENT_OUT ){ return "Pénzmozgás"; } }, ], ]); } public static function readUserSoldTransfers($user){ $transfers = []; $query = Transfer::find(); $query->innerJoinWith('userSoldItem'); $query->andWhere(['user_sold_item.id_user' => $user->id ]); $transfers = $query->all(); return $transfers; } public static function readCustomerCart($customer){ $transfers = []; if ( isset($customer) ){ $query = Transfer::find(); $query->innerJoinWith('customerCart'); $query->andWhere(['shopping_cart.id_customer' => $customer->id_customer ]); $transfers = $query->all(); } return $transfers; } public static function types( ) { return [ self::TYPE_MONEY_MOVEMENT_OUT => Yii::t('common/transfer','Pénzmozgás'), self::TYPE_PRODUCT => Yii::t('common/transfer','Product'), self::TYPE_TICKET => Yii::t('common/transfer','Ticket'), ]; } public static function statuses( ) { return [ self::STATUS_NOT_PAID => Yii::t('common/transfer','Nincs fizetve'), self::STATUS_PAID => Yii::t('common/transfer','Fizetve'), ]; } public function getStatusName( ) { $status = null; $statuses = self::statuses(); if ( array_key_exists($this->status, $statuses)){ $status = $statuses[$this->status]; } return $status; } public function beforeDelete(){ parent::beforeDelete(); if ( $this->type == Transfer::TYPE_TICKET){ $ticket = $this->ticket; if ( $ticket != null ){ $ticket->delete(); } }else if ($this->type == Transfer::TYPE_MONEY_MOVEMENT_OUT){ $mm = $this->moneyMovement; $mm->delete(); }else if ($this->type == Transfer::TYPE_PRODUCT){ $sale = $this->sale; $product = $this->product; $product->stock = $product->stock + $this->count; $product->save(); $sale->delete(); } ShoppingCart::deleteAll(['id_transfer' =>$this->id_transfer]); UserSoldItem::deleteAll(['id_transfer' =>$this->id_transfer]); return true; } /** * @param string $mode The mode to load * Available modes * * * */ public static function mkTotalQuery($mode,$start,$end,$idUser,$types,$idAccount){ $query = new Query(); $query->addSelect( [ new Expression( 'transfer.id_account as account'), new Expression( ' COALESCE(sum( ( case when direction = '.Transfer::DIRECTION_OUT.' then -1 else 1 end )* transfer.money ),0) as money /** --'. $mode.'*/' ) ]); $query->from('transfer'); if ( !RoleDefinition::isAdmin() ){ $query->innerJoin("user_account_assignment", 'transfer.id_account = user_account_assignment.id_account' ); $query->andWhere(['user_account_assignment.id_user' => Yii::$app->user->id ]); } $query->innerJoin("account", 'transfer.id_account = account.id_account' ); $query->andWhere(['account.type' => Account::TYPE_ALL]); $query->andFilterWhere([ 'transfer.id_account' => $idAccount, ]); $query->andFilterWhere(['transfer.id_user' => $idUser]); $query->andFilterWhere(['in' ,'transfer.type', $types]); if ( $mode == 'created_at'){ self::inInterval($query, 'transfer.created_at', $start, $end); }else if ( $mode == 'paid_at'){ self::inInterval($query, 'transfer.paid_at' , $start, $end); }else if ( $mode == 'created_at_not_paid'){ self::notPaid($query, 'transfer.paid_at', $start, $end); self::inInterval($query, 'transfer.created_at', $start, $end); }else if ( $mode == 'created_at_paid'){ self::inInterval($query, 'transfer.created_at', $start, $end); self::inInterval($query, 'transfer.paid_at', $start, $end); }else if ( $mode == 'paid_at_not_created_at'){ self::inInterval($query, 'transfer.paid_at' , $start, $end); self::notInInterval($query, 'transfer.created_at', $start, $end); } $query->groupBy('transfer.id_account'); return $query; } public static function notInInterval($query ,$field , $start,$end ){ $query->andFilterWhere( ['or', [ '<', $field , isset( $start ) ? $start : '1900-01-01' ] ,[ '>=' , $field , isset($end) ? $end : '3000-01-01' ] ] ); } public static function notPaid($query ,$field , $start,$end ){ $query->andFilterWhere( ['or', [ '<', $field , isset( $start ) ? $start : '1900-01-01' ] ,[ '>=' , $field , isset($end) ? $end : '3000-01-01' ] ,[ "transfer.status" => Transfer::STATUS_NOT_PAID ] ] ); } public static function inInterval($query ,$field , $start,$end ){ $query->andFilterWhere([ '>=', $field , $start ] ); $query->andFilterWhere([ '<' , $field , $end ] ); } /** * * Parse query results so, that all available account will be display, even then , if $queryResult does not contain any result for the given account * * @param mixed $queryResult an array, wchic contains items. each item has to key - value pairs: [ id_account => 0, money => 0 ] * */ public static function mkTotalsResultWithAllAvailableAccount($queryResult,$accounts,$accountMap,$idAccount){ $totals = []; $totals['total'] = 0; $totals['accounts'] = []; foreach ($accounts as $account){ if ( isset($idAccount) && is_numeric($idAccount) && $idAccount != $account->id_account ){ continue ; } $accountTotal = [ 'id_account' => $account->id_account, 'label' => $account->name, 'money' => 0, ]; $item = self::findByAccountInQueryResult($queryResult, $account); if ( isset($item)){ $accountTotal['money'] = $item['money']; } $totals['accounts'][] = $accountTotal; $totals['total'] += $accountTotal['money']; } return $totals; } public static function findByAccountInQueryResult( $queryResult, $account ){ $result = null; foreach ($queryResult as $item){ if( $item['account'] == $account->id_account ){ $result = $item; } } return $result; } /**create and execute a "total" query*/ public static function exTotalQuery($mode,$start,$end,$idUser,$types,$idAccount){ $query = self::mkTotalQuery($mode, $start, $end, $idUser, $types, $idAccount ); $command = $query->createCommand(); $result = $command->queryAll(); return $result; } /** *find all transfers which were paid in the period * */ public static function mkPaidAtTotals( $start, $end, $idUser, $types, $idAccount, $accounts, $accountMap){ $result = []; $queryResult = self::exTotalQuery('paid_at', $start, $end, $idUser, $types, $idAccount ); $result = self::mkTotalsResultWithAllAvailableAccount($queryResult, $accounts, $accountMap, $idAccount); return $result; } /**find all transfers in the period ( doesn't matter if paid or not )*/ public static function mkCreatedAtTotals( $start, $end, $idUser, $types, $idAccount, $accounts, $accountMap){ $result = []; $queryResult = self::exTotalQuery('created_at', $start, $end, $idUser, $types, $idAccount ); $result = self::mkTotalsResultWithAllAvailableAccount($queryResult, $accounts, $accountMap, $idAccount); return $result; } /**find transfers which were created but not paid in the period*/ public static function mkCreatedAtNotPaidTotals( $start, $end, $idUser, $types, $idAccount, $accounts, $accountMap){ $result = []; $queryResult = self::exTotalQuery('created_at_not_paid', $start, $end, $idUser, $types, $idAccount ); $result = self::mkTotalsResultWithAllAvailableAccount($queryResult, $accounts, $accountMap, $idAccount); return $result; } /** * find transfers which were created and paid in the period * * */ public static function mkCreatedAtPaidTotals( $start, $end, $idUser, $types, $idAccount, $accounts, $accountMap){ $result = []; $queryResult = self::exTotalQuery('created_at_paid', $start, $end, $idUser, $types, $idAccount ); $result = self::mkTotalsResultWithAllAvailableAccount($queryResult, $accounts, $accountMap, $idAccount); return $result; } /** * * find transfers, where depth was paid * */ public static function mkPaidAtNotCreatedAtPaidTotals( $start, $end, $idUser, $types, $idAccount, $accounts, $accountMap){ $result = []; $queryResult = self::exTotalQuery('paid_at_not_created_at', $start, $end, $idUser, $types, $idAccount ); $result = self::mkTotalsResultWithAllAvailableAccount($queryResult, $accounts, $accountMap, $idAccount); return $result; } public static function mkTotals( $start, $end, $idUser, $types, $idAccount, $accounts, $accountMap ){ $result = []; $result['paid_at'] = self::mkPaidAtTotals($start, $end, $idUser, $types, $idAccount, $accounts, $accountMap); $result['created_at'] = self::mkCreatedAtTotals($start, $end, $idUser, $types, $idAccount, $accounts, $accountMap); $result['created_at_not_paid'] = self::mkCreatedAtNotPaidTotals($start, $end, $idUser, $types, $idAccount, $accounts, $accountMap); $result['created_at_paid'] = self::mkCreatedAtPaidTotals($start, $end, $idUser, $types, $idAccount, $accounts, $accountMap); $result['paid_at_not_created_at'] = self::mkPaidAtNotCreatedAtPaidTotals($start, $end, $idUser, $types, $idAccount, $accounts, $accountMap); return $result; } public static function readPaid($start,$end,$idUser){ $query = (new \yii\db\Query()); $query->select(['coalesce(sum( case when transfer.direction = ' . Transfer::DIRECTION_IN. ' then transfer.money else -1 * transfer.money end ),0) AS transfer_money']); $query->from('transfer'); $query->innerJoin("account","account.id_account = transfer.id_account"); $query->andWhere(['transfer.id_user' => $idUser ]); $created_condition = ['and',[ '>=', 'transfer.created_at', $start ] ,[ '<', 'transfer.created_at', $end ] ]; $paid_condition = ['and',[ '>=', 'transfer.paid_at', $start] ,[ '<', 'transfer.paid_at', $end ] ]; $query->andFilterWhere(['or' , $created_condition , $paid_condition]); $query->andWhere(['transfer.status' => Transfer::STATUS_PAID]); $query->andWhere(['account.type' => Account::TYPE_ALL]); return $query->scalar(); } }