From 14324649c837a0a132a716a780864873da86cca0 Mon Sep 17 00:00:00 2001 From: Dario Rekowski on RockPI Date: Thu, 6 May 2021 14:52:59 +0000 Subject: [PATCH 01/14] update auto-generated transactions/add function to produce a transaction with valid txhash --- .../src/Controller/TransactionsController.php | 13 +++-- .../src/Model/Table/TransactionsTable.php | 54 +++++++++++++++++++ .../src/Template/Transactions/add.ctp | 3 +- 3 files changed, 65 insertions(+), 5 deletions(-) diff --git a/community_server/src/Controller/TransactionsController.php b/community_server/src/Controller/TransactionsController.php index 4f8e04c2b..90e78b7fb 100644 --- a/community_server/src/Controller/TransactionsController.php +++ b/community_server/src/Controller/TransactionsController.php @@ -313,15 +313,20 @@ class TransactionsController extends AppController if ($this->request->is('post')) { $transaction = $this->Transactions->patchEntity($transaction, $this->request->getData()); if ($this->Transactions->save($transaction)) { - $this->Flash->success(__('The transaction has been saved.')); - - return $this->redirect(['action' => 'index']); + $result = $this->Transactions->updateTxHash($transaction, 'start decay'); + if($result === true) { + $this->Flash->success(__('The transaction has been saved.')); + return $this->redirect(['action' => 'index']); + } else { + $this->Flash->error(__('Error by saving: ' . json_encode($result))); + } } $this->Flash->error(__('The transaction could not be saved. Please, try again.')); } $stateGroups = $this->Transactions->StateGroups->find('list', ['limit' => 200]); $transactionTypes = $this->Transactions->TransactionTypes->find('list', ['limit' => 200]); - $this->set(compact('transaction', 'stateGroups', 'transactionTypes')); + $blockchainTypes = $this->Transactions->BlockchainTypes->find('list'); + $this->set(compact('transaction', 'stateGroups', 'transactionTypes', 'blockchainTypes')); } /** diff --git a/community_server/src/Model/Table/TransactionsTable.php b/community_server/src/Model/Table/TransactionsTable.php index 893482e3f..fdd437076 100644 --- a/community_server/src/Model/Table/TransactionsTable.php +++ b/community_server/src/Model/Table/TransactionsTable.php @@ -266,4 +266,58 @@ class TransactionsTable extends Table return $final_transactions; } + + public function updateTxHash($transaction, $signatureMapString) + { + $transaction_id = $transaction->id; + $previousTxHash = null; + if($transaction_id > 1) { + try { + $previousTransaction = $this + ->find('all', ['contain' => false]) + ->select(['tx_hash']) + ->where(['id' => $transaction_id - 1]) + ->first(); + /*$previousTransaction = $transactionsTable->get($this->mTransactionID - 1, [ + 'contain' => false, + 'fields' => ['tx_hash'] + ]);*/ + } catch(Cake\Datasource\Exception\RecordNotFoundException $ex) { + return ['state' => 'error', 'msg' => 'previous transaction not found', 'details' => $ex->getMessage()]; + } + if(!$previousTransaction) { + // shouldn't occur + return ['state' => 'error', 'msg' => 'previous transaction not found']; + } + $previousTxHash = $previousTransaction->tx_hash; + } + try { + //$transactionEntity->received = $transactionsTable->get($transactionEntity->id, ['contain' => false, 'fields' => ['received']])->received; + $transaction->received = $this + ->find('all', ['contain' => false]) + ->where(['id' => $transaction->id]) + ->select(['received'])->first()->received; + } catch(Cake\Datasource\Exception\RecordNotFoundException $ex) { + return ['state' => 'error', 'msg' => 'current transaction not found in db', 'details' => $ex->getMessage()]; + } + + // calculate tx hash + // previous tx hash + id + received + sigMap as string + // Sodium use for the generichash function BLAKE2b today (11.11.2019), mabye change in the future + $state = \Sodium\crypto_generichash_init(); + //echo "prev hash: $previousTxHash\n"; + if($previousTxHash != null) { + \Sodium\crypto_generichash_update($state, stream_get_contents($previousTxHash)); + } + //echo "id: " . $transactionEntity->id . "\n"; + \Sodium\crypto_generichash_update($state, strval($transaction->id)); + //echo "received: " . $transactionEntity->received; + \Sodium\crypto_generichash_update($state, $transaction->received->i18nFormat('yyyy-MM-dd HH:mm:ss')); + \Sodium\crypto_generichash_update($state, $signatureMapString); + $transaction->tx_hash = \Sodium\crypto_generichash_final($state); + if ($this->save($transaction)) { + return true; + } + return ['state' => 'error', 'msg' => 'error by saving transaction', 'details' => $transaction->getErrors()]; + } } diff --git a/community_server/src/Template/Transactions/add.ctp b/community_server/src/Template/Transactions/add.ctp index 59782d944..012d82027 100644 --- a/community_server/src/Template/Transactions/add.ctp +++ b/community_server/src/Template/Transactions/add.ctp @@ -35,7 +35,8 @@ Form->control('state_group_id', ['options' => $stateGroups]); echo $this->Form->control('transaction_type_id', ['options' => $transactionTypes]); - echo $this->Form->control('received'); + echo $this->Form->control('memo', ['type' => 'textarea']); + echo $this->Form->control('blockchain_type_id', ['options' => $blockchainTypes]); ?> Form->button(__('Submit')) ?> From 4a982fc5753481beec22a5e34eeb87cd80b5f0d4 Mon Sep 17 00:00:00 2001 From: Dario Rekowski on RockPI Date: Thu, 6 May 2021 14:55:03 +0000 Subject: [PATCH 02/14] add new transaction type to setup script, by existing db please add the line by yourself! --- .../db/setup_db_tables/insert_transaction_types.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/community_server/db/setup_db_tables/insert_transaction_types.sql b/community_server/db/setup_db_tables/insert_transaction_types.sql index 02ef8374a..37919045d 100644 --- a/community_server/db/setup_db_tables/insert_transaction_types.sql +++ b/community_server/db/setup_db_tables/insert_transaction_types.sql @@ -6,5 +6,5 @@ INSERT INTO `transaction_types` (`id`, `name`, `text`) VALUES (5, 'group remove member', 'remove user from group, maybe he was moved elsewhere'), (6, 'hedera topic create', 'create new topic on hedera'), (7, 'hedera topic send message', 'send consensus message over hedera topic'), -(8, 'hedera account create', 'create new account on hedera for holding some founds with unencrypted keys'); - +(8, 'hedera account create', 'create new account on hedera for holding some founds with unencrypted keys'), +(9, 'decay start', 'signalize the starting point for decay calculation, allowed only once per chain'); From 0f29989c64273705fef81d8da2f317d96d6958da Mon Sep 17 00:00:00 2001 From: Dario Rekowski on RockPI Date: Fri, 7 May 2021 08:38:59 +0000 Subject: [PATCH 03/14] remove line, left over from stage1, led to wrong balance calculation --- community_server/src/Model/Transactions/TransactionBase.php | 1 - 1 file changed, 1 deletion(-) diff --git a/community_server/src/Model/Transactions/TransactionBase.php b/community_server/src/Model/Transactions/TransactionBase.php index a688daf02..7d1a1c18b 100644 --- a/community_server/src/Model/Transactions/TransactionBase.php +++ b/community_server/src/Model/Transactions/TransactionBase.php @@ -74,7 +74,6 @@ 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; From 5ed7b3e416bb5ddaa6914f24f9bf6a2b15651636 Mon Sep 17 00:00:00 2001 From: Dario Rekowski on RockPI Date: Mon, 10 May 2021 14:12:03 +0000 Subject: [PATCH 04/14] implement decay from start decay block ; --- .../src/Model/Table/StateBalancesTable.php | 63 ++++++++++++++----- .../src/Model/Table/TransactionsTable.php | 17 ++++- .../Model/Transactions/TransactionBase.php | 19 +++--- .../Transactions/TransactionCreation.php | 11 +++- 4 files changed, 84 insertions(+), 26 deletions(-) diff --git a/community_server/src/Model/Table/StateBalancesTable.php b/community_server/src/Model/Table/StateBalancesTable.php index 7564c30f2..4e91c2948 100644 --- a/community_server/src/Model/Table/StateBalancesTable.php +++ b/community_server/src/Model/Table/StateBalancesTable.php @@ -1,14 +1,12 @@ 'INNER' ]); } + + public static function getDecayStartDateCached() + { + if(self::$startDecayDate == null) { + $transactionsTable = TableRegistry::getTableLocator()->get('Transactions'); + self::$startDecayDate = $transactionsTable->getDecayStartDate(); + } + return self::$startDecayDate; + } /** * Default validation rules. @@ -83,20 +91,33 @@ class StateBalancesTable extends Table return $rules; } - - public function sortTransactions($a, $b) + public static function calculateDecay($startBalance, FrozenTime $startDate, FrozenTime $endDate) { - if ($a['date'] == $b['date']) { - return 0; + $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; } - return ($a['date'] > $b['date']) ? -1 : 1; + $state_balance = $this->newEntity(); + $state_balance->amount = $startBalance; + // if decay start date is before start date we calculate decay for full duration + if($decayStartDate < $startDate) { + $state_balance->record_date = $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; + } + return $state_balance->partDecay($endDate); + } - public function updateBalances($stateUserId) { $stateUserTransactionsTable = TableRegistry::getTableLocator()->get('StateUserTransactions'); $transactionsTable = TableRegistry::getTableLocator()->get('Transactions'); + $now = new FrozenTime; // info: cakephp use lazy loading, query will be executed later only if needed $state_balances = $this->find('all')->where(['state_user_id' => $stateUserId]); $state_user_transactions = $stateUserTransactionsTable @@ -128,18 +149,26 @@ class StateBalancesTable extends Table if($state_user_transactions->count() == 0){ $clear_state_balance = true; } else { + + $first_state_balance = $state_balances->first(); + $first_state_balance_decayed = self::calculateDecay( + $first_state_balance->amount, + $first_state_balance->record_date, + $now); + $last_state_user_transaction = $state_user_transactions->last(); - $last_transaction = $this->newEntity(); - $last_transaction->amount = $last_state_user_transaction->balance; - $last_transaction->record_date = $last_state_user_transaction->balance_date; + $last_state_user_transaction_decayed = self::calculateDecay( + $last_state_user_transaction->balance, + $last_state_user_transaction->balance_date, + $now); // if entrys are nearly the same, we don't need doing anything - if(abs($last_transaction->decay - $state_balances->first()->decay) > 100) { + if(abs($last_state_user_transaction_decayed - $first_state_balance_decayed) > 100) { $recalculate_state_user_transactions_balance = true; $update_state_balance = true; } } } - + if(!$recalculate_state_user_transactions_balance) { $last_state_user_transaction = $state_user_transactions->last(); if($last_state_user_transaction && $last_state_user_transaction->balance <= 0) { @@ -223,7 +252,11 @@ class StateBalancesTable extends Table if($i == 0) { $balance_cursor->amount = $amount; } else { - $balance_cursor->amount = $balance_cursor->partDecay($amount_date) + $amount; + + //$balance_cursor->amount = $balance_cursor->partDecay($amount_date) + $amount; + $balance_cursor->amount = + $this->calculateDecay($balance_cursor->amount, $balance_cursor->recordDate, $amount_date) + + $amount; } //echo "new balance: " . $balance_cursor->amount . "
"; diff --git a/community_server/src/Model/Table/TransactionsTable.php b/community_server/src/Model/Table/TransactionsTable.php index fdd437076..71d301722 100644 --- a/community_server/src/Model/Table/TransactionsTable.php +++ b/community_server/src/Model/Table/TransactionsTable.php @@ -211,7 +211,8 @@ class TransactionsTable extends Table 'name' => 'Gradido Akademie', 'type' => 'creation', 'transaction_id' => $transaction->id, - 'date' => $creation->target_date, + 'date' => $transaction->received,// $creation->target_date, + 'target_date' => $creation->target_date, 'balance' => $creation->amount, 'memo' => $transaction->memo ]; @@ -320,4 +321,18 @@ class TransactionsTable extends Table } return ['state' => 'error', 'msg' => 'error by saving transaction', 'details' => $transaction->getErrors()]; } + + /*! + * @return: false if no decay start block found + * @return: DateTime Object with start date if one start block found + * @return: ['state':'error'] if more than one found + */ + public function getDecayStartDate() + { + $transaction = $this->find()->where(['transaction_type_id' => 9])->select(['received'])->order(['received' => 'ASC']); + if($transaction->count() == 0) { + return null; + } + return $transaction->first()->received; + } } diff --git a/community_server/src/Model/Transactions/TransactionBase.php b/community_server/src/Model/Transactions/TransactionBase.php index 7d1a1c18b..1f80cc687 100644 --- a/community_server/src/Model/Transactions/TransactionBase.php +++ b/community_server/src/Model/Transactions/TransactionBase.php @@ -72,8 +72,11 @@ class TransactionBase { //debug($stateBalanceQuery); if($stateBalanceQuery->count() > 0) { + $stateBalanceEntry = $stateBalanceQuery->first(); - $stateBalanceEntry->amount = $stateBalanceEntry->partDecay($recordDate) + $addAmountCent; + $stateBalanceEntry->amount = + $stateBalancesTable->calculateDecay($stateBalanceEntry->amount, $stateBalanceEntry->record_date, $recordDate) + + $addAmountCent; } else { $stateBalanceEntry = $stateBalancesTable->newEntity(); $stateBalanceEntry->state_user_id = $stateUserId; @@ -92,11 +95,12 @@ class TransactionBase { protected function addStateUserTransaction($stateUserId, $transactionId, $transactionTypeId, $balance, $balance_date) { $stateUserTransactionTable = self::getTable('state_user_transactions'); + $stateUserTransactions = $stateUserTransactionTable ->find('all') ->where(['state_user_id' => $stateUserId]) ->order(['transaction_id DESC']); - + $new_balance = $balance; if($stateUserTransactions->count() > 0) { $stateBalanceTable = self::getTable('state_balances'); $state_user_transaction = $stateUserTransactions->first(); @@ -104,16 +108,17 @@ class TransactionBase { $this->addError('TransactionBase::addStateUserTransaction', 'state_user_transaction is zero, no first entry exist?'); return false; } - $balance_entity = $stateBalanceTable->newEntity(); - $balance_entity->amount = $state_user_transaction->balance; - $balance_entity->record_date = $state_user_transaction->balance_date; - $balance = $balance_entity->decay + $balance; + $new_balance += $stateBalanceTable->calculateDecay( + $state_user_transaction->balance, + $state_user_transaction->balance_date, + $balance_date + ); } $entity = $stateUserTransactionTable->newEntity(); $entity->state_user_id = $stateUserId; $entity->transaction_id = $transactionId; $entity->transaction_type_id = $transactionTypeId; - $entity->balance = $balance; + $entity->balance = $new_balance; $entity->balance_date = $balance_date; if(!$stateUserTransactionTable->save($entity)) { diff --git a/community_server/src/Model/Transactions/TransactionCreation.php b/community_server/src/Model/Transactions/TransactionCreation.php index 6aeddd955..63b886a3f 100644 --- a/community_server/src/Model/Transactions/TransactionCreation.php +++ b/community_server/src/Model/Transactions/TransactionCreation.php @@ -138,8 +138,9 @@ class TransactionCreation extends TransactionBase { return true; } - public function save($transaction_id, $firstPublic) + public function save($transaction_id, $firstPublic, $received) { + $stateBalancesTable = self::getTable('stateBalances'); $transactionCreationEntity = $this->transactionCreationsTable->newEntity(); $transactionCreationEntity->transaction_id = $transaction_id; @@ -151,23 +152,27 @@ class TransactionCreation extends TransactionBase { $this->addError('TransactionCreation::save', 'couldn\'t get state user id'); return false; } + $transactionCreationEntity->state_user_id = $receiverUserId; $transactionCreationEntity->amount = $this->getAmount(); $transactionCreationEntity->target_date = $this->protoTransactionCreation->getTargetDate()->getSeconds(); $target_date = new FrozenTime($transactionCreationEntity->target_date); + + $decayed_balance = $stateBalancesTable->calculateDecay($this->getAmount(), $target_date, $received); + if(!$this->transactionCreationsTable->save($transactionCreationEntity)) { $this->addError('TransactionCreation::save', 'error saving transactionCreation with errors: ' . json_encode($transactionCreationEntity->getErrors())); return false; } // update state balance - $final_balance = $this->updateStateBalance($receiverUserId, $this->getAmount(), $target_date); + $final_balance = $this->updateStateBalance($receiverUserId, $decayed_balance, $received); if(false === $final_balance) { return false; } // decay is a virtual field which is calculated from amount and now() - record_date - if(!$this->addStateUserTransaction($receiverUserId, $transaction_id, 1, $this->getAmount(), $target_date)) { + if(!$this->addStateUserTransaction($receiverUserId, $transaction_id, 1, $decayed_balance, $received)) { return false; } From b29c3916262ba95eb529d69e597661ec3140acbf Mon Sep 17 00:00:00 2001 From: Dario Rekowski on RockPI Date: Mon, 10 May 2021 14:13:21 +0000 Subject: [PATCH 05/14] ignore skeema local config files from now on --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 5c23ad8bd..c8c581e51 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.log /node_modules/* .vscode +.skeema From 40a9a8c2b587f5bef0fcc54136ed7bd13dd91b2b Mon Sep 17 00:00:00 2001 From: Dario Rekowski on RockPI Date: Mon, 10 May 2021 14:14:48 +0000 Subject: [PATCH 06/14] add migrations table for automatic table data migration --- .../skeema/gradido_community/migrations.sql | 5 + .../src/Controller/MigrationsController.php | 106 ++++++++++++++++++ .../src/Model/Entity/Migration.php | 26 +++++ .../src/Model/Table/MigrationsTable.php | 56 +++++++++ .../src/Template/Migrations/add.ctp | 23 ++++ .../src/Template/Migrations/edit.ctp | 29 +++++ .../src/Template/Migrations/index.ctp | 47 ++++++++ .../src/Template/Migrations/view.ctp | 28 +++++ .../tests/Fixture/MigrationsFixture.php | 44 ++++++++ .../Controller/MigrationsControllerTest.php | 75 +++++++++++++ .../Model/Table/MigrationsTableTest.php | 72 ++++++++++++ 11 files changed, 511 insertions(+) create mode 100644 community_server/db/skeema/gradido_community/migrations.sql create mode 100644 community_server/src/Controller/MigrationsController.php create mode 100644 community_server/src/Model/Entity/Migration.php create mode 100644 community_server/src/Model/Table/MigrationsTable.php create mode 100644 community_server/src/Template/Migrations/add.ctp create mode 100644 community_server/src/Template/Migrations/edit.ctp create mode 100644 community_server/src/Template/Migrations/index.ctp create mode 100644 community_server/src/Template/Migrations/view.ctp create mode 100644 community_server/tests/Fixture/MigrationsFixture.php create mode 100644 community_server/tests/TestCase/Controller/MigrationsControllerTest.php create mode 100644 community_server/tests/TestCase/Model/Table/MigrationsTableTest.php diff --git a/community_server/db/skeema/gradido_community/migrations.sql b/community_server/db/skeema/gradido_community/migrations.sql new file mode 100644 index 000000000..7665bcf29 --- /dev/null +++ b/community_server/db/skeema/gradido_community/migrations.sql @@ -0,0 +1,5 @@ +CREATE TABLE `migrations` ( + `id` int UNSIGNED NOT NULL AUTO_INCREMENT, + `db_version` int DEFAULT 0, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/community_server/src/Controller/MigrationsController.php b/community_server/src/Controller/MigrationsController.php new file mode 100644 index 000000000..93a1b8044 --- /dev/null +++ b/community_server/src/Controller/MigrationsController.php @@ -0,0 +1,106 @@ +paginate($this->Migrations); + + $this->set(compact('migrations')); + } + + /** + * View method + * + * @param string|null $id Migration id. + * @return \Cake\Http\Response|null + * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found. + */ + public function view($id = null) + { + $migration = $this->Migrations->get($id, [ + 'contain' => [], + ]); + + $this->set('migration', $migration); + } + + /** + * Add method + * + * @return \Cake\Http\Response|null Redirects on successful add, renders view otherwise. + */ + public function add() + { + $migration = $this->Migrations->newEntity(); + if ($this->request->is('post')) { + $migration = $this->Migrations->patchEntity($migration, $this->request->getData()); + if ($this->Migrations->save($migration)) { + $this->Flash->success(__('The migration has been saved.')); + + return $this->redirect(['action' => 'index']); + } + $this->Flash->error(__('The migration could not be saved. Please, try again.')); + } + $this->set(compact('migration')); + } + + /** + * Edit method + * + * @param string|null $id Migration 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) + { + $migration = $this->Migrations->get($id, [ + 'contain' => [], + ]); + if ($this->request->is(['patch', 'post', 'put'])) { + $migration = $this->Migrations->patchEntity($migration, $this->request->getData()); + if ($this->Migrations->save($migration)) { + $this->Flash->success(__('The migration has been saved.')); + + return $this->redirect(['action' => 'index']); + } + $this->Flash->error(__('The migration could not be saved. Please, try again.')); + } + $this->set(compact('migration')); + } + + /** + * Delete method + * + * @param string|null $id Migration 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']); + $migration = $this->Migrations->get($id); + if ($this->Migrations->delete($migration)) { + $this->Flash->success(__('The migration has been deleted.')); + } else { + $this->Flash->error(__('The migration could not be deleted. Please, try again.')); + } + + return $this->redirect(['action' => 'index']); + } +} diff --git a/community_server/src/Model/Entity/Migration.php b/community_server/src/Model/Entity/Migration.php new file mode 100644 index 000000000..700136cf8 --- /dev/null +++ b/community_server/src/Model/Entity/Migration.php @@ -0,0 +1,26 @@ + true, + ]; +} diff --git a/community_server/src/Model/Table/MigrationsTable.php b/community_server/src/Model/Table/MigrationsTable.php new file mode 100644 index 000000000..b5cb42154 --- /dev/null +++ b/community_server/src/Model/Table/MigrationsTable.php @@ -0,0 +1,56 @@ +setTable('migrations'); + $this->setDisplayField('id'); + $this->setPrimaryKey('id'); + } + + /** + * 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'); + + $validator + ->integer('db_version') + ->allowEmptyString('db_version'); + + return $validator; + } +} diff --git a/community_server/src/Template/Migrations/add.ctp b/community_server/src/Template/Migrations/add.ctp new file mode 100644 index 000000000..94a555733 --- /dev/null +++ b/community_server/src/Template/Migrations/add.ctp @@ -0,0 +1,23 @@ + + +
+ Form->create($migration) ?> +
+ + Form->control('db_version'); + ?> +
+ Form->button(__('Submit')) ?> + Form->end() ?> +
diff --git a/community_server/src/Template/Migrations/edit.ctp b/community_server/src/Template/Migrations/edit.ctp new file mode 100644 index 000000000..1e916afa1 --- /dev/null +++ b/community_server/src/Template/Migrations/edit.ctp @@ -0,0 +1,29 @@ + + +
+ Form->create($migration) ?> +
+ + Form->control('db_version'); + ?> +
+ Form->button(__('Submit')) ?> + Form->end() ?> +
diff --git a/community_server/src/Template/Migrations/index.ctp b/community_server/src/Template/Migrations/index.ctp new file mode 100644 index 000000000..9d755ecff --- /dev/null +++ b/community_server/src/Template/Migrations/index.ctp @@ -0,0 +1,47 @@ + + +
+

+ + + + + + + + + + + + + + + + + +
Paginator->sort('id') ?>Paginator->sort('db_version') ?>
Number->format($migration->id) ?>Number->format($migration->db_version) ?> + Html->link(__('View'), ['action' => 'view', $migration->id]) ?> + Html->link(__('Edit'), ['action' => 'edit', $migration->id]) ?> + Form->postLink(__('Delete'), ['action' => 'delete', $migration->id], ['confirm' => __('Are you sure you want to delete # {0}?', $migration->id)]) ?> +
+
+
    + Paginator->first('<< ' . __('first')) ?> + Paginator->prev('< ' . __('previous')) ?> + Paginator->numbers() ?> + Paginator->next(__('next') . ' >') ?> + Paginator->last(__('last') . ' >>') ?> +
+

Paginator->counter(['format' => __('Page {{page}} of {{pages}}, showing {{current}} record(s) out of {{count}} total')]) ?>

+
+
diff --git a/community_server/src/Template/Migrations/view.ctp b/community_server/src/Template/Migrations/view.ctp new file mode 100644 index 000000000..dc4c5ded3 --- /dev/null +++ b/community_server/src/Template/Migrations/view.ctp @@ -0,0 +1,28 @@ + + +
+

id) ?>

