Refactor code.

This commit is contained in:
James Cole 2020-11-08 14:13:21 +01:00
parent ec44d0dc8e
commit 0f32761ae8
No known key found for this signature in database
GPG Key ID: B5669F9493CDE38D
34 changed files with 45 additions and 750 deletions

View File

@ -1,112 +0,0 @@
<?php
/**
* CurrencyExchangeRateController.php
* Copyright (c) 2019 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Services\Currency\ExchangeRateInterface;
use FireflyIII\Transformers\CurrencyExchangeRateTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use League\Fractal\Resource\Item;
/**
* Class CurrencyExchangeRateController
*
* @codeCoverageIgnore
*/
class CurrencyExchangeRateController extends Controller
{
/** @var CurrencyRepositoryInterface The currency repository */
private $repository;
/**
* CurrencyExchangeRateController constructor.
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
/** @var User $admin */
$admin = auth()->user();
$this->repository = app(CurrencyRepositoryInterface::class);
$this->repository->setUser($admin);
return $next($request);
}
);
}
/**
* Show an exchange rate.
*
* @param Request $request
*
* @return JsonResponse
* @throws FireflyException
*/
public function index(Request $request): JsonResponse
{
$manager = $this->getManager();
$fromCurrency = $this->repository->findByCodeNull($request->get('from') ?? 'EUR');
$toCurrency = $this->repository->findByCodeNull($request->get('to') ?? 'USD');
if (null === $fromCurrency) {
throw new FireflyException('200007: Unknown source currency');
}
if (null === $toCurrency) {
throw new FireflyException('200007: Unknown destination currency');
}
/** @var Carbon $dateObj */
$dateObj = Carbon::createFromFormat('Y-m-d', $request->get('date') ?? date('Y-m-d'));
$this->parameters->set('from', $fromCurrency->code);
$this->parameters->set('to', $toCurrency->code);
$this->parameters->set('date', $dateObj->format('Y-m-d'));
$this->parameters->set('amount', $request->get('amount'));
$rate = $this->repository->getExchangeRate($fromCurrency, $toCurrency, $dateObj);
if (null === $rate) {
/** @var User $admin */
$admin = auth()->user();
// create service:
/** @var ExchangeRateInterface $service */
$service = app(ExchangeRateInterface::class);
$service->setUser($admin);
$rate = $service->getRate($fromCurrency, $toCurrency, $dateObj);
}
/** @var CurrencyExchangeRateTransformer $transformer */
$transformer = app(CurrencyExchangeRateTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new Item($rate, $transformer, 'currency_exchange_rates');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
}

View File

@ -374,26 +374,10 @@ class TransactionUpdateRequest extends FormRequest
// validate source/destination is equal, depending on the transaction journal type.
$this->validateEqualAccountsForUpdate($validator, $transactionGroup);
// If type is set, source + destination info is mandatory.
// Not going to do this. Not sure where the demand came from.
// validate that the currency fits the source and/or destination account.
// validate all account info
$this->validateAccountInformationUpdate($validator);
// The currency info must match the accounts involved.
// Instead will ignore currency info as much as possible.
// TODO if the transaction_journal_id is empty, some fields are mandatory, like the amount!
// all journals must have a description
// // validate foreign currency info
//
//
// // make sure all splits have valid source + dest info
// the group must have a description if > 1 journal.
}
);
}

View File

@ -41,10 +41,8 @@ class RecurrenceFactory
{
use TransactionTypeTrait, RecurringTransactionTrait;
/** @var MessageBag */
private $errors;
/** @var User */
private $user;
private MessageBag $errors;
private User $user;
/**
@ -54,9 +52,6 @@ class RecurrenceFactory
*/
public function __construct()
{
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
}
$this->errors = new MessageBag;
}

View File

