Simplify import storage routine.

This commit is contained in:
James Cole 2017-07-16 07:45:20 +02:00
parent 58bfb35fa6
commit b676b1fef9
No known key found for this signature in database
GPG Key ID: C16961E655E74B5E

View File

@ -44,6 +44,7 @@ class ImportStorage
{ {
/** @var Collection */ /** @var Collection */
public $errors; public $errors;
/** @var Collection */
public $journals; public $journals;
/** @var CurrencyRepositoryInterface */ /** @var CurrencyRepositoryInterface */
private $currencyRepository; private $currencyRepository;
@ -97,13 +98,12 @@ class ImportStorage
} }
/** /**
* Do storage of import objects * Do storage of import objects.
*/ */
public function store() public function store()
{ {
$this->defaultCurrency = Amount::getDefaultCurrencyByUser($this->job->user); $this->defaultCurrency = Amount::getDefaultCurrencyByUser($this->job->user);
// routine below consists of 3 steps.
/** /**
* @var int $index * @var int $index
* @var ImportJournal $object * @var ImportJournal $object
@ -129,7 +129,6 @@ class ImportStorage
protected function applyRules(TransactionJournal $journal): bool protected function applyRules(TransactionJournal $journal): bool
{ {
if ($this->rules->count() > 0) { if ($this->rules->count() > 0) {
/** @var Rule $rule */ /** @var Rule $rule */
foreach ($this->rules as $rule) { foreach ($this->rules as $rule) {
Log::debug(sprintf('Going to apply rule #%d to journal %d.', $rule->id, $journal->id)); Log::debug(sprintf('Going to apply rule #%d to journal %d.', $rule->id, $journal->id));
@ -171,6 +170,50 @@ class ImportStorage
return true; return true;
} }
/**
* @param Collection $set
* @param ImportJournal $importJournal
*
* @return bool
*/
private function filterTransferSet(Collection $set, ImportJournal $importJournal)
{
$amount = Steam::positive($importJournal->getAmount());
$asset = $importJournal->asset->getAccount();
$opposing = $this->getOpposingAccount($importJournal->opposing, $amount);
$description = $importJournal->getDescription();
$filtered = $set->filter(
function (TransactionJournal $journal) use ($asset, $opposing, $description) {
$match = true;
$original = [app('steam')->tryDecrypt($journal->source_name), app('steam')->tryDecrypt($journal->destination_name)];
$compare = [$asset->name, $opposing->name];
sort($original);
sort($compare);
// description does not match? Then cannot be duplicate.
if ($journal->description !== $description) {
$match = false;
}
// not both accounts in journal? Then cannot be duplicate.
if ($original !== $compare) {
$match = false;
}
if ($match) {
return $journal;
}
return null;
}
);
if (count($filtered) > 0) {
return true;
}
return false;
}
/** /**
* @param ImportJournal $importJournal * @param ImportJournal $importJournal
* *
@ -319,7 +362,10 @@ class ImportStorage
// verify that opposing account is of the correct type: // verify that opposing account is of the correct type:
if ($opposing->accountType->type === AccountType::EXPENSE && $transactionType->type !== TransactionType::WITHDRAWAL) { if ($opposing->accountType->type === AccountType::EXPENSE && $transactionType->type !== TransactionType::WITHDRAWAL) {
Log::error(sprintf('Row #%d is imported as a %s but opposing is an expense account. This cannot be!', $index, $transactionType->type)); $message = sprintf('Row #%d is imported as a %s but opposing is an expense account. This cannot be!', $index, $transactionType->type);
Log::error($message);
throw new FireflyException($message);
} }
/*** First step done! */ /*** First step done! */
@ -426,64 +472,33 @@ class ImportStorage
private function verifyDoubleTransfer(TransactionType $transactionType, ImportJournal $importJournal): bool private function verifyDoubleTransfer(TransactionType $transactionType, ImportJournal $importJournal): bool
{ {
if ($transactionType->type === TransactionType::TRANSFER) { if ($transactionType->type === TransactionType::TRANSFER) {
$amount = Steam::positive($importJournal->getAmount()); $amount = Steam::positive($importJournal->getAmount());
$asset = $importJournal->asset->getAccount(); $date = $importJournal->getDate($this->dateFormat);
$opposing = $this->getOpposingAccount($importJournal->opposing, $amount); $set = TransactionJournal::
$date = $importJournal->getDate($this->dateFormat);
$description = $importJournal->getDescription();
$set = TransactionJournal::
leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
->leftJoin( ->leftJoin(
'transactions AS source', function (JoinClause $join) { 'transactions AS source', function (JoinClause $join) {
$join->on('transaction_journals.id', '=', 'source.transaction_journal_id')->where('source.amount', '<', 0); $join->on('transaction_journals.id', '=', 'source.transaction_journal_id')->where('source.amount', '<', 0);
} }
) )
->leftJoin( ->leftJoin(
'transactions AS destination', function (JoinClause $join) { 'transactions AS destination', function (JoinClause $join) {
$join->on('transaction_journals.id', '=', 'destination.transaction_journal_id')->where( $join->on('transaction_journals.id', '=', 'destination.transaction_journal_id')->where(
'destination.amount', '>', 0 'destination.amount', '>', 0
); );
} }
) )
->leftJoin('accounts as source_accounts', 'source.account_id', '=', 'source_accounts.id') ->leftJoin('accounts as source_accounts', 'source.account_id', '=', 'source_accounts.id')
->leftJoin('accounts as destination_accounts', 'destination.account_id', '=', 'destination_accounts.id') ->leftJoin('accounts as destination_accounts', 'destination.account_id', '=', 'destination_accounts.id')
->where('transaction_journals.user_id', $this->job->user_id) ->where('transaction_journals.user_id', $this->job->user_id)
->where('transaction_types.type', TransactionType::TRANSFER) ->where('transaction_types.type', TransactionType::TRANSFER)
->where('transaction_journals.date', $date->format('Y-m-d')) ->where('transaction_journals.date', $date->format('Y-m-d'))
->where('destination.amount', $amount) ->where('destination.amount', $amount)
->get( ->get(
['transaction_journals.id', 'transaction_journals.encrypted', 'transaction_journals.description', ['transaction_journals.id', 'transaction_journals.encrypted', 'transaction_journals.description',
'source_accounts.name as source_name', 'destination_accounts.name as destination_name'] 'source_accounts.name as source_name', 'destination_accounts.name as destination_name']
); );
if ($set->count() > 0) { $filtered = $this->filterTransferSet($set, $importJournal);
$filtered = $set->filter(
function (TransactionJournal $journal) use ($asset, $opposing, $description) {
$match = true;
$compare = [$asset->name, $opposing->name];
if ($journal->description !== $description) {
$match = false;
}
// when both are in array match is true. So reverse:
if (!(in_array(app('steam')->tryDecrypt($journal->source_name), $compare)
&& in_array(
app('steam')->tryDecrypt($journal->destination_name), $compare
))
) {
$match = false;
}
if ($match) {
return $journal;
}
return null;
}
);
if (count($filtered) > 0) {
return true;
}
}
} }