mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
Merge commit 'd87850db8c2ed6bdbb15aef4e6c51eb0b6054b19' into stage0_community_server
This commit is contained in:
commit
cc95d22989
@ -9,5 +9,9 @@ WORKDIR /var/www/cakephp
|
||||
RUN mkdir logs && mkdir tmp && chmod 777 logs && chmod 777 tmp
|
||||
COPY ./community_server/ .
|
||||
COPY ./configs/community_server/app.php ./config/
|
||||
RUN composer update
|
||||
|
||||
RUN composer update
|
||||
RUN composer dump-autoload
|
||||
|
||||
|
||||
|
||||
|
||||
@ -30,7 +30,9 @@
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"App\\": "src/",
|
||||
"" : "src/"
|
||||
"" : "src/",
|
||||
"GPBMetadata\\": "src/GPBMetadata",
|
||||
"Model\\Messages\\Gradido\\" : "src/Model/Messages/Gradido"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
|
||||
@ -193,6 +193,13 @@ Type::build('datetime')
|
||||
->useImmutable();
|
||||
Type::build('timestamp')
|
||||
->useImmutable();
|
||||
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
header('Access-Control-Allow-Methods: POST, GET, PUT, PATCH, DELETE, OPTIONS');
|
||||
header('Access-Control-Allow-Headers: *');
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Custom Inflector rules, can be set to correctly pluralize or singularize
|
||||
|
||||
@ -58,6 +58,7 @@ Router::scope('/', function (RouteBuilder $routes) {
|
||||
// Skip token check for API URLs.
|
||||
//die($request->getParam('controller'));
|
||||
$whitelist = ['JsonRequestHandler', 'ElopageWebhook'];
|
||||
$ajaxWhitelist = ['TransactionSendCoins', 'TransactionCreations'];
|
||||
|
||||
foreach($whitelist as $entry) {
|
||||
if($request->getParam('controller') === $entry) {
|
||||
@ -68,15 +69,29 @@ Router::scope('/', function (RouteBuilder $routes) {
|
||||
return true;
|
||||
}
|
||||
$allowedCaller = Configure::read('API.allowedCaller');
|
||||
$ipPerHost = [];
|
||||
if($allowedCaller && count($allowedCaller) > 0) {
|
||||
$callerIp = $request->clientIp();
|
||||
foreach($allowedCaller as $allowed) {
|
||||
$ip = gethostbyname($allowed);
|
||||
$ipPerHost[$allowed] = $ip;
|
||||
if($ip === $callerIp) return true;
|
||||
}
|
||||
//die("caller ip: $callerIp<br>");
|
||||
}
|
||||
//var_dump(['caller_ip' => $callerIp, 'ips' => $ipPerHost]);
|
||||
die(json_encode(['state' => 'error', 'details' => ['caller_ip' => $callerIp, 'ips' => $ipPerHost]]));
|
||||
}
|
||||
}
|
||||
// disable csfr for all ajax requests in ajax whitelisted controller
|
||||
foreach($ajaxWhitelist as $entry) {
|
||||
if($request->getParam('controller') === $entry) {
|
||||
$action = $request->getParam('action');
|
||||
if(preg_match('/^ajax/', $action)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Register scoped middleware for in scopes.
|
||||
|
||||
38
community_server/copy_to_www.sh
Executable file
38
community_server/copy_to_www.sh
Executable file
@ -0,0 +1,38 @@
|
||||
#!/bin/bash
|
||||
|
||||
[! -z "${FOLDER_NAME}"] && FOLDER_NAME=community_server
|
||||
|
||||
COLOR_GREEN="\033[0;32m"
|
||||
COLOR_YELLOW="\e[33m"
|
||||
COLOR_NONE="\033[0m"
|
||||
|
||||
SCRIPT=`realpath -s $0`
|
||||
SCRIPTPATH=`dirname $SCRIPT`
|
||||
#echo -e "script: $SCRIPT, Path: $SCRIPTPATH "
|
||||
|
||||
cd /var/www/html
|
||||
if [ ! -d "$FOLDER_NAME" ] ; then
|
||||
mkdir $FOLDER_NAME
|
||||
else
|
||||
chmod -R 0755 $FOLDER_NAME
|
||||
fi
|
||||
cd $FOLDER_NAME
|
||||
cp -r $SCRIPTPATH/src .
|
||||
cp -r $SCRIPTPATH/config .
|
||||
cp -r $SCRIPTPATH/composer.json .
|
||||
cp -r $SCRIPTPATH/webroot .
|
||||
composer install
|
||||
if [ ! -d "tmp" ] ; then
|
||||
mkdir tmp
|
||||
chown -R www-data:www-data ./tmp
|
||||
fi
|
||||
if [ ! -d "logs" ] ; then
|
||||
mkdir logs
|
||||
chown -R www-data:www-data ./logs
|
||||
fi
|
||||
|
||||
cd ..
|
||||
chown -R www-data:www-data $FOLDER_NAME
|
||||
chmod -R 0755 $FOLDER_NAME/src
|
||||
chmod -R 0755 $FOLDER_NAME/config
|
||||
chmod -R 0755 $FOLDER_NAME/webroot
|
||||
@ -2,6 +2,7 @@ CREATE TABLE `state_balances` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`state_user_id` int(10) unsigned NOT NULL,
|
||||
`modified` datetime NOT NULL,
|
||||
`record_date`datetime NULL,
|
||||
`amount` bigint(20) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
@ -0,0 +1,9 @@
|
||||
CREATE TABLE `state_user_transactions` (
|
||||
`id` int UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`state_user_id` int UNSIGNED NOT NULL,
|
||||
`transaction_id` int UNSIGNED NOT NULL,
|
||||
`transaction_type_id` int UNSIGNED NOT NULL,
|
||||
`balance` bigint(20) DEFAULT 0,
|
||||
`balance_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
@ -139,7 +139,7 @@ class AppController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
protected function requestLogin($session_id = 0)
|
||||
protected function requestLogin($session_id = 0, $redirect = true)
|
||||
{
|
||||
$session = $this->getRequest()->getSession();
|
||||
// check login
|
||||
@ -159,9 +159,9 @@ class AppController extends Controller
|
||||
if ($session_id != 0) {
|
||||
$userStored = $session->read('StateUser');
|
||||
|
||||
|
||||
$transactionPendings = $session->read('Transaction.pending');
|
||||
$transactionExecutings = $session->read('Transaction.executing');
|
||||
$transactionExecutings = $session->read('Transaction.executing');
|
||||
|
||||
if ($session->read('session_id') != $session_id ||
|
||||
( $userStored && (!isset($userStored['id']) || !$userStored['email_checked'])) ||
|
||||
intval($transactionPendings) > 0 ||
|
||||
@ -182,6 +182,8 @@ class AppController extends Controller
|
||||
$session->destroy();
|
||||
}
|
||||
foreach ($json['user'] as $key => $value) {
|
||||
// we don't need the id of user in login server db
|
||||
if($key == 'id') continue;
|
||||
$session->write('StateUser.' . $key, $value);
|
||||
}
|
||||
//var_dump($json);
|
||||
@ -238,12 +240,18 @@ class AppController extends Controller
|
||||
//echo $newStateUser->id;
|
||||
}
|
||||
} else {
|
||||
if(!$redirect) {
|
||||
return ['state' => 'error', 'msg' => 'no pubkey'];
|
||||
}
|
||||
// we haven't get a pubkey? something seems to gone wrong on the login-server
|
||||
$this->Flash->error(__('no pubkey'));
|
||||
//var_dump($json);
|
||||
return $this->redirect($this->loginServerUrl . 'account/error500/noPubkey', 303);
|
||||
}
|
||||
} else {
|
||||
if(!$redirect) {
|
||||
return ['state' => 'not found', 'msg' => 'invalid session'];
|
||||
}
|
||||
if ($json['state'] === 'not found') {
|
||||
$this->Flash->error(__('invalid session'));
|
||||
} else {
|
||||
@ -255,6 +263,9 @@ class AppController extends Controller
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$msg = $e->getMessage();
|
||||
if(!$redirect) {
|
||||
return ['state' => 'error', 'msg' => 'login-server http request error', 'details' => $msg];
|
||||
}
|
||||
$this->Flash->error(__('error http request: ') . $msg);
|
||||
return $this->redirect(['controller' => 'Dashboard', 'action' => 'errorHttpRequest']);
|
||||
//continue;
|
||||
@ -263,6 +274,9 @@ class AppController extends Controller
|
||||
} else {
|
||||
// no login
|
||||
//die("no login");
|
||||
if(!$redirect) {
|
||||
return ['state' => 'error', 'msg' => 'not logged in'];
|
||||
}
|
||||
if (isset($loginServer['path'])) {
|
||||
return $this->redirect($loginServer['path'], 303);
|
||||
} else {
|
||||
|
||||
@ -15,7 +15,7 @@ use Cake\Core\Configure;
|
||||
|
||||
class JsonRequestClientComponent extends Component
|
||||
{
|
||||
public function sendTransaction($session_id, $base64Message, $user_balance = 0) {
|
||||
public function sendTransaction($session_id, $base64Message, $user_balance = 0, $auto_sign = false) {
|
||||
if(!is_numeric($session_id)) {
|
||||
return ['state' => 'error', 'type' => 'parameter error', 'msg' => 'session_id isn\'t numeric'];
|
||||
}
|
||||
@ -35,7 +35,8 @@ class JsonRequestClientComponent extends Component
|
||||
return $this->sendRequest(json_encode([
|
||||
'session_id' => $session_id,
|
||||
'transaction_base64' => $base64Message,
|
||||
'balance' => $user_balance
|
||||
'balance' => $user_balance,
|
||||
'auto_sign' => $auto_sign
|
||||
]), '/checkTransaction');
|
||||
|
||||
}
|
||||
|
||||
@ -21,7 +21,7 @@ class StateBalancesController extends AppController
|
||||
{
|
||||
parent::initialize();
|
||||
//$this->Auth->allow(['add', 'edit']);
|
||||
$this->Auth->allow(['overview', 'overviewGdt', 'ajaxGetBalance']);
|
||||
$this->Auth->allow(['overview', 'overviewGdt', 'ajaxGetBalance', 'ajaxListTransactions']);
|
||||
$this->loadComponent('JsonRequestClient');
|
||||
}
|
||||
/**
|
||||
@ -39,7 +39,33 @@ class StateBalancesController extends AppController
|
||||
$this->set(compact('stateBalances'));
|
||||
}
|
||||
|
||||
|
||||
private function updateBalances($state_user_id)
|
||||
{
|
||||
$state_balances = $this->StateBalances->find('all')->where(['state_user_id' => $state_user_id]);
|
||||
if($state_balances->count() == 1) {
|
||||
$stateUserTransactionsTable = TableRegistry::getTableLocator()->get('StateUserTransactions');
|
||||
$state_user_transactions = $stateUserTransactionsTable
|
||||
->find('all')
|
||||
->where(['state_user_id' => $state_user_id])
|
||||
->order(['transaction_id ASC'])
|
||||
->contain(['']);
|
||||
if($state_user_transactions->count() == 0){
|
||||
return;
|
||||
}
|
||||
$last_state_user_transaction = $state_user_transactions->last();
|
||||
$last_transaction = $this->StateBalance->newEntity();
|
||||
$last_transaction->amount = $last_state_user_transaction->balance;
|
||||
$last_transaction->record_date = $last_state_user_transaction->balance_date;
|
||||
// if entrys are nearly the same, we don't need doing anything
|
||||
if(abs($last_transaction->decay - $state_balances->decay) < 100) {
|
||||
return;
|
||||
}
|
||||
foreach($state_user_transactions as $state_user_transaction) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public function overview()
|
||||
{
|
||||
@ -177,51 +203,73 @@ class StateBalancesController extends AppController
|
||||
$this->set('gdtSum', $gdtSum);
|
||||
}
|
||||
|
||||
public function ajaxGetBalance($session_id)
|
||||
public function ajaxGetBalance($session_id = 0)
|
||||
{
|
||||
if(!isset($session_id) || !$session_id) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'invalid session']);
|
||||
if(!$session_id) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'invalid session id']);
|
||||
}
|
||||
$login_result = $this->requestLogin($session_id, false);
|
||||
if($login_result !== true) {
|
||||
return $this->returnJson($login_result);
|
||||
}
|
||||
$startTime = microtime(true);
|
||||
$session = $this->getRequest()->getSession();
|
||||
$result = $this->requestLogin($session_id);
|
||||
if ($result !== true) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'session not found']);
|
||||
}
|
||||
$user = $session->read('StateUser');
|
||||
//var_dump($user);
|
||||
return $this->returnJson(['state' => 'success', 'balance' => $user['balance']]);
|
||||
|
||||
$public_key_bin = hex2bin($user['public_hex']);
|
||||
$stateUserQuery = $this->StateBalances->StateUsers
|
||||
->find('all')
|
||||
->where(['public_key' => $public_key_bin])
|
||||
->contain(['StateBalances']);
|
||||
|
||||
$result_user_count = $stateUserQuery->count();
|
||||
if($result_user_count < 1) {
|
||||
return $this->returnJson(['state' => 'success', 'balance' => 0]);
|
||||
}
|
||||
else if($result_user_count > 1) {
|
||||
return $this->returnJson([
|
||||
'state' => 'error',
|
||||
'msg' => 'multiple entrys found',
|
||||
'details' => ['public_key' => $user['public_hex'], 'entry_count' => $result_count]
|
||||
]);
|
||||
}
|
||||
$state_balances = $stateUserQuery->first()->state_balances;
|
||||
$state_balances_count = count($state_balances);
|
||||
if($state_balances_count > 1) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'state balances count isn\'t as expected, expect 1 or 0', 'details' => $state_balances_count]);
|
||||
}
|
||||
if(!$state_balances_count) {
|
||||
return $this->returnJson(['state' => 'success', 'balance' => 0]);
|
||||
}
|
||||
|
||||
return $this->returnJson(['state' => 'success', 'balance' => $state_balances[0]->amount]);
|
||||
}
|
||||
|
||||
public function ajaxListTransactions($session_id, $page, $count)
|
||||
public function ajaxListTransactions($session_id = 0, $sort = 'ASC')
|
||||
{
|
||||
if(!isset($session_id) || !$session_id) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'invalid session']);
|
||||
if(!$session_id) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'invalid session id']);
|
||||
}
|
||||
|
||||
$startTime = microtime(true);
|
||||
$session = $this->getRequest()->getSession();
|
||||
$result = $this->requestLogin($session_id);
|
||||
if ($result !== true) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'session not found']);
|
||||
$login_result = $this->requestLogin($session_id, false);
|
||||
if($login_result !== true) {
|
||||
return $this->returnJson($login_result);
|
||||
}
|
||||
$session = $this->getRequest()->getSession();
|
||||
$user = $session->read('StateUser');
|
||||
|
||||
$gdtSum = 0;
|
||||
|
||||
|
||||
$gdtSum = 0;
|
||||
$gdtEntries = $this->JsonRequestClient->sendRequestGDT(['email' => $user['email']], 'GdtEntries' . DS . 'sumPerEmailApi');
|
||||
|
||||
if('success' == $gdtEntries['state'] && 'success' == $gdtEntries['data']['state']) {
|
||||
$gdtSum = intval($gdtEntries['data']['sum']);
|
||||
} else {
|
||||
if($user) {
|
||||
|
||||
if($user) {
|
||||
$this->addAdminError('StateBalancesController', 'overview', $gdtEntries, $user['id']);
|
||||
} else {
|
||||
$this->addAdminError('StateBalancesController', 'overview', $gdtEntries, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$creationsTable = TableRegistry::getTableLocator()->get('TransactionCreations');
|
||||
$creationTransactions = $creationsTable
|
||||
@ -316,6 +364,9 @@ class StateBalancesController extends AppController
|
||||
]);
|
||||
}
|
||||
uasort($transactions, array($this, 'sortTransactions'));
|
||||
if($sort == 'DESC') {
|
||||
$transactions = array_reverse($transactions);
|
||||
}
|
||||
return $this->returnJson([
|
||||
'state' => 'success',
|
||||
'transactions' => $transactions,
|
||||
|
||||
@ -0,0 +1,290 @@
|
||||
<?php
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Controller\AppController;
|
||||
use Cake\ORM\TableRegistry;
|
||||
|
||||
/**
|
||||
* StateUserTransactions Controller
|
||||
*
|
||||
* @property \App\Model\Table\StateUserTransactionsTable $StateUserTransactions
|
||||
*
|
||||
* @method \App\Model\Entity\StateUserTransaction[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
|
||||
*/
|
||||
class StateUserTransactionsController extends AppController
|
||||
{
|
||||
public function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
//$this->Auth->allow(['add', 'edit']);
|
||||
$this->Auth->allow(['ajaxListTransactions']);
|
||||
//$this->loadComponent('JsonRequestClient');
|
||||
}
|
||||
/**
|
||||
* Index method
|
||||
*
|
||||
* @return \Cake\Http\Response|null
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->paginate = [
|
||||
'contain' => ['StateUsers', 'Transactions', 'TransactionTypes'],
|
||||
];
|
||||
$stateUserTransactions = $this->paginate($this->StateUserTransactions);
|
||||
|
||||
$this->set(compact('stateUserTransactions'));
|
||||
}
|
||||
|
||||
public function sortTransactions($a, $b)
|
||||
{
|
||||
if ($a['date'] == $b['date']) {
|
||||
return 0;
|
||||
}
|
||||
return ($a['date'] > $b['date']) ? -1 : 1;
|
||||
}
|
||||
|
||||
|
||||
public function ajaxListTransactions($page = 1, $count = 20)
|
||||
{
|
||||
$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?']);
|
||||
}
|
||||
|
||||
$paged_state_user_transactions = $this->StateUserTransactions
|
||||
->find('all')
|
||||
->where(['state_user_id' => $user['id'], 'transaction_type_id IN' => [1,2]])
|
||||
->limit($count)
|
||||
->page($page)
|
||||
->order(['transaction_id'])
|
||||
;
|
||||
$all_user_transactions_count = $this->StateUserTransactions
|
||||
->find('all')
|
||||
->where(['state_user_id' => $user['id'], 'transaction_type_id IN' => [1,2]])
|
||||
->count()
|
||||
;
|
||||
$creationTransaction_ids = [];
|
||||
$transferTransaction_ids = [];
|
||||
$allTransaction_ids = [];
|
||||
foreach($paged_state_user_transactions as $state_user_transaction) {
|
||||
$allTransaction_ids[] = $state_user_transaction->transaction_id;
|
||||
switch($state_user_transaction->transaction_type_id) {
|
||||
case 1: $creationTransaction_ids[] = $state_user_transaction->transaction_id; break;
|
||||
case 2: $transferTransaction_ids[] = $state_user_transaction->transaction_id; break;
|
||||
}
|
||||
}
|
||||
$transactionsTable = TableRegistry::getTableLocator()->get('Transactions');
|
||||
$transactionCreationsTable = TableRegistry::getTableLocator()->get('TransactionCreations');
|
||||
$transactionSendCoinsTable = TableRegistry::getTableLocator()->get('TransactionSendCoins');
|
||||
$stateUsersTable = TableRegistry::getTableLocator()->get('StateUsers');
|
||||
if(count($allTransaction_ids) > 0) {
|
||||
$transactionEntries = $transactionsTable->find('all')->where(['id IN' => $allTransaction_ids])->order(['id'])->toArray();
|
||||
}
|
||||
if(count($creationTransaction_ids) > 0) {
|
||||
$transactionCreations = $transactionCreationsTable->find('all')->where(['transaction_id IN' => $creationTransaction_ids]);
|
||||
}
|
||||
if(count($transferTransaction_ids)) {
|
||||
$transactionTransfers = $transactionSendCoinsTable->find('all')->where(['transaction_id IN' => $transferTransaction_ids]);
|
||||
}
|
||||
//var_dump($transactions->all());
|
||||
|
||||
$transactions = [];
|
||||
// creations
|
||||
if(isset($transactionCreations)) {
|
||||
foreach ($transactionCreations as $creation) {
|
||||
//var_dump($creation);
|
||||
$transaction_entries_index = array_search($creation->transaction_id, $allTransaction_ids);
|
||||
if(FALSE === $transaction_entries_index) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'code error', 'details' => 'creation, transaction_entries_index is FALSE, shouldn\'t occure']);
|
||||
}
|
||||
$transaction = $transactionEntries[$transaction_entries_index];
|
||||
array_push($transactions, [
|
||||
'name' => 'Gradido Akademie',
|
||||
'type' => 'creation',
|
||||
'transaction_id' => $creation->transaction_id,
|
||||
'date' => $transaction->received,
|
||||
'balance' => $creation->amount,
|
||||
'memo' => $transaction->memo
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// involved users
|
||||
if(isset($transactionTransfers)) {
|
||||
$involvedUserIds = [];
|
||||
|
||||
foreach ($transactionTransfers as $transfer) {
|
||||
//var_dump($sendCoins);
|
||||
if ($transfer->state_user_id != $user['id']) {
|
||||
array_push($involvedUserIds, intval($transfer->state_user_id));
|
||||
} elseif ($transfer->receiver_user_id != $user['id']) {
|
||||
array_push($involvedUserIds, intval($transfer->receiver_user_id));
|
||||
}
|
||||
}
|
||||
|
||||
// exchange key with values and drop duplicates
|
||||
$involvedUser_temp = array_flip($involvedUserIds);
|
||||
// exchange back
|
||||
$involvedUserIds = array_flip($involvedUser_temp);
|
||||
|
||||
$involvedUser = $stateUsersTable->find('all', [
|
||||
'contain' => false,
|
||||
'where' => ['id IN' => $involvedUserIds],
|
||||
'fields' => ['id', 'first_name', 'last_name', 'email']
|
||||
]);
|
||||
//var_dump($involvedUser->toArray());
|
||||
$involvedUserIndices = [];
|
||||
foreach ($involvedUser as $involvedUser) {
|
||||
$involvedUserIndices[$involvedUser->id] = $involvedUser;
|
||||
}
|
||||
|
||||
// transfers - send coins
|
||||
foreach($transactionTransfers as $transfer)
|
||||
{
|
||||
$transaction_entries_index = array_search($transfer->transaction_id, $allTransaction_ids);
|
||||
if(FALSE === $transaction_entries_index) {
|
||||
|
||||
return $this->returnJson([
|
||||
'state' => 'error',
|
||||
'msg' => 'code error',
|
||||
'details' => 'transfer, transaction_entries_index is FALSE, shouldn\'t occure',
|
||||
'data' => ['haystack' => $allTransaction_ids, 'needle' => $transfer->transaction_id]
|
||||
]);
|
||||
}
|
||||
$transaction = $transactionEntries[$transaction_entries_index];
|
||||
$type = '';
|
||||
$otherUser = null;
|
||||
$other_user_public = '';
|
||||
|
||||
if ($transfer->state_user_id == $user['id']) {
|
||||
$type = 'send';
|
||||
|
||||
if(isset($involvedUserIndices[$transfer->receiver_user_id])) {
|
||||
$otherUser = $involvedUserIndices[$transfer->receiver_user_id];
|
||||
}
|
||||
$other_user_public = bin2hex(stream_get_contents($transfer->receiver_public_key));
|
||||
} else if ($transfer->receiver_user_id == $user['id']) {
|
||||
$type = 'receive';
|
||||
if(isset($involvedUserIndices[$transfer->state_user_id])) {
|
||||
$otherUser = $involvedUserIndices[$transfer->state_user_id];
|
||||
}
|
||||
if($transfer->sender_public_key) {
|
||||
$other_user_public = bin2hex(stream_get_contents($transfer->sender_public_key));
|
||||
}
|
||||
}
|
||||
if(null == $otherUser) {
|
||||
$otherUser = $stateUsersTable->newEntity();
|
||||
}
|
||||
array_push($transactions, [
|
||||
'name' => $otherUser->first_name . ' ' . $otherUser->last_name,
|
||||
'email' => $otherUser->email,
|
||||
'type' => $type,
|
||||
'transaction_id' => $transfer->transaction_id,
|
||||
'date' => $transaction->received,
|
||||
'balance' => $transfer->amount,
|
||||
'memo' => $transaction->memo,
|
||||
'pubkey' => $other_user_public
|
||||
]);
|
||||
//*/
|
||||
|
||||
}
|
||||
}
|
||||
uasort($transactions, array($this, 'sortTransactions'));
|
||||
|
||||
return $this->returnJson([
|
||||
'state' => 'success',
|
||||
'transactions' => $transactions,
|
||||
'transactionExecutingCount' => $session->read('Transaction.executing'),
|
||||
'count' => $all_user_transactions_count,
|
||||
'timeUsed' => microtime(true) - $startTime
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* View method
|
||||
*
|
||||
* @param string|null $id State User Transaction id.
|
||||
* @return \Cake\Http\Response|null
|
||||
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
|
||||
*/
|
||||
public function view($id = null)
|
||||
{
|
||||
$stateUserTransaction = $this->StateUserTransactions->get($id, [
|
||||
'contain' => ['StateUsers', 'Transactions', 'TransactionTypes'],
|
||||
]);
|
||||
|
||||
$this->set('stateUserTransaction', $stateUserTransaction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add method
|
||||
*
|
||||
* @return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$stateUserTransaction = $this->StateUserTransactions->newEntity();
|
||||
if ($this->request->is('post')) {
|
||||
$stateUserTransaction = $this->StateUserTransactions->patchEntity($stateUserTransaction, $this->request->getData());
|
||||
if ($this->StateUserTransactions->save($stateUserTransaction)) {
|
||||
$this->Flash->success(__('The state user transaction has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The state user transaction could not be saved. Please, try again.'));
|
||||
}
|
||||
$stateUsers = $this->StateUserTransactions->StateUsers->find('list', ['limit' => 200]);
|
||||
$transactions = $this->StateUserTransactions->Transactions->find('list', ['limit' => 200]);
|
||||
$transactionTypes = $this->StateUserTransactions->TransactionTypes->find('list', ['limit' => 200]);
|
||||
$this->set(compact('stateUserTransaction', 'stateUsers', 'transactions', 'transactionTypes'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit method
|
||||
*
|
||||
* @param string|null $id State User Transaction 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)
|
||||
{
|
||||
$stateUserTransaction = $this->StateUserTransactions->get($id, [
|
||||
'contain' => [],
|
||||
]);
|
||||
if ($this->request->is(['patch', 'post', 'put'])) {
|
||||
$stateUserTransaction = $this->StateUserTransactions->patchEntity($stateUserTransaction, $this->request->getData());
|
||||
if ($this->StateUserTransactions->save($stateUserTransaction)) {
|
||||
$this->Flash->success(__('The state user transaction has been saved.'));
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
$this->Flash->error(__('The state user transaction could not be saved. Please, try again.'));
|
||||
}
|
||||
$stateUsers = $this->StateUserTransactions->StateUsers->find('list', ['limit' => 200]);
|
||||
$transactions = $this->StateUserTransactions->Transactions->find('list', ['limit' => 200]);
|
||||
$transactionTypes = $this->StateUserTransactions->TransactionTypes->find('list', ['limit' => 200]);
|
||||
$this->set(compact('stateUserTransaction', 'stateUsers', 'transactions', 'transactionTypes'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete method
|
||||
*
|
||||
* @param string|null $id State User Transaction 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']);
|
||||
$stateUserTransaction = $this->StateUserTransactions->get($id);
|
||||
if ($this->StateUserTransactions->delete($stateUserTransaction)) {
|
||||
$this->Flash->success(__('The state user transaction has been deleted.'));
|
||||
} else {
|
||||
$this->Flash->error(__('The state user transaction could not be deleted. Please, try again.'));
|
||||
}
|
||||
|
||||
return $this->redirect(['action' => 'index']);
|
||||
}
|
||||
}
|
||||
@ -35,6 +35,7 @@ class TransactionCreationsController extends AppController
|
||||
$this->loadComponent('JsonRequestClient');
|
||||
//$this->Auth->allow(['add', 'edit']);
|
||||
//$this->Auth->allow('create');
|
||||
$this->Auth->allow('ajaxCreate');
|
||||
$this->set(
|
||||
'naviHierarchy',
|
||||
(new NaviHierarchy())->
|
||||
@ -446,6 +447,121 @@ class TransactionCreationsController extends AppController
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@ -37,6 +37,7 @@ class TransactionSendCoinsController extends AppController
|
||||
//$this->Auth->allow(['add', 'edit']);
|
||||
$this->Auth->allow('create');
|
||||
$this->Auth->allow('createRaw');
|
||||
$this->Auth->allow('ajaxCreate');
|
||||
$this->set(
|
||||
'naviHierarchy',
|
||||
(new NaviHierarchy())->
|
||||
@ -288,6 +289,143 @@ class TransactionSendCoinsController extends AppController
|
||||
|
||||
$this->set('timeUsed', microtime(true) - $startTime);
|
||||
}
|
||||
|
||||
public function ajaxCreate()
|
||||
{
|
||||
if ($this->request->is('post')) {
|
||||
$startTime = microtime(true);
|
||||
$jsonData = $this->request->input('json_decode', true);
|
||||
$session_id = $jsonData['session_id'];
|
||||
if(!$session_id) {
|
||||
return $this->returnJson(['state' => 'error', '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');
|
||||
|
||||
$receiverPubKeyHex = '';
|
||||
$senderPubKeyHex = $user['public_hex'];
|
||||
|
||||
if(!isset($jsonData['amount']) || !isset($jsonData['email'])) {
|
||||
return $this->returnJson(['state' => 'parameter missing', 'msg' => 'amount and/or email not set']);
|
||||
}
|
||||
$amount = intval($jsonData['amount']);
|
||||
if($amount < 0) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'amout must be > 0 and int']);
|
||||
}
|
||||
|
||||
if(!isset($user['balance']) || $jsonData['amount'] > $user['balance']) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'not enough GDD']);
|
||||
}
|
||||
$memo = '';
|
||||
if(isset($jsonData['memo'])) {
|
||||
$memo = $jsonData['memo'];
|
||||
}
|
||||
|
||||
$receiverEmail = $jsonData['email'];
|
||||
if($receiverEmail === $user['email']) {
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'sender and receiver email are the same']);
|
||||
}
|
||||
|
||||
$requestAnswear = $this->JsonRequestClient->sendRequest(json_encode([
|
||||
'session_id' => $session_id,
|
||||
'email' => $receiverEmail,
|
||||
'ask' => ['user.pubkeyhex', 'user.disabled']
|
||||
]), '/getUserInfos');
|
||||
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 payments',
|
||||
'timeUsed' => microtime(true) - $startTime
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
//var_dump($sessionStateUser);
|
||||
|
||||
$builderResult = TransactionTransfer::build(
|
||||
$amount,
|
||||
$memo,
|
||||
$receiverPubKeyHex,
|
||||
$senderPubKeyHex
|
||||
);
|
||||
$auto_sign = true;
|
||||
if(isset($jsonData['auto_sign'])) {
|
||||
$auto_sign = $jsonData['auto_sign'];
|
||||
}
|
||||
if($builderResult['state'] === 'success') {
|
||||
|
||||
$http = new Client();
|
||||
try {
|
||||
$loginServer = Configure::read('LoginServer');
|
||||
$url = $loginServer['host'] . ':' . $loginServer['port'];
|
||||
|
||||
$response = $http->post($url . '/checkTransaction', json_encode([
|
||||
'session_id' => $session_id,
|
||||
'transaction_base64' => base64_encode($builderResult['transactionBody']->serializeToString()),
|
||||
'auto_sign' => $auto_sign,
|
||||
'balance' => $user['balance']
|
||||
]), ['type' => 'json']);
|
||||
$json = $response->getJson();
|
||||
if($json['state'] != 'success') {
|
||||
if($json['msg'] == 'session not found') {
|
||||
$session->destroy();
|
||||
return $this->returnJson([
|
||||
'state' => 'error',
|
||||
'msg' => 'session not found',
|
||||
'details' => $session_id,
|
||||
'timeUsed' => microtime(true) - $startTime
|
||||
]);
|
||||
//$this->Flash->error(__('session not found, please login again'));
|
||||
} else {
|
||||
return $this->returnJson([
|
||||
'state' => 'error',
|
||||
'msg' => 'login server return error',
|
||||
'details' => $json,
|
||||
'timeUsed' => microtime(true) - $startTime
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
return $this->returnJson(['state' => 'success', 'timeUsed' => microtime(true) - $startTime]);
|
||||
}
|
||||
|
||||
} catch(\Exception $e) {
|
||||
$msg = $e->getMessage();
|
||||
//$this->Flash->error(__('error http request: ') . $msg);
|
||||
return $this->returnJson([
|
||||
'state' => 'error',
|
||||
'msg' => 'error http request',
|
||||
'details' => $msg,
|
||||
'timeUsed' => microtime(true) - $startTime
|
||||
]);
|
||||
}
|
||||
|
||||
} else {
|
||||
return $this->returnJson([
|
||||
'state' => 'error',
|
||||
'msg' => 'no valid receiver public key given',
|
||||
'details' => $receiverPubKeyHex,
|
||||
'timeUsed' => microtime(true) - $startTime
|
||||
]);
|
||||
}
|
||||
}
|
||||
return $this->returnJson(['state' => 'error', 'msg' => 'no post request']);
|
||||
}
|
||||
|
||||
public function createRaw()
|
||||
{
|
||||
|
||||
@ -7,6 +7,7 @@ use Model\Transactions\Transaction;
|
||||
use Model\Transactions\TransactionBody;
|
||||
|
||||
use Cake\Core\Configure;
|
||||
use Cake\ORM\TableRegistry;
|
||||
|
||||
/**
|
||||
* Transactions Controller
|
||||
@ -40,6 +41,118 @@ class TransactionsController extends AppController
|
||||
|
||||
$this->set(compact('transactions'));
|
||||
}
|
||||
|
||||
public function synchronizeWithStateUserTransactions()
|
||||
{
|
||||
$startTime = microtime(true);
|
||||
$missing_transaction_ids = [];
|
||||
$transaction_ids = $this->Transactions
|
||||
->find('all')
|
||||
->select(['id', 'transaction_type_id'])
|
||||
->order(['id'])
|
||||
->all()
|
||||
;
|
||||
$state_user_transaction_ids = $this->Transactions->StateUserTransactions
|
||||
->find('all')
|
||||
->select(['transaction_id'])
|
||||
->group(['transaction_id'])
|
||||
->order(['transaction_id'])
|
||||
->toArray()
|
||||
;
|
||||
$i2 = 0;
|
||||
$count1 = count($transaction_ids);
|
||||
$count2 = count($state_user_transaction_ids);
|
||||
foreach($transaction_ids as $i1 => $tr_id) {
|
||||
//echo "$i1: ";
|
||||
if($i2 >= $count2) {
|
||||
$missing_transaction_ids[] = $tr_id;
|
||||
//echo "adding to missing: $tr_id, continue <br>";
|
||||
continue;
|
||||
}
|
||||
$stu_id = $state_user_transaction_ids[$i2];
|
||||
if($tr_id->id == $stu_id->transaction_id) {
|
||||
$i2++;
|
||||
//echo "after i2++: $i2<br>";
|
||||
} else if($tr_id->id < $stu_id->transaction_id) {
|
||||
$missing_transaction_ids[] = $tr_id;
|
||||
//echo "adding to missing: $tr_id<br>";
|
||||
}
|
||||
}
|
||||
|
||||
if($this->request->is('POST')) {
|
||||
$tablesForType = [
|
||||
1 => $this->Transactions->TransactionCreations,
|
||||
2 => $this->Transactions->TransactionSendCoins,
|
||||
3 => $this->Transactions->TransactionGroupCreates,
|
||||
4 => $this->Transactions->TransactionGroupAddaddress,
|
||||
5 => $this->Transactions->TransactionGroupAddaddress
|
||||
];
|
||||
$idsForType = [];
|
||||
foreach($missing_transaction_ids as $i => $transaction) {
|
||||
if(!isset($idsForType[$transaction->transaction_type_id])) {
|
||||
$idsForType[$transaction->transaction_type_id] = [];
|
||||
}
|
||||
$idsForType[$transaction->transaction_type_id][] = $transaction->id;
|
||||
if($i > 200) break;
|
||||
}
|
||||
$entities = [];
|
||||
$state_user_ids = [];
|
||||
foreach($idsForType as $type_id => $transaction_ids) {
|
||||
$specific_transactions = $tablesForType[$type_id]->find('all')->where(['transaction_id IN' => $transaction_ids])->toArray();
|
||||
$keys = $tablesForType[$type_id]->getSchema()->columns();
|
||||
//var_dump($keys);
|
||||
foreach($specific_transactions as $specific) {
|
||||
|
||||
foreach($keys as $key) {
|
||||
if(preg_match('/_user_id/', $key)) {
|
||||
$entity = $this->Transactions->StateUserTransactions->newEntity();
|
||||
$entity->transaction_id = $specific['transaction_id'];
|
||||
$entity->transaction_type_id = $type_id;
|
||||
$entity->state_user_id = $specific[$key];
|
||||
if(!in_array($entity->state_user_id, $state_user_ids)) {
|
||||
array_push($state_user_ids, $entity->state_user_id);
|
||||
}
|
||||
$entities[] = $entity;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//var_dump($entities);
|
||||
$stateUsersTable = TableRegistry::getTableLocator()->get('StateUsers');
|
||||
$existingStateUsers = $stateUsersTable->find('all')->select(['id'])->where(['id IN' => $state_user_ids])->order(['id'])->all();
|
||||
$existing_state_user_ids = [];
|
||||
$finalEntities = [];
|
||||
foreach($existingStateUsers as $stateUser) {
|
||||
$existing_state_user_ids[] = $stateUser->id;
|
||||
}
|
||||
foreach($entities as $entity) {
|
||||
if(in_array($entity->state_user_id, $existing_state_user_ids)) {
|
||||
array_push($finalEntities, $entity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$results = $this->Transactions->StateUserTransactions->saveMany($finalEntities);
|
||||
foreach($entities as $i => $entity) {
|
||||
$errors = $entity->getErrors();
|
||||
/* if(count($errors)) {
|
||||
echo "$i: ";
|
||||
echo json_encode($errors);
|
||||
echo "<br>";
|
||||
echo "state_user_id: " . $entity->state_user_id;
|
||||
echo "<br>";
|
||||
}*/
|
||||
}
|
||||
$this->set('results', $results);
|
||||
$this->set('entities', $entities);
|
||||
}
|
||||
|
||||
$this->set('missing_transactions', $missing_transaction_ids);
|
||||
$this->set('count1', $count1);
|
||||
$this->set('count2', $count2);
|
||||
$timeUsed = microtime(true) - $startTime;
|
||||
$this->set('timeUsed', $timeUsed);
|
||||
}
|
||||
|
||||
/**
|
||||
* View method
|
||||
|
||||
@ -15,14 +15,15 @@ class BasicTypes
|
||||
return;
|
||||
}
|
||||
$pool->internalAddGeneratedFile(hex2bin(
|
||||
"0ae0030a10426173696354797065732e70726f746f12076772616469646f" .
|
||||
"22380a034b657912110a076564323535313918022001280c480012170a0d" .
|
||||
"656432353531395f726566313018032001280c480042050a036b65792258" .
|
||||
"0a0d5369676e617475726550616972120e0a067075624b65791801200128" .
|
||||
"0c12110a076564323535313918022001280c480012170a0d656432353531" .
|
||||
"395f726566313018032001280c4800420b0a097369676e61747572652237" .
|
||||
"0a0c5369676e61747572654d617012270a07736967506169721801200328" .
|
||||
"0b32162e6772616469646f2e5369676e617475726550616972222b0a0954" .
|
||||
"0afe030a10426173696354797065732e70726f746f12166d6f64656c2e6d" .
|
||||
"657373616765732e6772616469646f22380a034b657912110a0765643235" .
|
||||
"35313918022001280c480012170a0d656432353531395f72656631301803" .
|
||||
"2001280c480042050a036b657922580a0d5369676e617475726550616972" .
|
||||
"120e0a067075624b657918012001280c12110a0765643235353139180220" .
|
||||
"01280c480012170a0d656432353531395f726566313018032001280c4800" .
|
||||
"420b0a097369676e617475726522460a0c5369676e61747572654d617012" .
|
||||
"360a077369675061697218012003280b32252e6d6f64656c2e6d65737361" .
|
||||
"6765732e6772616469646f2e5369676e617475726550616972222b0a0954" .
|
||||
"696d657374616d70120f0a077365636f6e6473180120012803120d0a056e" .
|
||||
"616e6f7318022001280522230a1054696d657374616d705365636f6e6473" .
|
||||
"120f0a077365636f6e647318012001280322590a0c53656e646572416d6f" .
|
||||
32
community_server/src/GPBMetadata/StateCreateGroup.php
Normal file
32
community_server/src/GPBMetadata/StateCreateGroup.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: StateCreateGroup.proto
|
||||
|
||||
namespace GPBMetadata;
|
||||
|
||||
class StateCreateGroup
|
||||
{
|
||||
public static $is_initialized = false;
|
||||
|
||||
public static function initOnce() {
|
||||
$pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
|
||||
|
||||
if (static::$is_initialized == true) {
|
||||
return;
|
||||
}
|
||||
\GPBMetadata\BasicTypes::initOnce();
|
||||
$pool->internalAddGeneratedFile(hex2bin(
|
||||
"0ae4010a16537461746543726561746547726f75702e70726f746f12166d" .
|
||||
"6f64656c2e6d657373616765732e6772616469646f22a9010a1053746174" .
|
||||
"6543726561746547726f7570120c0a046e616d6518012001280912330a0e" .
|
||||
"67726f75705075626c69634b657918022001280b321b2e6d6f64656c2e6d" .
|
||||
"657373616765732e6772616469646f2e4b657912390a14706172656e7447" .
|
||||
"726f75705075626c69634b657918032001280b321b2e6d6f64656c2e6d65" .
|
||||
"7373616765732e6772616469646f2e4b65794a0408041005521168656465" .
|
||||
"7261436f6e73656e7375734964620670726f746f33"
|
||||
), true);
|
||||
|
||||
static::$is_initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
33
community_server/src/GPBMetadata/StateGroupChangeParent.php
Normal file
33
community_server/src/GPBMetadata/StateGroupChangeParent.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: StateGroupChangeParent.proto
|
||||
|
||||
namespace GPBMetadata;
|
||||
|
||||
class StateGroupChangeParent
|
||||
{
|
||||
public static $is_initialized = false;
|
||||
|
||||
public static function initOnce() {
|
||||
$pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
|
||||
|
||||
if (static::$is_initialized == true) {
|
||||
return;
|
||||
}
|
||||
\GPBMetadata\BasicTypes::initOnce();
|
||||
$pool->internalAddGeneratedFile(hex2bin(
|
||||
"0a8a020a1c537461746547726f75704368616e6765506172656e742e7072" .
|
||||
"6f746f12166d6f64656c2e6d657373616765732e6772616469646f22c901" .
|
||||
"0a16537461746547726f75704368616e6765506172656e7412330a0e6772" .
|
||||
"6f75705075626c69634b657918012001280b321b2e6d6f64656c2e6d6573" .
|
||||
"73616765732e6772616469646f2e4b6579123c0a176e6577506172656e74" .
|
||||
"47726f75705075626c69634b657918022001280b321b2e6d6f64656c2e6d" .
|
||||
"657373616765732e6772616469646f2e4b6579123c0a176f6c6450617265" .
|
||||
"6e7447726f75705075626c69634b657918032001280b321b2e6d6f64656c" .
|
||||
"2e6d657373616765732e6772616469646f2e4b6579620670726f746f33"
|
||||
), true);
|
||||
|
||||
static::$is_initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
32
community_server/src/GPBMetadata/Transaction.php
Normal file
32
community_server/src/GPBMetadata/Transaction.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: Transaction.proto
|
||||
|
||||
namespace GPBMetadata;
|
||||
|
||||
class Transaction
|
||||
{
|
||||
public static $is_initialized = false;
|
||||
|
||||
public static function initOnce() {
|
||||
$pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
|
||||
|
||||
if (static::$is_initialized == true) {
|
||||
return;
|
||||
}
|
||||
\GPBMetadata\BasicTypes::initOnce();
|
||||
$pool->internalAddGeneratedFile(hex2bin(
|
||||
"0ae4010a115472616e73616374696f6e2e70726f746f12166d6f64656c2e" .
|
||||
"6d657373616765732e6772616469646f22ae010a0b5472616e7361637469" .
|
||||
"6f6e120a0a026964180120012804123a0a08726563656976656418022001" .
|
||||
"280b32282e6d6f64656c2e6d657373616765732e6772616469646f2e5469" .
|
||||
"6d657374616d705365636f6e647312340a067369674d617018032001280b" .
|
||||
"32242e6d6f64656c2e6d657373616765732e6772616469646f2e5369676e" .
|
||||
"61747572654d6170120e0a0674784861736818042001280c12110a09626f" .
|
||||
"6479427974657318052001280c620670726f746f33"
|
||||
), true);
|
||||
|
||||
static::$is_initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
46
community_server/src/GPBMetadata/TransactionBody.php
Normal file
46
community_server/src/GPBMetadata/TransactionBody.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: TransactionBody.proto
|
||||
|
||||
namespace GPBMetadata;
|
||||
|
||||
class TransactionBody
|
||||
{
|
||||
public static $is_initialized = false;
|
||||
|
||||
public static function initOnce() {
|
||||
$pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
|
||||
|
||||
if (static::$is_initialized == true) {
|
||||
return;
|
||||
}
|
||||
\GPBMetadata\Transfer::initOnce();
|
||||
\GPBMetadata\StateCreateGroup::initOnce();
|
||||
\GPBMetadata\StateGroupChangeParent::initOnce();
|
||||
\GPBMetadata\TransactionCreation::initOnce();
|
||||
\GPBMetadata\BasicTypes::initOnce();
|
||||
$pool->internalAddGeneratedFile(hex2bin(
|
||||
"0a84040a155472616e73616374696f6e426f64792e70726f746f12166d6f" .
|
||||
"64656c2e6d657373616765732e6772616469646f1a165374617465437265" .
|
||||
"61746547726f75702e70726f746f1a1c537461746547726f75704368616e" .
|
||||
"6765506172656e742e70726f746f1a195472616e73616374696f6e437265" .
|
||||
"6174696f6e2e70726f746f1a10426173696354797065732e70726f746f22" .
|
||||
"e7020a0f5472616e73616374696f6e426f6479120c0a046d656d6f180120" .
|
||||
"01280912390a076372656174656418022001280b32282e6d6f64656c2e6d" .
|
||||
"657373616765732e6772616469646f2e54696d657374616d705365636f6e" .
|
||||
"6473123f0a0b63726561746547726f757018062001280b32282e6d6f6465" .
|
||||
"6c2e6d657373616765732e6772616469646f2e5374617465437265617465" .
|
||||
"47726f75704800124b0a1167726f75704368616e6765506172656e741807" .
|
||||
"2001280b322e2e6d6f64656c2e6d657373616765732e6772616469646f2e" .
|
||||
"537461746547726f75704368616e6765506172656e74480012340a087472" .
|
||||
"616e7366657218082001280b32202e6d6f64656c2e6d657373616765732e" .
|
||||
"6772616469646f2e5472616e736665724800123f0a086372656174696f6e" .
|
||||
"18092001280b322b2e6d6f64656c2e6d657373616765732e677261646964" .
|
||||
"6f2e5472616e73616374696f6e4372656174696f6e480042060a04646174" .
|
||||
"61620670726f746f33"
|
||||
), true);
|
||||
|
||||
static::$is_initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
32
community_server/src/GPBMetadata/TransactionCreation.php
Normal file
32
community_server/src/GPBMetadata/TransactionCreation.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: TransactionCreation.proto
|
||||
|
||||
namespace GPBMetadata;
|
||||
|
||||
class TransactionCreation
|
||||
{
|
||||
public static $is_initialized = false;
|
||||
|
||||
public static function initOnce() {
|
||||
$pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
|
||||
|
||||
if (static::$is_initialized == true) {
|
||||
return;
|
||||
}
|
||||
\GPBMetadata\BasicTypes::initOnce();
|
||||
$pool->internalAddGeneratedFile(hex2bin(
|
||||
"0ae6010a195472616e73616374696f6e4372656174696f6e2e70726f746f" .
|
||||
"12166d6f64656c2e6d657373616765732e6772616469646f22a8010a1354" .
|
||||
"72616e73616374696f6e4372656174696f6e123e0a0e7265636569766572" .
|
||||
"416d6f756e7418012001280b32262e6d6f64656c2e6d657373616765732e" .
|
||||
"6772616469646f2e5265636569766572416d6f756e7412120a0a6964656e" .
|
||||
"745f68617368180220012811123d0a0b7461726765745f64617465180320" .
|
||||
"01280b32282e6d6f64656c2e6d657373616765732e6772616469646f2e54" .
|
||||
"696d657374616d705365636f6e6473620670726f746f33"
|
||||
), true);
|
||||
|
||||
static::$is_initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,11 +16,13 @@ class Transfer
|
||||
}
|
||||
\GPBMetadata\BasicTypes::initOnce();
|
||||
$pool->internalAddGeneratedFile(hex2bin(
|
||||
"0a8d010a0e5472616e736665722e70726f746f12076772616469646f226a" .
|
||||
"0a085472616e73666572122c0a0d73656e646572416d6f756e7473180120" .
|
||||
"03280b32152e6772616469646f2e53656e646572416d6f756e7412300a0f" .
|
||||
"7265636569766572416d6f756e747318022003280b32172e677261646964" .
|
||||
"6f2e5265636569766572416d6f756e74620670726f746f33"
|
||||
"0abb010a0e5472616e736665722e70726f746f12166d6f64656c2e6d6573" .
|
||||
"73616765732e6772616469646f2288010a085472616e73666572123b0a0d" .
|
||||
"73656e646572416d6f756e747318012003280b32242e6d6f64656c2e6d65" .
|
||||
"7373616765732e6772616469646f2e53656e646572416d6f756e74123f0a" .
|
||||
"0f7265636569766572416d6f756e747318022003280b32262e6d6f64656c" .
|
||||
"2e6d657373616765732e6772616469646f2e5265636569766572416d6f75" .
|
||||
"6e74620670726f746f33"
|
||||
), true);
|
||||
|
||||
static::$is_initialized = true;
|
||||
@ -2,6 +2,7 @@
|
||||
namespace App\Model\Entity;
|
||||
|
||||
use Cake\ORM\Entity;
|
||||
use Cake\I18n\Time;
|
||||
|
||||
/**
|
||||
* StateBalance Entity
|
||||
@ -28,6 +29,39 @@ class StateBalance extends Entity
|
||||
'state_user_id' => true,
|
||||
'modified' => true,
|
||||
'amount' => true,
|
||||
'record_date' => true,
|
||||
'state_user' => true
|
||||
];
|
||||
|
||||
protected $_virtual = ['decay'];
|
||||
|
||||
protected function _getDecay()
|
||||
{
|
||||
// decay factor in seconds per year
|
||||
// q = e^((lg Kn - lg K0) / n)
|
||||
// 0.999999978
|
||||
//
|
||||
// SELECT TIMESTAMPDIFF(SECOND, modified, CURDATE()) AS age_in_seconds from state_balances
|
||||
// decay_for_duration = decay_factor^seconds
|
||||
// decay = gradido_cent * decay_for_duration
|
||||
$decay_duration = intval(Time::now()->getTimestamp() - $this->record_date->getTimestamp());
|
||||
if($decay_duration === 0) {
|
||||
return $this->amount;
|
||||
}
|
||||
return $this->amount * pow(0.99999997802044727, $decay_duration);
|
||||
|
||||
}
|
||||
public function partDecay($target_date)
|
||||
{
|
||||
$decay_duration = intval($target_date->getTimestamp() - $this->record_date->getTimestamp());
|
||||
if($decay_duration <= 0) {
|
||||
return $this->amount;
|
||||
}
|
||||
return $this->amount * pow(0.99999997802044727, $decay_duration);
|
||||
}
|
||||
|
||||
public function decayDuration($target_date)
|
||||
{
|
||||
return intval($target_date->getTimestamp() - $this->record_date->getTimestamp());
|
||||
}
|
||||
}
|
||||
|
||||
37
community_server/src/Model/Entity/StateUserTransaction.php
Normal file
37
community_server/src/Model/Entity/StateUserTransaction.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
namespace App\Model\Entity;
|
||||
|
||||
use Cake\ORM\Entity;
|
||||
|
||||
/**
|
||||
* StateUserTransaction Entity
|
||||
*
|
||||
* @property int $id
|
||||
* @property int $state_user_id
|
||||
* @property int $transaction_id
|
||||
* @property int $transaction_type_id
|
||||
*
|
||||
* @property \App\Model\Entity\StateUser $state_user
|
||||
* @property \App\Model\Entity\Transaction $transaction
|
||||
* @property \App\Model\Entity\TransactionType $transaction_type
|
||||
*/
|
||||
class StateUserTransaction extends Entity
|
||||
{
|
||||
/**
|
||||
* Fields that can be mass assigned using newEntity() or patchEntity().
|
||||
*
|
||||
* Note that when '*' is set to true, this allows all unspecified fields to
|
||||
* be mass assigned. For security purposes, it is advised to set '*' to false
|
||||
* (or remove it), and explicitly make individual fields accessible as needed.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_accessible = [
|
||||
'state_user_id' => true,
|
||||
'transaction_id' => true,
|
||||
'transaction_type_id' => true,
|
||||
'state_user' => true,
|
||||
'transaction' => true,
|
||||
'transaction_type' => true,
|
||||
];
|
||||
}
|
||||
@ -1,31 +0,0 @@
|
||||
<?php
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: StateCreateGroup.proto
|
||||
|
||||
namespace GPBMetadata;
|
||||
|
||||
class StateCreateGroup
|
||||
{
|
||||
public static $is_initialized = false;
|
||||
|
||||
public static function initOnce() {
|
||||
$pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
|
||||
|
||||
if (static::$is_initialized == true) {
|
||||
return;
|
||||
}
|
||||
\GPBMetadata\BasicTypes::initOnce();
|
||||
$pool->internalAddGeneratedFile(hex2bin(
|
||||
"0ab7010a16537461746543726561746547726f75702e70726f746f120767" .
|
||||
"72616469646f228b010a10537461746543726561746547726f7570120c0a" .
|
||||
"046e616d6518012001280912240a0e67726f75705075626c69634b657918" .
|
||||
"022001280b320c2e6772616469646f2e4b6579122a0a14706172656e7447" .
|
||||
"726f75705075626c69634b657918032001280b320c2e6772616469646f2e" .
|
||||
"4b65794a04080410055211686564657261436f6e73656e73757349646206" .
|
||||
"70726f746f33"
|
||||
), true);
|
||||
|
||||
static::$is_initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,31 +0,0 @@
|
||||
<?php
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: StateGroupChangeParent.proto
|
||||
|
||||
namespace GPBMetadata;
|
||||
|
||||
class StateGroupChangeParent
|
||||
{
|
||||
public static $is_initialized = false;
|
||||
|
||||
public static function initOnce() {
|
||||
$pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
|
||||
|
||||
if (static::$is_initialized == true) {
|
||||
return;
|
||||
}
|
||||
\GPBMetadata\BasicTypes::initOnce();
|
||||
$pool->internalAddGeneratedFile(hex2bin(
|
||||
"0ace010a1c537461746547726f75704368616e6765506172656e742e7072" .
|
||||
"6f746f12076772616469646f229c010a16537461746547726f7570436861" .
|
||||
"6e6765506172656e7412240a0e67726f75705075626c69634b6579180120" .
|
||||
"01280b320c2e6772616469646f2e4b6579122d0a176e6577506172656e74" .
|
||||
"47726f75705075626c69634b657918022001280b320c2e6772616469646f" .
|
||||
"2e4b6579122d0a176f6c64506172656e7447726f75705075626c69634b65" .
|
||||
"7918032001280b320c2e6772616469646f2e4b6579620670726f746f33"
|
||||
), true);
|
||||
|
||||
static::$is_initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,31 +0,0 @@
|
||||
<?php
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: Transaction.proto
|
||||
|
||||
namespace GPBMetadata;
|
||||
|
||||
class Transaction
|
||||
{
|
||||
public static $is_initialized = false;
|
||||
|
||||
public static function initOnce() {
|
||||
$pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
|
||||
|
||||
if (static::$is_initialized == true) {
|
||||
return;
|
||||
}
|
||||
\GPBMetadata\BasicTypes::initOnce();
|
||||
$pool->internalAddGeneratedFile(hex2bin(
|
||||
"0ab7010a115472616e73616374696f6e2e70726f746f1207677261646964" .
|
||||
"6f2290010a0b5472616e73616374696f6e120a0a02696418012001280412" .
|
||||
"2b0a08726563656976656418022001280b32192e6772616469646f2e5469" .
|
||||
"6d657374616d705365636f6e647312250a067369674d617018032001280b" .
|
||||
"32152e6772616469646f2e5369676e61747572654d6170120e0a06747848" .
|
||||
"61736818042001280c12110a09626f6479427974657318052001280c6206" .
|
||||
"70726f746f33"
|
||||
), true);
|
||||
|
||||
static::$is_initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,40 +0,0 @@
|
||||
<?php
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: TransactionBody.proto
|
||||
|
||||
namespace GPBMetadata;
|
||||
|
||||
class TransactionBody
|
||||
{
|
||||
public static $is_initialized = false;
|
||||
|
||||
public static function initOnce() {
|
||||
$pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
|
||||
|
||||
if (static::$is_initialized == true) {
|
||||
return;
|
||||
}
|
||||
\GPBMetadata\Transfer::initOnce();
|
||||
\GPBMetadata\StateCreateGroup::initOnce();
|
||||
\GPBMetadata\StateGroupChangeParent::initOnce();
|
||||
\GPBMetadata\TransactionCreation::initOnce();
|
||||
$pool->internalAddGeneratedFile(hex2bin(
|
||||
"0aec020a155472616e73616374696f6e426f64792e70726f746f12076772" .
|
||||
"616469646f1a16537461746543726561746547726f75702e70726f746f1a" .
|
||||
"1c537461746547726f75704368616e6765506172656e742e70726f746f1a" .
|
||||
"195472616e73616374696f6e4372656174696f6e2e70726f746f22f0010a" .
|
||||
"0f5472616e73616374696f6e426f6479120c0a046d656d6f180120012809" .
|
||||
"12300a0b63726561746547726f757018022001280b32192e677261646964" .
|
||||
"6f2e537461746543726561746547726f75704800123c0a1167726f757043" .
|
||||
"68616e6765506172656e7418032001280b321f2e6772616469646f2e5374" .
|
||||
"61746547726f75704368616e6765506172656e74480012250a087472616e" .
|
||||
"7366657218042001280b32112e6772616469646f2e5472616e7366657248" .
|
||||
"0012300a086372656174696f6e18052001280b321c2e6772616469646f2e" .
|
||||
"5472616e73616374696f6e4372656174696f6e480042060a046461746162" .
|
||||
"0670726f746f33"
|
||||
), true);
|
||||
|
||||
static::$is_initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,29 +0,0 @@
|
||||
<?php
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: TransactionCreation.proto
|
||||
|
||||
namespace GPBMetadata;
|
||||
|
||||
class TransactionCreation
|
||||
{
|
||||
public static $is_initialized = false;
|
||||
|
||||
public static function initOnce() {
|
||||
$pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
|
||||
|
||||
if (static::$is_initialized == true) {
|
||||
return;
|
||||
}
|
||||
\GPBMetadata\BasicTypes::initOnce();
|
||||
$pool->internalAddGeneratedFile(hex2bin(
|
||||
"0a88010a195472616e73616374696f6e4372656174696f6e2e70726f746f" .
|
||||
"12076772616469646f225a0a135472616e73616374696f6e437265617469" .
|
||||
"6f6e122f0a0e7265636569766572416d6f756e7418012001280b32172e67" .
|
||||
"72616469646f2e5265636569766572416d6f756e7412120a0a6964656e74" .
|
||||
"5f68617368180220012811620670726f746f33"
|
||||
), true);
|
||||
|
||||
static::$is_initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,85 @@
|
||||
<?php
|
||||
namespace App\Model\Table;
|
||||
|
||||
use Cake\ORM\Query;
|
||||
use Cake\ORM\RulesChecker;
|
||||
use Cake\ORM\Table;
|
||||
use Cake\Validation\Validator;
|
||||
|
||||
/**
|
||||
* StateUserTransactions Model
|
||||
*
|
||||
* @property \App\Model\Table\StateUsersTable&\Cake\ORM\Association\BelongsTo $StateUsers
|
||||
* @property \App\Model\Table\TransactionsTable&\Cake\ORM\Association\BelongsTo $Transactions
|
||||
* @property \App\Model\Table\TransactionTypesTable&\Cake\ORM\Association\BelongsTo $TransactionTypes
|
||||
*
|
||||
* @method \App\Model\Entity\StateUserTransaction get($primaryKey, $options = [])
|
||||
* @method \App\Model\Entity\StateUserTransaction newEntity($data = null, array $options = [])
|
||||
* @method \App\Model\Entity\StateUserTransaction[] newEntities(array $data, array $options = [])
|
||||
* @method \App\Model\Entity\StateUserTransaction|false save(\Cake\Datasource\EntityInterface $entity, $options = [])
|
||||
* @method \App\Model\Entity\StateUserTransaction saveOrFail(\Cake\Datasource\EntityInterface $entity, $options = [])
|
||||
* @method \App\Model\Entity\StateUserTransaction patchEntity(\Cake\Datasource\EntityInterface $entity, array $data, array $options = [])
|
||||
* @method \App\Model\Entity\StateUserTransaction[] patchEntities($entities, array $data, array $options = [])
|
||||
* @method \App\Model\Entity\StateUserTransaction findOrCreate($search, callable $callback = null, $options = [])
|
||||
*/
|
||||
class StateUserTransactionsTable extends Table
|
||||
{
|
||||
/**
|
||||
* Initialize method
|
||||
*
|
||||
* @param array $config The configuration for the Table.
|
||||
* @return void
|
||||
*/
|
||||
public function initialize(array $config)
|
||||
{
|
||||
parent::initialize($config);
|
||||
|
||||
$this->setTable('state_user_transactions');
|
||||
$this->setDisplayField('id');
|
||||
$this->setPrimaryKey('id');
|
||||
|
||||
$this->belongsTo('StateUsers', [
|
||||
'foreignKey' => 'state_user_id',
|
||||
'joinType' => 'INNER',
|
||||
]);
|
||||
$this->belongsTo('Transactions', [
|
||||
'foreignKey' => 'transaction_id',
|
||||
'joinType' => 'INNER',
|
||||
]);
|
||||
$this->belongsTo('TransactionTypes', [
|
||||
'foreignKey' => 'transaction_type_id',
|
||||
'joinType' => 'INNER',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default validation rules.
|
||||
*
|
||||
* @param \Cake\Validation\Validator $validator Validator instance.
|
||||
* @return \Cake\Validation\Validator
|
||||
*/
|
||||
public function validationDefault(Validator $validator)
|
||||
{
|
||||
$validator
|
||||
->nonNegativeInteger('id')
|
||||
->allowEmptyString('id', null, 'create');
|
||||
|
||||
return $validator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a rules checker object that will be used for validating
|
||||
* application integrity.
|
||||
*
|
||||
* @param \Cake\ORM\RulesChecker $rules The rules object to be modified.
|
||||
* @return \Cake\ORM\RulesChecker
|
||||
*/
|
||||
public function buildRules(RulesChecker $rules)
|
||||
{
|
||||
$rules->add($rules->existsIn(['state_user_id'], 'StateUsers'));
|
||||
$rules->add($rules->existsIn(['transaction_id'], 'Transactions'));
|
||||
$rules->add($rules->existsIn(['transaction_type_id'], 'TransactionTypes'));
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
||||
@ -73,6 +73,9 @@ class TransactionsTable extends Table
|
||||
$this->hasMany('TransactionSignatures', [
|
||||
'foreignKey' => 'transaction_id'
|
||||
]);
|
||||
$this->hasMany('StateUserTransactions', [
|
||||
'foreignKey' => 'transaction_id'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -6,7 +6,7 @@ use Cake\ORM\TableRegistry;
|
||||
|
||||
class TransactionBase {
|
||||
private $errors = [];
|
||||
static $stateUsersTable = null;
|
||||
static $tables = [];
|
||||
|
||||
public function getErrors() {
|
||||
return $this->errors;
|
||||
@ -24,18 +24,17 @@ class TransactionBase {
|
||||
return count($this->errors) > 0;
|
||||
}
|
||||
|
||||
public static function getStateUsersTable()
|
||||
{
|
||||
if(!self::$stateUsersTable) {
|
||||
self::$stateUsersTable = TableRegistry::getTableLocator()->get('state_users');
|
||||
public static function getTable($tableName) {
|
||||
if(!isset(self::$tables[$tableName])) {
|
||||
self::$tables[$tableName] = TableRegistry::getTableLocator()->get($tableName);
|
||||
}
|
||||
return self::$stateUsersTable;
|
||||
return self::$tables[$tableName];
|
||||
}
|
||||
|
||||
|
||||
protected function getStateUserId($publicKey) {
|
||||
|
||||
$stateUsersTable = self::getStateUsersTable();
|
||||
$stateUsersTable = self::getTable('state_users');
|
||||
$stateUser = $stateUsersTable->find('all')->select(['id'])->where(['public_key' => $publicKey])->first();
|
||||
if($stateUser) {
|
||||
return $stateUser->id;
|
||||
@ -53,7 +52,7 @@ class TransactionBase {
|
||||
}
|
||||
|
||||
protected function getStateUser($id) {
|
||||
$stateUsersTable = self::getStateUsersTable();
|
||||
$stateUsersTable = self::getTable('state_users');
|
||||
$stateUser = $stateUsersTable->get($id);
|
||||
if($stateUser) {
|
||||
return $stateUser;
|
||||
@ -63,9 +62,9 @@ class TransactionBase {
|
||||
}
|
||||
|
||||
|
||||
protected function updateStateBalance($stateUserId, $addAmountCent) {
|
||||
protected function updateStateBalance($stateUserId, $addAmountCent, $recordDate) {
|
||||
$finalBalance = 0;
|
||||
$stateBalancesTable = TableRegistry::getTableLocator()->get('stateBalances');
|
||||
$stateBalancesTable = self::getTable('stateBalances');
|
||||
$stateBalanceQuery = $stateBalancesTable
|
||||
->find('all')
|
||||
->select(['amount', 'id'])
|
||||
@ -75,12 +74,14 @@ class TransactionBase {
|
||||
|
||||
if($stateBalanceQuery->count() > 0) {
|
||||
$stateBalanceEntry = $stateBalanceQuery->first();
|
||||
$stateBalanceEntry->amount = $stateBalanceEntry->partDecay($recordDate) + $addAmountCent;
|
||||
$stateBalanceEntry->amount += $addAmountCent;
|
||||
} else {
|
||||
$stateBalanceEntry = $stateBalancesTable->newEntity();
|
||||
$stateBalanceEntry->state_user_id = $stateUserId;
|
||||
$stateBalanceEntry->amount = $addAmountCent;
|
||||
}
|
||||
$stateBalanceEntry->record_date = $recordDate;
|
||||
$finalBalance = $stateBalanceEntry->amount;
|
||||
//echo "\ntry to save: "; var_dump($stateBalanceEntry); echo "\n";
|
||||
if(!$stateBalancesTable->save($stateBalanceEntry)) {
|
||||
@ -90,4 +91,32 @@ class TransactionBase {
|
||||
}
|
||||
return $finalBalance;
|
||||
}
|
||||
|
||||
protected function addStateUserTransaction($stateUserId, $transactionId, $transactionTypeId, $balance) {
|
||||
$stateUserTransactionTable = self::getTable('state_user_transactions');
|
||||
$stateUserTransactions = $stateUserTransactionTable
|
||||
->find('all')
|
||||
->where(['state_user_id' => $stateUserId])
|
||||
->order(['transaction_id DESC']);
|
||||
|
||||
if($stateUserTransactions->count() > 0) {
|
||||
$stateBalanceTable = self::getTable('state_balances');
|
||||
$balance_entity = $stateBalanceTable->newEntity();
|
||||
$balance_entity->amount = $stateUserTransactions->first()->balance;
|
||||
$balance_entity->record_date = $stateUserTransactions->first()->balance_date;
|
||||
$balance = $balance_entity->decay + $balance;
|
||||
}
|
||||
$entity = $stateUserTransactionTable->newEntity();
|
||||
$entity->state_user_id = $stateUserId;
|
||||
$entity->transaction_id = $transactionId;
|
||||
$entity->transaction_type_id = $transactionTypeId;
|
||||
$entity->balance = $balance;
|
||||
|
||||
if(!$stateUserTransactionTable->save($entity)) {
|
||||
$errors = $entity->getErrors();
|
||||
$this->addError('TransactionBase::addStateUserTransaction', 'error saving state user balance with: ' . json_encode($errors));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -79,7 +79,7 @@ class TransactionBody extends TransactionBase {
|
||||
if ($transactionsTable->save($transactionEntity)) {
|
||||
// success
|
||||
$this->mTransactionID = $transactionEntity->id;
|
||||
if(!$this->mSpecificTransaction->save($transactionEntity->id, $firstPublic)) {
|
||||
if(!$this->mSpecificTransaction->save($transactionEntity->id, $firstPublic, $transactionEntity->received)) {
|
||||
$this->addErrors($this->mSpecificTransaction->getErrors());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -189,6 +189,12 @@ class TransactionCreation extends TransactionBase {
|
||||
return false;
|
||||
}
|
||||
} else {*/
|
||||
if($newSum2 <= 0) {
|
||||
$this->addError(
|
||||
'TransactionCreation::validate',
|
||||
'Creation less than 0 GDD per Month for '. $receiverEmail .' in target_date not allowed'
|
||||
);
|
||||
}
|
||||
if($newSum2 > 10000000) {
|
||||
$this->addError(
|
||||
'TransactionCreation::validate',
|
||||
@ -225,16 +231,27 @@ class TransactionCreation extends TransactionBase {
|
||||
}
|
||||
|
||||
// update state balance
|
||||
if(false === $this->updateStateBalance($receiverUserId, $this->getAmount())) {
|
||||
$final_balance = $this->updateStateBalance($receiverUserId, $this->getAmount(), $transactionCreationEntity->target_date);
|
||||
if(false === $final_balance) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$target_date = new FrozenDate($transactionCreationEntity->target_date);
|
||||
$stateBalancesTable = self::getTable('stateBalances');
|
||||
$state_balance = $stateBalancesTable->newEntity();
|
||||
$state_balance->amount = $this->getAmount();
|
||||
$state_balance->record_date = $target_date;
|
||||
// decay is a virtual field which is calculated from amount and now() - record_date
|
||||
if(!$this->addStateUserTransaction($receiverUserId, $transaction_id, 1, $state_balance->decay)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function sendNotificationEmail($memo)
|
||||
{
|
||||
$disable_email = Configure::read('disableEmail', false);
|
||||
if($disable_email) return true;
|
||||
// send notification email
|
||||
$receiverUserId = $this->getStateUserId($this->getReceiverPublic());
|
||||
$receiverUser = $this->getStateUser($receiverUserId);
|
||||
|
||||
@ -154,11 +154,15 @@ class TransactionTransfer extends TransactionBase {
|
||||
$this->addError($functionName, 'sender amount doesn\'t match receiver amount');
|
||||
return false;
|
||||
}
|
||||
if($senderSum < 0) {
|
||||
$this->addError($functionName, 'negative amount not supported');
|
||||
return false;
|
||||
}
|
||||
//die("\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
public function save($transaction_id, $firstPublic) {
|
||||
public function save($transaction_id, $firstPublic, $received) {
|
||||
|
||||
static $functionName = 'TransactionCreation::save';
|
||||
|
||||
@ -182,11 +186,11 @@ class TransactionTransfer extends TransactionBase {
|
||||
return false;
|
||||
}
|
||||
|
||||
$finalSenderBalance = $this->updateStateBalance($senderUserId, -$senderAmount->getAmount());
|
||||
$finalSenderBalance = $this->updateStateBalance($senderUserId, -$senderAmount->getAmount(), $received);
|
||||
if(false === $finalSenderBalance) {
|
||||
return false;
|
||||
}
|
||||
if(false === $this->updateStateBalance($receiverUserId, $receiverAmount->getAmount())) {
|
||||
if(false === $this->updateStateBalance($receiverUserId, $receiverAmount->getAmount(), $received)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -203,8 +207,12 @@ class TransactionTransfer extends TransactionBase {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(!$this->addStateUserTransaction($senderUserId, $transaction_id, 2, $senderAmount->getAmount())) {
|
||||
return false;
|
||||
}
|
||||
if(!$this->addStateUserTransaction($receiverUserId, $transaction_id, 2, -$senderAmount->getAmount())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//$this->addError('TransactionTransfer::save', 'not implemented yet');
|
||||
//return false;
|
||||
@ -214,7 +222,9 @@ class TransactionTransfer extends TransactionBase {
|
||||
public function sendNotificationEmail($memo)
|
||||
{
|
||||
// send notification email
|
||||
|
||||
$disable_email = Configure::read('disableEmail', false);
|
||||
if($disable_email) return true;
|
||||
|
||||
$senderAmount = $this->protoTransactionTransfer->getSenderAmounts()[0];
|
||||
$receiverAmount = $this->protoTransactionTransfer->getReceiverAmounts()[0];
|
||||
$senderUserId = $this->getStateUserId($senderAmount->getEd25519SenderPubkey());
|
||||
|
||||
31
community_server/src/Template/StateUserTransactions/add.ctp
Normal file
31
community_server/src/Template/StateUserTransactions/add.ctp
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* @var \App\View\AppView $this
|
||||
* @var \App\Model\Entity\StateUserTransaction $stateUserTransaction
|
||||
*/
|
||||
?>
|
||||
<nav class="large-3 medium-4 columns" id="actions-sidebar">
|
||||
<ul class="side-nav">
|
||||
<li class="heading"><?= __('Actions') ?></li>
|
||||
<li><?= $this->Html->link(__('List State User Transactions'), ['action' => 'index']) ?></li>
|
||||
<li><?= $this->Html->link(__('List State Users'), ['controller' => 'StateUsers', 'action' => 'index']) ?></li>
|
||||
<li><?= $this->Html->link(__('New State User'), ['controller' => 'StateUsers', 'action' => 'add']) ?></li>
|
||||
<li><?= $this->Html->link(__('List Transactions'), ['controller' => 'Transactions', 'action' => 'index']) ?></li>
|
||||
<li><?= $this->Html->link(__('New Transaction'), ['controller' => 'Transactions', 'action' => 'add']) ?></li>
|
||||
<li><?= $this->Html->link(__('List Transaction Types'), ['controller' => 'TransactionTypes', 'action' => 'index']) ?></li>
|
||||
<li><?= $this->Html->link(__('New Transaction Type'), ['controller' => 'TransactionTypes', 'action' => 'add']) ?></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<div class="stateUserTransactions form large-9 medium-8 columns content">
|
||||
<?= $this->Form->create($stateUserTransaction) ?>
|
||||
<fieldset>
|
||||
<legend><?= __('Add State User Transaction') ?></legend>
|
||||
<?php
|
||||
echo $this->Form->control('state_user_id', ['options' => $stateUsers]);
|
||||
echo $this->Form->control('transaction_id', ['options' => $transactions]);
|
||||
echo $this->Form->control('transaction_type_id', ['options' => $transactionTypes]);
|
||||
?>
|
||||
</fieldset>
|
||||
<?= $this->Form->button(__('Submit')) ?>
|
||||
<?= $this->Form->end() ?>
|
||||
</div>
|
||||
37
community_server/src/Template/StateUserTransactions/edit.ctp
Normal file
37
community_server/src/Template/StateUserTransactions/edit.ctp
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
/**
|
||||
* @var \App\View\AppView $this
|
||||
* @var \App\Model\Entity\StateUserTransaction $stateUserTransaction
|
||||
*/
|
||||
?>
|
||||
<nav class="large-3 medium-4 columns" id="actions-sidebar">
|
||||
<ul class="side-nav">
|
||||
<li class="heading"><?= __('Actions') ?></li>
|
||||
<li><?= $this->Form->postLink(
|
||||
__('Delete'),
|
||||
['action' => 'delete', $stateUserTransaction->id],
|
||||
['confirm' => __('Are you sure you want to delete # {0}?', $stateUserTransaction->id)]
|
||||
)
|
||||
?></li>
|
||||
<li><?= $this->Html->link(__('List State User Transactions'), ['action' => 'index']) ?></li>
|
||||
<li><?= $this->Html->link(__('List State Users'), ['controller' => 'StateUsers', 'action' => 'index']) ?></li>
|
||||
<li><?= $this->Html->link(__('New State User'), ['controller' => 'StateUsers', 'action' => 'add']) ?></li>
|
||||
<li><?= $this->Html->link(__('List Transactions'), ['controller' => 'Transactions', 'action' => 'index']) ?></li>
|
||||
<li><?= $this->Html->link(__('New Transaction'), ['controller' => 'Transactions', 'action' => 'add']) ?></li>
|
||||
<li><?= $this->Html->link(__('List Transaction Types'), ['controller' => 'TransactionTypes', 'action' => 'index']) ?></li>
|
||||
<li><?= $this->Html->link(__('New Transaction Type'), ['controller' => 'TransactionTypes', 'action' => 'add']) ?></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<div class="stateUserTransactions form large-9 medium-8 columns content">
|
||||
<?= $this->Form->create($stateUserTransaction) ?>
|
||||
<fieldset>
|
||||
<legend><?= __('Edit State User Transaction') ?></legend>
|
||||
<?php
|
||||
echo $this->Form->control('state_user_id', ['options' => $stateUsers]);
|
||||
echo $this->Form->control('transaction_id', ['options' => $transactions]);
|
||||
echo $this->Form->control('transaction_type_id', ['options' => $transactionTypes]);
|
||||
?>
|
||||
</fieldset>
|
||||
<?= $this->Form->button(__('Submit')) ?>
|
||||
<?= $this->Form->end() ?>
|
||||
</div>
|
||||
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
/**
|
||||
* @var \App\View\AppView $this
|
||||
* @var \App\Model\Entity\StateUserTransaction[]|\Cake\Collection\CollectionInterface $stateUserTransactions
|
||||
*/
|
||||
?>
|
||||
<nav class="large-3 medium-4 columns" id="actions-sidebar">
|
||||
<ul class="side-nav">
|
||||
<li class="heading"><?= __('Actions') ?></li>
|
||||
<li><?= $this->Html->link(__('New State User Transaction'), ['action' => 'add']) ?></li>
|
||||
<li><?= $this->Html->link(__('List State Users'), ['controller' => 'StateUsers', 'action' => 'index']) ?></li>
|
||||
<li><?= $this->Html->link(__('New State User'), ['controller' => 'StateUsers', 'action' => 'add']) ?></li>
|
||||
<li><?= $this->Html->link(__('List Transactions'), ['controller' => 'Transactions', 'action' => 'index']) ?></li>
|
||||
<li><?= $this->Html->link(__('New Transaction'), ['controller' => 'Transactions', 'action' => 'add']) ?></li>
|
||||
<li><?= $this->Html->link(__('List Transaction Types'), ['controller' => 'TransactionTypes', 'action' => 'index']) ?></li>
|
||||
<li><?= $this->Html->link(__('New Transaction Type'), ['controller' => 'TransactionTypes', 'action' => 'add']) ?></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<div class="stateUserTransactions index large-9 medium-8 columns content">
|
||||
<h3><?= __('State User Transactions') ?></h3>
|
||||
<table cellpadding="0" cellspacing="0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col"><?= $this->Paginator->sort('id') ?></th>
|
||||
<th scope="col"><?= $this->Paginator->sort('state_user_id') ?></th>
|
||||
<th scope="col"><?= $this->Paginator->sort('transaction_id') ?></th>
|
||||
<th scope="col"><?= $this->Paginator->sort('transaction_type_id') ?></th>
|
||||
<th scope="col" class="actions"><?= __('Actions') ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($stateUserTransactions as $stateUserTransaction): ?>
|
||||
<tr>
|
||||
<td><?= $this->Number->format($stateUserTransaction->id) ?></td>
|
||||
<td><?= $stateUserTransaction->has('state_user') ? $this->Html->link($stateUserTransaction->state_user->email, ['controller' => 'StateUsers', 'action' => 'view', $stateUserTransaction->state_user->id]) : '' ?></td>
|
||||
<td><?= $stateUserTransaction->has('transaction') ? $this->Html->link($stateUserTransaction->transaction->id, ['controller' => 'Transactions', 'action' => 'view', $stateUserTransaction->transaction->id]) : '' ?></td>
|
||||
<td><?= $stateUserTransaction->has('transaction_type') ? $this->Html->link($stateUserTransaction->transaction_type->name, ['controller' => 'TransactionTypes', 'action' => 'view', $stateUserTransaction->transaction_type->id]) : '' ?></td>
|
||||
<td class="actions">
|
||||
<?= $this->Html->link(__('View'), ['action' => 'view', $stateUserTransaction->id]) ?>
|
||||
<?= $this->Html->link(__('Edit'), ['action' => 'edit', $stateUserTransaction->id]) ?>
|
||||
<?= $this->Form->postLink(__('Delete'), ['action' => 'delete', $stateUserTransaction->id], ['confirm' => __('Are you sure you want to delete # {0}?', $stateUserTransaction->id)]) ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="paginator">
|
||||
<ul class="pagination">
|
||||
<?= $this->Paginator->first('<< ' . __('first')) ?>
|
||||
<?= $this->Paginator->prev('< ' . __('previous')) ?>
|
||||
<?= $this->Paginator->numbers() ?>
|
||||
<?= $this->Paginator->next(__('next') . ' >') ?>
|
||||
<?= $this->Paginator->last(__('last') . ' >>') ?>
|
||||
</ul>
|
||||
<p><?= $this->Paginator->counter(['format' => __('Page {{page}} of {{pages}}, showing {{current}} record(s) out of {{count}} total')]) ?></p>
|
||||
</div>
|
||||
</div>
|
||||
42
community_server/src/Template/StateUserTransactions/view.ctp
Normal file
42
community_server/src/Template/StateUserTransactions/view.ctp
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
* @var \App\View\AppView $this
|
||||
* @var \App\Model\Entity\StateUserTransaction $stateUserTransaction
|
||||
*/
|
||||
?>
|
||||
<nav class="large-3 medium-4 columns" id="actions-sidebar">
|
||||
<ul class="side-nav">
|
||||
<li class="heading"><?= __('Actions') ?></li>
|
||||
<li><?= $this->Html->link(__('Edit State User Transaction'), ['action' => 'edit', $stateUserTransaction->id]) ?> </li>
|
||||
<li><?= $this->Form->postLink(__('Delete State User Transaction'), ['action' => 'delete', $stateUserTransaction->id], ['confirm' => __('Are you sure you want to delete # {0}?', $stateUserTransaction->id)]) ?> </li>
|
||||
<li><?= $this->Html->link(__('List State User Transactions'), ['action' => 'index']) ?> </li>
|
||||
<li><?= $this->Html->link(__('New State User Transaction'), ['action' => 'add']) ?> </li>
|
||||
<li><?= $this->Html->link(__('List State Users'), ['controller' => 'StateUsers', 'action' => 'index']) ?> </li>
|
||||
<li><?= $this->Html->link(__('New State User'), ['controller' => 'StateUsers', 'action' => 'add']) ?> </li>
|
||||
<li><?= $this->Html->link(__('List Transactions'), ['controller' => 'Transactions', 'action' => 'index']) ?> </li>
|
||||
<li><?= $this->Html->link(__('New Transaction'), ['controller' => 'Transactions', 'action' => 'add']) ?> </li>
|
||||
<li><?= $this->Html->link(__('List Transaction Types'), ['controller' => 'TransactionTypes', 'action' => 'index']) ?> </li>
|
||||
<li><?= $this->Html->link(__('New Transaction Type'), ['controller' => 'TransactionTypes', 'action' => 'add']) ?> </li>
|
||||
</ul>
|
||||
</nav>
|
||||
<div class="stateUserTransactions view large-9 medium-8 columns content">
|
||||
<h3><?= h($stateUserTransaction->id) ?></h3>
|
||||
<table class="vertical-table">
|
||||
<tr>
|
||||
<th scope="row"><?= __('State User') ?></th>
|
||||
<td><?= $stateUserTransaction->has('state_user') ? $this->Html->link($stateUserTransaction->state_user->email, ['controller' => 'StateUsers', 'action' => 'view', $stateUserTransaction->state_user->id]) : '' ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?= __('Transaction') ?></th>
|
||||
<td><?= $stateUserTransaction->has('transaction') ? $this->Html->link($stateUserTransaction->transaction->id, ['controller' => 'Transactions', 'action' => 'view', $stateUserTransaction->transaction->id]) : '' ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?= __('Transaction Type') ?></th>
|
||||
<td><?= $stateUserTransaction->has('transaction_type') ? $this->Html->link($stateUserTransaction->transaction_type->name, ['controller' => 'TransactionTypes', 'action' => 'view', $stateUserTransaction->transaction_type->id]) : '' ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?= __('Id') ?></th>
|
||||
<td><?= $this->Number->format($stateUserTransaction->id) ?></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
?>
|
||||
<div class="transactions form large-9 medium-8 columns content">
|
||||
<h1>Synchronize state_user_transactions with transactions</h1>
|
||||
<p>transactions count: <?= $count1 ?></p>
|
||||
<p>state_user_transaction count: <?= $count2 ?></p>
|
||||
<p>Missing count: <?= count($missing_transactions); ?></p>
|
||||
<p>First 10 Missing ids: </p>
|
||||
<p><?php
|
||||
foreach($missing_transactions as $i => $id) {
|
||||
if($i > 10) break;
|
||||
if($i > 0) echo ', ';
|
||||
echo $id['id'];
|
||||
} ?></p>
|
||||
|
||||
<?php if(isset($entities) && isset($results)) : ?>
|
||||
<h2>Synchronize errors: </h2>
|
||||
<ul>
|
||||
<?php
|
||||
$succeed = 0;
|
||||
//var_dump($results);
|
||||
if($results) :
|
||||
foreach($results as $i => $result) :
|
||||
if(false != $result) {
|
||||
$succeed++;
|
||||
continue;
|
||||
}
|
||||
?>
|
||||
<li>Error saving entity: <?= json_encode($entities[$i]) ?> with error: <?= json_encode($entities[$i]->getErrors()) ?></li>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
<li><success>Succeed: <?= $succeed ?></success></li>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
|
||||
<?= $this->Form->create() ?>
|
||||
<?= $this->Form->button(__('Synchronize')) ?>
|
||||
<?= $this->Form->end() ?>
|
||||
</div>
|
||||
@ -45,21 +45,21 @@ class TransactionCreationsFixture extends TestFixture
|
||||
[
|
||||
'id' => 1,
|
||||
'transaction_id' => 1,
|
||||
'state_user_id' => 2,
|
||||
'state_user_id' => 1,
|
||||
'amount' => 10000000,
|
||||
'ident_hash' => hex2bin('3235303332373635330000000000000000000000000000000000000000000000')
|
||||
],
|
||||
[
|
||||
'id' => 2,
|
||||
'transaction_id' => 2,
|
||||
'state_user_id' => 2,
|
||||
'state_user_id' => 1,
|
||||
'amount' => 10000000,
|
||||
'ident_hash' => hex2bin('3235303332373635330000000000000000000000000000000000000000000000')
|
||||
],
|
||||
[
|
||||
'id' => 3,
|
||||
'transaction_id' => 3,
|
||||
'state_user_id' => 2,
|
||||
'state_user_id' => 1,
|
||||
'amount' => 10000000,
|
||||
'ident_hash' => hex2bin('3235303332373635330000000000000000000000000000000000000000000000')
|
||||
],
|
||||
|
||||
@ -43,10 +43,10 @@ class TransactionSendCoinsFixture extends TestFixture
|
||||
[
|
||||
'id' => 1,
|
||||
'transaction_id' => 4,
|
||||
'state_user_id' => 2,
|
||||
'receiver_public_key' => '0x80183e03535d17a54ff1fd7dbaed86939d423a19a258c26b8e338ce601338355',
|
||||
'receiver_user_id' => 1,
|
||||
'amount' => 150000001,
|
||||
'state_user_id' => 1,
|
||||
'receiver_public_key' => '8190bda585ee5f1d9fbf7d06e81e69ec18e13376104cff54b7457eb7d3ef710d',
|
||||
'receiver_user_id' => 4,
|
||||
'amount' => 15000000,
|
||||
'sender_final_balance' => 15000000
|
||||
],
|
||||
];
|
||||
|
||||
@ -67,19 +67,52 @@ class StateBalancesControllerTest extends TestCase
|
||||
public function testAjaxGetBalance()
|
||||
{
|
||||
$session_id = rand();
|
||||
$balance = rand();
|
||||
$this->session([
|
||||
'session_id' => $session_id,
|
||||
'Transaction' => ['pending' => 0, 'executing' => 0],
|
||||
'StateUser' => [
|
||||
'id' => 2, // 1 don't work, I don't know why
|
||||
'id' => 1,
|
||||
'email_checked' => 1,
|
||||
'balance' => $balance
|
||||
'public_hex' => '8190bda585ee5f1d9fbf7d06e81e69ec18e13376104cff54b7457eb7d3ef710d'
|
||||
]
|
||||
]);
|
||||
//echo "balance: $balance";
|
||||
$this->getAndParse('/state-balances/ajaxGetBalance/' . $session_id,
|
||||
['state' => 'success', 'balance' => $balance]
|
||||
['state' => 'success', 'balance' => 1200000]
|
||||
);
|
||||
}
|
||||
|
||||
public function testAjaxGetBalanceInvalidSession()
|
||||
{
|
||||
$session_id = rand();
|
||||
$this->session([
|
||||
'session_id' => $session_id,
|
||||
'Transaction' => ['pending' => 0, 'executing' => 0],
|
||||
'StateUser' => [
|
||||
'email_checked' => 1,
|
||||
'public_hex' => '8190bda585ee5f1d9fbf7d06e81e69ec18e13376104cff54b7457eb7d3ef710d'
|
||||
]
|
||||
]);
|
||||
//echo "balance: $balance";
|
||||
$this->getAndParse('/state-balances/ajaxGetBalance/' . 1211,
|
||||
['state' => 'not found', 'msg' => 'invalid session']
|
||||
);
|
||||
}
|
||||
|
||||
public function testAjaxGetBalanceInvalidSessionId()
|
||||
{
|
||||
$session_id = rand();
|
||||
$this->session([
|
||||
'session_id' => $session_id,
|
||||
'Transaction' => ['pending' => 0, 'executing' => 0],
|
||||
'StateUser' => [
|
||||
'email_checked' => 1,
|
||||
'public_hex' => '8190bda585ee5f1d9fbf7d06e81e69ec18e13376104cff54b7457eb7d3ef710d'
|
||||
]
|
||||
]);
|
||||
//echo "balance: $balance";
|
||||
$this->getAndParse('/state-balances/ajaxGetBalance' ,
|
||||
['state' => 'error', 'msg' => 'invalid session id']
|
||||
);
|
||||
}
|
||||
|
||||
@ -90,7 +123,38 @@ class StateBalancesControllerTest extends TestCase
|
||||
*/
|
||||
public function testAjaxListTransactions()
|
||||
{
|
||||
$this->markTestIncomplete('Not implemented yet.');
|
||||
//ajaxListTransactions
|
||||
$session_id = rand();
|
||||
$this->session([
|
||||
'session_id' => $session_id,
|
||||
'Transaction' => ['pending' => 0, 'executing' => 0],
|
||||
'StateUser' => [
|
||||
'id' => 1,
|
||||
'first_name' => 'Dario',
|
||||
'last_name' => 'Frodo',
|
||||
'email_checked' => 1,
|
||||
'email' => 'fördertest@gradido.org',
|
||||
'public_hex' => '94ae135b93cd9f33752b4e55c41903a3faa13a75bb90bfd411ea1d4a1a5e711f'
|
||||
]
|
||||
]);
|
||||
//echo "balance: $balance";
|
||||
$this->getAndParse('/state-balances/ajaxListTransactions/' . $session_id,
|
||||
[
|
||||
'state' => 'success', 'transactions' => [[
|
||||
'name' => 'Dario Frodo',
|
||||
'email'=> 'dariofrodo@gmx.de',
|
||||
'type'=> '',
|
||||
'transaction_id' => 4,
|
||||
'date' => '2021-02-19T13:27:14+00:00',
|
||||
'balance' => 150000001,
|
||||
'memo' => ''
|
||||
]],
|
||||
'transactionExecutingCount' => 0,
|
||||
'count' => 1,
|
||||
'gdtSum' => 0,
|
||||
'timeUsed' => 0.03168010711669922
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -169,10 +233,16 @@ class StateBalancesControllerTest extends TestCase
|
||||
$responseBodyString = (string)$this->_response->getBody();
|
||||
$json = json_decode($responseBodyString);
|
||||
$this->assertNotFalse($json);
|
||||
|
||||
|
||||
if(is_array($expected)) {
|
||||
// copy timeUsed because this value will be variy always
|
||||
if(isset($expected['timeUsed']) && isset($json->timeUsed)) {
|
||||
$expected['timeUsed'] = $json->timeUsed;
|
||||
}
|
||||
$expected = json_encode($expected);
|
||||
}
|
||||
|
||||
|
||||
$this->assertEquals($expected, $responseBodyString);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user