@ -38,18 +38,12 @@ use Log;
*/
class TransactionFactory
{
/** @var Account */
private $account;
/** @var TransactionCurrency */
private $currency;
/** @var TransactionCurrency */
private $foreignCurrency;
/** @var TransactionJournal */
private $journal;
/** @var bool */
private $reconciled;
/** @var User */
private $user;
private Account $account;
private TransactionCurrency $currency;
private TransactionCurrency $foreignCurrency;
private TransactionJournal $journal;
private bool $reconciled;
private User $user;
/**
@ -59,9 +53,6 @@ class TransactionFactory
*/
public function __construct()
{
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
}
$this->reconciled = false;
}

View File

@ -95,10 +95,6 @@ class TransactionJournalFactory
];
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
}
$this->currencyRepository = app(CurrencyRepositoryInterface::class);
$this->typeRepository = app(TransactionTypeRepositoryInterface::class);
$this->billRepository = app(BillRepositoryInterface::class);

View File

@ -34,18 +34,6 @@ use Log;
*/
class TransactionJournalMetaFactory
{
/**
* Constructor.
*
* @codeCoverageIgnore
*/
public function __construct()
{
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
}
}
/**
* @param array $data
*

View File

@ -33,18 +33,6 @@ use Log;
*/
class TransactionTypeFactory
{
/**
* Constructor.
*
* @codeCoverageIgnore
*/
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 $type
*

View File

@ -30,18 +30,6 @@ use Log;
*/
class ChartJsGenerator implements GeneratorInterface
{
/**
* Constructor.
*
* @codeCoverageIgnore
*/
public function __construct()
{
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
}
}
/**
* Expects data as:.
*

View File

@ -70,10 +70,6 @@ class AttachmentHelper implements AttachmentHelperInterface
$this->messages = new MessageBag;
$this->attachments = new Collection;
$this->uploadDisk = Storage::disk('upload');
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
}
}

View File

@ -39,10 +39,6 @@ class FiscalHelper implements FiscalHelperInterface
public function __construct()
{
$this->useCustomFiscalYear = app('preferences')->get('customFiscalYear', false)->data;
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
}
}
/**

View File

@ -44,9 +44,6 @@ class Help implements HelpInterface
*/
public function __construct()
{
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
}
$this->userAgent = sprintf($this->userAgent, config('firefly.version'));
}

View File

@ -47,16 +47,6 @@ class NetWorth implements NetWorthInterface
/** @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)));
}
}
/**
* Returns the user's net worth in an array with the following layout:
*

View File

@ -39,16 +39,6 @@ use Log;
*/
class PopupReport implements PopupReportInterface
{
/**
* Constructor.
*/
public function __construct()
{
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
}
}
/**
* Collect the transactions for one account and one budget.
*

View File

@ -49,12 +49,6 @@ class ReportHelper implements ReportHelperInterface
public function __construct(BudgetRepositoryInterface $budgetRepository)
{
$this->budgetRepository = $budgetRepository;
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
}
}
/**

View File

@ -1,83 +0,0 @@
<?php
/**
* ExchangeController.php
* Copyright (c) 2019 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Json;
use Carbon\Carbon;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Services\Currency\ExchangeRateInterface;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Log;
/**
* Class ExchangeController.
*/
class ExchangeController extends Controller
{
/**
* Returns an exchange rate.
*
* @param Request $request
* @param TransactionCurrency $fromCurrency
* @param TransactionCurrency $toCurrency
* @param Carbon $date
*
* @return JsonResponse
*/
public function getRate(Request $request, TransactionCurrency $fromCurrency, TransactionCurrency $toCurrency, Carbon $date): JsonResponse
{
/** @var CurrencyRepositoryInterface $repository */
$repository = app(CurrencyRepositoryInterface::class);
$rate = $repository->getExchangeRate($fromCurrency, $toCurrency, $date);
if (null === $rate) {
Log::debug(sprintf('No cached exchange rate in database for %s to %s on %s', $fromCurrency->code, $toCurrency->code, $date->format('Y-m-d')));
// create service:
/** @var User $user */
$user = auth()->user();
/** @var ExchangeRateInterface $service */
$service = app(ExchangeRateInterface::class);
$service->setUser($user);
// get rate:
$rate = $service->getRate($fromCurrency, $toCurrency, $date);
}
$return = $rate->toArray();
$return['amount'] = null;
if (null !== $request->get('amount')) {
// assume amount is in "from" currency:
$return['amount'] = bcmul($request->get('amount'), (string) $rate->rate, 12);
// round to toCurrency decimal places:
$return['amount'] = round($return['amount'], $toCurrency->decimal_places);
}
return response()->json($return);
}
}

