fitness-web/common/models/Transfer.php

664 lines
21 KiB
PHP

<?php
namespace common\models;
use Yii;
use yii\base\Object;
use yii\helpers\ArrayHelper;
use yii\behaviors\TimestampBehavior;
use common\components\AccountAwareBehavior;
use common\components\UserAwareBehavior;
use common\components\DiscountAwareBehavior;
use common\components\CustomerAwareBehavior;
use yii\db\Query;
use yii\db\Expression;
use common\components\RoleDefinition;
/**
* This is the model class for table "transfer".
*
* @property integer $id_transfer
* @property integer $id_discount
* @property integer $id_currency
* @property integer $id_account
* @property integer $id_object
* @property integer $status
* @property integer $type
* @property integer $item_price
* @property integer $count
* @property integer $money
* @property integer $money_currency
* @property integer $rate
* @property integer $id_user
* @property string $comment
* @property string $created_at
* @property string $updated_at
* @property integer $direction
* @property string $paid_at
* @property integer $id_customer
*/
class Transfer extends \common\models\BaseFitnessActiveRecord
{
const TYPE_PRODUCT = 10;
const TYPE_TICKET = 20;
const TYPE_MONEY_MOVEMENT_OUT = 30; //MONEY OUT FROM ACCOUNT
const STATUS_NOT_PAID = 10;
const STATUS_PAID = 20;
const DIRECTION_OUT = 10;// MONEY GOES OUT FROM ACCOUNT ( COMPANY LOST MONEY )
const DIRECTION_IN = 20;//MONEY GOES IN TO THE ACCOUNT ( COMPANY EARN MONEY )
/**
* @inheritdoc
*/
public function behaviors()
{
return ArrayHelper::merge( [
[
'class' => TimestampBehavior::className(),
'value' => function(){ return date('Y-m-d 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 = "Pénz kivétel - " . $this->moneyMovement->name;
}
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 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;
$transfer->direction = Transfer::DIRECTION_OUT;
$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->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->asTime($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;
}
/**
* @param string $mode The mode to load
* Available modes
* <ul>
* <li>
* <h2>created_at</h2>
* <p>Load all transfer which were created </p>
* </li>
* <li>
* <h2>paid_at</h2>
* <p>Load all transfer which were paid </p>
* </li>
* <li>
* <h2>created_at_paid</h2>
* <p>Load all transfer which were created and paid </p>
* </li>
* <li>
* <h2>created_at_not_paid</h2>
* <p>Load all transfer which were created but not paid </p>
* </li>
* <li>
* <h2>paid_at_not_created_at</h2>
* <p>Load all transfer which were not created but paid . Works correctly only,
* when start and end date given
* </p>
* </li>
* </ul>
*
* */
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->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;
}
}