mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-10-15 16:57:09 +00:00
Sync "convert to native"
This commit is contained in:
@@ -32,6 +32,7 @@ use FireflyIII\Models\UserGroup;
|
||||
use FireflyIII\Support\Facades\Preferences;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use NumberFormatter;
|
||||
|
||||
/**
|
||||
@@ -58,21 +59,21 @@ class Amount
|
||||
*/
|
||||
public function formatFlat(string $symbol, int $decimalPlaces, string $amount, ?bool $coloured = null): string
|
||||
{
|
||||
$locale = app('steam')->getLocale();
|
||||
$rounded = app('steam')->bcround($amount, $decimalPlaces);
|
||||
$locale = app('steam')->getLocale();
|
||||
$rounded = app('steam')->bcround($amount, $decimalPlaces);
|
||||
$coloured ??= true;
|
||||
|
||||
$fmt = new NumberFormatter($locale, NumberFormatter::CURRENCY);
|
||||
$fmt = new NumberFormatter($locale, NumberFormatter::CURRENCY);
|
||||
$fmt->setSymbol(NumberFormatter::CURRENCY_SYMBOL, $symbol);
|
||||
$fmt->setAttribute(NumberFormatter::MIN_FRACTION_DIGITS, $decimalPlaces);
|
||||
$fmt->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, $decimalPlaces);
|
||||
$result = (string) $fmt->format((float) $rounded); // intentional float
|
||||
$result = (string)$fmt->format((float)$rounded); // intentional float
|
||||
|
||||
if (true === $coloured) {
|
||||
if (1 === bccomp((string) $rounded, '0')) {
|
||||
if (1 === bccomp((string)$rounded, '0')) {
|
||||
return sprintf('<span class="text-success money-positive">%s</span>', $result);
|
||||
}
|
||||
if (-1 === bccomp((string) $rounded, '0')) {
|
||||
if (-1 === bccomp((string)$rounded, '0')) {
|
||||
return sprintf('<span class="text-danger money-negative">%s</span>', $result);
|
||||
}
|
||||
|
||||
@@ -106,23 +107,22 @@ class Amount
|
||||
$amount = $journal[$field] ?? '0';
|
||||
// Log::debug(sprintf('Field is %s, amount is %s', $field, $amount));
|
||||
// fallback, the transaction has a foreign amount in $currency.
|
||||
if ($convertToNative && null !== $journal['foreign_amount'] && $currency->id === (int) $journal['foreign_currency_id']) {
|
||||
if ($convertToNative && null !== $journal['foreign_amount'] && $currency->id === (int)$journal['foreign_currency_id']) {
|
||||
$amount = $journal['foreign_amount'];
|
||||
// Log::debug(sprintf('Overruled, amount is now %s', $amount));
|
||||
}
|
||||
|
||||
return (string) $amount;
|
||||
return (string)$amount;
|
||||
}
|
||||
|
||||
public function convertToNative(?User $user = null): bool
|
||||
{
|
||||
if (!$user instanceof User) {
|
||||
return true === Preferences::get('convert_to_native', false)->data && true === config('cer.enabled');
|
||||
// Log::debug(sprintf('convertToNative [a]: %s', var_export($result, true)));
|
||||
}
|
||||
Log::debug('convertToNative setting', Preferences::getForUser($user, 'convert_to_native', false));
|
||||
|
||||
return true === Preferences::getForUser($user, 'convert_to_native', false)->data && true === config('cer.enabled');
|
||||
// Log::debug(sprintf('convertToNative [b]: %s', var_export($result, true)));
|
||||
}
|
||||
|
||||
public function getNativeCurrency(): TransactionCurrency
|
||||
@@ -140,7 +140,7 @@ class Amount
|
||||
|
||||
public function getNativeCurrencyByUserGroup(UserGroup $userGroup): TransactionCurrency
|
||||
{
|
||||
$cache = new CacheProperties();
|
||||
$cache = new CacheProperties();
|
||||
$cache->addProperty('getNativeCurrencyByGroup');
|
||||
$cache->addProperty($userGroup->id);
|
||||
if ($cache->has()) {
|
||||
@@ -170,19 +170,19 @@ class Amount
|
||||
*/
|
||||
public function getAmountFromJournalObject(TransactionJournal $journal): string
|
||||
{
|
||||
$convertToNative = $this->convertToNative();
|
||||
$currency = $this->getNativeCurrency();
|
||||
$field = $convertToNative && $currency->id !== $journal->transaction_currency_id ? 'native_amount' : 'amount';
|
||||
$convertToNative = $this->convertToNative();
|
||||
$currency = $this->getNativeCurrency();
|
||||
$field = $convertToNative && $currency->id !== $journal->transaction_currency_id ? 'native_amount' : 'amount';
|
||||
|
||||
/** @var null|Transaction $sourceTransaction */
|
||||
$sourceTransaction = $journal->transactions()->where('amount', '<', 0)->first();
|
||||
if (null === $sourceTransaction) {
|
||||
return '0';
|
||||
}
|
||||
$amount = $sourceTransaction->{$field} ?? '0';
|
||||
if ((int) $sourceTransaction->foreign_currency_id === $currency->id) {
|
||||
$amount = $sourceTransaction->{$field} ?? '0';
|
||||
if ((int)$sourceTransaction->foreign_currency_id === $currency->id) {
|
||||
// use foreign amount instead!
|
||||
$amount = (string) $sourceTransaction->foreign_amount; // hard coded to be foreign amount.
|
||||
$amount = (string)$sourceTransaction->foreign_amount; // hard coded to be foreign amount.
|
||||
}
|
||||
|
||||
return $amount;
|
||||
@@ -245,20 +245,20 @@ class Amount
|
||||
private function getLocaleInfo(): array
|
||||
{
|
||||
// get config from preference, not from translation:
|
||||
$locale = app('steam')->getLocale();
|
||||
$array = app('steam')->getLocaleArray($locale);
|
||||
$locale = app('steam')->getLocale();
|
||||
$array = app('steam')->getLocaleArray($locale);
|
||||
|
||||
setlocale(LC_MONETARY, $array);
|
||||
$info = localeconv();
|
||||
$info = localeconv();
|
||||
|
||||
// correct variables
|
||||
$info['n_cs_precedes'] = $this->getLocaleField($info, 'n_cs_precedes');
|
||||
$info['p_cs_precedes'] = $this->getLocaleField($info, 'p_cs_precedes');
|
||||
$info['n_cs_precedes'] = $this->getLocaleField($info, 'n_cs_precedes');
|
||||
$info['p_cs_precedes'] = $this->getLocaleField($info, 'p_cs_precedes');
|
||||
|
||||
$info['n_sep_by_space'] = $this->getLocaleField($info, 'n_sep_by_space');
|
||||
$info['p_sep_by_space'] = $this->getLocaleField($info, 'p_sep_by_space');
|
||||
$info['n_sep_by_space'] = $this->getLocaleField($info, 'n_sep_by_space');
|
||||
$info['p_sep_by_space'] = $this->getLocaleField($info, 'p_sep_by_space');
|
||||
|
||||
$fmt = new NumberFormatter($locale, NumberFormatter::CURRENCY);
|
||||
$fmt = new NumberFormatter($locale, NumberFormatter::CURRENCY);
|
||||
|
||||
$info['mon_decimal_point'] = $fmt->getSymbol(NumberFormatter::MONETARY_SEPARATOR_SYMBOL);
|
||||
$info['mon_thousands_sep'] = $fmt->getSymbol(NumberFormatter::MONETARY_GROUPING_SEPARATOR_SYMBOL);
|
||||
@@ -290,11 +290,11 @@ class Amount
|
||||
|
||||
// there are five possible positions for the "+" or "-" sign (if it is even used)
|
||||
// pos_a and pos_e could be the ( and ) symbol.
|
||||
$posA = ''; // before everything
|
||||
$posB = ''; // before currency symbol
|
||||
$posC = ''; // after currency symbol
|
||||
$posD = ''; // before amount
|
||||
$posE = ''; // after everything
|
||||
$posA = ''; // before everything
|
||||
$posB = ''; // before currency symbol
|
||||
$posC = ''; // after currency symbol
|
||||
$posD = ''; // before amount
|
||||
$posE = ''; // after everything
|
||||
|
||||
// format would be (currency before amount)
|
||||
// AB%sC_D%vE
|
||||
@@ -336,9 +336,9 @@ class Amount
|
||||
}
|
||||
|
||||
if ($csPrecedes) {
|
||||
return $posA.$posB.'%s'.$posC.$space.$posD.'%v'.$posE;
|
||||
return $posA . $posB . '%s' . $posC . $space . $posD . '%v' . $posE;
|
||||
}
|
||||
|
||||
return $posA.$posD.'%v'.$space.$posB.'%s'.$posC.$posE;
|
||||
return $posA . $posD . '%v' . $space . $posB . '%s' . $posC . $posE;
|
||||
}
|
||||
}
|
||||
|
@@ -44,11 +44,22 @@ export default () => ({
|
||||
chartOptions: null,
|
||||
switchConvertToNative() {
|
||||
this.convertToNative = !this.convertToNative;
|
||||
setVariable('convertToNative', this.convertToNative);
|
||||
setVariable('convert_to_native', this.convertToNative);
|
||||
},
|
||||
localCacheKey(type) {
|
||||
return 'ds_accounts_' + type;
|
||||
},
|
||||
|
||||
eventListeners: {
|
||||
['@convert-to-native.window'](event){
|
||||
console.log('I heard that! it is now ' + event.detail);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
doSomeReload() {
|
||||
console.log('doSomeReload');
|
||||
},
|
||||
getFreshData() {
|
||||
const start = new Date(window.store.get('start'));
|
||||
const end = new Date(window.store.get('end'));
|
||||
@@ -273,8 +284,11 @@ export default () => ({
|
||||
|
||||
init() {
|
||||
// console.log('accounts init');
|
||||
Promise.all([getVariable('viewRange', '1M'), getVariable('convertToNative', false), getVariable('language', 'en_US'),
|
||||
getConfiguration('cer.enabled', false)
|
||||
Promise.all([
|
||||
getVariable('viewRange', '1M'), // 0
|
||||
getVariable('convert_to_native', false), // 1
|
||||
getVariable('language', 'en_US'), // 2
|
||||
getConfiguration('cer.enabled', false) // 3
|
||||
]).then((values) => {
|
||||
//console.log('accounts after promises');
|
||||
this.convertToNative = values[1] && values[3];
|
||||
@@ -296,7 +310,7 @@ export default () => ({
|
||||
this.loadChart();
|
||||
this.loadAccounts();
|
||||
});
|
||||
window.store.observe('convertToNative', () => {
|
||||
window.store.observe('convert_to_native', () => {
|
||||
if (!afterPromises) {
|
||||
return;
|
||||
}
|
||||
|
@@ -153,7 +153,7 @@ export default () => ({
|
||||
init() {
|
||||
// console.log('boxes init');
|
||||
// TODO can be replaced by "getVariables"
|
||||
Promise.all([getVariable('viewRange'), getVariable('convertToNative', false)]).then((values) => {
|
||||
Promise.all([getVariable('viewRange'), getVariable('convert_to_native', false)]).then((values) => {
|
||||
// console.log('boxes after promises');
|
||||
afterPromises = true;
|
||||
this.convertToNative = values[1];
|
||||
@@ -167,7 +167,7 @@ export default () => ({
|
||||
this.boxData = null;
|
||||
this.loadBoxes();
|
||||
});
|
||||
window.store.observe('convertToNative', (newValue) => {
|
||||
window.store.observe('convert_to_native', (newValue) => {
|
||||
if (!afterPromises) {
|
||||
return;
|
||||
}
|
||||
|
@@ -123,8 +123,6 @@ export default () => ({
|
||||
for (const i in data) {
|
||||
if (data.hasOwnProperty(i)) {
|
||||
let current = data[i];
|
||||
console.log('Now at');
|
||||
console.log(current);
|
||||
// // convert to EUR yes no?
|
||||
let label = current.label + ' (' + current.currency_code + ')';
|
||||
options.data.labels.push(label);
|
||||
@@ -159,7 +157,7 @@ export default () => ({
|
||||
|
||||
|
||||
init() {
|
||||
Promise.all([getVariable('convertToNative', false)]).then((values) => {
|
||||
Promise.all([getVariable('convert_to_native', false)]).then((values) => {
|
||||
this.convertToNative = values[0];
|
||||
afterPromises = true;
|
||||
if (false === this.loading) {
|
||||
@@ -176,7 +174,7 @@ export default () => ({
|
||||
this.loadChart();
|
||||
}
|
||||
});
|
||||
window.store.observe('convertToNative', (newValue) => {
|
||||
window.store.observe('convert_to_native', (newValue) => {
|
||||
if (!afterPromises) {
|
||||
return;
|
||||
}
|
||||
|
@@ -183,7 +183,7 @@ export default () => ({
|
||||
},
|
||||
init() {
|
||||
// console.log('categories init');
|
||||
Promise.all([getVariable('convertToNative', false),]).then((values) => {
|
||||
Promise.all([getVariable('convert_to_native', false),]).then((values) => {
|
||||
this.convertToNative = values[0];
|
||||
afterPromises = true;
|
||||
this.loadChart();
|
||||
@@ -195,7 +195,7 @@ export default () => ({
|
||||
this.chartData = null;
|
||||
this.loadChart();
|
||||
});
|
||||
window.store.observe('convertToNative', (newValue) => {
|
||||
window.store.observe('convert_to_native', (newValue) => {
|
||||
if (!afterPromises) {
|
||||
return;
|
||||
}
|
||||
|
@@ -46,7 +46,8 @@ import {
|
||||
} from "chart.js";
|
||||
import 'chartjs-adapter-date-fns';
|
||||
import {showInternalsButton} from "../../support/page-settings/show-internals-button.js";
|
||||
import {showWizardButton} from "../../support/page-settings/show-wizard-button.js";
|
||||
import {setVariable} from "../../store/set-variable.js";
|
||||
import {getVariable} from "../../store/get-variable.js";
|
||||
|
||||
// register things
|
||||
Chart.register({
|
||||
@@ -66,7 +67,25 @@ Chart.register({
|
||||
Legend
|
||||
});
|
||||
|
||||
let index = function () {
|
||||
return {
|
||||
convertToNative: false,
|
||||
saveNativeSettings(event) {
|
||||
setVariable('convert_to_native', event.currentTarget.checked);
|
||||
this.$dispatch('convert-to-native', event.currentTarget.checked);
|
||||
console.log('saveNativeSettings + dispatch.');
|
||||
},
|
||||
init() {
|
||||
Promise.all([getVariable('convert_to_native', false)]).then((values) => {
|
||||
this.convertToNative = values[0];
|
||||
console.log('convert_to_native: ' + this.convertToNative);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const comps = {
|
||||
index,
|
||||
dates,
|
||||
boxes,
|
||||
accounts,
|
||||
|
@@ -129,7 +129,7 @@ export default () => ({
|
||||
init() {
|
||||
// console.log('piggies init');
|
||||
apiData = [];
|
||||
Promise.all([getVariable('convertToNative', false)]).then((values) => {
|
||||
Promise.all([getVariable('convert_to_native', false)]).then((values) => {
|
||||
|
||||
afterPromises = true;
|
||||
this.convertToNative = values[0];
|
||||
@@ -144,7 +144,7 @@ export default () => ({
|
||||
apiData = [];
|
||||
this.loadPiggyBanks();
|
||||
});
|
||||
window.store.observe('convertToNative', (newValue) => {
|
||||
window.store.observe('convert_to_native', (newValue) => {
|
||||
if (!afterPromises) {
|
||||
return;
|
||||
}
|
||||
|
@@ -94,6 +94,7 @@ function getObjectName(type, name, direction, code) {
|
||||
if ('category' === type && null === name && 'out' === direction) {
|
||||
return translations.unknown_category + ' (' + translations.out + (convertToNative ? ', ' + code + ')' : ')');
|
||||
}
|
||||
|
||||
// account 4x
|
||||
if ('account' === type && null === name && 'in' === direction) {
|
||||
return translations.unknown_source + (convertToNative ? ' (' + code + ')' : '');
|
||||
@@ -348,9 +349,13 @@ export default () => ({
|
||||
init() {
|
||||
// console.log('sankey init');
|
||||
transactions = [];
|
||||
Promise.all([getVariable('convertToNative', false)]).then((values) => {
|
||||
Promise.all([getVariable('convert_to_native', false)]).then((values) => {
|
||||
this.convertToNative = values[0];
|
||||
convertToNative = values[0];
|
||||
|
||||
this.convertToNative = false;
|
||||
convertToNative = false;
|
||||
|
||||
// some translations:
|
||||
translations.all_money = i18next.t('firefly.all_money');
|
||||
translations.category = i18next.t('firefly.category');
|
||||
@@ -378,7 +383,7 @@ export default () => ({
|
||||
this.transactions = [];
|
||||
this.loadChart();
|
||||
});
|
||||
window.store.observe('convertToNative', (newValue) => {
|
||||
window.store.observe('convert_to_native', (newValue) => {
|
||||
if (!afterPromises) {
|
||||
return;
|
||||
}
|
||||
|
@@ -305,7 +305,7 @@ export default () => ({
|
||||
},
|
||||
|
||||
init() {
|
||||
Promise.all([getVariable('convertToNative', false)]).then((values) => {
|
||||
Promise.all([getVariable('convert_to_native', false)]).then((values) => {
|
||||
this.convertToNative = values[0];
|
||||
afterPromises = true;
|
||||
|
||||
@@ -323,7 +323,7 @@ export default () => ({
|
||||
this.startSubscriptions();
|
||||
}
|
||||
});
|
||||
window.store.observe('convertToNative', (newValue) => {
|
||||
window.store.observe('convert_to_native', (newValue) => {
|
||||
if (!afterPromises) {
|
||||
return;
|
||||
}
|
||||
|
@@ -40,7 +40,7 @@ export function setVariable(name, value = null) {
|
||||
// preference does not exist (yet).
|
||||
// POST it
|
||||
let poster = (new Post);
|
||||
poster.post(name, value).then((response) => {
|
||||
poster.post(name, value).then((response) => {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@@ -21,6 +21,14 @@
|
||||
import {format} from "date-fns";
|
||||
|
||||
export default function (amount, currencyCode) {
|
||||
if( (typeof amount !== 'number' && typeof amount !== 'string') || isNaN(amount)) {
|
||||
console.warn('format-money: amount is not a number:', amount);
|
||||
return '';
|
||||
}
|
||||
if(typeof currencyCode !== 'string' || currencyCode.length !== 3) {
|
||||
console.warn('format-money: currencyCode is not a valid ISO 4217 code:', currencyCode);
|
||||
return '';
|
||||
}
|
||||
let locale = window.__localeId__.replace('_', '-');
|
||||
|
||||
return Intl.NumberFormat(locale, {
|
||||
|
@@ -7,7 +7,7 @@
|
||||
@include('partials.dashboard.boxes')
|
||||
|
||||
<!-- row with account, budget and category data -->
|
||||
<div class="row mb-2" x-data="accounts">
|
||||
<div class="row mb-2" x-data="accounts" x-bind="eventListeners">
|
||||
<!-- column with 3 charts -->
|
||||
<div class="col-xl-8 col-lg-12 col-sm-12 col-xs-12">
|
||||
<!-- row with account chart -->
|
||||
@@ -49,7 +49,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="internalsModal" tabindex="-1" aria-labelledby="internalsModalLabel"
|
||||
<div x-data="index" class="modal fade" id="internalsModal" tabindex="-1" aria-labelledby="internalsModalLabel"
|
||||
aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
@@ -58,9 +58,17 @@
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>
|
||||
Buttons.
|
||||
</p>
|
||||
<div class="row mb-3">
|
||||
<label class="col-sm-4 col-form-label">Convert to native</label>
|
||||
<div class="col-sm-8">
|
||||
<div class="form-check form-switch form-check-inline">
|
||||
<label>
|
||||
<input class="form-check-input" x-model="convertToNative" type="checkbox" @change="saveNativeSettings"> <span
|
||||
>Yes no</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{ __('firefly.close') }}</button>
|
||||
|
Reference in New Issue
Block a user