Convert spendings' amounts if different currency is selected
MODIFY
app/Http/Controllers/SpendingController.php
app/Http/Controllers/SpendingController.php
@@ -4,16 +4,21 @@ namespace App\Http\Controllers;
use App\Helper;
use App\Models\Spending;
+use App\Repositories\ConversionRateRepository;
use App\Repositories\SpendingRepository;
use Illuminate\Http\Request;
class SpendingController extends Controller
{
private $spendingRepository;
+ private $conversionRateRepository;
- public function __construct(SpendingRepository $spendingRepository)
- {
+ public function __construct(
+ SpendingRepository $spendingRepository,
+ ConversionRateRepository $conversionRateRepository
+ ) {
$this->spendingRepository = $spendingRepository;
+ $this->conversionRateRepository = $conversionRateRepository;
}
public function create()
@@ -36,6 +41,17 @@ class SpendingController extends Controller
{
$request->validate($this->spendingRepository->getValidationRules());
+ $amount = Helper::rawNumberToInteger($request->input('amount'));
+
+ // Convert amount if a different currency was selected
+ if ($request->has('currency_id') && $request->currency_id !== session('space')->currency_id) {
+ $amount = $this->conversionRateRepository->convert(
+ $request->currency_id,
+ session('space')->currency_id,
+ $amount
+ );
+ }
+
$this->spendingRepository->create(
session('space')->id,
null,
@@ -43,7 +59,7 @@ class SpendingController extends Controller
$request->input('tag_id'),
$request->input('date'),
$request->input('description'),
- Helper::rawNumberToInteger($request->input('amount'))
+ $amount
);
return redirect()->route('dashboard');

MODIFY
app/Models/Recurring.php
app/Models/Recurring.php
@@ -51,6 +51,11 @@ class Recurring extends Model
}
// Relations
+ public function space()
+ {
+ return $this->belongsTo(Space::class);
+ }
+
public function spendings()
{
return $this->hasMany(Spending::class);

MODIFY
app/Repositories/ConversionRateRepository.php
app/Repositories/ConversionRateRepository.php
namespace App\Repositories;
use App\Models\ConversionRate;
+use Exception;
class ConversionRateRepository
{
- public function createOrUpdate(int $baseCurrencyId, int $targetCurrencyId, float $rate): void
+ public function getByIds(int $baseCurrencyId, int $targetCurrencyId)
{
- $existingConversionRate = ConversionRate::where('base_currency_id', $baseCurrencyId)
+ return ConversionRate::where('base_currency_id', $baseCurrencyId)
->where('target_currency_id', $targetCurrencyId)
->first();
+ }
+
+ public function createOrUpdate(int $baseCurrencyId, int $targetCurrencyId, float $rate): void
+ {
+ $existingConversionRate = $this->getByIds($baseCurrencyId, $targetCurrencyId);
if ($existingConversionRate) {
$existingConversionRate->fill([
@@ -24,4 +30,18 @@ class ConversionRateRepository
]);
}
}
+
+ /**
+ * $amount should be an integer, so if you want to convert "9.99", turn it into "99900" before calling this method
+ */
+ public function convert(int $baseCurrencyId, int $targetCurrencyId, int $amount): int
+ {
+ $conversionRate = $this->getByIds($baseCurrencyId, $targetCurrencyId);
+
+ if (!$conversionRate) {
+ throw new Exception('Could not find conversion rate');
+ }
+
+ return $amount * $conversionRate->rate;
+ }
}

MODIFY
app/Repositories/SpendingRepository.php
app/Repositories/SpendingRepository.php
@@ -13,6 +13,7 @@ class SpendingRepository
'tag_id' => 'nullable|exists:tags,id', // TODO CHECK IF TAG BELONGS TO USER
'date' => 'required|date|date_format:Y-m-d',
'description' => 'required|max:255',
+ 'currency_id' => 'nullable|exists:currencies,id',
'amount' => 'required|regex:/^\d*(\.\d{2})?$/'
];
}

MODIFY
resources/assets/js/components/TransactionWizard.vue
resources/assets/js/components/TransactionWizard.vue
_token: document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
date: this.date,
description: this.description,
+ currency_id: this.selectedCurrencyId,
amount: this.amount
}

Convert spendings' amounts if different currency is selected