diff --git a/backend/components/AdminMenuStructure.php b/backend/components/AdminMenuStructure.php index ad9f591..0c26d78 100644 --- a/backend/components/AdminMenuStructure.php +++ b/backend/components/AdminMenuStructure.php @@ -78,6 +78,8 @@ class AdminMenuStructure{ $items[] = ['label' => 'Bérletkártyák', 'url' => ['/card/index'] ]; $items[] = ['label' => 'Bérletek', 'url' => ['/ticket/index' , 'TicketSearch[start]' =>$today,'TicketSearch[end]' => $tomorrow ] ]; $items[] = ['label' => 'Statisztika', 'url' => ['/ticket/statistics' , 'TicketSearchStatisitcs[start]' =>$today,'TicketSearchStatisitcs[end]' => $tomorrow ] ]; + $items[] = ['label' => 'Kártya létrehozás', 'url' => ['/card-package/index' , ] ]; + $items[] = ['label' => 'Kártya csomag RFId hozzárendelés', 'url' => ['/card-package/import' , ] ]; $this->menuItems[] = ['label' => 'Bérletek/Vendégek', 'url' => $this->emptyUrl, 'items' => $items ]; @@ -119,7 +121,7 @@ class AdminMenuStructure{ // $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'] ]; - if ( RoleDefinition::isAdmin() || RoleDefinition::isEmployee() ){ + if ( RoleDefinition::isAdmin() ){ $this->menuItems[] = ['label' => 'Tartós megbízások', 'url' => $this->emptyUrl, 'items' => $items ]; diff --git a/backend/controllers/CardController.php b/backend/controllers/CardController.php index 852fb63..f1bb0cf 100644 --- a/backend/controllers/CardController.php +++ b/backend/controllers/CardController.php @@ -12,6 +12,7 @@ use yii\helpers\Json; use backend\models\CardImportRfidForm; use yii\web\UploadedFile; use common\components\Helper; +use backend\models\CardInsertForm; /** * CardController implements the CRUD actions for Card model. @@ -30,7 +31,8 @@ class CardController extends \backend\controllers\BackendController { 'view', 'update', 'list' , - 'import-rfid' + 'import-rfid', + 'insert' ], 'allow' => true, 'roles' => [ @@ -224,6 +226,7 @@ class CardController extends \backend\controllers\BackendController { $failed = []; $sqls = []; + $inserts = []; foreach ($arr as $item ){ $card = Card::find()->andWhere(['number' => $item['number']])->one(); if ( $card != null ){ @@ -232,7 +235,17 @@ class CardController extends \backend\controllers\BackendController { $sqls[] = $sql; $i++; }else{ - $failed [] = $item; +// $failed [] = $item; + $sql = "insert into card (number,status,type,created_at,updated_at, rfid_key) values("; + $sql .= " '" .$item['number'] . "'" ; + $sql .= " ," . Card::STATUS_ACTIVE ; + $sql .= " ," . Card::TYPE_RFID; + $sql .= " ,'" . date("Y-m-d H:i:s") ."'" ; + $sql .= " ,'" . date("Y-m-d H:i:s") ."'" ; + $sql .=" ,'" .$item['key'] ."'"; + $sql .= " );"; + $inserts[] = $sql; +// rfid_key = '" . strtolower( $item['key'] )."' where id_card = " .$card->id_card .";"; } } @@ -241,6 +254,8 @@ class CardController extends \backend\controllers\BackendController { $model->message .= "
failed: " . print_r($failed,true); $model->message .= "
sql:"; $model->message .= "
". implode("
", $sqls); + $model->message .= "


Inserts


"; + $model->message .= "
". implode("
", $inserts); } @@ -248,4 +263,90 @@ class CardController extends \backend\controllers\BackendController { 'model' => $model ] ); } + + + + public function actionInsert() { + $model = new CardInsertForm(); + $arr = []; + + if (Yii::$app->request->isPost) { + $model->file = UploadedFile::getInstance($model, 'file'); + + // print_r($model->file); + // $model->message = "ok"; + $file = $model->file->tempName; + + $file = fopen ( $file , "r" ); + + $trans = null; + $i = 0; + $j = 0; + while ( ($data = fgetcsv ( $file, 0, "," )) != null ) { + // if ($i == 0) { + // $i ++; + // continue; + // } + $j++; + $number = $key = false; + if ( isset($data[0]) ){ + $number = $data[0]; + } + + if ( isset($data[1]) ){ + $key = $data[1]; + } + + if ( isset($number) && isset($key) && !strpos($key, "E+") && strlen($key) > 7 ){ + $item = []; + $item['number'] = $number; + $item['key'] = Helper::fixAsciiChars( $key); + $arr[] = $item; + } + + + } + + $failed = []; + $sqls = []; + $inserts = []; + foreach ($arr as $item ){ + // $failed [] = $item; + $sql = "insert into card (number,status,type,created_at,updated_at, rfid_key) values("; + $sql .= " '" .$item['number'] . "'" ; + $sql .= " ," . Card::STATUS_ACTIVE ; + $sql .= " ," . Card::TYPE_RFID; + $sql .= " ,'" . date("Y-m-d H:i:s") ."'" ; + $sql .= " ,'" . date("Y-m-d H:i:s") ."'" ; + $sql .=" ,'" .$item['key'] ."'"; + $sql .= " );"; + $inserts[] = $sql; + } + + $model->message = "rows read: " .$j ." / ". "updated cards: " .$i; + $model->message .= "
array size: " . count($arr); + $model->message .= "
failed: " . print_r($failed,true); + $model->message .= "
sql:"; + $model->message .= "
". implode("
", $sqls); + $model->message .= "


Inserts


"; + $model->message .= "
". implode("
", $inserts); + + + $inserts = implode("\n", $inserts); + header("Content-type:text/plain"); //for pdf file + //header('Content-Type:text/plain; charset=ISO-8859-15'); + //if you want to read text file using text/plain header + header('Content-Disposition: attachment; filename="insert.sql"'); + header('Content-Length: ' . strlen($inserts)); + echo $inserts; + exit(); + + } + + return $this->render ( 'insert.php', [ + 'model' => $model + ] ); + } + + } diff --git a/backend/controllers/CardPackageController.php b/backend/controllers/CardPackageController.php new file mode 100644 index 0000000..2c9ae59 --- /dev/null +++ b/backend/controllers/CardPackageController.php @@ -0,0 +1,315 @@ + [ + 'class' => VerbFilter::className (), + 'actions' => [ + 'delete' => [ + 'post' + ] + ] + ] + ]; + } + + /** + * Lists all CardPackage models. + * + * @return mixed + */ + public function actionIndex() { + $searchModel = new CardPackageSearch (); + $dataProvider = $searchModel->search ( Yii::$app->request->queryParams ); + + return $this->render ( 'index', [ + 'searchModel' => $searchModel, + 'dataProvider' => $dataProvider + ] ); + } + + /** + * Displays a single CardPackage model. + * + * @param integer $id + * @return mixed + */ + public function actionView($id) { + $model = $this->findModel ( $id ); + + $query = Card::find (); + $query->innerJoin ( "card_card_package_assignment", "card_card_package_assignment.id_card = card.id_card " ); + $query->andWhere ( [ + 'card_card_package_assignment.id_card_package' => $id + ] ); + + $dataProvider = new ActiveDataProvider ( [ + 'query' => $query + ] ); + + return $this->render ( 'view', [ + 'model' => $model, + 'dataProvider' => $dataProvider + ] ); + } + public function actionDownload($id) { + $model = $this->findModel ( $id ); + + $model->updateCounters ( [ + 'printed' => 1 + ] ); + + $query = Card::find (); + $query->innerJoin ( "card_card_package_assignment", "card_card_package_assignment.id_card = card.id_card " ); + $query->andWhere ( [ + 'card_card_package_assignment.id_card_package' => $id + ] ); + + $cards = $query->all (); + + $numbers = [ ]; + foreach ( $cards as $card ) { + $numbers [] = $card->number; + } + + $this->generateXLS ( $model, $numbers ); + } + + /** + * Creates a new CardPackage model. + * If creation is successful, the browser will be redirected to the 'view' page. + * + * @return mixed + */ + public function actionCreate() { + $model = new CardPackage (); + $model->id_user = \Yii::$app->user->id; + $model->printed = 0; + + if ($model->load ( Yii::$app->request->post () ) && $model->validate ()) { + $conn = \Yii::$app->db; + $tx = $conn->beginTransaction (); + + $model->save ( false ); + + $count = $model->count; + + $numGen = new FreeUniqueCardNumberGenerator ( [ + 'count' => $model->count, + 'prefix' => '10' + ] ); + + $numGen->generate (); + + $numbers = $numGen->cache; + + try { + foreach ( $numbers as $number ) { + + $card = new Card (); + $card->number = $number; + $card->type = Card::TYPE_RFID; + $card->status = Card::STATUS_ACTIVE; + $card->save ( false ); + + $cardAssignment = new CardCardPackageAssignment (); + $cardAssignment->id_card = $card->id_card; + $cardAssignment->id_card_package = $model->id_card_package; + $cardAssignment->save ( false ); + } + $tx->commit (); + + return $this->redirect ( [ + 'index' + ] ); + } catch ( \Exception $e ) { + $tx->rollBack (); + } + + return $this->render ( 'create', [ + 'model' => $model + ] ); + } else { + return $this->render ( 'create', [ + 'model' => $model + ] ); + } + } + protected function generateXLS($model, $numbers) { + $objPHPExcel = new \PHPExcel (); + + $sheet = $objPHPExcel->setActiveSheetIndex ( 0 ); + + // $row = 1; + // $sheet->setCellValue('A'.$row, "Termék név") + // ->setCellValue('B'.$row, "Eladási ár") + // ->setCellValue('C'.$row, "Kassza") + // ->setCellValue('D'.$row, "Eladott mennyiség") + // ->setCellValue('E'.$row, "Eladás összege"); + $row = 0; + + foreach ( $numbers as $number ) { + $row ++; + $sheet->setCellValue ( 'A' . $row, $number ); + } + + $fileName = "kartya_csomag"; + $fileName .= "_" . $model->id_card_package; + $fileName .= "_" . date ( "Ymd_His" ); + $fileName .= ".xls"; + + // Redirect output to a client’s web browser (Excel5) + header ( 'Content-Type: application/vnd.ms-excel' ); + header ( 'Content-Disposition: attachment;filename="' . $fileName . '"' ); + header ( 'Cache-Control: max-age=0' ); + // If you're serving to IE 9, then the following may be needed + header ( 'Cache-Control: max-age=1' ); + // If you're serving to IE over SSL, then the following may be needed + header ( 'Expires: Mon, 26 Jul 1997 05:00:00 GMT' ); // Date in the past + header ( 'Last-Modified: ' . gmdate ( 'D, d M Y H:i:s' ) . ' GMT' ); // always modified + header ( 'Cache-Control: cache, must-revalidate' ); // HTTP/1.1 + header ( 'Pragma: public' ); // HTTP/1.0 + $objWriter = \PHPExcel_IOFactory::createWriter ( $objPHPExcel, 'Excel5' ); + $objWriter->save ( 'php://output' ); + exit (); + } + public function actionImport() { + $model = new CardPackageImportForm (); + + if (Yii::$app->request->isPost) { + $model->file = UploadedFile::getInstance ( $model, 'file' ); + + + + if ($model->validate ()) { + + + // print_r($model->file); + // $model->message = "ok"; + $file = $model->file->tempName; + $xlsUtil = new XLSUtil (); + $xlsUtil->loadFromFileName ( $file ); + $array = $xlsUtil->toArray (); + +// print_r($array); +// print_r( array_column($array, 2)); + +// foreach ($array as $item ){ +// echo $item[2]; +// } + + foreach ( $array as $row ) { + try { + $tx = \Yii::$app->db->beginTransaction (); + + $card = Card::find ()->andWhere ( [ + 'number' => $row [0] + ] )->one (); + + if ( isset( $card )) { + $card->rfid_key = Helper::fixAsciiChars( $row [2 ] ); + $card->save(false); + }else{ + throw new \Exception("Card not found"); + } + + + $tx->commit (); + + $model->done = $model->done + 1; + } catch ( \Exception $e ) { + $tx->rollBack (); + $model->failed = $model->failed + 1; + \Yii::error ( "Failed to import card rfid: " . print_r ( $row, true ) ); + } + } + + \Yii::$app->session->setFlash ( 'success', "Az importálás eredménye: sikeres:" . $model->done . "; Sikertelen: " . $model->failed ); + + \Yii::info('Importálás: sikeres: ' .$model->done . " , sikertelen: " . $model->failed); + return $this->redirect ( [ + 'card-package/import' + ] ); + } + } + + return $this->render ( "import", [ + 'model' => $model + ] ); + } + + /** + * Updates an existing CardPackage model. + * If update is successful, the browser will be redirected to the 'view' page. + * + * @param integer $id + * @return mixed + */ + public function actionUpdate($id) { + $model = $this->findModel ( $id ); + + if ($model->load ( Yii::$app->request->post () ) && $model->save ()) { + return $this->redirect ( [ + 'view', + 'id' => $model->id_card_package + ] ); + } else { + return $this->render ( 'update', [ + 'model' => $model + ] ); + } + } + + /** + * Deletes an existing CardPackage model. + * If deletion is successful, the browser will be redirected to the 'index' page. + * + * @param integer $id + * @return mixed + */ + public function actionDelete($id) { + $this->findModel ( $id )->delete (); + + return $this->redirect ( [ + 'index' + ] ); + } + + /** + * Finds the CardPackage model based on its primary key value. + * If the model is not found, a 404 HTTP exception will be thrown. + * + * @param integer $id + * @return CardPackage the loaded model + * @throws NotFoundHttpException if the model cannot be found + */ + protected function findModel($id) { + if (($model = CardPackage::findOne ( $id )) !== null) { + return $model; + } else { + throw new NotFoundHttpException ( 'The requested page does not exist.' ); + } + } +} diff --git a/backend/models/AccountStateSearch.php b/backend/models/AccountStateSearch.php index 359921a..9911d9b 100644 --- a/backend/models/AccountStateSearch.php +++ b/backend/models/AccountStateSearch.php @@ -8,6 +8,7 @@ use yii\data\ActiveDataProvider; use common\models\AccountState; use common\components\RoleDefinition; use common\models\Account; +use common\components\Helper; /** * AccountStateSearch represents the model behind the search form about `common\models\AccountState`. @@ -65,6 +66,8 @@ class AccountStateSearch extends AccountState if ( RoleDefinition::isReception()){ $query->andWhere(['transfer.id_user' => Yii::$app->user->id ]); } + + Helper::restrictIfNotAdminTheStartDate($query, $this->timestampStart,['account_state.created_at'],"date" ); } $dataProvider = new ActiveDataProvider([ diff --git a/backend/models/CardInsertForm.php b/backend/models/CardInsertForm.php new file mode 100644 index 0000000..ae28e33 --- /dev/null +++ b/backend/models/CardInsertForm.php @@ -0,0 +1,30 @@ + $query, + 'sort' =>[ + 'defaultOrder' => ['created_at' => SORT_DESC] + ] + ]); + + $this->load($params); + + if (!$this->validate()) { + // uncomment the following line if you do not want to return any records when validation fails + // $query->where('0=1'); + return $dataProvider; + } + + $query->andFilterWhere([ + 'id_card_package' => $this->id_card_package, + 'id_user' => $this->id_user, + ]); + + if ( isset($this->printStatus)){ + switch ($this->printStatus){ + case self::$STATUS_NOT_PRINTED: + $query->andWhere( ['or' ,['card_package.printed' => null], [ "card_package.printed" => 0 ] ]); + break; + case self::$STATUS_PRINTED: + $query->andWhere( [">" ,"card_package.printed" , 0 ]); + break; + } + } + + return $dataProvider; + } + + public static function getPrintStatuses(){ + return [ + self::$STATUS_NOT_PRINTED => "Nincs letöltve", + self::$STATUS_PRINTED => "Letöltve", + ]; + } +} diff --git a/backend/models/TransferSearch.php b/backend/models/TransferSearch.php index 0529c6f..8772ac0 100644 --- a/backend/models/TransferSearch.php +++ b/backend/models/TransferSearch.php @@ -97,6 +97,8 @@ class TransferSearch extends Transfer return $dataProvider; } + echo "start date:" .$this->timestampStart; + $query->andFilterWhere([ 'transfer.id_account' => $this->id_account, 'transfer.type' => $this->type, @@ -111,6 +113,10 @@ class TransferSearch extends Transfer $query->andFilterWhere(['or' , $created_condition , $paid_condition]); + if (!RoleDefinition::isAdmin()){ + Helper::restrictIfNotAdminTheStartDate($query, $this->timestampStart,['transfer.created_at','transfer.paid_at'],'date'); + } + return $dataProvider; } @@ -127,8 +133,14 @@ class TransferSearch extends Transfer $accountMap = ArrayHelper::map( $accounts ,'id_account','name' ); $idUser = $this->id_user; + /**mk totals need date time format*/ + $start = $this->timestampStart; + if ( isset($start) && !empty($start)){ + $start .= " 00:00"; + } - $this->totals = Transfer::mkTotals($this->timestampStart, $this->timestampEnd, $idUser, $this->types, $this->id_account, $accounts, $accountMap); + + $this->totals = Transfer::mkTotals($start, $this->timestampEnd, $idUser, $this->types, $this->id_account, $accounts, $accountMap); } diff --git a/backend/views/card-package/_form.php b/backend/views/card-package/_form.php new file mode 100644 index 0000000..e95b62a --- /dev/null +++ b/backend/views/card-package/_form.php @@ -0,0 +1,28 @@ + + +
+ + + + +
+
+ field($model, 'count')->textInput()->label("Hány új kártyát szerentnél?") ?> +
+
+ +
+ 'btn btn-success' ]) ?> +
+ + + +
diff --git a/backend/views/card-package/_search.php b/backend/views/card-package/_search.php new file mode 100644 index 0000000..cb3d1bf --- /dev/null +++ b/backend/views/card-package/_search.php @@ -0,0 +1,49 @@ + + + 'Mind'] + HtmlHelper::mkOptions( User::read() ,'id','username'); +$statusOptions = ['' => 'Mind'] + CardPackageSearch::getPrintStatuses(); +?> + + diff --git a/backend/views/card-package/create.php b/backend/views/card-package/create.php new file mode 100644 index 0000000..b49d4dc --- /dev/null +++ b/backend/views/card-package/create.php @@ -0,0 +1,21 @@ +title = Yii::t('common/card_package', 'Új kártya csomag'); +$this->params['breadcrumbs'][] = ['label' => Yii::t('common/card_package', 'Kártya csomagok'), 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +?> +
+ +

title) ?>