View File

@ -39,16 +39,6 @@ class AccountTasker implements AccountTaskerInterface
/** @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 Collection $accounts
* @param Carbon $start

View File

@ -40,17 +40,6 @@ class OperationsRepository implements OperationsRepositoryInterface
/** @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)));
die(__METHOD__);
}
}
/**
* This method returns a list of all the withdrawal transaction journals (as arrays) set in that period
* which have the specified accounts. It's grouped per currency, with as few details in the array

View File

@ -45,16 +45,6 @@ class AttachmentRepository implements AttachmentRepositoryInterface
/** @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 Attachment $attachment
*

View File

@ -41,17 +41,6 @@ class NoBudgetRepository implements NoBudgetRepositoryInterface
/** @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)));
die(get_class($this));
}
}
/**
* @param Collection $accounts
* @param Carbon $start

View File

@ -40,17 +40,6 @@ class NoCategoryRepository implements NoCategoryRepositoryInterface
/** @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)));
die(__METHOD__);
}
}
/**
* This method returns a list of all the withdrawal transaction journals (as arrays) set in that period
* which have no category set to them. It's grouped per currency, with as few details in the array

View File

@ -40,17 +40,6 @@ class OperationsRepository implements OperationsRepositoryInterface
/** @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)));
die(__METHOD__);
}
}
/**
* This method returns a list of all the withdrawal transaction journals (as arrays) set in that period
* which have the specified category set to them. It's grouped per currency, with as few details in the array

View File

@ -42,16 +42,6 @@ class JournalCLIRepository implements JournalCLIRepositoryInterface
/** @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)));
}
}
/**
* Get all transaction journals with a specific type, regardless of user.
*

View File

@ -49,16 +49,6 @@ class JournalRepository implements JournalRepositoryInterface
/** @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)));
}
}
/**
* Search in journal descriptions.
*

View File

@ -40,16 +40,6 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
/** @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 LinkType $linkType
*

View File

@ -39,16 +39,6 @@ class ObjectGroupRepository implements ObjectGroupRepositoryInterface
/** @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)));
}
}
/**
* @inheritDoc
*/

View File

@ -41,16 +41,6 @@ class RuleRepository implements RuleRepositoryInterface
/** @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)));
}
}
/**
* @return int
*/

View File

@ -37,16 +37,6 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
/** @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)));
}
}
/**
* @return int
*/

View File

@ -40,17 +40,6 @@ class OperationsRepository implements OperationsRepositoryInterface
/** @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)));
die(__METHOD__);
}
}
/**
* This method returns a list of all the withdrawal transaction journals (as arrays) set in that period
* which have the specified tag(s) set to them. It's grouped per currency, with as few details in the array

View File

@ -53,25 +53,13 @@ use Log;
*/
class TransactionGroupRepository implements TransactionGroupRepositoryInterface
{
/** @var User */
private $user;
/**
* Constructor.
*/
public function __construct()
{
if ('testing' === config('app.env')) {
app('log')->warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
}
}
private User $user;
/**
* @param TransactionGroup $group
*/
public function destroy(TransactionGroup $group): void
{
/** @var TransactionGroupDestroyService $service */
$service = new TransactionGroupDestroyService;
$service->destroy($group);
}

View File

@ -1,7 +1,7 @@
<?php
/**
* ExchangeRateInterface.php
* Copyright (c) 2019 james@firefly-iii.org
/*
* IsDuplicateTransaction.php
* Copyright (c) 2020 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
@ -18,33 +18,33 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Services\Currency;
namespace FireflyIII\Rules;
use Carbon\Carbon;
use FireflyIII\Models\CurrencyExchangeRate;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\User;
use Illuminate\Contracts\Validation\Rule;
/**
* Interface ExchangeRateInterface
* Class IsDuplicateTransaction
*/
interface ExchangeRateInterface
class IsDuplicateTransaction implements Rule
{
/**
* @param TransactionCurrency $fromCurrency
* @param TransactionCurrency $toCurrency
* @param Carbon $date
*
* @return CurrencyExchangeRate
*/
public function getRate(TransactionCurrency $fromCurrency, TransactionCurrency $toCurrency, Carbon $date): CurrencyExchangeRate;
private string $value;
/**
* @param User $user
*
* @return mixed
* @inheritDoc
*/
public function setUser(User $user);
}
public function passes($attribute, $value)
{
$this->value = $value;
return false;
}
/**
* @inheritDoc
*/
public function message()
{
return $this->value;
}
}

