mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
tested and fixed bugs, update api docu
This commit is contained in:
parent
394bfb71ef
commit
be26bf2758
@ -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;
|
||||
|
||||
@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
<?php
|
||||
namespace App\Model\Table;
|
||||
|
||||
use Cake\ORM\Table;
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
@ -15,9 +17,24 @@ class AppTable extends Table
|
||||
|
||||
public function truncate()
|
||||
{
|
||||
$truncateCommands = $this->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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
<?php
|
||||
namespace App\Model\Table;
|
||||
|
||||
use Cake\ORM\Query;
|
||||
|
||||
use Cake\ORM\RulesChecker;
|
||||
use Cake\ORM\Table;
|
||||
use Cake\Validation\Validator;
|
||||
use Cake\ORM\TableRegistry;
|
||||
use Cake\I18n\Number;
|
||||
use Cake\I18n\FrozenTime;
|
||||
/**
|
||||
* Transactions Model
|
||||
*
|
||||
@ -172,24 +172,25 @@ class TransactionsTable extends Table
|
||||
//var_dump($su_transaction);
|
||||
//die("step");
|
||||
// add decay transactions
|
||||
if($i > 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 . "<br>";
|
||||
$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)) . "<br>";
|
||||
$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 "<br>";*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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) ?>
|
||||
@ -10,7 +10,7 @@
|
||||
<p>Migrate from Version <?= $db_version ?></p>
|
||||
<?php if($result['success']) : ?>
|
||||
<h3><success>Success</success></h3>
|
||||
<?php elseif : ?>
|
||||
<?php else : ?>
|
||||
<h3><error>Error</error></h3>
|
||||
<p><?= json_encode($result) ?></p>
|
||||
<?php endif; ?>
|
||||
|
||||
@ -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": "<redirect url from klicktipp>"
|
||||
}
|
||||
````
|
||||
|
||||
## Unsubscribe
|
||||
Unsubscribe current logged in user from gradido newsletter
|
||||
|
||||
### Request
|
||||
`GET http://localhost/api/klicktipp_unsubscribe/[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"
|
||||
}
|
||||
````
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user