loadComponent('GradidoNumber'); $this->loadComponent('JsonRequestClient'); //$this->Auth->allow(['add', 'edit']); //$this->Auth->allow('create'); $this->Auth->allow('ajaxCreate'); $this->set( 'naviHierarchy', (new NaviHierarchy())-> add(new NaviHierarchyEntry(__('Startseite'), 'Dashboard', 'index', false))->add(new NaviHierarchyEntry(__('Gradido schöpfen'), 'TransactionCreations', 'create-multi', true)) ); } /** * Index method * * @return \Cake\Http\Response|null */ public function index() { $this->paginate = [ 'contain' => ['Transactions', 'StateUsers'] ]; $transactionCreations = $this->paginate($this->TransactionCreations); $identHashes = []; foreach ($transactionCreations as $creation) { $identHash = TransactionCreation::DRMakeStringHash($creation->state_user->email); $identHashes[$creation->state_user->id] = $identHash; } $this->set(compact('transactionCreations', 'identHashes')); } /** * View method * * @param string|null $id Transaction Creation id. * @return \Cake\Http\Response|null * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found. */ public function view($id = null) { $transactionCreation = $this->TransactionCreations->get($id, [ 'contain' => ['Transactions', 'StateUsers'] ]); $this->set('transactionCreation', $transactionCreation); } public function create() { $startTime = microtime(true); $this->viewBuilder()->setLayout('frontend'); $session = $this->getRequest()->getSession(); $user = $session->read('StateUser'); if (!$user) { $result = $this->requestLogin(); if ($result !== true) { return $result; } $user = $session->read('StateUser'); } $creationForm = new CreationForm(); $transactionCreation = $this->TransactionCreations->newEntity(); $transactionCreation->state_user_id = $user['id']; // adding possible addresses + input field for copy $stateUserTable = TableRegistry::getTableLocator()->get('StateUsers'); $stateUsers = $stateUserTable->find('all')->contain(false); $receiverProposal = []; foreach ($stateUsers as $stateUser) { $name = $stateUser->email; $keyHex = bin2hex(stream_get_contents($stateUser->public_key)); if ($name === null) { $name = $stateUser->first_name . ' ' . $stateUser->last_name; } array_push($receiverProposal, ['name' => $name, 'key' => $keyHex, 'email' => $stateUser->email]); //$stateUser->public_key } $timeUsed = microtime(true) - $startTime; $this->set(compact('transactionCreation', 'timeUsed', 'receiverProposal', 'creationForm')); if ($this->request->is('post')) { $requestData = $this->request->getData(); $mode = 'next'; if (isset($requestData['add'])) { $mode = 'add'; } if ($creationForm->validate($requestData)) { $pubKeyHex = ''; $identHash = ''; $amountCent = $this->GradidoNumber->parseInputNumberToCentNumber($requestData['amount']); $receiverIndex = intval($requestData['receiver'])-1; if (count($receiverProposal) > $receiverIndex) { $pubKeyHex = $receiverProposal[$receiverIndex]['key']; $identHash = TransactionCreation::DRMakeStringHash($receiverProposal[$receiverIndex]['email']); } $builderResult = TransactionCreation::build( $amountCent, $requestData['memo'], $pubKeyHex, $identHash ); if ($builderResult['state'] == 'success') { $user_balance = 0; if (isset($user['balance'])) { $user_balance = $user['balance']; } // $session_id, $base64Message, $user_balance = 0 $requestResult = $this->JsonRequestClient->sendTransaction( $session->read('session_id'), base64_encode($builderResult['transactionBody']->serializeToString()), $user_balance ); if ($requestResult['state'] != 'success') { $this->addAdminError('TransactionCreations', 'create', $requestResult, $user['id']); if ($requestResult['type'] == 'request error') { $this->Flash->error(__('Error by requesting LoginServer, please try again')); } else { $this->Flash->error(__('Error, please wait for the admin to fix it')); } } else { $json = $requestResult['data']; if ($json['state'] != 'success') { if ($json['msg'] == 'session not found') { $session->destroy(); return $this->redirect($this->loginServerUrl . 'account', 303); } else { $this->addAdminError('TransactionCreations', 'create', $json, $user['id']); $this->Flash->error(__('Login Server Error, please wait for the admin to fix it')); } } else { $pendingTransactionCount = $session->read('Transactions.pending'); if ($pendingTransactionCount == null) { $pendingTransactionCount = 1; } else { $pendingTransactionCount++; } $session->write('Transactions.pending', $pendingTransactionCount); if ($mode === 'next') { return $this->redirect($this->loginServerUrl . 'account/checkTransactions', 303); } else { $this->Flash->success(__('Transaction submitted for review.')); } } } } else { $this->Flash->error(__('Building transaction failed')); } // */ } else { $this->Flash->error(__('Something was invalid, please try again!')); } } } public function createMulti($page = 0) { $startTime = microtime(true); $this->viewBuilder()->setLayout('frontend'); $session = $this->getRequest()->getSession(); $result = $this->requestLogin(); $limit = 200; if ($result !== true) { return $result; } $user = $session->read('StateUser'); $stateUserTable = TableRegistry::getTableLocator()->get('StateUsers'); $connection = ConnectionManager::get('default'); $transactionActiveMonth = $connection->execute( 'SELECT id, received FROM transactions ' . 'where received >= date_sub(date_add(curdate(), interval 1 - day(curdate()) day), interval 2 month) ' . 'AND ' . 'received < date_add(date_add(curdate(), interval 1 - day(curdate()) day), interval 2 month) ' . 'AND ' . 'transaction_type_id = 1' )->fetchAll('assoc'); $transactionActiveMonthSortedById = []; foreach ($transactionActiveMonth as $t) { $transactionActiveMonthSortedById[$t['id']] = $t['received']; } $firstDayLastMonth = new FrozenDate(); $firstDayLastMonth = $firstDayLastMonth->day(1)->subMonth(1); $transactionsLastMonthTargeDate = $this->TransactionCreations ->find('all') //->select(['state_user_id', 'target_date', 'amount']) ->where(['EXTRACT(YEAR_MONTH FROM target_date) LIKE' => $firstDayLastMonth->format('Ym')]) ->group(['state_user_id']) ->contain([]); $transactionsLastMonthTargeDate->select([ 'state_user_id', 'sum_amount' => $transactionsLastMonthTargeDate->func()->sum('amount') ]); $transactionsLastMonthTargetDateSortedByStateUserId = []; foreach ($transactionsLastMonthTargeDate as $transactionCreation) { $transactionsLastMonthTargetDateSortedByStateUserId[$transactionCreation->state_user_id] = $transactionCreation->sum_amount; } $requestData = $this->request->getData(); if ($this->request->is('post') && isset($requestData['searchButton']) && isset($requestData['searchText']) && !empty($requestData['searchText']) ) { $mode = 'search'; $page = 0; $this->log("search for text: ".$requestData['searchText'], 'debug'); $stateUsers = $stateUserTable ->find('all') ->select(['id', 'first_name', 'last_name', 'email']) ->order(['first_name', 'last_name']) ->where( ['AND' => [ 'disabled' => 0, 'OR' => [ 'LOWER(first_name) LIKE' => '%'.strtolower($requestData['searchText']).'%', 'LOWER(last_name) LIKE' => '%'.strtolower($requestData['searchText']).'%', 'LOWER(email) LIKE' => '%'.strtolower($requestData['searchText']).'%' ] ] ] ) ->contain(['TransactionCreations' => [ 'fields' => [ 'TransactionCreations.amount', 'TransactionCreations.transaction_id', 'TransactionCreations.state_user_id' ] ]]); $this->log("search query: ".$stateUsers, 'debug'); } else { $stateUsers = $stateUserTable ->find('all') ->select(['id', 'first_name', 'last_name', 'email']) //->order(['id']) ->where(['disabled' => 0]) ->order(['first_name', 'last_name']) ->contain(['TransactionCreations' => [ 'fields' => [ 'TransactionCreations.amount', 'TransactionCreations.transaction_id', 'TransactionCreations.state_user_id' ] ]]); } //var_dump($stateUsers->toArray()); $possibleReceivers = []; $countUsers = 0; foreach ($stateUsers as $i => $stateUser) { $countUsers++; if ($i < $page * $limit || $i >= ($page + 1) * $limit) { continue; } $sumAmount = 0; $sumAmount2 = 0; if (isset($transactionsLastMonthTargetDateSortedByStateUserId[$stateUser->id])) { $sumAmount2 = $transactionsLastMonthTargetDateSortedByStateUserId[$stateUser->id]; } foreach ($stateUser->transaction_creations as $transactionCreation) { //var_dump($transactionCreation); if (isset($transactionActiveMonthSortedById[$transactionCreation->transaction_id])) { $sumAmount += $transactionCreation->amount; } } //if($sumAmount < 20000000) { array_push($possibleReceivers, [ 'name' => $stateUser->first_name . ' ' . $stateUser->last_name, 'id' => $stateUser->id, 'email' => $stateUser->email, 'amount' => $sumAmount, 'amount2' => $sumAmount2 ]); /*} else { $this->Flash->error(__('Creation above 2.000 GDD for 2 last two month')); }*/ } // usort($possibleReceivers, function ($a, $b) { // return (strtolower($a['name']) <=> strtolower($b['name'])); // }); // -> replaced by SQL "order by" above $creationForm = new CreationForm(); $timeUsed = microtime(true) - $startTime; $this->set(compact('timeUsed', 'stateUsers', 'creationForm', 'possibleReceivers')); $this->set('firstDayLastMonth', $firstDayLastMonth); $this->set('activeUser', $user); $this->set('creationForm', $creationForm); $this->set('transactionExecutingCount', $session->read('Transaction.executing')); $this->set('timeUsed', microtime(true) - $startTime); $this->set('countUsers', $countUsers); $this->set('limit', $limit); $this->set('page', $page); if ($this->request->is('post') && (!isset($mode) || !($mode === 'search'))) { $this->log("real POST", 'debug'); $mode = 'next'; if (isset($requestData['add'])) { $mode = 'add'; } $memo = $requestData['memo']; $amountCent = $this->GradidoNumber->parseInputNumberToCentNumber($requestData['amount']); //$targetDate = $requestData['target_date']; if (!isset($requestData['user']) || count($requestData['user']) == 0) { $this->Flash->error(__('No user selected')); } else { $users = $requestData['user']; if (isset($requestData['user_pending'])) { $pendings = $requestData['user_pending']; } else { $pendings = []; } $receiverUsers = $stateUserTable ->find('all') ->where(['id IN' => array_keys($users)]) ->select(['public_key', 'email', 'id']) ->contain(false); $transactions = []; foreach ($receiverUsers as $receiverUser) { $localAmountCent = $amountCent; //$localTargetDate = $targetDate; $id = $receiverUser->id; if ($requestData['user_amount'][$id] != '') { $localAmountCent = $this->GradidoNumber->parseInputNumberToCentNumber($requestData['user_amount'][$id]); } if (isset($requestData['user_target_date']) && isset($requestData['user_target_date'][$id])) { $localTargetDate = $requestData['user_target_date'][$id]; } if (isset($pendings[$id])) { $pendings[$id] += $localAmountCent; } else { $pendings[$id] = $localAmountCent; } $pubKeyHex = bin2hex(stream_get_contents($receiverUser->public_key)); $identHash = TransactionCreation::DRMakeStringHash($receiverUser->email); $localTargetDateFrozen = FrozenDate::now(); $localTargetDateFrozen = $localTargetDateFrozen ->year($localTargetDate['year']) ->month($localTargetDate['month']) ->day($localTargetDate['day']); //echo "input: "; var_dump($localTargetDate);echo "
"; //echo "output: "; var_dump($localTargetDateFrozen); //die('a'); $builderResult = TransactionCreation::build( $localAmountCent, $memo, $pubKeyHex, $identHash, $localTargetDateFrozen ); if ($builderResult['state'] == 'success') { array_push($transactions, base64_encode($builderResult['transactionBody']->serializeToString())); } } /*echo "pendings: "; var_dump($pendings); echo "
";*/ foreach ($possibleReceivers as $i => $possibleReceiver) { $id = $possibleReceiver['id']; if (isset($pendings[$id])) { $possibleReceivers[$i]['pending'] = $pendings[$id]; } } $this->set('possibleReceivers', $possibleReceivers); $creationTransactionCount = count($transactions); if ($creationTransactionCount > 0) { $user_balance = 0; if (isset($user['balance'])) { $user_balance = $user['balance']; } // $session_id, $base64Message, $user_balance = 0 $requestResult = $this->JsonRequestClient->sendTransaction( $session->read('session_id'), $transactions, $user_balance ); if ($requestResult['state'] != 'success') { $this->addAdminError('TransactionCreations', 'createMulti', $requestResult, $user['id']); if ($requestResult['type'] == 'request error') { $this->Flash->error(__('Error by requesting LoginServer, please try again')); } else { $this->Flash->error(__('Error, please wait for the admin to fix it')); } } else { $json = $requestResult['data']; if ($json['state'] != 'success') { if ($json['msg'] == 'session not found') { $session->destroy(); return $this->redirect($this->loginServerUrl . 'account', 303); } else { $this->addAdminError('TransactionCreations', 'createMulti', $json, $user['id']); $this->Flash->error(__('Login Server Error, please wait for the admin to fix it')); } } else { $pendingTransactionCount = $session->read('Transactions.pending'); if ($pendingTransactionCount == null) { $pendingTransactionCount = $creationTransactionCount; } else { $pendingTransactionCount += $creationTransactionCount; } $session->write('Transactions.pending', $pendingTransactionCount); if ($mode === 'next') { return $this->redirect($this->loginServerUrl . 'account/checkTransactions', 303); } else { $this->Flash->success(__('Transaction submitted for review.')); } } } } } } } public function ajaxCreate() { if ($this->request->is('post')) { $startTime = microtime(true); $jsonData = $this->request->input('json_decode', true); $session_id = $jsonData['session_id']; if(!isset($jsonData['session_id']) || intval($jsonData['session_id']) == 0) { return $this->returnJson(['state' => 'parameter missing', 'msg' => 'invalid session id']); } $login_result = $this->requestLogin($session_id, false); if($login_result !== true) { return $this->returnJson($login_result); } $session = $this->getRequest()->getSession(); $user = $session->read('StateUser'); $memo = ''; if(isset($jsonData['memo'])) { $memo = $jsonData['memo']; } $auto_sign = true; if(isset($jsonData['auto_sign'])) { $auto_sign = $jsonData['auto_sign']; } if(!isset($jsonData['amount']) || intval($jsonData['amount']) <= 0) { return $this->returnJson(['state' => 'parameter missing', 'msg' => 'amount not set or <= 0']); } if(!isset($jsonData['email'])) { return $this->returnJson(['state' => 'parameter missing', 'msg' => 'no receiver email set']); } $amount = intval($jsonData['amount']); if($amount > 10000000) { return $this->returnJson(['state' => 'error', 'msg' => 'amount is to big']); } if($amount <= 0) { return $this->returnJson(['state' => 'error', 'msg' => 'amount must be > 0']); } if(!isset($jsonData['target_date'])) { return $this->returnJson(['state' => 'parameter missing', 'msg' => 'target_date not found']); } //$targetDate = $requestData['target_date']; $stateUserTable = TableRegistry::getTableLocator()->get('StateUsers'); $requestAnswear = $this->JsonRequestClient->sendRequest(json_encode([ 'session_id' => $session_id, 'email' => $jsonData['email'], 'ask' => ['user.pubkeyhex', 'user.disabled', 'user.identHash'] ]), '/getUserInfos'); $receiverPubKeyHex = ''; if('success' == $requestAnswear['state'] && 'success' == $requestAnswear['data']['state']) { // will be allways 64 byte long, even if it is empty $receiverPubKeyHex = $requestAnswear['data']['userData']['pubkeyhex']; } else { return $this->returnJson([ 'state' => 'error', 'msg' => 'receiver email not found on login-server', 'details' => $requestAnswear, 'timeUsed' => microtime(true) - $startTime ]); } if($requestAnswear['data']['userData']['disabled']) { return $this->returnJson([ 'state' => 'error', 'msg' => 'receiver is currently disabled, he cannot receive creations', 'timeUsed' => microtime(true) - $startTime ]); } $builderResult = TransactionCreation::build( $amount, $memo, $receiverPubKeyHex, $requestAnswear['data']['userData']['identHash'], new FrozenDate($jsonData['target_date']) ); $transaction_base64 = ''; if ($builderResult['state'] == 'success') { // todo: maybe use sodium base 64 encoder to make sure it can be readed from login-server $transaction_base64 = base64_encode($builderResult['transactionBody']->serializeToString()); } $requestResult = $this->JsonRequestClient->sendTransaction( $session_id, $transaction_base64, $user['balance'], $auto_sign ); if ($requestResult['state'] != 'success') { $msg = 'error returned from login server'; if ($requestResult['type'] === 'request error') { $msg = 'login server couldn\'t reached'; } //$this->Flash->error(__('Error, please wait for the admin to fix it')); return $this->returnJson([ 'state' => 'request error', 'msg' => $msg, 'details' => $requestResult, 'timeUsed' => microtime(true) - $startTime ]); } else { $json = $requestResult['data']; if ($json['state'] != 'success') { if ($json['msg'] == 'session not found') { $session->destroy(); return $this->returnJson(['state' => 'error', 'msg' => 'session not found', 'timeUsed' => microtime(true) - $startTime]); } else { return $this->returnJson(['state' => 'error', 'msg' => 'login server error', 'details' => $json, 'timeUsed' => microtime(true) - $startTime]); } } else { return $this->returnJson(['state' => 'success', 'timeUsed' => microtime(true) - $startTime]); } } } } /** * Add method * * @return \Cake\Http\Response|null Redirects on successful add, renders view otherwise. */ public function add() { $transactionCreation = $this->TransactionCreations->newEntity(); if ($this->request->is('post')) { $transactionCreation = $this->TransactionCreations->patchEntity($transactionCreation, $this->request->getData()); if ($this->TransactionCreations->save($transactionCreation)) { $this->Flash->success(__('The transaction creation has been saved.')); return $this->redirect(['action' => 'index']); } $this->Flash->error(__('The transaction creation could not be saved. Please, try again.')); } $transactions = $this->TransactionCreations->Transactions->find('list', ['limit' => 200]); $stateUsers = $this->TransactionCreations->StateUsers->find('list', ['limit' => 200]); $this->set(compact('transactionCreation', 'transactions', 'stateUsers')); } /** * Edit method * * @param string|null $id Transaction Creation id. * @return \Cake\Http\Response|null Redirects on successful edit, renders view otherwise. * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found. */ public function edit($id = null) { $transactionCreation = $this->TransactionCreations->get($id, [ 'contain' => [] ]); if ($this->request->is(['patch', 'post', 'put'])) { $transactionCreation = $this->TransactionCreations->patchEntity($transactionCreation, $this->request->getData()); if ($this->TransactionCreations->save($transactionCreation)) { $this->Flash->success(__('The transaction creation has been saved.')); return $this->redirect(['action' => 'index']); } $this->Flash->error(__('The transaction creation could not be saved. Please, try again.')); } $transactions = $this->TransactionCreations->Transactions->find('list', ['limit' => 200]); $stateUsers = $this->TransactionCreations->StateUsers->find('list', ['limit' => 200]); $this->set(compact('transactionCreation', 'transactions', 'stateUsers')); } /** * Delete method * * @param string|null $id Transaction Creation id. * @return \Cake\Http\Response|null Redirects to index. * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found. */ public function delete($id = null) { $this->request->allowMethod(['post', 'delete']); $transactionCreation = $this->TransactionCreations->get($id); if ($this->TransactionCreations->delete($transactionCreation)) { $this->Flash->success(__('The transaction creation has been deleted.')); } else { $this->Flash->error(__('The transaction creation could not be deleted. Please, try again.')); } return $this->redirect(['action' => 'index']); } }