View File

@ -1,137 +0,0 @@
<?php
/**
* FixerIOv2.php
* Copyright (c) 2019 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Services\Currency;
use Carbon\Carbon;
use Exception;
use FireflyIII\Models\CurrencyExchangeRate;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\User;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Log;
/**
* Class FixerIOv2.
*/
class FixerIOv2 implements ExchangeRateInterface
{
/** @var User */
protected $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 TransactionCurrency $fromCurrency
* @param TransactionCurrency $toCurrency
* @param Carbon $date
*
* @return CurrencyExchangeRate
* @throws Exception
*/
public function getRate(TransactionCurrency $fromCurrency, TransactionCurrency $toCurrency, Carbon $date): CurrencyExchangeRate
{
// create new exchange rate with default values.
$rate = 0;
$exchangeRate = new CurrencyExchangeRate;
$exchangeRate->user()->associate($this->user);
$exchangeRate->fromCurrency()->associate($fromCurrency);
$exchangeRate->toCurrency()->associate($toCurrency);
$exchangeRate->date = $date;
$exchangeRate->rate = $rate;
$exchangeRate->updated_at = today(config('app.timezone'));
$exchangeRate->created_at = today(config('app.timezone'));
// get API key
$apiKey = config('firefly.fixer_api_key');
// if no API key, return unsaved exchange rate.
if ('' === $apiKey) {
Log::warning('No fixer.IO API key, will not do conversion.');
return $exchangeRate;
}
// build URI
$uri = sprintf(
'http://data.fixer.io/api/%s?access_key=%s&base=%s&symbols=%s',
$date->format('Y-m-d'), $apiKey, $fromCurrency->code, $toCurrency->code
);
Log::debug(sprintf('Going to request exchange rate using URI %s', str_replace($apiKey, 'xxxx', $uri)));
$client = new Client;
try {
$res = $client->request('GET', $uri);
$statusCode = $res->getStatusCode();
$body = $res->getBody()->getContents();
} catch (GuzzleException|Exception $e) {
// don't care about error
$body = sprintf('Guzzle exception: %s', $e->getMessage());
$statusCode = 500;
}
Log::debug(sprintf('Result status code is %d', $statusCode));
Log::debug(sprintf('Result body is: %s', $body));
$content = null;
if (200 !== $statusCode) {
Log::error(sprintf('Something went wrong. Received error code %d and body "%s" from FixerIO.', $statusCode, $body));
}
$success = false;
// get rate from body:
if (200 === $statusCode) {
$content = json_decode($body, true);
$success = $content['success'] ?? false;
}
if (null !== $content && true === $success) {
$code = $toCurrency->code;
$rate = (float)($content['rates'][$code] ?? 0);
Log::debug('Got the following rates from Fixer: ', $content['rates'] ?? []);
}
$exchangeRate->rate = $rate;
if (0.0 !== $rate) {
Log::debug('Rate is not zero, save it!');
$exchangeRate->save();
}
return $exchangeRate;
}
/**
* @param User $user
*
* @return void
*/
public function setUser(User $user)
{
$this->user = $user;
}
}

View File