+ + render('_form', [ + 'model' => $model, + ]) ?> + +
diff --git a/backend/views/card-package/import.php b/backend/views/card-package/import.php new file mode 100644 index 0000000..1371ed2 --- /dev/null +++ b/backend/views/card-package/import.php @@ -0,0 +1,38 @@ + + + +

Kártya csomag rfid hozzárendelés feltöltés

+ +

Itt van lehetőséged a kártyás cégtől kapott kártya-rfid hozzárendelés fájl feltöltésére

+ +
+ + ['enctype' => 'multipart/form-data']]) ?> + + +
+
+ field($model, 'file')->fileInput([''])->label("Excel fájl kiválasztása") ?> +
+
+ +
+ 'btn btn-success' ]) ?> +
+ + + +
+

+Az excel fájlnak a következő formátumban kell lennie: +

+Az importálás során csak az első és harmadik oszlopot olvassuk be. +

+ diff --git a/backend/views/card-package/index.php b/backend/views/card-package/index.php new file mode 100644 index 0000000..0037d15 --- /dev/null +++ b/backend/views/card-package/index.php @@ -0,0 +1,81 @@ +title = Yii::t('common/card_package', 'Kártyacsomagok'); +$this->params['breadcrumbs'][] = $this->title; +?> +

+ +

