mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-10-22 20:16:22 +00:00
Auto commit for release 'develop' on 2024-12-30
This commit is contained in:
@@ -99,7 +99,7 @@ class AccountController extends Controller
|
||||
);
|
||||
}
|
||||
|
||||
$return[] = [
|
||||
$return[] = [
|
||||
'id' => (string) $account->id,
|
||||
'name' => $account->name,
|
||||
'name_with_balance' => $nameWithBalance,
|
||||
|
@@ -72,19 +72,19 @@ class AccountController extends Controller
|
||||
public function overview(DateRequest $request): JsonResponse
|
||||
{
|
||||
// parameters for chart:
|
||||
$dates = $request->getAll();
|
||||
$dates = $request->getAll();
|
||||
|
||||
/** @var Carbon $start */
|
||||
$start = $dates['start'];
|
||||
$start = $dates['start'];
|
||||
|
||||
/** @var Carbon $end */
|
||||
$end = $dates['end'];
|
||||
$end = $dates['end'];
|
||||
|
||||
// user's preferences
|
||||
$defaultSet = $this->repository->getAccountsByType([AccountTypeEnum::ASSET->value])->pluck('id')->toArray();
|
||||
|
||||
/** @var Preference $frontpage */
|
||||
$frontpage = app('preferences')->get('frontpageAccounts', $defaultSet);
|
||||
$frontpage = app('preferences')->get('frontpageAccounts', $defaultSet);
|
||||
|
||||
if (!(is_array($frontpage->data) && count($frontpage->data) > 0)) {
|
||||
$frontpage->data = $defaultSet;
|
||||
@@ -92,14 +92,14 @@ class AccountController extends Controller
|
||||
}
|
||||
|
||||
// get accounts:
|
||||
$accounts = $this->repository->getAccountsById($frontpage->data);
|
||||
$chartData = [];
|
||||
$accounts = $this->repository->getAccountsById($frontpage->data);
|
||||
$chartData = [];
|
||||
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
$currency = $this->repository->getAccountCurrency($account) ?? $this->defaultCurrency;
|
||||
$field = $this->convertToNative && $currency->id !== $this->defaultCurrency->id ? 'native_balance' : 'balance';
|
||||
$currentSet = [
|
||||
$currency = $this->repository->getAccountCurrency($account) ?? $this->defaultCurrency;
|
||||
$field = $this->convertToNative && $currency->id !== $this->defaultCurrency->id ? 'native_balance' : 'balance';
|
||||
$currentSet = [
|
||||
'label' => $account->name,
|
||||
'currency_id' => (string) $currency->id,
|
||||
'currency_code' => $currency->code,
|
||||
@@ -116,14 +116,14 @@ class AccountController extends Controller
|
||||
$range = app('steam')->finalAccountBalanceInRange($account, $start, clone $end, $this->convertToNative);
|
||||
$previous = array_values($range)[0][$field];
|
||||
while ($currentStart <= $end) {
|
||||
$format = $currentStart->format('Y-m-d');
|
||||
$label = $currentStart->toAtomString();
|
||||
$balance = array_key_exists($format, $range) ? $range[$format][$field] : $previous;
|
||||
$previous = $balance;
|
||||
$format = $currentStart->format('Y-m-d');
|
||||
$label = $currentStart->toAtomString();
|
||||
$balance = array_key_exists($format, $range) ? $range[$format][$field] : $previous;
|
||||
$previous = $balance;
|
||||
$currentStart->addDay();
|
||||
$currentSet['entries'][$label] = $balance;
|
||||
}
|
||||
$chartData[] = $currentSet;
|
||||
$chartData[] = $currentSet;
|
||||
}
|
||||
|
||||
return response()->json($chartData);
|
||||
|
@@ -94,8 +94,8 @@ abstract class Controller extends BaseController
|
||||
if ($page < 1) {
|
||||
$page = 1;
|
||||
}
|
||||
if ($page > pow(2,16)) {
|
||||
$page = pow(2, 16);
|
||||
if ($page > 2 ** 16) {
|
||||
$page = 2 ** 16;
|
||||
}
|
||||
$bag->set('page', $page);
|
||||
|
||||
|
@@ -63,8 +63,8 @@ class DestroyController extends Controller
|
||||
*/
|
||||
public function destroy(DestroyRequest $request): JsonResponse
|
||||
{
|
||||
$objects = $request->getObjects();
|
||||
$this->unused = $request->boolean('unused', false);
|
||||
$objects = $request->getObjects();
|
||||
$this->unused = $request->boolean('unused', false);
|
||||
|
||||
$allExceptAssets = [AccountTypeEnum::BENEFICIARY->value, AccountTypeEnum::CASH->value, AccountTypeEnum::CREDITCARD->value, AccountTypeEnum::DEFAULT->value, AccountTypeEnum::EXPENSE->value, AccountTypeEnum::IMPORT->value, AccountTypeEnum::INITIAL_BALANCE->value, AccountTypeEnum::LIABILITY_CREDIT->value, AccountTypeEnum::RECONCILIATION->value, AccountTypeEnum::REVENUE->value];
|
||||
$all = [AccountTypeEnum::ASSET->value, AccountTypeEnum::BENEFICIARY->value, AccountTypeEnum::CASH->value, AccountTypeEnum::CREDITCARD->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::DEFAULT->value, AccountTypeEnum::EXPENSE->value, AccountTypeEnum::IMPORT->value, AccountTypeEnum::INITIAL_BALANCE->value, AccountTypeEnum::LIABILITY_CREDIT->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::RECONCILIATION->value];
|
||||
@@ -101,11 +101,11 @@ class DestroyController extends Controller
|
||||
private function destroyBudgets(): void
|
||||
{
|
||||
/** @var AvailableBudgetRepositoryInterface $abRepository */
|
||||
$abRepository = app(AvailableBudgetRepositoryInterface::class);
|
||||
$abRepository = app(AvailableBudgetRepositoryInterface::class);
|
||||
$abRepository->destroyAll();
|
||||
|
||||
/** @var BudgetLimitRepositoryInterface $blRepository */
|
||||
$blRepository = app(BudgetLimitRepositoryInterface::class);
|
||||
$blRepository = app(BudgetLimitRepositoryInterface::class);
|
||||
$blRepository->destroyAll();
|
||||
|
||||
/** @var BudgetRepositoryInterface $budgetRepository */
|
||||
|
@@ -79,11 +79,11 @@ class BillController extends Controller
|
||||
}
|
||||
|
||||
// collect all expenses in this period (regardless of type) by the given bills and accounts.
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value])->setRange($start, $end)->setSourceAccounts($accounts);
|
||||
$collector->setBills($bills);
|
||||
|
||||
$genericSet = $collector->getExtractedJournals();
|
||||
$genericSet = $collector->getExtractedJournals();
|
||||
foreach ($genericSet as $journal) {
|
||||
$billId = (int) $journal['bill_id'];
|
||||
$currencyId = (int) $journal['currency_id'];
|
||||
@@ -102,10 +102,10 @@ class BillController extends Controller
|
||||
}
|
||||
Log::debug(sprintf('Journal #%d in bill #%d will use %s (%s %s)', $journal['transaction_group_id'], $billId, $field, $currencyCode, $journal[$field] ?? '0'));
|
||||
|
||||
$key = sprintf('%d-%d', $billId, $currencyId);
|
||||
$key = sprintf('%d-%d', $billId, $currencyId);
|
||||
|
||||
if (0 !== $currencyId) {
|
||||
$response[$key] ??= [
|
||||
$response[$key] ??= [
|
||||
'id' => (string) $billId,
|
||||
'name' => $journal['bill_name'],
|
||||
'difference' => '0',
|
||||
@@ -137,11 +137,11 @@ class BillController extends Controller
|
||||
$response = [];
|
||||
|
||||
// collect all expenses in this period (regardless of type) by the given bills and accounts.
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value])->setRange($start, $end)->setSourceAccounts($accounts);
|
||||
$collector->withoutBill();
|
||||
|
||||
$genericSet = $collector->getExtractedJournals();
|
||||
$genericSet = $collector->getExtractedJournals();
|
||||
|
||||
foreach ($genericSet as $journal) {
|
||||
$currencyId = (int) $journal['currency_id'];
|
||||
@@ -161,7 +161,7 @@ class BillController extends Controller
|
||||
Log::debug(sprintf('Journal #%d will use %s (%s %s)', $journal['transaction_group_id'], $field, $currencyCode, $journal[$field] ?? '0'));
|
||||
|
||||
if (0 !== $currencyId) {
|
||||
$response[$currencyId] ??= [
|
||||
$response[$currencyId] ??= [
|
||||
'difference' => '0',
|
||||
'difference_float' => 0,
|
||||
'currency_id' => (string) $currencyId,
|
||||
|
@@ -51,14 +51,14 @@ class PeriodController extends Controller
|
||||
$default = Amount::getDefaultCurrency();
|
||||
|
||||
// collect all expenses in this period (regardless of type)
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value])->setRange($start, $end)->setSourceAccounts($accounts);
|
||||
$genericSet = $collector->getExtractedJournals();
|
||||
$genericSet = $collector->getExtractedJournals();
|
||||
foreach ($genericSet as $journal) {
|
||||
// same code as many other sumExpense methods. I think this needs some kind of generic method.
|
||||
$amount = '0';
|
||||
$currencyId = (int) $journal['currency_id'];
|
||||
$currencyCode = $journal['currency_code'];
|
||||
$amount = '0';
|
||||
$currencyId = (int) $journal['currency_id'];
|
||||
$currencyCode = $journal['currency_code'];
|
||||
if ($convertToNative) {
|
||||
$amount = Amount::getAmountFromJournal($journal);
|
||||
if ($default->id !== (int) $journal['currency_id'] && $default->id !== (int) $journal['foreign_currency_id']) {
|
||||
@@ -78,7 +78,7 @@ class PeriodController extends Controller
|
||||
}
|
||||
|
||||
|
||||
$response[$currencyId] ??= [
|
||||
$response[$currencyId] ??= [
|
||||
'difference' => '0',
|
||||
'difference_float' => 0,
|
||||
'currency_id' => (string) $currencyId,
|
||||
|
@@ -72,17 +72,17 @@ class TagController extends Controller
|
||||
$default = Amount::getDefaultCurrency();
|
||||
|
||||
// collect all expenses in this period (regardless of type) by the given bills and accounts.
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value])->setRange($start, $end)->setSourceAccounts($accounts);
|
||||
$collector->withoutTags();
|
||||
|
||||
$genericSet = $collector->getExtractedJournals();
|
||||
$genericSet = $collector->getExtractedJournals();
|
||||
|
||||
foreach ($genericSet as $journal) {
|
||||
// same code as many other sumExpense methods. I think this needs some kind of generic method.
|
||||
$amount = '0';
|
||||
$currencyId = (int) $journal['currency_id'];
|
||||
$currencyCode = $journal['currency_code'];
|
||||
$amount = '0';
|
||||
$currencyId = (int) $journal['currency_id'];
|
||||
$currencyCode = $journal['currency_code'];
|
||||
if ($convertToNative) {
|
||||
$amount = Amount::getAmountFromJournal($journal);
|
||||
if ($default->id !== (int) $journal['currency_id'] && $default->id !== (int) $journal['foreign_currency_id']) {
|
||||
@@ -101,7 +101,7 @@ class TagController extends Controller
|
||||
$amount = $journal['amount'];
|
||||
}
|
||||
|
||||
$response[$currencyId] ??= [
|
||||
$response[$currencyId] ??= [
|
||||
'difference' => '0',
|
||||
'difference_float' => 0,
|
||||
'currency_id' => (string) $currencyId,
|
||||
@@ -122,11 +122,11 @@ class TagController extends Controller
|
||||
*/
|
||||
public function tag(GenericRequest $request): JsonResponse
|
||||
{
|
||||
$accounts = $request->getAssetAccounts();
|
||||
$tags = $request->getTags();
|
||||
$start = $request->getStart();
|
||||
$end = $request->getEnd();
|
||||
$response = [];
|
||||
$accounts = $request->getAssetAccounts();
|
||||
$tags = $request->getTags();
|
||||
$start = $request->getStart();
|
||||
$end = $request->getEnd();
|
||||
$response = [];
|
||||
|
||||
// get all tags:
|
||||
if (0 === $tags->count()) {
|
||||
@@ -134,7 +134,7 @@ class TagController extends Controller
|
||||
}
|
||||
|
||||
// collect all expenses in this period (regardless of type) by the given bills and accounts.
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value])->setRange($start, $end)->setSourceAccounts($accounts);
|
||||
$collector->setTags($tags);
|
||||
$genericSet = $collector->getExtractedJournals();
|
||||
@@ -152,7 +152,7 @@ class TagController extends Controller
|
||||
|
||||
// on currency ID
|
||||
if (0 !== $currencyId) {
|
||||
$response[$key] ??= [
|
||||
$response[$key] ??= [
|
||||
'id' => (string) $tagId,
|
||||
'name' => $tag['name'],
|
||||
'difference' => '0',
|
||||
|
@@ -50,14 +50,14 @@ class PeriodController extends Controller
|
||||
$default = Amount::getDefaultCurrency();
|
||||
|
||||
// collect all expenses in this period (regardless of type)
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setTypes([TransactionTypeEnum::DEPOSIT->value])->setRange($start, $end)->setDestinationAccounts($accounts);
|
||||
$genericSet = $collector->getExtractedJournals();
|
||||
$genericSet = $collector->getExtractedJournals();
|
||||
foreach ($genericSet as $journal) {
|
||||
// currency
|
||||
$currencyId = $journal['currency_id'];
|
||||
$currencyCode = $journal['currency_code'];
|
||||
$field = $convertToNative && $currencyId !== $default->id ? 'native_amount' : 'amount';
|
||||
$currencyId = $journal['currency_id'];
|
||||
$currencyCode = $journal['currency_code'];
|
||||
$field = $convertToNative && $currencyId !== $default->id ? 'native_amount' : 'amount';
|
||||
|
||||
// perhaps use default currency instead?
|
||||
if ($convertToNative && $journal['currency_id'] !== $default->id) {
|
||||
@@ -69,7 +69,7 @@ class PeriodController extends Controller
|
||||
$field = 'foreign_amount';
|
||||
}
|
||||
|
||||
$response[$currencyId] ??= [
|
||||
$response[$currencyId] ??= [
|
||||
'difference' => '0',
|
||||
'difference_float' => 0,
|
||||
'currency_id' => (string) $currencyId,
|
||||
|
@@ -64,25 +64,25 @@ class TagController extends Controller
|
||||
*/
|
||||
public function noTag(GenericRequest $request): JsonResponse
|
||||
{
|
||||
$accounts = $request->getAssetAccounts();
|
||||
$start = $request->getStart();
|
||||
$end = $request->getEnd();
|
||||
$response = [];
|
||||
$accounts = $request->getAssetAccounts();
|
||||
$start = $request->getStart();
|
||||
$end = $request->getEnd();
|
||||
$response = [];
|
||||
$convertToNative = Amount::convertToNative();
|
||||
$default = Amount::getDefaultCurrency();
|
||||
|
||||
// collect all expenses in this period (regardless of type) by the given bills and accounts.
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setTypes([TransactionTypeEnum::DEPOSIT->value])->setRange($start, $end)->setDestinationAccounts($accounts);
|
||||
$collector->withoutTags();
|
||||
|
||||
$genericSet = $collector->getExtractedJournals();
|
||||
$genericSet = $collector->getExtractedJournals();
|
||||
|
||||
foreach ($genericSet as $journal) {
|
||||
// currency
|
||||
$currencyId = $journal['currency_id'];
|
||||
$currencyCode = $journal['currency_code'];
|
||||
$field = $convertToNative && $currencyId !== $default->id ? 'native_amount' : 'amount';
|
||||
$currencyId = $journal['currency_id'];
|
||||
$currencyCode = $journal['currency_code'];
|
||||
$field = $convertToNative && $currencyId !== $default->id ? 'native_amount' : 'amount';
|
||||
|
||||
// perhaps use default currency instead?
|
||||
if ($convertToNative && $journal['currency_id'] !== $default->id) {
|
||||
@@ -95,13 +95,13 @@ class TagController extends Controller
|
||||
}
|
||||
|
||||
$response[$currencyId] ??= [
|
||||
'difference' => '0',
|
||||
'difference_float' => 0,
|
||||
'currency_id' => (string) $currencyId,
|
||||
'currency_code' => $currencyCode,
|
||||
];
|
||||
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal[$field]));
|
||||
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
|
||||
'difference' => '0',
|
||||
'difference_float' => 0,
|
||||
'currency_id' => (string) $currencyId,
|
||||
'currency_code' => $currencyCode,
|
||||
];
|
||||
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal[$field]));
|
||||
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
|
||||
|
||||
}
|
||||
|
||||
|
@@ -42,22 +42,22 @@ class PeriodController extends Controller
|
||||
*/
|
||||
public function total(GenericRequest $request): JsonResponse
|
||||
{
|
||||
$accounts = $request->getAssetAccounts();
|
||||
$start = $request->getStart();
|
||||
$end = $request->getEnd();
|
||||
$response = [];
|
||||
$accounts = $request->getAssetAccounts();
|
||||
$start = $request->getStart();
|
||||
$end = $request->getEnd();
|
||||
$response = [];
|
||||
$convertToNative = Amount::convertToNative();
|
||||
$default = Amount::getDefaultCurrency();
|
||||
|
||||
// collect all expenses in this period (regardless of type)
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setTypes([TransactionType::TRANSFER])->setRange($start, $end)->setDestinationAccounts($accounts);
|
||||
$genericSet = $collector->getExtractedJournals();
|
||||
$genericSet = $collector->getExtractedJournals();
|
||||
foreach ($genericSet as $journal) {
|
||||
// currency
|
||||
$currencyId = $journal['currency_id'];
|
||||
$currencyCode = $journal['currency_code'];
|
||||
$field = $convertToNative && $currencyId !== $default->id ? 'native_amount' : 'amount';
|
||||
$currencyId = $journal['currency_id'];
|
||||
$currencyCode = $journal['currency_code'];
|
||||
$field = $convertToNative && $currencyId !== $default->id ? 'native_amount' : 'amount';
|
||||
|
||||
// perhaps use default currency instead?
|
||||
if ($convertToNative && $journal['currency_id'] !== $default->id) {
|
||||
@@ -69,14 +69,14 @@ class PeriodController extends Controller
|
||||
$field = 'foreign_amount';
|
||||
}
|
||||
|
||||
$response[$currencyId] ??= [
|
||||
'difference' => '0',
|
||||
'difference_float' => 0,
|
||||
'currency_id' => (string) $currencyId,
|
||||
'currency_code' => $currencyCode,
|
||||
];
|
||||
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal[$field]));
|
||||
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
|
||||
$response[$currencyId] ??= [
|
||||
'difference' => '0',
|
||||
'difference_float' => 0,
|
||||
'currency_id' => (string) $currencyId,
|
||||
'currency_code' => $currencyCode,
|
||||
];
|
||||
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal[$field]));
|
||||
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
|
||||
|
||||
}
|
||||
|
||||
|
@@ -71,17 +71,17 @@ class TagController extends Controller
|
||||
|
||||
|
||||
// collect all expenses in this period (regardless of type) by the given bills and accounts.
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setTypes([TransactionType::TRANSFER])->setRange($start, $end)->setDestinationAccounts($accounts);
|
||||
$collector->withoutTags();
|
||||
|
||||
$genericSet = $collector->getExtractedJournals();
|
||||
$genericSet = $collector->getExtractedJournals();
|
||||
|
||||
foreach ($genericSet as $journal) {
|
||||
// currency
|
||||
$currencyId = $journal['currency_id'];
|
||||
$currencyCode = $journal['currency_code'];
|
||||
$field = $convertToNative && $currencyId !== $default->id ? 'native_amount' : 'amount';
|
||||
$currencyId = $journal['currency_id'];
|
||||
$currencyCode = $journal['currency_code'];
|
||||
$field = $convertToNative && $currencyId !== $default->id ? 'native_amount' : 'amount';
|
||||
|
||||
// perhaps use default currency instead?
|
||||
if ($convertToNative && $journal['currency_id'] !== $default->id) {
|
||||
@@ -93,7 +93,7 @@ class TagController extends Controller
|
||||
$field = 'foreign_amount';
|
||||
}
|
||||
|
||||
$response[$currencyId] ??= [
|
||||
$response[$currencyId] ??= [
|
||||
'difference' => '0',
|
||||
'difference_float' => 0,
|
||||
'currency_id' => (string) $currencyId,
|
||||
@@ -115,11 +115,11 @@ class TagController extends Controller
|
||||
*/
|
||||
public function tag(GenericRequest $request): JsonResponse
|
||||
{
|
||||
$accounts = $request->getAssetAccounts();
|
||||
$tags = $request->getTags();
|
||||
$start = $request->getStart();
|
||||
$end = $request->getEnd();
|
||||
$response = [];
|
||||
$accounts = $request->getAssetAccounts();
|
||||
$tags = $request->getTags();
|
||||
$start = $request->getStart();
|
||||
$end = $request->getEnd();
|
||||
$response = [];
|
||||
|
||||
// get all tags:
|
||||
if (0 === $tags->count()) {
|
||||
@@ -127,7 +127,7 @@ class TagController extends Controller
|
||||
}
|
||||
|
||||
// collect all expenses in this period (regardless of type) by the given bills and accounts.
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setTypes([TransactionType::TRANSFER])->setRange($start, $end)->setDestinationAccounts($accounts);
|
||||
$collector->setTags($tags);
|
||||
$genericSet = $collector->getExtractedJournals();
|
||||
@@ -145,7 +145,7 @@ class TagController extends Controller
|
||||
|
||||
// on currency ID
|
||||
if (0 !== $currencyId) {
|
||||
$response[$key] ??= [
|
||||
$response[$key] ??= [
|
||||
'id' => (string) $tagId,
|
||||
'name' => $tag['name'],
|
||||
'difference' => '0',
|
||||
|
@@ -105,18 +105,18 @@ class ShowController extends Controller
|
||||
public function show(TransactionCurrency $currency): JsonResponse
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
$manager = $this->getManager();
|
||||
$user = auth()->user();
|
||||
$manager = $this->getManager();
|
||||
$this->parameters->set('defaultCurrency', $this->defaultCurrency);
|
||||
|
||||
// update fields with user info.
|
||||
$currency->refreshForUser($user);
|
||||
|
||||
/** @var CurrencyTransformer $transformer */
|
||||
$transformer = app(CurrencyTransformer::class);
|
||||
$transformer = app(CurrencyTransformer::class);
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
||||
$resource = new Item($currency, $transformer, 'currencies');
|
||||
$resource = new Item($currency, $transformer, 'currencies');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||
}
|
||||
|
@@ -93,8 +93,8 @@ class Controller extends BaseController
|
||||
if ($page < 1) {
|
||||
$page = 1;
|
||||
}
|
||||
if ($page > pow(2,16)) {
|
||||
$page = pow(2, 16);
|
||||
if ($page > 2 ** 16) {
|
||||
$page = 2 ** 16;
|
||||
}
|
||||
$bag->set('page', $page);
|
||||
|
||||
|
@@ -43,11 +43,11 @@ class PiggyBankFactory
|
||||
|
||||
public User $user {
|
||||
set(User $value) {
|
||||
$this->user = $value;
|
||||
$this->currencyRepository->setUser($value);
|
||||
$this->accountRepository->setUser($value);
|
||||
$this->piggyBankRepository->setUser($value);
|
||||
}
|
||||
$this->user = $value;
|
||||
$this->currencyRepository->setUser($value);
|
||||
$this->accountRepository->setUser($value);
|
||||
$this->piggyBankRepository->setUser($value);
|
||||
}
|
||||
}
|
||||
private AccountRepositoryInterface $accountRepository;
|
||||
private CurrencyRepositoryInterface $currencyRepository;
|
||||
@@ -62,15 +62,11 @@ class PiggyBankFactory
|
||||
|
||||
/**
|
||||
* Store a piggy bank or come back with an exception.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return PiggyBank
|
||||
*/
|
||||
public function store(array $data): PiggyBank
|
||||
{
|
||||
|
||||
$piggyBankData = $data;
|
||||
$piggyBankData = $data;
|
||||
|
||||
// unset some fields
|
||||
unset($piggyBankData['object_group_title'], $piggyBankData['transaction_currency_code'], $piggyBankData['transaction_currency_id'], $piggyBankData['accounts'], $piggyBankData['object_group_id'], $piggyBankData['notes']);
|
||||
@@ -94,11 +90,11 @@ class PiggyBankFactory
|
||||
|
||||
throw new FireflyException('400005: Could not store new piggy bank.', 0, $e);
|
||||
}
|
||||
$piggyBank = $this->setOrder($piggyBank, $data);
|
||||
$piggyBank = $this->setOrder($piggyBank, $data);
|
||||
$this->linkToAccountIds($piggyBank, $data['accounts']);
|
||||
$this->piggyBankRepository->updateNote($piggyBank, $data['notes']);
|
||||
|
||||
$objectGroupTitle = $data['object_group_title'] ?? '';
|
||||
$objectGroupTitle = $data['object_group_title'] ?? '';
|
||||
if ('' !== $objectGroupTitle) {
|
||||
$objectGroup = $this->findOrCreateObjectGroup($objectGroupTitle);
|
||||
if (null !== $objectGroup) {
|
||||
@@ -106,7 +102,7 @@ class PiggyBankFactory
|
||||
}
|
||||
}
|
||||
// try also with ID
|
||||
$objectGroupId = (int) ($data['object_group_id'] ?? 0);
|
||||
$objectGroupId = (int) ($data['object_group_id'] ?? 0);
|
||||
if (0 !== $objectGroupId) {
|
||||
$objectGroup = $this->findObjectGroupById($objectGroupId);
|
||||
if (null !== $objectGroup) {
|
||||
@@ -114,9 +110,10 @@ class PiggyBankFactory
|
||||
}
|
||||
}
|
||||
Log::debug('Touch piggy bank');
|
||||
$piggyBank->encrypted = false;
|
||||
$piggyBank->encrypted = false;
|
||||
$piggyBank->save();
|
||||
$piggyBank->touch();
|
||||
|
||||
return $piggyBank;
|
||||
}
|
||||
|
||||
@@ -132,6 +129,7 @@ class PiggyBankFactory
|
||||
$currency = $this->currencyRepository->find((int) ($data['transaction_currency_id'] ?? 0));
|
||||
}
|
||||
$currency ??= $defaultCurrency;
|
||||
|
||||
return $currency;
|
||||
}
|
||||
|
||||
@@ -144,12 +142,12 @@ class PiggyBankFactory
|
||||
}
|
||||
// first find by ID:
|
||||
if ($piggyBankId > 0) {
|
||||
$piggyBank = PiggyBank
|
||||
::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id')
|
||||
$piggyBank = PiggyBank::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id')
|
||||
->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id')
|
||||
->where('accounts.user_id', $this->user->id)
|
||||
->where('piggy_banks.id', $piggyBankId)
|
||||
->first(['piggy_banks.*']);
|
||||
->first(['piggy_banks.*'])
|
||||
;
|
||||
if (null !== $piggyBank) {
|
||||
return $piggyBank;
|
||||
}
|
||||
@@ -169,23 +167,24 @@ class PiggyBankFactory
|
||||
|
||||
public function findByName(string $name): ?PiggyBank
|
||||
{
|
||||
return PiggyBank
|
||||
::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id')
|
||||
return PiggyBank::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id')
|
||||
->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id')
|
||||
->where('accounts.user_id', $this->user->id)
|
||||
->where('piggy_banks.name', $name)
|
||||
->first(['piggy_banks.*']);
|
||||
->first(['piggy_banks.*'])
|
||||
;
|
||||
}
|
||||
|
||||
private function setOrder(PiggyBank $piggyBank, array $data): PiggyBank
|
||||
{
|
||||
$this->resetOrder();
|
||||
$order = $this->getMaxOrder() + 1;
|
||||
$order = $this->getMaxOrder() + 1;
|
||||
if (array_key_exists('order', $data)) {
|
||||
$order = $data['order'];
|
||||
}
|
||||
$piggyBank->order = $order;
|
||||
$piggyBank->saveQuietly();
|
||||
|
||||
return $piggyBank;
|
||||
|
||||
}
|
||||
@@ -193,8 +192,7 @@ class PiggyBankFactory
|
||||
public function resetOrder(): void
|
||||
{
|
||||
// TODO duplicate code
|
||||
$set = PiggyBank
|
||||
::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id')
|
||||
$set = PiggyBank::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id')
|
||||
->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id')
|
||||
->where('accounts.user_id', $this->user->id)
|
||||
->with(
|
||||
@@ -202,7 +200,8 @@ class PiggyBankFactory
|
||||
'objectGroups',
|
||||
]
|
||||
)
|
||||
->orderBy('piggy_banks.order', 'ASC')->get(['piggy_banks.*']);
|
||||
->orderBy('piggy_banks.order', 'ASC')->get(['piggy_banks.*'])
|
||||
;
|
||||
$current = 1;
|
||||
foreach ($set as $piggyBank) {
|
||||
if ($piggyBank->order !== $current) {
|
||||
@@ -214,7 +213,6 @@ class PiggyBankFactory
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private function getMaxOrder(): int
|
||||
{
|
||||
return (int) $this->piggyBankRepository->getPiggyBanks()->max('order');
|
||||
|
@@ -99,7 +99,7 @@ class PreferencesEventHandler
|
||||
{
|
||||
$repository = app(BudgetRepositoryInterface::class);
|
||||
$repository->setUserGroup($userGroup);
|
||||
$set = $repository->getBudgets();
|
||||
$set = $repository->getBudgets();
|
||||
|
||||
/** @var Budget $budget */
|
||||
foreach ($set as $budget) {
|
||||
@@ -127,13 +127,15 @@ class PreferencesEventHandler
|
||||
{
|
||||
// custom query because of the potential size of this update.
|
||||
$success = DB::table('transactions')
|
||||
->join('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->where('transaction_journals.user_group_id', $userGroup->id)
|
||||
->where(static function (Builder $q): void {
|
||||
$q->whereNotNull('native_amount')
|
||||
->orWhereNotNull('native_foreign_amount');
|
||||
})
|
||||
->update(['native_amount' => null, 'native_foreign_amount' => null]);
|
||||
->join('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->where('transaction_journals.user_group_id', $userGroup->id)
|
||||
->where(static function (Builder $q): void {
|
||||
$q->whereNotNull('native_amount')
|
||||
->orWhereNotNull('native_foreign_amount')
|
||||
;
|
||||
})
|
||||
->update(['native_amount' => null, 'native_foreign_amount' => null])
|
||||
;
|
||||
Log::debug(sprintf('Reset %d transactions.', $success));
|
||||
}
|
||||
}
|
||||
|
@@ -39,7 +39,7 @@ class AvailableBudgetObserver
|
||||
|
||||
public function updated(AvailableBudget $availableBudget): void
|
||||
{
|
||||
//Log::debug('Observe "updated" of an available budget.');
|
||||
// Log::debug('Observe "updated" of an available budget.');
|
||||
$this->updateNativeAmount($availableBudget);
|
||||
}
|
||||
|
||||
|
@@ -234,9 +234,9 @@ class BudgetController extends Controller
|
||||
$key = sprintf('%d-%d', $journal['source_account_id'], $journal['currency_id']);
|
||||
$amount = $journal['amount'];
|
||||
|
||||
$symbol = $journal['currency_symbol'];
|
||||
$code = $journal['currency_code'];
|
||||
$name = $journal['currency_name'];
|
||||
$symbol = $journal['currency_symbol'];
|
||||
$code = $journal['currency_code'];
|
||||
$name = $journal['currency_name'];
|
||||
|
||||
// if convert to native, use the native things, unless it's the foreign amount which is in the native currency.
|
||||
if ($this->convertToNative && $journal['currency_id'] !== $this->defaultCurrency->id) {
|
||||
|
@@ -50,13 +50,13 @@ class Account extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'user_id' => 'integer',
|
||||
'deleted_at' => 'datetime',
|
||||
'active' => 'boolean',
|
||||
'encrypted' => 'boolean',
|
||||
'virtual_balance' => 'string',
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'user_id' => 'integer',
|
||||
'deleted_at' => 'datetime',
|
||||
'active' => 'boolean',
|
||||
'encrypted' => 'boolean',
|
||||
'virtual_balance' => 'string',
|
||||
'native_virtual_balance' => 'string',
|
||||
];
|
||||
|
||||
|
@@ -48,10 +48,10 @@ class AutoBudget extends Model
|
||||
public const int AUTO_BUDGET_ROLLOVER = 2;
|
||||
protected $casts
|
||||
= [
|
||||
'amount' => 'string',
|
||||
'amount' => 'string',
|
||||
'native_amount' => 'string',
|
||||
];
|
||||
protected $fillable = ['budget_id', 'amount', 'period','native_amount'];
|
||||
protected $fillable = ['budget_id', 'amount', 'period', 'native_amount'];
|
||||
|
||||
public function budget(): BelongsTo
|
||||
{
|
||||
|
@@ -53,7 +53,7 @@ class AvailableBudget extends Model
|
||||
'native_amount' => 'string',
|
||||
];
|
||||
|
||||
protected $fillable = ['user_id', 'user_group_id', 'transaction_currency_id', 'amount', 'start_date', 'end_date', 'start_date_tz', 'end_date_tz','native_amount'];
|
||||
protected $fillable = ['user_id', 'user_group_id', 'transaction_currency_id', 'amount', 'start_date', 'end_date', 'start_date_tz', 'end_date_tz', 'native_amount'];
|
||||
|
||||
/**
|
||||
* Route binder. Converts the key in the URL to the specified object (or throw 404).
|
||||
|
@@ -43,12 +43,12 @@ class BudgetLimit extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'start_date' => SeparateTimezoneCaster::class,
|
||||
'end_date' => SeparateTimezoneCaster::class,
|
||||
'auto_budget' => 'boolean',
|
||||
'amount' => 'string',
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'start_date' => SeparateTimezoneCaster::class,
|
||||
'end_date' => SeparateTimezoneCaster::class,
|
||||
'auto_budget' => 'boolean',
|
||||
'amount' => 'string',
|
||||
'native_amount' => 'string',
|
||||
];
|
||||
protected $dispatchesEvents
|
||||
|
@@ -44,19 +44,19 @@ class PiggyBank extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'start_date' => 'date',
|
||||
'target_date' => 'date',
|
||||
'order' => 'int',
|
||||
'active' => 'boolean',
|
||||
'encrypted' => 'boolean',
|
||||
'target_amount' => 'string',
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'start_date' => 'date',
|
||||
'target_date' => 'date',
|
||||
'order' => 'int',
|
||||
'active' => 'boolean',
|
||||
'encrypted' => 'boolean',
|
||||
'target_amount' => 'string',
|
||||
'native_target_amount' => 'string',
|
||||
];
|
||||
|
||||
protected $fillable = ['name', 'order', 'target_amount', 'start_date', 'start_date_tz', 'target_date', 'target_date_tz', 'active', 'transaction_currency_id','native_target_amount'];
|
||||
protected $fillable = ['name', 'order', 'target_amount', 'start_date', 'start_date_tz', 'target_date', 'target_date_tz', 'active', 'transaction_currency_id', 'native_target_amount'];
|
||||
|
||||
/**
|
||||
* Route binder. Converts the key in the URL to the specified object (or throw 404).
|
||||
|
@@ -45,7 +45,7 @@ class PiggyBankEvent extends Model
|
||||
'amount' => 'native_string',
|
||||
];
|
||||
|
||||
protected $fillable = ['piggy_bank_id', 'transaction_journal_id', 'date', 'date_tz', 'amount','native_amount'];
|
||||
protected $fillable = ['piggy_bank_id', 'transaction_journal_id', 'date', 'date_tz', 'amount', 'native_amount'];
|
||||
|
||||
protected $hidden = ['amount_encrypted'];
|
||||
|
||||
|
@@ -28,12 +28,10 @@ use Carbon\Carbon;
|
||||
use FireflyIII\Enums\TransactionTypeEnum;
|
||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Support\Facades\Amount;
|
||||
use FireflyIII\Support\Report\Summarizer\TransactionSummarizer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Contracts\Auth\Authenticatable;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Class OperationsRepository
|
||||
@@ -68,7 +66,7 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
return $collector->getExtractedJournals();
|
||||
}
|
||||
|
||||
public function setUser(null | Authenticatable | User $user): void
|
||||
public function setUser(null|Authenticatable|User $user): void
|
||||
{
|
||||
if ($user instanceof User) {
|
||||
$this->user = $user;
|
||||
@@ -79,8 +77,8 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
{
|
||||
$array = [];
|
||||
foreach ($journals as $journal) {
|
||||
$currencyId = (int) $journal['currency_id'];
|
||||
$journalId = (int) $journal['transaction_journal_id'];
|
||||
$currencyId = (int) $journal['currency_id'];
|
||||
$journalId = (int) $journal['transaction_journal_id'];
|
||||
$array[$currencyId] ??= [
|
||||
'currency_id' => $journal['currency_id'],
|
||||
'currency_name' => $journal['currency_name'],
|
||||
@@ -132,8 +130,7 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
?Collection $accounts = null,
|
||||
?Collection $expense = null,
|
||||
?TransactionCurrency $currency = null
|
||||
): array
|
||||
{
|
||||
): array {
|
||||
$journals = $this->getTransactionsForSum(TransactionTypeEnum::WITHDRAWAL->value, $start, $end, $accounts, $expense, $currency);
|
||||
|
||||
return $this->groupByCurrency($journals, 'negative');
|
||||
@@ -150,8 +147,7 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
?Collection $accounts = null,
|
||||
?Collection $opposing = null,
|
||||
?TransactionCurrency $currency = null
|
||||
): array
|
||||
{
|
||||
): array {
|
||||
$start->startOfDay();
|
||||
$end->endOfDay();
|
||||
|
||||
@@ -184,14 +180,15 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
if (null !== $currency) {
|
||||
$collector->setCurrency($currency);
|
||||
}
|
||||
$journals = $collector->getExtractedJournals();
|
||||
$journals = $collector->getExtractedJournals();
|
||||
|
||||
// same but for foreign currencies:
|
||||
if (null !== $currency) {
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setUser($this->user)->setRange($start, $end)->setTypes([$type])->withAccountInformation()
|
||||
->setForeignCurrency($currency);
|
||||
->setForeignCurrency($currency)
|
||||
;
|
||||
if (TransactionTypeEnum::WITHDRAWAL->value === $type) {
|
||||
if (null !== $accounts) {
|
||||
$collector->setSourceAccounts($accounts);
|
||||
@@ -209,10 +206,10 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
}
|
||||
}
|
||||
|
||||
$result = $collector->getExtractedJournals();
|
||||
$result = $collector->getExtractedJournals();
|
||||
|
||||
// do not use array_merge because you want keys to overwrite (otherwise you get double results):
|
||||
$journals = $result + $journals;
|
||||
$journals = $result + $journals;
|
||||
}
|
||||
|
||||
return $journals;
|
||||
@@ -221,6 +218,7 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
private function groupByCurrency(array $journals, string $direction): array
|
||||
{
|
||||
$summarizer = new TransactionSummarizer($this->user);
|
||||
|
||||
return $summarizer->groupByCurrencyId($journals, $direction);
|
||||
}
|
||||
|
||||
@@ -233,8 +231,7 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
?Collection $accounts = null,
|
||||
?Collection $expense = null,
|
||||
?TransactionCurrency $currency = null
|
||||
): array
|
||||
{
|
||||
): array {
|
||||
$journals = $this->getTransactionsForSum(TransactionTypeEnum::WITHDRAWAL->value, $start, $end, $accounts, $expense, $currency);
|
||||
|
||||
return $this->groupByDirection($journals, 'destination', 'negative');
|
||||
@@ -243,6 +240,7 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
private function groupByDirection(array $journals, string $direction, string $method): array
|
||||
{
|
||||
$summarizer = new TransactionSummarizer($this->user);
|
||||
|
||||
return $summarizer->groupByDirection($journals, $method, $direction);
|
||||
}
|
||||
|
||||
@@ -255,8 +253,7 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
?Collection $accounts = null,
|
||||
?Collection $expense = null,
|
||||
?TransactionCurrency $currency = null
|
||||
): array
|
||||
{
|
||||
): array {
|
||||
$journals = $this->getTransactionsForSum(TransactionTypeEnum::WITHDRAWAL->value, $start, $end, $accounts, $expense, $currency);
|
||||
|
||||
return $this->groupByDirection($journals, 'source', 'negative');
|
||||
@@ -271,8 +268,7 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
?Collection $accounts = null,
|
||||
?Collection $revenue = null,
|
||||
?TransactionCurrency $currency = null
|
||||
): array
|
||||
{
|
||||
): array {
|
||||
$journals = $this->getTransactionsForSum(TransactionTypeEnum::DEPOSIT->value, $start, $end, $accounts, $revenue, $currency);
|
||||
|
||||
return $this->groupByCurrency($journals, 'positive');
|
||||
@@ -287,8 +283,7 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
?Collection $accounts = null,
|
||||
?Collection $revenue = null,
|
||||
?TransactionCurrency $currency = null
|
||||
): array
|
||||
{
|
||||
): array {
|
||||
$journals = $this->getTransactionsForSum(TransactionTypeEnum::DEPOSIT->value, $start, $end, $accounts, $revenue, $currency);
|
||||
|
||||
return $this->groupByDirection($journals, 'destination', 'positive');
|
||||
@@ -303,8 +298,7 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
?Collection $accounts = null,
|
||||
?Collection $revenue = null,
|
||||
?TransactionCurrency $currency = null
|
||||
): array
|
||||
{
|
||||
): array {
|
||||
$journals = $this->getTransactionsForSum(TransactionTypeEnum::DEPOSIT->value, $start, $end, $accounts, $revenue, $currency);
|
||||
|
||||
return $this->groupByDirection($journals, 'source', 'positive');
|
||||
@@ -325,7 +319,7 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
foreach ($journals as $journal) {
|
||||
$return = $this->groupByEitherJournal($return, $journal);
|
||||
}
|
||||
$final = [];
|
||||
$final = [];
|
||||
foreach ($return as $array) {
|
||||
$array['difference_float'] = (float) $array['difference'];
|
||||
$array['in_float'] = (float) $array['in'];
|
||||
@@ -338,12 +332,12 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
|
||||
private function groupByEitherJournal(array $return, array $journal): array
|
||||
{
|
||||
$sourceId = $journal['source_account_id'];
|
||||
$destinationId = $journal['destination_account_id'];
|
||||
$currencyId = $journal['currency_id'];
|
||||
$sourceKey = sprintf('%d-%d', $currencyId, $sourceId);
|
||||
$destKey = sprintf('%d-%d', $currencyId, $destinationId);
|
||||
$amount = app('steam')->positive($journal['amount']);
|
||||
$sourceId = $journal['source_account_id'];
|
||||
$destinationId = $journal['destination_account_id'];
|
||||
$currencyId = $journal['currency_id'];
|
||||
$sourceKey = sprintf('%d-%d', $currencyId, $sourceId);
|
||||
$destKey = sprintf('%d-%d', $currencyId, $destinationId);
|
||||
$amount = app('steam')->positive($journal['amount']);
|
||||
|
||||
// source first
|
||||
$return[$sourceKey] ??= [
|
||||
@@ -360,7 +354,7 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
];
|
||||
|
||||
// dest next:
|
||||
$return[$destKey] ??= [
|
||||
$return[$destKey] ??= [
|
||||
'id' => (string) $destinationId,
|
||||
'name' => $journal['destination_account_name'],
|
||||
'difference' => '0',
|
||||
@@ -378,15 +372,15 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
$return[$sourceKey]['difference'] = bcadd($return[$sourceKey]['out'], $return[$sourceKey]['in']);
|
||||
|
||||
// destination account? money comes in:
|
||||
$return[$destKey]['in'] = bcadd($return[$destKey]['in'], $amount);
|
||||
$return[$destKey]['difference'] = bcadd($return[$destKey]['out'], $return[$destKey]['in']);
|
||||
$return[$destKey]['in'] = bcadd($return[$destKey]['in'], $amount);
|
||||
$return[$destKey]['difference'] = bcadd($return[$destKey]['out'], $return[$destKey]['in']);
|
||||
|
||||
// foreign currency
|
||||
if (null !== $journal['foreign_currency_id'] && null !== $journal['foreign_amount']) {
|
||||
$currencyId = $journal['foreign_currency_id'];
|
||||
$sourceKey = sprintf('%d-%d', $currencyId, $sourceId);
|
||||
$destKey = sprintf('%d-%d', $currencyId, $destinationId);
|
||||
$amount = app('steam')->positive($journal['foreign_amount']);
|
||||
$currencyId = $journal['foreign_currency_id'];
|
||||
$sourceKey = sprintf('%d-%d', $currencyId, $sourceId);
|
||||
$destKey = sprintf('%d-%d', $currencyId, $destinationId);
|
||||
$amount = app('steam')->positive($journal['foreign_amount']);
|
||||
|
||||
// same as above:
|
||||
// source first
|
||||
@@ -404,7 +398,7 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
];
|
||||
|
||||
// dest next:
|
||||
$return[$destKey] ??= [
|
||||
$return[$destKey] ??= [
|
||||
'id' => (string) $destinationId,
|
||||
'name' => $journal['destination_account_name'],
|
||||
'difference' => '0',
|
||||
@@ -421,8 +415,8 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
$return[$sourceKey]['difference'] = bcadd($return[$sourceKey]['out'], $return[$sourceKey]['in']);
|
||||
|
||||
// destination account? money comes in:
|
||||
$return[$destKey]['in'] = bcadd($return[$destKey]['in'], $amount);
|
||||
$return[$destKey]['difference'] = bcadd($return[$destKey]['out'], $return[$destKey]['in']);
|
||||
$return[$destKey]['in'] = bcadd($return[$destKey]['in'], $amount);
|
||||
$return[$destKey]['difference'] = bcadd($return[$destKey]['out'], $return[$destKey]['in']);
|
||||
}
|
||||
|
||||
return $return;
|
||||
|
@@ -586,7 +586,7 @@ class BillRepository implements BillRepositoryInterface
|
||||
|
||||
$minField = $convertToNative && $bill->transactionCurrency->id !== $default->id ? 'native_amount_min' : 'amount_min';
|
||||
$maxField = $convertToNative && $bill->transactionCurrency->id !== $default->id ? 'native_amount_max' : 'amount_max';
|
||||
Log::debug(sprintf('min field is %s, max field is %s', $minField, $maxField));
|
||||
Log::debug(sprintf('min field is %s, max field is %s', $minField, $maxField));
|
||||
|
||||
if ($total > 0) {
|
||||
$currency = $convertToNative && $bill->transactionCurrency->id !== $default->id ? $default : $bill->transactionCurrency;
|
||||
|
@@ -29,12 +29,10 @@ use FireflyIII\Enums\TransactionTypeEnum;
|
||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Support\Facades\Amount;
|
||||
use FireflyIII\Support\Report\Summarizer\TransactionSummarizer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Contracts\Auth\Authenticatable;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Class NoBudgetRepository
|
||||
@@ -93,7 +91,7 @@ class NoBudgetRepository implements NoBudgetRepositoryInterface
|
||||
public function sumExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null, ?TransactionCurrency $currency = null): array
|
||||
{
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL]);
|
||||
|
||||
if (null !== $accounts && $accounts->count() > 0) {
|
||||
@@ -104,8 +102,9 @@ class NoBudgetRepository implements NoBudgetRepositoryInterface
|
||||
}
|
||||
$collector->withoutBudget();
|
||||
$collector->withBudgetInformation();
|
||||
$journals = $collector->getExtractedJournals();
|
||||
$journals = $collector->getExtractedJournals();
|
||||
$summarizer = new TransactionSummarizer($this->user);
|
||||
|
||||
return $summarizer->groupByCurrencyId($journals);
|
||||
}
|
||||
}
|
||||
|
@@ -218,10 +218,10 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
|
||||
// 2024-12-24 disable the exclusion for now.
|
||||
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
$repository->setUser($this->user);
|
||||
$subset = $repository->getAccountsByType(config('firefly.valid_liabilities'));
|
||||
$selection = new Collection();
|
||||
$subset = $repository->getAccountsByType(config('firefly.valid_liabilities'));
|
||||
$selection = new Collection();
|
||||
|
||||
/** @var Account $account */
|
||||
foreach ($subset as $account) {
|
||||
@@ -231,7 +231,7 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
}
|
||||
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setUser($this->user)
|
||||
->setRange($start, $end)
|
||||
// ->excludeDestinationAccounts($selection)
|
||||
@@ -249,13 +249,14 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
$collector->setNormalCurrency($currency);
|
||||
}
|
||||
$collector->setBudgets($budgets);
|
||||
$journals = $collector->getExtractedJournals();
|
||||
$journals = $collector->getExtractedJournals();
|
||||
|
||||
// same but for transactions in the foreign currency:
|
||||
if (null !== $currency) {
|
||||
Log::debug('STOP looking for transactions in the foreign currency.');
|
||||
}
|
||||
$summarizer = new TransactionSummarizer($this->user);
|
||||
|
||||
return $summarizer->groupByCurrencyId($journals);
|
||||
}
|
||||
}
|
||||
|
@@ -27,12 +27,10 @@ namespace FireflyIII\Repositories\Category;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Support\Facades\Amount;
|
||||
use FireflyIII\Support\Report\Summarizer\TransactionSummarizer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Contracts\Auth\Authenticatable;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Class NoCategoryRepository
|
||||
@@ -146,14 +144,15 @@ class NoCategoryRepository implements NoCategoryRepositoryInterface
|
||||
public function sumExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null): array
|
||||
{
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL])->withoutCategory();
|
||||
|
||||
if (null !== $accounts && $accounts->count() > 0) {
|
||||
$collector->setAccounts($accounts);
|
||||
}
|
||||
$journals = $collector->getExtractedJournals();
|
||||
$journals = $collector->getExtractedJournals();
|
||||
$summarizer = new TransactionSummarizer($this->user);
|
||||
|
||||
return $summarizer->groupByCurrencyId($journals);
|
||||
}
|
||||
|
||||
|
@@ -328,7 +328,7 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
public function sumExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $categories = null): array
|
||||
{
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionTypeEnum::WITHDRAWAL->value]);
|
||||
|
||||
if (null !== $accounts && $accounts->count() > 0) {
|
||||
@@ -339,8 +339,9 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
}
|
||||
$collector->setCategories($categories);
|
||||
$collector->withCategoryInformation();
|
||||
$journals = $collector->getExtractedJournals();
|
||||
$journals = $collector->getExtractedJournals();
|
||||
$summarizer = new TransactionSummarizer($this->user);
|
||||
|
||||
return $summarizer->groupByCurrencyId($journals);
|
||||
}
|
||||
|
||||
|
@@ -85,16 +85,16 @@ class Amount
|
||||
*/
|
||||
public function getAmountFromJournalObject(TransactionJournal $journal): string
|
||||
{
|
||||
$convertToNative = $this->convertToNative();
|
||||
$currency = $this->getDefaultCurrency();
|
||||
$field = $convertToNative && $currency->id !== $journal->transaction_currency_id ? 'native_amount' : 'amount';
|
||||
$convertToNative = $this->convertToNative();
|
||||
$currency = $this->getDefaultCurrency();
|
||||
$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';
|
||||
$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.
|
||||
@@ -113,15 +113,15 @@ 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($rounded, '0')) {
|
||||
@@ -166,12 +166,13 @@ class Amount
|
||||
return $this->getDefaultCurrencyByUserGroup($user->userGroup);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->getSystemCurrency();
|
||||
}
|
||||
|
||||
public function getDefaultCurrencyByUserGroup(UserGroup $userGroup): TransactionCurrency
|
||||
{
|
||||
$cache = new CacheProperties();
|
||||
$cache = new CacheProperties();
|
||||
$cache->addProperty('getDefaultCurrencyByGroup');
|
||||
$cache->addProperty($userGroup->id);
|
||||
if ($cache->has()) {
|
||||
@@ -234,20 +235,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);
|
||||
@@ -270,7 +271,7 @@ class Amount
|
||||
public static function getAmountJsConfig(bool $sepBySpace, int $signPosn, string $sign, bool $csPrecedes): string
|
||||
{
|
||||
// negative first:
|
||||
$space = ' ';
|
||||
$space = ' ';
|
||||
|
||||
// require space between symbol and amount?
|
||||
if (false === $sepBySpace) {
|
||||
@@ -279,11 +280,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
|
||||
@@ -325,11 +326,11 @@ class Amount
|
||||
}
|
||||
|
||||
// default is amount before currency
|
||||
$format = $posA . $posD . '%v' . $space . $posB . '%s' . $posC . $posE;
|
||||
$format = $posA.$posD.'%v'.$space.$posB.'%s'.$posC.$posE;
|
||||
|
||||
if ($csPrecedes) {
|
||||
// alternative is currency before amount
|
||||
$format = $posA . $posB . '%s' . $posC . $space . $posD . '%v' . $posE;
|
||||
$format = $posA.$posB.'%s'.$posC.$space.$posD.'%v'.$posE;
|
||||
}
|
||||
|
||||
return $format;
|
||||
|
@@ -507,12 +507,12 @@ class Navigation
|
||||
$diff = $start->diffInMonths($end, true);
|
||||
Log::debug(sprintf('preferredCarbonFormat(%s, %s) = %f', $start->format('Y-m-d'), $end->format('Y-m-d'), $diff));
|
||||
if ($diff >= 1.001) {
|
||||
// Log::debug(sprintf('Return Y-m because %s', $diff));
|
||||
// Log::debug(sprintf('Return Y-m because %s', $diff));
|
||||
$format = 'Y-m';
|
||||
}
|
||||
|
||||
if ($diff >= 12.001) {
|
||||
// Log::debug(sprintf('Return Y because %s', $diff));
|
||||
// Log::debug(sprintf('Return Y because %s', $diff));
|
||||
$format = 'Y';
|
||||
}
|
||||
|
||||
|
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* TransactionSummarizer.php
|
||||
* Copyright (c) 2024 james@firefly-iii.org.
|
||||
@@ -52,14 +53,14 @@ class TransactionSummarizer
|
||||
{
|
||||
$array = [];
|
||||
foreach ($journals as $journal) {
|
||||
$field = 'amount';
|
||||
$field = 'amount';
|
||||
|
||||
// grab default currency information.
|
||||
$currencyId = (int) $journal['currency_id'];
|
||||
$currencyName = $journal['currency_name'];
|
||||
$currencySymbol = $journal['currency_symbol'];
|
||||
$currencyCode = $journal['currency_code'];
|
||||
$currencyDecimalPlaces = $journal['currency_decimal_places'];
|
||||
$currencyId = (int) $journal['currency_id'];
|
||||
$currencyName = $journal['currency_name'];
|
||||
$currencySymbol = $journal['currency_symbol'];
|
||||
$currencyCode = $journal['currency_code'];
|
||||
$currencyDecimalPlaces = $journal['currency_decimal_places'];
|
||||
if ($this->convertToNative) {
|
||||
// if convert to native, use the native amount yes or no?
|
||||
$useNative = $this->default->id !== (int) $journal['currency_id'];
|
||||
@@ -83,11 +84,11 @@ class TransactionSummarizer
|
||||
$currencyDecimalPlaces = $journal['foreign_currency_decimal_places'];
|
||||
}
|
||||
}
|
||||
if(!$this->convertToNative) {
|
||||
if (!$this->convertToNative) {
|
||||
// default to the normal amount, but also
|
||||
}
|
||||
$amount = (string) ($journal[$field] ?? '0');
|
||||
$array[$currencyId] ??= [
|
||||
$array[$currencyId] ??= [
|
||||
'sum' => '0',
|
||||
'currency_id' => $currencyId,
|
||||
'currency_name' => $currencyName,
|
||||
@@ -95,14 +96,16 @@ class TransactionSummarizer
|
||||
'currency_code' => $currencyCode,
|
||||
'currency_decimal_places' => $currencyDecimalPlaces,
|
||||
];
|
||||
$array[$currencyId]['sum'] = bcadd($array[$currencyId]['sum'], app('steam')->$method($amount));
|
||||
$array[$currencyId]['sum'] = bcadd($array[$currencyId]['sum'], app('steam')->{$method}($amount));
|
||||
Log::debug(sprintf('Journal #%d adds amount %s %s', $journal['transaction_journal_id'], $currencyCode, $amount));
|
||||
}
|
||||
Log::debug('End of sumExpenses.', $array);
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
public function groupByDirection(array $journals, string $method, string $direction): array {
|
||||
public function groupByDirection(array $journals, string $method, string $direction): array
|
||||
{
|
||||
|
||||
$array = [];
|
||||
$idKey = sprintf('%s_account_id', $direction);
|
||||
@@ -136,7 +139,7 @@ class TransactionSummarizer
|
||||
if ($convertToNative && $journal['currency_id'] !== $default->id && $default->id === $journal['foreign_currency_id']) {
|
||||
$field = 'foreign_amount';
|
||||
}
|
||||
$key = sprintf('%s-%s', $journal[$idKey], $currencyId);
|
||||
$key = sprintf('%s-%s', $journal[$idKey], $currencyId);
|
||||
// sum it all up or create a new array.
|
||||
$array[$key] ??= [
|
||||
'id' => $journal[$idKey],
|
||||
@@ -150,7 +153,7 @@ class TransactionSummarizer
|
||||
];
|
||||
|
||||
// add the data from the $field to the array.
|
||||
$array[$key]['sum'] = bcadd($array[$key]['sum'], app('steam')->{$method}((string) ($journal[$field] ?? '0'))); // @phpstan-ignore-line
|
||||
$array[$key]['sum'] = bcadd($array[$key]['sum'], app('steam')->{$method}((string) ($journal[$field] ?? '0'))); // @phpstan-ignore-line
|
||||
Log::debug(sprintf('Field for transaction #%d is "%s" (%s). Sum: %s', $journal['transaction_group_id'], $currencyCode, $field, $array[$key]['sum']));
|
||||
|
||||
// also do foreign amount, but only when convertToNative is false (otherwise we have it already)
|
||||
@@ -158,7 +161,7 @@ class TransactionSummarizer
|
||||
if ((!$convertToNative || $journal['foreign_currency_id'] !== $default->id) && 0 !== (int) $journal['foreign_currency_id']) {
|
||||
Log::debug(sprintf('Use foreign amount from transaction #%d: %s %s. Sum: %s', $journal['transaction_group_id'], $currencyCode, $journal['foreign_amount'], $array[$key]['sum']));
|
||||
$key = sprintf('%s-%s', $journal[$idKey], $journal['foreign_currency_id']);
|
||||
$array[$key] ??= [
|
||||
$array[$key] ??= [
|
||||
'id' => $journal[$idKey],
|
||||
'name' => $journal[$nameKey],
|
||||
'sum' => '0',
|
||||
@@ -174,5 +177,4 @@ class TransactionSummarizer
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -58,7 +58,7 @@ class AccountTransformer extends AbstractTransformer
|
||||
|
||||
// get account type:
|
||||
$fullType = $account->accountType->type;
|
||||
$accountType = (string) config(sprintf( 'firefly.shortNamesByFullName.%s', $fullType));
|
||||
$accountType = (string) config(sprintf('firefly.shortNamesByFullName.%s', $fullType));
|
||||
$liabilityType = (string) config(sprintf('firefly.shortLiabilityNameByFullName.%s', $fullType));
|
||||
$liabilityType = '' === $liabilityType ? null : strtolower($liabilityType);
|
||||
$liabilityDirection = $this->repository->getMetaValue($account, 'liability_direction');
|
||||
|
Reference in New Issue
Block a user