diff --git a/src/Controller/StateBalancesController.php b/src/Controller/StateBalancesController.php index f280485bf..bfc9b6c57 100644 --- a/src/Controller/StateBalancesController.php +++ b/src/Controller/StateBalancesController.php @@ -39,7 +39,33 @@ class StateBalancesController extends AppController $this->set(compact('stateBalances')); } - + private function updateBalances($state_user_id) + { + $state_balances = $this->StateBalances->find('all')->where(['state_user_id' => $state_user_id]); + if($state_balances->count() == 1) { + $stateUserTransactionsTable = TableRegistry::getTableLocator()->get('StateUserTransactions'); + $state_user_transactions = $stateUserTransactionsTable + ->find('all') + ->where(['state_user_id' => $state_user_id]) + ->order(['transaction_id ASC']) + ->contain(['']); + if($state_user_transactions->count() == 0){ + return; + } + $last_state_user_transaction = $state_user_transactions->last(); + $last_transaction = $this->StateBalance->newEntity(); + $last_transaction->amount = $last_state_user_transaction->balance; + $last_transaction->record_date = $last_state_user_transaction->balance_date; + // if entrys are nearly the same, we don't need doing anything + if(abs($last_transaction->decay - $state_balances->decay) < 100) { + return; + } + foreach($state_user_transactions as $state_user_transaction) { + + } + + } + } public function overview() { diff --git a/src/Controller/TransactionsController.php b/src/Controller/TransactionsController.php index 2f0bc2747..4f8e04c2b 100644 --- a/src/Controller/TransactionsController.php +++ b/src/Controller/TransactionsController.php @@ -7,6 +7,7 @@ use Model\Transactions\Transaction; use Model\Transactions\TransactionBody; use Cake\Core\Configure; +use Cake\ORM\TableRegistry; /** * Transactions Controller @@ -40,6 +41,118 @@ class TransactionsController extends AppController $this->set(compact('transactions')); } + + public function synchronizeWithStateUserTransactions() + { + $startTime = microtime(true); + $missing_transaction_ids = []; + $transaction_ids = $this->Transactions + ->find('all') + ->select(['id', 'transaction_type_id']) + ->order(['id']) + ->all() + ; + $state_user_transaction_ids = $this->Transactions->StateUserTransactions + ->find('all') + ->select(['transaction_id']) + ->group(['transaction_id']) + ->order(['transaction_id']) + ->toArray() + ; + $i2 = 0; + $count1 = count($transaction_ids); + $count2 = count($state_user_transaction_ids); + foreach($transaction_ids as $i1 => $tr_id) { + //echo "$i1: "; + if($i2 >= $count2) { + $missing_transaction_ids[] = $tr_id; + //echo "adding to missing: $tr_id, continue
"; + 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
"; + } + } + + if($this->request->is('POST')) { + $tablesForType = [ + 1 => $this->Transactions->TransactionCreations, + 2 => $this->Transactions->TransactionSendCoins, + 3 => $this->Transactions->TransactionGroupCreates, + 4 => $this->Transactions->TransactionGroupAddaddress, + 5 => $this->Transactions->TransactionGroupAddaddress + ]; + $idsForType = []; + foreach($missing_transaction_ids as $i => $transaction) { + if(!isset($idsForType[$transaction->transaction_type_id])) { + $idsForType[$transaction->transaction_type_id] = []; + } + $idsForType[$transaction->transaction_type_id][] = $transaction->id; + if($i > 200) break; + } + $entities = []; + $state_user_ids = []; + foreach($idsForType as $type_id => $transaction_ids) { + $specific_transactions = $tablesForType[$type_id]->find('all')->where(['transaction_id IN' => $transaction_ids])->toArray(); + $keys = $tablesForType[$type_id]->getSchema()->columns(); + //var_dump($keys); + foreach($specific_transactions as $specific) { + + foreach($keys as $key) { + if(preg_match('/_user_id/', $key)) { + $entity = $this->Transactions->StateUserTransactions->newEntity(); + $entity->transaction_id = $specific['transaction_id']; + $entity->transaction_type_id = $type_id; + $entity->state_user_id = $specific[$key]; + if(!in_array($entity->state_user_id, $state_user_ids)) { + array_push($state_user_ids, $entity->state_user_id); + } + $entities[] = $entity; + } + } + } + } + //var_dump($entities); + $stateUsersTable = TableRegistry::getTableLocator()->get('StateUsers'); + $existingStateUsers = $stateUsersTable->find('all')->select(['id'])->where(['id IN' => $state_user_ids])->order(['id'])->all(); + $existing_state_user_ids = []; + $finalEntities = []; + foreach($existingStateUsers as $stateUser) { + $existing_state_user_ids[] = $stateUser->id; + } + foreach($entities as $entity) { + if(in_array($entity->state_user_id, $existing_state_user_ids)) { + array_push($finalEntities, $entity); + } + } + + + $results = $this->Transactions->StateUserTransactions->saveMany($finalEntities); + foreach($entities as $i => $entity) { + $errors = $entity->getErrors(); + /* if(count($errors)) { + echo "$i: "; + echo json_encode($errors); + echo "
"; + echo "state_user_id: " . $entity->state_user_id; + echo "
"; + }*/ + } + $this->set('results', $results); + $this->set('entities', $entities); + } + + $this->set('missing_transactions', $missing_transaction_ids); + $this->set('count1', $count1); + $this->set('count2', $count2); + $timeUsed = microtime(true) - $startTime; + $this->set('timeUsed', $timeUsed); + } /** * View method diff --git a/src/Model/Table/TransactionsTable.php b/src/Model/Table/TransactionsTable.php index 75659a5b2..6777070fe 100644 --- a/src/Model/Table/TransactionsTable.php +++ b/src/Model/Table/TransactionsTable.php @@ -73,6 +73,9 @@ class TransactionsTable extends Table $this->hasMany('TransactionSignatures', [ 'foreignKey' => 'transaction_id' ]); + $this->hasMany('StateUserTransactions', [ + 'foreignKey' => 'transaction_id' + ]); } /** diff --git a/src/Model/Transactions/TransactionBase.php b/src/Model/Transactions/TransactionBase.php index 12095a13c..80ce8ef5d 100644 --- a/src/Model/Transactions/TransactionBase.php +++ b/src/Model/Transactions/TransactionBase.php @@ -6,7 +6,7 @@ use Cake\ORM\TableRegistry; class TransactionBase { private $errors = []; - static $stateUsersTable = null; + static $tables = []; public function getErrors() { return $this->errors; @@ -24,18 +24,17 @@ class TransactionBase { return count($this->errors) > 0; } - public static function getStateUsersTable() - { - if(!self::$stateUsersTable) { - self::$stateUsersTable = TableRegistry::getTableLocator()->get('state_users'); + public static function getTable($tableName) { + if(!isset(self::$tables[$tableName])) { + self::$tables[$tableName] = TableRegistry::getTableLocator()->get($tableName); } - return self::$stateUsersTable; + return self::$tables[$tableName]; } protected function getStateUserId($publicKey) { - $stateUsersTable = self::getStateUsersTable(); + $stateUsersTable = self::getTable('state_users'); $stateUser = $stateUsersTable->find('all')->select(['id'])->where(['public_key' => $publicKey])->first(); if($stateUser) { return $stateUser->id; @@ -53,7 +52,7 @@ class TransactionBase { } protected function getStateUser($id) { - $stateUsersTable = self::getStateUsersTable(); + $stateUsersTable = self::getTable('state_users'); $stateUser = $stateUsersTable->get($id); if($stateUser) { return $stateUser; @@ -65,7 +64,7 @@ class TransactionBase { protected function updateStateBalance($stateUserId, $addAmountCent, $recordDate) { $finalBalance = 0; - $stateBalancesTable = TableRegistry::getTableLocator()->get('stateBalances'); + $stateBalancesTable = self::getTable('stateBalances'); $stateBalanceQuery = $stateBalancesTable ->find('all') ->select(['amount', 'id']) @@ -75,7 +74,7 @@ class TransactionBase { if($stateBalanceQuery->count() > 0) { $stateBalanceEntry = $stateBalanceQuery->first(); - //$stateBalanceEntry->amount = $stateBalanceEntry->partDecay($recordDate) + $addAmountCent;; + $stateBalanceEntry->amount = $stateBalanceEntry->partDecay($recordDate) + $addAmountCent; $stateBalanceEntry->amount += $addAmountCent; } else { $stateBalanceEntry = $stateBalancesTable->newEntity(); @@ -92,4 +91,32 @@ class TransactionBase { } return $finalBalance; } + + protected function addStateUserTransaction($stateUserId, $transactionId, $transactionTypeId, $balance) { + $stateUserTransactionTable = self::getTable('state_user_transactions'); + $stateUserTransactions = $stateUserTransactionTable + ->find('all') + ->where(['state_user_id' => $stateUserId]) + ->order(['transaction_id DESC']); + + if($stateUserTransactions->count() > 0) { + $stateBalanceTable = self::getTable('state_balances'); + $balance_entity = $stateBalanceTable->newEntity(); + $balance_entity->amount = $stateUserTransactions->first()->balance; + $balance_entity->record_date = $stateUserTransactions->first()->balance_date; + $balance = $balance_entity->decay + $balance; + } + $entity = $stateUserTransactionTable->newEntity(); + $entity->state_user_id = $stateUserId; + $entity->transaction_id = $transactionId; + $entity->transaction_type_id = $transactionTypeId; + $entity->balance = $balance; + + if(!$stateUserTransactionTable->save($entity)) { + $errors = $entity->getErrors(); + $this->addError('TransactionBase::addStateUserTransaction', 'error saving state user balance with: ' . json_encode($errors)); + return false; + } + return true; + } } \ No newline at end of file diff --git a/src/Model/Transactions/TransactionCreation.php b/src/Model/Transactions/TransactionCreation.php index e9feed4e9..cab8bbb5a 100644 --- a/src/Model/Transactions/TransactionCreation.php +++ b/src/Model/Transactions/TransactionCreation.php @@ -231,10 +231,19 @@ class TransactionCreation extends TransactionBase { } // update state balance - if(false === $this->updateStateBalance($receiverUserId, $this->getAmount(), $transactionCreationEntity->target_date)) { + $final_balance = $this->updateStateBalance($receiverUserId, $this->getAmount(), $transactionCreationEntity->target_date); + if(false === $final_balance) { return false; } - + $target_date = new DateTime($transactionCreationEntity->target_date); + $stateBalancesTable = self::getTable('stateBalances'); + $state_balance = $stateBalancesTable->newEntity(); + $state_balance->amount = $this->getAmount(); + $state_balance->record_date = $target_date; + // decay is a virtual field which is calculated from amount and now() - record_date + if(!$this->addStateUserTransaction($receiverUserId, $transaction_id, 1, $state_balance->decay)) { + return false; + } return true; } diff --git a/src/Model/Transactions/TransactionTransfer.php b/src/Model/Transactions/TransactionTransfer.php index d22dbadef..a509cf0f3 100644 --- a/src/Model/Transactions/TransactionTransfer.php +++ b/src/Model/Transactions/TransactionTransfer.php @@ -207,8 +207,12 @@ class TransactionTransfer extends TransactionBase { return false; } - - + if(!$this->addStateUserTransaction($senderUserId, $transaction_id, 2, $senderAmount->getAmount())) { + return false; + } + if(!$this->addStateUserTransaction($receiverUserId, $transaction_id, 2, -$senderAmount->getAmount())) { + return false; + } //$this->addError('TransactionTransfer::save', 'not implemented yet'); //return false; diff --git a/src/Template/Transactions/synchronize_with_state_user_transactions.ctp b/src/Template/Transactions/synchronize_with_state_user_transactions.ctp new file mode 100644 index 000000000..a4b48cb14 --- /dev/null +++ b/src/Template/Transactions/synchronize_with_state_user_transactions.ctp @@ -0,0 +1,46 @@ + +
+

Synchronize state_user_transactions with transactions

+

transactions count:

+

state_user_transaction count:

+

Missing count:

+

First 10 Missing ids:

+

$id) { + if($i > 10) break; + if($i > 0) echo ', '; + echo $id['id']; +} ?>

+ + +

Synchronize errors:

+ + + + Form->create() ?> + Form->button(__('Synchronize')) ?> + Form->end() ?> +