mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-04 19:53:44 +00:00
Improve test coverage.
This commit is contained in:
@@ -8,8 +8,8 @@ APP_DEBUG=false
|
||||
# This should be your email address
|
||||
SITE_OWNER=mail@example.com
|
||||
|
||||
# The encryption key for your database and sessions. Keep this very secure.
|
||||
# If you generate a new one all existing data must be considered LOST.
|
||||
# The encryption key for your sessions. Keep this very secure.
|
||||
# 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
|
||||
APP_KEY=SomeRandomStringOf32CharsExactly
|
||||
|
||||
@@ -103,8 +103,8 @@ MAPBOX_API_KEY=
|
||||
# Firefly III currently supports two provider for live Currency Exchange Rates:
|
||||
# "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,
|
||||
# built compatible with Fixer.IO, based on data published by European Central Bank, and don't require API key.
|
||||
CER_PROVIDER=fixer
|
||||
# built compatible with Fixer.IO, based on data published by European Central Bank, and doesn't require API key.
|
||||
CER_PROVIDER=ratesapi
|
||||
# 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.
|
||||
# Please note that this WILL ONLY WORK FOR PAID fixer.io accounts because they severely limited
|
||||
|
@@ -245,11 +245,13 @@ class TransactionJournalFactory
|
||||
/** create or get source and destination accounts */
|
||||
$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']);
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (FireflyException $e) {
|
||||
Log::error($e->getMessage());
|
||||
|
||||
return null;
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
// TODO After 4.8.0 better handling below:
|
||||
|
||||
|
@@ -96,7 +96,7 @@ class AccountFormRequest extends Request
|
||||
'name' => 'required|min:1|uniqueAccountForUser',
|
||||
'opening_balance' => 'numeric|required_with:opening_balance_date|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',
|
||||
'virtual_balance' => 'numeric|nullable',
|
||||
'currency_id' => 'exists:transaction_currencies,id',
|
||||
|
@@ -49,9 +49,7 @@ use Carbon\Carbon;
|
||||
use FireflyIII\Events\RequestedReportOnJournals;
|
||||
use FireflyIII\Events\StoredTransactionGroup;
|
||||
use FireflyIII\Factory\PiggyBankEventFactory;
|
||||
use FireflyIII\Factory\PiggyBankFactory;
|
||||
use FireflyIII\Models\Recurrence;
|
||||
use FireflyIII\Models\RecurrenceMeta;
|
||||
use FireflyIII\Models\RecurrenceRepetition;
|
||||
use FireflyIII\Models\RecurrenceTransaction;
|
||||
use FireflyIII\Models\TransactionGroup;
|
||||
@@ -94,16 +92,26 @@ class CreateRecurringTransactions implements ShouldQueue
|
||||
/** @var int Transaction groups created */
|
||||
public $created;
|
||||
|
||||
/**
|
||||
* @param Carbon $date
|
||||
*/
|
||||
public function setDate(Carbon $date): void
|
||||
{
|
||||
$this->date = $date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param Carbon $date
|
||||
*/
|
||||
public function __construct(Carbon $date)
|
||||
public function __construct(?Carbon $date)
|
||||
{
|
||||
$date->startOfDay();
|
||||
$this->date = $date;
|
||||
if (null !== $date) {
|
||||
$date->startOfDay();
|
||||
$this->date = $date;
|
||||
}
|
||||
$this->repository = app(RecurringRepositoryInterface::class);
|
||||
$this->journalRepository = app(JournalRepositoryInterface::class);
|
||||
$this->groupRepository = app(TransactionGroupRepositoryInterface::class);
|
||||
|
@@ -32,6 +32,7 @@ use Mail;
|
||||
|
||||
/**
|
||||
* Class MailError.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class MailError extends Job implements ShouldQueue
|
||||
{
|
||||
|
@@ -30,6 +30,7 @@ use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class AccessTokenCreatedMail
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class AccessTokenCreatedMail extends Mailable
|
||||
{
|
||||
|
@@ -30,6 +30,7 @@ use Illuminate\Queue\SerializesModels;
|
||||
* Class AdminTestMail.
|
||||
*
|
||||
* Sends a test mail to administrators.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class AdminTestMail extends Mailable
|
||||
{
|
||||
|
@@ -30,6 +30,7 @@ use Illuminate\Queue\SerializesModels;
|
||||
* Class ConfirmEmailChangeMail
|
||||
*
|
||||
* Sends message to new address to confirm change.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class ConfirmEmailChangeMail extends Mailable
|
||||
{
|
||||
|
@@ -31,6 +31,7 @@ use Laravel\Passport\Client;
|
||||
|
||||
/**
|
||||
* Class OAuthTokenCreatedMail
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class OAuthTokenCreatedMail extends Mailable
|
||||
{
|
||||
|
@@ -31,6 +31,7 @@ use Illuminate\Queue\SerializesModels;
|
||||
* Sends newly registered user an email message.
|
||||
*
|
||||
* Class RegisteredUser
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class RegisteredUser extends Mailable
|
||||
{
|
||||
|
@@ -31,6 +31,7 @@ use Illuminate\Support\Collection;
|
||||
* Class ReportNewJournalsMail.
|
||||
*
|
||||
* Sends a list of newly created journals to the user.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class ReportNewJournalsMail extends Mailable
|
||||
{
|
||||
|
@@ -30,6 +30,7 @@ use Illuminate\Queue\SerializesModels;
|
||||
/**
|
||||
* Sends user link for new password.
|
||||
* Class RequestedNewPassword
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class RequestedNewPassword extends Mailable
|
||||
{
|
||||
|
@@ -28,6 +28,7 @@ use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class UndoEmailChangeMail
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class UndoEmailChangeMail extends Mailable
|
||||
{
|
||||
|
@@ -46,11 +46,11 @@ use Session;
|
||||
|
||||
/**
|
||||
* Class EventServiceProvider.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class EventServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* The event listener mappings for the application.
|
||||
*
|
||||
* @var array
|
||||
@@ -103,7 +103,6 @@ class EventServiceProvider extends ServiceProvider
|
||||
];
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* Register any events for your application.
|
||||
*/
|
||||
public function boot(): void
|
||||
@@ -119,7 +118,7 @@ class EventServiceProvider extends ServiceProvider
|
||||
{
|
||||
// in case of repeated piggy banks and/or other problems.
|
||||
PiggyBank::created(
|
||||
function (PiggyBank $piggyBank) {
|
||||
static function (PiggyBank $piggyBank) {
|
||||
$repetition = new PiggyBankRepetition;
|
||||
$repetition->piggyBank()->associate($piggyBank);
|
||||
$repetition->startdate = $piggyBank->startdate;
|
||||
@@ -129,7 +128,7 @@ class EventServiceProvider extends ServiceProvider
|
||||
}
|
||||
);
|
||||
Client::created(
|
||||
function (Client $oauthClient) {
|
||||
static function (Client $oauthClient) {
|
||||
/** @var UserRepositoryInterface $repository */
|
||||
$repository = app(UserRepositoryInterface::class);
|
||||
$user = $repository->findNull((int)$oauthClient->user_id);
|
||||
|
@@ -50,7 +50,7 @@ use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use FireflyIII\Services\Currency\ExchangeRateInterface;
|
||||
use FireflyIII\Services\IP\IpifyOrg;
|
||||
use FireflyIII\Services\IP\IPRetrievalInterface;
|
||||
use FireflyIII\Services\Password\PwndVerifierV2;
|
||||
use FireflyIII\Services\Password\PwndVerifierV3;
|
||||
use FireflyIII\Services\Password\Verifier;
|
||||
use FireflyIII\Support\Amount;
|
||||
use FireflyIII\Support\ExpandedForm;
|
||||
@@ -183,7 +183,7 @@ class FireflyServiceProvider extends ServiceProvider
|
||||
$this->app->bind(ExchangeRateInterface::class, $class);
|
||||
|
||||
// password verifier thing
|
||||
$this->app->bind(Verifier::class, PwndVerifierV2::class);
|
||||
$this->app->bind(Verifier::class, PwndVerifierV3::class);
|
||||
|
||||
// IP thing:
|
||||
$this->app->bind(IPRetrievalInterface::class, IpifyOrg::class);
|
||||
|
@@ -57,17 +57,6 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
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.
|
||||
*
|
||||
@@ -87,6 +76,17 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $types
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count(array $types): int
|
||||
{
|
||||
return $this->user->accounts()->accountTypeIn($types)->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $number
|
||||
* @param array $types
|
||||
@@ -97,7 +97,7 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
{
|
||||
$query = $this->user->accounts()
|
||||
->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));
|
||||
|
||||
if (count($types) > 0) {
|
||||
@@ -298,30 +298,6 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
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.
|
||||
*
|
||||
@@ -444,18 +420,6 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
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
|
||||
*
|
||||
@@ -466,47 +430,6 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
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.
|
||||
*
|
||||
@@ -581,7 +504,7 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
* @param array $data
|
||||
*
|
||||
* @return Account
|
||||
* @throws \FireflyIII\Exceptions\FireflyException
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function store(array $data): Account
|
||||
{
|
||||
@@ -597,7 +520,7 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
* @param array $data
|
||||
*
|
||||
* @return Account
|
||||
* @throws \FireflyIII\Exceptions\FireflyException
|
||||
* @throws FireflyException
|
||||
* @throws FireflyException
|
||||
* @throws FireflyException
|
||||
*/
|
||||
|
@@ -40,7 +40,9 @@ interface AccountRepositoryInterface
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
*
|
||||
* @return TransactionJournal|null
|
||||
*
|
||||
*/
|
||||
public function getOpeningBalance(Account $account): ?TransactionJournal;
|
||||
|
||||
@@ -151,13 +153,6 @@ interface AccountRepositoryInterface
|
||||
*/
|
||||
public function getCashAccount(): Account;
|
||||
|
||||
/**
|
||||
* @param $account
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getInterestPerDay(Account $account): string;
|
||||
|
||||
/**
|
||||
* Return meta value for account. Null if not found.
|
||||
*
|
||||
@@ -211,12 +206,6 @@ interface AccountRepositoryInterface
|
||||
*/
|
||||
public function getReconciliation(Account $account): ?Account;
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isAsset(Account $account): bool;
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
@@ -225,23 +214,6 @@ interface AccountRepositoryInterface
|
||||
*/
|
||||
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.
|
||||
|
@@ -151,6 +151,47 @@ class AccountTasker implements AccountTaskerInterface
|
||||
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
|
||||
*
|
||||
@@ -208,45 +249,4 @@ class AccountTasker implements AccountTaskerInterface
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@@ -33,16 +33,16 @@ interface AccountTaskerInterface
|
||||
{
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAccountReport(Collection $accounts, Carbon $start, Carbon $end): array;
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return array
|
||||
@@ -50,8 +50,8 @@ interface AccountTaskerInterface
|
||||
public function getExpenseReport(Carbon $start, Carbon $end, Collection $accounts): array;
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return array
|
||||
|
@@ -90,17 +90,6 @@ class AttachmentRepository implements AttachmentRepositoryInterface
|
||||
return $disk->exists($attachment->fileName());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $attachmentId
|
||||
*
|
||||
* @return Attachment|null
|
||||
*/
|
||||
public function findWithoutUser(int $attachmentId): ?Attachment
|
||||
{
|
||||
|
||||
return Attachment::find($attachmentId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
@@ -109,24 +98,6 @@ class AttachmentRepository implements AttachmentRepositoryInterface
|
||||
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
|
||||
*
|
||||
|
@@ -48,26 +48,11 @@ interface AttachmentRepositoryInterface
|
||||
*/
|
||||
public function exists(Attachment $attachment): bool;
|
||||
|
||||
/**
|
||||
* @param int $attachmentId
|
||||
*
|
||||
* @return Attachment|null
|
||||
*/
|
||||
public function findWithoutUser(int $attachmentId): ?Attachment;
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function get(): Collection;
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getBetween(Carbon $start, Carbon $end): Collection;
|
||||
|
||||
/**
|
||||
* @param Attachment $attachment
|
||||
*
|
||||
|
@@ -489,36 +489,6 @@ class BudgetRepository implements BudgetRepositoryInterface
|
||||
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
|
||||
* in both the year/multi-year budget overview AND in the accompanying chart.
|
||||
|
@@ -172,17 +172,6 @@ interface BudgetRepositoryInterface
|
||||
*/
|
||||
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 Carbon $start
|
||||
|
@@ -41,6 +41,7 @@ class BelongsUser implements Rule
|
||||
* Create a new rule instance.
|
||||
*
|
||||
* @return void
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
@@ -51,6 +52,7 @@ class BelongsUser implements Rule
|
||||
* Get the validation error message.
|
||||
*
|
||||
* @return string
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function message(): string
|
||||
{
|
||||
|
@@ -36,6 +36,7 @@ class IsAssetAccountId implements Rule
|
||||
* Get the validation error message. This is not translated because only the API uses it.
|
||||
*
|
||||
* @return string
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function message(): string
|
||||
{
|
||||
|
@@ -33,7 +33,7 @@ class IsBoolean implements Rule
|
||||
{
|
||||
/**
|
||||
* Get the validation error message.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @return string
|
||||
*/
|
||||
public function message(): string
|
||||
@@ -51,25 +51,16 @@ class IsBoolean implements Rule
|
||||
*/
|
||||
public function passes($attribute, $value): bool
|
||||
{
|
||||
if (\is_bool($value)) {
|
||||
if (is_bool($value)) {
|
||||
return true;
|
||||
}
|
||||
if (\is_int($value) && 0 === $value) {
|
||||
if (is_int($value) && 0 === $value) {
|
||||
return true;
|
||||
}
|
||||
if (\is_int($value) && 1 === $value) {
|
||||
if (is_int($value) && 1 === $value) {
|
||||
return true;
|
||||
}
|
||||
if (\is_string($value) && '1' === $value) {
|
||||
return true;
|
||||
}
|
||||
if (\is_string($value) && '0' === $value) {
|
||||
return true;
|
||||
}
|
||||
if (\is_string($value) && 'true' === $value) {
|
||||
return true;
|
||||
}
|
||||
if (\is_string($value) && 'false' === $value) {
|
||||
if (is_string($value) && in_array($value, ['0', '1', 'true', 'false', 'on', 'off', 'yes', 'no', 'y', 'n'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -26,6 +26,7 @@ namespace FireflyIII\Rules;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Carbon\Exceptions\InvalidDateException;
|
||||
use Exception;
|
||||
use Illuminate\Contracts\Validation\Rule;
|
||||
use Log;
|
||||
|
||||
@@ -39,6 +40,7 @@ class IsDateOrTime implements Rule
|
||||
* Get the validation error message.
|
||||
*
|
||||
* @return string|array
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function message()
|
||||
{
|
||||
@@ -56,11 +58,14 @@ class IsDateOrTime implements Rule
|
||||
public function passes($attribute, $value): bool
|
||||
{
|
||||
$value = (string)$value;
|
||||
if ('' === $value) {
|
||||
return false;
|
||||
}
|
||||
if (10 === strlen($value)) {
|
||||
// probably a date format.
|
||||
try {
|
||||
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()));
|
||||
|
||||
return false;
|
||||
@@ -71,7 +76,7 @@ class IsDateOrTime implements Rule
|
||||
// is an atom string, I hope?
|
||||
try {
|
||||
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()));
|
||||
|
||||
return false;
|
||||
|
@@ -46,16 +46,19 @@ class IsValidAttachmentModel implements Rule
|
||||
/**
|
||||
* IsValidAttachmentModel constructor.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param string $model
|
||||
*/
|
||||
public function __construct(string $model)
|
||||
{
|
||||
$model = $this->normalizeModel($model);
|
||||
$this->model = $model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation error message.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @return string
|
||||
*/
|
||||
public function message(): string
|
||||
@@ -78,9 +81,9 @@ class IsValidAttachmentModel implements Rule
|
||||
if (!auth()->check()) {
|
||||
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 */
|
||||
$repository = app(BillRepositoryInterface::class);
|
||||
/** @var User $user */
|
||||
@@ -91,7 +94,7 @@ class IsValidAttachmentModel implements Rule
|
||||
return null !== $bill;
|
||||
}
|
||||
|
||||
if (ImportJob::class === $model) {
|
||||
if (ImportJob::class === $this->model) {
|
||||
/** @var ImportJobRepositoryInterface $repository */
|
||||
$repository = app(ImportJobRepositoryInterface::class);
|
||||
/** @var User $user */
|
||||
@@ -102,7 +105,7 @@ class IsValidAttachmentModel implements Rule
|
||||
return null !== $importJob;
|
||||
}
|
||||
|
||||
if (Transaction::class === $model) {
|
||||
if (Transaction::class === $this->model) {
|
||||
/** @var JournalRepositoryInterface $repository */
|
||||
$repository = app(JournalRepositoryInterface::class);
|
||||
/** @var User $user */
|
||||
@@ -113,7 +116,7 @@ class IsValidAttachmentModel implements Rule
|
||||
return null !== $transaction;
|
||||
}
|
||||
|
||||
if (TransactionJournal::class === $model) {
|
||||
if (TransactionJournal::class === $this->model) {
|
||||
$repository = app(JournalRepositoryInterface::class);
|
||||
$user = auth()->user();
|
||||
$repository->setUser($user);
|
||||
@@ -121,8 +124,23 @@ class IsValidAttachmentModel implements Rule
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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;
|
||||
}
|
||||
}
|
||||
|
@@ -26,7 +26,6 @@ namespace FireflyIII\Rules;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use Illuminate\Contracts\Validation\Rule;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
@@ -43,6 +42,8 @@ class UniqueIban implements Rule
|
||||
/**
|
||||
* Create a new rule instance.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param Account|null $account
|
||||
* @param string|null $expectedType
|
||||
*/
|
||||
@@ -55,6 +56,8 @@ class UniqueIban implements Rule
|
||||
/**
|
||||
* Get the validation error message.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function message(): string
|
||||
@@ -78,13 +81,13 @@ class UniqueIban implements Rule
|
||||
return true; // @codeCoverageIgnore
|
||||
}
|
||||
if (null === $this->expectedType) {
|
||||
return true;
|
||||
return true; // @codeCoverageIgnore
|
||||
}
|
||||
$maxCounts = $this->getMaxOccurrences();
|
||||
|
||||
foreach ($maxCounts as $type => $max) {
|
||||
$count = $this->countHits($type, $value);
|
||||
|
||||
Log::debug(sprintf('Count for "%s" and IBAN "%s" is %d', $type, $value, $count));
|
||||
if ($count > $max) {
|
||||
Log::debug(
|
||||
sprintf(
|
||||
@@ -108,24 +111,18 @@ class UniqueIban implements Rule
|
||||
*/
|
||||
private function countHits(string $type, string $iban): int
|
||||
{
|
||||
$count = 0;
|
||||
/** @noinspection NullPointerExceptionInspection */
|
||||
$query = auth()->user()
|
||||
->accounts()
|
||||
->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
|
||||
->where('account_types.type', $type);
|
||||
$query
|
||||
= auth()->user()
|
||||
->accounts()
|
||||
->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
|
||||
->where('accounts.iban', $iban)
|
||||
->where('account_types.type', $type);
|
||||
|
||||
if (null !== $this->account) {
|
||||
$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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -31,6 +31,7 @@ use Log;
|
||||
|
||||
/**
|
||||
* Class ValidJournals
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class ValidJournals implements Rule
|
||||
{
|
||||
|
@@ -27,6 +27,7 @@ use Illuminate\Contracts\Validation\Rule;
|
||||
|
||||
/**
|
||||
* Class ValidRecurrenceRepetitionType
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class ValidRecurrenceRepetitionType implements Rule
|
||||
{
|
||||
|
@@ -31,6 +31,7 @@ use Log;
|
||||
|
||||
/**
|
||||
* Class ValidRecurrenceRepetitionValue
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class ValidRecurrenceRepetitionValue implements Rule
|
||||
{
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -29,6 +29,7 @@ use Illuminate\Contracts\Validation\Rule;
|
||||
/**
|
||||
*
|
||||
* Class ZeroOrMore
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class ZeroOrMore implements Rule
|
||||
{
|
||||
|
@@ -35,6 +35,7 @@ use Tests\Object\FakeApiContext;
|
||||
* Special class to hide away bunq's static initialisation methods.
|
||||
*
|
||||
* Class ApiContext
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class ApiContext
|
||||
{
|
||||
|
@@ -31,6 +31,7 @@ use FireflyIII\Exceptions\FireflyException;
|
||||
|
||||
/**
|
||||
* Class MonetaryAccount
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class MonetaryAccount
|
||||
{
|
||||
|
@@ -31,6 +31,7 @@ use FireflyIII\Exceptions\FireflyException;
|
||||
|
||||
/**
|
||||
* Class Payment
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class Payment
|
||||
{
|
||||
|
@@ -55,6 +55,7 @@ class FixerIOv2 implements ExchangeRateInterface
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return CurrencyExchangeRate
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getRate(TransactionCurrency $fromCurrency, TransactionCurrency $toCurrency, Carbon $date): CurrencyExchangeRate
|
||||
{
|
||||
|
@@ -33,6 +33,7 @@ use Log;
|
||||
|
||||
/**
|
||||
* Class RatesApiIOv1.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class RatesApiIOv1 implements ExchangeRateInterface
|
||||
{
|
||||
|
@@ -34,6 +34,7 @@ use SimpleXMLElement;
|
||||
|
||||
/**
|
||||
* Class UpdateRequest
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class UpdateRequest implements GithubRequest
|
||||
{
|
||||
|
@@ -31,6 +31,7 @@ use RuntimeException;
|
||||
|
||||
/**
|
||||
* Class IpifyOrg
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class IpifyOrg implements IPRetrievalInterface
|
||||
{
|
||||
|
@@ -40,6 +40,8 @@ class AccountDestroyService
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
@@ -53,18 +55,38 @@ class AccountDestroyService
|
||||
* @param Account|null $moveTo
|
||||
*
|
||||
* @return void
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function destroy(Account $account, ?Account $moveTo): void
|
||||
{
|
||||
|
||||
if (null !== $moveTo) {
|
||||
DB::table('transactions')->where('account_id', $account->id)->update(['account_id' => $moveTo->id]);
|
||||
|
||||
// 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->moveTransactions($account, $moveTo);
|
||||
$this->updateRecurrences($account, $moveTo);
|
||||
}
|
||||
$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);
|
||||
|
||||
Log::debug('Now trigger account delete response #' . $account->id);
|
||||
@@ -75,37 +97,49 @@ class AccountDestroyService
|
||||
$journal = $transaction->transactionJournal()->first();
|
||||
if (null !== $journal) {
|
||||
Log::debug('Call for deletion of journal #' . $journal->id);
|
||||
/** @var JournalDestroyService $service */
|
||||
|
||||
$service->destroy($journal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// delete recurring transactions with this account:
|
||||
if (null === $moveTo) {
|
||||
$recurrences = RecurrenceTransaction::
|
||||
where(
|
||||
function (Builder $q) use ($account) {
|
||||
$q->where('source_id', $account->id);
|
||||
$q->orWhere('destination_id', $account->id);
|
||||
}
|
||||
)->get(['recurrence_id'])->pluck('recurrence_id')->toArray();
|
||||
|
||||
|
||||
$destroyService = new RecurrenceDestroyService();
|
||||
foreach ($recurrences as $recurrenceId) {
|
||||
$destroyService->destroyById((int)$recurrenceId);
|
||||
/**
|
||||
* @param Account $account
|
||||
*/
|
||||
private function destroyRecurrences(Account $account): void
|
||||
{
|
||||
$recurrences = RecurrenceTransaction::
|
||||
where(
|
||||
static function (Builder $q) use ($account) {
|
||||
$q->where('source_id', $account->id);
|
||||
$q->orWhere('destination_id', $account->id);
|
||||
}
|
||||
}
|
||||
)->get(['recurrence_id'])->pluck('recurrence_id')->toArray();
|
||||
|
||||
// delete piggy banks:
|
||||
PiggyBank::where('account_id', $account->id)->delete();
|
||||
|
||||
try {
|
||||
$account->delete();
|
||||
} catch (Exception $e) { // @codeCoverageIgnore
|
||||
Log::error(sprintf('Could not delete account: %s', $e->getMessage())); // @codeCoverageIgnore
|
||||
/** @var RecurrenceDestroyService $destroyService */
|
||||
$destroyService = app(RecurrenceDestroyService::class);
|
||||
foreach ($recurrences as $recurrenceId) {
|
||||
$destroyService->destroyById((int)$recurrenceId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @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]);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -30,6 +30,7 @@ use Log;
|
||||
|
||||
/**
|
||||
* Class BudgetDestroyService
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class BudgetDestroyService
|
||||
{
|
||||
|
@@ -30,6 +30,7 @@ use Log;
|
||||
|
||||
/**
|
||||
* Class CategoryDestroyService
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class CategoryDestroyService
|
||||
{
|
||||
|
@@ -29,6 +29,7 @@ use Log;
|
||||
|
||||
/**
|
||||
* Class CurrencyDestroyService
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class CurrencyDestroyService
|
||||
{
|
||||
|
@@ -23,9 +23,12 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Services\Internal\Destroy;
|
||||
|
||||
use DB;
|
||||
use Exception;
|
||||
use FireflyIII\Models\Attachment;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\TransactionJournalLink;
|
||||
use FireflyIII\Models\TransactionJournalMeta;
|
||||
use Log;
|
||||
|
||||
@@ -58,12 +61,42 @@ class JournalDestroyService
|
||||
}
|
||||
|
||||
// also delete journal_meta entries.
|
||||
|
||||
/** @var TransactionJournalMeta $meta */
|
||||
foreach ($journal->transactionJournalMeta()->get() as $meta) {
|
||||
Log::debug(sprintf('Will now delete meta-entry #%d', $meta->id));
|
||||
$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();
|
||||
} catch (Exception $e) {
|
||||
Log::error(sprintf('Could not delete bill: %s', $e->getMessage())); // @codeCoverageIgnore
|
||||
|
@@ -28,6 +28,7 @@ use FireflyIII\Models\TransactionGroup;
|
||||
|
||||
/**
|
||||
* Class TransactionGroupDestroyService
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class TransactionGroupDestroyService
|
||||
{
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
}
|
@@ -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 string $note
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @return bool
|
||||
*/
|
||||
public function updateNote(Account $account, string $note): bool
|
||||
@@ -186,117 +137,6 @@ trait AccountServiceTrait
|
||||
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.
|
||||
*
|
||||
@@ -340,52 +180,6 @@ trait AccountServiceTrait
|
||||
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.
|
||||
*
|
||||
@@ -486,7 +280,9 @@ trait AccountServiceTrait
|
||||
*
|
||||
* @param Account $account
|
||||
* @param array $data
|
||||
*
|
||||
* @return TransactionGroup|null
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
protected function updateOBGroup(Account $account, array $data): ?TransactionGroup
|
||||
{
|
||||
|
@@ -32,7 +32,7 @@ use Log;
|
||||
|
||||
/**
|
||||
* Trait BillServiceTrait
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
trait BillServiceTrait
|
||||
{
|
||||
|
@@ -57,6 +57,7 @@ trait JournalServiceTrait
|
||||
* @param string|null $amount
|
||||
*
|
||||
* @return string
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
protected function getForeignAmount(?string $amount): ?string
|
||||
{
|
||||
@@ -87,6 +88,7 @@ trait JournalServiceTrait
|
||||
* @param string|null $accountName
|
||||
*
|
||||
* @return Account
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
protected function getAccount(string $transactionType, string $direction, ?int $accountId, ?string $accountName): Account
|
||||
{
|
||||
@@ -166,6 +168,7 @@ trait JournalServiceTrait
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
protected function getAmount(string $amount): string
|
||||
{
|
||||
@@ -182,6 +185,8 @@ trait JournalServiceTrait
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
* @param NullArrayObject $data
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
protected function storeBudget(TransactionJournal $journal, NullArrayObject $data): void
|
||||
{
|
||||
@@ -204,6 +209,8 @@ trait JournalServiceTrait
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
* @param NullArrayObject $data
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
protected function storeCategory(TransactionJournal $journal, NullArrayObject $data): void
|
||||
{
|
||||
@@ -221,6 +228,8 @@ trait JournalServiceTrait
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
* @param string $notes
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
protected function storeNotes(TransactionJournal $journal, ?string $notes): void
|
||||
{
|
||||
@@ -255,6 +264,8 @@ trait JournalServiceTrait
|
||||
* @param TransactionJournal $journal
|
||||
* @param array $tags
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
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()));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
// }
|
||||
}
|
||||
|
@@ -205,6 +205,8 @@ trait RecurringTransactionTrait
|
||||
|
||||
/**
|
||||
* @param Recurrence $recurrence
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
protected function deleteRepetitions(Recurrence $recurrence): void
|
||||
{
|
||||
@@ -213,6 +215,8 @@ trait RecurringTransactionTrait
|
||||
|
||||
/**
|
||||
* @param Recurrence $recurrence
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
protected function deleteTransactions(Recurrence $recurrence): void
|
||||
{
|
||||
|
@@ -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();
|
||||
//
|
||||
// }
|
||||
|
||||
|
||||
}
|
@@ -29,6 +29,7 @@ use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Services\Internal\Support\AccountServiceTrait;
|
||||
use FireflyIII\User;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
@@ -43,6 +44,8 @@ class AccountUpdateService
|
||||
/** @var AccountRepositoryInterface */
|
||||
protected $accountRepository;
|
||||
|
||||
/** @var User */
|
||||
private $user;
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
@@ -67,6 +70,7 @@ class AccountUpdateService
|
||||
public function update(Account $account, array $data): Account
|
||||
{
|
||||
$this->accountRepository->setUser($account->user);
|
||||
$this->user = $account->user;
|
||||
|
||||
// update the account itself:
|
||||
$account->name = $data['name'];
|
||||
@@ -91,10 +95,13 @@ class AccountUpdateService
|
||||
// has valid initial balance (IB) data?
|
||||
$type = $account->accountType;
|
||||
// if it can have a virtual balance, it can also have an opening balance.
|
||||
|
||||
if (in_array($type->type, $this->canHaveVirtual, true)) {
|
||||
|
||||
if ($this->validOBData($data)) {
|
||||
$this->updateOBGroup($account, $data);
|
||||
}
|
||||
|
||||
if (!$this->validOBData($data)) {
|
||||
$this->deleteOBGroup($account);
|
||||
}
|
||||
|
@@ -28,6 +28,7 @@ use Log;
|
||||
|
||||
/**
|
||||
* Class CategoryUpdateService
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class CategoryUpdateService
|
||||
{
|
||||
|
@@ -28,6 +28,7 @@ use Log;
|
||||
|
||||
/**
|
||||
* Class CurrencyUpdateService
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class CurrencyUpdateService
|
||||
{
|
||||
|
@@ -31,6 +31,7 @@ use Log;
|
||||
|
||||
/**
|
||||
* Class GroupUpdateService
|
||||
* TODO test.
|
||||
*/
|
||||
class GroupUpdateService
|
||||
{
|
||||
|
@@ -48,6 +48,7 @@ use Log;
|
||||
* Class to centralise code that updates a journal given the input by system.
|
||||
*
|
||||
* Class JournalUpdateService
|
||||
* TODO test me
|
||||
*/
|
||||
class JournalUpdateService
|
||||
{
|
||||
|
@@ -26,16 +26,16 @@ namespace FireflyIII\Services\Internal\Update;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Recurrence;
|
||||
use FireflyIII\Services\Internal\Support\RecurringTransactionTrait;
|
||||
use FireflyIII\Services\Internal\Support\TransactionServiceTrait;
|
||||
use FireflyIII\Services\Internal\Support\TransactionTypeTrait;
|
||||
use FireflyIII\User;
|
||||
|
||||
/**
|
||||
* Class RecurrenceUpdateService
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class RecurrenceUpdateService
|
||||
{
|
||||
use TransactionTypeTrait, TransactionServiceTrait, RecurringTransactionTrait;
|
||||
use TransactionTypeTrait, RecurringTransactionTrait;
|
||||
|
||||
/** @var User */
|
||||
private $user;
|
||||
@@ -51,7 +51,6 @@ class RecurrenceUpdateService
|
||||
*/
|
||||
public function update(Recurrence $recurrence, array $data): Recurrence
|
||||
{
|
||||
// is expected by TransactionServiceTrait
|
||||
$this->user = $recurrence->user;
|
||||
$transactionType = $this->findTransactionType(ucfirst($data['recurrence']['type']));
|
||||
// update basic fields first:
|
||||
|
@@ -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;
|
||||
// }
|
||||
}
|
@@ -30,6 +30,7 @@ use RuntimeException;
|
||||
|
||||
/**
|
||||
* Class PwndVerifierV2.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class PwndVerifierV2 implements Verifier
|
||||
{
|
||||
|
92
app/Services/Password/PwndVerifierV3.php
Normal file
92
app/Services/Password/PwndVerifierV3.php
Normal 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;
|
||||
}
|
||||
}
|
@@ -29,6 +29,7 @@ use FireflyIII\Services\Spectre\Object\Token;
|
||||
|
||||
/**
|
||||
* Class CreateTokenRequest
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class CreateTokenRequest extends SpectreRequest
|
||||
{
|
||||
|
@@ -30,6 +30,7 @@ use Log;
|
||||
|
||||
/**
|
||||
* Class ListAccountsRequest
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class ListAccountsRequest extends SpectreRequest
|
||||
{
|
||||
|
@@ -29,6 +29,7 @@ use Log;
|
||||
|
||||
/**
|
||||
* Class ListCustomersRequest
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class ListCustomersRequest extends SpectreRequest
|
||||
{
|
||||
|
@@ -31,6 +31,7 @@ use Log;
|
||||
|
||||
/**
|
||||
* Class ListLoginsRequest
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class ListLoginsRequest extends SpectreRequest
|
||||
{
|
||||
|
@@ -30,6 +30,7 @@ use Log;
|
||||
|
||||
/**
|
||||
* Class ListTransactionsRequest
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class ListTransactionsRequest extends SpectreRequest
|
||||
{
|
||||
|
@@ -27,6 +27,7 @@ use Log;
|
||||
|
||||
/**
|
||||
* Class NewCustomerRequest
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class NewCustomerRequest extends SpectreRequest
|
||||
{
|
||||
|
@@ -32,6 +32,7 @@ use RuntimeException;
|
||||
|
||||
/**
|
||||
* Class SpectreRequest
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
abstract class SpectreRequest
|
||||
{
|
||||
|
@@ -27,6 +27,7 @@ use Log;
|
||||
|
||||
/**
|
||||
* Class GetAccountsRequest
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class GetAccountsRequest extends YnabRequest
|
||||
{
|
||||
|
@@ -27,6 +27,7 @@ use Log;
|
||||
|
||||
/**
|
||||
* Class GetBudgetsRequest
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class GetBudgetsRequest extends YnabRequest
|
||||
{
|
||||
|
@@ -27,6 +27,7 @@ use Log;
|
||||
|
||||
/**
|
||||
* Class GetTransactionsRequest
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class GetTransactionsRequest extends YnabRequest
|
||||
{
|
||||
|
@@ -30,6 +30,7 @@ use RuntimeException;
|
||||
|
||||
/**
|
||||
* Class YnabRequest
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
abstract class YnabRequest
|
||||
{
|
||||
|
@@ -33,6 +33,7 @@ use Preferences as Prefs;
|
||||
|
||||
/**
|
||||
* Class Amount.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class Amount
|
||||
{
|
||||
|
@@ -27,6 +27,7 @@ use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class CacheProperties.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class CacheProperties
|
||||
{
|
||||
|
@@ -24,6 +24,7 @@ namespace FireflyIII\Support;
|
||||
|
||||
/**
|
||||
* Class ChartColour.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class ChartColour
|
||||
{
|
||||
|
@@ -25,6 +25,7 @@ namespace FireflyIII\Support\Cronjobs;
|
||||
|
||||
/**
|
||||
* Class AbstractCronjob
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
abstract class AbstractCronjob
|
||||
{
|
||||
|
@@ -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));
|
||||
}
|
||||
|
||||
try {
|
||||
$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()));
|
||||
}
|
||||
$this->fireRecurring();
|
||||
|
||||
app('preferences')->mark();
|
||||
|
||||
@@ -114,12 +108,13 @@ class RecurringCronjob extends AbstractCronjob
|
||||
|
||||
/**
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function fireRecurring(): void
|
||||
{
|
||||
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->handle();
|
||||
app('fireflyconfig')->set('last_rt_job', (int)$this->date->format('U'));
|
||||
|
@@ -24,6 +24,7 @@ namespace FireflyIII\Support;
|
||||
|
||||
/**
|
||||
* Class Domain.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class Domain
|
||||
{
|
||||
|
@@ -48,6 +48,7 @@ use Throwable;
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.TooManyMethods)
|
||||
* @SuppressWarnings(PHPMD.TooManyPublicMethods)
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class ExpandedForm
|
||||
{
|
||||
|
@@ -27,7 +27,7 @@ use FireflyIII\Exceptions\FireflyException;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
|
||||
/**
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* Class FinTS
|
||||
*/
|
||||
class FinTS
|
||||
|
@@ -29,6 +29,7 @@ use Log;
|
||||
|
||||
/**
|
||||
* Class FireflyConfig.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class FireflyConfig
|
||||
{
|
||||
|
@@ -27,6 +27,7 @@ use FireflyIII\Models\AccountType;
|
||||
|
||||
/**
|
||||
* Trait AccountFilter
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
trait AccountFilter
|
||||
{
|
||||
@@ -78,10 +79,8 @@ trait AccountFilter
|
||||
'credit-card' => [AccountType::CREDITCARD],
|
||||
'creditcard' => [AccountType::CREDITCARD],
|
||||
'cc' => [AccountType::CREDITCARD],
|
||||
|
||||
];
|
||||
$return = $types[$type] ?? $types['all'];
|
||||
|
||||
return $return; // @codeCoverageIgnore
|
||||
return $types[$type] ?? $types['all'];
|
||||
}
|
||||
}
|
||||
|
@@ -26,6 +26,7 @@ use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Trait ApiSupport
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
trait ApiSupport
|
||||
{
|
||||
|
@@ -27,6 +27,7 @@ use FireflyIII\Models\TransactionType;
|
||||
|
||||
/**
|
||||
* Trait TransactionFilter
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
trait TransactionFilter
|
||||
{
|
||||
@@ -58,9 +59,8 @@ trait TransactionFilter
|
||||
'specials' => [TransactionType::OPENING_BALANCE, TransactionType::RECONCILIATION,],
|
||||
'default' => [TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::TRANSFER,],
|
||||
];
|
||||
$return = $types[$type] ?? $types['default'];
|
||||
return $types[$type] ?? $types['default'];
|
||||
|
||||
return $return;
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -32,7 +32,7 @@ use Log;
|
||||
|
||||
/**
|
||||
* Trait GetSpectreCustomerTrait
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
trait GetSpectreCustomerTrait
|
||||
{
|
||||
|
@@ -31,7 +31,7 @@ use Log;
|
||||
|
||||
/**
|
||||
* Trait GetSpectreTokenTrait
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
trait GetSpectreTokenTrait
|
||||
{
|
||||
|
@@ -119,7 +119,7 @@ class ChooseAccountsHandler implements BunqJobConfigurationInterface
|
||||
|
||||
Log::debug(sprintf('IBAN for bunq account #%d is "%s"', $bunqId, $bunqIban));
|
||||
if (null !== $bunqIban) {
|
||||
$ibanToAsset[$bunqIban] = $accountId;
|
||||
$ibanToAsset[$bunqIban] = $accountId; // @codeCoverageIgnore
|
||||
}
|
||||
$final[$bunqId] = $accountId;
|
||||
}
|
||||
|
@@ -312,7 +312,7 @@ class ConfigureMappingHandler implements FileConfigurationInterface
|
||||
asort($columnConfig[$columnIndex]['values']);
|
||||
// if the count of this array is zero, there is nothing to map.
|
||||
if (0 === count($columnConfig[$columnIndex]['values'])) {
|
||||
unset($columnConfig[$columnIndex]);
|
||||
unset($columnConfig[$columnIndex]); // @codeCoverageIgnore
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -34,8 +34,8 @@ use FireflyIII\Support\FinTS\FinTS;
|
||||
use Illuminate\Support\MessageBag;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class ChooseAccountHandler
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class ChooseAccountHandler implements FinTSConfigurationInterface
|
||||
{
|
||||
|
@@ -32,8 +32,8 @@ use Illuminate\Support\Facades\Crypt;
|
||||
use Illuminate\Support\MessageBag;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class NewFinTSJobHandler
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class NewFinTSJobHandler implements FinTSConfigurationInterface
|
||||
{
|
||||
@@ -62,7 +62,6 @@ class NewFinTSJobHandler implements FinTSConfigurationInterface
|
||||
|
||||
$this->repository->setConfiguration($this->importJob, $config);
|
||||
|
||||
|
||||
$incomplete = false;
|
||||
foreach ($config as $value) {
|
||||
$incomplete = '' === $value or $incomplete;
|
||||
|
@@ -33,6 +33,7 @@ use Log;
|
||||
|
||||
/**
|
||||
* Class ImportTransaction
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class ImportTransaction
|
||||
{
|
||||
@@ -179,7 +180,7 @@ class ImportTransaction
|
||||
'date-process' => 'date_process',
|
||||
'date-due' => 'date_due',
|
||||
];
|
||||
if (in_array($role, array_keys($replaceOldRoles))) {
|
||||
if (array_key_exists($role, $replaceOldRoles)) {
|
||||
$role = $replaceOldRoles[$role];
|
||||
}
|
||||
|
||||
|
@@ -114,9 +114,9 @@ class OpposingAccountMapper
|
||||
$creation = [
|
||||
'name' => $data['name'] ?? '(no name)',
|
||||
'iban' => $data['iban'] ?? null,
|
||||
'accountNumber' => $data['number'] ?? null,
|
||||
'account_number' => $data['number'] ?? null,
|
||||
'account_type_id' => null,
|
||||
'account_type' => $expectedType,
|
||||
'account_type' => $expectedType,
|
||||
'active' => true,
|
||||
'BIC' => $data['bic'] ?? null,
|
||||
];
|
||||
|
@@ -26,6 +26,7 @@ namespace FireflyIII\Support\Logging;
|
||||
|
||||
/**
|
||||
* Class AuditLogger
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class AuditLogger
|
||||
{
|
||||
|
@@ -26,6 +26,7 @@ namespace FireflyIII\Support\Logging;
|
||||
|
||||
/**
|
||||
* Class AuditProcessor
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class AuditProcessor
|
||||
{
|
||||
|
@@ -26,6 +26,10 @@ namespace FireflyIII\Support;
|
||||
|
||||
use ArrayObject;
|
||||
|
||||
/**
|
||||
* Class NullArrayObject
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class NullArrayObject extends ArrayObject
|
||||
{
|
||||
public $default = null;
|
||||
|
@@ -32,6 +32,7 @@ use Session;
|
||||
|
||||
/**
|
||||
* Class Preferences.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class Preferences
|
||||
{
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -33,6 +33,7 @@ use stdClass;
|
||||
|
||||
/**
|
||||
* Class Steam.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class Steam
|
||||
{
|
||||
|
@@ -105,7 +105,7 @@ class AccountTransformer extends AbstractTransformer
|
||||
'notes' => $this->repository->getNoteText($account),
|
||||
'monthly_payment_date' => $monthlyPaymentDate,
|
||||
'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,
|
||||
'bic' => $this->repository->getMetaValue($account, 'BIC'),
|
||||
'virtual_balance' => round($account->virtual_balance, $decimalPlaces),
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user