title) ?>

+ +

+ Itt generálhatunk a rendszerbe új beléptető kártyákat.
+ A kártyak generálása úgynevezett csomagonként történik. + A művelet során az új kártyákat egy csomagba rendezzük, + majd letölthetjük a csomaghoz tartozó excel fájlt, ami az elkészítendő kártyák + kártya azonosítóit tartalmazzák. + A letöltött fájlt továbbküldhetjük a kártya készítő cégnek. + +

+

+ Miután a kártya készítő cég végzett, a kártyák mellé mellékel egy excel fájlt, amit + a '> + Kártya csomag RFID hozzárendelés + + menüpont alatt importálhatunk be. + Ezután lesz használható a kártya az rfid olvasóval +

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

+ 'btn btn-success']) ?> +

+ + $dataProvider, + 'columns' => [ + + 'id_card_package', + [ + 'attribute' => 'id_user', + 'value' => 'userName' + ], + 'count', + 'printed', + 'created_at:datetime', + ['attribute'=> 'updated_at','value' => 'printedDate', 'label' =>'Utolsó letöltés ideje','format' => 'datetime'], + + ['class' => 'yii\grid\ActionColumn', + + 'template' => '{view}, {download}', + + 'urlCreator' => function ($action, $model, $key, $index){ + $result = ""; + if ( 'view' == $action ){ + $result = Url::toRoute(['card-package/view' , 'id' => $model->id_card_package ]); + }else if ( 'download' == $action ){ + $result = Url::toRoute(['card-package/download' , 'id' => $model->id_card_package ]); + } + return $result; + }, + 'buttons' =>[ + 'view' => function ($url, $model, $key) { + return Html::a("Részletek" ,$url,['class' =>'btn btn-primary btn-xs']); + }, + 'download' => function ($url, $model, $key) { + return Html::a("Excel letöltés" ,$url,['class' =>'btn btn-primary btn-xs']); + }, + ] + + ], + ], + ]); ?> + +
diff --git a/backend/views/card-package/update.php b/backend/views/card-package/update.php new file mode 100644 index 0000000..6b889af --- /dev/null +++ b/backend/views/card-package/update.php @@ -0,0 +1,23 @@ +title = Yii::t('common/card_package', 'Update {modelClass}: ', [ + 'modelClass' => 'Card Package', +]) . ' ' . $model->id_card_package; +$this->params['breadcrumbs'][] = ['label' => Yii::t('common/card_package', 'Card Packages'), 'url' => ['index']]; +$this->params['breadcrumbs'][] = ['label' => $model->id_card_package, 'url' => ['view', 'id' => $model->id_card_package]]; +$this->params['breadcrumbs'][] = Yii::t('common/card_package', 'Update'); +?> +
+ +

