Improve test coverage.

This commit is contained in:
James Cole
2019-07-31 16:53:09 +02:00
parent 5524941c90
commit 9b574ce7ad
155 changed files with 1890 additions and 2263 deletions

View File

@@ -8,8 +8,8 @@ APP_DEBUG=false
# This should be your email address # This should be your email address
SITE_OWNER=mail@example.com SITE_OWNER=mail@example.com
# The encryption key for your database and sessions. Keep this very secure. # The encryption key for your sessions. Keep this very secure.
# If you generate a new one all existing data must be considered LOST. # If you generate a new one existing data must be considered LOST.
# Change it to a string of exactly 32 chars or use command `php artisan key:generate` to generate it # Change it to a string of exactly 32 chars or use command `php artisan key:generate` to generate it
APP_KEY=SomeRandomStringOf32CharsExactly APP_KEY=SomeRandomStringOf32CharsExactly
@@ -103,8 +103,8 @@ MAPBOX_API_KEY=
# Firefly III currently supports two provider for live Currency Exchange Rates: # Firefly III currently supports two provider for live Currency Exchange Rates:
# "fixer" is the default (for backward compatibility), and "ratesapi" is the new one. # "fixer" is the default (for backward compatibility), and "ratesapi" is the new one.
# RatesApi.IO (see https://ratesapi.io) is a FREE and OPEN SOURCE live currency exchange rates, # RatesApi.IO (see https://ratesapi.io) is a FREE and OPEN SOURCE live currency exchange rates,
# built compatible with Fixer.IO, based on data published by European Central Bank, and don't require API key. # built compatible with Fixer.IO, based on data published by European Central Bank, and doesn't require API key.
CER_PROVIDER=fixer CER_PROVIDER=ratesapi
# If you have select "fixer" as default currency exchange rates, # If you have select "fixer" as default currency exchange rates,
# set a Fixer IO API key here (see https://fixer.io) to enable live currency exchange rates. # set a Fixer IO API key here (see https://fixer.io) to enable live currency exchange rates.
# Please note that this WILL ONLY WORK FOR PAID fixer.io accounts because they severely limited # Please note that this WILL ONLY WORK FOR PAID fixer.io accounts because they severely limited

View File

@@ -245,11 +245,13 @@ class TransactionJournalFactory
/** create or get source and destination accounts */ /** create or get source and destination accounts */
$sourceAccount = $this->getAccount($type->type, 'source', (int)$row['source_id'], $row['source_name']); $sourceAccount = $this->getAccount($type->type, 'source', (int)$row['source_id'], $row['source_name']);
$destinationAccount = $this->getAccount($type->type, 'destination', (int)$row['destination_id'], $row['destination_name']); $destinationAccount = $this->getAccount($type->type, 'destination', (int)$row['destination_id'], $row['destination_name']);
// @codeCoverageIgnoreStart
} catch (FireflyException $e) { } catch (FireflyException $e) {
Log::error($e->getMessage()); Log::error($e->getMessage());
return null; return null;
} }
// @codeCoverageIgnoreEnd
// TODO After 4.8.0 better handling below: // TODO After 4.8.0 better handling below:

View File

@@ -96,7 +96,7 @@ class AccountFormRequest extends Request
'name' => 'required|min:1|uniqueAccountForUser', 'name' => 'required|min:1|uniqueAccountForUser',
'opening_balance' => 'numeric|required_with:opening_balance_date|nullable', 'opening_balance' => 'numeric|required_with:opening_balance_date|nullable',
'opening_balance_date' => 'date|required_with:opening_balance|nullable', 'opening_balance_date' => 'date|required_with:opening_balance|nullable',
'iban' => ['iban', 'nullable', new UniqueIban(null, $this->string('what'))], 'iban' => ['iban', 'nullable', new UniqueIban(null, $this->string('objectType'))],
'BIC' => 'bic|nullable', 'BIC' => 'bic|nullable',
'virtual_balance' => 'numeric|nullable', 'virtual_balance' => 'numeric|nullable',
'currency_id' => 'exists:transaction_currencies,id', 'currency_id' => 'exists:transaction_currencies,id',

View File

