mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop
This commit is contained in:
commit
26d851e69e
@ -3,6 +3,9 @@
|
|||||||
Over time, many people have contributed to Firefly III. Their efforts are not always visible, but always remembered and appreciated.
|
Over time, many people have contributed to Firefly III. Their efforts are not always visible, but always remembered and appreciated.
|
||||||
Please find below all the people who contributed to the Firefly III code. Their names are mentioned in the year of their first contribution.
|
Please find below all the people who contributed to the Firefly III code. Their names are mentioned in the year of their first contribution.
|
||||||
|
|
||||||
|
## 2025
|
||||||
|
- SoftBrix
|
||||||
|
|
||||||
## 2024
|
## 2024
|
||||||
- Sobuno
|
- Sobuno
|
||||||
- TasneemTantawy
|
- TasneemTantawy
|
||||||
|
@ -714,9 +714,9 @@ class GroupCollector implements GroupCollectorInterface
|
|||||||
if (null === $transaction['amount']) {
|
if (null === $transaction['amount']) {
|
||||||
throw new FireflyException(sprintf('Amount is NULL for a transaction in group #%d, please investigate.', $groudId));
|
throw new FireflyException(sprintf('Amount is NULL for a transaction in group #%d, please investigate.', $groudId));
|
||||||
}
|
}
|
||||||
$nativeAmount = (string) ('' === $transaction['native_amount'] ? '0' : $transaction['native_amount']);
|
$nativeAmount = (string) ('' === $transaction['native_amount'] ? '0' : $transaction['native_amount']);
|
||||||
$nativeForeignAmount = (string) ('' === $transaction['native_foreign_amount'] ? '0' : $transaction['native_foreign_amount']);
|
$nativeForeignAmount = (string) ('' === $transaction['native_foreign_amount'] ? '0' : $transaction['native_foreign_amount']);
|
||||||
$foreignAmount = (string) ('' === $transaction['foreign_amount'] ? '0' : $transaction['foreign_amount']);
|
$foreignAmount = (string) ('' === $transaction['foreign_amount'] ? '0' : $transaction['foreign_amount']);
|
||||||
|
|
||||||
// set default:
|
// set default:
|
||||||
if (!array_key_exists($currencyId, $groups[$groudId]['sums'])) {
|
if (!array_key_exists($currencyId, $groups[$groudId]['sums'])) {
|
||||||
@ -740,7 +740,7 @@ class GroupCollector implements GroupCollectorInterface
|
|||||||
$groups[$groudId]['sums'][$currencyId]['currency_symbol'] = $transaction['foreign_currency_symbol'];
|
$groups[$groudId]['sums'][$currencyId]['currency_symbol'] = $transaction['foreign_currency_symbol'];
|
||||||
$groups[$groudId]['sums'][$currencyId]['currency_decimal_places'] = $transaction['foreign_currency_decimal_places'];
|
$groups[$groudId]['sums'][$currencyId]['currency_decimal_places'] = $transaction['foreign_currency_decimal_places'];
|
||||||
$groups[$groudId]['sums'][$currencyId]['amount'] = '0';
|
$groups[$groudId]['sums'][$currencyId]['amount'] = '0';
|
||||||
$groups[$groudId]['sums'][$currencyId]['native_amount'] = '0';
|
$groups[$groudId]['sums'][$currencyId]['native_amount'] = '0';
|
||||||
}
|
}
|
||||||
$groups[$groudId]['sums'][$currencyId]['amount'] = bcadd($groups[$groudId]['sums'][$currencyId]['amount'], $foreignAmount);
|
$groups[$groudId]['sums'][$currencyId]['amount'] = bcadd($groups[$groudId]['sums'][$currencyId]['amount'], $foreignAmount);
|
||||||
$groups[$groudId]['sums'][$currencyId]['native_amount'] = bcadd($groups[$groudId]['sums'][$currencyId]['amount'], $nativeForeignAmount);
|
$groups[$groudId]['sums'][$currencyId]['native_amount'] = bcadd($groups[$groudId]['sums'][$currencyId]['amount'], $nativeForeignAmount);
|
||||||
|
@ -84,11 +84,11 @@ class AccountController extends Controller
|
|||||||
Log::debug('RevenueAccounts');
|
Log::debug('RevenueAccounts');
|
||||||
|
|
||||||
/** @var Carbon $start */
|
/** @var Carbon $start */
|
||||||
$start = clone session('start', today(config('app.timezone'))->startOfMonth());
|
$start = clone session('start', today(config('app.timezone'))->startOfMonth());
|
||||||
|
|
||||||
/** @var Carbon $end */
|
/** @var Carbon $end */
|
||||||
$end = clone session('end', today(config('app.timezone'))->endOfMonth());
|
$end = clone session('end', today(config('app.timezone'))->endOfMonth());
|
||||||
$cache = new CacheProperties();
|
$cache = new CacheProperties();
|
||||||
$cache->addProperty($start);
|
$cache->addProperty($start);
|
||||||
$cache->addProperty($end);
|
$cache->addProperty($end);
|
||||||
$cache->addProperty($this->convertToNative);
|
$cache->addProperty($this->convertToNative);
|
||||||
@ -99,13 +99,13 @@ class AccountController extends Controller
|
|||||||
$start->subDay();
|
$start->subDay();
|
||||||
|
|
||||||
// prep some vars:
|
// prep some vars:
|
||||||
$currencies = [];
|
$currencies = [];
|
||||||
$chartData = [];
|
$chartData = [];
|
||||||
$tempData = [];
|
$tempData = [];
|
||||||
|
|
||||||
// grab all accounts and names
|
// grab all accounts and names
|
||||||
$accounts = $this->accountRepository->getAccountsByType([AccountTypeEnum::EXPENSE->value]);
|
$accounts = $this->accountRepository->getAccountsByType([AccountTypeEnum::EXPENSE->value]);
|
||||||
$accountNames = $this->extractNames($accounts);
|
$accountNames = $this->extractNames($accounts);
|
||||||
|
|
||||||
// grab all balances
|
// grab all balances
|
||||||
$startBalances = app('steam')->finalAccountsBalance($accounts, $start);
|
$startBalances = app('steam')->finalAccountsBalance($accounts, $start);
|
||||||
@ -137,13 +137,13 @@ class AccountController extends Controller
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Log::debug(sprintf('Will process expense array "%s" with amount %s', $key, $endBalance));
|
// Log::debug(sprintf('Will process expense array "%s" with amount %s', $key, $endBalance));
|
||||||
$searchCode = $this->convertToNative ? $this->defaultCurrency->code : $key;
|
$searchCode = $this->convertToNative ? $this->defaultCurrency->code : $key;
|
||||||
// Log::debug(sprintf('Search code is %s', $searchCode));
|
// Log::debug(sprintf('Search code is %s', $searchCode));
|
||||||
// see if there is an accompanying start amount.
|
// see if there is an accompanying start amount.
|
||||||
// grab the difference and find the currency.
|
// grab the difference and find the currency.
|
||||||
$startBalance = ($startBalances[$account->id][$key] ?? '0');
|
$startBalance = ($startBalances[$account->id][$key] ?? '0');
|
||||||
// Log::debug(sprintf('Start balance is %s', $startBalance));
|
// Log::debug(sprintf('Start balance is %s', $startBalance));
|
||||||
$diff = bcsub($endBalance, $startBalance);
|
$diff = bcsub($endBalance, $startBalance);
|
||||||
$currencies[$searchCode] ??= $this->currencyRepository->findByCode($searchCode);
|
$currencies[$searchCode] ??= $this->currencyRepository->findByCode($searchCode);
|
||||||
if (0 !== bccomp($diff, '0')) {
|
if (0 !== bccomp($diff, '0')) {
|
||||||
// store the values in a temporary array.
|
// store the values in a temporary array.
|
||||||
@ -161,10 +161,10 @@ class AccountController extends Controller
|
|||||||
foreach ($currencies as $currency) {
|
foreach ($currencies as $currency) {
|
||||||
$newCurrencies[$currency->id] = $currency;
|
$newCurrencies[$currency->id] = $currency;
|
||||||
}
|
}
|
||||||
$currencies = $newCurrencies;
|
$currencies = $newCurrencies;
|
||||||
|
|
||||||
// sort temp array by amount.
|
// sort temp array by amount.
|
||||||
$amounts = array_column($tempData, 'diff_float');
|
$amounts = array_column($tempData, 'diff_float');
|
||||||
array_multisort($amounts, SORT_DESC, $tempData);
|
array_multisort($amounts, SORT_DESC, $tempData);
|
||||||
|
|
||||||
// loop all found currencies and build the data array for the chart.
|
// loop all found currencies and build the data array for the chart.
|
||||||
@ -175,12 +175,12 @@ class AccountController extends Controller
|
|||||||
foreach ($currencies as $currencyId => $currency) {
|
foreach ($currencies as $currencyId => $currency) {
|
||||||
$dataSet
|
$dataSet
|
||||||
= [
|
= [
|
||||||
'label' => (string) trans('firefly.spent'),
|
'label' => (string) trans('firefly.spent'),
|
||||||
'type' => 'bar',
|
'type' => 'bar',
|
||||||
'currency_symbol' => $currency->symbol,
|
'currency_symbol' => $currency->symbol,
|
||||||
'currency_code' => $currency->code,
|
'currency_code' => $currency->code,
|
||||||
'entries' => $this->expandNames($tempData),
|
'entries' => $this->expandNames($tempData),
|
||||||
];
|
];
|
||||||
$chartData[$currencyId] = $dataSet;
|
$chartData[$currencyId] = $dataSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,7 +191,7 @@ class AccountController extends Controller
|
|||||||
$chartData[$currencyId]['entries'][$name] = (float) $entry['difference'];
|
$chartData[$currencyId]['entries'][$name] = (float) $entry['difference'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = $this->generator->multiSet($chartData);
|
$data = $this->generator->multiSet($chartData);
|
||||||
$cache->store($data);
|
$cache->store($data);
|
||||||
|
|
||||||
return response()->json($data);
|
return response()->json($data);
|
||||||
@ -213,7 +213,7 @@ class AccountController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function expenseBudget(Account $account, Carbon $start, Carbon $end): JsonResponse
|
public function expenseBudget(Account $account, Carbon $start, Carbon $end): JsonResponse
|
||||||
{
|
{
|
||||||
$cache = new CacheProperties();
|
$cache = new CacheProperties();
|
||||||
$cache->addProperty($account->id);
|
$cache->addProperty($account->id);
|
||||||
$cache->addProperty($start);
|
$cache->addProperty($start);
|
||||||
$cache->addProperty($end);
|
$cache->addProperty($end);
|
||||||
@ -232,9 +232,9 @@ class AccountController extends Controller
|
|||||||
|
|
||||||
/** @var array $journal */
|
/** @var array $journal */
|
||||||
foreach ($journals as $journal) {
|
foreach ($journals as $journal) {
|
||||||
$budgetId = (int) $journal['budget_id'];
|
$budgetId = (int) $journal['budget_id'];
|
||||||
$key = sprintf('%d-%d', $budgetId, $journal['currency_id']);
|
$key = sprintf('%d-%d', $budgetId, $journal['currency_id']);
|
||||||
$budgetIds[] = $budgetId;
|
$budgetIds[] = $budgetId;
|
||||||
if (!array_key_exists($key, $result)) {
|
if (!array_key_exists($key, $result)) {
|
||||||
$result[$key] = [
|
$result[$key] = [
|
||||||
'total' => '0',
|
'total' => '0',
|
||||||
@ -247,7 +247,7 @@ class AccountController extends Controller
|
|||||||
$result[$key]['total'] = bcadd($journal['amount'], $result[$key]['total']);
|
$result[$key]['total'] = bcadd($journal['amount'], $result[$key]['total']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$names = $this->getBudgetNames($budgetIds);
|
$names = $this->getBudgetNames($budgetIds);
|
||||||
|
|
||||||
foreach ($result as $row) {
|
foreach ($result as $row) {
|
||||||
$budgetId = $row['budget_id'];
|
$budgetId = $row['budget_id'];
|
||||||
@ -256,7 +256,7 @@ class AccountController extends Controller
|
|||||||
$chartData[$label] = ['amount' => $row['total'], 'currency_symbol' => $row['currency_symbol'], 'currency_code' => $row['currency_code']];
|
$chartData[$label] = ['amount' => $row['total'], 'currency_symbol' => $row['currency_symbol'], 'currency_code' => $row['currency_code']];
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = $this->generator->multiCurrencyPieChart($chartData);
|
$data = $this->generator->multiCurrencyPieChart($chartData);
|
||||||
$cache->store($data);
|
$cache->store($data);
|
||||||
|
|
||||||
return response()->json($data);
|
return response()->json($data);
|
||||||
@ -278,7 +278,7 @@ class AccountController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function expenseCategory(Account $account, Carbon $start, Carbon $end): JsonResponse
|
public function expenseCategory(Account $account, Carbon $start, Carbon $end): JsonResponse
|
||||||
{
|
{
|
||||||
$cache = new CacheProperties();
|
$cache = new CacheProperties();
|
||||||
$cache->addProperty($account->id);
|
$cache->addProperty($account->id);
|
||||||
$cache->addProperty($start);
|
$cache->addProperty($start);
|
||||||
$cache->addProperty($end);
|
$cache->addProperty($end);
|
||||||
@ -296,7 +296,7 @@ class AccountController extends Controller
|
|||||||
|
|
||||||
/** @var array $journal */
|
/** @var array $journal */
|
||||||
foreach ($journals as $journal) {
|
foreach ($journals as $journal) {
|
||||||
$key = sprintf('%d-%d', $journal['category_id'], $journal['currency_id']);
|
$key = sprintf('%d-%d', $journal['category_id'], $journal['currency_id']);
|
||||||
if (!array_key_exists($key, $result)) {
|
if (!array_key_exists($key, $result)) {
|
||||||
$result[$key] = [
|
$result[$key] = [
|
||||||
'total' => '0',
|
'total' => '0',
|
||||||
@ -308,7 +308,7 @@ class AccountController extends Controller
|
|||||||
}
|
}
|
||||||
$result[$key]['total'] = bcadd($journal['amount'], $result[$key]['total']);
|
$result[$key]['total'] = bcadd($journal['amount'], $result[$key]['total']);
|
||||||
}
|
}
|
||||||
$names = $this->getCategoryNames(array_keys($result));
|
$names = $this->getCategoryNames(array_keys($result));
|
||||||
|
|
||||||
foreach ($result as $row) {
|
foreach ($result as $row) {
|
||||||
$categoryId = $row['category_id'];
|
$categoryId = $row['category_id'];
|
||||||
@ -317,7 +317,7 @@ class AccountController extends Controller
|
|||||||
$chartData[$label] = ['amount' => $row['total'], 'currency_symbol' => $row['currency_symbol'], 'currency_code' => $row['currency_code']];
|
$chartData[$label] = ['amount' => $row['total'], 'currency_symbol' => $row['currency_symbol'], 'currency_code' => $row['currency_code']];
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = $this->generator->multiCurrencyPieChart($chartData);
|
$data = $this->generator->multiCurrencyPieChart($chartData);
|
||||||
$cache->store($data);
|
$cache->store($data);
|
||||||
|
|
||||||
return response()->json($data);
|
return response()->json($data);
|
||||||
@ -330,9 +330,9 @@ class AccountController extends Controller
|
|||||||
* */
|
* */
|
||||||
public function frontpage(AccountRepositoryInterface $repository): JsonResponse
|
public function frontpage(AccountRepositoryInterface $repository): JsonResponse
|
||||||
{
|
{
|
||||||
$start = clone session('start', today(config('app.timezone'))->startOfMonth());
|
$start = clone session('start', today(config('app.timezone'))->startOfMonth());
|
||||||
$end = clone session('end', today(config('app.timezone'))->endOfMonth());
|
$end = clone session('end', today(config('app.timezone'))->endOfMonth());
|
||||||
$defaultSet = $repository->getAccountsByType([AccountTypeEnum::DEFAULT->value, AccountTypeEnum::ASSET->value])->pluck('id')->toArray();
|
$defaultSet = $repository->getAccountsByType([AccountTypeEnum::DEFAULT->value, AccountTypeEnum::ASSET->value])->pluck('id')->toArray();
|
||||||
Log::debug('Default set is ', $defaultSet);
|
Log::debug('Default set is ', $defaultSet);
|
||||||
$frontpage = app('preferences')->get('frontpageAccounts', $defaultSet);
|
$frontpage = app('preferences')->get('frontpageAccounts', $defaultSet);
|
||||||
$frontpageArray = !is_array($frontpage->data) ? [] : $frontpage->data;
|
$frontpageArray = !is_array($frontpage->data) ? [] : $frontpage->data;
|
||||||
@ -341,7 +341,7 @@ class AccountController extends Controller
|
|||||||
app('preferences')->set('frontpageAccounts', $defaultSet);
|
app('preferences')->set('frontpageAccounts', $defaultSet);
|
||||||
Log::debug('frontpage set is empty!');
|
Log::debug('frontpage set is empty!');
|
||||||
}
|
}
|
||||||
$accounts = $repository->getAccountsById($frontpageArray);
|
$accounts = $repository->getAccountsById($frontpageArray);
|
||||||
|
|
||||||
return response()->json($this->accountBalanceChart($accounts, $start, $end));
|
return response()->json($this->accountBalanceChart($accounts, $start, $end));
|
||||||
}
|
}
|
||||||
@ -362,7 +362,7 @@ class AccountController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function incomeCategory(Account $account, Carbon $start, Carbon $end): JsonResponse
|
public function incomeCategory(Account $account, Carbon $start, Carbon $end): JsonResponse
|
||||||
{
|
{
|
||||||
$cache = new CacheProperties();
|
$cache = new CacheProperties();
|
||||||
$cache->addProperty($account->id);
|
$cache->addProperty($account->id);
|
||||||
$cache->addProperty($start);
|
$cache->addProperty($start);
|
||||||
$cache->addProperty($end);
|
$cache->addProperty($end);
|
||||||
@ -382,7 +382,7 @@ class AccountController extends Controller
|
|||||||
|
|
||||||
/** @var array $journal */
|
/** @var array $journal */
|
||||||
foreach ($journals as $journal) {
|
foreach ($journals as $journal) {
|
||||||
$key = sprintf('%d-%d', $journal['category_id'], $journal['currency_id']);
|
$key = sprintf('%d-%d', $journal['category_id'], $journal['currency_id']);
|
||||||
if (!array_key_exists($key, $result)) {
|
if (!array_key_exists($key, $result)) {
|
||||||
$result[$key] = [
|
$result[$key] = [
|
||||||
'total' => '0',
|
'total' => '0',
|
||||||
@ -395,14 +395,14 @@ class AccountController extends Controller
|
|||||||
$result[$key]['total'] = bcadd($journal['amount'], $result[$key]['total']);
|
$result[$key]['total'] = bcadd($journal['amount'], $result[$key]['total']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$names = $this->getCategoryNames(array_keys($result));
|
$names = $this->getCategoryNames(array_keys($result));
|
||||||
foreach ($result as $row) {
|
foreach ($result as $row) {
|
||||||
$categoryId = $row['category_id'];
|
$categoryId = $row['category_id'];
|
||||||
$name = $names[$categoryId] ?? '(unknown)';
|
$name = $names[$categoryId] ?? '(unknown)';
|
||||||
$label = (string) trans('firefly.name_in_currency', ['name' => $name, 'currency' => $row['currency_name']]);
|
$label = (string) trans('firefly.name_in_currency', ['name' => $name, 'currency' => $row['currency_name']]);
|
||||||
$chartData[$label] = ['amount' => $row['total'], 'currency_symbol' => $row['currency_symbol'], 'currency_code' => $row['currency_code']];
|
$chartData[$label] = ['amount' => $row['total'], 'currency_symbol' => $row['currency_symbol'], 'currency_code' => $row['currency_code']];
|
||||||
}
|
}
|
||||||
$data = $this->generator->multiCurrencyPieChart($chartData);
|
$data = $this->generator->multiCurrencyPieChart($chartData);
|
||||||
$cache->store($data);
|
$cache->store($data);
|
||||||
|
|
||||||
return response()->json($data);
|
return response()->json($data);
|
||||||
@ -418,22 +418,22 @@ class AccountController extends Controller
|
|||||||
$start->startOfDay();
|
$start->startOfDay();
|
||||||
$end->endOfDay();
|
$end->endOfDay();
|
||||||
Log::debug(sprintf('Now in period("%s", "%s")', $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s')));
|
Log::debug(sprintf('Now in period("%s", "%s")', $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s')));
|
||||||
$chartData = [];
|
$chartData = [];
|
||||||
$cache = new CacheProperties();
|
$cache = new CacheProperties();
|
||||||
$cache->addProperty('chart.account.period');
|
$cache->addProperty('chart.account.period');
|
||||||
$cache->addProperty($start);
|
$cache->addProperty($start);
|
||||||
$cache->addProperty($end);
|
$cache->addProperty($end);
|
||||||
$cache->addProperty($this->convertToNative);
|
$cache->addProperty($this->convertToNative);
|
||||||
$cache->addProperty($account->id);
|
$cache->addProperty($account->id);
|
||||||
if ($cache->has()) {
|
if ($cache->has()) {
|
||||||
//return response()->json($cache->get());
|
// return response()->json($cache->get());
|
||||||
}
|
}
|
||||||
|
|
||||||
// collect and filter balances for the entire period.
|
// collect and filter balances for the entire period.
|
||||||
$step = $this->calculateStep($start, $end);
|
$step = $this->calculateStep($start, $end);
|
||||||
Log::debug(sprintf('Step is %s', $step));
|
Log::debug(sprintf('Step is %s', $step));
|
||||||
$locale = app('steam')->getLocale();
|
$locale = app('steam')->getLocale();
|
||||||
$return = [];
|
$return = [];
|
||||||
|
|
||||||
// fix for issue https://github.com/firefly-iii/firefly-iii/issues/8041
|
// fix for issue https://github.com/firefly-iii/firefly-iii/issues/8041
|
||||||
// have to make sure this chart is always based on the balance at the END of the period.
|
// have to make sure this chart is always based on the balance at the END of the period.
|
||||||
@ -443,8 +443,8 @@ class AccountController extends Controller
|
|||||||
$format = (string) trans('config.month_and_day_js', [], $locale);
|
$format = (string) trans('config.month_and_day_js', [], $locale);
|
||||||
$accountCurrency = $this->accountRepository->getAccountCurrency($account);
|
$accountCurrency = $this->accountRepository->getAccountCurrency($account);
|
||||||
|
|
||||||
$range = Steam::finalAccountBalanceInRange($account, $start, $end, $this->convertToNative);
|
$range = Steam::finalAccountBalanceInRange($account, $start, $end, $this->convertToNative);
|
||||||
$range = Steam::filterAccountBalances($range, $account, $this->convertToNative, $accountCurrency);
|
$range = Steam::filterAccountBalances($range, $account, $this->convertToNative, $accountCurrency);
|
||||||
|
|
||||||
// temp, get end balance.
|
// temp, get end balance.
|
||||||
Log::debug('temp get end balance');
|
Log::debug('temp get end balance');
|
||||||
@ -455,14 +455,14 @@ class AccountController extends Controller
|
|||||||
$accountCurrency ??= $this->defaultCurrency; // do this AFTER getting the balances.
|
$accountCurrency ??= $this->defaultCurrency; // do this AFTER getting the balances.
|
||||||
Log::debug('Start chart loop.');
|
Log::debug('Start chart loop.');
|
||||||
|
|
||||||
$newRange = [];
|
$newRange = [];
|
||||||
$expectedIndex = 0;
|
$expectedIndex = 0;
|
||||||
Log::debug('Balances exist at:');
|
Log::debug('Balances exist at:');
|
||||||
foreach ($range as $key => $value) {
|
foreach ($range as $key => $value) {
|
||||||
$newRange[] = ['date' => $key, 'info' => $value];
|
$newRange[] = ['date' => $key, 'info' => $value];
|
||||||
Log::debug(sprintf('%d - %s (%s)', count($newRange) - 1, $key, json_encode($value)));
|
Log::debug(sprintf('%d - %s (%s)', count($newRange) - 1, $key, json_encode($value)));
|
||||||
}
|
}
|
||||||
$carbon = Carbon::createFromFormat('Y-m-d', $newRange[0]['date'])->endOfDay();
|
$carbon = Carbon::createFromFormat('Y-m-d', $newRange[0]['date'])->endOfDay();
|
||||||
Log::debug(sprintf('Start of loop, $carbon is %s', $carbon->format('Y-m-d H:i:s')));
|
Log::debug(sprintf('Start of loop, $carbon is %s', $carbon->format('Y-m-d H:i:s')));
|
||||||
while ($end->gte($current)) {
|
while ($end->gte($current)) {
|
||||||
$momentBalance = $previous;
|
$momentBalance = $previous;
|
||||||
@ -483,21 +483,21 @@ class AccountController extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Log::debug(sprintf('momentBalance is now %s', json_encode($momentBalance)));
|
Log::debug(sprintf('momentBalance is now %s', json_encode($momentBalance)));
|
||||||
$return = $this->updateChartKeys($return, $momentBalance);
|
$return = $this->updateChartKeys($return, $momentBalance);
|
||||||
$previous = $momentBalance;
|
$previous = $momentBalance;
|
||||||
|
|
||||||
// process each balance thing.
|
// process each balance thing.
|
||||||
foreach ($momentBalance as $key => $amount) {
|
foreach ($momentBalance as $key => $amount) {
|
||||||
$label = $current->isoFormat($format);
|
$label = $current->isoFormat($format);
|
||||||
$return[$key]['entries'][$label] = $amount;
|
$return[$key]['entries'][$label] = $amount;
|
||||||
}
|
}
|
||||||
$current = app('navigation')->addPeriod($current, $step, 0);
|
$current = app('navigation')->addPeriod($current, $step, 0);
|
||||||
// here too, to fix #8041, the data is corrected to the end of the period.
|
// here too, to fix #8041, the data is corrected to the end of the period.
|
||||||
$current = app('navigation')->endOfX($current, $step, null);
|
$current = app('navigation')->endOfX($current, $step, null);
|
||||||
}
|
}
|
||||||
Log::debug('End of chart loop.');
|
Log::debug('End of chart loop.');
|
||||||
// second loop (yes) to create nice array with info! Yay!
|
// second loop (yes) to create nice array with info! Yay!
|
||||||
$chartData = [];
|
$chartData = [];
|
||||||
|
|
||||||
foreach ($return as $key => $info) {
|
foreach ($return as $key => $info) {
|
||||||
if (3 === strlen($key)) {
|
if (3 === strlen($key)) {
|
||||||
@ -520,7 +520,7 @@ class AccountController extends Controller
|
|||||||
$chartData[] = $info;
|
$chartData[] = $info;
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = $this->generator->multiSet($chartData);
|
$data = $this->generator->multiSet($chartData);
|
||||||
$cache->store($data);
|
$cache->store($data);
|
||||||
|
|
||||||
return response()->json($data);
|
return response()->json($data);
|
||||||
@ -546,11 +546,11 @@ class AccountController extends Controller
|
|||||||
public function revenueAccounts(): JsonResponse
|
public function revenueAccounts(): JsonResponse
|
||||||
{
|
{
|
||||||
/** @var Carbon $start */
|
/** @var Carbon $start */
|
||||||
$start = clone session('start', today(config('app.timezone'))->startOfMonth());
|
$start = clone session('start', today(config('app.timezone'))->startOfMonth());
|
||||||
|
|
||||||
/** @var Carbon $end */
|
/** @var Carbon $end */
|
||||||
$end = clone session('end', today(config('app.timezone'))->endOfMonth());
|
$end = clone session('end', today(config('app.timezone'))->endOfMonth());
|
||||||
$cache = new CacheProperties();
|
$cache = new CacheProperties();
|
||||||
$cache->addProperty($start);
|
$cache->addProperty($start);
|
||||||
$cache->addProperty($end);
|
$cache->addProperty($end);
|
||||||
$cache->addProperty($this->convertToNative);
|
$cache->addProperty($this->convertToNative);
|
||||||
@ -561,13 +561,13 @@ class AccountController extends Controller
|
|||||||
$start->subDay();
|
$start->subDay();
|
||||||
|
|
||||||
// prep some vars:
|
// prep some vars:
|
||||||
$currencies = [];
|
$currencies = [];
|
||||||
$chartData = [];
|
$chartData = [];
|
||||||
$tempData = [];
|
$tempData = [];
|
||||||
|
|
||||||
// grab all accounts and names
|
// grab all accounts and names
|
||||||
$accounts = $this->accountRepository->getAccountsByType([AccountTypeEnum::REVENUE->value]);
|
$accounts = $this->accountRepository->getAccountsByType([AccountTypeEnum::REVENUE->value]);
|
||||||
$accountNames = $this->extractNames($accounts);
|
$accountNames = $this->extractNames($accounts);
|
||||||
|
|
||||||
// grab all balances
|
// grab all balances
|
||||||
$startBalances = app('steam')->finalAccountsBalance($accounts, $start);
|
$startBalances = app('steam')->finalAccountsBalance($accounts, $start);
|
||||||
@ -600,13 +600,13 @@ class AccountController extends Controller
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Log::debug(sprintf('Will process expense array "%s" with amount %s', $key, $endBalance));
|
// Log::debug(sprintf('Will process expense array "%s" with amount %s', $key, $endBalance));
|
||||||
$searchCode = $this->convertToNative ? $this->defaultCurrency->code : $key;
|
$searchCode = $this->convertToNative ? $this->defaultCurrency->code : $key;
|
||||||
// Log::debug(sprintf('Search code is %s', $searchCode));
|
// Log::debug(sprintf('Search code is %s', $searchCode));
|
||||||
// see if there is an accompanying start amount.
|
// see if there is an accompanying start amount.
|
||||||
// grab the difference and find the currency.
|
// grab the difference and find the currency.
|
||||||
$startBalance = ($startBalances[$account->id][$key] ?? '0');
|
$startBalance = ($startBalances[$account->id][$key] ?? '0');
|
||||||
// Log::debug(sprintf('Start balance is %s', $startBalance));
|
// Log::debug(sprintf('Start balance is %s', $startBalance));
|
||||||
$diff = bcsub($endBalance, $startBalance);
|
$diff = bcsub($endBalance, $startBalance);
|
||||||
$currencies[$searchCode] ??= $this->currencyRepository->findByCode($searchCode);
|
$currencies[$searchCode] ??= $this->currencyRepository->findByCode($searchCode);
|
||||||
if (0 !== bccomp($diff, '0')) {
|
if (0 !== bccomp($diff, '0')) {
|
||||||
// store the values in a temporary array.
|
// store the values in a temporary array.
|
||||||
@ -626,10 +626,10 @@ class AccountController extends Controller
|
|||||||
foreach ($currencies as $currency) {
|
foreach ($currencies as $currency) {
|
||||||
$newCurrencies[$currency->id] = $currency;
|
$newCurrencies[$currency->id] = $currency;
|
||||||
}
|
}
|
||||||
$currencies = $newCurrencies;
|
$currencies = $newCurrencies;
|
||||||
|
|
||||||
// sort temp array by amount.
|
// sort temp array by amount.
|
||||||
$amounts = array_column($tempData, 'diff_float');
|
$amounts = array_column($tempData, 'diff_float');
|
||||||
array_multisort($amounts, SORT_ASC, $tempData);
|
array_multisort($amounts, SORT_ASC, $tempData);
|
||||||
|
|
||||||
// loop all found currencies and build the data array for the chart.
|
// loop all found currencies and build the data array for the chart.
|
||||||
@ -640,12 +640,12 @@ class AccountController extends Controller
|
|||||||
foreach ($currencies as $currencyId => $currency) {
|
foreach ($currencies as $currencyId => $currency) {
|
||||||
$dataSet
|
$dataSet
|
||||||
= [
|
= [
|
||||||
'label' => (string) trans('firefly.earned'),
|
'label' => (string) trans('firefly.earned'),
|
||||||
'type' => 'bar',
|
'type' => 'bar',
|
||||||
'currency_symbol' => $currency->symbol,
|
'currency_symbol' => $currency->symbol,
|
||||||
'currency_code' => $currency->code,
|
'currency_code' => $currency->code,
|
||||||
'entries' => $this->expandNames($tempData),
|
'entries' => $this->expandNames($tempData),
|
||||||
];
|
];
|
||||||
$chartData[$currencyId] = $dataSet;
|
$chartData[$currencyId] = $dataSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -656,7 +656,7 @@ class AccountController extends Controller
|
|||||||
$chartData[$currencyId]['entries'][$name] = bcmul($entry['difference'], '-1');
|
$chartData[$currencyId]['entries'][$name] = bcmul($entry['difference'], '-1');
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = $this->generator->multiSet($chartData);
|
$data = $this->generator->multiSet($chartData);
|
||||||
$cache->store($data);
|
$cache->store($data);
|
||||||
|
|
||||||
return response()->json($data);
|
return response()->json($data);
|
||||||
|
@ -108,6 +108,6 @@ class ExchangeRateRepository implements ExchangeRateRepositoryInterface
|
|||||||
#[\Override]
|
#[\Override]
|
||||||
public function getAll(): Collection
|
public function getAll(): Collection
|
||||||
{
|
{
|
||||||
return $this->userGroup->currencyExchangeRates()->orderBy('date','ASC')->get();
|
return $this->userGroup->currencyExchangeRates()->orderBy('date', 'ASC')->get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -410,11 +410,11 @@ class Steam
|
|||||||
$defaultCurrency = app('amount')->getNativeCurrency();
|
$defaultCurrency = app('amount')->getNativeCurrency();
|
||||||
if ($convertToNative) {
|
if ($convertToNative) {
|
||||||
if ($defaultCurrency->id === $currency?->id) {
|
if ($defaultCurrency->id === $currency?->id) {
|
||||||
//Log::debug(sprintf('Unset "native_balance" and "%s" for account #%d', $defaultCurrency->code, $account->id));
|
// Log::debug(sprintf('Unset "native_balance" and "%s" for account #%d', $defaultCurrency->code, $account->id));
|
||||||
unset($set['native_balance'], $set[$defaultCurrency->code]);
|
unset($set['native_balance'], $set[$defaultCurrency->code]);
|
||||||
}
|
}
|
||||||
if (null !== $currency && $defaultCurrency->id !== $currency->id) {
|
if (null !== $currency && $defaultCurrency->id !== $currency->id) {
|
||||||
//Log::debug(sprintf('Unset balance for account #%d', $account->id));
|
// Log::debug(sprintf('Unset balance for account #%d', $account->id));
|
||||||
unset($set['balance']);
|
unset($set['balance']);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -426,13 +426,13 @@ class Steam
|
|||||||
|
|
||||||
if (!$convertToNative) {
|
if (!$convertToNative) {
|
||||||
if (null === $currency) {
|
if (null === $currency) {
|
||||||
//Log::debug(sprintf('Unset native_balance and make defaultCurrency balance the balance for account #%d', $account->id));
|
// Log::debug(sprintf('Unset native_balance and make defaultCurrency balance the balance for account #%d', $account->id));
|
||||||
$set['balance'] = $set[$defaultCurrency->code] ?? '0';
|
$set['balance'] = $set[$defaultCurrency->code] ?? '0';
|
||||||
unset($set['native_balance'], $set[$defaultCurrency->code]);
|
unset($set['native_balance'], $set[$defaultCurrency->code]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null !== $currency) {
|
if (null !== $currency) {
|
||||||
//Log::debug(sprintf('Unset native_balance + defaultCurrency + currencyCode balance for account #%d', $account->id));
|
// Log::debug(sprintf('Unset native_balance + defaultCurrency + currencyCode balance for account #%d', $account->id));
|
||||||
unset($set['native_balance'], $set[$defaultCurrency->code], $set[$currency->code]);
|
unset($set['native_balance'], $set[$defaultCurrency->code], $set[$currency->code]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ return [
|
|||||||
'running_balance_column' => env('USE_RUNNING_BALANCE', false),
|
'running_balance_column' => env('USE_RUNNING_BALANCE', false),
|
||||||
// see cer.php for exchange rates feature flag.
|
// see cer.php for exchange rates feature flag.
|
||||||
],
|
],
|
||||||
'version' => 'develop/2025-02-01',
|
'version' => 'develop/2025-02-02',
|
||||||
'api_version' => '2.1.0', // field is no longer used.
|
'api_version' => '2.1.0', // field is no longer used.
|
||||||
'db_version' => 25,
|
'db_version' => 25,
|
||||||
|
|
||||||
|
6
package-lock.json
generated
6
package-lock.json
generated
@ -7159,9 +7159,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/import-fresh": {
|
"node_modules/import-fresh": {
|
||||||
"version": "3.3.0",
|
"version": "3.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
|
||||||
"integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
|
"integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -20,12 +20,8 @@
|
|||||||
"/public/v1/js/app.js.LICENSE.txt": "/public/v1/js/app.js.LICENSE.txt",
|
"/public/v1/js/app.js.LICENSE.txt": "/public/v1/js/app.js.LICENSE.txt",
|
||||||
"/public/v1/js/app_vue.js": "/public/v1/js/app_vue.js",
|
"/public/v1/js/app_vue.js": "/public/v1/js/app_vue.js",
|
||||||
"/public/v1/js/app_vue.js.LICENSE.txt": "/public/v1/js/app_vue.js.LICENSE.txt",
|
"/public/v1/js/app_vue.js.LICENSE.txt": "/public/v1/js/app_vue.js.LICENSE.txt",
|
||||||
"/public/v1/js/create.js": "/public/v1/js/create.js",
|
|
||||||
"/public/v1/js/create.js.LICENSE.txt": "/public/v1/js/create.js.LICENSE.txt",
|
|
||||||
"/public/v1/js/create_transaction.js": "/public/v1/js/create_transaction.js",
|
"/public/v1/js/create_transaction.js": "/public/v1/js/create_transaction.js",
|
||||||
"/public/v1/js/create_transaction.js.LICENSE.txt": "/public/v1/js/create_transaction.js.LICENSE.txt",
|
"/public/v1/js/create_transaction.js.LICENSE.txt": "/public/v1/js/create_transaction.js.LICENSE.txt",
|
||||||
"/public/v1/js/edit.js": "/public/v1/js/edit.js",
|
|
||||||
"/public/v1/js/edit.js.LICENSE.txt": "/public/v1/js/edit.js.LICENSE.txt",
|
|
||||||
"/public/v1/js/edit_transaction.js": "/public/v1/js/edit_transaction.js",
|
"/public/v1/js/edit_transaction.js": "/public/v1/js/edit_transaction.js",
|
||||||
"/public/v1/js/edit_transaction.js.LICENSE.txt": "/public/v1/js/edit_transaction.js.LICENSE.txt",
|
"/public/v1/js/edit_transaction.js.LICENSE.txt": "/public/v1/js/edit_transaction.js.LICENSE.txt",
|
||||||
"/public/v1/js/exchange-rates/index.js": "/public/v1/js/exchange-rates/index.js",
|
"/public/v1/js/exchange-rates/index.js": "/public/v1/js/exchange-rates/index.js",
|
||||||
@ -100,8 +96,6 @@
|
|||||||
"/public/v1/js/ff/transactions/mass/edit-bulk.js": "/public/v1/js/ff/transactions/mass/edit-bulk.js",
|
"/public/v1/js/ff/transactions/mass/edit-bulk.js": "/public/v1/js/ff/transactions/mass/edit-bulk.js",
|
||||||
"/public/v1/js/ff/transactions/mass/edit.js": "/public/v1/js/ff/transactions/mass/edit.js",
|
"/public/v1/js/ff/transactions/mass/edit.js": "/public/v1/js/ff/transactions/mass/edit.js",
|
||||||
"/public/v1/js/ff/transactions/show.js": "/public/v1/js/ff/transactions/show.js",
|
"/public/v1/js/ff/transactions/show.js": "/public/v1/js/ff/transactions/show.js",
|
||||||
"/public/v1/js/index.js": "/public/v1/js/index.js",
|
|
||||||
"/public/v1/js/index.js.LICENSE.txt": "/public/v1/js/index.js.LICENSE.txt",
|
|
||||||
"/public/v1/js/lib/Chart.bundle.min.js": "/public/v1/js/lib/Chart.bundle.min.js",
|
"/public/v1/js/lib/Chart.bundle.min.js": "/public/v1/js/lib/Chart.bundle.min.js",
|
||||||
"/public/v1/js/lib/accounting.min.js": "/public/v1/js/lib/accounting.min.js",
|
"/public/v1/js/lib/accounting.min.js": "/public/v1/js/lib/accounting.min.js",
|
||||||
"/public/v1/js/lib/bootstrap-multiselect.js": "/public/v1/js/lib/bootstrap-multiselect.js",
|
"/public/v1/js/lib/bootstrap-multiselect.js": "/public/v1/js/lib/bootstrap-multiselect.js",
|
||||||
@ -160,8 +154,6 @@
|
|||||||
"/public/v1/js/lib/vue.js": "/public/v1/js/lib/vue.js",
|
"/public/v1/js/lib/vue.js": "/public/v1/js/lib/vue.js",
|
||||||
"/public/v1/js/profile.js": "/public/v1/js/profile.js",
|
"/public/v1/js/profile.js": "/public/v1/js/profile.js",
|
||||||
"/public/v1/js/profile.js.LICENSE.txt": "/public/v1/js/profile.js.LICENSE.txt",
|
"/public/v1/js/profile.js.LICENSE.txt": "/public/v1/js/profile.js.LICENSE.txt",
|
||||||
"/public/v1/js/show.js": "/public/v1/js/show.js",
|
|
||||||
"/public/v1/js/show.js.LICENSE.txt": "/public/v1/js/show.js.LICENSE.txt",
|
|
||||||
"/public/v1/js/webhooks/create.js": "/public/v1/js/webhooks/create.js",
|
"/public/v1/js/webhooks/create.js": "/public/v1/js/webhooks/create.js",
|
||||||
"/public/v1/js/webhooks/create.js.LICENSE.txt": "/public/v1/js/webhooks/create.js.LICENSE.txt",
|
"/public/v1/js/webhooks/create.js.LICENSE.txt": "/public/v1/js/webhooks/create.js.LICENSE.txt",
|
||||||
"/public/v1/js/webhooks/edit.js": "/public/v1/js/webhooks/edit.js",
|
"/public/v1/js/webhooks/edit.js": "/public/v1/js/webhooks/edit.js",
|
||||||
|
@ -138,7 +138,7 @@
|
|||||||
"visit_webhook_url": "Webhook-URL besuchen",
|
"visit_webhook_url": "Webhook-URL besuchen",
|
||||||
"reset_webhook_secret": "Webhook Secret zur\u00fccksetzen",
|
"reset_webhook_secret": "Webhook Secret zur\u00fccksetzen",
|
||||||
"header_exchange_rates": "Wechselkurse",
|
"header_exchange_rates": "Wechselkurse",
|
||||||
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/explanation\/financial-concepts\/exchange-rates\/\">the documentation<\/a>.",
|
"exchange_rates_intro": "Firefly III unterst\u00fctzt das Herunterladen und Verwenden von Wechselkursen. Lesen Sie mehr dar\u00fcber in <a href=\"https:\/\/docs.firefly-iii.org\/explanation\/financial-concepts\/exchange-rates\/\"> der Dokumentation<\/a>.",
|
||||||
"exchange_rates_from_to": "Zwischen {from} und {to} (und umgekehrt)",
|
"exchange_rates_from_to": "Zwischen {from} und {to} (und umgekehrt)",
|
||||||
"exchange_rates_intro_rates": "Firefly III verwendet die folgenden Wechselkurse. Der Kehrwert wird automatisch berechnet, wenn er nicht angegeben wurde. Wenn f\u00fcr das Datum der Transaktion kein Wechselkurs vorhanden ist, sucht Firefly III in der Vergangenheit nach einem Kurs. Wenn keine vorhanden sind, wird der Kurs \u201e1\u201c verwendet.",
|
"exchange_rates_intro_rates": "Firefly III verwendet die folgenden Wechselkurse. Der Kehrwert wird automatisch berechnet, wenn er nicht angegeben wurde. Wenn f\u00fcr das Datum der Transaktion kein Wechselkurs vorhanden ist, sucht Firefly III in der Vergangenheit nach einem Kurs. Wenn keine vorhanden sind, wird der Kurs \u201e1\u201c verwendet.",
|
||||||
"header_exchange_rates_rates": "Wechselkurse",
|
"header_exchange_rates_rates": "Wechselkurse",
|
||||||
|
@ -138,7 +138,7 @@
|
|||||||
"visit_webhook_url": "Visiter l'URL du webhook",
|
"visit_webhook_url": "Visiter l'URL du webhook",
|
||||||
"reset_webhook_secret": "R\u00e9initialiser le secret du webhook",
|
"reset_webhook_secret": "R\u00e9initialiser le secret du webhook",
|
||||||
"header_exchange_rates": "Taux de change",
|
"header_exchange_rates": "Taux de change",
|
||||||
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/explanation\/financial-concepts\/exchange-rates\/\">the documentation<\/a>.",
|
"exchange_rates_intro": "Firefly III prend en charge le chargement et l'utilisation des taux de change. En savoir plus \u00e0 ce sujet dans <a href=\"https:\/\/docs.firefly-iii.org\/explanation\/financial-concepts\/exchange-rates\/\">la documentation<\/a>.",
|
||||||
"exchange_rates_from_to": "Entre {from} et {to} (et l'inverse)",
|
"exchange_rates_from_to": "Entre {from} et {to} (et l'inverse)",
|
||||||
"exchange_rates_intro_rates": "Firefly III utilise les taux de change suivants. L'inverse est calcul\u00e9 automatiquement lorsqu'il n'est pas fourni. Si aucun taux de change n'existe pour la date de la transaction, Firefly III reviendra dans le temps pour en trouver un. Si aucun n'est pr\u00e9sent, le taux \"1\" sera utilis\u00e9.",
|
"exchange_rates_intro_rates": "Firefly III utilise les taux de change suivants. L'inverse est calcul\u00e9 automatiquement lorsqu'il n'est pas fourni. Si aucun taux de change n'existe pour la date de la transaction, Firefly III reviendra dans le temps pour en trouver un. Si aucun n'est pr\u00e9sent, le taux \"1\" sera utilis\u00e9.",
|
||||||
"header_exchange_rates_rates": "Taux de change",
|
"header_exchange_rates_rates": "Taux de change",
|
||||||
|
Loading…
Reference in New Issue
Block a user