diff --git a/skeema/gradido_community/transaction_group_addaddress.sql b/skeema/gradido_community/transaction_group_addaddress.sql index b9ca95651..cb21ed99f 100644 --- a/skeema/gradido_community/transaction_group_addaddress.sql +++ b/skeema/gradido_community/transaction_group_addaddress.sql @@ -1,8 +1,9 @@ CREATE TABLE `transaction_group_addaddress` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `transaction_id` int(10) unsigned NOT NULL, - `address_type_id` int(10) unsigned NOT NULL, + `id` int unsigned NOT NULL AUTO_INCREMENT, + `transaction_id` int unsigned NOT NULL, + `address_type_id` int unsigned NOT NULL, `remove_from_group` BOOLEAN DEFAULT FALSE, `public_key` binary(32) NOT NULL, + `state_user_id` int unsigned NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/src/Controller/StateBalancesController.php b/src/Controller/StateBalancesController.php index 581869818..31febe498 100644 --- a/src/Controller/StateBalancesController.php +++ b/src/Controller/StateBalancesController.php @@ -21,7 +21,7 @@ class StateBalancesController extends AppController { parent::initialize(); //$this->Auth->allow(['add', 'edit']); - $this->Auth->allow(['overview', 'overviewGdt', 'ajaxGetBalance', 'ajaxListTransactions', 'ajaxGdtOverview']); + $this->Auth->allow(['overview', 'overviewGdt', 'ajaxListTransactions', 'ajaxGdtOverview', 'ajaxGetBalance', 'ajaxGdtTransactions']); $this->loadComponent('JsonRequestClient'); } /** @@ -386,8 +386,45 @@ class StateBalancesController extends AppController public function ajaxListTransactions($page = 0, $count = 20) { - // TODO: add efficient paging with additional table: state_user_transactions - return $this->returnJson(['state' => 'success', 'transactions' => [], 'transactionExecutingCount' => 0, 'count' => 0]); + + return $this->returnJson([ + 'state' => 'error', + 'msg' => 'moved', + 'details' => 'moved to state-user-transactions/ajaxListTransactions/' + ]); + } + + public function ajaxGdtOverview() + { + $gdtSum = 0; + $gdtCount = -1; + $session = $this->getRequest()->getSession(); + $user = $session->read('StateUser'); + + if(!$user) { + return $this->returnJson(['state' => 'error', 'msg' => 'user not found', 'details' => 'exist a valid session cookie?']); + } + $gdtEntries = $this->JsonRequestClient->sendRequestGDT(['email' => $user['email']], 'GdtEntries' . DS . 'sumPerEmailApi'); + + if('success' == $gdtEntries['state'] && 'success' == $gdtEntries['data']['state']) { + $gdtSum = intval($gdtEntries['data']['sum']); + if(isset($gdtEntries['data']['count'])) { + $gdtCount = intval($gdtEntries['data']['count']); + } + } else { + if($user) { + $this->addAdminError('StateBalancesController', 'ajaxGdtOverview', $gdtEntries, $user['id']); + } else { + $this->addAdminError('StateBalancesController', 'ajaxGdtOverview', $gdtEntries, 0); + } + } + + return $this->returnJson([ + 'state' => 'success', + 'transactions' => $transactions, + 'transactionExecutingCount' => $session->read('Transaction.executing'), + 'count' => $all_user_transactions_count + ]); } public function ajaxGdtOverview() @@ -440,9 +477,9 @@ class StateBalancesController extends AppController //echo "gdtSum: $gdtSum
"; $this->set('gdtSum', $gdtSum); $this->set('ownEntries', $ownEntries); - $this->set('gdtSumPerEmail', $requestResult['data']['gdtSumPerEmail']); - $this->set('moreEntrysAsShown', $requestResult['data']['moreEntrysAsShown']); - $this->set('user', $user); + $this->set('gdtSumPerEmail', $requestResult['data']['gdtSumPerEmail']); + $this->set('moreEntrysAsShown', $requestResult['data']['moreEntrysAsShown']); + $this->set('user', $user); if (isset($requestResult['data']['publishers'])) { $publishers = $requestResult['data']['publishers']; @@ -453,6 +490,66 @@ class StateBalancesController extends AppController $this->Flash->error(__('Fehler beim GDT Server, bitte abwarten oder den Admin benachrichtigen!')); } } + + public function ajaxGdtTransactions() + { + $startTime = microtime(true); + $session = $this->getRequest()->getSession(); + $user = $session->read('StateUser'); + if(!$user) { + return $this->returnJson(['state' => 'error', 'msg' => 'user not found', 'details' => 'exist a valid session cookie?']); + } + + $requestResult = $this->JsonRequestClient->sendRequestGDT(['email' => $user['email']], 'GdtEntries' . DS . 'listPerEmailApi'); + $connectEntries = []; + $publishers = []; + + //var_dump($requestResult); + if('success' === $requestResult['state'] && 'success' === $requestResult['data']['state']) { + + //var_dump(array_keys($requestResult['data'])); + $ownEntries = $requestResult['data']['ownEntries']; + //$gdtEntries = $requestResult['data']['entries']; + + $gdtSum = 0; + foreach ($ownEntries as $i => $gdtEntry) { + $gdtSum += $gdtEntry['gdt']; + //echo "index: $i
"; + //var_dump($gdtEntry); + } + if (isset($requestResult['data']['connectEntrys'])) { + $connectEntries = $requestResult['data']['connectEntrys']; + + foreach ($connectEntries as $entry) { + //if(!$count) var_dump($entry); + //$count++; + $gdtSum += $entry['connect']['gdt_entry']['gdt']; + } + } + + //echo "gdtSum: $gdtSum
"; + + if (isset($requestResult['data']['publishers'])) { + $publishers = $requestResult['data']['publishers']; + } + } else { + $this->addAdminError('StateBalancesController', 'ajaxGdtTransactions', $requestResult, $user['id']); + //$this->Flash->error(__('Fehler beim GDT Server, bitte abwarten oder den Admin benachrichtigen!')); + return $this->returnJson(['state' => 'error', 'msg' => 'error from gdt server', 'details' => $requestResult]); + } + + + return $this->returnJson([ + 'state' => 'success', + 'gdtSum' => $gdtSum, + 'ownEntries' => $ownEntries, + 'connectEntries' => $connectEntries, + 'publishers' => $publishers, + 'gdtSumPerEmail' => $requestResult['data']['gdtSumPerEmail'], + 'moreEntrysAsShown' => $requestResult['data']['moreEntrysAsShown'], + 'timeUsed' => microtime(true) - $startTime + ]); + } public function sortTransactions($a, $b) { diff --git a/src/Controller/StateUserTransactionsController.php b/src/Controller/StateUserTransactionsController.php index 8c252218c..e9008179e 100644 --- a/src/Controller/StateUserTransactionsController.php +++ b/src/Controller/StateUserTransactionsController.php @@ -20,6 +20,7 @@ class StateUserTransactionsController extends AppController $this->Auth->allow(['ajaxListTransactions']); //$this->loadComponent('JsonRequestClient'); } + /** * Index method * diff --git a/src/Model/Entity/TransactionGroupAddaddres.php b/src/Model/Entity/TransactionGroupAddaddres.php index 0559a6302..30819209f 100644 --- a/src/Model/Entity/TransactionGroupAddaddres.php +++ b/src/Model/Entity/TransactionGroupAddaddres.php @@ -31,6 +31,7 @@ class TransactionGroupAddaddres extends Entity 'remove_from_group' => true, 'public_key' => true, 'transaction' => true, - 'address_type' => true + 'address_type' => true, + 'state_user_id' => true ]; } diff --git a/src/Model/Table/TransactionGroupAddaddressTable.php b/src/Model/Table/TransactionGroupAddaddressTable.php index 3fd03f32a..cb9912083 100644 --- a/src/Model/Table/TransactionGroupAddaddressTable.php +++ b/src/Model/Table/TransactionGroupAddaddressTable.php @@ -45,6 +45,10 @@ class TransactionGroupAddaddressTable extends Table 'foreignKey' => 'address_type_id', 'joinType' => 'INNER' ]); + $this->belongsTo('StateUsers', [ + 'foreignKey' => 'state_user_id', + 'joinType' => 'INNER' + ]); } /** @@ -77,6 +81,7 @@ class TransactionGroupAddaddressTable extends Table { $rules->add($rules->existsIn(['transaction_id'], 'Transactions')); $rules->add($rules->existsIn(['address_type_id'], 'AddressTypes')); + $rules->add($rules->existsIn(['state_user_id'], 'StateUsers')); return $rules; } diff --git a/src/Model/Transactions/Record.php b/src/Model/Transactions/Record.php index 7a93dab5b..339f4edd3 100644 --- a/src/Model/Transactions/Record.php +++ b/src/Model/Transactions/Record.php @@ -54,7 +54,55 @@ class Signature } -class ManageNodeGroupAdd + +class GradidoModifieUserBalance +{ + private $state_users = []; + + public function getUserId($userPublicKey) + { + $stateUsersTable = TableRegistry::getTableLocator()->get('StateUsers'); + $stateUser = $stateUsersTable->find('all')->where(['public_key' => hex2bin($userPublicKey)]); + if($stateUser->isEmpty()) { + return ['state' => 'error', 'msg' => 'couldn\'t find user via public key']; + } + $id = $stateUser->first()->id; + if($id && is_int($id) && (int)$id > 0 && !in_array((int)$id, $this->state_users)) { + array_push($this->state_users, (int)$id); + } + return $stateUser->first()->id; + } + + public function updateBalance($newBalance, $recordDate, $userId) + { + $stateBalancesTable = TableRegistry::getTableLocator()->get('StateBalances'); + $stateBalanceQuery = $stateBalancesTable->find('all')->where(['state_user_id' => $userId]); + $entity = null; + + if(!$stateBalanceQuery->isEmpty()) { + $entity = $stateBalanceQuery->first(); + if($entity->record_date != NULL && $entity->record_date > $recordDate) { + return false; + } + } else { + $entity = $stateBalancesTable->newEntity(); + $entity->state_user_id = $userId; + } + $entity->record_date = $recordDate; + $entity->amount = $newBalance; + if(!$stateBalancesTable->save($entity)) { + return ['state' => 'error', 'msg' => 'error saving state balance', 'details' => $entity->getErrors()]; + } + return true; + } + + public function getAllStateUsers() + { + return $this->state_users; + } +} + +class ManageNodeGroupAdd extends GradidoModifieUserBalance { /* "add_user": { @@ -100,11 +148,13 @@ class ManageNodeGroupAdd } $transactionGroupEntity->public_key = hex2bin($this->user_pubkey); + $transactionGroupEntity->state_user_id = $this->getUserId($this->user_pubkey); $transactionGroupEntity->remove_from_group = $this->remove_from_group; if(!$transactionGroupAddadressTable->save($transactionGroupEntity)) { return ['state' => 'error', 'msg' => 'error saving TransactionGroupAddaddress Entity', 'details' => $transactionGroupEntity->getErrors()]; } $userPubkeyBin = hex2bin($this->user_pubkey); + if($this->remove_from_group) { $stateGroup_query = $stateGroupAddresses->find('all')->where(['public_key' => hex2bin($this->user_pubkey)]); if(!$stateGroup_query->isEmpty()) { @@ -128,42 +178,6 @@ class ManageNodeGroupAdd } } -class GradidoModifieUserBalance -{ - - public function getUserId($userPublicKey) - { - $stateUsersTable = TableRegistry::getTableLocator()->get('StateUsers'); - $stateUser = $stateUsersTable->find('all')->where(['public_key' => hex2bin($userPublicKey)]); - if($stateUser->isEmpty()) { - return ['state' => 'error', 'msg' => 'couldn\'t find user via public key']; - } - return $stateUser->first()->id; - } - - public function updateBalance($newBalance, $recordDate, $userId) - { - $stateBalancesTable = TableRegistry::getTableLocator()->get('StateBalances'); - $stateBalanceQuery = $stateBalancesTable->find('all')->where(['state_user_id' => $userId]); - $entity = null; - - if(!$stateBalanceQuery->isEmpty()) { - $entity = $stateBalanceQuery->first(); - if($entity->record_date != NULL && $entity->record_date > $recordDate) { - return false; - } - } else { - $entity = $stateBalancesTable->newEntity(); - $entity->state_user_id = $userId; - } - $entity->record_date = $recordDate; - $entity->amount = $newBalance; - if(!$stateBalancesTable->save($entity)) { - return ['state' => 'error', 'msg' => 'error saving state balance', 'details' => $entity->getErrors()]; - } - return true; - } -} class GradidoCreation extends GradidoModifieUserBalance { @@ -180,6 +194,7 @@ class GradidoCreation extends GradidoModifieUserBalance private $targetDate; // seems currently not in node server implementet, use hedera date until it is implemented private $new_balance; + public function __construct($data) { $this->userPubkey = $data['user']; @@ -219,6 +234,8 @@ class GradidoCreation extends GradidoModifieUserBalance return true; } + + } class GradidoTransfer extends GradidoModifieUserBalance @@ -245,6 +262,7 @@ class GradidoTransfer extends GradidoModifieUserBalance private $receiver_pubkey; private $receiver_new_balance; + public function __construct($data) { $this->amount = $data['amount']; @@ -295,7 +313,7 @@ class GradidoTransfer extends GradidoModifieUserBalance } } if(is_int($receiver_id) && $receiver_id > 0) { - $transferEntity->receiver_user_id = $receiver_id; + $this->state_users[] = $receiver_id; $balance_result = $this->updateBalance($this->receiver_new_balance, $received, $receiver_id); if(is_array($balance_result)) { return $balance_result; @@ -308,6 +326,7 @@ class GradidoTransfer extends GradidoModifieUserBalance return true; } + } @@ -358,6 +377,7 @@ class Record { $transactionTypesTable = TableRegistry::getTableLocator()->get('TransactionTypes'); $transactionsTable = TableRegistry::getTableLocator()->get('Transactions'); + $stateUserTransactionsTable = TableRegistry::getTableLocator()->get('StateUserTransactions'); $transactionTypeName = $this->nodeTransactionTypeToDBTransactionType($this->transactionType); $transactionTypeResults = $transactionTypesTable->find('all')->where(['name' => $transactionTypeName]); @@ -409,6 +429,22 @@ class Record if($transaction_obj_result !== true) { return ['state' => 'error', 'msg' => 'error finalizing transaction object', 'details' => $transaction_obj_result]; } + $state_users = $this->transactionObj->getAllStateUsers(); + $sut_entities = []; + foreach($state_users as $state_user_id) { + $entity = $stateUserTransactionsTable->newEntity(); + $entity->state_user_id = $state_user_id; + $entity->transaction_id = $newTransaction->id; + $entity->transaction_type_id = $newTransaction->transaction_type_id; + $sut_entities[] = $entity; + } + $sut_results = $stateUserTransactionsTable->saveMany($sut_entities); + foreach($sut_results as $i => $result) { + if(false == $result) { + return ['state' => 'error', 'msg' => 'error saving state_user_transaction', 'details' => $sut_entities[$i]->getErrors()]; + } + } + return true; } diff --git a/webroot/css/grd_styles.css b/webroot/css/grd_styles.css index 08ecdc3a5..e745ea55e 100644 --- a/webroot/css/grd_styles.css +++ b/webroot/css/grd_styles.css @@ -1582,6 +1582,46 @@ To change this license header, choose License Headers in Project Properties. To change this template file, choose Tools | Templates and open the template in the editor. */ +/* + Created on : 23.11.2020, 14:04:28 + Author : einhornimmond +*/ +/* Style the tab */ +.tab { + overflow: hidden; + border: 1px solid #ccc; + background-color: #f1f1f1; +} +/* Style the buttons that are used to open the tab content */ +.tab button { + background-color: inherit; + float: left; + border: none; + outline: none; + cursor: pointer; + padding: 14px 16px; + transition: 0.3s; +} +/* Change background color of buttons on hover */ +.tab button:hover { + background-color: #ddd; +} +/* Create an active/current tablink class */ +.tab button.active { + background-color: #ccc; +} +/* Style the tab content */ +.tabcontent { + display: none; + padding: 6px 12px; + border: 1px solid #ccc; + border-top: none; +} +/* +To change this license header, choose License Headers in Project Properties. +To change this template file, choose Tools | Templates +and open the template in the editor. +*/ /* ============================================================ Screen styles for forms. diff --git a/webroot/js/tabs.js b/webroot/js/tabs.js new file mode 100644 index 000000000..2db9ab693 --- /dev/null +++ b/webroot/js/tabs.js @@ -0,0 +1,27 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + + +function openTab(evt, tabName) { + // Declare all variables + var i, tabcontent, tablinks; + + // Get all elements with class="tabcontent" and hide them + tabcontent = document.getElementsByClassName("tabcontent"); + for (i = 0; i < tabcontent.length; i++) { + tabcontent[i].style.display = "none"; + } + + // Get all elements with class="tablinks" and remove the class "active" + tablinks = document.getElementsByClassName("tablinks"); + for (i = 0; i < tablinks.length; i++) { + tablinks[i].className = tablinks[i].className.replace(" active", ""); + } + + // Show the current tab, and add an "active" class to the button that opened the tab + document.getElementById(tabName).style.display = "block"; + evt.currentTarget.className += " active"; +} \ No newline at end of file diff --git a/websrc/src/less/21-tabs.less b/websrc/src/less/21-tabs.less new file mode 100644 index 000000000..694dd1dab --- /dev/null +++ b/websrc/src/less/21-tabs.less @@ -0,0 +1,45 @@ +/* +To change this license header, choose License Headers in Project Properties. +To change this template file, choose Tools | Templates +and open the template in the editor. +*/ +/* + Created on : 23.11.2020, 14:04:28 + Author : einhornimmond +*/ + + /* Style the tab */ +.tab { + overflow: hidden; + border: 1px solid #ccc; + background-color: #f1f1f1; +} + +/* Style the buttons that are used to open the tab content */ +.tab button { + background-color: inherit; + float: left; + border: none; + outline: none; + cursor: pointer; + padding: 14px 16px; + transition: 0.3s; +} + +/* Change background color of buttons on hover */ +.tab button:hover { + background-color: #ddd; +} + +/* Create an active/current tablink class */ +.tab button.active { + background-color: #ccc; +} + +/* Style the tab content */ +.tabcontent { + display: none; + padding: 6px 12px; + border: 1px solid #ccc; + border-top: none; +} \ No newline at end of file