mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-12-19 04:49:30 +00:00
Fix issues related to #11109
This commit is contained in:
@@ -28,6 +28,7 @@ use Carbon\Carbon;
|
||||
use FireflyIII\Api\V1\Controllers\Controller;
|
||||
use FireflyIII\Api\V1\Requests\Models\CurrencyExchangeRate\DestroyRequest;
|
||||
use FireflyIII\Enums\UserRoleEnum;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\CurrencyExchangeRate;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\ExchangeRate\ExchangeRateRepositoryInterface;
|
||||
@@ -75,6 +76,9 @@ class DestroyController extends Controller
|
||||
if ($exchangeRate instanceof CurrencyExchangeRate) {
|
||||
$this->repository->deleteRate($exchangeRate);
|
||||
}
|
||||
if (!$exchangeRate instanceof CurrencyExchangeRate) {
|
||||
throw new FireflyException('Bla');
|
||||
}
|
||||
|
||||
return response()->json([], 204);
|
||||
}
|
||||
|
||||
@@ -82,7 +82,6 @@ class UpdateController extends Controller
|
||||
$exchangeRate = $this->repository->updateExchangeRate($exchangeRate, $rate, $date);
|
||||
|
||||
$transformer = new ExchangeRateTransformer();
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
||||
return response()
|
||||
->api($this->jsonApiObject(self::RESOURCE_KEY, $exchangeRate, $transformer))
|
||||
|
||||
0
public/v1/js/.gitkeep
Normal file → Executable file
0
public/v1/js/.gitkeep
Normal file → Executable file
@@ -44,20 +44,29 @@
|
||||
<div class="box-body no-padding">
|
||||
<nav v-if="totalPages > 1">
|
||||
<ul class="pagination">
|
||||
<li v-if="1 === this.page" class="page-item disabled" aria-disabled="true" :aria-label="$t('pagination.previous')">
|
||||
<li v-if="1 === this.page" class="page-item disabled" aria-disabled="true"
|
||||
:aria-label="$t('pagination.previous')">
|
||||
<span class="page-link" aria-hidden="true">‹</span>
|
||||
</li>
|
||||
<li class="page-item" v-if="1 !== this.page">
|
||||
<a class="page-link" :href="'/exchange-rates/'+from_code+'/'+to_code+'?page=' + (this.page-1)" rel="prev" :aria-label="$t('pagination.next')">‹</a>
|
||||
<a class="page-link"
|
||||
:href="'/exchange-rates/'+from_code+'/'+to_code+'?page=' + (this.page-1)"
|
||||
rel="prev" :aria-label="$t('pagination.next')">‹</a>
|
||||
</li>
|
||||
<li v-for="item in this.totalPages" :class="item === page ? 'page-item active' : 'page-item'" aria-current="page">
|
||||
<li v-for="item in this.totalPages"
|
||||
:class="item === page ? 'page-item active' : 'page-item'" aria-current="page">
|
||||
<span v-if="item === page" class="page-link" v-text="item"></span>
|
||||
<a v-if="item !== page" class="page-link" :href="'/exchange-rates/'+from_code+'/'+to_code+'?page=' + item" v-text="item"></a>
|
||||
<a v-if="item !== page" class="page-link"
|
||||
:href="'/exchange-rates/'+from_code+'/'+to_code+'?page=' + item"
|
||||
v-text="item"></a>
|
||||
</li>
|
||||
<li v-if="totalPages !== page" class="page-item">
|
||||
<a class="page-link" :href="'/exchange-rates/'+from_code+'/'+to_code+'?page=' + (this.page+1)" rel="next" :aria-label="$t('pagination.next')">›</a>
|
||||
<a class="page-link"
|
||||
:href="'/exchange-rates/'+from_code+'/'+to_code+'?page=' + (this.page+1)"
|
||||
rel="next" :aria-label="$t('pagination.next')">›</a>
|
||||
</li>
|
||||
<li v-if="totalPages === page" class="page-item disabled" aria-disabled="true" :aria-label="$t('pagination.next')">
|
||||
<li v-if="totalPages === page" class="page-item disabled" aria-disabled="true"
|
||||
:aria-label="$t('pagination.next')">
|
||||
<span class="page-link" aria-hidden="true">›</span>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -97,9 +106,11 @@
|
||||
>
|
||||
</td>
|
||||
<td>
|
||||
<!-- (<span v-text="rate.rate_id"></span>) -->
|
||||
<input type="number" class="form-control" min="0" step="any" v-model="rate.rate">
|
||||
</td>
|
||||
<td>
|
||||
<!-- (<span v-text="rate.inverse_id"></span>) -->
|
||||
<input type="number" class="form-control" min="0" step="any" v-model="rate.inverse">
|
||||
</td>
|
||||
<td>
|
||||
@@ -122,20 +133,29 @@
|
||||
|
||||
<nav v-if="totalPages > 1">
|
||||
<ul class="pagination">
|
||||
<li v-if="1 === this.page" class="page-item disabled" aria-disabled="true" :aria-label="$t('pagination.previous')">
|
||||
<li v-if="1 === this.page" class="page-item disabled" aria-disabled="true"
|
||||
:aria-label="$t('pagination.previous')">
|
||||
<span class="page-link" aria-hidden="true">‹</span>
|
||||
</li>
|
||||
<li class="page-item" v-if="1 !== this.page">
|
||||
<a class="page-link" :href="'/exchange-rates/'+from_code+'/'+to_code+'?page=' + (this.page-1)" rel="prev" :aria-label="$t('pagination.next')">‹</a>
|
||||
<a class="page-link"
|
||||
:href="'/exchange-rates/'+from_code+'/'+to_code+'?page=' + (this.page-1)"
|
||||
rel="prev" :aria-label="$t('pagination.next')">‹</a>
|
||||
</li>
|
||||
<li v-for="item in this.totalPages" :class="item === page ? 'page-item active' : 'page-item'" aria-current="page">
|
||||
<li v-for="item in this.totalPages"
|
||||
:class="item === page ? 'page-item active' : 'page-item'" aria-current="page">
|
||||
<span v-if="item === page" class="page-link" v-text="item"></span>
|
||||
<a v-if="item !== page" class="page-link" :href="'/exchange-rates/'+from_code+'/'+to_code+'?page=' + item" v-text="item"></a>
|
||||
<a v-if="item !== page" class="page-link"
|
||||
:href="'/exchange-rates/'+from_code+'/'+to_code+'?page=' + item"
|
||||
v-text="item"></a>
|
||||
</li>
|
||||
<li v-if="totalPages !== page" class="page-item">
|
||||
<a class="page-link" :href="'/exchange-rates/'+from_code+'/'+to_code+'?page=' + (this.page+1)" rel="next" :aria-label="$t('pagination.next')">›</a>
|
||||
<a class="page-link"
|
||||
:href="'/exchange-rates/'+from_code+'/'+to_code+'?page=' + (this.page+1)"
|
||||
rel="next" :aria-label="$t('pagination.next')">›</a>
|
||||
</li>
|
||||
<li v-if="totalPages === page" class="page-item disabled" aria-disabled="true" :aria-label="$t('pagination.next')">
|
||||
<li v-if="totalPages === page" class="page-item disabled" aria-disabled="true"
|
||||
:aria-label="$t('pagination.next')">
|
||||
<span class="page-link" aria-hidden="true">›</span>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -160,7 +180,8 @@
|
||||
<label for="ffInput_date" class="col-sm-4 control-label"
|
||||
v-text="$t('form.date')"></label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="date" name="date" id="ffInput_date" :disabled="posting"
|
||||
<input class="form-control" type="date" name="date" id="ffInput_date"
|
||||
:disabled="posting"
|
||||
autocomplete="off" spellcheck="false" v-model="newDate">
|
||||
</div>
|
||||
</div>
|
||||
@@ -168,16 +189,19 @@
|
||||
<label for="ffInput_rate" class="col-sm-4 control-label"
|
||||
v-text="$t('form.rate')"></label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="number" name="rate" id="ffInput_rate" :disabled="posting"
|
||||
<input class="form-control" type="number" name="rate" id="ffInput_rate"
|
||||
:disabled="posting"
|
||||
autocomplete="off" spellcheck="false" v-model="newRate" step="any">
|
||||
<p class="help-block" v-text="$t('firefly.help_rate_form', {from: from_code, to: to_code})">
|
||||
<p class="help-block"
|
||||
v-text="$t('firefly.help_rate_form', {from: from_code, to: to_code})">
|
||||
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="nodisablebutton btn pull-right btn-success" v-text="$t('firefly.save_new_rate')"></button>
|
||||
<button type="submit" class="nodisablebutton btn pull-right btn-success"
|
||||
v-text="$t('firefly.save_new_rate')"></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -217,9 +241,9 @@ export default {
|
||||
mounted() {
|
||||
// get from and to code from URL
|
||||
this.newDate = format(new Date, 'yyyy-MM-dd');
|
||||
let parts = window.location.href.split('/');
|
||||
this.from_code = parts[parts.length - 2];
|
||||
this.to_code = parts[parts.length - 1];
|
||||
let parts = window.location.pathname.split('/');
|
||||
this.from_code = parts[parts.length - 2].toUpperCase();
|
||||
this.to_code = parts[parts.length - 1].toUpperCase();
|
||||
|
||||
const params = new Proxy(new URLSearchParams(window.location.search), {
|
||||
get: (searchParams, prop) => searchParams.get(prop),
|
||||
@@ -232,8 +256,8 @@ export default {
|
||||
this.downloadRates(this.page);
|
||||
},
|
||||
methods: {
|
||||
submitRate: function(e) {
|
||||
if(e) e.preventDefault();
|
||||
submitRate: function (e) {
|
||||
if (e) e.preventDefault();
|
||||
this.posting = true;
|
||||
|
||||
axios.post("./api/v1/exchange-rates", {
|
||||
@@ -260,33 +284,74 @@ export default {
|
||||
if (0 === parts.length) {
|
||||
return;
|
||||
}
|
||||
console.log('These are the parts', parts);
|
||||
if ('' !== this.rates[index].rate) {
|
||||
//console.log('[a] Rate info is', this.rates[index]);
|
||||
this.updating = true;
|
||||
axios.put("./api/v1/exchange-rates/" + this.rates[index].rate_id, {rate: this.rates[index].rate})
|
||||
.then(() => {
|
||||
this.updating = false;
|
||||
});
|
||||
if (0 === parseInt(this.rates[index].rate_id)) {
|
||||
console.log('[a] POST, not PUT.');
|
||||
axios.post('./api/v1/exchange-rates',
|
||||
{
|
||||
from: this.from_code,
|
||||
to: this.to_code,
|
||||
rate: this.rates[index].rate,
|
||||
date: this.rates[index].date_field
|
||||
})
|
||||
.then(() => {
|
||||
this.updating = false;
|
||||
});
|
||||
}
|
||||
if (0 !== parseInt(this.rates[index].rate_id)) {
|
||||
console.log('[a] PUT, not POST.');
|
||||
axios.put('./api/v1/exchange-rates/' + this.rates[index].rate_id, {rate: this.rates[index].rate})
|
||||
.then(() => {
|
||||
this.updating = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
if ('' !== this.rates[index].inverse) {
|
||||
//console.log('[b] Rate info is', this.rates[index]);
|
||||
this.updating = true;
|
||||
axios.put("./api/v1/exchange-rates/" + this.rates[index].inverse_id, {rate: this.rates[index].inverse})
|
||||
.then(() => {
|
||||
this.updating = false;
|
||||
});
|
||||
if (0 === parseInt(this.rates[index].inverse_id)) {
|
||||
console.log('[b] POST, not PUT.');
|
||||
// post, not put
|
||||
axios.post('./api/v1/exchange-rates',
|
||||
{
|
||||
// remember, this is in reverse.
|
||||
from: this.to_code,
|
||||
to: this.from_code,
|
||||
rate: this.rates[index].inverse,
|
||||
date: this.rates[index].date_field
|
||||
})
|
||||
.then(() => {
|
||||
this.updating = false;
|
||||
});
|
||||
}
|
||||
if (0 !== parseInt(this.rates[index].inverse_id)) {
|
||||
console.log('[b] PUT, not POST.');
|
||||
axios.put('./api/v1/exchange-rates/' + this.rates[index].inverse_id, {rate: this.rates[index].inverse})
|
||||
.then(() => {
|
||||
this.updating = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
deleteRate: function (index) {
|
||||
// console.log(this.rates[index].key);
|
||||
let parts = this.spliceKey(this.rates[index].key);
|
||||
|
||||
if (0 === parts.length) {
|
||||
return;
|
||||
}
|
||||
// console.log(parts);
|
||||
|
||||
let rateId = parseInt(this.rates[index].rate_id);
|
||||
let inverseId = parseInt(this.rates[index].inverse_id);
|
||||
// delete A to B
|
||||
axios.delete("./api/v1/exchange-rates/" + parts.from + '/' + parts.to + '/' + format(parts.date, 'yyyy-MM-dd'));
|
||||
// delete B to A.
|
||||
axios.delete("./api/v1/exchange-rates/" + parts.to + '/' + parts.from + '/' + format(parts.date, 'yyyy-MM-dd'));
|
||||
if (rateId > 0) {
|
||||
axios.delete('./api/v1/exchange-rates/' + rateId);
|
||||
}
|
||||
if (inverseId > 0) {
|
||||
axios.delete('./api/v1/exchange-rates/' + inverseId);
|
||||
}
|
||||
|
||||
this.rates.splice(index, 1);
|
||||
},
|
||||
@@ -307,6 +372,7 @@ export default {
|
||||
};
|
||||
},
|
||||
downloadCurrencies: function () {
|
||||
console.log('Now downloading currencies.');
|
||||
this.loading = true;
|
||||
axios.get("./api/v1/currencies/" + this.from_code).then((response) => {
|
||||
this.from = {
|
||||
@@ -327,31 +393,36 @@ export default {
|
||||
downloadRates: function (page) {
|
||||
this.tempRates = {};
|
||||
this.loading = true;
|
||||
axios.get("./api/v1/exchange-rates/" + this.from_code + '/' + this.to_code + '?page=' + page).then((response) => {
|
||||
console.log('Now downloading rates.', page);
|
||||
axios.get('./api/v1/exchange-rates/' + this.from_code + '/' + this.to_code + '?page=' + page).then((response) => {
|
||||
for (let i in response.data.data) {
|
||||
if (response.data.data.hasOwnProperty(i)) {
|
||||
console.log('Downloaded entry #' + i);
|
||||
let current = response.data.data[i];
|
||||
let date = new Date(current.attributes.date);
|
||||
let from_code = current.attributes.from_currency_code;
|
||||
let to_code = current.attributes.to_currency_code;
|
||||
let from_code = current.attributes.from_currency_code.toUpperCase();
|
||||
let to_code = current.attributes.to_currency_code.toUpperCase();
|
||||
let rate = current.attributes.rate;
|
||||
let inverse = '';
|
||||
let rate_id = current.id;
|
||||
let inverse_id = '0';
|
||||
let key = from_code + '_' + to_code + '_' + format(date, 'yyyy-MM-dd');
|
||||
// console.log('Key is now "' + key + '"');
|
||||
console.log('Key is now "' + key + '"');
|
||||
|
||||
// perhaps the returned rate is actually the inverse rate.
|
||||
if (from_code === this.to_code && to_code === this.from_code) {
|
||||
// console.log('Inverse rate found!');
|
||||
key = to_code + '_' + from_code + '_' + format(date, 'yyyy-MM-dd');
|
||||
rate = '';
|
||||
// new: set rate id to zero.
|
||||
rate_id = '0';
|
||||
inverse = current.attributes.rate;
|
||||
inverse_id = current.id;
|
||||
// console.log('Key updated to "' + key + '"');
|
||||
console.log('Key updated to "' + key + '"');
|
||||
}
|
||||
|
||||
if (!this.tempRates.hasOwnProperty(key)) {
|
||||
console.log('New entry stored');
|
||||
this.tempRates[key] = {
|
||||
key: key,
|
||||
date: date,
|
||||
@@ -374,6 +445,7 @@ export default {
|
||||
this.tempRates[key].rate = rate;
|
||||
this.tempRates[key].rate_id = rate_id;
|
||||
}
|
||||
console.log('Found exchange rate #' + this.tempRates[key].rate_id + ' with inverse #' + this.tempRates[key].inverse_id);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ return [
|
||||
'webhook_account_info' => 'Cannot deliver account information for budget related webhooks.',
|
||||
'webhook_transaction_info' => 'Cannot deliver transaction information for budget related webhooks.',
|
||||
'invalid_account_type' => 'A piggy bank can only be linked to asset accounts and liabilities',
|
||||
'unique_currency_code' => 'This currency code is already in use',
|
||||
'invalid_account_currency' => 'This account does not use the currency you have selected',
|
||||
'current_amount_too_much' => 'The combined amount in "current_amount" cannot exceed the "target_amount".',
|
||||
'filter_must_be_in' => 'Filter ":filter" must be one of: :values',
|
||||
|
||||
Reference in New Issue
Block a user