title) ?>

+ + render('_form', [ + 'model' => $model, + ]) ?> + +
diff --git a/backend/views/card-package/view.php b/backend/views/card-package/view.php new file mode 100644 index 0000000..c55aafb --- /dev/null +++ b/backend/views/card-package/view.php @@ -0,0 +1,59 @@ +title = "Kártya csomag: "+$model->id_card_package; +$this->params['breadcrumbs'][] = ['label' => Yii::t('common/card_package', 'Kártya csomagok'), 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +?> +
+ +

title) ?>

+ +

+ $model->id_card_package], ['class' => 'btn btn-primary']) ?> +

+ + $model, + 'attributes' => [ + 'id_card_package', + ['attribute' => 'user','value' => $model->userName], + 'id_user', + 'count', + 'printed', + 'created_at:datetime', + 'printedDate:datetime', + ], + ]) ?> + + $dataProvider, + 'columns' => [ + [ + 'attribute' => 'id_card', + 'label' => "Kártya azonosító" + ], + [ + 'attribute' => 'number', + 'label' => "Kártyaszám" + ], + [ + 'attribute' => 'rfid_key', + 'label' => "RFID szám" + ], + [ + 'attribute' => 'created_at', + 'label' => "Létrehozva", + 'format' => 'datetime' + ], + ] + ]); + ?> + +
diff --git a/backend/views/card/insert.php b/backend/views/card/insert.php new file mode 100644 index 0000000..ef02f5b --- /dev/null +++ b/backend/views/card/insert.php @@ -0,0 +1,16 @@ + + + ['enctype' => 'multipart/form-data']]) ?> + + field($model, 'file')->fileInput() ?> + + + message); + ?> + + + \ No newline at end of file diff --git a/backend/web/images/card_package.jpg b/backend/web/images/card_package.jpg new file mode 100644 index 0000000..c52bbdb Binary files /dev/null and b/backend/web/images/card_package.jpg differ diff --git a/changelog.txt b/changelog.txt index b0debd8..64a23b3 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,5 @@ +-0.0.33 + - Az adminon kívül mindenki csak max 3 napot lát visszamenőleg mindenből -0.0.32 - Add product inventory to reception -0.0.31 diff --git a/common/components/FreeUniqueCardNumberGenerator.php b/common/components/FreeUniqueCardNumberGenerator.php new file mode 100644 index 0000000..882179b --- /dev/null +++ b/common/components/FreeUniqueCardNumberGenerator.php @@ -0,0 +1,40 @@ +count == 0) { + return; + } + + for($i = 0; $i < $this->count; $i ++) { + + $unique = false; + $number = null; + while ( $unique == false ) { + $number = Helper::generateRandomString($this->length, $this->keyset); + $number = $this->prefix . $number; + $unique = $this->checkCacheUnique ( $number ) && $this->checkDBUniqu ( $number ); + } + $this->cache [] = $number; + } + } + protected function checkDBUniqu($number) { + $query = Card::find (); + Card::addCardNumberCondition ( $query, $number ); + $found = $query->all (); + $result = count ( $found ) == 0; + return $result; + } + protected function checkCacheUnique($number) { + return array_search ( $number, $this->cache ) === false; + } +} \ No newline at end of file diff --git a/common/components/Helper.php b/common/components/Helper.php index 331f5d7..8d0a500 100644 --- a/common/components/Helper.php +++ b/common/components/Helper.php @@ -5,6 +5,88 @@ namespace common\components; use \Yii; class Helper { + + public static function isStartDateToEarly($days_between){ + $days_visiblity = Helper::getReceptionVisibilityDays(); +// $days_between = $this->calcStartDaysSinceToday(); + return $days_between > $days_visiblity; + } + + /** + * @param string $start the date string, format "datetime => "Y-m-d H:i", "date => "Y-m-d" + * */ + public static function calcStartDatimeDaysSinceToday($start, $format = "datetime" ){ + $now = time(); + + if ( $format == "datetime"){ + $format = "Y-m-d H:i"; + }else if ( $format == "date") { + $format = "Y-m-d"; + }else{ + //use format + } + + $d = \DateTime::createFromFormat( $format , $start)->getTimeStamp(); + $days_between = ceil(abs( $now - $d) / 86400 ); + + return $days_between; + } + + + /** + * Leellenőriz egy dátumot. Ha az aktuális felhasználó nem admin, + * akkor a params[reception_visibility_days] napnál korábbi , vagy null + * dátumot e params-ban megadott dátumra állítjuk + * + * + * */ + public static function restrictIfNotAdminTheStartDate($query,$date, $fields = ['transfer.paid_at','transfer.created_at'], $format = 'datetime'){ + $result = null; + + + $needFix = false; + if ( !isset($date) || empty($date)){ + $needFix = true; + }else { + $days = Helper::calcStartDatimeDaysSinceToday($date,$format); + if ( Helper::isStartDateToEarly($days)){ + $needFix = true; + } + } + + if ( $needFix == true ){ + $d = Helper::getReceptionVisibilityDays(); + + $time = date( "Y-m-d H:i:s", strtotime("today -$d day") ); + + $conditions = []; + + foreach ($fields as $f ){ + $conditions[] = ['>=', $f, $time]; + } + + + if ( count($conditions) > 1 ){ + $andWhereCond = []; + $andWhereCond[0] = "or"; + $i = 1; + foreach ($conditions as $c){ + $andWhereCond[$i] = $c; + $i++; + } + }else if ( count($conditions) == 1 ){ + $andWhereCond = $conditions[0]; + } + +// $start_date_condition = ['or',[ '>=', 'transfer.created_at', $time ] ,[ '>=', 'transfer.paid_at', $time] ]; + if ( isset($andWhereCond)){ + $query->andWhere( $andWhereCond ); + } + + } + + return $result; + } public static function getDateTimeString( ){ @@ -173,16 +255,27 @@ class Helper { public static function isUserCartVisibilityUser() { return \Yii::$app->params ['user_cart_item_visibility'] == 'user'; } + public static function isCompanyMovar() { return \Yii::$app->params ['company'] == 'movar'; } + public static function isProductVisibilityAccount() { return \Yii::$app->params ['product_visiblity'] == 'account'; } + public static function isAccountStateClosePreloadMoney() { return \Yii::$app->params ['account_state_close_preload_money'] == true; } + public static function isAccountStateOpenSendMail() { + return \Yii::$app->params ['mail_account_state_open'] == true; + } + + public static function isAccountStateCloseSendMail() { + return \Yii::$app->params ['mail_account_state_close'] == true; + } + public static function getReceptionVisibilityDays() { return \Yii::$app->params ['reception_visibility_days'] ; } @@ -237,5 +330,15 @@ class Helper { } return $result; } + + public static function generateRandomString($length = 6,$characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' ) { + $charactersLength = strlen($characters); + $randomString = ''; + for ($i = 0; $i < $length; $i++) { + $randomString .= $characters[rand(0, $charactersLength - 1)]; + } + return $randomString; + } + } \ No newline at end of file diff --git a/common/components/XLSUtil.php b/common/components/XLSUtil.php new file mode 100644 index 0000000..6c1875b --- /dev/null +++ b/common/components/XLSUtil.php @@ -0,0 +1,44 @@ +objPHPExcel = $objReader->load ( $inputFileName ); + echo "type is: " . $inputFileType; + } catch ( Exception $e ) { + \Yii::error ( "failed to read xls" ); + throw $e; + } + } + + /** + * first sheet to array + */ + public function toArray( ) { + $objPHPExcel = $this->objPHPExcel; + $array = [ ]; + // Get worksheet dimensions + $sheet = $objPHPExcel->getActiveSheet(); + //$highestColumn = $sheet->getHighestColumn(); + $hr = $sheet->getHighestRow(); + foreach ( $sheet->getRowIterator () as $row ) { + $arrayRow = []; + $cellIterator = $row->getCellIterator (); + $cellIterator->setIterateOnlyExistingCells ( false ); // Loop all cells, even if it is not set + foreach ( $cellIterator as $cell ) { + $arrayRow [] = $cell->getCalculatedValue(); + } + $array[] = $arrayRow; + } + + return $array; + } +} \ No newline at end of file diff --git a/common/components/accountstate/AccountStateMail.php b/common/components/accountstate/AccountStateMail.php index 089d02c..10cafed 100644 --- a/common/components/accountstate/AccountStateMail.php +++ b/common/components/accountstate/AccountStateMail.php @@ -63,10 +63,14 @@ class AccountStateMail extends Object { $this->attachPdf(); - $this->message->setFrom(\Yii::$app->params['infoEmail']) - ->setTo( \Yii::$app->params['notify_mail'] ) - ->setSubject($subject ) - ->send(); + try{ + $this->message->setFrom(\Yii::$app->params['infoEmail']) + ->setTo( \Yii::$app->params['notify_mail'] ) + ->setSubject($subject ) + ->send(); + }catch (\Exception $e){ + \Yii::error("Nem sikerült elküldeni a kassza müvelet emailt"); + } } diff --git a/common/config/params.php b/common/config/params.php index be06504..0cfed25 100644 --- a/common/config/params.php +++ b/common/config/params.php @@ -4,12 +4,15 @@ return [ 'supportEmail' => 'rocho02@gmail.com', 'infoEmail' => 'info@rocho-net.hu', 'user.passwordResetTokenExpire' => 3600, - 'version' => 'v0.0.32', + 'version' => 'v0.0.33', 'company' => 'movar',//gyor 'company_name' => "Freimann Kft.", 'product_visiblity' => 'account',// on reception which products to display. account or global 'notify_mail' => ['rocho02@gmail.com' ], + /**Kassza nyitáskor küldjünk email-t?*/ 'mail_account_state_open' => true, + /**Kassza záráskor küldjünk email-t?*/ + 'mail_account_state_close' => true, 'login_reception_email' => true, //if reception login should send email 'login_admin_email' => true, //if admin login should send email 'account_state_close_preload_money' => 'true',//preload money wnen show account state close page diff --git a/common/models/CardCardPackageAssignment.php b/common/models/CardCardPackageAssignment.php new file mode 100644 index 0000000..089e90d --- /dev/null +++ b/common/models/CardCardPackageAssignment.php @@ -0,0 +1,50 @@ + Yii::t('common/card_package', 'Id Card Card Package Assignment'), + 'id_card_package' => Yii::t('common/card_package', 'Id Card Package'), + 'id_card' => Yii::t('common/card_package', 'Id Card'), + 'created_at' => Yii::t('common/card_package', 'Created At'), + 'updated_at' => Yii::t('common/card_package', 'Updated At'), + ]; + } +} diff --git a/common/models/CardPackage.php b/common/models/CardPackage.php new file mode 100644 index 0000000..c64f630 --- /dev/null +++ b/common/models/CardPackage.php @@ -0,0 +1,80 @@ +hasOne(User::className(), ['id' => 'id_user' ]); + } + public function getCardAssignments(){ + return $this->hasMany(CardCardPackageAssignment::className(), ['id_card_package' => 'id_card_package' ]); + } + public function getCards(){ + return $this->hasMany(Card::className(), ['id_card' => 'id_card' ])->via('cardAssignments'); + } + + public function getUserName(){ + $user = $this->user; + $result = ""; + if ( isset($user) ){ + $result = $this->user->username; + } + return $result; + } + + /** + * @inheritdoc + */ + public function rules() + { + return [ + [['count'], 'integer',"min" => 1 , "max" => 3000], + [['count'], 'required'], + ]; + } + + public function getPrintedDate(){ + if ( $this->printed > 0 ){ + return $this->updated_at; + } + return null; + } + + /** + * @inheritdoc + */ + public function attributeLabels() + { + return [ + 'id_card_package' => Yii::t('common/card_package', 'Kártya csomag azonosító'), + 'id_user' => Yii::t('common/card_package', 'Felhasználó'), + 'count' => Yii::t('common/card_package', 'Mennyiség'), + 'printed' => Yii::t('common/card_package', 'Letöltve'), + 'printedDate' => Yii::t('common/card_package', 'Utolsó letöltés ideje'), + 'count' => Yii::t('common/card_package', 'Mennyiség'), + 'created_at' => Yii::t('common/card_package', 'Létrehozva'), + 'updated_at' => Yii::t('common/card_package', 'Nyomtatva'), + ]; + } +} diff --git a/common/models/Transfer.php b/common/models/Transfer.php index 8c1b555..fb30ce2 100644 --- a/common/models/Transfer.php +++ b/common/models/Transfer.php @@ -671,6 +671,13 @@ class Transfer extends \common\models\BaseFitnessActiveRecord { self::notInInterval ( $query, 'transfer.created_at', $start, $end ); } + echo "start date is: ". $start; + echo "start date is: " . gettype( $start ); + + if ( !RoleDefinition::isAdmin() ){ + Helper::restrictIfNotAdminTheStartDate($query, $start); + } + $query->groupBy ( 'transfer.id_account' ); return $query; @@ -837,6 +844,16 @@ class Transfer extends \common\models\BaseFitnessActiveRecord { return $result; } + + /** + * Ezt a függvényt használjuk a zárások összegének kiszámolására! + * A számolás csak a következő feltételekkel bíró tranzakciókat + * tartalmazza: + * - trazakció típus: common\models\Account::TYPE_ALL + * - tranzakció fizetési módja: készpénz + * - tranzakció státusza: fizetve + * - + * */ public static function readPaid($start, $end, $idUser) { $query = (new \yii\db\Query ()); $query->select ( [ diff --git a/common/models/TransferSaleSearch.php b/common/models/TransferSaleSearch.php index 147b92a..10921e9 100644 --- a/common/models/TransferSaleSearch.php +++ b/common/models/TransferSaleSearch.php @@ -14,6 +14,7 @@ use common\models\Account; use yii\helpers\ArrayHelper; use common\models\MoneyMovement; use common\components\RoleDefinition; +use common\components\Helper; /** * TransferSearch represents the model behind the search form about `common\models\Transfer`. */ @@ -168,6 +169,16 @@ class TransferSaleSearch extends Transfer $query->andFilterWhere(['or' , $created_condition , $paid_condition]); + + $needRestirct = false; + if ( $this->isModeAdmin() ){ + $needRestirct = !RoleDefinition::isAdmin(); + }else{ + $needRestirct = true; + } + if ( $needRestirct ){ + Helper::restrictIfNotAdminTheStartDate($query, $this->timestampStart); + } // $query->andWhere(['transfer.status' => Transfer::STATUS_PAID]); diff --git a/common/models/TransferTicketSearch.php b/common/models/TransferTicketSearch.php index fa4a74c..71c493f 100644 --- a/common/models/TransferTicketSearch.php +++ b/common/models/TransferTicketSearch.php @@ -14,12 +14,19 @@ use common\models\Account; use yii\helpers\ArrayHelper; use common\models\MoneyMovement; use common\components\RoleDefinition; +use common\components\Helper; /** * TransferSearch represents the model behind the search form about `common\models\Transfer`. */ class TransferTicketSearch extends Transfer { + /** + * if mode is recepion, date restriction will be used + * if mode is admin, date restriction will be used based on user role + * */ + public $mode = 'reception'; + public $start; public $end; @@ -126,6 +133,8 @@ class TransferTicketSearch extends Transfer } + + protected function calcTotal(){ $this->total = 0; $this->total += $this->ticketMoney; @@ -166,9 +175,24 @@ class TransferTicketSearch extends Transfer $query->andWhere(['transfer.status' => Transfer::STATUS_PAID]); + $this->restrictStartDate($query); } + function restrictStartDate($query){ + $needRestriction = false; + if ( $this->mode == 'admin'){ + $needRestriction = !RoleDefinition::isAdmin( ) ; + }else{ + $needRestriction = true; + } + + if ( $needRestriction ){ + Helper::restrictIfNotAdminTheStartDate($query, $this->timestampStart); + } + + } + protected function readTicketStas(){ $query = (new \yii\db\Query()); diff --git a/console/migrations/m160211_111418_create__table__card_package.php b/console/migrations/m160211_111418_create__table__card_package.php new file mode 100644 index 0000000..02e491c --- /dev/null +++ b/console/migrations/m160211_111418_create__table__card_package.php @@ -0,0 +1,50 @@ +db->driverName === 'mysql') { + // http://stackoverflow.com/questions/766809/whats-the-difference-between-utf8-general-ci-and-utf8-unicode-ci + $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB'; + } + + $this->createTable('{{%card_package}}', [ + 'id_card_package' => $this->primaryKey(), + 'id_user' => $this->integer(11), + 'count' => $this->integer(11), + 'created_at' => $this->dateTime()->notNull(), + 'updated_at' => $this->dateTime()->notNull(), + ], $tableOptions); + + $this->createTable('{{%card_card_package_assignment}}', [ + 'id_card_card_package_assignment' => $this->primaryKey(), + 'id_card_package' => $this->integer(11), + 'id_card' => $this->integer(11), + 'created_at' => $this->dateTime()->notNull(), + 'updated_at' => $this->dateTime()->notNull(), + ], $tableOptions); + } + + public function down() + { + echo "m160211_111418_create__table__card_package cannot be reverted.\n"; + + return false; + } + + /* + // Use safeUp/safeDown to run migration code within a transaction + public function safeUp() + { + } + + public function safeDown() + { + } + */ +} diff --git a/console/migrations/m160212_051248_alter__table__card_package__add_column_printed.php b/console/migrations/m160212_051248_alter__table__card_package__add_column_printed.php new file mode 100644 index 0000000..f934f01 --- /dev/null +++ b/console/migrations/m160212_051248_alter__table__card_package__add_column_printed.php @@ -0,0 +1,30 @@ +addColumn("card_package", "printed", "int"); + } + + public function down() + { + echo "m160212_051248_alter__table__card_package__add_column_printed cannot be reverted.\n"; + + return false; + } + + /* + // Use safeUp/safeDown to run migration code within a transaction + public function safeUp() + { + } + + public function safeDown() + { + } + */ +} diff --git a/frontend/components/FrontendMenuStructure.php b/frontend/components/FrontendMenuStructure.php index 779a9c7..d5ebc01 100644 --- a/frontend/components/FrontendMenuStructure.php +++ b/frontend/components/FrontendMenuStructure.php @@ -82,10 +82,10 @@ class FrontendMenuStructure{ $items[] = ['label' => Yii::t('frontend/transfer','Ticket sale detailed'), 'url' => [ '/transfer/tickets','TransferTicketSearch[id_user]' =>\Yii::$app->user->id, 'TransferTicketSearch[id_account]' => Account::readDefault(), 'TransferTicketSearch[start]' => $this->start, 'TransferTicketSearch[end]' => $this->tomorrow ] ]; } - if ( $isadmin || Yii::$app->user->can('reception.transfers') ){ +// if ( $isadmin || Yii::$app->user->can('reception.transfers') ){ $items[] = ['label' => Yii::t('frontend/transfer','Transfers'), 'url' => ['/transfer/index', 'TransferSearch[id_user]' =>\Yii::$app->user->id, 'TransferSearch[id_account]' => Account::readDefault(), 'TransferSearch[start]' => $this->start, 'TransferSearch[end]' => $this->tomorrow ] ]; //$items[] = ['label' => Yii::t('frontend/collection','Collections'), 'url' => ['/collection/index' , 'CollectionSearch[start]' =>$this->start,'CollectionSearch[end]' => $this->tomorrow ] ]; - } +// } $items[] = ['label' => Yii::t('frontend/card','Vendégek'), 'url' => [ '/card/index' ] ]; $items[] = ['label' => Yii::t('frontend/card','Leltár'), 'url' => [ '/product/inventory' ] ]; diff --git a/frontend/controllers/AccountStateController.php b/frontend/controllers/AccountStateController.php index 9e73d51..f19fa98 100644 --- a/frontend/controllers/AccountStateController.php +++ b/frontend/controllers/AccountStateController.php @@ -86,8 +86,10 @@ class AccountStateController extends Controller { // return $this->redirect(['view', 'id' => $model->id_account_state]); - $mail = new AccountStateMail(['model' => $model,'controller' => $this]); - $mail->sednMail(); + if ( Helper::isAccountStateOpenSendMail() ){ + $mail = new AccountStateMail(['model' => $model,'controller' => $this]); + $mail->sednMail(); + } return $this->redirect ( [ @@ -132,9 +134,10 @@ class AccountStateController extends Controller { if ($model->load ( Yii::$app->request->post () ) && $model->save ()) { - - $mail = new AccountStateMail(['model' => $model,'controller' => $this]); - $mail->sednMail(); + if ( Helper::isAccountStateCloseSendMail()){ + $mail = new AccountStateMail(['model' => $model,'controller' => $this]); + $mail->sednMail(); + } return $this->redirect ( [ 'index' diff --git a/frontend/models/AccountstateSearch.php b/frontend/models/AccountstateSearch.php index e690752..827df6d 100644 --- a/frontend/models/AccountstateSearch.php +++ b/frontend/models/AccountstateSearch.php @@ -6,6 +6,7 @@ use Yii; use yii\base\Model; use yii\data\ActiveDataProvider; use common\models\AccountState; +use common\components\Helper; /** * AccountstateSearch represents the model behind the search form about `common\models\AccountState`. @@ -80,6 +81,8 @@ class AccountstateSearch extends AccountState $query->andFilterWhere([ '>=', 'account_state.created_at', $this->timestampStart ] ); $query->andFilterWhere([ '<', 'account_state.created_at', $this->timestampEnd ] ); + Helper::restrictIfNotAdminTheStartDate($query, $this->timestampStart, ['account_state.created_at']); + $query->orderBy( 'created_at desc' ); $query->limit = 20; diff --git a/frontend/models/MoneyMovementSearch.php b/frontend/models/MoneyMovementSearch.php index 45896ea..0e32fd4 100644 --- a/frontend/models/MoneyMovementSearch.php +++ b/frontend/models/MoneyMovementSearch.php @@ -7,6 +7,7 @@ use yii\base\Model; use yii\data\ActiveDataProvider; use common\models\MoneyMovement; use yii\helpers\ArrayHelper; +use common\components\Helper; /** * MoneyMovementSearch represents the model behind the search form about `common\models\MoneyMovement`. @@ -67,6 +68,8 @@ class MoneyMovementSearch extends MoneyMovement $query->andFilterWhere([ '>=', 'money_movement.created_at', $this->timestampStart ] ); $query->andFilterWhere([ '<', 'money_movement.created_at', $this->timestampEnd ] ); + + Helper::restrictIfNotAdminTheStartDate($query, $this->timestampStart,['money_movement.created_at']); return $dataProvider; } diff --git a/frontend/models/TransferSearch.php b/frontend/models/TransferSearch.php index 85889ba..3a9ce72 100644 --- a/frontend/models/TransferSearch.php +++ b/frontend/models/TransferSearch.php @@ -12,6 +12,7 @@ use yii\db\Expression; use common\models\Account; use yii\helpers\ArrayHelper; +use common\components\Helper; /** * TransferSearch represents the model behind the search form about `common\models\Transfer`. */ @@ -91,6 +92,8 @@ class TransferSearch extends Transfer $query->andFilterWhere(['or' , $created_condition , $paid_condition]); + Helper::restrictIfNotAdminTheStartDate($query, $this->timestampStart); + return $dataProvider; } @@ -106,6 +109,7 @@ class TransferSearch extends Transfer $accountMap = ArrayHelper::map( $accounts ,'id_account','name' ); $idUser = Yii::$app->user->id; + $this->totals = Transfer::mkTotals($this->timestampStart, $this->timestampEnd, $idUser, $this->types, $this->id_account, $accounts, $accountMap); diff --git a/frontend/web/js/app.js b/frontend/web/js/app.js index d5184ea..213a416 100644 --- a/frontend/web/js/app.js +++ b/frontend/web/js/app.js @@ -1,6 +1,7 @@ var enterPressed; var keyDate; var seq = ''; +var socket; $(document).ready( function(){ @@ -69,3 +70,28 @@ function addDocumentKeypressedListener(){ } } + + + +function startServer(){ + try{ + socket = new WebSocket("ws://localhost:8025/websockets/qrcode"); + console.info('socket created'); + socket.onmessage = function (event) { + console.log(event.data); + var msg = JSON.stringify(event.data); + if ( msg.msg == 'qrcode'){ + console.info('qrcode rcvd'); + } + } + }catch(e){ + } + +} + + +//startServer(); + +function sendMessage(){ + socket.send("Here's some text that the server is urgently awaiting!"); +} \ No newline at end of file diff --git a/frontend/web/js/product.sell.js b/frontend/web/js/product.sell.js index f45c06a..f02db5e 100644 --- a/frontend/web/js/product.sell.js +++ b/frontend/web/js/product.sell.js @@ -576,18 +576,18 @@ function ProductSell(o){ // Some item from your model is active! if (current.name == $input.val()) { // This means the exact match is found. Use toLowerCase() if you want case insensitive match. - console.info(current); +// console.info(current); _findProduct(current.id_product); } else { // This means it is only a partial match, you can either add a new item // or take the active if you don't want new items - console.info('partial'); +// console.info('partial'); app.product = null; productChanged(); } } else { // Nothing is active so it is a new value (or maybe empty value) - console.info('incactive'); +// console.info('incactive'); app.product = null; productChanged(); }