@ -1,126 +0,0 @@
<?php
/**
* RatesApiIOv1.php
* Copyright (c) 2019 https://github.com/BoGnY
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Services\Currency;
use Carbon\Carbon;
use Exception;
use FireflyIII\Models\CurrencyExchangeRate;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\User;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Log;
/**
* Class RatesApiIOv1.
* @codeCoverageIgnore
*/
class RatesApiIOv1 implements ExchangeRateInterface
{
/** @var User */
protected $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 TransactionCurrency $fromCurrency
* @param TransactionCurrency $toCurrency
* @param Carbon $date
*
* @return CurrencyExchangeRate
*/
public function getRate(TransactionCurrency $fromCurrency, TransactionCurrency $toCurrency, Carbon $date): CurrencyExchangeRate
{
// create new exchange rate with default values.
$rate = 0;
$exchangeRate = new CurrencyExchangeRate;
$exchangeRate->user()->associate($this->user);
$exchangeRate->fromCurrency()->associate($fromCurrency);
$exchangeRate->toCurrency()->associate($toCurrency);
$exchangeRate->date = $date;
$exchangeRate->rate = $rate;
$exchangeRate->updated_at = today(config('app.timezone'));
$exchangeRate->created_at = today(config('app.timezone'));
// build URI
$uri = sprintf(
'https://api.ratesapi.io/api/%s?base=%s&symbols=%s',
$date->format('Y-m-d'), $fromCurrency->code, $toCurrency->code
);
Log::debug(sprintf('Going to request exchange rate using URI %s', $uri));
$client = new Client;
try {
$res = $client->request('GET', $uri);
$statusCode = $res->getStatusCode();
$body = $res->getBody()->getContents();
} catch (GuzzleException|Exception $e) {
// don't care about error
$body = sprintf('Guzzle exception: %s', $e->getMessage());
$statusCode = 500;
}
Log::debug(sprintf('Result status code is %d', $statusCode));
Log::debug(sprintf('Result body is: %s', $body));
$content = null;
if (200 !== $statusCode) {
Log::error(sprintf('Something went wrong. Received error code %d and body "%s" from RatesApiIO.', $statusCode, $body));
}
$success = false;
// get rate from body:
if (200 === $statusCode) {
$content = json_decode($body, true);
$success = true;
}
if (null !== $content && true === $success) {
$code = $toCurrency->code;
$rate = (float)($content['rates'][$code] ?? 0);
Log::debug('Got the following rates from RatesApi: ', $content['rates'] ?? []);
}
$exchangeRate->rate = $rate;
if (0.0 !== $rate) {
Log::debug('Rate is not zero, save it!');
$exchangeRate->save();
}
return $exchangeRate;
}
/**
* @param User $user
*
* @return void
*/
public function setUser(User $user)
{
$this->user = $user;
}
}

View File

@ -210,12 +210,19 @@ trait AugumentData
return $cache->get(); // @codeCoverageIgnore
}
$set = $blRepository->getBudgetLimits($budget, $start, $end);
$limits = new Collection();
$set = $blRepository->getBudgetLimits($budget, $start, $end);
$limits = new Collection();
$budgetCollection = new Collection([$budget]);
/** @var BudgetLimit $entry */
foreach ($set as $entry) {
$entry->spent = $opsRepository->spentInPeriod(new Collection([$budget]), new Collection(), $entry->start_date, $entry->end_date);
$currency = $entry->transactionCurrency;
// clone because these objects change each other.
$currentStart = clone $start;
$currentEnd = clone $end;
$expenses = $opsRepository->sumExpenses($currentStart, $currentEnd, null, $budgetCollection, $currency);
$spent = $expenses[(int)$currency->id]['sum'] ?? '0';
$entry->spent = $spent;
$limits->push($entry);
}
$cache->store($limits);

View File

@ -65,7 +65,7 @@ return [
'log' => [
'transport' => 'log',
'channel' => env('MAIL_LOG_CHANNEL', 'stack'),
'level' => 'debug',
'level' => 'notice',
],
'array' => [