+ + + + + + + + + +
Number->format($migration->id) ?>
Number->format($migration->db_version) ?>
+
diff --git a/community_server/tests/Fixture/MigrationsFixture.php b/community_server/tests/Fixture/MigrationsFixture.php new file mode 100644 index 000000000..1fab6a133 --- /dev/null +++ b/community_server/tests/Fixture/MigrationsFixture.php @@ -0,0 +1,44 @@ + ['type' => 'integer', 'length' => 10, 'unsigned' => true, 'null' => false, 'default' => null, 'comment' => '', 'autoIncrement' => true, 'precision' => null], + 'db_version' => ['type' => 'integer', 'length' => 11, 'unsigned' => false, 'null' => true, 'default' => '0', 'comment' => '', 'precision' => null, 'autoIncrement' => null], + '_constraints' => [ + 'primary' => ['type' => 'primary', 'columns' => ['id'], 'length' => []], + ], + '_options' => [ + 'engine' => 'InnoDB', + 'collation' => 'utf8mb4_unicode_ci' + ], + ]; + // @codingStandardsIgnoreEnd + /** + * Init method + * + * @return void + */ + public function init() + { + $this->records = [ + [ + 'id' => 1, + 'db_version' => 1, + ], + ]; + parent::init(); + } +} diff --git a/community_server/tests/TestCase/Controller/MigrationsControllerTest.php b/community_server/tests/TestCase/Controller/MigrationsControllerTest.php new file mode 100644 index 000000000..4bb794d4d --- /dev/null +++ b/community_server/tests/TestCase/Controller/MigrationsControllerTest.php @@ -0,0 +1,75 @@ +markTestIncomplete('Not implemented yet.'); + } + + /** + * Test view method + * + * @return void + */ + public function testView() + { + $this->markTestIncomplete('Not implemented yet.'); + } + + /** + * Test add method + * + * @return void + */ + public function testAdd() + { + $this->markTestIncomplete('Not implemented yet.'); + } + + /** + * Test edit method + * + * @return void + */ + public function testEdit() + { + $this->markTestIncomplete('Not implemented yet.'); + } + + /** + * Test delete method + * + * @return void + */ + public function testDelete() + { + $this->markTestIncomplete('Not implemented yet.'); + } +} diff --git a/community_server/tests/TestCase/Model/Table/MigrationsTableTest.php b/community_server/tests/TestCase/Model/Table/MigrationsTableTest.php new file mode 100644 index 000000000..f88893585 --- /dev/null +++ b/community_server/tests/TestCase/Model/Table/MigrationsTableTest.php @@ -0,0 +1,72 @@ +exists('Migrations') ? [] : ['className' => MigrationsTable::class]; + $this->Migrations = TableRegistry::getTableLocator()->get('Migrations', $config); + } + + /** + * tearDown method + * + * @return void + */ + public function tearDown() + { + unset($this->Migrations); + + parent::tearDown(); + } + + /** + * Test initialize method + * + * @return void + */ + public function testInitialize() + { + $this->markTestIncomplete('Not implemented yet.'); + } + + /** + * Test validationDefault method + * + * @return void + */ + public function testValidationDefault() + { + $this->markTestIncomplete('Not implemented yet.'); + } +} From d9d78d1539c638696ff1bffaf84e6112d6fed05f Mon Sep 17 00:00:00 2001 From: Dario Rekowski on RockPI Date: Mon, 10 May 2021 15:21:02 +0000 Subject: [PATCH 07/14] fill migration controller, update some other functions to using same result format --- .../src/Controller/AppController.php | 16 +++ .../src/Controller/MigrationsController.php | 47 ++++++++ .../Controller/StateBalancesController.php | 2 +- community_server/src/Model/Table/AppTable.php | 23 ++++ .../src/Model/Table/StateBalancesTable.php | 39 +++---- .../Table/StateUserTransactionsTable.php | 2 +- .../src/Model/Table/TransactionsTable.php | 104 ++++++++++++++++++ .../src/Template/Migrations/migrate.ctp | 18 +++ 8 files changed, 230 insertions(+), 21 deletions(-) create mode 100644 community_server/src/Model/Table/AppTable.php create mode 100644 community_server/src/Template/Migrations/migrate.ctp diff --git a/community_server/src/Controller/AppController.php b/community_server/src/Controller/AppController.php index 1cdcf4418..80690b238 100644 --- a/community_server/src/Controller/AppController.php +++ b/community_server/src/Controller/AppController.php @@ -156,8 +156,24 @@ class AppController extends Controller } } + protected function checkForMigration($html = true) + { + $migrationsTable = TableRegistry::getTableLocator()->get('Migrations'); + $last_migration = $migrationsTable->find()->last(); + $current_db_version = 1; + if($last_migration) { + $current_db_version = $last_migration->db_version; + } + $php_data_version = 2; + if($current_db_version < $php_data_version) { + $this->redirect(['controller' => 'Migrations', 'action' => 'migrate', $html, $current_db_version]); + } + } + + protected function requestLogin($sessionId = 0, $redirect = true) { + $this->checkForMigration($redirect); $session = $this->getRequest()->getSession(); // check login // disable encryption for cookies diff --git a/community_server/src/Controller/MigrationsController.php b/community_server/src/Controller/MigrationsController.php index 93a1b8044..c2febef0f 100644 --- a/community_server/src/Controller/MigrationsController.php +++ b/community_server/src/Controller/MigrationsController.php @@ -2,6 +2,7 @@ namespace App\Controller; use App\Controller\AppController; +use Cake\ORM\TableRegistry; /** * Migrations Controller @@ -23,6 +24,52 @@ class MigrationsController extends AppController $this->set(compact('migrations')); } + + protected function callFunctions(array $callables) + { + foreach($callables as $callable) { + $result = call_user_func($callable); + if(!$result['success']) { + return $result; + } + } + return ['success' => true]; + } + + public function migrate($html, $current_db_version) + { + $startTime = microtime(true); + $stateUserTransactionsTable = TableRegistry::getTableLocator()->get('StateUserTransactions'); + $transactionsTable = TableRegistry::getTableLocator()->get('Transactions'); + $stateBalancesTable = TableRegistry::getTableLocator()->get('StateBalances'); + + $new_db_version = 1; + + $commands = []; + // migrate from version 1 to 2 + if($current_db_version == 1) { + $stateUserTransactionsTable->truncate(); + $commands = [ + [$transactionsTable, 'fillStateUserTransactions'], + [$stateBalancesTable, 'updateAllBalances'] + ]; + $new_db_version = 2; + } + + $migration_result = $this->callFunctions($commands); + if($migration_result['success']) { + $migration_entity = $this->Migrations->newEntity(); + $migration_entity->db_version = $new_db_version; + $this->Migrations->save($migration_entity); + } + if(!$html) { + return $this->returnJson($migration_result); + } else { + $this->set('db_version', $current_db_version); + $this->set('result', $migration_result); + $this->set('timeUsed', microtime(true) - $startTime); + } + } /** * View method diff --git a/community_server/src/Controller/StateBalancesController.php b/community_server/src/Controller/StateBalancesController.php index 3994b989a..655dbc026 100644 --- a/community_server/src/Controller/StateBalancesController.php +++ b/community_server/src/Controller/StateBalancesController.php @@ -62,7 +62,7 @@ class StateBalancesController extends AppController $user = $session->read('StateUser'); $update_balance_result = $this->StateBalances->updateBalances($user['id']); - if($update_balance_result !== true) { + if($update_balance_result['success'] !== true) { $this->addAdminError('StateBalances', 'overview', $update_balance_result, $user['id']); } // sendRequestGDT diff --git a/community_server/src/Model/Table/AppTable.php b/community_server/src/Model/Table/AppTable.php new file mode 100644 index 000000000..3a281afcc --- /dev/null +++ b/community_server/src/Model/Table/AppTable.php @@ -0,0 +1,23 @@ +schema()->truncateSql($this->connection()); + foreach ($truncateCommands as $truncateCommand) { + $this->connection()->query($truncateCommand); + } + } +} diff --git a/community_server/src/Model/Table/StateBalancesTable.php b/community_server/src/Model/Table/StateBalancesTable.php index 4e91c2948..87e961c5d 100644 --- a/community_server/src/Model/Table/StateBalancesTable.php +++ b/community_server/src/Model/Table/StateBalancesTable.php @@ -113,6 +113,20 @@ class StateBalancesTable extends Table } + public function updateAllBalances() + { + $stateUserTable = TableRegistry::getTableLocator()->get('StateUsers'); + $state_users = $stateUserTable->find()->select(['id'])->contain([]); + foreach($state_users as $state_user) { + $result = $this->updateBalances($state_user->id); + if($result['success'] === false) { + $result['state_user_id'] = $state_user->id; + return $result; + } + } + return ['success' => true]; + } + public function updateBalances($stateUserId) { $stateUserTransactionsTable = TableRegistry::getTableLocator()->get('StateUserTransactions'); @@ -128,7 +142,7 @@ class StateBalancesTable extends Table ; if(!$state_user_transactions || !$state_user_transactions->count()) { - return true; + return ['success' => true]; } // first: decide what todo @@ -222,40 +236,27 @@ class StateBalancesTable extends Table $transaction = $transactions_indiced[$state_user_transaction->transaction_id]; if($transaction->transaction_type_id > 2) { continue; - } - //echo "transaction id: ".$transaction->id . "
"; - $amount_date = null; + } $amount = 0; if($transaction->transaction_type_id == 1) { // creation - $temp = $transaction->transaction_creation; - - /*$balance_temp = $this->newEntity(); - $balance_temp->amount = $temp->amount; - $balance_temp->record_date = $temp->target_date; - */ - $amount = intval($temp->amount);//$balance_temp->partDecay($transaction->received); - $amount_date = $temp->target_date; - - //$amount_date = + $amount = intval($transaction->transaction_creation->amount); } else if($transaction->transaction_type_id == 2) { // transfer - $temp = $transaction->transaction_send_coin; $amount = intval($temp->amount); // reverse if sender if($stateUserId == $temp->state_user_id) { $amount *= -1.0; } - $amount_date = $transaction->received; - } + $amount_date = $transaction->received; if($i == 0) { $balance_cursor->amount = $amount; } else { //$balance_cursor->amount = $balance_cursor->partDecay($amount_date) + $amount; $balance_cursor->amount = - $this->calculateDecay($balance_cursor->amount, $balance_cursor->recordDate, $amount_date) + $this->calculateDecay($balance_cursor->amount, $balance_cursor->record_date, $amount_date) + $amount; } //echo "new balance: " . $balance_cursor->amount . "
"; @@ -294,7 +295,7 @@ class StateBalancesTable extends Table return ['success' => false, 'error' => 'error saving state balance', 'details' => $state_balance->getErrors()]; } } - return true; + return ['success' => true]; } diff --git a/community_server/src/Model/Table/StateUserTransactionsTable.php b/community_server/src/Model/Table/StateUserTransactionsTable.php index 6cfe94a23..2c984d964 100644 --- a/community_server/src/Model/Table/StateUserTransactionsTable.php +++ b/community_server/src/Model/Table/StateUserTransactionsTable.php @@ -22,7 +22,7 @@ use Cake\Validation\Validator; * @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 +class StateUserTransactionsTable extends AppTable { /** * Initialize method diff --git a/community_server/src/Model/Table/TransactionsTable.php b/community_server/src/Model/Table/TransactionsTable.php index 71d301722..9ae2fe02a 100644 --- a/community_server/src/Model/Table/TransactionsTable.php +++ b/community_server/src/Model/Table/TransactionsTable.php @@ -335,4 +335,108 @@ class TransactionsTable extends Table } return $transaction->first()->received; } + + public function fillStateUserTransactions() + { + $missing_transaction_ids = []; + $transaction_ids = $this + ->find('all') + ->select(['id', 'transaction_type_id']) + ->order(['id']) + ->all() + ; + $state_user_transaction_ids = $this->StateUserTransactions + ->find('all') + ->select(['transaction_id']) + ->group(['transaction_id']) + ->order(['transaction_id']) + ->toArray() + ; + $i2 = 0; + $count = count($state_user_transaction_ids); + foreach($transaction_ids as $tr_id) { + //echo "$i1: "; + if($i2 >= $count) { + $missing_transaction_ids[] = $tr_id; + //echo "adding to missing: $tr_id, continue
"; + continue; + } + $stu_id = $state_user_transaction_ids[$i2]; + if($tr_id->id == $stu_id->transaction_id) { + $i2++; + //echo "after i2++: $i2
"; + } else if($tr_id->id < $stu_id->transaction_id) { + $missing_transaction_ids[] = $tr_id; + //echo "adding to missing: $tr_id
"; + } + } + + + $tablesForType = [ + 1 => $this->TransactionCreations, + 2 => $this->TransactionSendCoins, + 3 => $this->TransactionGroupCreates, + 4 => $this->TransactionGroupAddaddress, + 5 => $this->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; + } + $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->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->StateUserTransactions->saveMany($finalEntities); + $errors = []; + foreach($results as $i => $res) { + if($res == false) { + $errors[] = $finalEntities[$i]->getErrors(); + } + } + 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; + } } diff --git a/community_server/src/Template/Migrations/migrate.ctp b/community_server/src/Template/Migrations/migrate.ctp new file mode 100644 index 000000000..6ceeec81c --- /dev/null +++ b/community_server/src/Template/Migrations/migrate.ctp @@ -0,0 +1,18 @@ +

