diff --git a/community_server/db/skeema/gradido_community/transaction_types.sql b/community_server/db/skeema/gradido_community/transaction_types.sql
index a3e6779d9..10aad25b0 100644
--- a/community_server/db/skeema/gradido_community/transaction_types.sql
+++ b/community_server/db/skeema/gradido_community/transaction_types.sql
@@ -1,6 +1,6 @@
CREATE TABLE `transaction_types` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `name` varchar(45) COLLATE utf8mb4_unicode_ci NOT NULL,
+ `name` varchar(90) COLLATE utf8mb4_unicode_ci NOT NULL,
`text` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
diff --git a/community_server/src/Controller/AppController.php b/community_server/src/Controller/AppController.php
index 80690b238..9f577d77a 100644
--- a/community_server/src/Controller/AppController.php
+++ b/community_server/src/Controller/AppController.php
@@ -166,7 +166,7 @@ class AppController extends Controller
}
$php_data_version = 2;
if($current_db_version < $php_data_version) {
- $this->redirect(['controller' => 'Migrations', 'action' => 'migrate', $html, $current_db_version]);
+ $this->redirect(['controller' => 'Migrations', 'action' => 'migrate', 'html' => $html, 'db_version' => $current_db_version]);
}
}
diff --git a/community_server/src/Controller/MigrationsController.php b/community_server/src/Controller/MigrationsController.php
index ddf02bfdc..31fa41001 100644
--- a/community_server/src/Controller/MigrationsController.php
+++ b/community_server/src/Controller/MigrationsController.php
@@ -13,6 +13,12 @@ use Cake\ORM\TableRegistry;
*/
class MigrationsController extends AppController
{
+ public function initialize()
+ {
+ parent::initialize();
+ $this->Auth->allow('migrate');
+ }
+
/**
* Index method
*
@@ -36,8 +42,12 @@ class MigrationsController extends AppController
return ['success' => true];
}
- public function migrate($html, $current_db_version)
+ public function migrate()
{
+
+ $html = $this->request->getQuery('html');
+ $current_db_version = $this->request->getQuery('db_version');
+
$startTime = microtime(true);
$stateUserTransactionsTable = TableRegistry::getTableLocator()->get('StateUserTransactions');
$transactionsTable = TableRegistry::getTableLocator()->get('Transactions');
@@ -52,10 +62,10 @@ class MigrationsController extends AppController
if($current_db_version == 1) {
$stateUserTransactionsTable->truncate();
$commands = [
- [$transactionsTable, 'fillStateUserTransactions'],
- [$stateBalancesTable, 'updateAllBalances'],
[$blockchainTypesTable, 'fillWithDefault'],
- [$transactionTypesTable, 'fillWithDefault']
+ [$transactionTypesTable, 'fillWithDefault'],
+ [$transactionsTable, 'fillStateUserTransactions'],
+ [$stateBalancesTable, 'updateAllBalances']
];
$new_db_version = 2;
}
diff --git a/community_server/src/Model/Entity/StateBalance.php b/community_server/src/Model/Entity/StateBalance.php
index 7d595653e..334db222f 100644
--- a/community_server/src/Model/Entity/StateBalance.php
+++ b/community_server/src/Model/Entity/StateBalance.php
@@ -44,9 +44,7 @@ class StateBalance extends Entity
} else if(method_exists($dateOrTime, 'i18nFormat')) {
return $dateOrTime->i18nFormat(Time::UNIX_TIMESTAMP_FORMAT);
} else {
- var_dump($dateOrTime);
- debug_print_backtrace(0, 6);
- die("date or time unexpected object");
+ return 0;
}
}
@@ -59,8 +57,12 @@ class StateBalance extends Entity
// 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->convertToTimestamp($this->record_date));
+ $startDate = $this->convertToTimestamp($this->record_date);
+ if($startDate == 0) {
+ return $this->amount;
+ }
+
+ $decay_duration = intval(Time::now()->getTimestamp() - $startDate);
if($decay_duration === 0) {
return $this->amount;
}
diff --git a/community_server/src/Model/Table/AppTable.php b/community_server/src/Model/Table/AppTable.php
index 3a281afcc..138a7f949 100644
--- a/community_server/src/Model/Table/AppTable.php
+++ b/community_server/src/Model/Table/AppTable.php
@@ -1,5 +1,7 @@
schema()->truncateSql($this->connection());
+ $truncateCommands = $this->getSchema()->truncateSql($this->getConnection());
foreach ($truncateCommands as $truncateCommand) {
- $this->connection()->query($truncateCommand);
+ $this->getConnection()->query($truncateCommand);
}
+ $this->getConnection()->query('ALTER TABLE ' . $this->getSchema()->name() . ' AUTO_INCREMENT=1');
}
+ public function saveManyWithErrors($entities)
+ {
+ $save_results = $this->saveMany($entities);
+ // save all at once failed, no try one by one to get error message
+ if($save_results === false) {
+ foreach($entities as $entity) {
+ if(!$this->save($entity)) {
+ return ['success' => false, 'errors' => $entity->getErrors()];
+ }
+ }
+ } else {
+ return ['success' => true];
+ }
+ }
}
diff --git a/community_server/src/Model/Table/BlockchainTypesTable.php b/community_server/src/Model/Table/BlockchainTypesTable.php
index 252fb8fd7..3aa67a83d 100644
--- a/community_server/src/Model/Table/BlockchainTypesTable.php
+++ b/community_server/src/Model/Table/BlockchainTypesTable.php
@@ -84,18 +84,11 @@ class BlockchainTypesTable extends AppTable
];
$entities = $this->newEntities($entry_contents);
$this->truncate();
- $save_results = $this->saveMany($entities);
- $errors = [];
- foreach($save_results as $i => $result)
- {
- if(!$result) {
- $errors[] = $entities[$i]->getErrors();
- }
+ $save_results = $this->saveManyWithErrors($entities);
+ if(!$save_results['success']) {
+ $save_results['msg'] = 'error by saving default transaction types';
}
- if(count($errors) > 0) {
- return ['success' => false, 'msg' => 'error by saving blockchain types', 'errors' => $errors];
- }
- return ['success' => true];
+ return $save_results;
}
}
diff --git a/community_server/src/Model/Table/StateBalancesTable.php b/community_server/src/Model/Table/StateBalancesTable.php
index 87e961c5d..8ee3be193 100644
--- a/community_server/src/Model/Table/StateBalancesTable.php
+++ b/community_server/src/Model/Table/StateBalancesTable.php
@@ -91,25 +91,38 @@ class StateBalancesTable extends Table
return $rules;
}
- public static function calculateDecay($startBalance, FrozenTime $startDate, FrozenTime $endDate)
+ public function calculateDecay($startBalance, FrozenTime $startDate, FrozenTime $endDate, $withInterval = false)
{
$decayStartDate = self::getDecayStartDateCached();
// if no start decay block exist, we just return input
// if start date for decay is after enddate, we also just return input
if($decayStartDate === null || $decayStartDate >= $endDate) {
- return $startBalance;
+ if($withInterval) {
+ return ['balance' => $startBalance, 'interval' => new \DateInterval('PT0S')];
+ } else {
+ return $startBalance;
+ }
}
$state_balance = $this->newEntity();
$state_balance->amount = $startBalance;
+ $interval = null;
// if decay start date is before start date we calculate decay for full duration
if($decayStartDate < $startDate) {
$state_balance->record_date = $startDate;
+ $interval = $endDate->diff($startDate);
}
// if decay start in between start date and end date we caculcate decay from decay start time to end date
else {
$state_balance->record_date = $decayStartDate;
+ $interval = $endDate->diff($decayStartDate);
}
- return $state_balance->partDecay($endDate);
+ $decay = $state_balance->partDecay($endDate);
+ if($withInterval) {
+ return ['balance' => $decay, 'interval' => $interval];
+ } else {
+ return $decay;
+ }
+
}
diff --git a/community_server/src/Model/Table/TransactionTypesTable.php b/community_server/src/Model/Table/TransactionTypesTable.php
index 7669ff2b3..2ffd1e64c 100644
--- a/community_server/src/Model/Table/TransactionTypesTable.php
+++ b/community_server/src/Model/Table/TransactionTypesTable.php
@@ -55,7 +55,7 @@ class TransactionTypesTable extends AppTable
$validator
->scalar('name')
- ->maxLength('name', 24)
+ ->maxLength('name', 45)
->requirePresence('name', 'create')
->notEmptyString('name');
@@ -111,17 +111,10 @@ class TransactionTypesTable extends AppTable
];
$entities = $this->newEntities($entry_contents);
$this->truncate();
- $save_results = $this->saveMany($entities);
- $errors = [];
- foreach($save_results as $i => $result)
- {
- if(!$result) {
- $errors[] = $entities[$i]->getErrors();
- }
+ $save_results = $this->saveManyWithErrors($entities);
+ if(!$save_results['success']) {
+ $save_results['msg'] = 'error by saving default transaction types';
}
- if(count($errors) > 0) {
- return ['success' => false, 'msg' => 'error by saving transaction types', 'errors' => $errors];
- }
- return ['success' => true];
+ return $save_results;
}
}
diff --git a/community_server/src/Model/Table/TransactionsTable.php b/community_server/src/Model/Table/TransactionsTable.php
index 9ae2fe02a..5169129d7 100644
--- a/community_server/src/Model/Table/TransactionsTable.php
+++ b/community_server/src/Model/Table/TransactionsTable.php
@@ -1,12 +1,12 @@
0 && $decay == true)
- {
+ $prev = null;
+ if($i > 0 ) {
$prev = $stateUserTransactions[$i-1];
+ }
+ if($prev && $decay == true)
+ {
+
if($prev->balance > 0) {
// var_dump($stateUserTransactions);
$current = $su_transaction;
//echo "decay between " . $prev->transaction_id . " and " . $current->transaction_id . "
";
- $interval = $current->balance_date->diff($prev->balance_date);
- $state_balance->amount = $prev->balance;
- $state_balance->record_date = $prev->balance_date;
- $diff_amount = $state_balance->partDecay($current->balance_date);
-
+ $calculated_decay = $stateBalancesTable->calculateDecay($prev->balance, $prev->balance_date, $current->balance_date, true);
+
//echo $interval->format('%R%a days');
//echo "prev balance: " . $prev->balance . ", diff_amount: $diff_amount, summe: " . (-intval($prev->balance - $diff_amount)) . "
";
$final_transactions[] = [
'type' => 'decay',
- 'balance' => floatval(intval($prev->balance - $diff_amount)),
- 'decay_duration' => $interval->format('%a days, %H hours, %I minutes, %S seconds'),
+ 'balance' => floatval($prev->balance - $calculated_decay['balance']),
+ 'decay_duration' => $calculated_decay['interval']->format('%a days, %H hours, %I minutes, %S seconds'),
'memo' => ''
];
}
@@ -207,13 +208,16 @@ class TransactionsTable extends Table
echo "
";*/
if($su_transaction->transaction_type_id == 1) { // creation
$creation = $transaction->transaction_creation;
+ $balance = $stateBalancesTable->calculateDecay($creation->amount, $creation->target_date, $transaction->received);
+
$final_transactions[] = [
'name' => 'Gradido Akademie',
'type' => 'creation',
'transaction_id' => $transaction->id,
'date' => $transaction->received,// $creation->target_date,
'target_date' => $creation->target_date,
- 'balance' => $creation->amount,
+ 'creation_amount' => $creation->amount,
+ 'balance' => $balance,
'memo' => $transaction->memo
];
} else if($su_transaction->transaction_type_id == 2) { // transfer or send coins
@@ -253,12 +257,18 @@ class TransactionsTable extends Table
}
if($i == $stateUserTransactionsCount-1 && $decay == true) {
- $state_balance->amount = $su_transaction->balance;
- $state_balance->record_date = $su_transaction->balance_date;
+ $calculated_decay = $stateBalancesTable->calculateDecay(
+ $su_transaction->balance,
+ $su_transaction->balance_date, new FrozenTime(), true);
+ $decay_start_date = $stateBalancesTable->getDecayStartDateCached();
+ $duration = $su_transaction->balance_date->timeAgoInWords();
+ if($decay_start_date > $su_transaction->balance_date) {
+ $duration = $decay_start_date->timeAgoInWords();
+ }
$final_transactions[] = [
'type' => 'decay',
- 'balance' => floatval(intval($su_transaction->balance - $state_balance->decay)),
- 'decay_duration' => $su_transaction->balance_date->timeAgoInWords(),
+ 'balance' => floatval($su_transaction->balance - $calculated_decay['balance']),
+ 'decay_duration' => $duration,
'memo' => ''
];
}
@@ -337,12 +347,13 @@ class TransactionsTable extends Table
}
public function fillStateUserTransactions()
- {
+ {
$missing_transaction_ids = [];
$transaction_ids = $this
->find('all')
->select(['id', 'transaction_type_id'])
->order(['id'])
+ ->where(['transaction_type_id <' => 6])
->all()
;
$state_user_transaction_ids = $this->StateUserTransactions
@@ -422,21 +433,10 @@ class TransactionsTable extends Table
}
}
- $results = $this->StateUserTransactions->saveMany($finalEntities);
- $errors = [];
- foreach($results as $i => $res) {
- if($res == false) {
- $errors[] = $finalEntities[$i]->getErrors();
- }
+ $save_results = $this->StateUserTransactions->saveManyWithErrors($finalEntities);
+ if(!$save_results['success']) {
+ $save_results['msg'] = 'error by saving at least one state user transaction';
}
- if(count($errors) == 0) {
- $result = ['success' => true];
- } else {
- $result = ['success' => false, 'msg' => 'error by saving at least one state user transaction', 'errors' => $errors];
- }
-
-
-
- return $result;
+ return $save_results;
}
}
diff --git a/community_server/src/Template/AppRequests/list_transactions.ctp b/community_server/src/Template/AppRequests/list_transactions.ctp
index f829b5f16..28a76f2be 100644
--- a/community_server/src/Template/AppRequests/list_transactions.ctp
+++ b/community_server/src/Template/AppRequests/list_transactions.ctp
@@ -12,6 +12,9 @@ $body['gdtSum'] = $this->element('centToFloat', ['cent' => $body['gdtSum'], 'pre
foreach($body['transactions'] as $i => $transaction) {
$body['transactions'][$i]['balance'] = $this->element('centToFloat', ['cent' => $transaction['balance'], 'precision' => 4]);
+ if(isset($transaction['creation_amount'])) {
+ $body['transactions'][$i]['creation_amount'] = $this->element('centToFloat', ['cent' => $transaction['creation_amount'], 'precision' => 4]);
+ }
}
?>= json_encode($body) ?>
\ No newline at end of file
diff --git a/community_server/src/Template/Migrations/migrate.ctp b/community_server/src/Template/Migrations/migrate.ctp
index 4c191fb61..d345c9a90 100644
--- a/community_server/src/Template/Migrations/migrate.ctp
+++ b/community_server/src/Template/Migrations/migrate.ctp
@@ -10,7 +10,7 @@
Migrate from Version = $db_version ?>
= json_encode($result) ?>
diff --git a/docu/community-server.api.md b/docu/community-server.api.md index 9354bf232..5685c9586 100644 --- a/docu/community-server.api.md +++ b/docu/community-server.api.md @@ -23,13 +23,13 @@ Additional session can be provided as GET-Parameter ```json { "state":"success", - "balance":1590.60, + "balance":15906078, "decay":15873851, "decay_date":"2021-04-16T11:47:21+00:00" } ``` -- `balance` : balance describes gradido +- `balance` : balance describes gradido cents which are 4 digits behind the separator. A balance value of 174500 equals therefor 17,45 GDD - `decay` : balance with decay on it at the time in decay_date, so it is the precise balance of user at time of calling this function - `decay_date`: date and time for decay amount, should be the time and date of function call @@ -59,16 +59,32 @@ Assuming: session is valid { "state":"success", "transactions": [ + { + "type": "decay", + "balance": "14.74", + "decay_duration": "4 days, 2 hours ago", + "memo": "" + }, { "name": "Max Mustermann", "email": "Maxim Mustermann", "type": "send", "transaction_id": 2, "date": "2021-02-19T13:25:36+00:00", - "balance": 192.0, + "balance": 192, "memo": "a piece of cake :)", "pubkey": "038a6f93270dc57b91d76bf110ad3863fcb7d1b08e7692e793fcdb4467e5b6a7" - } + }, + { + "name": "Gradido Akademie", + "type": "creation", + "transaction_id": 10, + "date": "2021-04-15T11:19:45+00:00", + "target_date": "2021-02-01T00:00:00+00:00", + "creation_amount": "1000", + "balance": "1000", + "memo": "AGE Februar 2021" + } ], "transactionExecutingCount": 0, "count": 1, @@ -95,8 +111,11 @@ Transaction: - `receiver`: user has received gradidos from another user - `transaction_id`: id of transaction in db, in stage2 also the hedera sequence number of transaction - `date`: date of ordering transaction (booking date) -- `balance`: Gradido +- `balance`: Gradido as float, max 2 Nachkommastellen, by creation balance after subtract decay amount - `memo`: Details about transaction +- `decay_duration`: only for decay, time duration for decay calculation in english text +- `creation_amount`: only for creation transaction, created account before decay +- `target_date`: only by creation transaction, target date for creation, start time for decay calculation (if < as global decay start time) ## Creation transaction Makes a creation transaction to create new Gradido @@ -150,7 +169,6 @@ with - `session_id`: optional, only used if cookie GRADIDO_LOGIN not exist and no sesion_id in php session - `email` or `username` or `pubkey`: used to identify how gets the gradidos (email and username are only aliases for pubkey) - `amount`: gdd amount to transfer in gradido cent (10000000 = 1000,00 GDD) -- `target_date`: target date for creation, can be max 3 months before current date, but not after current date, allowed formats do you find here: https://pocoproject.org/docs/Poco.DateTimeFormat.html - `memo`: text for receiver, currently saved as clear text in blockchain - `auto_sign`: if set to true, transaction will be directly signed on login-server and proceed if needed signs are there if set to false, transaction must be signed after on `http://localhost/account/checkTransactions` @@ -245,3 +263,41 @@ Without auto-sign the transaction is pending on the login-server and waits for t // TODO Is this in line with our usability goals? // TODO Should this not be handled client side? + +# Klicktipp + +## Subscribe +Subscribe current logged in user to gradido newsletter + +### Request +`GET http://localhost/api/klicktipp_subscribe/[session_id]` +Parts symbolized by [] are optional + - session_id: session will be searched in php session and GRADIDO_LOGIN cookie and if not found use this + +### Response +Assuming: session is valid + +```json +{ + "state": "success", + "redirect_url": "