mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-08-16 19:04:36 +00:00
Compare commits
96 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
7f8ed7abb6 | ||
|
c593936b32 | ||
|
c54204ede9 | ||
|
d9132bbee3 | ||
|
c1be98762e | ||
|
c2733e2a8f | ||
|
722cf9b4fe | ||
|
01e31e73e0 | ||
|
dba7d05296 | ||
|
a8709a4a45 | ||
|
49b1435cba | ||
|
6a25b41952 | ||
|
c561f99de6 | ||
|
9d9053d828 | ||
|
c3c9a2f3c0 | ||
|
28465142e9 | ||
|
5473a618c9 | ||
|
ac1a8d8053 | ||
|
15ae9203b6 | ||
|
9dfc2ae20b | ||
|
230de7cbdd | ||
|
feaa003a52 | ||
|
295d01dc16 | ||
|
cbf1fde45e | ||
|
6cc47287d3 | ||
|
4bbe728376 | ||
|
427a90ec85 | ||
|
55ddb26dac | ||
|
891777f079 | ||
|
1655286b67 | ||
|
dd81636bf2 | ||
|
56a43a707d | ||
|
c2f92c6e45 | ||
|
61bd2dc840 | ||
|
f6a675f2e2 | ||
|
85b43055a7 | ||
|
e63f7bcc70 | ||
|
384dd37430 | ||
|
c6b336171c | ||
|
d2f4399a1a | ||
|
02d1bc093c | ||
|
420e493987 | ||
|
0a15479bff | ||
|
a9b76a3679 | ||
|
d1a3cd9044 | ||
|
81735d59f8 | ||
|
1d8da7f9f0 | ||
|
c5f0684030 | ||
|
25867adcb9 | ||
|
d55694cd68 | ||
|
05f069d61e | ||
|
5f6e7ad138 | ||
|
61bc38921e | ||
|
94c660545d | ||
|
4d3907948d | ||
|
e6442dd8af | ||
|
7905e0bd70 | ||
|
f4b1da352d | ||
|
0d33348941 | ||
|
c7c875e95f | ||
|
19d24b3e2a | ||
|
8fed6b6657 | ||
|
b5eafa1910 | ||
|
c15501937f | ||
|
4c743bd5b0 | ||
|
44289cbd95 | ||
|
b2f1642cfe | ||
|
341ef0220c | ||
|
9df88115bc | ||
|
c7273edb5e | ||
|
c398aa2b69 | ||
|
aa786eaaf3 | ||
|
e58a5e12d6 | ||
|
12b3575c5c | ||
|
3ca186dc8f | ||
|
1535f596f6 | ||
|
2cc326caa1 | ||
|
43436ae942 | ||
|
fbfd8475de | ||
|
405752f353 | ||
|
2af98b259a | ||
|
015242a666 | ||
|
54933fda2e | ||
|
852d057a47 | ||
|
1778f0b4f3 | ||
|
6daf083b3f | ||
|
4a7d9b130a | ||
|
4163efba55 | ||
|
db5847b49b | ||
|
6829003f5e | ||
|
047927718e | ||
|
91deb22a3f | ||
|
1629ca0739 | ||
|
8b87204f10 | ||
|
f920d90e3d | ||
|
1cb91282af |
20
.env.example
20
.env.example
@@ -22,15 +22,15 @@ APP_KEY=SomeRandomStringOf32CharsExactly
|
||||
# If text is still in English, remember that not everything may have been translated.
|
||||
DEFAULT_LANGUAGE=en_US
|
||||
|
||||
# The locale defines how numbers are formatted.
|
||||
# by default this value is the same as whatever the language is.
|
||||
DEFAULT_LOCALE=equal
|
||||
|
||||
# Change this value to your preferred time zone.
|
||||
# Example: Europe/Amsterdam
|
||||
# For a list of supported time zones, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
||||
TZ=Europe/Amsterdam
|
||||
|
||||
# This variable must match your installation's external address but keep in mind that
|
||||
# it's only used on the command line as a fallback value.
|
||||
APP_URL=http://localhost
|
||||
|
||||
# TRUSTED_PROXIES is a useful variable when using Docker and/or a reverse proxy.
|
||||
# Set it to ** and reverse proxies work just fine.
|
||||
TRUSTED_PROXIES=
|
||||
@@ -270,3 +270,15 @@ IS_SANDSTORM=false
|
||||
IS_DOCKER=false
|
||||
IS_HEROKU=false
|
||||
BUNQ_USE_SANDBOX=false
|
||||
|
||||
#
|
||||
# If you have trouble configuring your Firefly III installation, DON'T BOTHER setting this variable.
|
||||
# It won't work. It doesn't do ANYTHING. Don't believe the lies you read online. I'm not joking.
|
||||
# This configuration value WILL NOT HELP.
|
||||
#
|
||||
# This variable is ONLY used in some of the emails Firefly III sends around. Nowhere else.
|
||||
# So when configuring anything WEB related this variable doesn't do anything. Nothing
|
||||
#
|
||||
# If you're stuck I understand you get desperate but look SOMEWHERE ELSE.
|
||||
#
|
||||
APP_URL=http://localhost
|
||||
|
12
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
12
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
@@ -16,10 +16,10 @@ I am running Firefly III version x.x.x, and my problem is:
|
||||
<!-- Please add extra info here, such as OS, browser, and the output from the /debug page of your Firefly III installation (click the version at the bottom). -->
|
||||
|
||||
**Bonus points**
|
||||
<!-- Earn bonus points by checking the boxes -->
|
||||
<!-- Before you submit, verify the following please: -->
|
||||
|
||||
- [ ] Nobody reported this bug before
|
||||
- [ ] I have added a stack trace from my log files <!-- (see https://bit.ly/FF3-get-debug-info) -->
|
||||
- [ ] I have added a screenshot.
|
||||
- [ ] I was able to replicate it on the demo site https://demo.firefly-iii.org/
|
||||
<!-- - [ ] I donated money (this is a joke :wink:)-->
|
||||
- I searched and nobody reported this bug before
|
||||
- I have added a stack trace from my log files <!-- (see https://bit.ly/FF3-get-debug-info) -->
|
||||
- I have added a screenshot.
|
||||
- I was able to replicate it on the demo site https://demo.firefly-iii.org/
|
||||
<!-- - I donated money (this is a joke ;)-->
|
||||
|
10
.github/ISSUE_TEMPLATE/Custom.md
vendored
10
.github/ISSUE_TEMPLATE/Custom.md
vendored
@@ -16,8 +16,8 @@ I am running Firefly III version x.x.x.
|
||||
|
||||
<!-- Complete the following checklist for bonus points -->
|
||||
|
||||
- [ ] I have read the FAQ at https://bit.ly/FF3-FAQ
|
||||
- [ ] I added a screenshot
|
||||
- [ ] I added log files <!-- (see https://bit.ly/FF3-get-debug-info) -->
|
||||
- [ ] I was able to replicate the issue on the demo site.
|
||||
<!-- - [ ] I donated money (this is a joke :wink:)-->
|
||||
- I have read the FAQ at https://bit.ly/FF3-FAQ
|
||||
- I added a screenshot
|
||||
- I added log files <!-- (see https://bit.ly/FF3-get-debug-info) -->
|
||||
- I was able to replicate the issue on the demo site.
|
||||
<!-- - I donated money (this is a joke :wink:)-->
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,4 +1,5 @@
|
||||
/node_modules
|
||||
/frontend/node_modules
|
||||
/public/hot
|
||||
/public/storage
|
||||
/storage/*.key
|
||||
|
@@ -98,7 +98,7 @@ class AccountFactory
|
||||
'user_id' => $this->user->id,
|
||||
'account_type_id' => $type->id,
|
||||
'name' => $data['name'],
|
||||
'virtual_balance' => $data['virtual_balance'] ?? '0',
|
||||
'virtual_balance' => $data['virtual_balance'] ?? null,
|
||||
'active' => true === $data['active'],
|
||||
'iban' => $data['iban'],
|
||||
];
|
||||
@@ -109,12 +109,12 @@ class AccountFactory
|
||||
|
||||
// remove virtual balance when not an asset account or a liability
|
||||
if (!in_array($type->type, $this->canHaveVirtual, true)) {
|
||||
$databaseData['virtual_balance'] = '0';
|
||||
$databaseData['virtual_balance'] = null;
|
||||
}
|
||||
|
||||
// fix virtual balance when it's empty
|
||||
if ('' === $databaseData['virtual_balance']) {
|
||||
$databaseData['virtual_balance'] = '0';
|
||||
if ('' === (string)$databaseData['virtual_balance']) {
|
||||
$databaseData['virtual_balance'] = null;
|
||||
}
|
||||
|
||||
$return = Account::create($databaseData);
|
||||
|
@@ -280,25 +280,29 @@ class TransactionJournalFactory
|
||||
|
||||
/** create or get source and destination accounts */
|
||||
$sourceInfo = [
|
||||
'id' => (int) $row['source_id'],
|
||||
'name' => $row['source_name'],
|
||||
'iban' => $row['source_iban'],
|
||||
'number' => $row['source_number'],
|
||||
'bic' => $row['source_bic'],
|
||||
'id' => (int) $row['source_id'],
|
||||
'name' => $row['source_name'],
|
||||
'iban' => $row['source_iban'],
|
||||
'number' => $row['source_number'],
|
||||
'bic' => $row['source_bic'],
|
||||
'currency_id' => $currency->id,
|
||||
];
|
||||
|
||||
$destInfo = [
|
||||
'id' => (int) $row['destination_id'],
|
||||
'name' => $row['destination_name'],
|
||||
'iban' => $row['destination_iban'],
|
||||
'number' => $row['destination_number'],
|
||||
'bic' => $row['destination_bic'],
|
||||
'id' => (int) $row['destination_id'],
|
||||
'name' => $row['destination_name'],
|
||||
'iban' => $row['destination_iban'],
|
||||
'number' => $row['destination_number'],
|
||||
'bic' => $row['destination_bic'],
|
||||
'currency_id' => $currency->id,
|
||||
];
|
||||
Log::debug('Source info:', $sourceInfo);
|
||||
Log::debug('Destination info:', $destInfo);
|
||||
|
||||
$sourceAccount = $this->getAccount($type->type, 'source', $sourceInfo);
|
||||
Log::debug('Now calling getAccount for the source.');
|
||||
$sourceAccount = $this->getAccount($type->type, 'source', $sourceInfo);
|
||||
Log::debug('Now calling getAccount for the destination.');
|
||||
$destinationAccount = $this->getAccount($type->type, 'destination', $destInfo);
|
||||
Log::debug('Done with getAccount(2x)');
|
||||
$currency = $this->getCurrencyByAccount($type->type, $currency, $sourceAccount, $destinationAccount);
|
||||
$foreignCurrency = $this->compareCurrencies($currency, $foreignCurrency);
|
||||
$foreignCurrency = $this->getForeignByAccount($type->type, $foreignCurrency, $destinationAccount);
|
||||
@@ -468,6 +472,7 @@ class TransactionJournalFactory
|
||||
*/
|
||||
private function getCurrency(?TransactionCurrency $currency, Account $account): TransactionCurrency
|
||||
{
|
||||
Log::debug('Now in getCurrency()');
|
||||
$preference = $this->accountRepository->getAccountCurrency($account);
|
||||
if (null === $preference && null === $currency) {
|
||||
// return user's default:
|
||||
@@ -489,6 +494,7 @@ class TransactionJournalFactory
|
||||
*/
|
||||
private function getCurrencyByAccount(string $type, ?TransactionCurrency $currency, Account $source, Account $destination): TransactionCurrency
|
||||
{
|
||||
Log::debug('Now ingetCurrencyByAccount()');
|
||||
switch ($type) {
|
||||
default:
|
||||
case TransactionType::WITHDRAWAL:
|
||||
@@ -538,15 +544,15 @@ class TransactionJournalFactory
|
||||
$dataRow = $row->getArrayCopy();
|
||||
|
||||
unset($dataRow['import_hash_v2'], $dataRow['original_source']);
|
||||
$json = json_encode($dataRow);
|
||||
$json = json_encode($dataRow, JSON_THROW_ON_ERROR, 512);
|
||||
if (false === $json) {
|
||||
// @codeCoverageIgnoreStart
|
||||
$json = json_encode((string) microtime());
|
||||
$json = json_encode((string) microtime(), JSON_THROW_ON_ERROR, 512);
|
||||
Log::error(sprintf('Could not hash the original row! %s', json_last_error_msg()), $dataRow);
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
$hash = hash('sha256', $json);
|
||||
Log::debug(sprintf('The hash is: %s', $hash));
|
||||
Log::debug(sprintf('The hash is: %s', $hash), $dataRow);
|
||||
|
||||
return $hash;
|
||||
}
|
||||
@@ -601,7 +607,7 @@ class TransactionJournalFactory
|
||||
|
||||
// validate source account.
|
||||
$sourceId = isset($data['source_id']) ? (int) $data['source_id'] : null;
|
||||
$sourceName = $data['source_name'] ?? null;
|
||||
$sourceName = isset($data['source_name']) ? (string) $data['source_name'] : null;
|
||||
$validSource = $this->accountValidator->validateSource($sourceId, $sourceName, null);
|
||||
|
||||
// do something with result:
|
||||
@@ -611,7 +617,7 @@ class TransactionJournalFactory
|
||||
Log::debug('Source seems valid.');
|
||||
// validate destination account
|
||||
$destinationId = isset($data['destination_id']) ? (int) $data['destination_id'] : null;
|
||||
$destinationName = (string)($data['destination_name'] ?? null);
|
||||
$destinationName = isset($data['destination_name']) ? (string) $data['destination_name'] : null;
|
||||
$validDestination = $this->accountValidator->validateDestination($destinationId, $destinationName, null);
|
||||
// do something with result:
|
||||
if (false === $validDestination) {
|
||||
|
@@ -154,14 +154,14 @@ class MonthReportGenerator implements ReportGeneratorInterface
|
||||
$journals[$index]['invoice_date'] = $journalRepository->getMetaDateById($journal['transaction_journal_id'], 'invoice_date');
|
||||
|
||||
}
|
||||
|
||||
$locale = app('steam')->getLocale();
|
||||
$return = [
|
||||
'journals' => $journals,
|
||||
'currency' => $currency,
|
||||
'exists' => count($journals) > 0,
|
||||
'end' => $this->end->formatLocalized((string) trans('config.month_and_day')),
|
||||
'end' => $this->end->formatLocalized((string) trans('config.month_and_day', [], $locale)),
|
||||
'endBalance' => app('steam')->balance($account, $this->end),
|
||||
'dayBefore' => $date->formatLocalized((string) trans('config.month_and_day')),
|
||||
'dayBefore' => $date->formatLocalized((string) trans('config.month_and_day', [], $locale)),
|
||||
'dayBeforeBalance' => $dayBeforeBalance,
|
||||
];
|
||||
|
||||
|
@@ -165,7 +165,8 @@ class UserEventHandler
|
||||
$user = $event->user;
|
||||
$ipAddress = $event->ipAddress;
|
||||
$token = app('preferences')->getForUser($user, 'email_change_undo_token', 'invalid');
|
||||
$uri = route('profile.undo-email-change', [$token->data, hash('sha256', $oldEmail)]);
|
||||
$hashed = hash('sha256', sprintf('%s%s', (string) config('app.key'), $oldEmail));
|
||||
$uri = route('profile.undo-email-change', [$token->data,$hashed]);
|
||||
try {
|
||||
Mail::to($oldEmail)->send(new UndoEmailChangeMail($newEmail, $oldEmail, $uri, $ipAddress));
|
||||
// @codeCoverageIgnoreStart
|
||||
|
@@ -91,8 +91,9 @@ trait TimeCollection
|
||||
if ($end < $start) {
|
||||
[$start, $end] = [$end, $start];
|
||||
}
|
||||
$startStr = $start->format('Y-m-d H:i:s');
|
||||
$endStr = $end->format('Y-m-d H:i:s');
|
||||
// always got to end of day / start of day for ranges.
|
||||
$startStr = $start->format('Y-m-d 00:00:00');
|
||||
$endStr = $end->format('Y-m-d 23:59:59');
|
||||
|
||||
$this->query->where('transaction_journals.date', '>=', $startStr);
|
||||
$this->query->where('transaction_journals.date', '<=', $endStr);
|
||||
@@ -117,4 +118,4 @@ trait TimeCollection
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -59,7 +59,7 @@ class AvailableBudgetController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.budgets'));
|
||||
app('view')->share('mainTitleIcon', 'fa-tasks');
|
||||
app('view')->share('mainTitleIcon', 'fa-pie-chart');
|
||||
$this->abRepository = app(AvailableBudgetRepositoryInterface::class);
|
||||
$this->currencyRepos = app(CurrencyRepositoryInterface::class);
|
||||
|
||||
|
@@ -70,7 +70,7 @@ class BudgetLimitController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.budgets'));
|
||||
app('view')->share('mainTitleIcon', 'fa-tasks');
|
||||
app('view')->share('mainTitleIcon', 'fa-pie-chart');
|
||||
$this->repository = app(BudgetRepositoryInterface::class);
|
||||
$this->opsRepository = app(OperationsRepositoryInterface::class);
|
||||
$this->blRepository = app(BudgetLimitRepositoryInterface::class);
|
||||
|
@@ -58,7 +58,7 @@ class CreateController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.budgets'));
|
||||
app('view')->share('mainTitleIcon', 'fa-tasks');
|
||||
app('view')->share('mainTitleIcon', 'fa-pie-chart');
|
||||
$this->repository = app(BudgetRepositoryInterface::class);
|
||||
$this->attachments = app(AttachmentHelperInterface::class);
|
||||
|
||||
|
@@ -54,7 +54,7 @@ class DeleteController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.budgets'));
|
||||
app('view')->share('mainTitleIcon', 'fa-tasks');
|
||||
app('view')->share('mainTitleIcon', 'fa-pie-chart');
|
||||
$this->repository = app(BudgetRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
|
@@ -59,7 +59,7 @@ class EditController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.budgets'));
|
||||
app('view')->share('mainTitleIcon', 'fa-tasks');
|
||||
app('view')->share('mainTitleIcon', 'fa-pie-chart');
|
||||
$this->repository = app(BudgetRepositoryInterface::class);
|
||||
$this->attachments = app(AttachmentHelperInterface::class);
|
||||
|
||||
|
@@ -72,7 +72,7 @@ class IndexController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.budgets'));
|
||||
app('view')->share('mainTitleIcon', 'fa-tasks');
|
||||
app('view')->share('mainTitleIcon', 'fa-pie-chart');
|
||||
$this->repository = app(BudgetRepositoryInterface::class);
|
||||
$this->opsRepository = app(OperationsRepositoryInterface::class);
|
||||
$this->abRepository = app(AvailableBudgetRepositoryInterface::class);
|
||||
@@ -86,7 +86,6 @@ class IndexController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO the "budgeted" progress bar doesn't update.
|
||||
* Show all budgets.
|
||||
*
|
||||
* @param Request $request
|
||||
@@ -106,7 +105,6 @@ class IndexController extends Controller
|
||||
$budgeted = '0';
|
||||
$spent = '0';
|
||||
|
||||
|
||||
// new period stuff:
|
||||
$periodTitle = app('navigation')->periodShow($start, $range);
|
||||
$prevLoop = $this->getPreviousPeriods($start, $range);
|
||||
|
@@ -64,7 +64,7 @@ class ShowController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.budgets'));
|
||||
app('view')->share('mainTitleIcon', 'fa-tasks');
|
||||
app('view')->share('mainTitleIcon', 'fa-pie-chart');
|
||||
$this->journalRepos = app(JournalRepositoryInterface::class);
|
||||
$this->repository = app(BudgetRepositoryInterface::class);
|
||||
|
||||
|
@@ -57,7 +57,7 @@ class CreateController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.categories'));
|
||||
app('view')->share('mainTitleIcon', 'fa-bar-chart');
|
||||
app('view')->share('mainTitleIcon', 'fa-bookmark');
|
||||
$this->repository = app(CategoryRepositoryInterface::class);
|
||||
$this->attachments = app(AttachmentHelperInterface::class);
|
||||
|
||||
|
@@ -53,7 +53,7 @@ class DeleteController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.categories'));
|
||||
app('view')->share('mainTitleIcon', 'fa-bar-chart');
|
||||
app('view')->share('mainTitleIcon', 'fa-bookmark');
|
||||
$this->repository = app(CategoryRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
|
@@ -59,7 +59,7 @@ class EditController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.categories'));
|
||||
app('view')->share('mainTitleIcon', 'fa-bar-chart');
|
||||
app('view')->share('mainTitleIcon', 'fa-bookmark');
|
||||
$this->repository = app(CategoryRepositoryInterface::class);
|
||||
$this->attachments = app(AttachmentHelperInterface::class);
|
||||
|
||||
|
@@ -53,7 +53,7 @@ class IndexController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.categories'));
|
||||
app('view')->share('mainTitleIcon', 'fa-bar-chart');
|
||||
app('view')->share('mainTitleIcon', 'fa-bookmark');
|
||||
$this->repository = app(CategoryRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
|
@@ -59,7 +59,7 @@ class NoCategoryController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.categories'));
|
||||
app('view')->share('mainTitleIcon', 'fa-bar-chart');
|
||||
app('view')->share('mainTitleIcon', 'fa-bookmark');
|
||||
$this->journalRepos = app(JournalRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
|
@@ -58,7 +58,7 @@ class ShowController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.categories'));
|
||||
app('view')->share('mainTitleIcon', 'fa-bar-chart');
|
||||
app('view')->share('mainTitleIcon', 'fa-bookmark');
|
||||
$this->repository = app(CategoryRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
@@ -84,7 +84,7 @@ class ShowController extends Controller
|
||||
$start = $start ?? session('start', Carbon::now()->startOfMonth());
|
||||
/** @var Carbon $end */
|
||||
$end = $end ?? session('end', Carbon::now()->endOfMonth());
|
||||
$subTitleIcon = 'fa-bar-chart';
|
||||
$subTitleIcon = 'fa-bookmark';
|
||||
$page = (int) $request->get('page');
|
||||
$attachments = $this->repository->getAttachments($category);
|
||||
$pageSize = (int) app('preferences')->get('listPageSize', 50)->data;
|
||||
@@ -122,7 +122,7 @@ class ShowController extends Controller
|
||||
public function showAll(Request $request, Category $category)
|
||||
{
|
||||
// default values:
|
||||
$subTitleIcon = 'fa-bar-chart';
|
||||
$subTitleIcon = 'fa-bookmark';
|
||||
$page = (int) $request->get('page');
|
||||
$pageSize = (int) app('preferences')->get('listPageSize', 50)->data;
|
||||
$start = null;
|
||||
|
@@ -432,9 +432,15 @@ class AccountController extends Controller
|
||||
$cache->addProperty($end);
|
||||
$cache->addProperty($account->id);
|
||||
if ($cache->has()) {
|
||||
return response()->json($cache->get()); // @codeCoverageIgnore
|
||||
return response()->json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
$currencies = $this->accountRepository->getUsedCurrencies($account);
|
||||
|
||||
// if the account is not expense or revenue, just use the account's default currency.
|
||||
if (!in_array($account->accountType->type, [AccountType::REVENUE, AccountType::EXPENSE], true)) {
|
||||
$currencies = [$this->accountRepository->getAccountCurrency($account) ?? app('amount')->getDefaultCurrency()];
|
||||
}
|
||||
|
||||
/** @var TransactionCurrency $currency */
|
||||
foreach ($currencies as $currency) {
|
||||
$chartData[] = $this->periodByCurrency($start, $end, $account, $currency);
|
||||
@@ -565,6 +571,7 @@ class AccountController extends Controller
|
||||
*/
|
||||
private function periodByCurrency(Carbon $start, Carbon $end, Account $account, TransactionCurrency $currency): array
|
||||
{
|
||||
$locale = app('steam')->getLocale();
|
||||
$step = $this->calculateStep($start, $end);
|
||||
$result = [
|
||||
'label' => sprintf('%s (%s)', $account->name, $currency->symbol),
|
||||
@@ -576,7 +583,7 @@ class AccountController extends Controller
|
||||
switch ($step) {
|
||||
case '1D':
|
||||
// per day the entire period, balance for every day.
|
||||
$format = (string) trans('config.month_and_day');
|
||||
$format = (string) trans('config.month_and_day', [], $locale);
|
||||
$range = app('steam')->balanceInRange($account, $start, $end, $currency);
|
||||
$previous = array_values($range)[0];
|
||||
while ($end >= $current) {
|
||||
|
@@ -111,6 +111,7 @@ class BillController extends Controller
|
||||
if ($cache->has()) {
|
||||
return response()->json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
$locale = app('steam')->getLocale();
|
||||
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
@@ -131,7 +132,7 @@ class BillController extends Controller
|
||||
];
|
||||
|
||||
foreach ($journals as $journal) {
|
||||
$date = $journal['date']->formatLocalized((string) trans('config.month_and_day'));
|
||||
$date = $journal['date']->formatLocalized((string) trans('config.month_and_day', [], $locale));
|
||||
$chartData[0]['entries'][$date] = $bill->amount_min; // minimum amount of bill
|
||||
$chartData[1]['entries'][$date] = $bill->amount_max; // maximum amount of bill
|
||||
|
||||
|
@@ -179,14 +179,14 @@ class BudgetController extends Controller
|
||||
if ($cache->has()) {
|
||||
return response()->json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$locale = app('steam')->getLocale();
|
||||
$entries = [];
|
||||
$amount = $budgetLimit->amount;
|
||||
$budgetCollection = new Collection([$budget]);
|
||||
while ($start <= $end) {
|
||||
$spent = $this->opsRepository->spentInPeriod($budgetCollection, new Collection, $start, $start);
|
||||
$amount = bcadd($amount, $spent);
|
||||
$format = $start->formatLocalized((string)trans('config.month_and_day'));
|
||||
$format = $start->formatLocalized((string)trans('config.month_and_day', [], $locale));
|
||||
$entries[$format] = $amount;
|
||||
|
||||
$start->addDay();
|
||||
|
@@ -76,6 +76,7 @@ class PiggyBankController extends Controller
|
||||
}
|
||||
$set = $repository->getEvents($piggyBank);
|
||||
$set = $set->reverse();
|
||||
$locale =app('steam')->getLocale();
|
||||
|
||||
// get first event or start date of piggy bank or today
|
||||
$startDate = $piggyBank->start_date ?? new Carbon;
|
||||
@@ -99,7 +100,7 @@ class PiggyBankController extends Controller
|
||||
}
|
||||
);
|
||||
$currentSum = $filtered->sum('amount');
|
||||
$label = $oldest->formatLocalized((string) trans('config.month_and_day'));
|
||||
$label = $oldest->formatLocalized((string) trans('config.month_and_day', [], $locale));
|
||||
$chartData[$label] = $currentSum;
|
||||
$oldest = app('navigation')->addPeriod($oldest, $step, 0);
|
||||
}
|
||||
@@ -110,7 +111,7 @@ class PiggyBankController extends Controller
|
||||
}
|
||||
);
|
||||
$finalSum = $finalFiltered->sum('amount');
|
||||
$finalLabel = $today->formatLocalized((string) trans('config.month_and_day'));
|
||||
$finalLabel = $today->formatLocalized((string) trans('config.month_and_day', [], $locale));
|
||||
$chartData[$finalLabel] = $finalSum;
|
||||
|
||||
$data = $this->generator->singleSet($piggyBank->name, $chartData);
|
||||
|
@@ -79,6 +79,7 @@ class ReportController extends Controller
|
||||
if ($cache->has()) {
|
||||
return response()->json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
$locale = app('steam')->getLocale();
|
||||
$current = clone $start;
|
||||
$chartData = [];
|
||||
/** @var NetWorthInterface $helper */
|
||||
@@ -110,7 +111,7 @@ class ReportController extends Controller
|
||||
/** @var array $netWorthItem */
|
||||
foreach ($result as $netWorthItem) {
|
||||
$currencyId = $netWorthItem['currency']->id;
|
||||
$label = $current->formatLocalized((string) trans('config.month_and_day'));
|
||||
$label = $current->formatLocalized((string) trans('config.month_and_day', [], $locale));
|
||||
if (!isset($chartData[$currencyId])) {
|
||||
$chartData[$currencyId] = [
|
||||
'label' => 'Net worth in ' . $netWorthItem['currency']->name,
|
||||
|
@@ -138,6 +138,7 @@ class TransactionController extends Controller
|
||||
$collector->setTypes([TransactionType::DEPOSIT]);
|
||||
break;
|
||||
case 'transfers':
|
||||
case 'transfer':
|
||||
$collector->setTypes([TransactionType::TRANSFER]);
|
||||
break;
|
||||
}
|
||||
|
@@ -85,17 +85,20 @@ class Controller extends BaseController
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$locale = app('steam')->getLocale();
|
||||
// translations for specific strings:
|
||||
$this->monthFormat = (string) trans('config.month');
|
||||
$this->monthAndDayFormat = (string) trans('config.month_and_day');
|
||||
$this->dateTimeFormat = (string) trans('config.date_time');
|
||||
$this->monthFormat = (string) trans('config.month', [], $locale);
|
||||
$this->monthAndDayFormat = (string) trans('config.month_and_day', [], $locale);
|
||||
$this->dateTimeFormat = (string) trans('config.date_time', [], $locale);
|
||||
|
||||
// get shown-intro-preference:
|
||||
if (auth()->check()) {
|
||||
$language = $this->getLanguage();
|
||||
$language = app('steam')->getLanguage();
|
||||
$locale = app('steam')->getLocale();
|
||||
$page = $this->getPageName();
|
||||
$shownDemo = $this->hasSeenDemo();
|
||||
app('view')->share('language', $language);
|
||||
app('view')->share('locale', $locale);
|
||||
app('view')->share('shownDemo', $shownDemo);
|
||||
app('view')->share('current_route_name', $page);
|
||||
app('view')->share('original_route_name', Route::currentRouteName());
|
||||
|
@@ -126,7 +126,6 @@ class DebugController extends Controller
|
||||
$phpOs = str_replace($search, $replace, PHP_OS);
|
||||
$interface = PHP_SAPI;
|
||||
$now = Carbon::now()->format('Y-m-d H:i:s e');
|
||||
$extensions = implode(', ', get_loaded_extensions());
|
||||
$drivers = implode(', ', DB::availableDrivers());
|
||||
$currentDriver = DB::getDriverName();
|
||||
$userAgent = $request->header('user-agent');
|
||||
@@ -143,7 +142,7 @@ class DebugController extends Controller
|
||||
// set languages, see what happens:
|
||||
$original = setlocale(LC_ALL, 0);
|
||||
$localeAttempts = [];
|
||||
$parts = explode(',', (string) trans('config.locale'));
|
||||
$parts = app('steam')->getLocaleArray(app('steam')->getLocale());
|
||||
foreach ($parts as $code) {
|
||||
$code = trim($code);
|
||||
$localeAttempts[$code] = var_export(setlocale(LC_ALL, $code), true);
|
||||
@@ -178,7 +177,6 @@ class DebugController extends Controller
|
||||
'debug',
|
||||
compact(
|
||||
'phpVersion',
|
||||
'extensions',
|
||||
'localeAttempts',
|
||||
'appEnv',
|
||||
'appDebug',
|
||||
|
@@ -126,7 +126,7 @@ class JavascriptController extends Controller
|
||||
/** @noinspection NullPointerExceptionInspection */
|
||||
$lang = $pref->data;
|
||||
$dateRange = $this->getDateRangeConfig();
|
||||
$uid = substr(hash('sha256', auth()->user()->id . auth()->user()->email), 0, 12);
|
||||
$uid = substr(hash('sha256', sprintf('%s-%s-%s', (string) config('app.key'), auth()->user()->id, auth()->user()->email)), 0, 12);
|
||||
|
||||
$data = [
|
||||
'currencyCode' => $currency->code,
|
||||
|
@@ -263,7 +263,7 @@ class BoxController extends Controller
|
||||
*/
|
||||
public function netWorth(): JsonResponse
|
||||
{
|
||||
$date = Carbon::now()->startOfDay();
|
||||
$date = Carbon::now()->endOfDay();
|
||||
|
||||
// start and end in the future? use $end
|
||||
if ($this->notInSessionRange($date)) {
|
||||
|
@@ -63,7 +63,7 @@ class BudgetController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.budgets'));
|
||||
app('view')->share('mainTitleIcon', 'fa-tasks');
|
||||
app('view')->share('mainTitleIcon', 'fa-pie-chart');
|
||||
$this->repository = app(BudgetRepositoryInterface::class);
|
||||
$this->opsRepository = app(OperationsRepositoryInterface::class);
|
||||
$this->abRepository = app(AvailableBudgetRepositoryInterface::class);
|
||||
|
@@ -151,6 +151,7 @@ class RecurrenceController extends Controller
|
||||
$today = Carbon::now()->startOfDay();
|
||||
$date = Carbon::createFromFormat('Y-m-d', $string)->startOfDay();
|
||||
$preSelected = (string) $request->get('pre_select');
|
||||
$locale = app('steam')->getLocale();
|
||||
|
||||
Log::debug(sprintf('date = %s, today = %s. date > today? %s', $date->toAtomString(), $today->toAtomString(), var_export($date > $today, true)));
|
||||
Log::debug(sprintf('past = true? %s', var_export('true' === (string) $request->get('past'), true)));
|
||||
@@ -163,7 +164,7 @@ class RecurrenceController extends Controller
|
||||
$dayOfWeek = (string) trans(sprintf('config.dow_%s', $date->dayOfWeekIso));
|
||||
$ndom = sprintf('ndom,%s,%s', $date->weekOfMonth, $date->dayOfWeekIso);
|
||||
$yearly = sprintf('yearly,%s', $date->format('Y-m-d'));
|
||||
$yearlyDate = $date->formatLocalized((string) trans('config.month_and_day_no_year'));
|
||||
$yearlyDate = $date->formatLocalized((string) trans('config.month_and_day_no_year', [], $locale));
|
||||
$result = [
|
||||
'daily' => ['label' => (string) trans('firefly.recurring_daily'), 'selected' => 0 === strpos($preSelected, 'daily')],
|
||||
$weekly => ['label' => (string) trans('firefly.recurring_weekly', ['weekday' => $dayOfWeek]),
|
||||
|
@@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use FireflyIII\Http\Requests\NewUserFormRequest;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Controllers\CreateStuff;
|
||||
@@ -110,6 +111,12 @@ class NewUserController extends Controller
|
||||
|
||||
// store currency preference:
|
||||
app('preferences')->set('currencyPreference', $currency->code);
|
||||
|
||||
// store frontpage preferences:
|
||||
$accounts = $this->repository->getAccountsByType([AccountType::ASSET])->pluck('id')->toArray();
|
||||
app('preferences')->set('frontPageAccounts', $accounts);
|
||||
|
||||
// mark.
|
||||
app('preferences')->mark();
|
||||
|
||||
// set default optional fields:
|
||||
|
@@ -71,7 +71,7 @@ class PiggyBankController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.piggyBanks'));
|
||||
app('view')->share('mainTitleIcon', 'fa-sort-amount-asc');
|
||||
app('view')->share('mainTitleIcon', 'fa-bullseye');
|
||||
|
||||
$this->attachments = app(AttachmentHelperInterface::class);
|
||||
$this->piggyRepos = app(PiggyBankRepositoryInterface::class);
|
||||
|
@@ -31,6 +31,7 @@ use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Redirector;
|
||||
use Illuminate\View\View;
|
||||
use JsonException;
|
||||
|
||||
/**
|
||||
* Class PreferencesController.
|
||||
@@ -90,8 +91,9 @@ class PreferencesController extends Controller
|
||||
|
||||
$viewRange = $viewRangePref->data;
|
||||
$frontPageAccounts = app('preferences')->get('frontPageAccounts', $accountIds);
|
||||
$language = app('preferences')->get('language', config('firefly.default_language', 'en_US'))->data;
|
||||
$language = app('steam')->getLanguage();
|
||||
$languages = config('firefly.languages');
|
||||
$locale = app('preferences')->get('locale', config('firefly.default_locale', 'equal'))->data;
|
||||
$listPageSize = app('preferences')->get('listPageSize', 50)->data;
|
||||
$customFiscalYear = app('preferences')->get('customFiscalYear', 0)->data;
|
||||
$fiscalYearStartStr = app('preferences')->get('fiscalYearStart', '01-01')->data;
|
||||
@@ -100,6 +102,15 @@ class PreferencesController extends Controller
|
||||
|
||||
ksort($languages);
|
||||
|
||||
// list of locales also has "equal" which makes it equal to whatever the language is.
|
||||
|
||||
try {
|
||||
$locales = json_decode(file_get_contents(resource_path(sprintf('lang/%s/locales.json', $language))), true, 512, JSON_THROW_ON_ERROR);
|
||||
} catch (JsonException $e) {
|
||||
Log::error($e->getMessage());
|
||||
$locales = [];
|
||||
}
|
||||
$locales = ['equal' => (string) trans('firefly.equal_to_language')] + $locales;
|
||||
// an important fallback is that the frontPageAccount array gets refilled automatically
|
||||
// when it turns up empty.
|
||||
if (0 === count($frontPageAccounts->data)) {
|
||||
@@ -113,6 +124,8 @@ class PreferencesController extends Controller
|
||||
'groupedAccounts',
|
||||
'frontPageAccounts',
|
||||
'languages',
|
||||
'locales',
|
||||
'locale',
|
||||
'tjOptionalFields',
|
||||
'viewRange',
|
||||
'customFiscalYear',
|
||||
@@ -172,6 +185,11 @@ class PreferencesController extends Controller
|
||||
session()->flash('info', 'All translations are supplied by volunteers. There might be errors and mistakes. I appreciate your feedback.');
|
||||
}
|
||||
|
||||
// same for locale:
|
||||
/** @var Preference $currentLocale */
|
||||
$locale = $request->get('locale');
|
||||
app('preferences')->set('locale', $locale);
|
||||
|
||||
// optional fields for transactions:
|
||||
$setOptions = $request->get('tj');
|
||||
$optionalTj = [
|
||||
|
@@ -555,7 +555,7 @@ class ProfileController extends Controller
|
||||
/** @var string $match */
|
||||
$match = null;
|
||||
foreach ($set as $entry) {
|
||||
$hashed = hash('sha256', $entry->data);
|
||||
$hashed = hash('sha256', sprintf('%s%s', (string) config('app.key'), $entry->data));
|
||||
if ($hashed === $hash) {
|
||||
$match = $entry->data;
|
||||
break;
|
||||
|
@@ -110,8 +110,13 @@ class IndexController extends Controller
|
||||
$array['first_date'] = new Carbon($array['first_date']);
|
||||
$array['repeat_until'] = null === $array['repeat_until'] ? null : new Carbon($array['repeat_until']);
|
||||
$array['latest_date'] = null === $array['latest_date'] ? null : new Carbon($array['latest_date']);
|
||||
$array['occurrences'] = array_slice($this->recurring->getOccurrencesInRange($recurrence->recurrenceRepetitions->first(), $today, $year), 0, 1);
|
||||
$recurring[] = $array;
|
||||
$array['occurrences'] = [];
|
||||
|
||||
if (0 !== $recurrence->recurrenceRepetitions->count()) {
|
||||
$array['ocurrences'] = array_slice($this->recurring->getOccurrencesInRange($recurrence->recurrenceRepetitions->first(), $today, $year), 0, 1);
|
||||
}
|
||||
|
||||
$recurring[] = $array;
|
||||
}
|
||||
$paginator = new LengthAwarePaginator($recurring, $total, $pageSize, $page);
|
||||
$paginator->setPath(route('recurring.index'));
|
||||
|
@@ -301,7 +301,6 @@ class BudgetController extends Controller
|
||||
$report[$budgetId]['currencies'][$currencyId]['sum_pct'] = $pct;
|
||||
}
|
||||
}
|
||||
|
||||
return view('reports.budget.partials.budgets', compact('sums', 'report'));
|
||||
}
|
||||
|
||||
@@ -317,6 +316,7 @@ class BudgetController extends Controller
|
||||
*/
|
||||
public function general(Collection $accounts, Carbon $start, Carbon $end)
|
||||
{
|
||||
|
||||
$report = [
|
||||
'budgets' => [],
|
||||
'sums' => [],
|
||||
@@ -488,6 +488,7 @@ class BudgetController extends Controller
|
||||
foreach ($expenses as $currency) {
|
||||
foreach ($currency['budgets'] as $budget) {
|
||||
$count = 0;
|
||||
$total = '0';
|
||||
foreach ($budget['transaction_journals'] as $journal) {
|
||||
$count++;
|
||||
$key = sprintf('%d-%d', $budget['id'], $currency['currency_id']);
|
||||
@@ -506,7 +507,7 @@ class BudgetController extends Controller
|
||||
$report[$key]['entries'][$dateKey] = $report[$key] ['entries'][$dateKey] ?? '0';
|
||||
$report[$key]['entries'][$dateKey] = bcadd($journal['amount'], $report[$key] ['entries'][$dateKey]);
|
||||
$report[$key]['sum'] = bcadd($report[$key] ['sum'], $journal['amount']);
|
||||
$report[$key]['avg'] = bcdiv($report[$key]['sum'], (string) $count);
|
||||
$report[$key]['avg'] = bcdiv($report[$key]['sum'], (string) count($periods));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -64,7 +64,7 @@ class ReportController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.reports'));
|
||||
app('view')->share('mainTitleIcon', 'fa-line-chart');
|
||||
app('view')->share('mainTitleIcon', 'fa-bar-chart');
|
||||
app('view')->share('subTitleIcon', 'fa-calendar');
|
||||
$this->helper = app(ReportHelperInterface::class);
|
||||
$this->repository = app(BudgetRepositoryInterface::class);
|
||||
|
@@ -41,6 +41,7 @@ class CronController
|
||||
{
|
||||
$results = [];
|
||||
$results[] = $this->runRecurring();
|
||||
$results[] = $this->runAutoBudget();
|
||||
|
||||
return implode("<br>\n", $results);
|
||||
}
|
||||
|
@@ -60,7 +60,7 @@ class TagController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.tags'));
|
||||
app('view')->share('mainTitleIcon', 'fa-tags');
|
||||
app('view')->share('mainTitleIcon', 'fa-tag');
|
||||
|
||||
$this->attachments = app(AttachmentHelperInterface::class);
|
||||
$this->repository = app(TagRepositoryInterface::class);
|
||||
|
@@ -56,7 +56,7 @@ class BulkController extends Controller
|
||||
function ($request, $next) {
|
||||
$this->repository = app(JournalRepositoryInterface::class);
|
||||
app('view')->share('title', (string) trans('firefly.transactions'));
|
||||
app('view')->share('mainTitleIcon', 'fa-repeat');
|
||||
app('view')->share('mainTitleIcon', 'fa-exchange');
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -206,9 +206,9 @@ class ConvertController extends Controller
|
||||
|
||||
// double check its not an empty string.
|
||||
$sourceId = '' === $sourceId || null === $sourceId ? null : (int) $sourceId;
|
||||
$sourceName = '' === $sourceName ? null : $sourceName;
|
||||
$sourceName = '' === $sourceName ? null : (string) $sourceName;
|
||||
$destinationId = '' === $destinationId || null === $destinationId ? null : (int) $destinationId;
|
||||
$destinationName = (string)('' === $destinationName ? null : $destinationName);
|
||||
$destinationName = '' === $destinationName ? null : (string) $destinationName;
|
||||
$validSource = $validator->validateSource($sourceId, $sourceName, null);
|
||||
$validDestination = $validator->validateDestination($destinationId, $destinationName, null);
|
||||
|
||||
|
@@ -49,7 +49,7 @@ class CreateController extends Controller
|
||||
$this->middleware(
|
||||
static function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.transactions'));
|
||||
app('view')->share('mainTitleIcon', 'fa-repeat');
|
||||
app('view')->share('mainTitleIcon', 'fa-exchange');
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -56,7 +56,7 @@ class DeleteController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.transactions'));
|
||||
app('view')->share('mainTitleIcon', 'fa-repeat');
|
||||
app('view')->share('mainTitleIcon', 'fa-exchange');
|
||||
|
||||
$this->repository = app(TransactionGroupRepositoryInterface::class);
|
||||
|
||||
|
@@ -52,7 +52,7 @@ class EditController extends Controller
|
||||
static function ($request, $next) {
|
||||
|
||||
app('view')->share('title', (string) trans('firefly.transactions'));
|
||||
app('view')->share('mainTitleIcon', 'fa-repeat');
|
||||
app('view')->share('mainTitleIcon', 'fa-exchange');
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -56,8 +56,8 @@ class IndexController extends Controller
|
||||
// translations:
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('mainTitleIcon', 'fa-credit-card');
|
||||
app('view')->share('title', (string) trans('firefly.accounts'));
|
||||
app('view')->share('mainTitleIcon', 'fa-exchange');
|
||||
app('view')->share('title', (string) trans('firefly.transactions'));
|
||||
|
||||
$this->repository = app(JournalRepositoryInterface::class);
|
||||
|
||||
@@ -88,7 +88,9 @@ class IndexController extends Controller
|
||||
$end = session('end');
|
||||
}
|
||||
if (null === $end) {
|
||||
$end = session('end'); // @codeCoverageIgnore
|
||||
// get last transaction ever?
|
||||
$last = $this->repository->getLast();
|
||||
$end = $last ? $last->date : session('end');
|
||||
}
|
||||
|
||||
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
|
||||
@@ -134,14 +136,15 @@ class IndexController extends Controller
|
||||
$repository = app(JournalRepositoryInterface::class);
|
||||
|
||||
|
||||
$subTitleIcon = config('firefly.transactionIconsByWhat.' . $objectType);
|
||||
$types = config('firefly.transactionTypesByWhat.' . $objectType);
|
||||
$subTitleIcon = config('firefly.transactionIconsByType.' . $objectType);
|
||||
$types = config('firefly.transactionTypesByType.' . $objectType);
|
||||
$page = (int) $request->get('page');
|
||||
$pageSize = (int) app('preferences')->get('listPageSize', 50)->data;
|
||||
$path = route('transactions.index.all', [$objectType]);
|
||||
$first = $repository->firstNull();
|
||||
$start = null === $first ? new Carbon : $first->date;
|
||||
$end = new Carbon;
|
||||
$last = $this->repository->getLast();
|
||||
$end = $last ? $last->date : new Carbon;
|
||||
$subTitle = (string) trans('firefly.all_' . $objectType);
|
||||
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
|
@@ -57,7 +57,7 @@ class LinkController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.transactions'));
|
||||
app('view')->share('mainTitleIcon', 'fa-repeat');
|
||||
app('view')->share('mainTitleIcon', 'fa-exchange');
|
||||
|
||||
$this->journalRepository = app(JournalRepositoryInterface::class);
|
||||
$this->repository = app(LinkTypeRepositoryInterface::class);
|
||||
|
@@ -62,7 +62,7 @@ class MassController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.transactions'));
|
||||
app('view')->share('mainTitleIcon', 'fa-repeat');
|
||||
app('view')->share('mainTitleIcon', 'fa-exchange');
|
||||
$this->repository = app(JournalRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
|
@@ -26,6 +26,7 @@ use App;
|
||||
use Carbon\Carbon;
|
||||
use Closure;
|
||||
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Controllers\RequestInformation;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/**
|
||||
@@ -33,6 +34,7 @@ use Illuminate\Http\Request;
|
||||
*/
|
||||
class Range
|
||||
{
|
||||
use RequestInformation;
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
@@ -72,16 +74,16 @@ class Range
|
||||
*/
|
||||
private function configureView(): void
|
||||
{
|
||||
$pref = app('preferences')->get('language', config('firefly.default_language', 'en_US'));
|
||||
/** @noinspection NullPointerExceptionInspection */
|
||||
$lang = $pref->data;
|
||||
App::setLocale($lang);
|
||||
Carbon::setLocale(substr($lang, 0, 2));
|
||||
$locale = explode(',', (string) trans('config.locale'));
|
||||
$locale = array_map('trim', $locale);
|
||||
// get locale preference:
|
||||
$language = app('steam')->getLanguage();
|
||||
$locale = app('steam')->getLocale();
|
||||
App::setLocale($language);
|
||||
Carbon::setLocale(substr($locale, 0, 2));
|
||||
|
||||
setlocale(LC_TIME, $locale);
|
||||
$moneyResult = setlocale(LC_MONETARY, $locale);
|
||||
$localeArray = app('steam')->getLocaleArray($locale);
|
||||
|
||||
setlocale(LC_TIME, $localeArray);
|
||||
$moneyResult = setlocale(LC_MONETARY, $localeArray);
|
||||
|
||||
// send error to view if could not set money format
|
||||
if (false === $moneyResult) {
|
||||
@@ -89,12 +91,12 @@ class Range
|
||||
}
|
||||
|
||||
// save some formats:
|
||||
$monthAndDayFormat = (string) trans('config.month_and_day');
|
||||
$dateTimeFormat = (string) trans('config.date_time');
|
||||
$monthAndDayFormat = (string) trans('config.month_and_day', [], $locale);
|
||||
$dateTimeFormat = (string) trans('config.date_time', [], $locale);
|
||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
||||
|
||||
// also format for moment JS:
|
||||
$madMomentJS = (string) trans('config.month_and_day_moment_js');
|
||||
$madMomentJS = (string) trans('config.month_and_day_moment_js', [], $locale);
|
||||
|
||||
app('view')->share('madMomentJS', $madMomentJS);
|
||||
app('view')->share('monthAndDayFormat', $monthAndDayFormat);
|
||||
|
@@ -58,7 +58,7 @@ class SecureHeaders
|
||||
"base-uri 'self'",
|
||||
"font-src 'self' data:",
|
||||
"connect-src 'self'",
|
||||
sprintf("img-src 'self' data: https://api.tiles.mapbox.com %s", $trackingScriptSrc),
|
||||
sprintf("img-src 'self' data: https://a.tile.openstreetmap.org https://b.tile.openstreetmap.org https://c.tile.openstreetmap.org https://api.tiles.mapbox.com %s", $trackingScriptSrc),
|
||||
"manifest-src 'self'",
|
||||
];
|
||||
|
||||
|
@@ -68,7 +68,7 @@ class BudgetFormStoreRequest extends Request
|
||||
'name' => 'required|between:1,100|uniqueObjectForUser:budgets,name',
|
||||
'active' => 'numeric|between:0,1',
|
||||
'auto_budget_type' => 'numeric|between:0,2',
|
||||
'auto_budget_currency_id' => 'required|exists:transaction_currencies,id',
|
||||
'auto_budget_currency_id' => 'exists:transaction_currencies,id',
|
||||
'auto_budget_amount' => 'min:0|max:1000000000',
|
||||
'auto_budget_period' => 'in:daily,weekly,monthly,quarterly,half_year,yearly',
|
||||
];
|
||||
|
@@ -78,7 +78,7 @@ class BudgetFormUpdateRequest extends Request
|
||||
'name' => $nameRule,
|
||||
'active' => 'numeric|between:0,1',
|
||||
'auto_budget_option' => 'numeric|between:0,2',
|
||||
'auto_budget_currency_id' => 'required|exists:transaction_currencies,id',
|
||||
'auto_budget_currency_id' => 'exists:transaction_currencies,id',
|
||||
'auto_budget_amount' => 'min:0|max:1000000000',
|
||||
'auto_budget_period' => 'in:daily,weekly,monthly,quarterly,half_year,yearly',
|
||||
];
|
||||
|
@@ -53,7 +53,7 @@ class PiggyBankFormRequest extends Request
|
||||
'account_id' => $this->integer('account_id'),
|
||||
'targetamount' => $this->string('targetamount'),
|
||||
'targetdate' => $this->date('targetdate'),
|
||||
'notes' => $this->string('notes'),
|
||||
'notes' => $this->nlString('notes'),
|
||||
];
|
||||
}
|
||||
|
||||
|
@@ -50,7 +50,7 @@ class ProfileFormRequest extends Request
|
||||
// fixed
|
||||
return [
|
||||
'current_password' => 'required',
|
||||
'new_password' => 'required|confirmed|secure_password',
|
||||
'new_password' => 'required|confirmed|secure_password|min:16',
|
||||
'new_password_confirmation' => 'required',
|
||||
];
|
||||
}
|
||||
|
@@ -297,8 +297,9 @@ class Request extends FormRequest
|
||||
$latitudeKey = $this->getLocationKey($prefix, 'latitude');
|
||||
$zoomLevelKey = $this->getLocationKey($prefix, 'zoom_level');
|
||||
$hasLocationKey = $this->getLocationKey($prefix, 'has_location');
|
||||
$hasLocation = $this->boolean($hasLocationKey);
|
||||
|
||||
// for a POST (store, all fields must be present and accounted for:
|
||||
// for a POST (store), all fields must be present and accounted for:
|
||||
if (
|
||||
('POST' === $this->method() && $this->routeIs('*.store'))
|
||||
&& ($this->has($longitudeKey) && $this->has($latitudeKey) && $this->has($zoomLevelKey))
|
||||
@@ -322,12 +323,14 @@ class Request extends FormRequest
|
||||
$data['latitude'] = $this->nullableString($latitudeKey);
|
||||
$data['zoom_level'] = $this->nullableString($zoomLevelKey);
|
||||
}
|
||||
if (null === $data['longitude'] || null === $data['latitude'] || null === $data['zoom_level']) {
|
||||
Log::debug('One of the fields is NULL, wont save.');
|
||||
if (false === $hasLocation || null === $data['longitude'] || null === $data['latitude'] || null === $data['zoom_level']) {
|
||||
Log::debug('One of the fields is NULL or hasLocation is false, wont save.');
|
||||
$data['store_location'] = false;
|
||||
$data['update_location'] = false;
|
||||
$data['update_location'] = true; // update is always true, but the values are null:
|
||||
$data['longitude'] = null;
|
||||
$data['latitude'] = null;
|
||||
$data['zoom_level'] = null;
|
||||
}
|
||||
|
||||
Log::debug(sprintf('Returning longitude: "%s", latitude: "%s", zoom level: "%s"', $data['longitude'], $data['latitude'], $data['zoom_level']));
|
||||
|
||||
return $data;
|
||||
|
@@ -94,12 +94,6 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
* @property-read int|null $notes_count
|
||||
* @property-read int|null $piggy_banks_count
|
||||
* @property-read int|null $transactions_count
|
||||
* @property \Illuminate\Support\Carbon|null $created_at
|
||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||
* @property int $account_type_id
|
||||
* @property bool $encrypted
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\AccountMeta[] $accountMeta
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\PiggyBank[] $piggyBanks
|
||||
*/
|
||||
class Account extends Model
|
||||
{
|
||||
@@ -258,7 +252,11 @@ class Account extends Model
|
||||
*/
|
||||
public function setVirtualBalanceAttribute($value): void
|
||||
{
|
||||
$this->attributes['virtual_balance'] = (string) $value;
|
||||
$value = (string)$value;
|
||||
if('' === $value) {
|
||||
$value = null;
|
||||
}
|
||||
$this->attributes['virtual_balance'] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -83,7 +83,7 @@ class AccountMeta extends Model
|
||||
*/
|
||||
public function getDataAttribute($value)
|
||||
{
|
||||
return json_decode($value);
|
||||
return json_decode($value, true, 512, JSON_THROW_ON_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -77,6 +77,10 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
* @property-read int|null $budgetlimits_count
|
||||
* @property-read int|null $transaction_journals_count
|
||||
* @property-read int|null $transactions_count
|
||||
* @property \Illuminate\Support\Carbon|null $created_at
|
||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||
* @property bool $encrypted
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\BudgetLimit[] $budgetlimits
|
||||
*/
|
||||
class Budget extends Model
|
||||
{
|
||||
|
@@ -78,7 +78,6 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
* @property-read int|null $notes_count
|
||||
* @property-read int|null $piggy_bank_events_count
|
||||
* @property-read int|null $piggy_bank_repetitions_count
|
||||
* @property bool $encrypted
|
||||
*/
|
||||
class PiggyBank extends Model
|
||||
{
|
||||
|
@@ -78,13 +78,6 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|Location[] $locations
|
||||
* @property-read int|null $locations_count
|
||||
* @property-read int|null $transaction_journals_count
|
||||
* @property \Illuminate\Support\Carbon|null $created_at
|
||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||
* @property string $tagMode
|
||||
* @property string|null $description
|
||||
* @property float|null $latitude
|
||||
* @property float|null $longitude
|
||||
* @property int|null $zoomLevel
|
||||
*/
|
||||
class Tag extends Model
|
||||
{
|
||||
|
@@ -48,7 +48,7 @@ use FireflyIII\Services\FireflyIIIOrg\Update\UpdateRequest;
|
||||
use FireflyIII\Services\FireflyIIIOrg\Update\UpdateRequestInterface;
|
||||
use FireflyIII\Services\IP\IpifyOrg;
|
||||
use FireflyIII\Services\IP\IPRetrievalInterface;
|
||||
use FireflyIII\Services\Password\PwndVerifierV3;
|
||||
use FireflyIII\Services\Password\PwndVerifierV2;
|
||||
use FireflyIII\Services\Password\Verifier;
|
||||
use FireflyIII\Support\Amount;
|
||||
use FireflyIII\Support\ExpandedForm;
|
||||
@@ -189,7 +189,7 @@ class FireflyServiceProvider extends ServiceProvider
|
||||
$this->app->bind(ExchangeRateInterface::class, $class);
|
||||
|
||||
// password verifier thing
|
||||
$this->app->bind(Verifier::class, PwndVerifierV3::class);
|
||||
$this->app->bind(Verifier::class, PwndVerifierV2::class);
|
||||
|
||||
// IP thing:
|
||||
$this->app->bind(IPRetrievalInterface::class, IpifyOrg::class);
|
||||
|
@@ -79,6 +79,8 @@ class BudgetRepository implements BudgetRepositoryInterface
|
||||
$budget->order = $index + 1;
|
||||
$budget->save();
|
||||
}
|
||||
// other budgets, set to 0.
|
||||
$this->user->budgets()->where('active', 0)->update(['order' => 0]);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -187,12 +189,12 @@ class BudgetRepository implements BudgetRepositoryInterface
|
||||
*/
|
||||
public function getActiveBudgets(): Collection
|
||||
{
|
||||
//throw new \RuntimeException;
|
||||
/** @var Collection $set */
|
||||
$set = $this->user->budgets()->where('active', 1)
|
||||
->orderBy('order', 'DESC')
|
||||
->orderBy('order', 'ASC')
|
||||
->orderBy('name', 'ASC')
|
||||
->get();
|
||||
|
||||
return $set;
|
||||
}
|
||||
|
||||
@@ -202,7 +204,7 @@ class BudgetRepository implements BudgetRepositoryInterface
|
||||
public function getBudgets(): Collection
|
||||
{
|
||||
/** @var Collection $set */
|
||||
$set = $this->user->budgets()->orderBy('order', 'DESC')
|
||||
$set = $this->user->budgets()->orderBy('order', 'ASC')
|
||||
->orderBy('name', 'ASC')->get();
|
||||
|
||||
return $set;
|
||||
@@ -227,7 +229,7 @@ class BudgetRepository implements BudgetRepositoryInterface
|
||||
{
|
||||
/** @var Collection $set */
|
||||
$set = $this->user->budgets()
|
||||
->orderBy('order', 'DESC')
|
||||
->orderBy('order', 'ASC')
|
||||
->orderBy('name', 'ASC')->where('active', 0)->get();
|
||||
|
||||
return $set;
|
||||
@@ -277,11 +279,13 @@ class BudgetRepository implements BudgetRepositoryInterface
|
||||
*/
|
||||
public function store(array $data): Budget
|
||||
{
|
||||
$order = $this->getMaxOrder();
|
||||
try {
|
||||
$newBudget = Budget::create(
|
||||
[
|
||||
'user_id' => $this->user->id,
|
||||
'name' => $data['name'],
|
||||
'order' => $order + 1,
|
||||
]
|
||||
);
|
||||
} catch (QueryException $e) {
|
||||
@@ -487,4 +491,9 @@ class BudgetRepository implements BudgetRepositoryInterface
|
||||
{
|
||||
return $budget->attachments()->get();
|
||||
}
|
||||
|
||||
public function getMaxOrder(): int
|
||||
{
|
||||
return (int)$this->user->budgets()->max('order');
|
||||
}
|
||||
}
|
||||
|
@@ -58,6 +58,11 @@ interface BudgetRepositoryInterface
|
||||
*/
|
||||
public function destroyAutoBudget(Budget $budget): void;
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getMaxOrder(): int;
|
||||
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
|
@@ -384,7 +384,7 @@ class ImportJobRepository implements ImportJobRepositoryInterface
|
||||
$attachment = new Attachment; // create Attachment object.
|
||||
$attachment->user()->associate($job->user);
|
||||
$attachment->attachable()->associate($job);
|
||||
$attachment->md5 = md5($content);
|
||||
$attachment->md5 = substr(hash('sha256', $content), 0, 32); // limit due to DB.
|
||||
$attachment->filename = $name;
|
||||
$attachment->mime = 'plain/txt';
|
||||
$attachment->size = strlen($content);
|
||||
|
@@ -407,4 +407,19 @@ class JournalRepository implements JournalRepositoryInterface
|
||||
|
||||
return $transaction->account;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TransactionJournal|null
|
||||
*/
|
||||
public function getLast(): ?TransactionJournal
|
||||
{
|
||||
/** @var TransactionJournal $entry */
|
||||
$entry = $this->user->transactionJournals()->orderBy('date', 'DESC')->first(['transaction_journals.*']);
|
||||
$result = null;
|
||||
if (null !== $entry) {
|
||||
$result = $entry;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
@@ -37,6 +37,10 @@ use Illuminate\Support\Collection;
|
||||
*/
|
||||
interface JournalRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* @return TransactionJournal|null
|
||||
*/
|
||||
public function getLast(): ?TransactionJournal;
|
||||
|
||||
/**
|
||||
* TODO maybe create JSON repository?
|
||||
@@ -44,6 +48,7 @@ interface JournalRepositoryInterface
|
||||
* Search in journal descriptions.
|
||||
*
|
||||
* @param string $search
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function searchJournalDescriptions(string $search): Collection;
|
||||
|
@@ -142,6 +142,9 @@ trait ModifiesPiggyBanks
|
||||
*/
|
||||
public function createEvent(PiggyBank $piggyBank, string $amount): PiggyBankEvent
|
||||
{
|
||||
if (0 === bccomp('0', $amount)) {
|
||||
return new PiggyBankEvent;
|
||||
}
|
||||
/** @var PiggyBankEvent $event */
|
||||
$event = PiggyBankEvent::create(['date' => Carbon::now(), 'amount' => $amount, 'piggy_bank_id' => $piggyBank->id]);
|
||||
|
||||
@@ -219,11 +222,12 @@ trait ModifiesPiggyBanks
|
||||
if (1 === bccomp($amount, $max)) {
|
||||
$amount = $max;
|
||||
}
|
||||
$difference = bcsub($amount, $repetition->currentamount);
|
||||
$repetition->currentamount = $amount;
|
||||
$repetition->save();
|
||||
|
||||
// create event
|
||||
$this->createEvent($piggyBank, $amount);
|
||||
$this->createEvent($piggyBank, $difference);
|
||||
|
||||
return $piggyBank;
|
||||
}
|
||||
@@ -343,4 +347,4 @@ trait ModifiesPiggyBanks
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -237,7 +237,6 @@ trait AccountServiceTrait
|
||||
Log::error($e->getMessage());
|
||||
Log::error($e->getTraceAsString());
|
||||
}
|
||||
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
return $group;
|
||||
|
@@ -345,6 +345,7 @@ trait JournalServiceTrait
|
||||
*/
|
||||
private function createAccount(?Account $account, array $data, string $preferredType): Account
|
||||
{
|
||||
Log::debug('Now in createAccount()', $data);
|
||||
// return new account.
|
||||
if (null === $account) {
|
||||
$data['name'] = $data['name'] ?? '(no name)';
|
||||
@@ -359,8 +360,10 @@ trait JournalServiceTrait
|
||||
'account_type_id' => null,
|
||||
'account_type' => $preferredType,
|
||||
'name' => $data['name'],
|
||||
'virtual_balance' => null,
|
||||
'active' => true,
|
||||
'iban' => $data['iban'],
|
||||
'currency_id' => $data['currency_id'] ?? null,
|
||||
]
|
||||
);
|
||||
// store BIC
|
||||
@@ -375,6 +378,7 @@ trait JournalServiceTrait
|
||||
$metaFactory = app(AccountMetaFactory::class);
|
||||
$metaFactory->create(['account_id' => $account->id, 'name' => 'account_number', 'data' => $data['bic']]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $account;
|
||||
|
@@ -58,8 +58,11 @@ class PwndVerifierV2 implements Verifier
|
||||
$rest = substr($hash, 5);
|
||||
$uri = sprintf('https://api.pwnedpasswords.com/range/%s', $prefix);
|
||||
$opt = [
|
||||
'headers' => ['User-Agent' => 'Firefly III v' . config('firefly.version')],
|
||||
'timeout' => 5];
|
||||
'headers' => [
|
||||
'User-Agent' => 'Firefly III v' . config('firefly.version'),
|
||||
'Add-Padding' => 'true',
|
||||
],
|
||||
'timeout' => 3.1415];
|
||||
|
||||
Log::debug(sprintf('hash prefix is %s', $prefix));
|
||||
Log::debug(sprintf('rest is %s', $rest));
|
||||
@@ -87,7 +90,7 @@ class PwndVerifierV2 implements Verifier
|
||||
|
||||
return true;
|
||||
}
|
||||
Log::debug(sprintf('Could not find %s, return FALSE.', $rest));
|
||||
Log::debug(sprintf('Found %s, return FALSE.', $rest));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@@ -1,96 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* PwndVerifierV3.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Services\Password;
|
||||
|
||||
|
||||
use Exception;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use Log;
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* Class PwndVerifierV3
|
||||
* @codeCoverageIgnore
|
||||
* @codeCoverageIgnore
|
||||
* @deprecated
|
||||
*/
|
||||
class PwndVerifierV3 implements Verifier
|
||||
{
|
||||
|
||||
/**
|
||||
* Verify the given password against (some) service.
|
||||
*
|
||||
* @param string $password
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function validPassword(string $password): bool
|
||||
{
|
||||
Log::debug('Now in API v3.');
|
||||
$hash = strtoupper(sha1($password));
|
||||
$prefix = substr($hash, 0, 5);
|
||||
$rest = substr($hash, 5);
|
||||
$uri = sprintf('https://api.pwnedpasswords.com/%s/%s', 'range', $prefix);
|
||||
|
||||
Log::debug(sprintf('URI is %s', $uri));
|
||||
|
||||
$headers = [
|
||||
'User-Agent' => sprintf('Firefly III v%s', config('firefly.version')),
|
||||
];
|
||||
Log::debug('Headers', $headers);
|
||||
$opts = [
|
||||
'headers' => $headers,
|
||||
'timeout' => 5,
|
||||
];
|
||||
|
||||
Log::debug(sprintf('hash prefix is %s', $prefix));
|
||||
Log::debug(sprintf('rest is %s', $rest));
|
||||
|
||||
try {
|
||||
$client = new Client;
|
||||
$res = $client->request('GET', $uri, $opts);
|
||||
} catch (GuzzleException|Exception $e) {
|
||||
Log::error(sprintf('Could not verify password security: %s', $e->getMessage()));
|
||||
return true;
|
||||
}
|
||||
Log::debug(sprintf('Status code returned is %d', $res->getStatusCode()));
|
||||
if (404 === $res->getStatusCode()) {
|
||||
return true;
|
||||
}
|
||||
$body = $res->getBody()->getContents();
|
||||
try {
|
||||
$strpos = stripos($body, $rest);
|
||||
} catch (RuntimeException $e) {
|
||||
Log::error(sprintf('Could not get body from Pwnd result: %s', $e->getMessage()));
|
||||
$strpos = false;
|
||||
}
|
||||
if (false === $strpos) {
|
||||
Log::debug(sprintf('%s was not found in result body. Return true.', $rest));
|
||||
return true;
|
||||
}
|
||||
Log::debug(sprintf('Found %s, so return FALSE.', $rest));
|
||||
return false;
|
||||
}
|
||||
}
|
@@ -325,9 +325,11 @@ class Amount
|
||||
*/
|
||||
public function getLocaleInfo(): array
|
||||
{
|
||||
$locale = explode(',', (string) trans('config.locale'));
|
||||
$locale = array_map('trim', $locale);
|
||||
setlocale(LC_MONETARY, $locale);
|
||||
// get config from preference, not from translation:
|
||||
$locale = app('steam')->getLocale();
|
||||
$array = app('steam')->getLocaleArray($locale);
|
||||
|
||||
setlocale(LC_MONETARY, $array);
|
||||
$info = localeconv();
|
||||
// correct variables
|
||||
$info['n_cs_precedes'] = $this->getLocaleField($info, 'n_cs_precedes');
|
||||
|
@@ -101,8 +101,8 @@ class CacheProperties
|
||||
{
|
||||
$content = '';
|
||||
foreach ($this->properties as $property) {
|
||||
$content .= json_encode($property);
|
||||
$content .= json_encode($property, JSON_THROW_ON_ERROR, 512);
|
||||
}
|
||||
$this->hash = substr(sha1($content), 0, 16);
|
||||
$this->hash = substr(hash('sha256', $content), 0, 16);
|
||||
}
|
||||
}
|
||||
|
@@ -557,7 +557,7 @@ class ExportDataGenerator
|
||||
$recurrence->description,
|
||||
$recurrence->first_date ? $recurrence->first_date->format('Y-m-d') : null,
|
||||
$recurrence->repeat_until ? $recurrence->repeat_until->format('Y-m-d') : null,
|
||||
$recurrence->latest_date ? $recurrence->repeat_until->format('Y-m-d') : null,
|
||||
$recurrence->latest_date ? $recurrence->latest_date->format('Y-m-d') : null,
|
||||
$recurrence->repetitions,
|
||||
$recurrence->apply_rules,
|
||||
$recurrence->active,
|
||||
|
@@ -61,6 +61,7 @@ trait ChartGeneration
|
||||
return $cache->get(); // @codeCoverageIgnore
|
||||
}
|
||||
Log::debug('Regenerate chart.account.account-balance-chart from scratch.');
|
||||
$locale = app('steam')->getLocale();
|
||||
/** @var GeneratorInterface $generator */
|
||||
$generator = app(GeneratorInterface::class);
|
||||
|
||||
@@ -89,7 +90,7 @@ trait ChartGeneration
|
||||
$previous = array_values($range)[0];
|
||||
while ($currentStart <= $end) {
|
||||
$format = $currentStart->format('Y-m-d');
|
||||
$label = $currentStart->formatLocalized((string)trans('config.month_and_day'));
|
||||
$label = $currentStart->formatLocalized((string)trans('config.month_and_day', [], $locale));
|
||||
$balance = isset($range[$format]) ? round($range[$format], 12) : $previous;
|
||||
$previous = $balance;
|
||||
$currentStart->addDay();
|
||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Support\Http\Controllers;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Support\Cronjobs\AutoBudgetCronjob;
|
||||
use FireflyIII\Support\Cronjobs\RecurringCronjob;
|
||||
|
||||
/**
|
||||
@@ -50,4 +51,23 @@ trait CronRunner
|
||||
return 'The recurring transaction cron job fired successfully.';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function runAutoBudget(): string
|
||||
{
|
||||
/** @var AutoBudgetCronjob $autoBudget */
|
||||
$autoBudget = app(AutoBudgetCronjob::class);
|
||||
try {
|
||||
$result = $autoBudget->fire();
|
||||
} catch (FireflyException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
if (false === $result) {
|
||||
return 'The auto budget cron job did not fire.';
|
||||
}
|
||||
|
||||
return 'The auto budget cron job fired successfully.';
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -119,19 +119,6 @@ trait RequestInformation
|
||||
return '<p>' . trans('firefly.route_has_no_help') . '</p>'; // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user's language.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getLanguage(): string // get preference
|
||||
{
|
||||
/** @var string $language */
|
||||
$language = app('preferences')->get('language', config('firefly.default_language', 'en_US'))->data;
|
||||
|
||||
return $language;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of triggers.
|
||||
*
|
||||
@@ -300,7 +287,7 @@ trait RequestInformation
|
||||
$data,
|
||||
[
|
||||
'email' => 'required|string|email|max:255|unique:users',
|
||||
'password' => 'required|string|min:6|secure_password|confirmed',
|
||||
'password' => 'required|string|min:16|secure_password|confirmed',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
@@ -183,30 +183,30 @@ class StageImportDataHandler
|
||||
// transaction data:
|
||||
'transactions' => [
|
||||
[
|
||||
'date' => $transaction->getMadeOn()->format('Y-m-d'),
|
||||
'tags' => $tags,
|
||||
'user' => $this->importJob->user_id,
|
||||
'notes' => $notes,
|
||||
'date' => $transaction->getMadeOn()->format('Y-m-d'),
|
||||
'tags' => $tags,
|
||||
'user' => $this->importJob->user_id,
|
||||
'notes' => trim($notes),
|
||||
|
||||
// all custom fields:
|
||||
'external_id' => (string)$transaction->getId(),
|
||||
'external_id' => (string)$transaction->getId(),
|
||||
|
||||
// journal data:
|
||||
'description' => $transaction->getDescription(),
|
||||
'piggy_bank_id' => null,
|
||||
'piggy_bank_name' => null,
|
||||
'bill_id' => null,
|
||||
'bill_name' => null,
|
||||
'original-source' => sprintf('spectre-v%s', config('firefly.version')),
|
||||
'type' => $type,
|
||||
'currency_id' => null,
|
||||
'currency_code' => $currencyCode,
|
||||
'amount' => $amount,
|
||||
'budget_id' => null,
|
||||
'budget_name' => null,
|
||||
'category_id' => null,
|
||||
'category_name' => $transaction->getCategory(),
|
||||
'source_id' => $source->id,
|
||||
'description' => $transaction->getDescription(),
|
||||
'piggy_bank_id' => null,
|
||||
'piggy_bank_name' => null,
|
||||
'bill_id' => null,
|
||||
'bill_name' => null,
|
||||
'original-source' => sprintf('spectre-v%s', config('firefly.version')),
|
||||
'type' => $type,
|
||||
'currency_id' => null,
|
||||
'currency_code' => $currencyCode,
|
||||
'amount' => $amount,
|
||||
'budget_id' => null,
|
||||
'budget_name' => null,
|
||||
'category_id' => null,
|
||||
'category_name' => $transaction->getCategory(),
|
||||
'source_id' => $source->id,
|
||||
'source_name' => null,
|
||||
'destination_id' => $destination->id,
|
||||
'destination_name' => null,
|
||||
|
@@ -287,10 +287,11 @@ class Navigation
|
||||
*/
|
||||
public function listOfPeriods(Carbon $start, Carbon $end): array
|
||||
{
|
||||
$locale = app('steam')->getLocale();
|
||||
// define period to increment
|
||||
$increment = 'addDay';
|
||||
$format = $this->preferredCarbonFormat($start, $end);
|
||||
$displayFormat = (string)trans('config.month_and_day');
|
||||
$displayFormat = (string)trans('config.month_and_day', [], $locale);
|
||||
// increment by month (for year)
|
||||
if ($start->diffInMonths($end) > 1) {
|
||||
$increment = 'addMonth';
|
||||
@@ -391,13 +392,14 @@ class Navigation
|
||||
*/
|
||||
public function preferredCarbonLocalizedFormat(Carbon $start, Carbon $end): string
|
||||
{
|
||||
$format = (string)trans('config.month_and_day');
|
||||
$locale = app('steam')->getLocale();
|
||||
$format = (string)trans('config.month_and_day', [], $locale);
|
||||
if ($start->diffInMonths($end) > 1) {
|
||||
$format = (string)trans('config.month');
|
||||
$format = (string)trans('config.month', [], $locale);
|
||||
}
|
||||
|
||||
if ($start->diffInMonths($end) > 12) {
|
||||
$format = (string)trans('config.year');
|
||||
$format = (string)trans('config.year', [], $locale);
|
||||
}
|
||||
|
||||
return $format;
|
||||
|
@@ -26,7 +26,6 @@ use Cache;
|
||||
use Exception;
|
||||
use FireflyIII\Models\Preference;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Contracts\Auth\Authenticatable;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
use Session;
|
||||
@@ -200,7 +199,7 @@ class Preferences
|
||||
$lastActivity = implode(',', $lastActivity);
|
||||
}
|
||||
|
||||
return md5($lastActivity);
|
||||
return hash('sha256', $lastActivity);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -70,11 +70,10 @@ class Steam
|
||||
->where('transactions.transaction_currency_id', $currency->id)
|
||||
->get(['transactions.amount'])->toArray();
|
||||
$nativeBalance = $this->sumTransactions($transactions, 'amount');
|
||||
|
||||
// get all balances in foreign currency:
|
||||
$transactions = $account->transactions()
|
||||
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->where('transaction_journals.date', '<=', $date->format('Y-m-d'))
|
||||
->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
|
||||
->where('transactions.foreign_currency_id', $currency->id)
|
||||
->where('transactions.transaction_currency_id', '!=', $currency->id)
|
||||
->get(['transactions.foreign_amount'])->toArray();
|
||||
@@ -585,4 +584,42 @@ class Steam
|
||||
return $amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user's language.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLanguage(): string // get preference
|
||||
{
|
||||
return app('preferences')->get('language', config('firefly.default_language', 'en_US'))->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user's locale.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLocale(): string // get preference
|
||||
{
|
||||
/** @var string $language */
|
||||
$locale = app('preferences')->get('locale', config('firefly.default_locale', 'equal'))->data;
|
||||
if ('equal' === $locale) {
|
||||
return $this->getLanguage();
|
||||
}
|
||||
|
||||
return $locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $locale
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getLocaleArray(string $locale): array {
|
||||
return [
|
||||
sprintf('%s.utf8', $locale),
|
||||
sprintf('%s.UTF-8', $locale),
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -73,7 +73,7 @@ class SetSourceAccount implements ActionInterface
|
||||
$type = $journal->transactionType->type;
|
||||
|
||||
// if this is a transfer or a withdrawal, the new source account must be an asset account or a default account, and it MUST exist:
|
||||
if ((TransactionType::WITHDRAWAL === $type || TransactionType::TRANSFER === $type) && !$this->findAssetAccount()) {
|
||||
if ((TransactionType::WITHDRAWAL === $type || TransactionType::TRANSFER === $type) && !$this->findAssetAccount($type)) {
|
||||
Log::error(
|
||||
sprintf(
|
||||
'Cannot change source account of journal #%d because no asset account with name "%s" exists.',
|
||||
@@ -119,6 +119,10 @@ class SetSourceAccount implements ActionInterface
|
||||
{
|
||||
// switch on type:
|
||||
$allowed = config(sprintf('firefly.expected_source_types.source.%s', $type));
|
||||
$allowed = is_array($allowed) ? $allowed : [];
|
||||
|
||||
Log::debug(sprintf('Check config for expected_source_types.source.%s, result is', $type), $allowed);
|
||||
|
||||
$account = $this->repository->findByName($this->action->action_value, $allowed);
|
||||
|
||||
if (null === $account) {
|
||||
|
@@ -73,8 +73,8 @@ trait TransactionValidation
|
||||
|
||||
// validate source account.
|
||||
$sourceId = isset($transaction['source_id']) ? (int) $transaction['source_id'] : null;
|
||||
$sourceName = $transaction['source_name'] ?? null;
|
||||
$sourceIban = $transaction['source_iban'] ?? null;
|
||||
$sourceName = isset($transaction['source_name']) ? (string) $transaction['source_name'] : null;
|
||||
$sourceIban = isset($transaction['source_iban']) ? (string) $transaction['source_iban'] : null;
|
||||
$validSource = $accountValidator->validateSource($sourceId, $sourceName, $sourceIban);
|
||||
|
||||
// do something with result:
|
||||
@@ -86,8 +86,8 @@ trait TransactionValidation
|
||||
}
|
||||
// validate destination account
|
||||
$destinationId = isset($transaction['destination_id']) ? (int) $transaction['destination_id'] : null;
|
||||
$destinationName = $transaction['destination_name'] ?? null;
|
||||
$destinationIban = $transaction['destination_iban'] ?? null;
|
||||
$destinationName = isset($transaction['destination_name']) ? (string) $transaction['destination_name'] : null;
|
||||
$destinationIban = isset($transaction['destination_iban']) ? (string) $transaction['destination_iban'] : null;
|
||||
$validDestination = $accountValidator->validateDestination($destinationId, $destinationName, $destinationIban);
|
||||
// do something with result:
|
||||
if (false === $validDestination) {
|
||||
|
53
changelog.md
53
changelog.md
@@ -2,8 +2,59 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## [5.2.5 (API 1.1.0)] - 2020-05-04
|
||||
|
||||
## [5.2.0 (API 1.1.0)] - 2020-04-11
|
||||
### Added
|
||||
- Some warnings that custom locales may not work on Windows or in Docker images.
|
||||
|
||||
### Changed
|
||||
- [Issue 3305](https://github.com/firefly-iii/firefly-iii/issues/3305) User [@lguima](https://github.com/lguima) revamped the left side menu and associated icons.
|
||||
|
||||
### Fixed
|
||||
- [Issue 3307](https://github.com/firefly-iii/firefly-iii/issues/3307) Editing or creating accounts would automatically give them a location.
|
||||
- [Issue 3314](https://github.com/firefly-iii/firefly-iii/issues/3314) Future transactions would not always be visible, even when the daterange should include them.
|
||||
- [Issue 3318](https://github.com/firefly-iii/firefly-iii/issues/3318) Cron called over URL would skip auto-budgets.
|
||||
- [Issue 3321](https://github.com/firefly-iii/firefly-iii/issues/3321) API for piggy bank funds would create events with the wrong amount.
|
||||
- [Issue 3330](https://github.com/firefly-iii/firefly-iii/issues/3330) Transactions not stored at 00:00 would be excluded from some views.
|
||||
|
||||
## [5.2.4 (API 1.1.0)] - 2020-04-26
|
||||
|
||||
### Fixed
|
||||
- [Issue 3287](https://github.com/firefly-iii/firefly-iii/issues/3287) Locale issue
|
||||
- [Issue 3251](https://github.com/firefly-iii/firefly-iii/issues/3251) Budget order
|
||||
|
||||
## [5.2.3 (API 1.1.0)] - 2020-04-22
|
||||
|
||||
### Added
|
||||
- Support for British English! 🇬🇧
|
||||
- You can set your locale *and* your language now.
|
||||
|
||||
### Changed
|
||||
- [Issue 3270](https://github.com/firefly-iii/firefly-iii/issues/3270) Wrong average in budget table.
|
||||
|
||||
### Fixed
|
||||
- [Issue 3264](https://github.com/firefly-iii/firefly-iii/issues/3264) Error when exporting recurring transactions
|
||||
- [Issue 3272](https://github.com/firefly-iii/firefly-iii/issues/3272) Rule issue when using "set source account" action.
|
||||
- [Issue 3281](https://github.com/firefly-iii/firefly-iii/issues/3281) Bad markdown parsing in piggy banks.
|
||||
- [Issue 3284](https://github.com/firefly-iii/firefly-iii/issues/3284) Recurring transactions with bad info couldn't be rendered.
|
||||
|
||||
## [5.2.2 (API 1.1.0)] - 2020-04-14
|
||||
|
||||
### Fixed
|
||||
- [Issue 3529](https://github.com/firefly-iii/firefly-iii/issues/3529) Issue with rule execution.
|
||||
- [Issue 3263](https://github.com/firefly-iii/firefly-iii/issues/3263) Issue with new user account creation.
|
||||
|
||||
## [5.2.2 (API 1.1.0)] - 2020-04-13
|
||||
|
||||
### Fixed
|
||||
- Virtual balance would always be stored as "0.0" despite the field being nullable.
|
||||
- The rule action "set source account" was improperly configured.
|
||||
|
||||
## [5.2.1 (API 1.1.0)] - 2020-04-10
|
||||
|
||||
Firefly III 5.2.1 fixes an issue with charts and allows users to store budgets again.
|
||||
|
||||
## [5.2.0 (API 1.1.0)] - 2020-04-10
|
||||
|
||||
- ⚠️ This will be the last version to support PHP version 7.3. The next release will require PHP **7.4**
|
||||
- ⚠️ The bunq and CSV import routines have been disabled and replaced by their stand alone variants: [bunq](https://github.com/firefly-iii/bunq-importer), [CSV](https://github.com/firefly-iii/csv-importer).
|
||||
|
562
composer.lock
generated
562
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -138,7 +138,7 @@ return [
|
||||
],
|
||||
|
||||
'encryption' => null === env('USE_ENCRYPTION') || true === env('USE_ENCRYPTION'),
|
||||
'version' => '5.2.0',
|
||||
'version' => '5.2.5',
|
||||
'api_version' => '1.1.0',
|
||||
'db_version' => 13,
|
||||
'maxUploadSize' => 15242880,
|
||||
@@ -323,7 +323,8 @@ return [
|
||||
*/
|
||||
'languages' => [
|
||||
// currently enabled languages
|
||||
'en_US' => ['name_locale' => 'English', 'name_english' => 'English'],
|
||||
'en_US' => ['name_locale' => 'English (US)', 'name_english' => 'English (US)'],
|
||||
'en_GB' => ['name_locale' => 'English (GB)', 'name_english' => 'English (GB)'],
|
||||
'cs_CZ' => ['name_locale' => 'Czech', 'name_english' => 'Czech'],
|
||||
'el_GR' => ['name_locale' => 'Ελληνικά', 'name_english' => 'Greek'],
|
||||
'es_ES' => ['name_locale' => 'Español', 'name_english' => 'Spanish'],
|
||||
@@ -382,7 +383,7 @@ return [
|
||||
'Opening balance' => 'opening-balance',
|
||||
'Reconciliation' => 'reconciliation',
|
||||
],
|
||||
'transactionIconsByWhat' => [
|
||||
'transactionIconsByType' => [
|
||||
'expenses' => 'fa-long-arrow-left',
|
||||
'withdrawal' => 'fa-long-arrow-left',
|
||||
'revenue' => 'fa-long-arrow-right',
|
||||
@@ -557,6 +558,7 @@ return [
|
||||
],
|
||||
'default_currency' => 'EUR',
|
||||
'default_language' => envNonEmpty('DEFAULT_LANGUAGE', 'en_US'),
|
||||
'default_locale' => envNonEmpty('DEFAULT_LOCALE', 'equal'),
|
||||
'search_modifiers' => ['amount_is', 'amount', 'amount_max', 'amount_min', 'amount_less', 'amount_more', 'source', 'destination', 'category',
|
||||
'budget', 'bill', 'type', 'date', 'date_before', 'date_after', 'on', 'before', 'after', 'from', 'to', 'tag', 'created_on',
|
||||
'updated_on',],
|
||||
|
@@ -30,7 +30,7 @@ $factory->define(
|
||||
'user_id' => 1,
|
||||
'attachable_id' => 1,
|
||||
'attachable_type' => TransactionJournal::class,
|
||||
'md5' => md5($faker->words(6, true)),
|
||||
'md5' => substr(hash('sha256', $faker->words(6, true)), 0, 32),
|
||||
'mime' => 'text/plain',
|
||||
'size' => 1,
|
||||
'filename' => 'ok',
|
||||
|
@@ -133,7 +133,7 @@ class CreateMainTables extends Migration
|
||||
$table->integer('user_id', false, true);
|
||||
$table->integer('attachable_id', false, true);
|
||||
$table->string('attachable_type', 255);
|
||||
$table->string('md5', 32);
|
||||
$table->string('md5', 128);
|
||||
$table->string('filename', 1024);
|
||||
$table->string('title', 1024)->nullable();
|
||||
$table->text('description')->nullable();
|
||||
|
2
public/v1/js/app.js
vendored
2
public/v1/js/app.js
vendored
File diff suppressed because one or more lines are too long
@@ -5,18 +5,18 @@
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Sizzle CSS Selector Engine v2.3.4
|
||||
* Sizzle CSS Selector Engine v2.3.5
|
||||
* https://sizzlejs.com/
|
||||
*
|
||||
* Copyright JS Foundation and other contributors
|
||||
* Released under the MIT license
|
||||
* https://js.foundation/
|
||||
*
|
||||
* Date: 2019-04-08
|
||||
* Date: 2020-03-14
|
||||
*/
|
||||
|
||||
/*!
|
||||
* jQuery JavaScript Library v3.4.1
|
||||
* jQuery JavaScript Library v3.5.0
|
||||
* https://jquery.com/
|
||||
*
|
||||
* Includes Sizzle.js
|
||||
@@ -26,5 +26,5 @@
|
||||
* Released under the MIT license
|
||||
* https://jquery.org/license
|
||||
*
|
||||
* Date: 2019-05-01T21:04Z
|
||||
* Date: 2020-04-10T15:07Z
|
||||
*/
|
||||
|
2
public/v1/js/app_vue.js
vendored
2
public/v1/js/app_vue.js
vendored
File diff suppressed because one or more lines are too long
2
public/v1/js/create_transaction.js
vendored
2
public/v1/js/create_transaction.js
vendored
File diff suppressed because one or more lines are too long
2
public/v1/js/edit_transaction.js
vendored
2
public/v1/js/edit_transaction.js
vendored
File diff suppressed because one or more lines are too long
6
public/v1/js/ff/accounts/show.js
vendored
6
public/v1/js/ff/accounts/show.js
vendored
@@ -84,10 +84,10 @@ $(function () {
|
||||
dragging: false
|
||||
}).setView([latitude, longitude], zoomLevel);
|
||||
|
||||
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
|
||||
attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="http://mapbox.com">Mapbox</a>',
|
||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png?access_token={accessToken}', {
|
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
|
||||
maxZoom: 18,
|
||||
id: 'mapbox.streets',
|
||||
id: 'mapbox/streets-v11',
|
||||
accessToken: mapboxToken
|
||||
}).addTo(mymap);
|
||||
L.marker([latitude, longitude]).addTo(mymap);
|
||||
|
6
public/v1/js/ff/tags/show.js
vendored
6
public/v1/js/ff/tags/show.js
vendored
@@ -40,10 +40,10 @@ $(function () {
|
||||
dragging: false
|
||||
}).setView([latitude, longitude], zoomLevel);
|
||||
|
||||
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
|
||||
attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="http://mapbox.com">Mapbox</a>',
|
||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png?access_token={accessToken}', {
|
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
|
||||
maxZoom: 18,
|
||||
id: 'mapbox.streets',
|
||||
id: 'mapbox/streets-v11',
|
||||
accessToken: mapboxToken
|
||||
}).addTo(mymap);
|
||||
L.marker([latitude, longitude]).addTo(mymap);
|
||||
|
2
public/v1/js/profile.js
vendored
2
public/v1/js/profile.js
vendored
File diff suppressed because one or more lines are too long
@@ -20,17 +20,18 @@
|
||||
<template>
|
||||
<div>
|
||||
<table class="table table-hover sortable">
|
||||
<caption>Bills table</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="hidden-sm hidden-xs" data-defaultsort="disabled"> </th>
|
||||
<th>{{ 'list.name' | trans }}</th>
|
||||
<th data-defaultsign="az" class="hidden-sm hidden-md hidden-xs">{{ 'list.matchesOn' | trans }}</th>
|
||||
<th data-defaultsign="_19" colspan="2">{{ 'list.amount' | trans }}</th>
|
||||
<th data-defaultsign="month" class="hidden-sm hidden-xs">{{ 'list.paid_current_period' | trans }}</th>
|
||||
<th data-defaultsign="month" class="hidden-sm hidden-xs">{{ 'list.next_expected_match' | trans }}</th>
|
||||
<th class="hidden-sm hidden-xs hidden-md">{{ 'list.active' | trans }}</th>
|
||||
<th class="hidden-sm hidden-xs hidden-md">{{ 'list.automatch' | trans }}</th>
|
||||
<th data-defaultsign="az" class="hidden-sm hidden-xs">{{ 'list.repeat_freq' | trans }}</th>
|
||||
<th scope="col" class="hidden-sm hidden-xs" data-defaultsort="disabled"> </th>
|
||||
<th scope="col">{{ 'list.name' | trans }}</th>
|
||||
<th scope="col"data-defaultsign="az" class="hidden-sm hidden-md hidden-xs">{{ 'list.matchesOn' | trans }}</th>
|
||||
<th scope="col" data-defaultsign="_19" colspan="2">{{ 'list.amount' | trans }}</th>
|
||||
<th scope="col" data-defaultsign="month" class="hidden-sm hidden-xs">{{ 'list.paid_current_period' | trans }}</th>
|
||||
<th scope="col" data-defaultsign="month" class="hidden-sm hidden-xs">{{ 'list.next_expected_match' | trans }}</th>
|
||||
<th scope="col" class="hidden-sm hidden-xs hidden-md">{{ 'list.active' | trans }}</th>
|
||||
<th scope="col" class="hidden-sm hidden-xs hidden-md">{{ 'list.automatch' | trans }}</th>
|
||||
<th scope="col" data-defaultsign="az" class="hidden-sm hidden-xs">{{ 'list.repeat_freq' | trans }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user