@@ -49,9 +49,7 @@ use Carbon\Carbon;
use FireflyIII\Events\RequestedReportOnJournals; use FireflyIII\Events\RequestedReportOnJournals;
use FireflyIII\Events\StoredTransactionGroup; use FireflyIII\Events\StoredTransactionGroup;
use FireflyIII\Factory\PiggyBankEventFactory; use FireflyIII\Factory\PiggyBankEventFactory;
use FireflyIII\Factory\PiggyBankFactory;
use FireflyIII\Models\Recurrence; use FireflyIII\Models\Recurrence;
use FireflyIII\Models\RecurrenceMeta;
use FireflyIII\Models\RecurrenceRepetition; use FireflyIII\Models\RecurrenceRepetition;
use FireflyIII\Models\RecurrenceTransaction; use FireflyIII\Models\RecurrenceTransaction;
use FireflyIII\Models\TransactionGroup; use FireflyIII\Models\TransactionGroup;
@@ -94,16 +92,26 @@ class CreateRecurringTransactions implements ShouldQueue
/** @var int Transaction groups created */ /** @var int Transaction groups created */
public $created; public $created;
/**
* @param Carbon $date
*/
public function setDate(Carbon $date): void
{
$this->date = $date;
}
/** /**
* Create a new job instance. * Create a new job instance.
* @codeCoverageIgnore * @codeCoverageIgnore
* *
* @param Carbon $date * @param Carbon $date
*/ */
public function __construct(Carbon $date) public function __construct(?Carbon $date)
{ {
$date->startOfDay(); if (null !== $date) {
$this->date = $date; $date->startOfDay();
$this->date = $date;
}
$this->repository = app(RecurringRepositoryInterface::class); $this->repository = app(RecurringRepositoryInterface::class);
$this->journalRepository = app(JournalRepositoryInterface::class); $this->journalRepository = app(JournalRepositoryInterface::class);
$this->groupRepository = app(TransactionGroupRepositoryInterface::class); $this->groupRepository = app(TransactionGroupRepositoryInterface::class);

View File

@@ -32,6 +32,7 @@ use Mail;
/** /**
* Class MailError. * Class MailError.
* @codeCoverageIgnore
*/ */
class MailError extends Job implements ShouldQueue class MailError extends Job implements ShouldQueue
{ {

View File

@@ -30,6 +30,7 @@ use Illuminate\Queue\SerializesModels;
/** /**
* Class AccessTokenCreatedMail * Class AccessTokenCreatedMail
* @codeCoverageIgnore
*/ */
class AccessTokenCreatedMail extends Mailable class AccessTokenCreatedMail extends Mailable
{ {

View File

@@ -30,6 +30,7 @@ use Illuminate\Queue\SerializesModels;
* Class AdminTestMail. * Class AdminTestMail.
* *
* Sends a test mail to administrators. * Sends a test mail to administrators.
* @codeCoverageIgnore
*/ */
class AdminTestMail extends Mailable class AdminTestMail extends Mailable
{ {

View File

@@ -30,6 +30,7 @@ use Illuminate\Queue\SerializesModels;
* Class ConfirmEmailChangeMail * Class ConfirmEmailChangeMail
* *
* Sends message to new address to confirm change. * Sends message to new address to confirm change.
* @codeCoverageIgnore
*/ */
class ConfirmEmailChangeMail extends Mailable class ConfirmEmailChangeMail extends Mailable
{ {

View File

@@ -31,6 +31,7 @@ use Laravel\Passport\Client;
/** /**
* Class OAuthTokenCreatedMail * Class OAuthTokenCreatedMail
* @codeCoverageIgnore
*/ */
class OAuthTokenCreatedMail extends Mailable class OAuthTokenCreatedMail extends Mailable
{ {

View File

@@ -31,6 +31,7 @@ use Illuminate\Queue\SerializesModels;
* Sends newly registered user an email message. * Sends newly registered user an email message.
* *
* Class RegisteredUser * Class RegisteredUser
* @codeCoverageIgnore
*/ */
class RegisteredUser extends Mailable class RegisteredUser extends Mailable
{ {

View File

@@ -31,6 +31,7 @@ use Illuminate\Support\Collection;
* Class ReportNewJournalsMail. * Class ReportNewJournalsMail.
* *
* Sends a list of newly created journals to the user. * Sends a list of newly created journals to the user.
* @codeCoverageIgnore
*/ */
class ReportNewJournalsMail extends Mailable class ReportNewJournalsMail extends Mailable
{ {

View File

@@ -30,6 +30,7 @@ use Illuminate\Queue\SerializesModels;
/** /**
* Sends user link for new password. * Sends user link for new password.
* Class RequestedNewPassword * Class RequestedNewPassword
* @codeCoverageIgnore
*/ */
class RequestedNewPassword extends Mailable class RequestedNewPassword extends Mailable
{ {

View File

@@ -28,6 +28,7 @@ use Illuminate\Queue\SerializesModels;
/** /**
* Class UndoEmailChangeMail * Class UndoEmailChangeMail
* @codeCoverageIgnore
*/ */
class UndoEmailChangeMail extends Mailable class UndoEmailChangeMail extends Mailable
{ {

View File

@@ -46,11 +46,11 @@ use Session;
/** /**
* Class EventServiceProvider. * Class EventServiceProvider.
* @codeCoverageIgnore
*/ */
class EventServiceProvider extends ServiceProvider class EventServiceProvider extends ServiceProvider
{ {
/** /**
* @codeCoverageIgnore
* The event listener mappings for the application. * The event listener mappings for the application.
* *
* @var array * @var array
@@ -103,7 +103,6 @@ class EventServiceProvider extends ServiceProvider
]; ];
/** /**
* @codeCoverageIgnore
* Register any events for your application. * Register any events for your application.
*/ */
public function boot(): void public function boot(): void
@@ -119,7 +118,7 @@ class EventServiceProvider extends ServiceProvider
{ {
// in case of repeated piggy banks and/or other problems. // in case of repeated piggy banks and/or other problems.
PiggyBank::created( PiggyBank::created(
function (PiggyBank $piggyBank) { static function (PiggyBank $piggyBank) {
$repetition = new PiggyBankRepetition; $repetition = new PiggyBankRepetition;
$repetition->piggyBank()->associate($piggyBank); $repetition->piggyBank()->associate($piggyBank);
$repetition->startdate = $piggyBank->startdate; $repetition->startdate = $piggyBank->startdate;
@@ -129,7 +128,7 @@ class EventServiceProvider extends ServiceProvider
} }
); );
Client::created( Client::created(
function (Client $oauthClient) { static function (Client $oauthClient) {
/** @var UserRepositoryInterface $repository */ /** @var UserRepositoryInterface $repository */
$repository = app(UserRepositoryInterface::class); $repository = app(UserRepositoryInterface::class);
$user = $repository->findNull((int)$oauthClient->user_id); $user = $repository->findNull((int)$oauthClient->user_id);

View File

@@ -50,7 +50,7 @@ use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\Services\Currency\ExchangeRateInterface; use FireflyIII\Services\Currency\ExchangeRateInterface;
use FireflyIII\Services\IP\IpifyOrg; use FireflyIII\Services\IP\IpifyOrg;
use FireflyIII\Services\IP\IPRetrievalInterface; use FireflyIII\Services\IP\IPRetrievalInterface;
use FireflyIII\Services\Password\PwndVerifierV2; use FireflyIII\Services\Password\PwndVerifierV3;
use FireflyIII\Services\Password\Verifier; use FireflyIII\Services\Password\Verifier;
use FireflyIII\Support\Amount; use FireflyIII\Support\Amount;
use FireflyIII\Support\ExpandedForm; use FireflyIII\Support\ExpandedForm;
@@ -183,7 +183,7 @@ class FireflyServiceProvider extends ServiceProvider
$this->app->bind(ExchangeRateInterface::class, $class); $this->app->bind(ExchangeRateInterface::class, $class);
// password verifier thing // password verifier thing
$this->app->bind(Verifier::class, PwndVerifierV2::class); $this->app->bind(Verifier::class, PwndVerifierV3::class);
// IP thing: // IP thing:
$this->app->bind(IPRetrievalInterface::class, IpifyOrg::class); $this->app->bind(IPRetrievalInterface::class, IpifyOrg::class);

View File

@@ -57,17 +57,6 @@ class AccountRepository implements AccountRepositoryInterface
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this))); Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
} }
} }
/**
* @param array $types
*
* @return int
*/
public function count(array $types): int
{
return $this->user->accounts()->accountTypeIn($types)->count();
}
/** /**
* Moved here from account CRUD. * Moved here from account CRUD.
* *
@@ -87,6 +76,17 @@ class AccountRepository implements AccountRepositoryInterface
return true; return true;
} }
/**
* @param array $types
*
* @return int
*/
public function count(array $types): int
{
return $this->user->accounts()->accountTypeIn($types)->count();
}
/** /**
* @param string $number * @param string $number
* @param array $types * @param array $types
@@ -97,7 +97,7 @@ class AccountRepository implements AccountRepositoryInterface
{ {
$query = $this->user->accounts() $query = $this->user->accounts()
->leftJoin('account_meta', 'account_meta.account_id', '=', 'accounts.id') ->leftJoin('account_meta', 'account_meta.account_id', '=', 'accounts.id')
->where('account_meta.name', 'accountNumber') ->where('account_meta.name', 'account_number')
->where('account_meta.data', json_encode($number)); ->where('account_meta.data', json_encode($number));
if (count($types) > 0) { if (count($types) > 0) {
@@ -298,30 +298,6 @@ class AccountRepository implements AccountRepositoryInterface
return $factory->findOrCreate('Cash account', $type->type); return $factory->findOrCreate('Cash account', $type->type);
} }
/**
* @param $account
*
* @return string
*/
public function getInterestPerDay(Account $account): string
{
$interest = $this->getMetaValue($account, 'interest');
$interestPeriod = $this->getMetaValue($account, 'interest_period');
Log::debug(sprintf('Start with interest of %s percent', $interest));
// calculate
if ('monthly' === $interestPeriod) {
$interest = bcdiv(bcmul($interest, '12'), '365'); // per year
Log::debug(sprintf('Interest is now (monthly to daily) %s percent', $interest));
}
if ('yearly' === $interestPeriod) {
$interest = bcdiv($interest, '365'); // per year
Log::debug(sprintf('Interest is now (yearly to daily) %s percent', $interest));
}
return $interest;
}
/** /**
* Return meta value for account. Null if not found. * Return meta value for account. Null if not found.
* *
@@ -444,18 +420,6 @@ class AccountRepository implements AccountRepositoryInterface
return $account; return $account;
} }
/**
* @param Account $account
*
* @return bool
*/
public function isAsset(Account $account): bool
{
$type = $account->accountType->type;
return AccountType::ASSET === $type || AccountType::DEFAULT === $type;
}
/** /**
* @param Account $account * @param Account $account
* *
@@ -466,47 +430,6 @@ class AccountRepository implements AccountRepositoryInterface
return in_array($account->accountType->type, [AccountType::CREDITCARD, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE], true); return in_array($account->accountType->type, [AccountType::CREDITCARD, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE], true);
} }
/**
* Returns the date of the very last transaction in this account.
*
* @param Account $account
*
* @return TransactionJournal|null
*/
public function latestJournal(Account $account): ?TransactionJournal
{
$first = $account->transactions()
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->orderBy('transaction_journals.date', 'DESC')
->orderBy('transaction_journals.order', 'ASC')
->where('transaction_journals.user_id', $this->user->id)
->orderBy('transaction_journals.id', 'DESC')
->first(['transaction_journals.id']);
if (null !== $first) {
return TransactionJournal::find((int)$first->id);
}
return null;
}
/**
* Returns the date of the very last transaction in this account.
*
* @param Account $account
*
* @return Carbon|null
*/
public function latestJournalDate(Account $account): ?Carbon
{
$result = null;
$journal = $this->latestJournal($account);
if (null !== $journal) {
$result = $journal->date;
}
return $result;
}
/** /**
* Returns the date of the very first transaction in this account. * Returns the date of the very first transaction in this account.
* *
@@ -581,7 +504,7 @@ class AccountRepository implements AccountRepositoryInterface
* @param array $data * @param array $data
* *
* @return Account * @return Account
* @throws \FireflyIII\Exceptions\FireflyException * @throws FireflyException
*/ */
public function store(array $data): Account public function store(array $data): Account
{ {
@@ -597,7 +520,7 @@ class AccountRepository implements AccountRepositoryInterface
* @param array $data * @param array $data
* *
* @return Account * @return Account
* @throws \FireflyIII\Exceptions\FireflyException * @throws FireflyException
* @throws FireflyException * @throws FireflyException
* @throws FireflyException * @throws FireflyException
*/ */

View File

@@ -40,7 +40,9 @@ interface AccountRepositoryInterface
/** /**
* @param Account $account * @param Account $account
*
* @return TransactionJournal|null * @return TransactionJournal|null
*
*/ */
public function getOpeningBalance(Account $account): ?TransactionJournal; public function getOpeningBalance(Account $account): ?TransactionJournal;
@@ -151,13 +153,6 @@ interface AccountRepositoryInterface
*/ */
public function getCashAccount(): Account; public function getCashAccount(): Account;
/**
* @param $account
*
* @return string
*/
public function getInterestPerDay(Account $account): string;
/** /**
* Return meta value for account. Null if not found. * Return meta value for account. Null if not found.
* *
@@ -211,12 +206,6 @@ interface AccountRepositoryInterface
*/ */
public function getReconciliation(Account $account): ?Account; public function getReconciliation(Account $account): ?Account;
/**
* @param Account $account
*
* @return bool
*/
public function isAsset(Account $account): bool;
/** /**
* @param Account $account * @param Account $account
@@ -225,23 +214,6 @@ interface AccountRepositoryInterface
*/ */
public function isLiability(Account $account): bool; public function isLiability(Account $account): bool;
/**
* Returns the date of the very first transaction in this account.
*
* @param Account $account
*
* @return TransactionJournal|null
*/
public function latestJournal(Account $account): ?TransactionJournal;
/**
* Returns the date of the very last transaction in this account.
*
* @param Account $account
*
* @return Carbon|null
*/
public function latestJournalDate(Account $account): ?Carbon;
/** /**
* Returns the date of the very first transaction in this account. * Returns the date of the very first transaction in this account.

View File

@@ -151,6 +151,47 @@ class AccountTasker implements AccountTaskerInterface
return $expenses; return $expenses;
} }
/**
* @param Carbon $start
* @param Carbon $end
* @param Collection $accounts
*
* @return array
*/
public function getIncomeReport(Carbon $start, Carbon $end, Collection $accounts): array
{
// get all expenses for the given accounts in the given period!
// also transfers!
// get all transactions:
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setAccounts($accounts)->setRange($start, $end);
$collector->setTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER])
->withAccountInformation();
$income = $this->groupByDestination($collector->getExtractedJournals());
// sort the result
// Obtain a list of columns
$sum = [];
foreach ($income as $accountId => $row) {
$sum[$accountId] = (float)$row['sum'];
}
array_multisort($sum, SORT_DESC, $income);
return $income;
}
/**
* @param User $user
*/
public function setUser(User $user): void
{
$this->user = $user;
}
/** /**
* @param array $array * @param array $array
* *
@@ -208,45 +249,4 @@ class AccountTasker implements AccountTaskerInterface
return $expenses; return $expenses;
} }
/**
* @param Carbon $start
* @param Carbon $end
* @param Collection $accounts
*
* @return array
*/
public function getIncomeReport(Carbon $start, Carbon $end, Collection $accounts): array
{
// get all expenses for the given accounts in the given period!
// also transfers!
// get all transactions:
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setAccounts($accounts)->setRange($start, $end);
$collector->setTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER])
->withAccountInformation();
$income = $this->groupByDestination($collector->getExtractedJournals());
// sort the result
// Obtain a list of columns
$sum = [];
foreach ($income as $accountId => $row) {
$sum[$accountId] = (float)$row['sum'];
}
array_multisort($sum, SORT_DESC, $income);
return $income;
}
/**
* @param User $user
*/
public function setUser(User $user): void
{
$this->user = $user;
}
} }

View File

@@ -33,16 +33,16 @@ interface AccountTaskerInterface
{ {
/** /**
* @param Collection $accounts * @param Collection $accounts
* @param Carbon $start * @param Carbon $start
* @param Carbon $end * @param Carbon $end
* *
* @return array * @return array
*/ */
public function getAccountReport(Collection $accounts, Carbon $start, Carbon $end): array; public function getAccountReport(Collection $accounts, Carbon $start, Carbon $end): array;
/** /**
* @param Carbon $start * @param Carbon $start
* @param Carbon $end * @param Carbon $end
* @param Collection $accounts * @param Collection $accounts
* *
* @return array * @return array
@@ -50,8 +50,8 @@ interface AccountTaskerInterface
public function getExpenseReport(Carbon $start, Carbon $end, Collection $accounts): array; public function getExpenseReport(Carbon $start, Carbon $end, Collection $accounts): array;
/** /**
* @param Carbon $start * @param Carbon $start
* @param Carbon $end * @param Carbon $end
* @param Collection $accounts * @param Collection $accounts
* *
* @return array * @return array

View File

@@ -90,17 +90,6 @@ class AttachmentRepository implements AttachmentRepositoryInterface
return $disk->exists($attachment->fileName()); return $disk->exists($attachment->fileName());
} }
/**
* @param int $attachmentId
*
* @return Attachment|null
*/
public function findWithoutUser(int $attachmentId): ?Attachment
{
return Attachment::find($attachmentId);
}
/** /**
* @return Collection * @return Collection
*/ */
@@ -109,24 +98,6 @@ class AttachmentRepository implements AttachmentRepositoryInterface
return $this->user->attachments()->get(); return $this->user->attachments()->get();
} }
/**
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function getBetween(Carbon $start, Carbon $end): Collection
{
$query = $this->user
->attachments()
->leftJoin('transaction_journals', 'attachments.attachable_id', '=', 'transaction_journals.id')
->where('transaction_journals.date', '>=', $start->format('Y-m-d'))
->where('transaction_journals.date', '<=', $end->format('Y-m-d'))
->get(['attachments.*']);
return $query;
}
/** /**
* @param Attachment $attachment * @param Attachment $attachment
* *

View File

@@ -48,26 +48,11 @@ interface AttachmentRepositoryInterface
*/ */
public function exists(Attachment $attachment): bool; public function exists(Attachment $attachment): bool;
/**
* @param int $attachmentId
*
* @return Attachment|null
*/
public function findWithoutUser(int $attachmentId): ?Attachment;
/** /**
* @return Collection * @return Collection
*/ */
public function get(): Collection; public function get(): Collection;
/**
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function getBetween(Carbon $start, Carbon $end): Collection;
/** /**
* @param Attachment $attachment * @param Attachment $attachment
* *

View File

@@ -489,36 +489,6 @@ class BudgetRepository implements BudgetRepositoryInterface
return $return; return $return;
} }
/**
* Calculate the average amount in the budgets available in this period.
* Grouped by day.
*
* @param Carbon $start
* @param Carbon $end
*
* @return string
*/
public function getAverageAvailable(Carbon $start, Carbon $end): string
{
/** @var Collection $list */
$list = $this->user->availableBudgets()
->where('start_date', '>=', $start->format('Y-m-d 00:00:00'))
->where('end_date', '<=', $end->format('Y-m-d 00:00:00'))
->get();
if (0 === $list->count()) {
return '0';
}
$total = '0';
$days = 0;
/** @var AvailableBudget $availableBudget */
foreach ($list as $availableBudget) {
$total = bcadd($availableBudget->amount, $total);
$days += $availableBudget->start_date->diffInDays($availableBudget->end_date);
}
return bcdiv($total, (string)$days);
}
/** /**
* This method is being used to generate the budget overview in the year/multi-year report. Its used * This method is being used to generate the budget overview in the year/multi-year report. Its used
* in both the year/multi-year budget overview AND in the accompanying chart. * in both the year/multi-year budget overview AND in the accompanying chart.

View File

@@ -172,17 +172,6 @@ interface BudgetRepositoryInterface
*/ */
public function getAvailableBudgetsByCurrency(TransactionCurrency $currency): Collection; public function getAvailableBudgetsByCurrency(TransactionCurrency $currency): Collection;
/**
* Calculate the average amount in the budgets available in this period.
* Grouped by day.
*
* @param Carbon $start
* @param Carbon $end
*
* @return string
*/
public function getAverageAvailable(Carbon $start, Carbon $end): string;
/** /**
* @param Budget $budget * @param Budget $budget
* @param Carbon $start * @param Carbon $start

View File

@@ -41,6 +41,7 @@ class BelongsUser implements Rule
* Create a new rule instance. * Create a new rule instance.
* *
* @return void * @return void
* @codeCoverageIgnore
*/ */
public function __construct() public function __construct()
{ {
@@ -51,6 +52,7 @@ class BelongsUser implements Rule
* Get the validation error message. * Get the validation error message.
* *
* @return string * @return string
* @codeCoverageIgnore
*/ */
public function message(): string public function message(): string
{ {

View File

@@ -36,6 +36,7 @@ class IsAssetAccountId implements Rule
* Get the validation error message. This is not translated because only the API uses it. * Get the validation error message. This is not translated because only the API uses it.
* *
* @return string * @return string
* @codeCoverageIgnore
*/ */
public function message(): string public function message(): string
{ {

View File

@@ -33,7 +33,7 @@ class IsBoolean implements Rule
{ {
/** /**
* Get the validation error message. * Get the validation error message.
* * @codeCoverageIgnore
* @return string * @return string
*/ */
public function message(): string public function message(): string
@@ -51,25 +51,16 @@ class IsBoolean implements Rule
*/ */
public function passes($attribute, $value): bool public function passes($attribute, $value): bool
{ {
if (\is_bool($value)) { if (is_bool($value)) {
return true; return true;
} }
if (\is_int($value) && 0 === $value) { if (is_int($value) && 0 === $value) {
return true; return true;
} }
if (\is_int($value) && 1 === $value) { if (is_int($value) && 1 === $value) {
return true; return true;
} }
if (\is_string($value) && '1' === $value) { if (is_string($value) && in_array($value, ['0', '1', 'true', 'false', 'on', 'off', 'yes', 'no', 'y', 'n'])) {
return true;
}
if (\is_string($value) && '0' === $value) {
return true;
}
if (\is_string($value) && 'true' === $value) {
return true;
}
if (\is_string($value) && 'false' === $value) {
return true; return true;
} }

View File

@@ -26,6 +26,7 @@ namespace FireflyIII\Rules;
use Carbon\Carbon; use Carbon\Carbon;
use Carbon\Exceptions\InvalidDateException; use Carbon\Exceptions\InvalidDateException;
use Exception;
use Illuminate\Contracts\Validation\Rule; use Illuminate\Contracts\Validation\Rule;
use Log; use Log;
@@ -39,6 +40,7 @@ class IsDateOrTime implements Rule
* Get the validation error message. * Get the validation error message.
* *
* @return string|array * @return string|array
* @codeCoverageIgnore
*/ */
public function message() public function message()
{ {
@@ -56,11 +58,14 @@ class IsDateOrTime implements Rule
public function passes($attribute, $value): bool public function passes($attribute, $value): bool
{ {
$value = (string)$value; $value = (string)$value;
if ('' === $value) {
return false;
}
if (10 === strlen($value)) { if (10 === strlen($value)) {
// probably a date format. // probably a date format.
try { try {
Carbon::createFromFormat('Y-m-d', $value); Carbon::createFromFormat('Y-m-d', $value);
} catch (InvalidDateException $e) { } catch (InvalidDateException|Exception $e) {
Log::error(sprintf('"%s" is not a valid date: %s', $value, $e->getMessage())); Log::error(sprintf('"%s" is not a valid date: %s', $value, $e->getMessage()));
return false; return false;
@@ -71,7 +76,7 @@ class IsDateOrTime implements Rule
// is an atom string, I hope? // is an atom string, I hope?
try { try {
Carbon::parse($value); Carbon::parse($value);
} catch (InvalidDateException $e) { } catch (InvalidDateException|Exception $e) {
Log::error(sprintf('"%s" is not a valid date or time: %s', $value, $e->getMessage())); Log::error(sprintf('"%s" is not a valid date or time: %s', $value, $e->getMessage()));
return false; return false;

View File

@@ -46,16 +46,19 @@ class IsValidAttachmentModel implements Rule
/** /**
* IsValidAttachmentModel constructor. * IsValidAttachmentModel constructor.
* *
* @codeCoverageIgnore
*
* @param string $model * @param string $model
*/ */
public function __construct(string $model) public function __construct(string $model)
{ {
$model = $this->normalizeModel($model);
$this->model = $model; $this->model = $model;
} }
/** /**
* Get the validation error message. * Get the validation error message.
* * @codeCoverageIgnore
* @return string * @return string
*/ */
public function message(): string public function message(): string
@@ -78,9 +81,9 @@ class IsValidAttachmentModel implements Rule
if (!auth()->check()) { if (!auth()->check()) {
return false; return false;
} }
$model = false === strpos('FireflyIII', $this->model) ? 'FireflyIII\\Models\\' . $this->model : $this->model;
if (Bill::class === $model) {
if (Bill::class === $this->model) {
/** @var BillRepositoryInterface $repository */ /** @var BillRepositoryInterface $repository */
$repository = app(BillRepositoryInterface::class); $repository = app(BillRepositoryInterface::class);
/** @var User $user */ /** @var User $user */
@@ -91,7 +94,7 @@ class IsValidAttachmentModel implements Rule
return null !== $bill; return null !== $bill;
} }
if (ImportJob::class === $model) { if (ImportJob::class === $this->model) {
/** @var ImportJobRepositoryInterface $repository */ /** @var ImportJobRepositoryInterface $repository */
$repository = app(ImportJobRepositoryInterface::class); $repository = app(ImportJobRepositoryInterface::class);
/** @var User $user */ /** @var User $user */
@@ -102,7 +105,7 @@ class IsValidAttachmentModel implements Rule
return null !== $importJob; return null !== $importJob;
} }
if (Transaction::class === $model) { if (Transaction::class === $this->model) {
/** @var JournalRepositoryInterface $repository */ /** @var JournalRepositoryInterface $repository */
$repository = app(JournalRepositoryInterface::class); $repository = app(JournalRepositoryInterface::class);
/** @var User $user */ /** @var User $user */
@@ -113,7 +116,7 @@ class IsValidAttachmentModel implements Rule
return null !== $transaction; return null !== $transaction;
} }
if (TransactionJournal::class === $model) { if (TransactionJournal::class === $this->model) {
$repository = app(JournalRepositoryInterface::class); $repository = app(JournalRepositoryInterface::class);
$user = auth()->user(); $user = auth()->user();
$repository->setUser($user); $repository->setUser($user);
@@ -121,8 +124,23 @@ class IsValidAttachmentModel implements Rule
return null !== $result; return null !== $result;
} }
Log::error(sprintf('No model was recognized from string "%s"', $model)); Log::error(sprintf('No model was recognized from string "%s"', $this->model));
return false; return false;
} }
/**
* @param string $model
*
* @return string
*/
private function normalizeModel(string $model): string
{
$search = ['FireflyIII\Models\\'];
$replace = '';
$model = str_replace($search, $replace, $model);
$model = sprintf('FireflyIII\Models\%s', $model);
return $model;
}
} }

View File

@@ -26,7 +26,6 @@ namespace FireflyIII\Rules;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType; use FireflyIII\Models\AccountType;
use Illuminate\Contracts\Validation\Rule; use Illuminate\Contracts\Validation\Rule;
use Illuminate\Support\Collection;
use Log; use Log;
/** /**
@@ -43,6 +42,8 @@ class UniqueIban implements Rule
/** /**
* Create a new rule instance. * Create a new rule instance.
* *
* @codeCoverageIgnore
*
* @param Account|null $account * @param Account|null $account
* @param string|null $expectedType * @param string|null $expectedType
*/ */
@@ -55,6 +56,8 @@ class UniqueIban implements Rule
/** /**
* Get the validation error message. * Get the validation error message.
* *
* @codeCoverageIgnore
*
* @return string * @return string
*/ */
public function message(): string public function message(): string
@@ -78,13 +81,13 @@ class UniqueIban implements Rule
return true; // @codeCoverageIgnore return true; // @codeCoverageIgnore
} }
if (null === $this->expectedType) { if (null === $this->expectedType) {
return true; return true; // @codeCoverageIgnore
} }
$maxCounts = $this->getMaxOccurrences(); $maxCounts = $this->getMaxOccurrences();
foreach ($maxCounts as $type => $max) { foreach ($maxCounts as $type => $max) {
$count = $this->countHits($type, $value); $count = $this->countHits($type, $value);
Log::debug(sprintf('Count for "%s" and IBAN "%s" is %d', $type, $value, $count));
if ($count > $max) { if ($count > $max) {
Log::debug( Log::debug(
sprintf( sprintf(
@@ -108,24 +111,18 @@ class UniqueIban implements Rule
*/ */
private function countHits(string $type, string $iban): int private function countHits(string $type, string $iban): int
{ {
$count = 0; $query
/** @noinspection NullPointerExceptionInspection */ = auth()->user()
$query = auth()->user() ->accounts()
->accounts() ->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id') ->where('accounts.iban', $iban)
->where('account_types.type', $type); ->where('account_types.type', $type);
if (null !== $this->account) { if (null !== $this->account) {
$query->where('accounts.id', '!=', $this->account->id); $query->where('accounts.id', '!=', $this->account->id);
} }
/** @var Collection $result */
$result = $query->get(['accounts.*']);
foreach ($result as $account) {
if ($account->iban === $iban) {
$count++;
}
}
return $count; return $query->count();
} }
/** /**

View File

@@ -31,6 +31,7 @@ use Log;
/** /**
* Class ValidJournals * Class ValidJournals
* @codeCoverageIgnore
*/ */
class ValidJournals implements Rule class ValidJournals implements Rule
{ {

View File

@@ -27,6 +27,7 @@ use Illuminate\Contracts\Validation\Rule;
/** /**
* Class ValidRecurrenceRepetitionType * Class ValidRecurrenceRepetitionType
* @codeCoverageIgnore
*/ */
class ValidRecurrenceRepetitionType implements Rule class ValidRecurrenceRepetitionType implements Rule
{ {

View File

@@ -31,6 +31,7 @@ use Log;
/** /**
* Class ValidRecurrenceRepetitionValue * Class ValidRecurrenceRepetitionValue
* @codeCoverageIgnore
*/ */
class ValidRecurrenceRepetitionValue implements Rule class ValidRecurrenceRepetitionValue implements Rule
{ {

View File

@@ -1,87 +0,0 @@
<?php
/**
* ValidTransactions.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Rules;
use FireflyIII\Models\Transaction;
use Illuminate\Contracts\Validation\Rule;
use Log;
/**
* Class ValidTransactions
*/
class ValidTransactions implements Rule
{
/**
* Create a new rule instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Get the validation error message.
*
* @return string
*/
public function message(): string
{
return (string)trans('validation.invalid_selection');
}
/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param mixed $value
*
* @return bool
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function passes($attribute, $value): bool
{
Log::debug('In ValidTransactions::passes');
if (!is_array($value)) {
return true;
}
$userId = auth()->user()->id;
foreach ($value as $transactionId) {
$count = Transaction::where('transactions.id', $transactionId)
->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id')
->where('accounts.user_id', $userId)->count();
if (0 === $count) {
Log::debug(sprintf('Count for transaction #%d and user #%d is zero! Return FALSE', $transactionId, $userId));
return false;
}
}
Log::debug('Return true!');
return true;
}
}

View File

@@ -29,6 +29,7 @@ use Illuminate\Contracts\Validation\Rule;
/** /**
* *
* Class ZeroOrMore * Class ZeroOrMore
* @codeCoverageIgnore
*/ */
class ZeroOrMore implements Rule class ZeroOrMore implements Rule
{ {

View File

@@ -35,6 +35,7 @@ use Tests\Object\FakeApiContext;
* Special class to hide away bunq's static initialisation methods. * Special class to hide away bunq's static initialisation methods.
* *
* Class ApiContext * Class ApiContext
* @codeCoverageIgnore
*/ */
class ApiContext class ApiContext
{ {

View File

@@ -31,6 +31,7 @@ use FireflyIII\Exceptions\FireflyException;
/** /**
* Class MonetaryAccount * Class MonetaryAccount
* @codeCoverageIgnore
*/ */
class MonetaryAccount class MonetaryAccount
{ {

View File

@@ -31,6 +31,7 @@ use FireflyIII\Exceptions\FireflyException;
/** /**
* Class Payment * Class Payment
* @codeCoverageIgnore
*/ */
class Payment class Payment
{ {

View File

@@ -55,6 +55,7 @@ class FixerIOv2 implements ExchangeRateInterface
* @param Carbon $date * @param Carbon $date
* *
* @return CurrencyExchangeRate * @return CurrencyExchangeRate
* @throws Exception
*/ */
public function getRate(TransactionCurrency $fromCurrency, TransactionCurrency $toCurrency, Carbon $date): CurrencyExchangeRate public function getRate(TransactionCurrency $fromCurrency, TransactionCurrency $toCurrency, Carbon $date): CurrencyExchangeRate
{ {

View File

@@ -33,6 +33,7 @@ use Log;
/** /**
* Class RatesApiIOv1. * Class RatesApiIOv1.
* @codeCoverageIgnore
*/ */
class RatesApiIOv1 implements ExchangeRateInterface class RatesApiIOv1 implements ExchangeRateInterface
{ {

View File

@@ -34,6 +34,7 @@ use SimpleXMLElement;
/** /**
* Class UpdateRequest * Class UpdateRequest
* @codeCoverageIgnore
*/ */
class UpdateRequest implements GithubRequest class UpdateRequest implements GithubRequest
{ {

View File

@@ -31,6 +31,7 @@ use RuntimeException;
/** /**
* Class IpifyOrg * Class IpifyOrg
* @codeCoverageIgnore
*/ */
class IpifyOrg implements IPRetrievalInterface class IpifyOrg implements IPRetrievalInterface
{ {

View File

@@ -40,6 +40,8 @@ class AccountDestroyService
{ {
/** /**
* Constructor. * Constructor.
*
* @codeCoverageIgnore
*/ */
public function __construct() public function __construct()
{ {
@@ -53,18 +55,38 @@ class AccountDestroyService
* @param Account|null $moveTo * @param Account|null $moveTo
* *
* @return void * @return void
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/ */
public function destroy(Account $account, ?Account $moveTo): void public function destroy(Account $account, ?Account $moveTo): void
{ {
if (null !== $moveTo) { if (null !== $moveTo) {
DB::table('transactions')->where('account_id', $account->id)->update(['account_id' => $moveTo->id]); $this->moveTransactions($account, $moveTo);
$this->updateRecurrences($account, $moveTo);
// also update recurring transactions:
DB::table('recurrences_transactions')->where('source_id', $account->id)->update(['source_id' => $moveTo->id]);
DB::table('recurrences_transactions')->where('destination_id', $account->id)->update(['destination_id' => $moveTo->id]);
} }
$this->destroyJournals($account);
// delete recurring transactions with this account:
if (null === $moveTo) {
$this->destroyRecurrences($account);
}
// delete piggy banks:
PiggyBank::where('account_id', $account->id)->delete();
// delete account.
try {
$account->delete();
} catch (Exception $e) { // @codeCoverageIgnore
Log::error(sprintf('Could not delete account: %s', $e->getMessage())); // @codeCoverageIgnore
}
}
/**
* @param Account $account
*/
private function destroyJournals(Account $account): void
{
/** @var JournalDestroyService $service */
$service = app(JournalDestroyService::class); $service = app(JournalDestroyService::class);
Log::debug('Now trigger account delete response #' . $account->id); Log::debug('Now trigger account delete response #' . $account->id);
@@ -75,37 +97,49 @@ class AccountDestroyService
$journal = $transaction->transactionJournal()->first(); $journal = $transaction->transactionJournal()->first();
if (null !== $journal) { if (null !== $journal) {
Log::debug('Call for deletion of journal #' . $journal->id); Log::debug('Call for deletion of journal #' . $journal->id);
/** @var JournalDestroyService $service */
$service->destroy($journal); $service->destroy($journal);
} }
} }
}
// delete recurring transactions with this account: /**
if (null === $moveTo) { * @param Account $account
$recurrences = RecurrenceTransaction:: */
where( private function destroyRecurrences(Account $account): void
function (Builder $q) use ($account) { {
$q->where('source_id', $account->id); $recurrences = RecurrenceTransaction::
$q->orWhere('destination_id', $account->id); where(
} static function (Builder $q) use ($account) {
)->get(['recurrence_id'])->pluck('recurrence_id')->toArray(); $q->where('source_id', $account->id);
$q->orWhere('destination_id', $account->id);
$destroyService = new RecurrenceDestroyService();
foreach ($recurrences as $recurrenceId) {
$destroyService->destroyById((int)$recurrenceId);
} }
} )->get(['recurrence_id'])->pluck('recurrence_id')->toArray();
// delete piggy banks: /** @var RecurrenceDestroyService $destroyService */
PiggyBank::where('account_id', $account->id)->delete(); $destroyService = app(RecurrenceDestroyService::class);
foreach ($recurrences as $recurrenceId) {
try { $destroyService->destroyById((int)$recurrenceId);
$account->delete();
} catch (Exception $e) { // @codeCoverageIgnore
Log::error(sprintf('Could not delete account: %s', $e->getMessage())); // @codeCoverageIgnore
} }
} }
/**
* @param Account $account
* @param Account $moveTo
*/
private function moveTransactions(Account $account, Account $moveTo): void
{
DB::table('transactions')->where('account_id', $account->id)->update(['account_id' => $moveTo->id]);
}
/**
* @param Account $account
* @param Account $moveTo
*/
private function updateRecurrences(Account $account, Account $moveTo): void
{
DB::table('recurrences_transactions')->where('source_id', $account->id)->update(['source_id' => $moveTo->id]);
DB::table('recurrences_transactions')->where('destination_id', $account->id)->update(['destination_id' => $moveTo->id]);
}
} }

View File

@@ -30,6 +30,7 @@ use Log;
/** /**
* Class BudgetDestroyService * Class BudgetDestroyService
* @codeCoverageIgnore
*/ */
class BudgetDestroyService class BudgetDestroyService
{ {

View File

@@ -30,6 +30,7 @@ use Log;
/** /**
* Class CategoryDestroyService * Class CategoryDestroyService
* @codeCoverageIgnore
*/ */
class CategoryDestroyService class CategoryDestroyService
{ {

View File

@@ -29,6 +29,7 @@ use Log;
/** /**
* Class CurrencyDestroyService * Class CurrencyDestroyService
* @codeCoverageIgnore
*/ */
class CurrencyDestroyService class CurrencyDestroyService
{ {

View File

@@ -23,9 +23,12 @@ declare(strict_types=1);
namespace FireflyIII\Services\Internal\Destroy; namespace FireflyIII\Services\Internal\Destroy;
use DB;
use Exception; use Exception;
use FireflyIII\Models\Attachment;
use FireflyIII\Models\Transaction; use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionJournalLink;
use FireflyIII\Models\TransactionJournalMeta; use FireflyIII\Models\TransactionJournalMeta;
use Log; use Log;
@@ -58,12 +61,42 @@ class JournalDestroyService
} }
// also delete journal_meta entries. // also delete journal_meta entries.
/** @var TransactionJournalMeta $meta */ /** @var TransactionJournalMeta $meta */
foreach ($journal->transactionJournalMeta()->get() as $meta) { foreach ($journal->transactionJournalMeta()->get() as $meta) {
Log::debug(sprintf('Will now delete meta-entry #%d', $meta->id)); Log::debug(sprintf('Will now delete meta-entry #%d', $meta->id));
$meta->delete(); $meta->delete();
} }
// also delete attachments.
/** @var Attachment $attachment */
foreach ($journal->attachments()->get() as $attachment) {
$attachment->delete();
}
// delete all from 'budget_transaction_journal'
DB::table('budget_transaction_journal')
->where('transaction_journal_id', $journal->id)->delete();
// delete all from 'category_transaction_journal'
DB::table('category_transaction_journal')
->where('transaction_journal_id', $journal->id)->delete();
// delete all from 'tag_transaction_journal'
DB::table('tag_transaction_journal')
->where('transaction_journal_id', $journal->id)->delete();
// delete all links:
TransactionJournalLink::where('source_id', $journal->id)->delete();
TransactionJournalLink::where('destination_id', $journal->id)->delete();
// delete all notes
$journal->notes()->delete();
// update events
$journal->piggyBankEvents()->update(['transaction_journal_id' => null]);
$journal->delete(); $journal->delete();
} catch (Exception $e) { } catch (Exception $e) {
Log::error(sprintf('Could not delete bill: %s', $e->getMessage())); // @codeCoverageIgnore Log::error(sprintf('Could not delete bill: %s', $e->getMessage())); // @codeCoverageIgnore

View File

@@ -28,6 +28,7 @@ use FireflyIII\Models\TransactionGroup;
/** /**
* Class TransactionGroupDestroyService * Class TransactionGroupDestroyService
* @codeCoverageIgnore
*/ */
class TransactionGroupDestroyService class TransactionGroupDestroyService
{ {

View File

@@ -1,71 +0,0 @@
<?php
/**
* EncryptService.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Services\Internal\File;
use Crypt;
use FireflyIII\Exceptions\FireflyException;
use Illuminate\Contracts\Encryption\EncryptException;
use Illuminate\Support\Facades\Storage;
use Log;
/**
* Class EncryptService
*/
class EncryptService
{
/**
* Constructor.
*/
public function __construct()
{
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
}
}
/**
* @param string $file
* @param string $key
*
* @throws FireflyException
*/
public function encrypt(string $file, string $key): void
{
if (!file_exists($file)) {
throw new FireflyException(sprintf('File "%s" does not seem to exist.', $file));
}
$content = file_get_contents($file);
try {
$content = Crypt::encrypt($content);
} catch (EncryptException $e) {
$message = sprintf('Could not encrypt file: %s', $e->getMessage());
Log::error($message);
throw new FireflyException($message);
}
$newName = sprintf('%s.upload', $key);
$disk = Storage::disk('upload');
$disk->put($newName, $content);
}
}

View File

@@ -105,60 +105,11 @@ trait AccountServiceTrait
} }
} }
// /**
// * @param User $user
// * @param string $name
// *
// * @return Account
// * @throws \FireflyIII\Exceptions\FireflyException
// */
// public function storeOpposingAccount(User $user, string $name): Account
// {
// $opposingAccountName = (string)trans('firefly.initial_balance_account', ['name' => $name]);
// Log::debug('Going to create an opening balance opposing account.');
// /** @var AccountFactory $factory */
// $factory = app(AccountFactory::class);
// $factory->setUser($user);
//
// return $factory->findOrCreate($opposingAccountName, AccountType::INITIAL_BALANCE);
// }
// /**
// * @param Account $account
// * @param array $data
// *
// * @return bool
// * @throws \FireflyIII\Exceptions\FireflyException
// */
// public function updateOB(Account $account, array $data): bool
// {
// Log::debug(sprintf('updateIB() for account #%d', $account->id));
//
// $openingBalanceGroup = $this->getOBGroup($account);
//
// // no opening balance journal? create it:
// if (null === $openingBalanceGroup) {
// Log::debug('No opening balance journal yet, create group.');
// $this->storeOBGroup($account, $data);
//
// return true;
// }
//
// // opening balance data? update it!
// if (null !== $openingBalanceGroup->id) {
// Log::debug('Opening balance group found, update group.');
// $this->updateOBGroup($account, $openingBalanceGroup, $data);
//
// return true;
// }
//
// return true; // @codeCoverageIgnore
// }
/** /**
* @param Account $account * @param Account $account
* @param string $note * @param string $note
* *
* @codeCoverageIgnore
* @return bool * @return bool
*/ */
public function updateNote(Account $account, string $note): bool public function updateNote(Account $account, string $note): bool
@@ -186,117 +137,6 @@ trait AccountServiceTrait
return true; return true;
} }
// /**
// * Find existing opening balance.
// *
// * @param Account $account
// *
// * @return TransactionJournal|null
// */
// public function getIBJournal(Account $account): ?TransactionJournal
// {
// $journal = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
// ->where('transactions.account_id', $account->id)
// ->transactionTypes([TransactionType::OPENING_BALANCE])
// ->first(['transaction_journals.*']);
// if (null === $journal) {
// Log::debug('Could not find a opening balance journal, return NULL.');
//
// return null;
// }
// Log::debug(sprintf('Found opening balance: journal #%d.', $journal->id));
//
// return $journal;
// }
// /**
// * @param Account $account
// * @param array $data
// *
// * @return TransactionJournal|null
// * @throws \FireflyIII\Exceptions\FireflyException
// * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
// */
// public function storeIBJournal(Account $account, array $data): ?TransactionJournal
// {
// $amount = (string)$data['openingBalance'];
// Log::debug(sprintf('Submitted amount is %s', $amount));
//
// if (0 === bccomp($amount, '0')) {
// return null;
// }
//
// // store journal, without transactions:
// $name = $data['name'];
// $currencyId = $data['currency_id'];
// $journalData = [
// 'type' => TransactionType::OPENING_BALANCE,
// 'user' => $account->user->id,
// 'transaction_currency_id' => $currencyId,
// 'description' => (string)trans('firefly.initial_balance_description', ['account' => $account->name]),
// 'completed' => true,
// 'date' => $data['openingBalanceDate'],
// 'bill_id' => null,
// 'bill_name' => null,
// 'piggy_bank_id' => null,
// 'piggy_bank_name' => null,
// 'tags' => null,
// 'notes' => null,
// 'transactions' => [],
//
// ];
// /** @var TransactionJournalFactory $factory */
// $factory = app(TransactionJournalFactory::class);
// $factory->setUser($account->user);
// $journal = $factory->create($journalData);
// $opposing = $this->storeOpposingAccount($account->user, $name);
// Log::notice(sprintf('Created new opening balance journal: #%d', $journal->id));
//
// $firstAccount = $account;
// $secondAccount = $opposing;
// $firstAmount = $amount;
// $secondAmount = bcmul($amount, '-1');
// Log::notice(sprintf('First amount is %s, second amount is %s', $firstAmount, $secondAmount));
//
// if (bccomp($amount, '0') === -1) {
// Log::debug(sprintf('%s is a negative number.', $amount));
// $firstAccount = $opposing;
// $secondAccount = $account;
// $firstAmount = bcmul($amount, '-1');
// $secondAmount = $amount;
// Log::notice(sprintf('First amount is %s, second amount is %s', $firstAmount, $secondAmount));
// }
// /** @var TransactionFactory $factory */
// $factory = app(TransactionFactory::class);
// $factory->setUser($account->user);
// $factory->create(
// [
// 'account' => $firstAccount,
// 'transaction_journal' => $journal,
// 'amount' => $firstAmount,
// 'currency_id' => $currencyId,
// 'description' => null,
// 'identifier' => 0,
// 'foreign_amount' => null,
// 'reconciled' => false,
// ]
// );
// $factory->create(
// [
// 'account' => $secondAccount,
// 'transaction_journal' => $journal,
// 'amount' => $secondAmount,
// 'currency_id' => $currencyId,
// 'description' => null,
// 'identifier' => 0,
// 'foreign_amount' => null,
// 'reconciled' => false,
// ]
// );
//
// return $journal;
// }
/** /**
* Verify if array contains valid data to possibly store or update the opening balance. * Verify if array contains valid data to possibly store or update the opening balance.
* *
@@ -340,52 +180,6 @@ trait AccountServiceTrait
return $currency; return $currency;
} }
// /**
// * @param Account $account
// * @param TransactionJournal $journal
// * @param array $data
// *
// * @return bool
// * @SuppressWarnings(PHPMD.CyclomaticComplexity)
// */
// protected function updateIBJournal(Account $account, TransactionJournal $journal, array $data): bool
// {
// $date = $data['openingBalanceDate'];
// $amount = (string)$data['openingBalance'];
// $negativeAmount = bcmul($amount, '-1');
// $currencyId = (int)$data['currency_id'];
// Log::debug(sprintf('Submitted amount for opening balance to update is "%s"', $amount));
// if (0 === bccomp($amount, '0')) {
// Log::notice(sprintf('Amount "%s" is zero, delete opening balance.', $amount));
// /** @var JournalDestroyService $service */
// $service = app(JournalDestroyService::class);
// $service->destroy($journal);
//
// return true;
// }
// $journal->date = $date;
// $journal->transaction_currency_id = $currencyId;
// $journal->save();
// /** @var Transaction $transaction */
// foreach ($journal->transactions()->get() as $transaction) {
// if ((int)$account->id === (int)$transaction->account_id) {
// Log::debug(sprintf('Will (eq) change transaction #%d amount from "%s" to "%s"', $transaction->id, $transaction->amount, $amount));
// $transaction->amount = $amount;
// $transaction->transaction_currency_id = $currencyId;
// $transaction->save();
// }
// if (!((int)$account->id === (int)$transaction->account_id)) {
// Log::debug(sprintf('Will (neq) change transaction #%d amount from "%s" to "%s"', $transaction->id, $transaction->amount, $negativeAmount));
// $transaction->amount = $negativeAmount;
// $transaction->transaction_currency_id = $currencyId;
// $transaction->save();
// }
// }
// Log::debug('Updated opening balance journal.');
//
// return true;
// }
/** /**
* Delete TransactionGroup with opening balance in it. * Delete TransactionGroup with opening balance in it.
* *
@@ -486,7 +280,9 @@ trait AccountServiceTrait
* *
* @param Account $account * @param Account $account
* @param array $data * @param array $data
*
* @return TransactionGroup|null * @return TransactionGroup|null
* @codeCoverageIgnore
*/ */
protected function updateOBGroup(Account $account, array $data): ?TransactionGroup protected function updateOBGroup(Account $account, array $data): ?TransactionGroup
{ {

View File

@@ -32,7 +32,7 @@ use Log;
/** /**
* Trait BillServiceTrait * Trait BillServiceTrait
* * @codeCoverageIgnore
*/ */
trait BillServiceTrait trait BillServiceTrait
{ {

View File

@@ -57,6 +57,7 @@ trait JournalServiceTrait
* @param string|null $amount * @param string|null $amount
* *
* @return string * @return string
* @codeCoverageIgnore
*/ */
protected function getForeignAmount(?string $amount): ?string protected function getForeignAmount(?string $amount): ?string
{ {
@@ -87,6 +88,7 @@ trait JournalServiceTrait
* @param string|null $accountName * @param string|null $accountName
* *
* @return Account * @return Account
* @codeCoverageIgnore
*/ */
protected function getAccount(string $transactionType, string $direction, ?int $accountId, ?string $accountName): Account protected function getAccount(string $transactionType, string $direction, ?int $accountId, ?string $accountName): Account
{ {
@@ -166,6 +168,7 @@ trait JournalServiceTrait
* *
* @return string * @return string
* @throws FireflyException * @throws FireflyException
* @codeCoverageIgnore
*/ */
protected function getAmount(string $amount): string protected function getAmount(string $amount): string
{ {
@@ -182,6 +185,8 @@ trait JournalServiceTrait
/** /**
* @param TransactionJournal $journal * @param TransactionJournal $journal
* @param NullArrayObject $data * @param NullArrayObject $data
*
* @codeCoverageIgnore
*/ */
protected function storeBudget(TransactionJournal $journal, NullArrayObject $data): void protected function storeBudget(TransactionJournal $journal, NullArrayObject $data): void
{ {
@@ -204,6 +209,8 @@ trait JournalServiceTrait
/** /**
* @param TransactionJournal $journal * @param TransactionJournal $journal
* @param NullArrayObject $data * @param NullArrayObject $data
*
* @codeCoverageIgnore
*/ */
protected function storeCategory(TransactionJournal $journal, NullArrayObject $data): void protected function storeCategory(TransactionJournal $journal, NullArrayObject $data): void
{ {
@@ -221,6 +228,8 @@ trait JournalServiceTrait
/** /**
* @param TransactionJournal $journal * @param TransactionJournal $journal
* @param string $notes * @param string $notes
*
* @codeCoverageIgnore
*/ */
protected function storeNotes(TransactionJournal $journal, ?string $notes): void protected function storeNotes(TransactionJournal $journal, ?string $notes): void
{ {
@@ -255,6 +264,8 @@ trait JournalServiceTrait
* @param TransactionJournal $journal * @param TransactionJournal $journal
* @param array $tags * @param array $tags
* @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.CyclomaticComplexity)
*
* @codeCoverageIgnore
*/ */
protected function storeTags(TransactionJournal $journal, ?array $tags): void protected function storeTags(TransactionJournal $journal, ?array $tags): void
{ {
@@ -276,147 +287,4 @@ trait JournalServiceTrait
} }
//
// /**
// * Link tags to journal.
// *
// * @param TransactionJournal $journal
// * @param array $data
// * @SuppressWarnings(PHPMD.CyclomaticComplexity)
// */
// public function connectTags(TransactionJournal $journal, array $data): void
// {
// /** @var TagFactory $factory */
// $factory = app(TagFactory::class);
// $factory->setUser($journal->user);
// $set = [];
// if (!is_array($data['tags'])) {
// return; // @codeCoverageIgnore
// }
// foreach ($data['tags'] as $string) {
// if ('' !== $string) {
// $tag = $factory->findOrCreate($string);
// if (null !== $tag) {
// $set[] = $tag->id;
// }
// }
// }
// $journal->tags()->sync($set);
// }
//
//
// /**
// * @param int|null $budgetId
// * @param null|string $budgetName
// *
// * @return Budget|null
// */
// protected function findBudget(?int $budgetId, ?string $budgetName): ?Budget
// {
// /** @var BudgetFactory $factory */
// $factory = app(BudgetFactory::class);
// $factory->setUser($this->user);
//
// return $factory->find($budgetId, $budgetName);
// }
//
// /**
// * @param int|null $categoryId
// * @param null|string $categoryName
// *
// * @return Category|null
// */
// protected function findCategory(?int $categoryId, ?string $categoryName): ?Category
// {
// Log::debug(sprintf('Going to find or create category #%d, with name "%s"', $categoryId, $categoryName));
// /** @var CategoryFactory $factory */
// $factory = app(CategoryFactory::class);
// $factory->setUser($this->user);
//
// return $factory->findOrCreate($categoryId, $categoryName);
// }
//
//
// /**
// * @param TransactionJournal $journal
// * @param Budget|null $budget
// */
// protected function setBudget(TransactionJournal $journal, ?Budget $budget): void
// {
// if (null === $budget) {
// $journal->budgets()->sync([]);
//
// return;
// }
// $journal->budgets()->sync([$budget->id]);
//
// }
//
//
// /**
// * @param TransactionJournal $journal
// * @param Category|null $category
// */
// protected function setCategory(TransactionJournal $journal, ?Category $category): void
// {
// if (null === $category) {
// $journal->categories()->sync([]);
//
// return;
// }
// $journal->categories()->sync([$category->id]);
//
// }
//
//
// /**
// * @param TransactionJournal $journal
// * @param array $data
// * @param string $field
// */
// protected function storeMeta(TransactionJournal $journal, array $data, string $field): void
// {
// $set = [
// 'journal' => $journal,
// 'name' => $field,
// 'data' => (string)($data[$field] ?? ''),
// ];
//
// Log::debug(sprintf('Going to store meta-field "%s", with value "%s".', $set['name'], $set['data']));
//
// /** @var TransactionJournalMetaFactory $factory */
// $factory = app(TransactionJournalMetaFactory::class);
// $factory->updateOrCreate($set);
// }
//
// /**
// * @param TransactionJournal $journal
// * @param string $notes
// */
// protected function storeNote(TransactionJournal $journal, ?string $notes): void
// {
// $notes = (string)$notes;
// if ('' !== $notes) {
// $note = $journal->notes()->first();
// if (null === $note) {
// $note = new Note;
// $note->noteable()->associate($journal);
// }
// $note->text = $notes;
// $note->save();
//
// return;
// }
// $note = $journal->notes()->first();
// if (null !== $note) {
// try {
// $note->delete();
// } catch (Exception $e) {
// Log::debug(sprintf('Journal service trait could not delete note: %s', $e->getMessage()));
// }
// }
//
//
// }
} }

View File

@@ -205,6 +205,8 @@ trait RecurringTransactionTrait
/** /**
* @param Recurrence $recurrence * @param Recurrence $recurrence
*
* @codeCoverageIgnore
*/ */
protected function deleteRepetitions(Recurrence $recurrence): void protected function deleteRepetitions(Recurrence $recurrence): void
{ {
@@ -213,6 +215,8 @@ trait RecurringTransactionTrait
/** /**
* @param Recurrence $recurrence * @param Recurrence $recurrence
*
* @codeCoverageIgnore
*/ */
protected function deleteTransactions(Recurrence $recurrence): void protected function deleteTransactions(Recurrence $recurrence): void
{ {

View File

@@ -1,171 +0,0 @@
<?php
/**
* TransactionServiceTrait.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Services\Internal\Support;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Factory\AccountFactory;
use FireflyIII\Factory\TransactionCurrencyFactory;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use Log;
/**
* Trait TransactionServiceTrait
*
*/
trait TransactionServiceTrait
{
// /**
// * @param TransactionJournal $journal
// * @param string $direction
// *
// * @return string|null
// * @SuppressWarnings(PHPMD.CyclomaticComplexity)
// */
// public function accountType(TransactionJournal $journal, string $direction): ?string
// {
// $types = [];
// $type = $journal->transactionType->type;
// if (TransactionType::WITHDRAWAL === $type) {
// $types['source'] = AccountType::ASSET;
// $types['destination'] = AccountType::EXPENSE;
// }
// if (TransactionType::DEPOSIT === $type) {
// $types['source'] = AccountType::REVENUE;
// $types['destination'] = AccountType::ASSET;
// }
// if (TransactionType::TRANSFER === $type) {
// $types['source'] = AccountType::ASSET;
// $types['destination'] = AccountType::ASSET;
// }
// if (TransactionType::RECONCILIATION === $type) {
// $types['source'] = null;
// $types['destination'] = null;
// }
//
// return $types[$direction] ?? null;
// }
// /**
// * @param string|null $expectedType
// * @param Account|null $account
// * @param int|null $accountId
// * @param string|null $accountName
// *
// * @return Account|null
// * @throws FireflyException
// * @SuppressWarnings(PHPMD.CyclomaticComplexity)
// */
// public function findAccount(?string $expectedType, ?Account $account, ?int $accountId, ?string $accountName): ?Account
// {
// $result = null;
//
// if (null !== $account && $account->user_id === $this->user->id) {
// return $account;
// }
//
// $accountId = (int)$accountId;
// $accountName = (string)$accountName;
// $repository = app(AccountRepositoryInterface::class);
// $repository->setUser($this->user);
//
// if (null === $expectedType) {
// return $repository->findNull($accountId);
// }
//
// if ($accountId > 0) {
// // must be able to find it based on ID. Validator should catch invalid ID's.
// return $repository->findNull($accountId);
// }
// if (AccountType::ASSET === $expectedType) {
// return $repository->findByName($accountName, [AccountType::ASSET]);
// }
// // for revenue and expense:
// if ('' !== $accountName) {
// /** @var AccountFactory $factory */
// $factory = app(AccountFactory::class);
// $factory->setUser($this->user);
//
// return $factory->findOrCreate($accountName, $expectedType);
// }
//
// return $repository->getCashAccount();
// }
// /**
// * @param int|null $currencyId
// * @param null|string $currencyCode
// *
// * @return TransactionCurrency|null
// */
// protected function findCurrency(?int $currencyId, ?string $currencyCode): ?TransactionCurrency
// {
// $factory = app(TransactionCurrencyFactory::class);
//
// return $factory->find($currencyId, $currencyCode);
// }
//
// /**
// * @param Transaction $transaction
// * @param string|null $amount
// */
// protected function setForeignAmount(Transaction $transaction, ?string $amount): void
// {
// $amount = '' === (string)$amount ? null : $amount;
// $transaction->foreign_amount = $amount;
// $transaction->save();
// }
//
// /**
// * @param Transaction $transaction
// * @param TransactionCurrency|null $currency
// */
// protected function setForeignCurrency(Transaction $transaction, ?TransactionCurrency $currency): void
// {
// if (null === $currency) {
// $transaction->foreign_currency_id = null;
// $transaction->save();
//
// return;
// }
// // enable currency if not enabled:
// if (false === $currency->enabled) {
// $currency->enabled = true;
// $currency->save();
// }
//
// $transaction->foreign_currency_id = $currency->id;
// $transaction->save();
//
// }
}

View File

@@ -29,6 +29,7 @@ use FireflyIII\Models\AccountType;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Services\Internal\Support\AccountServiceTrait; use FireflyIII\Services\Internal\Support\AccountServiceTrait;
use FireflyIII\User;
use Log; use Log;
/** /**
@@ -43,6 +44,8 @@ class AccountUpdateService
/** @var AccountRepositoryInterface */ /** @var AccountRepositoryInterface */
protected $accountRepository; protected $accountRepository;
/** @var User */
private $user;
/** /**
* Constructor. * Constructor.
*/ */
@@ -67,6 +70,7 @@ class AccountUpdateService
public function update(Account $account, array $data): Account public function update(Account $account, array $data): Account
{ {
$this->accountRepository->setUser($account->user); $this->accountRepository->setUser($account->user);
$this->user = $account->user;
// update the account itself: // update the account itself:
$account->name = $data['name']; $account->name = $data['name'];
@@ -91,10 +95,13 @@ class AccountUpdateService
// has valid initial balance (IB) data? // has valid initial balance (IB) data?
$type = $account->accountType; $type = $account->accountType;
// if it can have a virtual balance, it can also have an opening balance. // if it can have a virtual balance, it can also have an opening balance.
if (in_array($type->type, $this->canHaveVirtual, true)) { if (in_array($type->type, $this->canHaveVirtual, true)) {
if ($this->validOBData($data)) { if ($this->validOBData($data)) {
$this->updateOBGroup($account, $data); $this->updateOBGroup($account, $data);
} }
if (!$this->validOBData($data)) { if (!$this->validOBData($data)) {
$this->deleteOBGroup($account); $this->deleteOBGroup($account);
} }

View File

@@ -28,6 +28,7 @@ use Log;
/** /**
* Class CategoryUpdateService * Class CategoryUpdateService
* @codeCoverageIgnore
*/ */
class CategoryUpdateService class CategoryUpdateService
{ {

View File

@@ -28,6 +28,7 @@ use Log;
/** /**
* Class CurrencyUpdateService * Class CurrencyUpdateService
* @codeCoverageIgnore
*/ */
class CurrencyUpdateService class CurrencyUpdateService
{ {

View File

@@ -31,6 +31,7 @@ use Log;
/** /**
* Class GroupUpdateService * Class GroupUpdateService
* TODO test.
*/ */
class GroupUpdateService class GroupUpdateService
{ {

View File

@@ -48,6 +48,7 @@ use Log;
* Class to centralise code that updates a journal given the input by system. * Class to centralise code that updates a journal given the input by system.
* *
* Class JournalUpdateService * Class JournalUpdateService
* TODO test me
*/ */
class JournalUpdateService class JournalUpdateService
{ {

View File

@@ -26,16 +26,16 @@ namespace FireflyIII\Services\Internal\Update;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Recurrence; use FireflyIII\Models\Recurrence;
use FireflyIII\Services\Internal\Support\RecurringTransactionTrait; use FireflyIII\Services\Internal\Support\RecurringTransactionTrait;
use FireflyIII\Services\Internal\Support\TransactionServiceTrait;
use FireflyIII\Services\Internal\Support\TransactionTypeTrait; use FireflyIII\Services\Internal\Support\TransactionTypeTrait;
use FireflyIII\User; use FireflyIII\User;
/** /**
* Class RecurrenceUpdateService * Class RecurrenceUpdateService
* @codeCoverageIgnore
*/ */
class RecurrenceUpdateService class RecurrenceUpdateService
{ {
use TransactionTypeTrait, TransactionServiceTrait, RecurringTransactionTrait; use TransactionTypeTrait, RecurringTransactionTrait;
/** @var User */ /** @var User */
private $user; private $user;
@@ -51,7 +51,6 @@ class RecurrenceUpdateService
*/ */
public function update(Recurrence $recurrence, array $data): Recurrence public function update(Recurrence $recurrence, array $data): Recurrence
{ {
// is expected by TransactionServiceTrait
$this->user = $recurrence->user; $this->user = $recurrence->user;
$transactionType = $this->findTransactionType(ucfirst($data['recurrence']['type'])); $transactionType = $this->findTransactionType(ucfirst($data['recurrence']['type']));
// update basic fields first: // update basic fields first:

View File

@@ -1,179 +0,0 @@
<?php
/**
* TransactionUpdateService.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Services\Internal\Update;
use FireflyIII\Models\Transaction;
use FireflyIII\Services\Internal\Support\TransactionServiceTrait;
use FireflyIII\User;
use Log;
/**
* Class TransactionUpdateService
* TODO i think this is deprecated.
*/
class TransactionUpdateService
{
use TransactionServiceTrait;
/** @var User */
private $user;
/**
* Constructor.
*/
public function __construct()
{
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
}
}
// /**
// * @param int $transactionId
// *
// * @return Transaction|null
// */
// public function reconcile(int $transactionId): ?Transaction
// {
// $transaction = Transaction::find($transactionId);
// if (null !== $transaction) {
// $transaction->reconciled = true;
// $transaction->save();
//
// return $transaction;
// }
//
// return null;
//
// }
/**
* @param User $user
*/
public function setUser(User $user): void
{
$this->user = $user;
}
// /**
// * @param Transaction $transaction
// * @param array $data
// *
// * @return Transaction
// * @throws \FireflyIII\Exceptions\FireflyException
// * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
// * @SuppressWarnings(PHPMD.CyclomaticComplexity)
// * @SuppressWarnings(PHPMD.NPathComplexity)
// *
// */
// public function update(Transaction $transaction, array $data): Transaction
// {
// $currency = $this->findCurrency($data['currency_id'], $data['currency_code']);
// $journal = $transaction->transactionJournal;
// $amount = (string)$data['amount'];
// $account = null;
// // update description:
// $transaction->description = $data['description'];
// $foreignAmount = null;
// if ((float)$transaction->amount < 0) {
// // this is the source transaction.
// $type = $this->accountType($journal, 'source');
// $account = $this->findAccount($type, $data['source_id'], $data['source_name']);
// $amount = app('steam')->negative($amount);
// $foreignAmount = app('steam')->negative((string)$data['foreign_amount']);
// }
//
// if ((float)$transaction->amount > 0) {
// // this is the destination transaction.
// $type = $this->accountType($journal, 'destination');
// $account = $this->findAccount($type, $data['destination_id'], $data['destination_name']);
// $amount = app('steam')->positive($amount);
// $foreignAmount = app('steam')->positive((string)$data['foreign_amount']);
// }
//
// // update the actual transaction:
// $transaction->description = $data['description'];
// $transaction->amount = $amount;
// $transaction->foreign_amount = null;
// $transaction->transaction_currency_id = null === $currency ? $transaction->transaction_currency_id : $currency->id;
// $transaction->account_id = $account->id;
// $transaction->reconciled = $data['reconciled'];
// $transaction->save();
//
// // set foreign currency
// $foreign = $this->findCurrency($data['foreign_currency_id'], $data['foreign_currency_code']);
// // set foreign amount:
// if (null !== $foreign && null !== $data['foreign_amount']) {
// $this->setForeignCurrency($transaction, $foreign);
// $this->setForeignAmount($transaction, $foreignAmount);
// }
// if (null === $foreign || null === $data['foreign_amount']) {
// $this->setForeignCurrency($transaction, null);
// $this->setForeignAmount($transaction, null);
// }
//
// // set budget:
// $budget = $this->findBudget($data['budget_id'], $data['budget_name']);
// $this->setBudget($transaction, $budget);
//
// // set category
// $category = $this->findCategory($data['category_id'], $data['category_name']);
// $this->setCategory($transaction, $category);
//
// return $transaction;
// }
//
// /**
// * Update budget for a journal.
// *
// * @param Transaction $transaction
// * @param int $budgetId
// *
// * @return Transaction
// */
// public function updateBudget(Transaction $transaction, int $budgetId): Transaction
// {
// $budget = $this->findBudget($budgetId, null);
// $this->setBudget($transaction, $budget);
//
// return $transaction;
//
// }
//
// /**
// * Update category for a journal.
// *
// * @param Transaction $transaction
// * @param string $category
// *
// * @return Transaction
// */
// public function updateCategory(Transaction $transaction, string $category): Transaction
// {
// $found = $this->findCategory(0, $category);
// $this->setCategory($transaction, $found);
//
// return $transaction;
// }
}

View File

@@ -30,6 +30,7 @@ use RuntimeException;
/** /**
* Class PwndVerifierV2. * Class PwndVerifierV2.
* @codeCoverageIgnore
*/ */
class PwndVerifierV2 implements Verifier class PwndVerifierV2 implements Verifier
{ {

View File

@@ -0,0 +1,92 @@
<?php
/**
* PwndVerifierV3.php
* Copyright (c) 2019 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
namespace FireflyIII\Services\Password;
use Exception;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Log;
use RuntimeException;
/**
* Class PwndVerifierV3
* @codeCoverageIgnore
*/
class PwndVerifierV3 implements Verifier
{
/**
* Verify the given password against (some) service.
*
* @param string $password
*
* @return bool
*/
public function validPassword(string $password): bool
{
Log::debug('Now in API v3.');
$hash = strtoupper(sha1($password));
$prefix = substr($hash, 0, 5);
$rest = substr($hash, 5);
$uri = sprintf('https://api.pwnedpasswords.com/%s/%s', 'range', $prefix);
Log::debug(sprintf('URI is %s', $uri));
$headers = [
'User-Agent' => sprintf('Firefly III v%s', config('firefly.version')),
];
Log::debug('Headers', $headers);
$opts = [
'headers' => $headers,
'timeout' => 5,
];
Log::debug(sprintf('hash prefix is %s', $prefix));
Log::debug(sprintf('rest is %s', $rest));
try {
$client = new Client;
$res = $client->request('GET', $uri, $opts);
} catch (GuzzleException|Exception $e) {
Log::error(sprintf('Could not verify password security: %s', $e->getMessage()));
return true;
}
Log::debug(sprintf('Status code returned is %d', $res->getStatusCode()));
if (404 === $res->getStatusCode()) {
return true;
}
$body = $res->getBody()->getContents();
try {
$strpos = stripos($body, $rest);
} catch (RuntimeException $e) {
Log::error(sprintf('Could not get body from Pwnd result: %s', $e->getMessage()));
$strpos = false;
}
if (false === $strpos) {
Log::debug(sprintf('%s was not found in result body. Return true.', $rest));
return true;
}
Log::debug(sprintf('Found %s, so return FALSE.', $rest));
return false;
}
}

View File

@@ -29,6 +29,7 @@ use FireflyIII\Services\Spectre\Object\Token;
/** /**
* Class CreateTokenRequest * Class CreateTokenRequest
* @codeCoverageIgnore
*/ */
class CreateTokenRequest extends SpectreRequest class CreateTokenRequest extends SpectreRequest
{ {

View File

@@ -30,6 +30,7 @@ use Log;
/** /**
* Class ListAccountsRequest * Class ListAccountsRequest
* @codeCoverageIgnore
*/ */
class ListAccountsRequest extends SpectreRequest class ListAccountsRequest extends SpectreRequest
{ {

View File

@@ -29,6 +29,7 @@ use Log;
/** /**
* Class ListCustomersRequest * Class ListCustomersRequest
* @codeCoverageIgnore
*/ */
class ListCustomersRequest extends SpectreRequest class ListCustomersRequest extends SpectreRequest
{ {

View File

@@ -31,6 +31,7 @@ use Log;
/** /**
* Class ListLoginsRequest * Class ListLoginsRequest
* @codeCoverageIgnore
*/ */
class ListLoginsRequest extends SpectreRequest class ListLoginsRequest extends SpectreRequest
{ {

View File

@@ -30,6 +30,7 @@ use Log;
/** /**
* Class ListTransactionsRequest * Class ListTransactionsRequest
* @codeCoverageIgnore
*/ */
class ListTransactionsRequest extends SpectreRequest class ListTransactionsRequest extends SpectreRequest
{ {

View File

@@ -27,6 +27,7 @@ use Log;
/** /**
* Class NewCustomerRequest * Class NewCustomerRequest
* @codeCoverageIgnore
*/ */
class NewCustomerRequest extends SpectreRequest class NewCustomerRequest extends SpectreRequest
{ {

View File

@@ -32,6 +32,7 @@ use RuntimeException;
/** /**
* Class SpectreRequest * Class SpectreRequest
* @codeCoverageIgnore
*/ */
abstract class SpectreRequest abstract class SpectreRequest
{ {

View File

@@ -27,6 +27,7 @@ use Log;
/** /**
* Class GetAccountsRequest * Class GetAccountsRequest
* @codeCoverageIgnore
*/ */
class GetAccountsRequest extends YnabRequest class GetAccountsRequest extends YnabRequest
{ {

View File

@@ -27,6 +27,7 @@ use Log;
/** /**
* Class GetBudgetsRequest * Class GetBudgetsRequest
* @codeCoverageIgnore
*/ */
class GetBudgetsRequest extends YnabRequest class GetBudgetsRequest extends YnabRequest
{ {

View File

@@ -27,6 +27,7 @@ use Log;
/** /**
* Class GetTransactionsRequest * Class GetTransactionsRequest
* @codeCoverageIgnore
*/ */
class GetTransactionsRequest extends YnabRequest class GetTransactionsRequest extends YnabRequest
{ {

View File

@@ -30,6 +30,7 @@ use RuntimeException;
/** /**
* Class YnabRequest * Class YnabRequest
* @codeCoverageIgnore
*/ */
abstract class YnabRequest abstract class YnabRequest
{ {

View File

@@ -33,6 +33,7 @@ use Preferences as Prefs;
/** /**
* Class Amount. * Class Amount.
* @codeCoverageIgnore
*/ */
class Amount class Amount
{ {

View File

@@ -27,6 +27,7 @@ use Illuminate\Support\Collection;
/** /**
* Class CacheProperties. * Class CacheProperties.
* @codeCoverageIgnore
*/ */
class CacheProperties class CacheProperties
{ {

View File

@@ -24,6 +24,7 @@ namespace FireflyIII\Support;
/** /**
* Class ChartColour. * Class ChartColour.
* @codeCoverageIgnore
*/ */
class ChartColour class ChartColour
{ {

View File

@@ -25,6 +25,7 @@ namespace FireflyIII\Support\Cronjobs;
/** /**
* Class AbstractCronjob * Class AbstractCronjob
* @codeCoverageIgnore
*/ */
abstract class AbstractCronjob abstract class AbstractCronjob
{ {

View File

@@ -99,13 +99,7 @@ class RecurringCronjob extends AbstractCronjob
Log::info(sprintf('It has been %s since the recurring transactions cron-job has fired. It will fire now!', $diffForHumans)); Log::info(sprintf('It has been %s since the recurring transactions cron-job has fired. It will fire now!', $diffForHumans));
} }
try { $this->fireRecurring();
$this->fireRecurring();
} catch (FireflyException $e) {
Log::error($e->getMessage());
Log::error($e->getTraceAsString());
throw new FireflyException(sprintf('Could not run recurring transaction cron job: %s', $e->getMessage()));
}
app('preferences')->mark(); app('preferences')->mark();
@@ -114,12 +108,13 @@ class RecurringCronjob extends AbstractCronjob
/** /**
* *
* @throws FireflyException
*/ */
private function fireRecurring(): void private function fireRecurring(): void
{ {
Log::info(sprintf('Will now fire recurring cron job task for date "%s".', $this->date->format('Y-m-d'))); Log::info(sprintf('Will now fire recurring cron job task for date "%s".', $this->date->format('Y-m-d')));
$job = new CreateRecurringTransactions($this->date); /** @var CreateRecurringTransactions $job */
$job = app(CreateRecurringTransactions::class);
$job->setDate($this->date);
$job->setForce($this->force); $job->setForce($this->force);
$job->handle(); $job->handle();
app('fireflyconfig')->set('last_rt_job', (int)$this->date->format('U')); app('fireflyconfig')->set('last_rt_job', (int)$this->date->format('U'));

View File

@@ -24,6 +24,7 @@ namespace FireflyIII\Support;
/** /**
* Class Domain. * Class Domain.
* @codeCoverageIgnore
*/ */
class Domain class Domain
{ {

View File

@@ -48,6 +48,7 @@ use Throwable;
* *
* @SuppressWarnings(PHPMD.TooManyMethods) * @SuppressWarnings(PHPMD.TooManyMethods)
* @SuppressWarnings(PHPMD.TooManyPublicMethods) * @SuppressWarnings(PHPMD.TooManyPublicMethods)
* @codeCoverageIgnore
*/ */
class ExpandedForm class ExpandedForm
{ {

View File

@@ -27,7 +27,7 @@ use FireflyIII\Exceptions\FireflyException;
use Illuminate\Support\Facades\Crypt; use Illuminate\Support\Facades\Crypt;
/** /**
* * @codeCoverageIgnore
* Class FinTS * Class FinTS
*/ */
class FinTS class FinTS

View File

@@ -29,6 +29,7 @@ use Log;
/** /**
* Class FireflyConfig. * Class FireflyConfig.
* @codeCoverageIgnore
*/ */
class FireflyConfig class FireflyConfig
{ {

View File

@@ -27,6 +27,7 @@ use FireflyIII\Models\AccountType;
/** /**
* Trait AccountFilter * Trait AccountFilter
* @codeCoverageIgnore
*/ */
trait AccountFilter trait AccountFilter
{ {
@@ -78,10 +79,8 @@ trait AccountFilter
'credit-card' => [AccountType::CREDITCARD], 'credit-card' => [AccountType::CREDITCARD],
'creditcard' => [AccountType::CREDITCARD], 'creditcard' => [AccountType::CREDITCARD],
'cc' => [AccountType::CREDITCARD], 'cc' => [AccountType::CREDITCARD],
]; ];
$return = $types[$type] ?? $types['all'];
return $return; // @codeCoverageIgnore return $types[$type] ?? $types['all'];
} }
} }

View File

@@ -26,6 +26,7 @@ use Illuminate\Support\Collection;
/** /**
* Trait ApiSupport * Trait ApiSupport
* @codeCoverageIgnore
*/ */
trait ApiSupport trait ApiSupport
{ {

View File

@@ -27,6 +27,7 @@ use FireflyIII\Models\TransactionType;
/** /**
* Trait TransactionFilter * Trait TransactionFilter
* @codeCoverageIgnore
*/ */
trait TransactionFilter trait TransactionFilter
{ {
@@ -58,9 +59,8 @@ trait TransactionFilter
'specials' => [TransactionType::OPENING_BALANCE, TransactionType::RECONCILIATION,], 'specials' => [TransactionType::OPENING_BALANCE, TransactionType::RECONCILIATION,],
'default' => [TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::TRANSFER,], 'default' => [TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::TRANSFER,],
]; ];
$return = $types[$type] ?? $types['default']; return $types[$type] ?? $types['default'];
return $return;
} }
} }

View File

@@ -32,7 +32,7 @@ use Log;
/** /**
* Trait GetSpectreCustomerTrait * Trait GetSpectreCustomerTrait
* * @codeCoverageIgnore
*/ */
trait GetSpectreCustomerTrait trait GetSpectreCustomerTrait
{ {

View File

@@ -31,7 +31,7 @@ use Log;
/** /**
* Trait GetSpectreTokenTrait * Trait GetSpectreTokenTrait
* * @codeCoverageIgnore
*/ */
trait GetSpectreTokenTrait trait GetSpectreTokenTrait
{ {

View File

@@ -119,7 +119,7 @@ class ChooseAccountsHandler implements BunqJobConfigurationInterface
Log::debug(sprintf('IBAN for bunq account #%d is "%s"', $bunqId, $bunqIban)); Log::debug(sprintf('IBAN for bunq account #%d is "%s"', $bunqId, $bunqIban));
if (null !== $bunqIban) { if (null !== $bunqIban) {
$ibanToAsset[$bunqIban] = $accountId; $ibanToAsset[$bunqIban] = $accountId; // @codeCoverageIgnore
} }
$final[$bunqId] = $accountId; $final[$bunqId] = $accountId;
} }

View File

@@ -312,7 +312,7 @@ class ConfigureMappingHandler implements FileConfigurationInterface
asort($columnConfig[$columnIndex]['values']); asort($columnConfig[$columnIndex]['values']);
// if the count of this array is zero, there is nothing to map. // if the count of this array is zero, there is nothing to map.
if (0 === count($columnConfig[$columnIndex]['values'])) { if (0 === count($columnConfig[$columnIndex]['values'])) {
unset($columnConfig[$columnIndex]); unset($columnConfig[$columnIndex]); // @codeCoverageIgnore
} }
} }

View File

@@ -34,8 +34,8 @@ use FireflyIII\Support\FinTS\FinTS;
use Illuminate\Support\MessageBag; use Illuminate\Support\MessageBag;
/** /**
*
* Class ChooseAccountHandler * Class ChooseAccountHandler
* @codeCoverageIgnore
*/ */
class ChooseAccountHandler implements FinTSConfigurationInterface class ChooseAccountHandler implements FinTSConfigurationInterface
{ {

View File

@@ -32,8 +32,8 @@ use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\MessageBag; use Illuminate\Support\MessageBag;
/** /**
*
* Class NewFinTSJobHandler * Class NewFinTSJobHandler
* @codeCoverageIgnore
*/ */
class NewFinTSJobHandler implements FinTSConfigurationInterface class NewFinTSJobHandler implements FinTSConfigurationInterface
{ {
@@ -62,7 +62,6 @@ class NewFinTSJobHandler implements FinTSConfigurationInterface
$this->repository->setConfiguration($this->importJob, $config); $this->repository->setConfiguration($this->importJob, $config);
$incomplete = false; $incomplete = false;
foreach ($config as $value) { foreach ($config as $value) {
$incomplete = '' === $value or $incomplete; $incomplete = '' === $value or $incomplete;

View File

@@ -33,6 +33,7 @@ use Log;
/** /**
* Class ImportTransaction * Class ImportTransaction
* @codeCoverageIgnore
*/ */
class ImportTransaction class ImportTransaction
{ {
@@ -179,7 +180,7 @@ class ImportTransaction
'date-process' => 'date_process', 'date-process' => 'date_process',
'date-due' => 'date_due', 'date-due' => 'date_due',
]; ];
if (in_array($role, array_keys($replaceOldRoles))) { if (array_key_exists($role, $replaceOldRoles)) {
$role = $replaceOldRoles[$role]; $role = $replaceOldRoles[$role];
} }

View File

@@ -114,9 +114,9 @@ class OpposingAccountMapper
$creation = [ $creation = [
'name' => $data['name'] ?? '(no name)', 'name' => $data['name'] ?? '(no name)',
'iban' => $data['iban'] ?? null, 'iban' => $data['iban'] ?? null,
'accountNumber' => $data['number'] ?? null, 'account_number' => $data['number'] ?? null,
'account_type_id' => null, 'account_type_id' => null,
'account_type' => $expectedType, 'account_type' => $expectedType,
'active' => true, 'active' => true,
'BIC' => $data['bic'] ?? null, 'BIC' => $data['bic'] ?? null,
]; ];

View File

@@ -26,6 +26,7 @@ namespace FireflyIII\Support\Logging;
/** /**
* Class AuditLogger * Class AuditLogger
* @codeCoverageIgnore
*/ */
class AuditLogger class AuditLogger
{ {

View File

@@ -26,6 +26,7 @@ namespace FireflyIII\Support\Logging;
/** /**
* Class AuditProcessor * Class AuditProcessor
* @codeCoverageIgnore
*/ */
class AuditProcessor class AuditProcessor
{ {

View File

@@ -26,6 +26,10 @@ namespace FireflyIII\Support;
use ArrayObject; use ArrayObject;
/**
* Class NullArrayObject
* @codeCoverageIgnore
*/
class NullArrayObject extends ArrayObject class NullArrayObject extends ArrayObject
{ {
public $default = null; public $default = null;

View File

@@ -32,6 +32,7 @@ use Session;
/** /**
* Class Preferences. * Class Preferences.
* @codeCoverageIgnore
*/ */
class Preferences class Preferences
{ {

View File

@@ -1,203 +0,0 @@
<?php
/**
* Modifier.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Support\Search;
use Carbon\Carbon;
use Exception;
use FireflyIII\Models\Transaction;
use Log;
/**
* Class Modifier
*/
class Modifier
{
/**
* @param Transaction $transaction
* @param string $amount
* @param int $expected
*
* @return bool
*/
public static function amountCompare(Transaction $transaction, string $amount, int $expected): bool
{
$amount = app('steam')->positive($amount);
$transactionAmount = app('steam')->positive($transaction->transaction_amount);
$compare = bccomp($amount, $transactionAmount);
Log::debug(sprintf('%s vs %s is %d', $amount, $transactionAmount, $compare));
return $compare === $expected;
}
/**
* @param array $modifier
* @param Transaction $transaction
*
* @return bool
*
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
public static function apply(array $modifier, Transaction $transaction): bool
{
$res = true;
switch ($modifier['type']) {
case 'source':
$name = $transaction->account_name;
$res = self::stringCompare($name, $modifier['value']);
Log::debug(sprintf('Source is %s? %s', $modifier['value'], var_export($res, true)));
break;
case 'destination':
$name = $transaction->opposing_account_name;
$res = self::stringCompare($name, $modifier['value']);
Log::debug(sprintf('Destination is %s? %s', $modifier['value'], var_export($res, true)));
break;
case 'category':
$res = self::category($transaction, $modifier['value']);
Log::debug(sprintf('Category is %s? %s', $modifier['value'], var_export($res, true)));
break;
case 'budget':
$res = self::budget($transaction, $modifier['value']);
Log::debug(sprintf('Budget is %s? %s', $modifier['value'], var_export($res, true)));
break;
case 'bill':
$name = $transaction->bill_name;
$res = self::stringCompare($name, $modifier['value']);
Log::debug(sprintf('Bill is %s? %s', $modifier['value'], var_export($res, true)));
break;
}
return $res;
}
/**
* @param Carbon $date
* @param string $compare
*
* @return bool
*/
public static function dateAfter(Carbon $date, string $compare): bool
{
try {
$compareDate = new Carbon($compare);
} catch (Exception $e) {
Log::debug(sprintf('Not interesting in Modifier:dateAfter(): %s', $e->getMessage()));
return false;
}
return $date->greaterThanOrEqualTo($compareDate);
}
/**
* @param Carbon $date
* @param string $compare
*
* @return bool
*/
public static function dateBefore(Carbon $date, string $compare): bool
{
try {
$compareDate = new Carbon($compare);
} catch (Exception $e) {
Log::debug(sprintf('Not interesting in modifier:dateBefore(): %s', $e->getMessage()));
return false;
}
return $date->lessThanOrEqualTo($compareDate);
}
/**
* @param Carbon $date
* @param string $compare
*
* @return bool
*/
public static function sameDate(Carbon $date, string $compare): bool
{
try {
$compareDate = new Carbon($compare);
} catch (Exception $e) {
Log::debug(sprintf('Not interesting in Modifier:sameDate(): %s', $e->getMessage()));
return false;
}
return $compareDate->isSameDay($date);
}
/**
* @param string $haystack
* @param string $needle
*
* @return bool
*/
public static function stringCompare(string $haystack, string $needle): bool
{
$res = !(false === stripos($haystack, $needle));
Log::debug(sprintf('"%s" is in "%s"? %s', $needle, $haystack, var_export($res, true)));
return $res;
}
/**
* @param Transaction $transaction
* @param string $search
*
* @return bool
*/
private static function budget(Transaction $transaction, string $search): bool
{
$journalBudget = '';
if (null !== $transaction->transaction_journal_budget_name) {
$journalBudget = $transaction->transaction_journal_budget_name;
}
$transactionBudget = '';
if (null !== $transaction->transaction_budget_name) {
$journalBudget = $transaction->transaction_budget_name;
}
return self::stringCompare($journalBudget, $search) || self::stringCompare($transactionBudget, $search);
}
/**
* @param Transaction $transaction
* @param string $search
*
* @return bool
*/
private static function category(Transaction $transaction, string $search): bool
{
$journalCategory = '';
if (null !== $transaction->transaction_journal_category_name) {
$journalCategory = $transaction->transaction_journal_category_name;
}
$transactionCategory = '';
if (null !== $transaction->transaction_category_name) {
$journalCategory = $transaction->transaction_category_name;
}
return self::stringCompare($journalCategory, $search) || self::stringCompare($transactionCategory, $search);
}
}

View File

@@ -33,6 +33,7 @@ use stdClass;
/** /**
* Class Steam. * Class Steam.
* @codeCoverageIgnore
*/ */
class Steam class Steam
{ {

View File

@@ -105,7 +105,7 @@ class AccountTransformer extends AbstractTransformer
'notes' => $this->repository->getNoteText($account), 'notes' => $this->repository->getNoteText($account),
'monthly_payment_date' => $monthlyPaymentDate, 'monthly_payment_date' => $monthlyPaymentDate,
'credit_card_type' => $creditCardType, 'credit_card_type' => $creditCardType,
'account_number' => $this->repository->getMetaValue($account, 'accountNumber'), 'account_number' => $this->repository->getMetaValue($account, 'account_number'),
'iban' => '' === $account->iban ? null : $account->iban, 'iban' => '' === $account->iban ? null : $account->iban,
'bic' => $this->repository->getMetaValue($account, 'BIC'), 'bic' => $this->repository->getMetaValue($account, 'BIC'),
'virtual_balance' => round($account->virtual_balance, $decimalPlaces), 'virtual_balance' => round($account->virtual_balance, $decimalPlaces),

Some files were not shown because too many files have changed in this diff Show More