working on decay

This commit is contained in:
einhornimmond 2021-03-05 18:31:52 +01:00 committed by Ulf Gebhardt
parent 09fbce76e7
commit 91b4473ada
No known key found for this signature in database
GPG Key ID: 81308EFE29ABFEBD
7 changed files with 243 additions and 15 deletions

View File

@ -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()
{

View File

@ -7,6 +7,7 @@ use Model\Transactions\Transaction;
use Model\Transactions\TransactionBody;
use Cake\Core\Configure;
use Cake\ORM\TableRegistry;
/**
* Transactions Controller
@ -40,6 +41,118 @@ class TransactionsController extends AppController
$this->set(compact('transactions'));
}
public function synchronizeWithStateUserTransactions()
{
$startTime = microtime(true);
$missing_transaction_ids = [];
$transaction_ids = $this->Transactions
->find('all')
->select(['id', 'transaction_type_id'])
->order(['id'])
->all()
;
$state_user_transaction_ids = $this->Transactions->StateUserTransactions
->find('all')
->select(['transaction_id'])
->group(['transaction_id'])
->order(['transaction_id'])
->toArray()
;
$i2 = 0;
$count1 = count($transaction_ids);
$count2 = count($state_user_transaction_ids);
foreach($transaction_ids as $i1 => $tr_id) {
//echo "$i1: ";
if($i2 >= $count2) {
$missing_transaction_ids[] = $tr_id;
//echo "adding to missing: $tr_id, continue <br>";
continue;
}
$stu_id = $state_user_transaction_ids[$i2];
if($tr_id->id == $stu_id->transaction_id) {
$i2++;
//echo "after i2++: $i2<br>";
} else if($tr_id->id < $stu_id->transaction_id) {
$missing_transaction_ids[] = $tr_id;
//echo "adding to missing: $tr_id<br>";
}
}
if($this->request->is('POST')) {
$tablesForType = [
1 => $this->Transactions->TransactionCreations,
2 => $this->Transactions->TransactionSendCoins,
3 => $this->Transactions->TransactionGroupCreates,
4 => $this->Transactions->TransactionGroupAddaddress,
5 => $this->Transactions->TransactionGroupAddaddress
];
$idsForType = [];
foreach($missing_transaction_ids as $i => $transaction) {
if(!isset($idsForType[$transaction->transaction_type_id])) {
$idsForType[$transaction->transaction_type_id] = [];
}
$idsForType[$transaction->transaction_type_id][] = $transaction->id;
if($i > 200) break;
}
$entities = [];
$state_user_ids = [];
foreach($idsForType as $type_id => $transaction_ids) {
$specific_transactions = $tablesForType[$type_id]->find('all')->where(['transaction_id IN' => $transaction_ids])->toArray();
$keys = $tablesForType[$type_id]->getSchema()->columns();
//var_dump($keys);
foreach($specific_transactions as $specific) {
foreach($keys as $key) {
if(preg_match('/_user_id/', $key)) {
$entity = $this->Transactions->StateUserTransactions->newEntity();
$entity->transaction_id = $specific['transaction_id'];
$entity->transaction_type_id = $type_id;
$entity->state_user_id = $specific[$key];
if(!in_array($entity->state_user_id, $state_user_ids)) {
array_push($state_user_ids, $entity->state_user_id);
}
$entities[] = $entity;
}
}
}
}
//var_dump($entities);
$stateUsersTable = TableRegistry::getTableLocator()->get('StateUsers');
$existingStateUsers = $stateUsersTable->find('all')->select(['id'])->where(['id IN' => $state_user_ids])->order(['id'])->all();
$existing_state_user_ids = [];
$finalEntities = [];
foreach($existingStateUsers as $stateUser) {
$existing_state_user_ids[] = $stateUser->id;
}
foreach($entities as $entity) {
if(in_array($entity->state_user_id, $existing_state_user_ids)) {
array_push($finalEntities, $entity);
}
}
$results = $this->Transactions->StateUserTransactions->saveMany($finalEntities);
foreach($entities as $i => $entity) {
$errors = $entity->getErrors();
/* if(count($errors)) {
echo "$i: ";
echo json_encode($errors);
echo "<br>";
echo "state_user_id: " . $entity->state_user_id;
echo "<br>";
}*/
}
$this->set('results', $results);
$this->set('entities', $entities);
}
$this->set('missing_transactions', $missing_transaction_ids);
$this->set('count1', $count1);
$this->set('count2', $count2);
$timeUsed = microtime(true) - $startTime;
$this->set('timeUsed', $timeUsed);
}
/**
* View method

View File

@ -73,6 +73,9 @@ class TransactionsTable extends Table
$this->hasMany('TransactionSignatures', [
'foreignKey' => 'transaction_id'
]);
$this->hasMany('StateUserTransactions', [
'foreignKey' => 'transaction_id'
]);
}
/**

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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;

View File

@ -0,0 +1,46 @@
<?php
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
?>
<div class="transactions form large-9 medium-8 columns content">
<h1>Synchronize state_user_transactions with transactions</h1>
<p>transactions count: <?= $count1 ?></p>
<p>state_user_transaction count: <?= $count2 ?></p>
<p>Missing count: <?= count($missing_transactions); ?></p>
<p>First 10 Missing ids: </p>
<p><?php
foreach($missing_transactions as $i => $id) {
if($i > 10) break;
if($i > 0) echo ', ';
echo $id['id'];
} ?></p>
<?php if(isset($entities) && isset($results)) : ?>
<h2>Synchronize errors: </h2>
<ul>
<?php
$succeed = 0;
//var_dump($results);
if($results) :
foreach($results as $i => $result) :
if(false != $result) {
$succeed++;
continue;
}
?>
<li>Error saving entity: <?= json_encode($entities[$i]) ?> with error: <?= json_encode($entities[$i]->getErrors()) ?></li>
<?php endforeach; ?>
<?php endif; ?>
<li><success>Succeed: <?= $succeed ?></success></li>
</ul>
<?php endif; ?>
<?= $this->Form->create() ?>
<?= $this->Form->button(__('Synchronize')) ?>
<?= $this->Form->end() ?>
</div>