Migrate DB

+

Migrate from Version

+ +

Success

+ +

Error

+

+ +

Html->link('Back to Dashboard', ['controller' => 'Dashboard', 'action' => 'index']) ?>

+); From a22593925a15d00db3afbccb5cc7228f295fabd2 Mon Sep 17 00:00:00 2001 From: Dario Rekowski on RockPI Date: Mon, 10 May 2021 15:37:39 +0000 Subject: [PATCH 08/14] more migrations --- .../db/setup_db_tables/insert_migrations.sql | 2 + .../src/Controller/MigrationsController.php | 6 +- .../src/Model/Table/BlockchainTypesTable.php | 35 ++++++++++- .../src/Model/Table/TransactionTypesTable.php | 60 ++++++++++++++++++- 4 files changed, 100 insertions(+), 3 deletions(-) create mode 100644 community_server/db/setup_db_tables/insert_migrations.sql diff --git a/community_server/db/setup_db_tables/insert_migrations.sql b/community_server/db/setup_db_tables/insert_migrations.sql new file mode 100644 index 000000000..e6f38117d --- /dev/null +++ b/community_server/db/setup_db_tables/insert_migrations.sql @@ -0,0 +1,2 @@ +INSERT INTO `migrations` (`id`, `db_version`) VALUES +(1, 2); diff --git a/community_server/src/Controller/MigrationsController.php b/community_server/src/Controller/MigrationsController.php index c2febef0f..ddf02bfdc 100644 --- a/community_server/src/Controller/MigrationsController.php +++ b/community_server/src/Controller/MigrationsController.php @@ -41,7 +41,9 @@ class MigrationsController extends AppController $startTime = microtime(true); $stateUserTransactionsTable = TableRegistry::getTableLocator()->get('StateUserTransactions'); $transactionsTable = TableRegistry::getTableLocator()->get('Transactions'); + $transactionTypesTable = TableRegistry::getTableLocator()->get('TransactionTypes'); $stateBalancesTable = TableRegistry::getTableLocator()->get('StateBalances'); + $blockchainTypesTable = TableRegistry::getTableLocator()->get('BlockchainTypes'); $new_db_version = 1; @@ -51,7 +53,9 @@ class MigrationsController extends AppController $stateUserTransactionsTable->truncate(); $commands = [ [$transactionsTable, 'fillStateUserTransactions'], - [$stateBalancesTable, 'updateAllBalances'] + [$stateBalancesTable, 'updateAllBalances'], + [$blockchainTypesTable, 'fillWithDefault'], + [$transactionTypesTable, 'fillWithDefault'] ]; $new_db_version = 2; } diff --git a/community_server/src/Model/Table/BlockchainTypesTable.php b/community_server/src/Model/Table/BlockchainTypesTable.php index 90213ac9f..252fb8fd7 100644 --- a/community_server/src/Model/Table/BlockchainTypesTable.php +++ b/community_server/src/Model/Table/BlockchainTypesTable.php @@ -18,7 +18,7 @@ use Cake\Validation\Validator; * @method \App\Model\Entity\BlockchainType[] patchEntities($entities, array $data, array $options = []) * @method \App\Model\Entity\BlockchainType findOrCreate($search, callable $callback = null, $options = []) */ -class BlockchainTypesTable extends Table +class BlockchainTypesTable extends AppTable { /** * Initialize method @@ -65,4 +65,37 @@ class BlockchainTypesTable extends Table return $validator; } + + public function fillWithDefault() + { + $entry_contents = [ + [ + 'id' => 1, + 'name' => 'mysql', + 'text' => 'use mysql db as blockchain, work only with single community-server', + 'symbol' => NULL + ], + [ + 'id' => 2, + 'name' => 'hedera', + 'text' => 'use hedera for transactions', + 'symbol' => 'HBAR' + ] + ]; + $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(); + } + } + if(count($errors) > 0) { + return ['success' => false, 'msg' => 'error by saving blockchain types', 'errors' => $errors]; + } + return ['success' => true]; + + } } diff --git a/community_server/src/Model/Table/TransactionTypesTable.php b/community_server/src/Model/Table/TransactionTypesTable.php index 5cc842f5e..7669ff2b3 100644 --- a/community_server/src/Model/Table/TransactionTypesTable.php +++ b/community_server/src/Model/Table/TransactionTypesTable.php @@ -20,7 +20,7 @@ use Cake\Validation\Validator; * @method \App\Model\Entity\TransactionType[] patchEntities($entities, array $data, array $options = []) * @method \App\Model\Entity\TransactionType findOrCreate($search, callable $callback = null, $options = []) */ -class TransactionTypesTable extends Table +class TransactionTypesTable extends AppTable { /** * Initialize method @@ -66,4 +66,62 @@ class TransactionTypesTable extends Table return $validator; } + + public function fillWithDefault() + { + + $entry_contents = [ + [ + 'id' => 1, + 'name' => 'creation', + 'text' => 'create new gradidos for member and also for group (in development)', + ], [ + 'id' => 2, + 'name' => 'transfer', + 'text' => 'send gradidos from one member to another, also cross group transfer', + ], [ + 'id' => 3, + 'name' => 'group create', + 'text' => 'create a new group, trigger creation of new hedera topic and new blockchain on node server' + ], [ + 'id' => 4, + 'name' => 'group add member', + 'text' => 'add user to a group or move if he was already in a group' + ], [ + 'id' => 5, + 'name' => 'group remove member', + 'text' => 'remove user from group, maybe he was moved elsewhere' + ],[ + 'id' => 6, + 'name' => 'hedera topic create', + 'text' => 'create new topic on hedera' + ],[ + 'id' => 7, + 'name' => 'hedera topic send message', + 'text' => 'send consensus message over hedera topic' + ],[ + 'id' => 8, + 'name' => 'hedera account create', + 'text' => 'create new account on hedera for holding some founds with unencrypted keys' + ],[ + 'id' => 9, + 'name' => 'decay start', + 'text' => 'signalize the starting point for decay calculation, allowed only once per chain' + ] + ]; + $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(); + } + } + if(count($errors) > 0) { + return ['success' => false, 'msg' => 'error by saving transaction types', 'errors' => $errors]; + } + return ['success' => true]; + } } From 394bfb71ef2325b651572fe758f98a68e9e173a4 Mon Sep 17 00:00:00 2001 From: Dario Rekowski on RockPI Date: Mon, 10 May 2021 15:38:14 +0000 Subject: [PATCH 09/14] add missing template updates --- community_server/src/Template/Migrations/migrate.ctp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/community_server/src/Template/Migrations/migrate.ctp b/community_server/src/Template/Migrations/migrate.ctp index 6ceeec81c..4c191fb61 100644 --- a/community_server/src/Template/Migrations/migrate.ctp +++ b/community_server/src/Template/Migrations/migrate.ctp @@ -15,4 +15,4 @@

Html->link('Back to Dashboard', ['controller' => 'Dashboard', 'action' => 'index']) ?>

-); + From be26bf27587b891512067670e5a7ec150fecd61b Mon Sep 17 00:00:00 2001 From: Dario Rekowski on RockPI Date: Mon, 10 May 2021 17:59:34 +0000 Subject: [PATCH 10/14] tested and fixed bugs, update api docu --- .../gradido_community/transaction_types.sql | 2 +- .../src/Controller/AppController.php | 2 +- .../src/Controller/MigrationsController.php | 18 +++-- .../src/Model/Entity/StateBalance.php | 12 ++-- community_server/src/Model/Table/AppTable.php | 21 +++++- .../src/Model/Table/BlockchainTypesTable.php | 15 ++-- .../src/Model/Table/StateBalancesTable.php | 19 +++++- .../src/Model/Table/TransactionTypesTable.php | 17 ++--- .../src/Model/Table/TransactionsTable.php | 64 ++++++++--------- .../AppRequests/list_transactions.ctp | 3 + .../src/Template/Migrations/migrate.ctp | 2 +- docu/community-server.api.md | 68 +++++++++++++++++-- 12 files changed, 165 insertions(+), 78 deletions(-) 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]); + } } ?> \ 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

Success

- +

Error

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": "" +} +```` + +## 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" +} +```` + From 2dff5bdf314f0793a707117bfc1a1c9df3760876 Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Mon, 10 May 2021 20:14:14 +0200 Subject: [PATCH 11/14] update docu --- docu/community-server.api.md | 56 ++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/docu/community-server.api.md b/docu/community-server.api.md index 5685c9586..11556513b 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":15906078, - "decay":15873851, + "balance":1590.60, + "decay":1587.38, "decay_date":"2021-04-16T11:47:21+00:00" } ``` -- `balance` : balance describes gradido cents which are 4 digits behind the separator. A balance value of 174500 equals therefor 17,45 GDD +- `balance` : balance describes gradido as float with max two decimal places - `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,32 +59,32 @@ Assuming: session is valid { "state":"success", "transactions": [ - { - "type": "decay", - "balance": "14.74", - "decay_duration": "4 days, 2 hours ago", - "memo": "" - }, + { + "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, + "balance": 192.0, "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" - } + { + "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.0", + "balance": "1000.0", + "memo": "AGE Februar 2021" + } ], "transactionExecutingCount": 0, "count": 1, @@ -136,7 +136,7 @@ with { "session_id" : -127182, "email": "max.musterman@gmail.de", - "amount": 10000000, + "amount": 1000.0, "target_date":"2021-02-19T13:25:36+00:00", "memo":"AGE", "auto_sign": true @@ -147,7 +147,7 @@ with { "session_id" : -127182, "username": "Maxi_786", - "amount": 10000000, + "amount": 1000.0, "target_date":"2021-02-19T13:25:36+00:00", "memo":"AGE", "auto_sign": true @@ -158,7 +158,7 @@ with { "session_id" : -127182, "pubkey": "038a6f93270dc57b91d76bf110ad3863fcb7d1b08e7692e793fcdb4467e5b6a7", - "amount": 10000000, + "amount": 1000.0, "target_date":"2021-02-19T13:25:36+00:00", "memo":"AGE", "auto_sign": true @@ -168,7 +168,7 @@ 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) +- `amount`: gdd amount to transfer in gradido as float - `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` @@ -204,7 +204,7 @@ with { "session_id" : -127182, "email": "max.musterman@gmail.de", - "amount": 1000000, + "amount": 100.0, "memo":"a gift", "auto_sign": true } @@ -214,7 +214,7 @@ with { "session_id" : -127182, "username": "Maxi_786", - "amount": 1000000, + "amount": 100.0, "memo":"a gift", "auto_sign": true } @@ -224,13 +224,13 @@ with { "session_id" : -127182, "pubkey": "038a6f93270dc57b91d76bf110ad3863fcb7d1b08e7692e793fcdb4467e5b6a7", - "amount": 1000000, + "amount": 100.0, "memo":"a gift", "auto_sign": true } ``` - `session_id`: optional, only used if cookie GRADIDO_LOGIN not exist and no sesion_id in php session -- `amount`: amount to transfer, 2000000 = 200,00 GDD +- `amount`: amount to transfer as float - `email` or `username` or `pubkey`: used to identify how gets the gradidos (email and username are only aliases for pubkey) - `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 From f8e8b6e56e4b44b2e3f7e5a90f431c1257464fc8 Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Mon, 10 May 2021 20:17:10 +0200 Subject: [PATCH 12/14] ignore netbeans project files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index c8c581e51..44f403757 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /node_modules/* .vscode .skeema +nbproject \ No newline at end of file From 4733944f2fbbf80ca5be379347089193b84c47f4 Mon Sep 17 00:00:00 2001 From: Dario Rekowski on RockPI Date: Mon, 10 May 2021 18:57:10 +0000 Subject: [PATCH 13/14] fix bug in merged code --- .../src/Model/Table/TransactionsTable.php | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/community_server/src/Model/Table/TransactionsTable.php b/community_server/src/Model/Table/TransactionsTable.php index 3bccb7bbf..742ce7882 100644 --- a/community_server/src/Model/Table/TransactionsTable.php +++ b/community_server/src/Model/Table/TransactionsTable.php @@ -184,21 +184,21 @@ class TransactionsTable extends Table $current = $su_transaction; //echo "decay between " . $prev->transaction_id . " and " . $current->transaction_id . "
"; $calculated_decay = $stateBalancesTable->calculateDecay($prev->balance, $prev->balance_date, $current->balance_date, true); - $balance = floatval($prev->balance - $diff_amount); + $balance = floatval($prev->balance - $calculated_decay['balance']); // skip small decays (smaller than 0,00 GDD) if(abs($balance) >= 100) { - //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($prev->balance - $calculated_decay['balance']), - 'decay_duration' => $calculated_decay['interval']->format('%a days, %H hours, %I minutes, %S seconds'), - 'memo' => '' - ]; + //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' => $balance, + 'decay_duration' => $calculated_decay['interval']->format('%a days, %H hours, %I minutes, %S seconds'), + 'memo' => '' + ]; + } } } - } // sender or receiver when user has sended money // group name if creation @@ -269,17 +269,17 @@ class TransactionsTable extends Table if($decay_start_date > $su_transaction->balance_date) { $duration = $decay_start_date->timeAgoInWords(); } - $balance = floatval($su_transaction->balance - $state_balance->decay); + $balance = floatval($su_transaction->balance - $calculated_decay['balance']); if($balance > 100) { - $final_transactions[] = [ - 'type' => 'decay', - 'balance' => floatval($su_transaction->balance - $calculated_decay['balance']), - 'decay_duration' => $duration, - 'memo' => '' - ]; + $final_transactions[] = [ + 'type' => 'decay', + 'balance' => $balance, + 'decay_duration' => $duration, + 'memo' => '' + ]; + } } } - } return $final_transactions; From 2417cfa6ee5220e39e7ebeaa2a436c17eed17cb6 Mon Sep 17 00:00:00 2001 From: Dario Rekowski on RockPI Date: Tue, 11 May 2021 09:42:51 +0000 Subject: [PATCH 14/14] add Ulfs suggestion --- community_server/src/Model/Table/StateBalancesTable.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/community_server/src/Model/Table/StateBalancesTable.php b/community_server/src/Model/Table/StateBalancesTable.php index 8ee3be193..7e5f96be9 100644 --- a/community_server/src/Model/Table/StateBalancesTable.php +++ b/community_server/src/Model/Table/StateBalancesTable.php @@ -189,7 +189,7 @@ class StateBalancesTable extends Table $last_state_user_transaction->balance_date, $now); // if entrys are nearly the same, we don't need doing anything - if(abs($last_state_user_transaction_decayed - $first_state_balance_decayed) > 100) { + if(floor($last_state_user_transaction_decayed/100) !== floor($first_state_balance_decayed/100)) { $recalculate_state_user_transactions_balance = true; $update_state_balance = true; }