mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
working on decay
This commit is contained in:
parent
09fbce76e7
commit
91b4473ada
@ -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()
|
||||
{
|
||||
|
||||
@ -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
|
||||
|
||||
@ -73,6 +73,9 @@ class TransactionsTable extends Table
|
||||
$this->hasMany('TransactionSignatures', [
|
||||
'foreignKey' => 'transaction_id'
|
||||
]);
|
||||
$this->hasMany('StateUserTransactions', [
|
||||
'foreignKey' => 'transaction_id'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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>
|
||||
Loading…
x
Reference in New Issue
Block a user