From eb989d5f80c29ab7dd1b2123b5301a44a08fada3 Mon Sep 17 00:00:00 2001 From: Schneider Roland Date: Wed, 30 Dec 2015 12:02:26 +0100 Subject: [PATCH 1/8] add webcam to customer create/update --- common/assets/WebcamjsAsset.php | 16 ++++++++ common/components/Image.php | 14 +++++++ common/components/Upload.php | 13 +++++++ common/models/Customer.php | 8 ++++ composer.json | 3 +- composer.lock | 40 ++++++++++++++++++- frontend/assets/CustomerAsset.php | 31 +++++++++++++++ frontend/controllers/CustomerController.php | 23 +++++++++++ frontend/models/CustomerCreate.php | 1 + frontend/models/CustomerUpdate.php | 3 +- frontend/views/customer/_camera.php | 29 ++++++++++++++ frontend/views/customer/_form_create.php | 2 +- frontend/views/customer/_form_update.php | 2 +- frontend/views/customer/create.php | 2 +- frontend/views/customer/update.php | 17 ++++++++ frontend/web/js/customer.js | 43 +++++++++++++++++++++ 16 files changed, 240 insertions(+), 7 deletions(-) create mode 100644 common/assets/WebcamjsAsset.php create mode 100644 frontend/assets/CustomerAsset.php create mode 100644 frontend/views/customer/_camera.php create mode 100644 frontend/web/js/customer.js diff --git a/common/assets/WebcamjsAsset.php b/common/assets/WebcamjsAsset.php new file mode 100644 index 0000000..91d0b3e --- /dev/null +++ b/common/assets/WebcamjsAsset.php @@ -0,0 +1,16 @@ + 'id_user' ] ); } + public function getImage1(){ + return $this->hasOne ( Image::className (), [ + 'id_image' => 'id_image' + ] ); + } public function getCustomerCardNumber(){ $result = null; diff --git a/composer.json b/composer.json index 43d682f..99efb4e 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,8 @@ "bower-asset/moment": "^2.10", "bower-asset/accounting": "^0.3.2", "dmstr/yii2-adminlte-asset": "2.*", - "bassjobsen/bootstrap-3-typeahead": "^4.0" + "bassjobsen/bootstrap-3-typeahead": "^4.0", + "bower-asset/webcamjs": "^1.0" }, "require-dev": { "yiisoft/yii2-codeception": "*", diff --git a/composer.lock b/composer.lock index f0c982d..20dc733 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "acfc873fb659d08adc23d325138a56b2", - "content-hash": "28e2bce30da929c84bd2ac7cffd90f3f", + "hash": "fa82e6ba1233a366a5f044d19a7bd69d", + "content-hash": "ea0b9fcfc8a270415b8f9292af1c17d3", "packages": [ { "name": "almasaeed2010/adminlte", @@ -410,6 +410,42 @@ "remarkable" ] }, + { + "name": "bower-asset/webcamjs", + "version": "v1.0.6", + "source": { + "type": "git", + "url": "https://github.com/jhuckaby/webcamjs.git", + "reference": "1f164b822507977bf746838c66b9e4332764c062" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jhuckaby/webcamjs/zipball/1f164b822507977bf746838c66b9e4332764c062", + "reference": "1f164b822507977bf746838c66b9e4332764c062", + "shasum": "" + }, + "type": "bower-asset-library", + "extra": { + "bower-asset-main": "webcam.js", + "bower-asset-ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests", + "build.sh", + "demos", + "flash" + ] + }, + "license": [ + "MIT" + ], + "description": "HTML5 Webcam Image Capture Library with Flash Fallback", + "keywords": [ + "webcam" + ] + }, { "name": "bower-asset/yii2-pjax", "version": "v2.0.4", diff --git a/frontend/assets/CustomerAsset.php b/frontend/assets/CustomerAsset.php new file mode 100644 index 0000000..e1b094e --- /dev/null +++ b/frontend/assets/CustomerAsset.php @@ -0,0 +1,31 @@ + + * @since 2.0 + */ +class CustomerAsset extends AssetBundle +{ + public $basePath = '@webroot'; + public $baseUrl = '@web'; + public $css = [ + ]; + public $js = [ + 'js/customer.js', + ]; + public $depends = [ + 'frontend\assets\AppAsset', + 'common\assets\MomentAsset', + 'common\assets\WebcamjsAsset', + 'yii\jui\JuiAsset', + ]; +} diff --git a/frontend/controllers/CustomerController.php b/frontend/controllers/CustomerController.php index 4024fcf..cb18e55 100644 --- a/frontend/controllers/CustomerController.php +++ b/frontend/controllers/CustomerController.php @@ -13,6 +13,7 @@ use yii\base\Object; use common\models\Card; use frontend\models\CustomerUpdate; use frontend\models\CustomerCreate; +use common\models\Image; /** * CustomerController implements the CRUD actions for Customer model. @@ -119,6 +120,7 @@ class CustomerController extends Controller } if ($model->load(Yii::$app->request->post()) && $model->save()) { + $this->saveBinaryImage($model); \Yii::$app->session->setFlash( 'success','Vendég létrehozva!' ); return $this->redirect(['update', 'number' => $model->cardNumber]); } else { @@ -160,6 +162,9 @@ class CustomerController extends Controller if ($model->load(Yii::$app->request->post()) && $model->save()) { + $this->saveBinaryImage($model); + + \Yii::$app->session->setFlash( 'success','Vendég módosításai elmentve' ); return $this->redirect(['update', 'number' => $card->number]); @@ -175,6 +180,24 @@ class CustomerController extends Controller } + protected function saveBinaryImage($model){ + if ( !empty($model->photo_data)){ + $encoded_data = $model->photo_data; + $binary_data = base64_decode( $encoded_data ); + // save to server (beware of permissions) + $path = \common\components\Image::saveBinary($binary_data,'profile'); + + $image = new Image(); + $image->path = $path; + $image->save(); + + //todo delete old image + + $model->id_image = $image->id_image; + $model->save(false); + } + } + /** * Deletes an existing Customer model. * If deletion is successful, the browser will be redirected to the 'index' page. diff --git a/frontend/models/CustomerCreate.php b/frontend/models/CustomerCreate.php index 6ce1f7b..a6f4357 100644 --- a/frontend/models/CustomerCreate.php +++ b/frontend/models/CustomerCreate.php @@ -100,6 +100,7 @@ class CustomerCreate extends \common\models\Customer [['zip'], 'string', 'max' => 8], [['city'], 'string', 'max' => 30], + [['photo_data'] ,'safe'] // [['email','phone'], 'validateEmailOrPhoneRequired' ], ]; diff --git a/frontend/models/CustomerUpdate.php b/frontend/models/CustomerUpdate.php index dab17eb..ed920a9 100644 --- a/frontend/models/CustomerUpdate.php +++ b/frontend/models/CustomerUpdate.php @@ -100,7 +100,8 @@ class CustomerUpdate extends \common\models\Customer [['zip'], 'string', 'max' => 8], - [['city'], 'string', 'max' => 30] + [['city'], 'string', 'max' => 30], + [['photo_data'] ,'safe'] ]; } diff --git a/frontend/views/customer/_camera.php b/frontend/views/customer/_camera.php new file mode 100644 index 0000000..08ab227 --- /dev/null +++ b/frontend/views/customer/_camera.php @@ -0,0 +1,29 @@ +registerJs ( 'new Customer( '. json_encode($options).');' ); +?> + + + +
+
+
+
+
+
+
+
+Fénykép \ No newline at end of file diff --git a/frontend/views/customer/_form_create.php b/frontend/views/customer/_form_create.php index 22c0fc3..16a66c1 100644 --- a/frontend/views/customer/_form_create.php +++ b/frontend/views/customer/_form_create.php @@ -16,7 +16,7 @@ use kartik\widgets\DatePicker;
- +field($model, 'photo_data')->hiddenInput()->label(false) ?>
diff --git a/frontend/views/customer/_form_update.php b/frontend/views/customer/_form_update.php index cebebf1..ea8b541 100644 --- a/frontend/views/customer/_form_update.php +++ b/frontend/views/customer/_form_update.php @@ -18,7 +18,7 @@ use yii\base\Widget; - + field($model, 'photo_data')->hiddenInput()->label(false) ?>
field($model, 'cardNumber')->widget(CardNumberTypeahead::className(),[]) ?> diff --git a/frontend/views/customer/create.php b/frontend/views/customer/create.php index 5708176..499ecf2 100644 --- a/frontend/views/customer/create.php +++ b/frontend/views/customer/create.php @@ -20,7 +20,7 @@ $card = $customer->card;
$receptionForm, 'route' => ['customer/create'] ] )?> - + render('_camera',['model' => $model]); ?>

title) ?>

render('_form_create', [ diff --git a/frontend/views/customer/update.php b/frontend/views/customer/update.php index 5a7175a..a39db12 100644 --- a/frontend/views/customer/update.php +++ b/frontend/views/customer/update.php @@ -4,10 +4,16 @@ use yii\helpers\Html; use frontend\components\ReceptionMenuWidget; use frontend\components\ReceptionCardNumberWidget; use frontend\components\ReceptionWidget; +use common\assets\WebcamjsAsset; +use frontend\assets\CustomerAsset; +use common\components\Image; +use yii\helpers\Url; /* @var $this yii\web\View */ /* @var $model common\models\Customer */ + + $this->title = Yii::t('common/customer', 'Update customer:' ) . ' ' . $model->name; $this->params['breadcrumbs'][] = ['label' => Yii::t('common/customer', 'Customers'), 'url' => ['index']]; $this->params['breadcrumbs'][] = ['label' => $model->name, 'url' => ['view', 'id' => $model->id_customer]]; @@ -16,6 +22,8 @@ $this->params['breadcrumbs'][] = Yii::t('common/customer', 'Update'); $customer = $model; $card = $customer->card; + + ?>
@@ -23,9 +31,18 @@ $card = $customer->card; $receptionForm, 'route' => ['customer/reception'] ] )?> + render('_camera',['model' => $model]); ?> +

title) ?>

+ + image1 ){ + echo Html::img( Url::base( ) . Image::thumb( $model->image1->path,160,120 )); + } + + ?> render('_form_update', [ 'model' => $model, ]) ?>
+ diff --git a/frontend/web/js/customer.js b/frontend/web/js/customer.js new file mode 100644 index 0000000..bcb170e --- /dev/null +++ b/frontend/web/js/customer.js @@ -0,0 +1,43 @@ +function Customer(o){ + + var defaults = { + 'image_data' : 'customerupdate-photo_data' + + }; + + init(); + + function init(){ + + defaults = $.extend(defaults,o); + + Webcam.set({ + width: 160, + height: 120, + dest_width: 320, + dest_height: 240, + image_format: 'jpeg', + jpeg_quality: 90, +// force_flash: false, +// flip_horiz: true, +// fps: 45 + }); + + Webcam.attach( '#my_camera' ); + + $("#snap").click(snap); + + } + + function snap(){ + Webcam.snap( function(data_uri) { + document.getElementById('my_result').innerHTML = ''; + + var raw_image_data = data_uri.replace(/^data\:image\/\w+\;base64\,/, ''); + + document.getElementById(defaults.image_data ).value = raw_image_data; + + } ); + } + +} \ No newline at end of file From bb70546af4f6d1b0004b1047a15669be938ab169 Mon Sep 17 00:00:00 2001 From: Schneider Roland Date: Wed, 30 Dec 2015 12:12:52 +0100 Subject: [PATCH 2/8] show customer photo on reception --- frontend/views/common/_reception_customer.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/frontend/views/common/_reception_customer.php b/frontend/views/common/_reception_customer.php index b79b290..2c2b96d 100644 --- a/frontend/views/common/_reception_customer.php +++ b/frontend/views/common/_reception_customer.php @@ -4,6 +4,8 @@ use frontend\model\ReceptionForm; use yii\helpers\Html; use yii\widgets\DetailView; use yii\base\Widget; +use common\components\Image; +use yii\helpers\Url; /* @var $this yii\web\View */ /* @var $model frontend\model\ReceptionForm */ @@ -34,6 +36,12 @@ if ( $model->isCardWithCustomer() ){ 'label' => 'Telefon', 'value' => $model->customer->phone ], + [ + 'label' => 'Fénykép', + 'value' => $model->customer->image1 ? Html::img( Url::base( ) . Image::thumb( $model->customer->image1->path,160,120 )) : 'Nincs kép', + 'format' => 'raw' + + ], ] ]) From f9ace803359e4f47079bf31f025352f1723acd46 Mon Sep 17 00:00:00 2001 From: Schneider Roland Date: Wed, 30 Dec 2015 12:17:41 +0100 Subject: [PATCH 3/8] change version to v.0.0.10 --- changelog.txt | 3 +++ common/config/params.php | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/changelog.txt b/changelog.txt index decdb0b..1e198c9 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,6 @@ +-0.0.10 + add webcam to customer create/update + display customer photo in reception panel -0.0.9 add rfid_key to card and key add typeahead to reception product/sale diff --git a/common/config/params.php b/common/config/params.php index afd5a75..87808e6 100644 --- a/common/config/params.php +++ b/common/config/params.php @@ -3,5 +3,5 @@ return [ 'adminEmail' => 'rocho02@gmail.com', 'supportEmail' => 'rocho02@gmail.com', 'user.passwordResetTokenExpire' => 3600, - 'version' => 'v0.0.9' + 'version' => 'v0.0.10' ]; From 1bcc435ab68f5b19ab273f4711681b509b9fda22 Mon Sep 17 00:00:00 2001 From: Schneider Roland Date: Wed, 30 Dec 2015 13:35:05 +0100 Subject: [PATCH 4/8] fix migration add column id_key to customer --- .../m151208_212339_alter__table__customer__add__column__key.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/console/migrations/m151208_212339_alter__table__customer__add__column__key.php b/console/migrations/m151208_212339_alter__table__customer__add__column__key.php index 7091c04..2a4cca8 100644 --- a/console/migrations/m151208_212339_alter__table__customer__add__column__key.php +++ b/console/migrations/m151208_212339_alter__table__customer__add__column__key.php @@ -7,7 +7,7 @@ class m151208_212339_alter__table__customer__add__column__key extends Migration { public function up() { - $this->addColumn("key", "id_key", "int"); + $this->addColumn("customer", "id_key", "int"); } public function down() From 72fc1396741f8f48479d85dbd7d07781f8266783 Mon Sep 17 00:00:00 2001 From: Schneider Roland Date: Thu, 31 Dec 2015 00:19:38 +0100 Subject: [PATCH 5/8] add money movement type 'in', add daily transfers --- common/messages/hu/frontend/transfer.php | 3 +- common/models/MoneyMovement.php | 30 +- common/models/Product.php | 4 +- common/models/Transfer.php | 19 +- frontend/components/FrontendMenuStructure.php | 1 + frontend/controllers/TransferController.php | 24 +- frontend/models/TransferListSearch.php | 375 +++++++++++++++++ frontend/views/money-movement/_form.php | 3 + frontend/views/money-movement/index.php | 4 + frontend/views/product/sale.php | 2 + frontend/views/transfer/_search_list.php | 59 +++ frontend/views/transfer/list.php | 379 ++++++++++++++++++ frontend/web/js/product.sell.js | 2 +- 13 files changed, 896 insertions(+), 9 deletions(-) create mode 100644 frontend/models/TransferListSearch.php create mode 100644 frontend/views/transfer/_search_list.php create mode 100644 frontend/views/transfer/list.php diff --git a/common/messages/hu/frontend/transfer.php b/common/messages/hu/frontend/transfer.php index 816b973..720d116 100644 --- a/common/messages/hu/frontend/transfer.php +++ b/common/messages/hu/frontend/transfer.php @@ -28,5 +28,6 @@ return [ 'Update' => 'Módosítás', 'Update {modelClass}: ' => '{modelClass} módosítás: ', 'pieces' => 'db', - 'Transfers Summary' => 'Bevétel' + 'Transfers Summary' => 'Bevétel', + 'Daily transfers' => 'Napi bevételek' ]; diff --git a/common/models/MoneyMovement.php b/common/models/MoneyMovement.php index 4c45d40..9024c0a 100644 --- a/common/models/MoneyMovement.php +++ b/common/models/MoneyMovement.php @@ -27,6 +27,7 @@ class MoneyMovement extends \yii\db\ActiveRecord { const TYPE_OUT = 10; + const TYPE_IN = 20; public $_account; @@ -47,7 +48,7 @@ class MoneyMovement extends \yii\db\ActiveRecord return ArrayHelper::merge( [ [ 'class' => TimestampBehavior::className(), - 'value' => function(){ return date('Y-m-d H:i:s' ); } + 'value' => function(){ return date('Y-m-d H:i:s' , time()); } ], [ 'class' => AccountAwareBehavior::className(), @@ -65,10 +66,11 @@ class MoneyMovement extends \yii\db\ActiveRecord { return [ [['id_account', 'name', 'money'], 'required'], - [['id_account' , 'money'], 'integer'], + [['id_account' , 'money'], 'integer' , 'min' => 0], [['name'], 'string', 'max' => 64], [['comment'], 'string', 'max' => 255], [['id_account'], 'validateAccount'], + [['type'] , 'in','range' => array_keys(MoneyMovement::types())], ]; } @@ -91,6 +93,7 @@ class MoneyMovement extends \yii\db\ActiveRecord 'id_user' => Yii::t('common/money-movement', 'Id User'), 'name' => Yii::t('common/money-movement', 'Name'), 'type' => Yii::t('common/money-movement', 'Type'), + 'humanType' => Yii::t('common/money-movement', 'Type'), 'money' => Yii::t('common/money-movement', 'Money'), 'comment' => Yii::t('common/money-movement', 'Comment'), 'created_at' => Yii::t('common/money-movement', 'Created At'), @@ -100,6 +103,7 @@ class MoneyMovement extends \yii\db\ActiveRecord ]; } + public function afterSave($insert, $changedAttributes){ parent::afterSave($insert, $changedAttributes); if ( $insert) { @@ -114,4 +118,26 @@ class MoneyMovement extends \yii\db\ActiveRecord $transfer->save(); } + public static function types(){ + return [ + self::TYPE_IN => "Betét", + self::TYPE_OUT => "Kivét", + + ]; + } + + public static function typeName($type){ + $types = MoneyMovement::types(); + $result = ""; + if ( array_key_exists($type, $types)){ + $result = $types[$type]; + } + return $result; + } + + + public function getHumanType(){ + return self::typeName($this->type); + } + } diff --git a/common/models/Product.php b/common/models/Product.php index 94c04f7..21bd74a 100644 --- a/common/models/Product.php +++ b/common/models/Product.php @@ -118,9 +118,9 @@ class Product extends \common\models\BaseFitnessActiveRecord { $warehouses = null; if ( $forceIncludeObjectWithId == null){ - $warehouses = Product::find()->andWhere(['status' => Product::STATUS_ACTIVE])->all(); + $warehouses = Product::find()->andWhere(['status' => Product::STATUS_ACTIVE])->orderBy(['product.name' => SORT_ASC])->all(); }else{ - $warehouses = Product::find()->andWhere( ['or', ['status' => Product::STATUS_ACTIVE], ['id_product' => $forceIncludeObjectWithId ] ])->all(); + $warehouses = Product::find()->andWhere( ['or', ['status' => Product::STATUS_ACTIVE], ['id_product' => $forceIncludeObjectWithId ] ])->orderBy(['product.name' => SORT_ASC])->all(); } return $warehouses; diff --git a/common/models/Transfer.php b/common/models/Transfer.php index e76efaf..d0f179e 100644 --- a/common/models/Transfer.php +++ b/common/models/Transfer.php @@ -247,6 +247,19 @@ class Transfer extends \common\models\BaseFitnessActiveRecord 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 = ""; @@ -315,7 +328,11 @@ class Transfer extends \common\models\BaseFitnessActiveRecord $transfer->type = Transfer::TYPE_MONEY_MOVEMENT_OUT; $transfer->status = Transfer::STATUS_PAID; - $transfer->direction = Transfer::DIRECTION_OUT; + 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; diff --git a/frontend/components/FrontendMenuStructure.php b/frontend/components/FrontendMenuStructure.php index 78e2f4b..c675559 100644 --- a/frontend/components/FrontendMenuStructure.php +++ b/frontend/components/FrontendMenuStructure.php @@ -67,6 +67,7 @@ class FrontendMenuStructure{ ['label' => Yii::t('frontend/account-state','Open account state'), 'url' => ['/account-state/open'] ], ['label' => Yii::t('frontend/account-state','Close account state'), 'url' => ['/account-state/close'] ], ['label' => Yii::t('frontend/money-movement','Money movements'), 'url' => [ '/money-movement/index', 'MoneyMovementSearch[start]' => $this->start, 'MoneyMovementSearch[end]' => $this->tomorrow ] ], + ['label' => Yii::t('frontend/transfer','Daily transfers'), 'url' => [ '/transfer/list', 'TransferListSearch[start]' => $this->start, 'TransferListSearch[end]' => $this->tomorrow ] ], ]; if ( $isadmin || Yii::$app->user->can('reception.transfers') ){ diff --git a/frontend/controllers/TransferController.php b/frontend/controllers/TransferController.php index 11ae4f6..2d57342 100644 --- a/frontend/controllers/TransferController.php +++ b/frontend/controllers/TransferController.php @@ -10,6 +10,7 @@ use yii\web\NotFoundHttpException; use yii\filters\VerbFilter; use frontend\models\TransferMoneyMovementSearch; use common\models\Account; +use frontend\models\TransferListSearch; /** * TransferController implements the CRUD actions for Transfer model. @@ -55,13 +56,31 @@ class TransferController extends Controller $dataProvider = $searchModel->search(Yii::$app->request->queryParams); $searchModel->totalsTransfers(Yii::$app->request->queryParams); - - return $this->render('index', [ 'searchModel' => $searchModel, 'dataProvider' => $dataProvider, ]); + + } + + /** + * Lists all Transfer models. + * @return mixed + */ + public function actionList() + { + $searchModel = new TransferListSearch(); + $searchModel->accounts = Account::read(); + $searchModel->load(Yii::$app->request->queryParams); + + $searchModel->search(Yii::$app->request->queryParams); + + + return $this->render('list', [ + 'searchModel' => $searchModel, + ]); + } /** @@ -76,6 +95,7 @@ class TransferController extends Controller ]); } + /** * Creates a new Transfer model. * If creation is successful, the browser will be redirected to the 'view' page. diff --git a/frontend/models/TransferListSearch.php b/frontend/models/TransferListSearch.php new file mode 100644 index 0000000..7472a60 --- /dev/null +++ b/frontend/models/TransferListSearch.php @@ -0,0 +1,375 @@ + 0, 'accounts' =>[] ]; +// public $totalsCreatedAtNotPaid= ['total' => 0, 'accounts' =>[]]; +// public $totalsCreatedAtPaid= ['total' => 0, 'accounts' =>[]]; +// public $totalsPaidAt= ['total' => 0, 'accounts' =>[]]; +// public $totalsPaidAtNotCreatedAt= ['total' => 0, 'accounts' =>[]]; + + + public $totals; + + public $accounts; + + public $types; + + + /** + * all money gained with ticket sell + * */ + public $ticketMoney; + /** + * all money gained with product sell + * */ + public $productMoney; + /** + * all money gained with product sell grouped by category + * */ + public $productMoneies; + /** + * all money lost by money movement + * */ + public $moneyMovementMoneis; + public $moneyMovementMoney; + /** + * total gained money + * */ + public $total; + + /** + * ticket sale statisitc + * */ + public $ticketStats; + + /** + * money movements by type + * */ + public $moneyMovementsByType; + + public $tickets; + /** + * all product transfer + * */ + public $products; + public $moneyMovements; + + public $productsByCategory; + + + /** + * @inheritdoc + */ + public function rules() + { + return [ + + [[ 'start', ], 'date', 'format' =>Yii::$app->formatter->datetimeFormat , 'timestampAttribute' => 'timestampStart' ,'timestampAttributeFormat' => 'yyyy-MM-dd HH:mm' ,'timeZone' => 'UTC' ], + [[ 'end' , ], 'date' ,'format' =>Yii::$app->formatter->datetimeFormat , 'timestampAttribute' => 'timestampEnd' ,'timestampAttributeFormat' => 'yyyy-MM-dd HH:mm' ,'timeZone' => 'UTC' ], + + [ [ 'id_account' ] , 'integer'], + ['types', 'each', 'rule' => ['integer']], + ]; + } + + + + /** + * Creates data provider instance with search query applied + * + * @param array $params + * + * @return ActiveDataProvider + */ + public function search($params) + { + $query = Transfer::find(); + + $dataProvider = new ActiveDataProvider([ + 'query' => $query, + ]); + + + + $this->load($params); + + + if (!$this->validate()) { + } + + $this->readTicketMoney(); + $this->readProductsMoney(); + $this->readMoneyMovementMoney(); + $this->calcTotal(); + + $this->readProductsByCategory(); + $this->readProductsByCategoryDetailed(); + $this->readTicketStas(); + $this->readMoneyMovementsStats(); + + + $this->readTickets(); + $this->readProducts(); + $this->readMoneyMovements(); + + } + + protected function calcTotal(){ + $this->total = 0; + $this->total += $this->ticketMoney; + $this->total += $this->productMoney; + $this->total += $this->moneyMovementMoneis; + } + + + protected function addQueryFilters($query){ + $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->andWhere(['transfer.id_user' => Yii::$app->user->id ]); + + $query->andFilterWhere([ + 'transfer.id_account' => $this->id_account, + 'transfer.type' => $this->type, + 'transfer.id_user' => $this->id_user, + ]); + + $created_condition = ['and',[ '>=', 'transfer.created_at', $this->timestampStart ] ,[ '<', 'transfer.created_at', $this->timestampEnd ] ]; + $paid_condition = ['and',[ '>=', 'transfer.paid_at', $this->timestampStart ] ,[ '<', 'transfer.paid_at', $this->timestampEnd ] ]; + + + $query->andFilterWhere(['or' , $created_condition , $paid_condition]); + + $query->andWhere(['transfer.status' => Transfer::STATUS_PAID]); + + } + + + protected function readTicketStas(){ + + $query = (new \yii\db\Query()); + $query->select(['ticket_type.name as ticket_type_name' , 'coalesce(sum(abs(transfer.count)),0) AS ticket_count', 'coalesce(sum(abs(transfer.money)),0) AS ticket_money']); + $query->from('transfer'); + $query->andWhere(['transfer.type' => Transfer::TYPE_TICKET]); + $query->innerJoin("ticket", "ticket.id_ticket = transfer.id_object"); + $query->innerJoin("ticket_type", "ticket.id_ticket_type = ticket_type.id_ticket_type"); + + $query->groupBy(['ticket_type.id_ticket_type','ticket_type.name']); + $this->addQueryFilters($query); + + + $this->ticketStats = $query->all(); + } + + + protected function readTicketMoney(){ + + $query = (new \yii\db\Query()); + $query->select([' coalesce(sum(abs(transfer.money)),0) AS ticket_money']); + $query->from('transfer'); + $query->andWhere(['transfer.type' => Transfer::TYPE_TICKET]); + $query->innerJoin("ticket", "ticket.id_ticket = transfer.id_object"); + $this->addQueryFilters($query); + $this->ticketMoney = $query->scalar(); + } + + protected function readProductsByCategory(){ + + + $query = (new \yii\db\Query()); + $query->select(['coalesce(sum(transfer.money),0) AS product_money', 'coalesce(sum(transfer.count),0) as category_count', 'product_category.name as category_name']); + $query->from('transfer'); + $query->groupBy(['product_category.id_product_category','product_category.name']); + $query->andWhere(['transfer.type' => Transfer::TYPE_PRODUCT]); + $query->innerJoin("sale", "sale.id_sale = transfer.id_object"); + $query->innerJoin("product", "sale.id_product = product.id_product"); + $query->innerJoin("product_category", "product.id_product_category = product_category.id_product_category"); + $this->addQueryFilters($query); + + $this->productMoneies = $query->all(); + + } + + + protected function readProductsByCategoryDetailed(){ + + $formatted = []; + $formatted['categories'] = []; + $formatted['total'] = 0; + $prevCategory = null; + $curCategory = null; + + $category = null; + + $query = (new \yii\db\Query()); + $query->select(['product_category.id_product_category as product_category_id','product_category.name as product_category_name', 'product.name as product_name' ,'coalesce(sum(transfer.money),0) AS product_money', 'coalesce(sum(transfer.count),0) as product_count']); + $query->from('transfer'); + $query->groupBy(['product.id_product','product.name','product_category.id_product_category','product_category.name']); + $query->andWhere(['transfer.type' => Transfer::TYPE_PRODUCT]); + $query->innerJoin("sale", "sale.id_sale = transfer.id_object"); + $query->innerJoin("product", "sale.id_product = product.id_product"); + $query->innerJoin("product_category", "product.id_product_category = product_category.id_product_category"); + $query->orderBy(['product_category.name' => SORT_ASC,'product.name' => SORT_ASC]); + $this->addQueryFilters($query); + + $result = $query->all(); + + foreach ($result as $row){ + $curCategory = $row['product_category_id']; + if ( $curCategory != $prevCategory ){ + //store last category + if ( $category != null ){ + $formatted['categories'][] = $category; + } + $prevCategory = $curCategory; + //create new category + $category = []; + $category['category'] = []; + $category['category']['name'] = $row['product_category_name']; + $category['category']['id'] = $row['product_category_id']; + $category['products'] = []; + $category['total'] = 0; + + } + $category['products'][] = $row; + $category['total'] += $row['product_money']; + $formatted['total'] += $row['product_money']; + + } + + if ( $category != null ){ + $formatted['categories'][]= $category; + } + + $this->productsByCategory = $formatted; + + } + + protected function readProductsMoney(){ + + + $query = (new \yii\db\Query()); + $query->select(['coalesce(sum(transfer.money),0) AS product_money' ]); + $query->from('transfer'); + $query->andWhere(['transfer.type' => Transfer::TYPE_PRODUCT]); + $query->innerJoin("sale", "sale.id_sale = transfer.id_object"); + $this->addQueryFilters($query); + + $this->productMoney = $query->scalar(); + + } + + + protected function readMoneyMovementMoney(){ + $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 money_movement_money']); + $query->from('transfer'); + $query->andWhere(['transfer.type' => Transfer::TYPE_MONEY_MOVEMENT_OUT]); + $query->innerJoin("money_movement", "money_movement.id_money_movement = transfer.id_object"); + $this->addQueryFilters($query); + + $this->moneyMovementMoneis = $query->scalar(); + } + protected function readMoneyMovementsStats(){ + $query = (new \yii\db\Query()); + $query->select([ 'money_movement.type as money_movement_type', ' coalesce(count(transfer.id_transfer),0) AS money_movement_count', 'coalesce(sum( case when transfer.direction = ' . Transfer::DIRECTION_IN. ' then transfer.money else -1 * transfer.money end ),0) AS money_movement_money']); + $query->from('transfer'); + $query->andWhere(['transfer.type' => Transfer::TYPE_MONEY_MOVEMENT_OUT]); + $query->innerJoin("money_movement", "money_movement.id_money_movement = transfer.id_object"); + $query->groupBy(['money_movement.type']); + $this->addQueryFilters($query); + + $this->moneyMovementsByType = $query->all(); + for ($i = 0; $i < count($this->moneyMovementsByType) ;$i++ ){ + $this->moneyMovementsByType[$i]['name'] = MoneyMovement::typeName($this->moneyMovementsByType[$i]['money_movement_type']); + } + } + + protected function readTickets(){ + $query = (new \yii\db\Query()); + $query->select(['account.name as account_name','ticket_type.name as ticket_type_name' , 'transfer.count AS ticket_count', 'transfer.money AS ticket_money','transfer.item_price AS ticket_item_price', 'transfer.created_at as ticket_created_at','transfer.paid_at as ticket_paid_at']); + $query->from('transfer'); + $query->andWhere(['transfer.type' => Transfer::TYPE_TICKET]); + $query->innerJoin("ticket", "ticket.id_ticket = transfer.id_object"); + $query->innerJoin("ticket_type", "ticket.id_ticket_type = ticket_type.id_ticket_type"); + $query->innerJoin("account", "transfer.id_account = account.id_account"); + $query->orderBy(['transfer.created_at' => SORT_ASC]); + $this->addQueryFilters($query); + + + $this->tickets = $query->all(); + + for ($i = 0; $i < count($this->tickets) ;$i++ ){ + $this->tickets[$i]['ticket_created_at'] = Yii::$app->formatter->asDatetime($this->tickets[$i]['ticket_created_at'], 'yyyy.MM.dd HH:mm:ss'); + $this->tickets[$i]['ticket_paid_at'] = empty($this->tickets[$i]['ticket_paid_at'] ) ? '-' : Yii::$app->formatter->asDatetime($this->tickets[$i]['ticket_paid_at'], 'yyyy.MM.dd HH:mm:ss'); + } + + } + + protected function readProducts(){ + + $query = (new \yii\db\Query()); + $query->select([ 'account.name as account_name' , 'product_category.name as product_category_name', 'product.name as product_name', 'transfer.money AS product_money', 'transfer.count AS product_count', 'transfer.money AS product_money','transfer.item_price AS product_item_price', 'transfer.created_at as product_created_at','transfer.paid_at as product_paid_at']); + $query->from('transfer'); + $query->andWhere(['transfer.type' => Transfer::TYPE_PRODUCT]); + $query->innerJoin("sale", "sale.id_sale = transfer.id_object"); + $query->innerJoin("product", "sale.id_product = product.id_product"); + $query->innerJoin("product_category", "product.id_product_category = product_category.id_product_category"); + $query->innerJoin("account", "transfer.id_account = account.id_account"); + $query->orderBy(['transfer.created_at' => SORT_ASC]); + $this->addQueryFilters($query); + + $this->products = $query->all(); + + for ($i = 0; $i < count($this->products) ;$i++ ){ + $this->products[$i]['product_created_at'] = Yii::$app->formatter->asDatetime($this->products[$i]['product_created_at'], 'yyyy.MM.dd HH:mm:ss'); + $this->products[$i]['product_paid_at'] = empty($this->products[$i]['product_paid_at'] ) ? '-' : Yii::$app->formatter->asDatetime($this->products[$i]['product_paid_at'], 'yyyy.MM.dd HH:mm:ss'); + } + + } + + protected function readMoneyMovements(){ + $query = (new \yii\db\Query()); + $query->select([ 'account.name as account_name', 'transfer.direction as transfer_direction' ,'money_movement.type as money_movement_type', 'transfer.money AS money_movement_money', 'money_movement.name as money_movement_name','transfer.created_at as money_movement_created_at', ]); + $query->from('transfer'); + $query->andWhere(['transfer.type' => Transfer::TYPE_MONEY_MOVEMENT_OUT]); + $query->innerJoin("money_movement", "money_movement.id_money_movement = transfer.id_object"); + $query->innerJoin("account", "transfer.id_account = account.id_account"); + $query->orderBy(['transfer.created_at' => SORT_ASC]); + $this->addQueryFilters($query); + + $this->moneyMovements = $query->all(); + + for ($i = 0; $i < count($this->moneyMovements) ;$i++ ){ + $this->moneyMovements[$i]['money_movement_type_name'] = MoneyMovement::typeName($this->moneyMovements[$i]['money_movement_type']); + $this->moneyMovements[$i]['money_movement_created_at'] = Yii::$app->formatter->asDatetime($this->moneyMovements[$i]['money_movement_created_at'], 'yyyy.MM.dd HH:mm:ss'); + $this->moneyMovements[$i]['signed_money'] = Transfer::toSignedMoney($this->moneyMovements[$i]['transfer_direction'],$this->moneyMovements[$i]['money_movement_money']); + } + } + + +} diff --git a/frontend/views/money-movement/_form.php b/frontend/views/money-movement/_form.php index a9680de..8723049 100644 --- a/frontend/views/money-movement/_form.php +++ b/frontend/views/money-movement/_form.php @@ -3,6 +3,7 @@ use yii\helpers\Html; use yii\widgets\ActiveForm; use frontend\components\HtmlHelper; +use common\models\MoneyMovement; /* @var $this yii\web\View */ /* @var $model common\models\MoneyMovement */ @@ -18,6 +19,8 @@ $accountOptions = HtmlHelper::mkAccountOptions($accounts); field($model, 'id_account')->dropDownList($accountOptions) ?> + + field($model, 'type')->dropDownList(MoneyMovement::types()) ?> field($model, 'name')->textInput(['maxlength' => true]) ?> diff --git a/frontend/views/money-movement/index.php b/frontend/views/money-movement/index.php index ef198b8..3c431b0 100644 --- a/frontend/views/money-movement/index.php +++ b/frontend/views/money-movement/index.php @@ -25,6 +25,10 @@ $this->params['breadcrumbs'][] = $this->title; 'accountName', 'userName', + [ + 'attribute' => 'type', + 'value' =>'humanType' + ], 'name', 'money', 'created_at:datetime', diff --git a/frontend/views/product/sale.php b/frontend/views/product/sale.php index 82ebfd8..b857c3e 100644 --- a/frontend/views/product/sale.php +++ b/frontend/views/product/sale.php @@ -78,6 +78,8 @@ $this->params['breadcrumbs'][] = Yii::t('frontend/product', 'Sale'); .table-transfers .product-money{ width: 100px; } + .typeahead.dropdown-menu{ + } diff --git a/frontend/views/transfer/_search_list.php b/frontend/views/transfer/_search_list.php new file mode 100644 index 0000000..7516ffd --- /dev/null +++ b/frontend/views/transfer/_search_list.php @@ -0,0 +1,59 @@ + + +'Mind']+ HtmlHelper::mkAccountOptions( $model->accounts ); +?> + + diff --git a/frontend/views/transfer/list.php b/frontend/views/transfer/list.php new file mode 100644 index 0000000..509336b --- /dev/null +++ b/frontend/views/transfer/list.php @@ -0,0 +1,379 @@ +title = Yii::t ( 'frontend/transfer', 'Daily transfers' ); +$this->params ['breadcrumbs'] [] = $this->title; +?> + + +
+ +

title) ?>

+ render('_search_list', ['model' => $searchModel]); ?> + + +
+ + + + + +
+
+

Egyszerű összesítés

+ + + + + + + + + + + + + + + + + + + +
BérletekticketMoney?> FT
TermékekproductMoney?> FT
PénzmozgásokmoneyMovementMoneis?> FT
Végösszegtotal?> FT
+
+
+

Közepes összesítés

+ +

Bérletek típus szerint

+ + + + + + + + + + ticketStats as $ticketStat ) { + ?> + + + + + + + +
Bérlet típusMennyiségÖsszeg
Db FT
+ +
+
+ Összesen: ticketMoney; ?> Ft + +
+
+

Termékek kategória szerint

+ + + + + + + + + + productMoneies as $pm ) { + ?> + + + + + + + +
Termék kategóriaMennyiségÖsszeg
Db FT
+
+
+ Összesen: productMoney; ?> Ft + +
+
+ +

Termékek kategória szerint részletes

+ + productsByCategory['categories'] as $categoryHolder ){ + + $products = $categoryHolder['products']; + ?> +

+ + + + + + + + + + + + + + + + + + + + + + + + + +
TermékMennyiségÖsszeg
Db FT
FT
+ +
+
+ Összesen: + productsByCategory['total']; + ?> +
+
+ +

Pénzmozgások típus szerint

+ + + + + + + + + + moneyMovementsByType as $mmStat ) { + ?> + + + + + + + +
Pénzmozgás típusMennyiségÖsszeg
Db FT
+
+
+ Összesen: moneyMovementMoneis; ?> Ft + +
+
+ +
+
+ Végösszeg: total; ?> Ft + +
+
+
+
+

Részletes összesítés

+

Bérletek

+ + + + + + + + + + + + + + tickets as $t ){?> + + + + + + + + + + + + +
KiadvaFizetveKasszaBérlet típusEgység árMennyiségÖsszeg
Ft Db FT
+ tickets ) == 0 ) { + ?> + Nincs találat + + +
+
+ Összesen: ticketMoney; ?> Ft + +
+
+ +

Termék eladások

+ + + + + + + + + + + + + + + products as $p ){?> + + + + + + + + + + + + + +
KiadvaFizetveKasszaKategóriaTermékEgység árMennyiségÖsszeg
Ft Db FT
+ products ) == 0 ) { + ?> + Nincs találat + + +
+
+ Összesen: productMoney; ?> Ft + +
+
+ + +

Pénzmozgások

+ + + + + + + + + + + + moneyMovements as $p ){?> + + + + + + + + + + +
DátumKasszaNévTípusÖsszeg
Ft
+ moneyMovements ) == 0 ) { + ?> + Nincs találat + + +
+
+ Összesen: moneyMovementMoneis; ?> Ft + +
+
+ + +
+
+ Végösszeg: total; ?> Ft + +
+
+
+
+ +
+ + + + + +
diff --git a/frontend/web/js/product.sell.js b/frontend/web/js/product.sell.js index dcdff21..0de8079 100644 --- a/frontend/web/js/product.sell.js +++ b/frontend/web/js/product.sell.js @@ -538,7 +538,7 @@ function ProductSell(o){ var $input = $('#product_search'); $input.typeahead({source: app.defaults.products, autoSelect: true, - items: 12, + items: 20, minLength: 3, // displayText: function (item){ // return item. From f59eadd8cca6b9e2d401219ba0df573d9231612b Mon Sep 17 00:00:00 2001 From: Schneider Roland Date: Thu, 31 Dec 2015 13:52:22 +0100 Subject: [PATCH 6/8] fix account_state ( collection_money ), display product/ticket on reception only for selected account, add daily transfers (reception/admin) --- backend/components/AdminMenuStructure.php | 7 +- backend/controllers/TransferController.php | 20 +- backend/models/TransferListSearch.php | 21 + backend/views/layouts/content.php | 5 + backend/views/transfer/_search_list.php | 63 +++ backend/views/transfer/list.php | 399 ++++++++++++++++++ common/config/main.php | 7 +- common/models/AccountState.php | 81 +++- common/models/Product.php | 29 +- common/models/TicketType.php | 6 +- common/models/Transfer.php | 19 +- common/models/TransferListSearch.php | 390 +++++++++++++++++ common/views/common/_account_statistic.php | 7 + ...t_state__add__column__collection_money.php | 27 ++ .../AccountStateBanknoteCountWidget.php | 49 ++- frontend/components/FrontendMenuStructure.php | 7 +- .../controllers/AccountStateController.php | 3 + frontend/controllers/ProductController.php | 5 +- frontend/controllers/TicketController.php | 2 +- frontend/models/TransferListSearch.php | 356 +--------------- frontend/views/account-state/close.php | 1 - frontend/views/layouts/main.php | 9 +- frontend/views/product/sale.php | 3 +- frontend/views/ticket/create.php | 1 + frontend/views/transfer/_view.php | 4 + frontend/views/transfer/list.php | 36 +- 26 files changed, 1153 insertions(+), 404 deletions(-) create mode 100644 backend/models/TransferListSearch.php create mode 100644 backend/views/transfer/_search_list.php create mode 100644 backend/views/transfer/list.php create mode 100644 common/models/TransferListSearch.php create mode 100644 console/migrations/m151231_095117_alter__table__account_state__add__column__collection_money.php diff --git a/backend/components/AdminMenuStructure.php b/backend/components/AdminMenuStructure.php index fc27946..7652e58 100644 --- a/backend/components/AdminMenuStructure.php +++ b/backend/components/AdminMenuStructure.php @@ -36,8 +36,8 @@ class AdminMenuStructure{ $today = \Yii::$app->formatter->asDate( strtotime('today UTC') ); $tomorrow = \Yii::$app->formatter->asDate( ( 60 *60 *24 + time())); - $todayDatetime = \Yii::$app->formatter->asDatetime( strtotime('today UTC') ); - $tomorrowDatetime = \Yii::$app->formatter->asDatetime( strtotime('tomorrow UTC') ); + $todayDatetime = \Yii::$app->formatter->asDatetime( strtotime('today') ); + $tomorrowDatetime = \Yii::$app->formatter->asDatetime( strtotime('tomorrow') ); ///////////////////////////// @@ -89,7 +89,8 @@ class AdminMenuStructure{ ///////////////////////////// $items = []; $items[] = ['label' => 'Tranzakciók', 'url' => ['/transfer/index' , 'TransferSearch[start]' =>$today,'TransferSearch[end]' => $tomorrow ] ]; - $items[] = ['label' => 'Bevétel', 'url' => ['/transfer/summary' , 'TransferSummarySearch[start]' =>$today,'TransferSummarySearch[end]' => $tomorrow ] ]; +// $items[] = ['label' => 'Bevétel', 'url' => ['/transfer/summary' , 'TransferSummarySearch[start]' =>$today,'TransferSummarySearch[end]' => $tomorrow ] ]; + $items[] = ['label' => 'Napi bevételek', 'url' => ['/transfer/list', 'TransferListSearch[start]' =>$todayDatetime,'TransferListSearch[end]' => $tomorrowDatetime ] ]; $items[] = ['label' => 'Kassza müveletek', 'url' => ['/account-state/index'] ]; $items[] = ['label' => 'Zárások', 'url' => ['/collection/index' , 'CollectionSearch[start]' =>$todayDatetime,'CollectionSearch[end]' => $tomorrowDatetime ] ]; $this->menuItems[] = ['label' => 'Pénzügy', 'url' => $this->emptyUrl, diff --git a/backend/controllers/TransferController.php b/backend/controllers/TransferController.php index b7f7217..441934c 100644 --- a/backend/controllers/TransferController.php +++ b/backend/controllers/TransferController.php @@ -10,6 +10,7 @@ use yii\filters\VerbFilter; use common\models\Account; use common\models\User; use backend\models\TransferSummarySearch; +use backend\models\TransferListSearch; /** * TransferController implements the CRUD actions for Transfer model. @@ -24,7 +25,7 @@ class TransferController extends \backend\controllers\BackendController 'rules' => [ // allow authenticated users [ - 'actions' => [ 'index','view','summary' ], + 'actions' => [ 'index','view','summary','list' ], 'allow' => true, 'roles' => ['admin','employee','reception'], ], @@ -58,7 +59,24 @@ class TransferController extends \backend\controllers\BackendController ]); } + /** + * Lists all Transfer models. + * @return mixed + */ + public function actionList() + { + $searchModel = new TransferListSearch(); + $searchModel->accounts = Account::read(); + $searchModel->users = User::read(); + $searchModel->search(Yii::$app->request->queryParams); + + + return $this->render('list', [ + 'searchModel' => $searchModel, + ]); + + } /** * Lists all Transfer models. diff --git a/backend/models/TransferListSearch.php b/backend/models/TransferListSearch.php new file mode 100644 index 0000000..0b3f50a --- /dev/null +++ b/backend/models/TransferListSearch.php @@ -0,0 +1,21 @@ +innerJoin("user_account_assignment",'transfer.id_account = user_account_assignment.id_account' ); + $query->andWhere(['user_account_assignment.id_user' => Yii::$app->user->id ]); + } + } + +} diff --git a/backend/views/layouts/content.php b/backend/views/layouts/content.php index d38d50d..e7c991c 100644 --- a/backend/views/layouts/content.php +++ b/backend/views/layouts/content.php @@ -22,5 +22,10 @@ use dmstr\widgets\Alert;
© name ?> params['version'] ?> Fitness - WebAdmin + +
+ Az oldalon szereplő adatok csak tájékoztató jellegűek. + Az adatok helyességéért és igazságtartalmáért felelősséget nem vállalunk. +
diff --git a/backend/views/transfer/_search_list.php b/backend/views/transfer/_search_list.php new file mode 100644 index 0000000..c5e6ddf --- /dev/null +++ b/backend/views/transfer/_search_list.php @@ -0,0 +1,63 @@ + + +'Mind']+ HtmlHelper::mkAccountOptions( $model->accounts ); + $userOptions = ['' => 'Mind'] + HtmlHelper::mkOptions($model->users,'id','username'); +?> + + diff --git a/backend/views/transfer/list.php b/backend/views/transfer/list.php new file mode 100644 index 0000000..b688f85 --- /dev/null +++ b/backend/views/transfer/list.php @@ -0,0 +1,399 @@ +title = Yii::t ( 'frontend/transfer', 'Daily transfers' ); +$this->params ['breadcrumbs'] [] = $this->title; +?> + + +
+ +

title) ?>

+ render('_search_list', ['model' => $searchModel]); ?> + + +
+ + + + + +
+
+

Egyszerű összesítés

+ + + + + + + + + + + + + + + + + + + +
BérletekticketMoney?> FT
TermékekproductMoney?> FT
PénzmozgásokmoneyMovementMoneis?> FT
Végösszegtotal?> FT
+
+
+

Közepes összesítés

+ +

Bérletek típus szerint

+ + + + + + + + + + ticketStats as $ticketStat ) { + ?> + + + + + + + +
Bérlet típusMennyiségÖsszeg
Db FT
+ +
+
+ Összesen: ticketMoney; ?> Ft + +
+
+

Termékek kategória szerint

+ + + + + + + + + + productMoneies as $pm ) { + ?> + + + + + + + +
Termék kategóriaMennyiségÖsszeg
Db FT
+
+
+ Összesen: productMoney; ?> Ft + +
+
+ +

Termékek kategória szerint részletes

+ + productsByCategory['categories'] as $categoryHolder ){ + + $products = $categoryHolder['products']; + ?> +

+ + + + + + + + + + + + + + + + + + + + + + + + + +
TermékMennyiségÖsszeg
Db FT
FT
+ +
+
+ Összesen: + productsByCategory['total']; + ?> +
+
+ +

Pénzmozgások típus szerint

+ + + + + + + + + + moneyMovementsByType as $mmStat ) { + ?> + + + + + + + +
Pénzmozgás típusMennyiségÖsszeg
Db FT
+
+
+ Összesen: moneyMovementMoneis; ?> Ft + +
+
+ +
+
+ Végösszeg: total; ?> Ft + +
+
+
+
+

Részletes összesítés

+ +

Bérletek

+ + + + + + + + + + + + + + + tickets as $t ){?> + + + + + + + + + + + + + +
KiadvaFizetveKasszaFelhasználóBérlet típusEgység árMennyiségÖsszeg
Ft Db FT
+ tickets ) == 0 ) { + ?> + Nincs találat + + +
+
+ Összesen: ticketMoney; ?> Ft + +
+
+ + +

Termék eladások

+ + + + + + + + + + + + + + + + products as $p ){?> + + + + + + + + + + + + + + +
KiadvaFizetveKasszaFelhasználóKategóriaTermékEgység árMennyiségÖsszeg
Ft Db FT
+ products ) == 0 ) { + ?> + Nincs találat + + +
+
+ Összesen: productMoney; ?> Ft + +
+
+ + +

Pénzmozgások

+ + + + + + + + + + + + + moneyMovements as $p ){?> + + + + + + + + + + + +
DátumKasszaFelhasználóNévTípusÖsszeg
Ft
+ moneyMovements ) == 0 ) { + ?> + Nincs találat + + +
+
+ Összesen: moneyMovementMoneis; ?> Ft + +
+
+ + +
+
+ Végösszeg: total; ?> Ft + +
+
+
+
+ +
+ + + + + +
diff --git a/common/config/main.php b/common/config/main.php index bbc7e4a..3dc1cda 100644 --- a/common/config/main.php +++ b/common/config/main.php @@ -1,7 +1,10 @@ dirname(dirname(__DIR__)) . '/vendor', // 'language' => 'hu-HU', + 'timezone' => 'Europe/Budapest', 'language' => 'hu', 'components' => [ 'cache' => [ @@ -21,8 +24,8 @@ return [ 'datetimeFormat' => 'yyyy.MM.dd HH:mm', 'timeFormat' => 'HH:mm', 'locale' => 'hu-Hu', - 'timeZone' => 'UTC', - 'defaultTimeZone' => 'UTC' , + 'timeZone' => 'EUROPE/BUDAPEST', + 'defaultTimeZone' => 'EUROPE/BUDAPEST', 'nullDisplay' => "-", ], 'authManager' => [ diff --git a/common/models/AccountState.php b/common/models/AccountState.php index 8368dfd..6ee5cfb 100644 --- a/common/models/AccountState.php +++ b/common/models/AccountState.php @@ -26,6 +26,7 @@ use yii\helpers\ArrayHelper; * @property integer $banknote_10000_ft * @property integer $banknote_20000_ft * @property integer $id_user + * @property integer $collection_money * @property string $created_at * @property string $updated_at */ @@ -53,6 +54,7 @@ class AccountState extends \common\models\BaseFitnessActiveRecord [['id_account', 'type', 'money', 'banknote_5_ft', 'banknote_10_ft', 'banknote_20_ft', 'banknote_50_ft', 'banknote_100_ft', 'banknote_200_ft', 'banknote_500_ft', 'banknote_1000_ft', 'banknote_2000_ft', 'banknote_5000_ft', 'banknote_10000_ft', 'banknote_20000_ft' ], 'integer'], [['comment' ], 'string' ,'max' => 255], [['prev_state' ], 'integer'], + [['id_account'] , 'validatePrevState'], ]; } @@ -87,6 +89,11 @@ class AccountState extends \common\models\BaseFitnessActiveRecord ]; } + public function validatePrevState($attribute,$params){ + + + } + public static function banknoteValues() { return [ @@ -124,6 +131,10 @@ class AccountState extends \common\models\BaseFitnessActiveRecord return $this->hasOne( User::className(), ["id" =>"id_user" ] ); } + public function getPrevObject(){ + return $this->hasOne( AccountState::className(), ["id_account_state" =>"prev_state" ] ); + } + public function getUserName(){ $result = ""; $user = $this->user; @@ -164,40 +175,45 @@ class AccountState extends \common\models\BaseFitnessActiveRecord * @param $type int the type of accountstate to load * @param $user $id of user to load the account * */ - public static function readLast($type, $user = null){ + public static function readLast($type, $user = null,$account = null){ $result = null; $query = AccountState::find(); - //filter user - if ( isset($user)){ - $query->innerJoinWith("account"); - $query->innerJoinWith("account.userAccountAssignments"); - $query->andWhere(['user_account_assignment.id_user' => Yii::$app->user->id]); - } //filter type if ( isset($type)){ $query->andWhere(['account_state.type' => $type]); } - //filter last - $query->join("INNER JOIN ", - "(select max(created_at) as cdate, id_account from account_state group by id_account) as sq1" - ,"sq1.cdate = account_state.created_at and sq1.id_account = account_state.id_account"); + if ( $account ){ + $query->andWhere(["account_state.id_account" => $account ]); + } + + $query->limit(1); + $query->orderBy(['created_at' => SORT_DESC]); - $result = $query->all(); + $result = $query->one(); return $result; } function beforeSave($insert){ $result = parent::beforeSave($insert); if ( $result ){ + $start = null; + $end = null; $prev = null; + $this->prev_money = 0; - if ( isset($this->prev_state) ){ - $prev = AccountState::findOne($this->prev_state); + if ( $this->type == AccountState::TYPE_CLOSE){ + $lastOpen = AccountState::readLast(AccountState::TYPE_OPEN,null, $this->id_account); + if ( $lastOpen != null ){ + $start = $lastOpen->created_at; + $this->prev_state = $lastOpen->id_account_state; + $this->prev_money = $lastOpen->money; + } + $end = date("Y-m-d H:i:s"); + $this->collection_money = Transfer::readPaid($start, $end, Yii::$app->user->id); + + } - if ( $prev != null){ - $this->prev_money = $prev->money; - } } return $result; @@ -205,12 +221,39 @@ class AccountState extends \common\models\BaseFitnessActiveRecord public function hasDifferenceToPrevState(){ $result = false; - if ( isset( $this->prev_state ) && $this->type == self::TYPE_OPEN){ - $result = $this->prev_money != $this->money; + if ( $this->type == self::TYPE_CLOSE){ + $result = ( $this->prev_money + $this->collection_money) != $this->money; } return $result; } + public function hasPlus(){ + $result = false; + if ( $this->type == self::TYPE_CLOSE){ + $result = ( $this->prev_money + $this->collection_money) < $this->money; + } + return $result; + } + + public function hasMinus(){ + $result = false; + if ( $this->type == self::TYPE_CLOSE){ + $result =( $this->prev_money + $this->collection_money) > $this->money; + } + return $result; + } + + public function getSignedDiff(){ + $result = $this->money - ( $this->prev_money + $this->collection_money); + return $result; + } + + public function getExpected(){ + $result = $this->prev_money + $this->collection_money ; + return $result; + } + + public static function readLastForUser($type){ return static::readLast($type, Yii::$app->user->id); } diff --git a/common/models/Product.php b/common/models/Product.php index 21bd74a..057bddb 100644 --- a/common/models/Product.php +++ b/common/models/Product.php @@ -126,7 +126,33 @@ class Product extends \common\models\BaseFitnessActiveRecord { return $warehouses; } - public static function findProduct($query){ + /** + * $param int $forceIncludeAccount id warehouse, that should be included in list, even if it is inactive + * */ + public static function readForDefaultAccount($forceIncludeObjectWithId = null){ + $result = null; + + $account = Account::readDefault(); + + if ( $forceIncludeObjectWithId == null){ + $query = Product::find()->andWhere(['status' => Product::STATUS_ACTIVE])->orderBy(['product.name' => SORT_ASC]); + if ( $account ) + $query->andWhere(["product.id_account" => $account]); + + $result = $query->all(); + }else{ + $query = Product::find()->andWhere( ['or', ['status' => Product::STATUS_ACTIVE], ['id_product' => $forceIncludeObjectWithId ] ])->orderBy(['product.name' => SORT_ASC]); + if ( $account ) + $query->andWhere(["product.id_account" => $account]); + + $result = $query->all(); + + } + + return $result; + } + + public static function findProduct($query, $account = null){ $result = []; $product = null; @@ -137,6 +163,7 @@ class Product extends \common\models\BaseFitnessActiveRecord { ['barcode' => $query ], ] )->andWhere(['status' =>Product::STATUS_ACTIVE]) + ->andFilterWhere(['product.id_account' => $account]) ->all(); diff --git a/common/models/TicketType.php b/common/models/TicketType.php index efe3c1b..831514e 100644 --- a/common/models/TicketType.php +++ b/common/models/TicketType.php @@ -198,13 +198,13 @@ class TicketType extends \common\models\BaseFitnessActiveRecord { /** * $param int $forceIncludeAccount id account, that should be included in list, even if it is inactive * */ - public static function read($forceIncludeObjectWithId = null){ + public static function read($forceIncludeObjectWithId = null, $account = null){ $ticketTypes = null; if ( $forceIncludeObjectWithId == null){ - $ticketTypes = TicketType::find()->andWhere(['status' => self::STATUS_ACTIVE])->all(); + $ticketTypes = TicketType::find()->andWhere(['status' => self::STATUS_ACTIVE])->andFilterWhere(['ticket_type.id_account' => $account])->all(); }else{ - $ticketTypes = TicketType::find()->andWhere( ['or', ['status' => self::STATUS_ACTIVE], ['id_ticket_type' => $forceIncludeObjectWithId ] ])->all(); + $ticketTypes = TicketType::find()->andWhere( ['or', ['status' => self::STATUS_ACTIVE], ['id_ticket_type' => $forceIncludeObjectWithId ] ])->andFilterWhere(['ticket_type.id_account' => $account])->all(); } return $ticketTypes; diff --git a/common/models/Transfer.php b/common/models/Transfer.php index d0f179e..6785ea1 100644 --- a/common/models/Transfer.php +++ b/common/models/Transfer.php @@ -59,7 +59,7 @@ class Transfer extends \common\models\BaseFitnessActiveRecord return ArrayHelper::merge( [ [ 'class' => TimestampBehavior::className(), - 'value' => function(){ return date('Y-m-d H:i:s' ); } + 'value' => function(){ return date('Y-m-d H:i:s' ); } ], [ 'class' => DiscountAwareBehavior::className(), @@ -168,7 +168,7 @@ class Transfer extends \common\models\BaseFitnessActiveRecord }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; + $result = $this->moneyMovement->humanType; } return $result; } @@ -677,4 +677,19 @@ class Transfer extends \common\models\BaseFitnessActiveRecord 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->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]); + + return $query->scalar(); + } } diff --git a/common/models/TransferListSearch.php b/common/models/TransferListSearch.php new file mode 100644 index 0000000..4e7f64e --- /dev/null +++ b/common/models/TransferListSearch.php @@ -0,0 +1,390 @@ + 0, 'accounts' =>[] ]; +// public $totalsCreatedAtNotPaid= ['total' => 0, 'accounts' =>[]]; +// public $totalsCreatedAtPaid= ['total' => 0, 'accounts' =>[]]; +// public $totalsPaidAt= ['total' => 0, 'accounts' =>[]]; +// public $totalsPaidAtNotCreatedAt= ['total' => 0, 'accounts' =>[]]; + + + public $totals; + + public $accounts; + + public $types; + + public $users; + + + /** + * all money gained with ticket sell + * */ + public $ticketMoney; + /** + * all money gained with product sell + * */ + public $productMoney; + /** + * all money gained with product sell grouped by category + * */ + public $productMoneies; + /** + * all money lost by money movement + * */ + public $moneyMovementMoneis; + public $moneyMovementMoney; + /** + * total gained money + * */ + public $total; + + /** + * ticket sale statisitc + * */ + public $ticketStats; + + /** + * money movements by type + * */ + public $moneyMovementsByType; + + public $tickets; + /** + * all product transfer + * */ + public $products; + public $moneyMovements; + + public $productsByCategory; + + + /** + * @inheritdoc + */ + public function rules() + { + return [ + + [[ 'start', ], 'date', 'format' =>Yii::$app->formatter->datetimeFormat , 'timestampAttribute' => 'timestampStart' ,'timestampAttributeFormat' => 'yyyy-MM-dd HH:mm' ,'timeZone' => 'UTC' ], + [[ 'end' , ], 'date' ,'format' =>Yii::$app->formatter->datetimeFormat , 'timestampAttribute' => 'timestampEnd' ,'timestampAttributeFormat' => 'yyyy-MM-dd HH:mm' ,'timeZone' => 'UTC' ], + + [ [ 'id_account','id_user' ] , 'integer'], + ['types', 'each', 'rule' => ['integer']], + ]; + } + + + + /** + * Creates data provider instance with search query applied + * + * @param array $params + * + * @return ActiveDataProvider + */ + public function search($params) + { + $query = Transfer::find(); + + $dataProvider = new ActiveDataProvider([ + 'query' => $query, + ]); + + + + $this->load($params); + + + if (!$this->validate()) { + } + + + + $this->readTicketMoney(); + $this->readProductsMoney(); + $this->readMoneyMovementMoney(); + $this->calcTotal(); + + $this->readProductsByCategory(); + $this->readProductsByCategoryDetailed(); + $this->readTicketStas(); + $this->readMoneyMovementsStats(); + + + $this->readTickets(); + $this->readProducts(); + $this->readMoneyMovements(); + + } + + protected function calcTotal(){ + $this->total = 0; + $this->total += $this->ticketMoney; + $this->total += $this->productMoney; + $this->total += $this->moneyMovementMoneis; + } + + + protected function addAccountConstraint($query){ + $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->andWhere(['transfer.id_user' => Yii::$app->user->id ]); + } + + protected function addQueryFilters($query){ + + $this->addAccountConstraint($query); + + $query->andFilterWhere([ + 'transfer.id_account' => $this->id_account, + 'transfer.id_user' => $this->id_user, + 'transfer.type' => $this->type, + 'transfer.id_user' => $this->id_user, + ]); + + $created_condition = ['and',[ '>=', 'transfer.created_at', $this->timestampStart ] ,[ '<', 'transfer.created_at', $this->timestampEnd ] ]; + $paid_condition = ['and',[ '>=', 'transfer.paid_at', $this->timestampStart ] ,[ '<', 'transfer.paid_at', $this->timestampEnd ] ]; + + + $query->andFilterWhere(['or' , $created_condition , $paid_condition]); + + $query->andWhere(['transfer.status' => Transfer::STATUS_PAID]); + + } + + + protected function readTicketStas(){ + + $query = (new \yii\db\Query()); + $query->select(['ticket_type.name as ticket_type_name' , 'coalesce(sum(abs(transfer.count)),0) AS ticket_count', 'coalesce(sum(abs(transfer.money)),0) AS ticket_money']); + $query->from('transfer'); + $query->andWhere(['transfer.type' => Transfer::TYPE_TICKET]); + $query->innerJoin("ticket", "ticket.id_ticket = transfer.id_object"); + $query->innerJoin("ticket_type", "ticket.id_ticket_type = ticket_type.id_ticket_type"); + + $query->groupBy(['ticket_type.id_ticket_type','ticket_type.name']); + $this->addQueryFilters($query); + + + $this->ticketStats = $query->all(); + } + + + protected function readTicketMoney(){ + + $query = (new \yii\db\Query()); + $query->select([' coalesce(sum(abs(transfer.money)),0) AS ticket_money']); + $query->from('transfer'); + $query->andWhere(['transfer.type' => Transfer::TYPE_TICKET]); + $query->innerJoin("ticket", "ticket.id_ticket = transfer.id_object"); + $this->addQueryFilters($query); + $this->ticketMoney = $query->scalar(); + } + + protected function readProductsByCategory(){ + + + $query = (new \yii\db\Query()); + $query->select(['coalesce(sum(transfer.money),0) AS product_money', 'coalesce(sum(transfer.count),0) as category_count', 'product_category.name as category_name']); + $query->from('transfer'); + $query->groupBy(['product_category.id_product_category','product_category.name']); + $query->andWhere(['transfer.type' => Transfer::TYPE_PRODUCT]); + $query->innerJoin("sale", "sale.id_sale = transfer.id_object"); + $query->innerJoin("product", "sale.id_product = product.id_product"); + $query->innerJoin("product_category", "product.id_product_category = product_category.id_product_category"); + $this->addQueryFilters($query); + + $this->productMoneies = $query->all(); + + } + + + protected function readProductsByCategoryDetailed(){ + + $formatted = []; + $formatted['categories'] = []; + $formatted['total'] = 0; + $prevCategory = null; + $curCategory = null; + + $category = null; + + $query = (new \yii\db\Query()); + $query->select(['product_category.id_product_category as product_category_id','product_category.name as product_category_name', 'product.name as product_name' ,'coalesce(sum(transfer.money),0) AS product_money', 'coalesce(sum(transfer.count),0) as product_count']); + $query->from('transfer'); + $query->groupBy(['product.id_product','product.name','product_category.id_product_category','product_category.name']); + $query->andWhere(['transfer.type' => Transfer::TYPE_PRODUCT]); + $query->innerJoin("sale", "sale.id_sale = transfer.id_object"); + $query->innerJoin("product", "sale.id_product = product.id_product"); + $query->innerJoin("product_category", "product.id_product_category = product_category.id_product_category"); + $query->orderBy(['product_category.name' => SORT_ASC,'product.name' => SORT_ASC]); + $this->addQueryFilters($query); + + $result = $query->all(); + + foreach ($result as $row){ + $curCategory = $row['product_category_id']; + if ( $curCategory != $prevCategory ){ + //store last category + if ( $category != null ){ + $formatted['categories'][] = $category; + } + $prevCategory = $curCategory; + //create new category + $category = []; + $category['category'] = []; + $category['category']['name'] = $row['product_category_name']; + $category['category']['id'] = $row['product_category_id']; + $category['products'] = []; + $category['total'] = 0; + + } + $category['products'][] = $row; + $category['total'] += $row['product_money']; + $formatted['total'] += $row['product_money']; + + } + + if ( $category != null ){ + $formatted['categories'][]= $category; + } + + $this->productsByCategory = $formatted; + + } + + protected function readProductsMoney(){ + + + $query = (new \yii\db\Query()); + $query->select(['coalesce(sum(transfer.money),0) AS product_money' ]); + $query->from('transfer'); + $query->andWhere(['transfer.type' => Transfer::TYPE_PRODUCT]); + $query->innerJoin("sale", "sale.id_sale = transfer.id_object"); + $this->addQueryFilters($query); + + $this->productMoney = $query->scalar(); + + } + + + protected function readMoneyMovementMoney(){ + $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 money_movement_money']); + $query->from('transfer'); + $query->andWhere(['transfer.type' => Transfer::TYPE_MONEY_MOVEMENT_OUT]); + $query->innerJoin("money_movement", "money_movement.id_money_movement = transfer.id_object"); + $this->addQueryFilters($query); + + $this->moneyMovementMoneis = $query->scalar(); + } + protected function readMoneyMovementsStats(){ + $query = (new \yii\db\Query()); + $query->select([ 'money_movement.type as money_movement_type', ' coalesce(count(transfer.id_transfer),0) AS money_movement_count', 'coalesce(sum( case when transfer.direction = ' . Transfer::DIRECTION_IN. ' then transfer.money else -1 * transfer.money end ),0) AS money_movement_money']); + $query->from('transfer'); + $query->andWhere(['transfer.type' => Transfer::TYPE_MONEY_MOVEMENT_OUT]); + $query->innerJoin("money_movement", "money_movement.id_money_movement = transfer.id_object"); + $query->groupBy(['money_movement.type']); + $this->addQueryFilters($query); + + $this->moneyMovementsByType = $query->all(); + for ($i = 0; $i < count($this->moneyMovementsByType) ;$i++ ){ + $this->moneyMovementsByType[$i]['name'] = MoneyMovement::typeName($this->moneyMovementsByType[$i]['money_movement_type']); + } + } + + protected function readTickets(){ + $query = (new \yii\db\Query()); + $query->select(['user.username as user_name', 'account.name as account_name','ticket_type.name as ticket_type_name' , 'transfer.count AS ticket_count', 'transfer.money AS ticket_money','transfer.item_price AS ticket_item_price', 'transfer.created_at as ticket_created_at','transfer.paid_at as ticket_paid_at']); + $query->from('transfer'); + $query->andWhere(['transfer.type' => Transfer::TYPE_TICKET]); + $query->innerJoin("ticket", "ticket.id_ticket = transfer.id_object"); + $query->innerJoin("ticket_type", "ticket.id_ticket_type = ticket_type.id_ticket_type"); + $query->innerJoin("account", "transfer.id_account = account.id_account"); + $query->innerJoin("user", "transfer.id_user = user.id"); + $query->orderBy(['transfer.created_at' => SORT_ASC]); + $this->addQueryFilters($query); + + + $this->tickets = $query->all(); + + for ($i = 0; $i < count($this->tickets) ;$i++ ){ + $this->tickets[$i]['ticket_created_at'] = Yii::$app->formatter->asDatetime($this->tickets[$i]['ticket_created_at'], 'yyyy.MM.dd HH:mm:ss'); + $this->tickets[$i]['ticket_paid_at'] = empty($this->tickets[$i]['ticket_paid_at'] ) ? '-' : Yii::$app->formatter->asDatetime($this->tickets[$i]['ticket_paid_at'], 'yyyy.MM.dd HH:mm:ss'); + } + + } + + protected function readProducts(){ + + $query = (new \yii\db\Query()); + $query->select([ 'user.username as user_name','account.name as account_name' , 'product_category.name as product_category_name', 'product.name as product_name', 'transfer.money AS product_money', 'transfer.count AS product_count', 'transfer.money AS product_money','transfer.item_price AS product_item_price', 'transfer.created_at as product_created_at','transfer.paid_at as product_paid_at']); + $query->from('transfer'); + $query->andWhere(['transfer.type' => Transfer::TYPE_PRODUCT]); + $query->innerJoin("sale", "sale.id_sale = transfer.id_object"); + $query->innerJoin("product", "sale.id_product = product.id_product"); + $query->innerJoin("product_category", "product.id_product_category = product_category.id_product_category"); + $query->innerJoin("account", "transfer.id_account = account.id_account"); + $query->innerJoin("user", "transfer.id_user = user.id"); + $query->orderBy(['transfer.created_at' => SORT_ASC]); + $this->addQueryFilters($query); + + $this->products = $query->all(); + + for ($i = 0; $i < count($this->products) ;$i++ ){ + $this->products[$i]['product_created_at'] = Yii::$app->formatter->asDatetime($this->products[$i]['product_created_at'], 'yyyy.MM.dd HH:mm:ss'); + $this->products[$i]['product_paid_at'] = empty($this->products[$i]['product_paid_at'] ) ? '-' : Yii::$app->formatter->asDatetime($this->products[$i]['product_paid_at'], 'yyyy.MM.dd HH:mm:ss'); + } + + } + + protected function readMoneyMovements(){ + $query = (new \yii\db\Query()); + $query->select([ 'user.username as user_name','account.name as account_name', 'transfer.direction as transfer_direction' ,'money_movement.type as money_movement_type', 'transfer.money AS money_movement_money', 'money_movement.name as money_movement_name','transfer.created_at as money_movement_created_at', ]); + $query->from('transfer'); + $query->andWhere(['transfer.type' => Transfer::TYPE_MONEY_MOVEMENT_OUT]); + $query->innerJoin("money_movement", "money_movement.id_money_movement = transfer.id_object"); + $query->innerJoin("account", "transfer.id_account = account.id_account"); + $query->innerJoin("user", "transfer.id_user = user.id"); + $query->orderBy(['transfer.created_at' => SORT_ASC]); + $this->addQueryFilters($query); + + $this->moneyMovements = $query->all(); + + for ($i = 0; $i < count($this->moneyMovements) ;$i++ ){ + $this->moneyMovements[$i]['money_movement_type_name'] = MoneyMovement::typeName($this->moneyMovements[$i]['money_movement_type']); + $this->moneyMovements[$i]['money_movement_created_at'] = Yii::$app->formatter->asDatetime($this->moneyMovements[$i]['money_movement_created_at'], 'yyyy.MM.dd HH:mm:ss'); + $this->moneyMovements[$i]['signed_money'] = Transfer::toSignedMoney($this->moneyMovements[$i]['transfer_direction'],$this->moneyMovements[$i]['money_movement_money']); + } + } + + +} diff --git a/common/views/common/_account_statistic.php b/common/views/common/_account_statistic.php index 7f54d89..0062183 100644 --- a/common/views/common/_account_statistic.php +++ b/common/views/common/_account_statistic.php @@ -1,6 +1,12 @@ + + \ No newline at end of file diff --git a/console/migrations/m151231_095117_alter__table__account_state__add__column__collection_money.php b/console/migrations/m151231_095117_alter__table__account_state__add__column__collection_money.php new file mode 100644 index 0000000..51fec62 --- /dev/null +++ b/console/migrations/m151231_095117_alter__table__account_state__add__column__collection_money.php @@ -0,0 +1,27 @@ +addColumn("account_state", "collection_money", "int"); + } + + public function down() + { + } + + /* + // Use safeUp/safeDown to run migration code within a transaction + public function safeUp() + { + } + + public function safeDown() + { + } + */ +} diff --git a/frontend/components/AccountStateBanknoteCountWidget.php b/frontend/components/AccountStateBanknoteCountWidget.php index a874368..154867e 100644 --- a/frontend/components/AccountStateBanknoteCountWidget.php +++ b/frontend/components/AccountStateBanknoteCountWidget.php @@ -18,7 +18,11 @@ class AccountStateBanknoteCountWidget extends Widget{ $panelStyleClas = 'panel-default'; if ( $this->model->hasDifferenceToPrevState()){ - $panelStyleClas = 'panel-danger'; + if ( $this->model->hasPlus()){ + $panelStyleClas = 'panel-success'; + }else if ( $this->model->hasMinus() ){ + $panelStyleClas = 'panel-danger'; + } } $s = ""; @@ -27,8 +31,51 @@ class AccountStateBanknoteCountWidget extends Widget{ $s .= "Kassza művelet - " . $this->model->typeName; $s .= Html::endTag("div"); $s .= Html::beginTag("div",['class' => 'panel-body '] ); + + + $s .= $this->generateInfoRow(); $s .= $this->generateNotes(); + + if ( $this->model->hasDifferenceToPrevState()){ + + $ft = " Ft"; + $s .= DetailView::widget([ + 'model' => $this->model, + 'template' =>"{label}{value} ", + 'attributes' => [ + [ + 'label' => "Előző nyitás ideje", + 'value' => $this->model->prevObject ? \Yii::$app->formatter->asDatetime( $this->model->prevObject->created_at) : "-", + ], + [ + 'label' => "Előzőleg nyitott", + 'value' => $this->model->prevObject ? $this->model->user->username : "-", + ], + [ + 'label' => "Előző nyitás összege", + 'value' => $this->model->prev_money.$ft + ], + [ + 'label' => "Bevételek összesen utolsó nyitás óta", + 'value' => $this->model->collection_money .$ft + ], + [ + 'label' => "Zárás összege", + 'value' => $this->model->money.$ft + ], + [ + 'label' => "Várt összeg", + 'value' => $this->model->expected.$ft + ], + [ + 'label' => "Különbözet", + 'value' => $this->model->signedDiff.$ft + ], + ] + ]); + } + $s .= $this->generateComment(); $s .= Html::endTag("div"); $s .= Html::endTag("div"); diff --git a/frontend/components/FrontendMenuStructure.php b/frontend/components/FrontendMenuStructure.php index c675559..11ce991 100644 --- a/frontend/components/FrontendMenuStructure.php +++ b/frontend/components/FrontendMenuStructure.php @@ -7,6 +7,7 @@ use yii\helpers\Html; use common\models\MoneyMovement; use yii\db\Query; use common\models\AccountState; +use backend\models\AccountSearch; class FrontendMenuStructure{ @@ -20,8 +21,8 @@ class FrontendMenuStructure{ public function __construct(){ $this->menuItems = []; - $this->start = Yii::$app->formatter->asDatetime( strtotime('today UTC') ); - $this->tomorrow = Yii::$app->formatter->asDatetime( strtotime('tomorrow UTC') ); + $this->start = \Yii::$app->formatter->asDatetime( strtotime('today') ); + $this->tomorrow = Yii::$app->formatter->asDatetime( strtotime('tomorrow') ); $this->startDate = Yii::$app->formatter->asDate( strtotime('today UTC') ); $this->tomorrowDate = Yii::$app->formatter->asDate( strtotime('tomorrow UTC') ); @@ -30,7 +31,7 @@ class FrontendMenuStructure{ if ( $this->isLogged() ){ - $lastAccountState = AccountState::find()->andWhere(['id_user' => Yii::$app->user->id])->orderBy(['account_state.created_at' => SORT_DESC])->limit(1)->one(); + $lastAccountState = AccountState::find()->andWhere(['id_user' => Yii::$app->user->id])->andWhere(['type' => AccountState::TYPE_OPEN ])->orderBy(['account_state.created_at' => SORT_DESC])->limit(1)->one(); if ( isset($lastAccountState) ){ $this->start = Yii::$app->formatter->asDatetime(strtotime( $lastAccountState->created_at . ' UTC' )); } diff --git a/frontend/controllers/AccountStateController.php b/frontend/controllers/AccountStateController.php index d5b3229..4974f2e 100644 --- a/frontend/controllers/AccountStateController.php +++ b/frontend/controllers/AccountStateController.php @@ -84,6 +84,8 @@ class AccountStateController extends Controller */ public function actionClose() { + $lastStates = AccountState::readLastForUser(AccountState::TYPE_OPEN ); + $lastStates = AccountState::modelsToArray($lastStates); $model = new AccountState(); $model->type = AccountState::TYPE_CLOSE; $model->id_user = Yii::$app->user->id; @@ -97,6 +99,7 @@ class AccountStateController extends Controller return $this->render('close', [ 'model' => $model, 'accounts' => $accounts, + 'lastStates' => $lastStates, ]); } } diff --git a/frontend/controllers/ProductController.php b/frontend/controllers/ProductController.php index 866a2dc..a26bf59 100644 --- a/frontend/controllers/ProductController.php +++ b/frontend/controllers/ProductController.php @@ -82,7 +82,7 @@ class ProductController extends Controller $model->customer = $this->customer; $model->card = $this->card; - $products = Product::read(); + $products = Product::readForDefaultAccount(); $products = Product::modelToMapIdName($products); $model->products = $products; @@ -199,7 +199,7 @@ class ProductController extends Controller public function actionLookup($query = null) { $result = []; - $product = Product::findProduct($query); + $product = Product::findProduct($query, Account::readDefault()); $product = Product::modelToArray($product); $result['product'] = $product; @@ -207,7 +207,6 @@ class ProductController extends Controller \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; - return $result; } diff --git a/frontend/controllers/TicketController.php b/frontend/controllers/TicketController.php index 0e72397..073a9b1 100644 --- a/frontend/controllers/TicketController.php +++ b/frontend/controllers/TicketController.php @@ -97,7 +97,7 @@ class TicketController extends FrontendController $discounts = Discount::read(); - $ticketTypes = TicketType::read(); + $ticketTypes = TicketType::read(null, Account::readDefault()); $accounts = Account::readAccounts(); diff --git a/frontend/models/TransferListSearch.php b/frontend/models/TransferListSearch.php index 7472a60..6d164f9 100644 --- a/frontend/models/TransferListSearch.php +++ b/frontend/models/TransferListSearch.php @@ -16,360 +16,8 @@ use common\models\MoneyMovement; /** * TransferSearch represents the model behind the search form about `common\models\Transfer`. */ -class TransferListSearch extends Transfer +class TransferListSearch extends \common\models\TransferListSearch { - - public $start; - public $end; - - public $timestampStart; - public $timestampEnd; - -// public $totalsCreatedAt = ['total' => 0, 'accounts' =>[] ]; -// public $totalsCreatedAtNotPaid= ['total' => 0, 'accounts' =>[]]; -// public $totalsCreatedAtPaid= ['total' => 0, 'accounts' =>[]]; -// public $totalsPaidAt= ['total' => 0, 'accounts' =>[]]; -// public $totalsPaidAtNotCreatedAt= ['total' => 0, 'accounts' =>[]]; - - - public $totals; - - public $accounts; - - public $types; - - - /** - * all money gained with ticket sell - * */ - public $ticketMoney; - /** - * all money gained with product sell - * */ - public $productMoney; - /** - * all money gained with product sell grouped by category - * */ - public $productMoneies; - /** - * all money lost by money movement - * */ - public $moneyMovementMoneis; - public $moneyMovementMoney; - /** - * total gained money - * */ - public $total; - - /** - * ticket sale statisitc - * */ - public $ticketStats; - - /** - * money movements by type - * */ - public $moneyMovementsByType; - - public $tickets; - /** - * all product transfer - * */ - public $products; - public $moneyMovements; - - public $productsByCategory; - - - /** - * @inheritdoc - */ - public function rules() - { - return [ - - [[ 'start', ], 'date', 'format' =>Yii::$app->formatter->datetimeFormat , 'timestampAttribute' => 'timestampStart' ,'timestampAttributeFormat' => 'yyyy-MM-dd HH:mm' ,'timeZone' => 'UTC' ], - [[ 'end' , ], 'date' ,'format' =>Yii::$app->formatter->datetimeFormat , 'timestampAttribute' => 'timestampEnd' ,'timestampAttributeFormat' => 'yyyy-MM-dd HH:mm' ,'timeZone' => 'UTC' ], - - [ [ 'id_account' ] , 'integer'], - ['types', 'each', 'rule' => ['integer']], - ]; - } - - - - /** - * Creates data provider instance with search query applied - * - * @param array $params - * - * @return ActiveDataProvider - */ - public function search($params) - { - $query = Transfer::find(); - - $dataProvider = new ActiveDataProvider([ - 'query' => $query, - ]); - - - - $this->load($params); - - - if (!$this->validate()) { - } - - $this->readTicketMoney(); - $this->readProductsMoney(); - $this->readMoneyMovementMoney(); - $this->calcTotal(); - - $this->readProductsByCategory(); - $this->readProductsByCategoryDetailed(); - $this->readTicketStas(); - $this->readMoneyMovementsStats(); - - - $this->readTickets(); - $this->readProducts(); - $this->readMoneyMovements(); - - } - - protected function calcTotal(){ - $this->total = 0; - $this->total += $this->ticketMoney; - $this->total += $this->productMoney; - $this->total += $this->moneyMovementMoneis; - } - - - protected function addQueryFilters($query){ - $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->andWhere(['transfer.id_user' => Yii::$app->user->id ]); - - $query->andFilterWhere([ - 'transfer.id_account' => $this->id_account, - 'transfer.type' => $this->type, - 'transfer.id_user' => $this->id_user, - ]); - - $created_condition = ['and',[ '>=', 'transfer.created_at', $this->timestampStart ] ,[ '<', 'transfer.created_at', $this->timestampEnd ] ]; - $paid_condition = ['and',[ '>=', 'transfer.paid_at', $this->timestampStart ] ,[ '<', 'transfer.paid_at', $this->timestampEnd ] ]; - - - $query->andFilterWhere(['or' , $created_condition , $paid_condition]); - - $query->andWhere(['transfer.status' => Transfer::STATUS_PAID]); - - } - - - protected function readTicketStas(){ - - $query = (new \yii\db\Query()); - $query->select(['ticket_type.name as ticket_type_name' , 'coalesce(sum(abs(transfer.count)),0) AS ticket_count', 'coalesce(sum(abs(transfer.money)),0) AS ticket_money']); - $query->from('transfer'); - $query->andWhere(['transfer.type' => Transfer::TYPE_TICKET]); - $query->innerJoin("ticket", "ticket.id_ticket = transfer.id_object"); - $query->innerJoin("ticket_type", "ticket.id_ticket_type = ticket_type.id_ticket_type"); - - $query->groupBy(['ticket_type.id_ticket_type','ticket_type.name']); - $this->addQueryFilters($query); - - - $this->ticketStats = $query->all(); - } - - - protected function readTicketMoney(){ - - $query = (new \yii\db\Query()); - $query->select([' coalesce(sum(abs(transfer.money)),0) AS ticket_money']); - $query->from('transfer'); - $query->andWhere(['transfer.type' => Transfer::TYPE_TICKET]); - $query->innerJoin("ticket", "ticket.id_ticket = transfer.id_object"); - $this->addQueryFilters($query); - $this->ticketMoney = $query->scalar(); - } - - protected function readProductsByCategory(){ - - - $query = (new \yii\db\Query()); - $query->select(['coalesce(sum(transfer.money),0) AS product_money', 'coalesce(sum(transfer.count),0) as category_count', 'product_category.name as category_name']); - $query->from('transfer'); - $query->groupBy(['product_category.id_product_category','product_category.name']); - $query->andWhere(['transfer.type' => Transfer::TYPE_PRODUCT]); - $query->innerJoin("sale", "sale.id_sale = transfer.id_object"); - $query->innerJoin("product", "sale.id_product = product.id_product"); - $query->innerJoin("product_category", "product.id_product_category = product_category.id_product_category"); - $this->addQueryFilters($query); - - $this->productMoneies = $query->all(); - - } - - - protected function readProductsByCategoryDetailed(){ - - $formatted = []; - $formatted['categories'] = []; - $formatted['total'] = 0; - $prevCategory = null; - $curCategory = null; - - $category = null; - - $query = (new \yii\db\Query()); - $query->select(['product_category.id_product_category as product_category_id','product_category.name as product_category_name', 'product.name as product_name' ,'coalesce(sum(transfer.money),0) AS product_money', 'coalesce(sum(transfer.count),0) as product_count']); - $query->from('transfer'); - $query->groupBy(['product.id_product','product.name','product_category.id_product_category','product_category.name']); - $query->andWhere(['transfer.type' => Transfer::TYPE_PRODUCT]); - $query->innerJoin("sale", "sale.id_sale = transfer.id_object"); - $query->innerJoin("product", "sale.id_product = product.id_product"); - $query->innerJoin("product_category", "product.id_product_category = product_category.id_product_category"); - $query->orderBy(['product_category.name' => SORT_ASC,'product.name' => SORT_ASC]); - $this->addQueryFilters($query); - - $result = $query->all(); - - foreach ($result as $row){ - $curCategory = $row['product_category_id']; - if ( $curCategory != $prevCategory ){ - //store last category - if ( $category != null ){ - $formatted['categories'][] = $category; - } - $prevCategory = $curCategory; - //create new category - $category = []; - $category['category'] = []; - $category['category']['name'] = $row['product_category_name']; - $category['category']['id'] = $row['product_category_id']; - $category['products'] = []; - $category['total'] = 0; - - } - $category['products'][] = $row; - $category['total'] += $row['product_money']; - $formatted['total'] += $row['product_money']; - - } - - if ( $category != null ){ - $formatted['categories'][]= $category; - } - - $this->productsByCategory = $formatted; - - } - - protected function readProductsMoney(){ - - - $query = (new \yii\db\Query()); - $query->select(['coalesce(sum(transfer.money),0) AS product_money' ]); - $query->from('transfer'); - $query->andWhere(['transfer.type' => Transfer::TYPE_PRODUCT]); - $query->innerJoin("sale", "sale.id_sale = transfer.id_object"); - $this->addQueryFilters($query); - - $this->productMoney = $query->scalar(); - - } - - - protected function readMoneyMovementMoney(){ - $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 money_movement_money']); - $query->from('transfer'); - $query->andWhere(['transfer.type' => Transfer::TYPE_MONEY_MOVEMENT_OUT]); - $query->innerJoin("money_movement", "money_movement.id_money_movement = transfer.id_object"); - $this->addQueryFilters($query); - - $this->moneyMovementMoneis = $query->scalar(); - } - protected function readMoneyMovementsStats(){ - $query = (new \yii\db\Query()); - $query->select([ 'money_movement.type as money_movement_type', ' coalesce(count(transfer.id_transfer),0) AS money_movement_count', 'coalesce(sum( case when transfer.direction = ' . Transfer::DIRECTION_IN. ' then transfer.money else -1 * transfer.money end ),0) AS money_movement_money']); - $query->from('transfer'); - $query->andWhere(['transfer.type' => Transfer::TYPE_MONEY_MOVEMENT_OUT]); - $query->innerJoin("money_movement", "money_movement.id_money_movement = transfer.id_object"); - $query->groupBy(['money_movement.type']); - $this->addQueryFilters($query); - - $this->moneyMovementsByType = $query->all(); - for ($i = 0; $i < count($this->moneyMovementsByType) ;$i++ ){ - $this->moneyMovementsByType[$i]['name'] = MoneyMovement::typeName($this->moneyMovementsByType[$i]['money_movement_type']); - } - } - - protected function readTickets(){ - $query = (new \yii\db\Query()); - $query->select(['account.name as account_name','ticket_type.name as ticket_type_name' , 'transfer.count AS ticket_count', 'transfer.money AS ticket_money','transfer.item_price AS ticket_item_price', 'transfer.created_at as ticket_created_at','transfer.paid_at as ticket_paid_at']); - $query->from('transfer'); - $query->andWhere(['transfer.type' => Transfer::TYPE_TICKET]); - $query->innerJoin("ticket", "ticket.id_ticket = transfer.id_object"); - $query->innerJoin("ticket_type", "ticket.id_ticket_type = ticket_type.id_ticket_type"); - $query->innerJoin("account", "transfer.id_account = account.id_account"); - $query->orderBy(['transfer.created_at' => SORT_ASC]); - $this->addQueryFilters($query); - - - $this->tickets = $query->all(); - - for ($i = 0; $i < count($this->tickets) ;$i++ ){ - $this->tickets[$i]['ticket_created_at'] = Yii::$app->formatter->asDatetime($this->tickets[$i]['ticket_created_at'], 'yyyy.MM.dd HH:mm:ss'); - $this->tickets[$i]['ticket_paid_at'] = empty($this->tickets[$i]['ticket_paid_at'] ) ? '-' : Yii::$app->formatter->asDatetime($this->tickets[$i]['ticket_paid_at'], 'yyyy.MM.dd HH:mm:ss'); - } - - } - - protected function readProducts(){ - - $query = (new \yii\db\Query()); - $query->select([ 'account.name as account_name' , 'product_category.name as product_category_name', 'product.name as product_name', 'transfer.money AS product_money', 'transfer.count AS product_count', 'transfer.money AS product_money','transfer.item_price AS product_item_price', 'transfer.created_at as product_created_at','transfer.paid_at as product_paid_at']); - $query->from('transfer'); - $query->andWhere(['transfer.type' => Transfer::TYPE_PRODUCT]); - $query->innerJoin("sale", "sale.id_sale = transfer.id_object"); - $query->innerJoin("product", "sale.id_product = product.id_product"); - $query->innerJoin("product_category", "product.id_product_category = product_category.id_product_category"); - $query->innerJoin("account", "transfer.id_account = account.id_account"); - $query->orderBy(['transfer.created_at' => SORT_ASC]); - $this->addQueryFilters($query); - - $this->products = $query->all(); - - for ($i = 0; $i < count($this->products) ;$i++ ){ - $this->products[$i]['product_created_at'] = Yii::$app->formatter->asDatetime($this->products[$i]['product_created_at'], 'yyyy.MM.dd HH:mm:ss'); - $this->products[$i]['product_paid_at'] = empty($this->products[$i]['product_paid_at'] ) ? '-' : Yii::$app->formatter->asDatetime($this->products[$i]['product_paid_at'], 'yyyy.MM.dd HH:mm:ss'); - } - - } - - protected function readMoneyMovements(){ - $query = (new \yii\db\Query()); - $query->select([ 'account.name as account_name', 'transfer.direction as transfer_direction' ,'money_movement.type as money_movement_type', 'transfer.money AS money_movement_money', 'money_movement.name as money_movement_name','transfer.created_at as money_movement_created_at', ]); - $query->from('transfer'); - $query->andWhere(['transfer.type' => Transfer::TYPE_MONEY_MOVEMENT_OUT]); - $query->innerJoin("money_movement", "money_movement.id_money_movement = transfer.id_object"); - $query->innerJoin("account", "transfer.id_account = account.id_account"); - $query->orderBy(['transfer.created_at' => SORT_ASC]); - $this->addQueryFilters($query); - - $this->moneyMovements = $query->all(); - - for ($i = 0; $i < count($this->moneyMovements) ;$i++ ){ - $this->moneyMovements[$i]['money_movement_type_name'] = MoneyMovement::typeName($this->moneyMovements[$i]['money_movement_type']); - $this->moneyMovements[$i]['money_movement_created_at'] = Yii::$app->formatter->asDatetime($this->moneyMovements[$i]['money_movement_created_at'], 'yyyy.MM.dd HH:mm:ss'); - $this->moneyMovements[$i]['signed_money'] = Transfer::toSignedMoney($this->moneyMovements[$i]['transfer_direction'],$this->moneyMovements[$i]['money_movement_money']); - } - } - + } diff --git a/frontend/views/account-state/close.php b/frontend/views/account-state/close.php index 8d792e1..2378870 100644 --- a/frontend/views/account-state/close.php +++ b/frontend/views/account-state/close.php @@ -13,7 +13,6 @@ $this->params['breadcrumbs'][] = $this->title; AccountStateAsset::register($this); $options = []; - $this->registerJs ( 'new AccountState( '. json_encode($options).');' ); ?>