mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Merge branch 'release/5.3.0-alpha.1'
This commit is contained in:
commit
2c69a2eda2
25
.env.example
25
.env.example
@ -57,10 +57,10 @@ APP_LOG_LEVEL=notice
|
||||
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
|
||||
# For other database types, please see the FAQ: https://docs.firefly-iii.org/support/faq
|
||||
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
|
||||
# Use "mysql" for MySQL and MariaDB. Use "sqlite" for SQLite.
|
||||
DB_CONNECTION=pgsql
|
||||
# Use "pgsql" for PostgreSQL and MariaDB. Use "sqlite" for SQLite.
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=fireflyiiidb
|
||||
DB_PORT=5432
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=firefly
|
||||
DB_USERNAME=firefly
|
||||
DB_PASSWORD=secret_firefly_password
|
||||
@ -167,6 +167,23 @@ FIXER_API_KEY=
|
||||
# If you use Docker or similar, you can set this variable from a file by appending it with _FILE
|
||||
LOGIN_PROVIDER=eloquent
|
||||
|
||||
#
|
||||
# It's also possible to change the way users are authenticated. You could use Authelia for example.
|
||||
# Authentication via the REMOTE_USER header is supported. Change the value below to "remote_user_guard".
|
||||
#
|
||||
# If you do this please read the documentation for instructions and warnings:
|
||||
# https://docs.firefly-iii.org/advanced-installation/authentication
|
||||
#
|
||||
# This function is available in Firefly III v5.3.0 and higher.
|
||||
AUTHENTICATION_GUARD=web
|
||||
|
||||
#
|
||||
# Likewise, it's impossible to log out users who's authentication is handled by an external system.
|
||||
# Enter a custom URL here that will force a logout (your authentication provider can tell you).
|
||||
# Setting this variable only works when AUTHENTICATION_GUARD != web
|
||||
#
|
||||
CUSTOM_LOGOUT_URI=
|
||||
|
||||
# LDAP connection configuration
|
||||
# OpenLDAP, FreeIPA or ActiveDirectory
|
||||
# # If you use Docker or similar, you can set this variable from a file by appending it with _FILE
|
||||
@ -289,7 +306,7 @@ DEMO_PASSWORD=
|
||||
USE_ENCRYPTION=false
|
||||
IS_SANDSTORM=false
|
||||
IS_HEROKU=false
|
||||
BUNQ_USE_SANDBOX=false
|
||||
FIREFLY_III_LAYOUT=v1
|
||||
|
||||
#
|
||||
# If you have trouble configuring your Firefly III installation, DON'T BOTHER setting this variable.
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,5 +1,6 @@
|
||||
/node_modules
|
||||
/frontend/node_modules
|
||||
/frontend/fonts
|
||||
/public/hot
|
||||
/public/storage
|
||||
/storage/*.key
|
||||
|
@ -1,181 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* ImportController.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\Api\V1\Controllers;
|
||||
|
||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\TransactionFilter;
|
||||
use FireflyIII\Transformers\ImportJobTransformer;
|
||||
use FireflyIII\Transformers\TransactionGroupTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Collection;
|
||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use League\Fractal\Resource\Collection as FractalCollection;
|
||||
use League\Fractal\Resource\Item;
|
||||
|
||||
/**
|
||||
* Class ImportController
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class ImportController extends Controller
|
||||
{
|
||||
use TransactionFilter;
|
||||
/** @var ImportJobRepositoryInterface Import job repository. */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* ImportController constructor.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->repository->setUser($user);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return JsonResponse
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function listAll(): JsonResponse
|
||||
{
|
||||
// create some objects:
|
||||
$manager = $this->getManager();
|
||||
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||
|
||||
// get list of accounts. Count it and split it.
|
||||
$collection = $this->repository->get();
|
||||
$count = $collection->count();
|
||||
$importJobs = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
|
||||
// make paginator:
|
||||
$paginator = new LengthAwarePaginator($importJobs, $count, $pageSize, $this->parameters->get('page'));
|
||||
$paginator->setPath(route('api.v1.import.list') . $this->buildParams());
|
||||
|
||||
/** @var ImportJobTransformer $transformer */
|
||||
$transformer = app(ImportJobTransformer::class);
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
||||
$resource = new FractalCollection($importJobs, $transformer, 'import_jobs');
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ImportJob $importJob
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function show(ImportJob $importJob): JsonResponse
|
||||
{
|
||||
$manager = $this->getManager();
|
||||
/** @var ImportJobTransformer $transformer */
|
||||
$transformer = app(ImportJobTransformer::class);
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
||||
$resource = new Item($importJob, $transformer, 'import_jobs');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show all transactions
|
||||
*
|
||||
* @param Request $request
|
||||
* @param ImportJob $importJob
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function transactions(Request $request, ImportJob $importJob): JsonResponse
|
||||
{
|
||||
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||
$type = $request->get('type') ?? 'default';
|
||||
$this->parameters->set('type', $type);
|
||||
|
||||
$types = $this->mapTransactionTypes($this->parameters->get('type'));
|
||||
$manager = $this->getManager();
|
||||
|
||||
$tag = $importJob->tag;
|
||||
$transactions = new Collection();
|
||||
$paginator = new LengthAwarePaginator($transactions, 0, $pageSize);
|
||||
$paginator->setPath(route('api.v1.import.transactions', [$importJob->key]) . $this->buildParams());
|
||||
|
||||
if (null !== $tag) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
// use new group collector:
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector
|
||||
->setUser($admin)
|
||||
// filter on tag.
|
||||
->setTag($tag)
|
||||
// all info needed for the API:
|
||||
->withAPIInformation()
|
||||
// set page size:
|
||||
->setLimit($pageSize)
|
||||
// set page to retrieve
|
||||
->setPage($this->parameters->get('page'))
|
||||
// set types of transactions to return.
|
||||
->setTypes($types);
|
||||
|
||||
if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) {
|
||||
$collector->setRange($this->parameters->get('start'), $this->parameters->get('end'));
|
||||
}
|
||||
$paginator = $collector->getPaginatedGroups();
|
||||
$paginator->setPath(route('api.v1.transactions.index') . $this->buildParams());
|
||||
$transactions = $paginator->getCollection();
|
||||
}
|
||||
|
||||
/** @var TransactionGroupTransformer $transformer */
|
||||
$transformer = app(TransactionGroupTransformer::class);
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
||||
$resource = new FractalCollection($transactions, $transformer, 'transactions');
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
}
|
196
app/Api/V1/Controllers/ObjectGroupController.php
Normal file
196
app/Api/V1/Controllers/ObjectGroupController.php
Normal file
@ -0,0 +1,196 @@
|
||||
<?php
|
||||
/**
|
||||
* GroupController.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\Api\V1\Controllers;
|
||||
|
||||
use FireflyIII\Api\V1\Requests\ObjectGroupUpdateRequest;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\ObjectGroup;
|
||||
use FireflyIII\Repositories\ObjectGroup\ObjectGroupRepositoryInterface;
|
||||
use FireflyIII\Transformers\ObjectGroupTransformer;
|
||||
use FireflyIII\Transformers\PiggyBankTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use League\Fractal\Resource\Collection as FractalCollection;
|
||||
use League\Fractal\Resource\Item;
|
||||
|
||||
/**
|
||||
* Class GroupController.
|
||||
*
|
||||
*/
|
||||
class ObjectGroupController extends Controller
|
||||
{
|
||||
private ObjectGroupRepositoryInterface $repository;
|
||||
|
||||
/**
|
||||
* ObjectGroupController constructor.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
$this->repository = app(ObjectGroupRepositoryInterface::class);
|
||||
$this->repository->setUser($user);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param ObjectGroup $objectGroup
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function delete(ObjectGroup $objectGroup): JsonResponse
|
||||
{
|
||||
$this->repository->destroy($objectGroup);
|
||||
|
||||
return response()->json([], 204);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
$manager = $this->getManager();
|
||||
|
||||
// types to get, page size:
|
||||
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||
|
||||
// get list of accounts. Count it and split it.
|
||||
$collection = $this->repository->get();
|
||||
$count = $collection->count();
|
||||
$objectGroups = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
|
||||
// make paginator:
|
||||
$paginator = new LengthAwarePaginator($objectGroups, $count, $pageSize, $this->parameters->get('page'));
|
||||
$paginator->setPath(route('api.v1.object-groups.index') . $this->buildParams());
|
||||
|
||||
/** @var ObjectGroupTransformer $transformer */
|
||||
$transformer = app(ObjectGroupTransformer::class);
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
||||
$resource = new FractalCollection($objectGroups, $transformer, 'object_groups');
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* List all piggies under the object group.
|
||||
*
|
||||
* @param ObjectGroup $objectGroup
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
*/
|
||||
public function piggyBanks(ObjectGroup $objectGroup): JsonResponse
|
||||
{
|
||||
// create some objects:
|
||||
$manager = $this->getManager();
|
||||
|
||||
// types to get, page size:
|
||||
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||
|
||||
// get list of piggy banks. Count it and split it.
|
||||
$collection = $this->repository->getPiggyBanks($objectGroup);
|
||||
$count = $collection->count();
|
||||
$piggyBanks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
|
||||
// make paginator:
|
||||
$paginator = new LengthAwarePaginator($piggyBanks, $count, $pageSize, $this->parameters->get('page'));
|
||||
$paginator->setPath(route('api.v1.object-groups.piggy_banks', [$objectGroup->id]) . $this->buildParams());
|
||||
|
||||
/** @var PiggyBankTransformer $transformer */
|
||||
$transformer = app(PiggyBankTransformer::class);
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
||||
$resource = new FractalCollection($piggyBanks, $transformer, 'piggy_banks');
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Show single instance.
|
||||
*
|
||||
* @param ObjectGroup $objectGroup
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function show(ObjectGroup $objectGroup): JsonResponse
|
||||
{
|
||||
$manager = $this->getManager();
|
||||
|
||||
/** @var ObjectGroupTransformer $transformer */
|
||||
$transformer = app(ObjectGroupTransformer::class);
|
||||
$transformer->setParameters($this->parameters);
|
||||
$resource = new Item($objectGroup, $transformer, 'object_groups');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
/**
|
||||
* Update object.
|
||||
*
|
||||
* @param ObjectGroupUpdateRequest $request
|
||||
* @param Account $account
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function update(ObjectGroupUpdateRequest $request, ObjectGroup $objectGroup): JsonResponse
|
||||
{
|
||||
$data = $request->getUpdateData();
|
||||
$this->repository->update($objectGroup, $data);
|
||||
$this->repository->sort();
|
||||
$manager = $this->getManager();
|
||||
|
||||
/** @var ObjectGroupTransformer $transformer */
|
||||
$transformer = app(ObjectGroupTransformer::class);
|
||||
$transformer->setParameters($this->parameters);
|
||||
$resource = new Item($objectGroup, $transformer, 'object_groups');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
}
|
@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Api\V1\Controllers;
|
||||
|
||||
use FireflyIII\Api\V1\Requests\PiggyBankRequest;
|
||||
use FireflyIII\Api\V1\Requests\PiggyBankStoreRequest;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||
@ -204,12 +205,12 @@ class PiggyBankController extends Controller
|
||||
/**
|
||||
* Store new object.
|
||||
*
|
||||
* @param PiggyBankRequest $request
|
||||
* @param PiggyBankStoreRequest $request
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function store(PiggyBankRequest $request): JsonResponse
|
||||
public function store(PiggyBankStoreRequest $request): JsonResponse
|
||||
{
|
||||
$piggyBank = $this->repository->store($request->getAll());
|
||||
$manager = $this->getManager();
|
||||
|
@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* RabobankDescription.php
|
||||
* ObjectGroupUpdateRequest.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
@ -18,52 +19,53 @@
|
||||
* 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\Import\Specifics;
|
||||
namespace FireflyIII\Api\V1\Requests;
|
||||
|
||||
/**
|
||||
* Class RabobankDescription.
|
||||
* Class AccountObjectGroupUpdateRequestUpdateRequest
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @deprecated
|
||||
*/
|
||||
class RabobankDescription implements SpecificInterface
|
||||
class ObjectGroupUpdateRequest extends Request
|
||||
{
|
||||
|
||||
/**
|
||||
* Description of this specific.
|
||||
* Authorize logged in users.
|
||||
*
|
||||
* @return string
|
||||
* @codeCoverageIgnore
|
||||
* @return bool
|
||||
*/
|
||||
public static function getDescription(): string
|
||||
public function authorize(): bool
|
||||
{
|
||||
return 'import.specific_rabo_descr';
|
||||
// Only allow authenticated users
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Name of this specific.
|
||||
*
|
||||
* @return string
|
||||
* @codeCoverageIgnore
|
||||
* @return array
|
||||
*/
|
||||
public static function getName(): string
|
||||
public function getUpdateData(): array
|
||||
{
|
||||
return 'import.specific_rabo_name';
|
||||
return [
|
||||
'title' => $this->string('title'),
|
||||
'order' => $this->integer('order'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the specific.
|
||||
*
|
||||
* @param array $row
|
||||
* The rules that the incoming request must be matched against.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
*/
|
||||
public function run(array $row): array
|
||||
public function rules(): array
|
||||
{
|
||||
$row = array_values($row);
|
||||
$objectGroup = $this->route()->parameter('objectGroup');
|
||||
|
||||
return $row;
|
||||
return [
|
||||
'title' => sprintf('min:1|uniqueObjectGroup:%d', $objectGroup->id),
|
||||
'order' => 'numeric',
|
||||
];
|
||||
}
|
||||
}
|
86
app/Api/V1/Requests/PiggyBankStoreRequest.php
Normal file
86
app/Api/V1/Requests/PiggyBankStoreRequest.php
Normal file
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
/**
|
||||
* PiggyBankStoreRequest.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\Api\V1\Requests;
|
||||
|
||||
use FireflyIII\Rules\ZeroOrMore;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class PiggyBankStoreRequest
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class PiggyBankStoreRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Authorize logged in users.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
// Only allow authenticated users
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all data from the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
{
|
||||
return [
|
||||
'name' => $this->string('name'),
|
||||
'account_id' => $this->integer('account_id'),
|
||||
'targetamount' => $this->string('target_amount'),
|
||||
'current_amount' => $this->string('current_amount'),
|
||||
'startdate' => $this->date('start_date'),
|
||||
'targetdate' => $this->date('target_date'),
|
||||
'notes' => $this->nlString('notes'),
|
||||
'object_group_id' => $this->integer('object_group_id'),
|
||||
'object_group' => $this->string('object_group_name'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'required|between:1,255|uniquePiggyBankForUser',
|
||||
'current_amount' => ['numeric', new ZeroOrMore, 'lte:target_amount'],
|
||||
'account_id' => 'required|numeric|belongsToUser:accounts,id',
|
||||
'object_group_id' => 'numeric|belongsToUser:object_groups,id',
|
||||
'target_amount' => ['numeric', new ZeroOrMore, 'lte:target_amount', 'required'],
|
||||
'start_date' => 'date|nullable',
|
||||
'target_date' => 'date|nullable|after:start_date',
|
||||
'notes' => 'max:65000',
|
||||
];
|
||||
}
|
||||
|
||||
}
|
@ -55,9 +55,9 @@ class FixRecurringTransactions extends Command
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
public function handle(): int
|
||||
{
|
||||
$start = microtime(true);
|
||||
$this->stupidLaravel();
|
||||
|
@ -50,9 +50,9 @@ class CreateDatabase extends Command
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
public function handle(): int
|
||||
{
|
||||
if ('mysql' !== env('DB_CONNECTION')) {
|
||||
$this->info(sprintf('CreateDB does not apply to "%s", skipped.', env('DB_CONNECTION')));
|
||||
|
@ -159,7 +159,7 @@ class DecryptDatabase extends Command
|
||||
if ('The MAC is invalid.' === $e->getMessage()) {
|
||||
throw new FireflyException($e->getMessage()); // @codeCoverageIgnore
|
||||
}
|
||||
Log::debug(sprintf('Could not decrypt. %s', $e->getMessage()));
|
||||
//Log::debug(sprintf('Could not decrypt. %s', $e->getMessage()));
|
||||
}
|
||||
|
||||
return $value;
|
||||
|
@ -1,76 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* CreateCSVImport.php
|
||||
* Copyright (c) 2020 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/>.
|
||||
*/
|
||||
|
||||
/** @noinspection MultipleReturnStatementsInspection */
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Import;
|
||||
|
||||
use Exception;
|
||||
use FireflyIII\Console\Commands\VerifiesAccessToken;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Import\Routine\RoutineInterface;
|
||||
use FireflyIII\Import\Storage\ImportArrayStorage;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Console\Command;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class CreateCSVImport.
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class CreateCSVImport extends Command
|
||||
{
|
||||
use VerifiesAccessToken;
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Use this command to create a new CSV file import.';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature
|
||||
= 'firefly-iii:csv-import
|
||||
{file? : The CSV file to import.}
|
||||
{configuration? : The configuration file to use for the import.}
|
||||
{--user=1 : The user ID that the import should import for.}
|
||||
{--token= : The user\'s access token.}';
|
||||
/**
|
||||
* Run the command.
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$this->error('This command is disabled.');
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -60,7 +60,7 @@ class ApplyRules extends Command
|
||||
*/
|
||||
protected $signature
|
||||
= 'firefly-iii:apply-rules
|
||||
{--user=1 : The user ID that the import should import for.}
|
||||
{--user=1 : The user ID.}
|
||||
{--token= : The user\'s access token.}
|
||||
{--accounts= : A comma-separated list of asset accounts or liabilities to apply your rules to.}
|
||||
{--rule_groups= : A comma-separated list of rule groups to apply. Take the ID\'s of these rule groups from the Firefly III interface.}
|
||||
|
@ -38,6 +38,7 @@ use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Redirector;
|
||||
use Log;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Class GracefulNotFoundHandler
|
||||
@ -53,7 +54,7 @@ class GracefulNotFoundHandler extends ExceptionHandler
|
||||
* @throws Exception
|
||||
* @return mixed
|
||||
*/
|
||||
public function render($request, Exception $exception)
|
||||
public function render($request, Throwable $exception)
|
||||
{
|
||||
$route = $request->route();
|
||||
if (null === $route) {
|
||||
@ -136,12 +137,12 @@ class GracefulNotFoundHandler extends ExceptionHandler
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Exception $exception
|
||||
* @param Throwable $exception
|
||||
*
|
||||
* @throws Exception
|
||||
* @return Redirector|Response
|
||||
*/
|
||||
private function handleAccount(Request $request, Exception $exception)
|
||||
private function handleAccount(Request $request, Throwable $exception)
|
||||
{
|
||||
Log::debug('404 page is probably a deleted account. Redirect to overview of account types.');
|
||||
/** @var User $user */
|
||||
@ -164,12 +165,12 @@ class GracefulNotFoundHandler extends ExceptionHandler
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Exception $exception
|
||||
* @param Throwable $exception
|
||||
*
|
||||
* @throws Exception
|
||||
* @return RedirectResponse|Redirector|Response
|
||||
*/
|
||||
private function handleAttachment(Request $request, Exception $exception)
|
||||
private function handleAttachment(Request $request, Throwable $exception)
|
||||
{
|
||||
Log::debug('404 page is probably a deleted attachment. Redirect to parent object.');
|
||||
/** @var User $user */
|
||||
@ -208,13 +209,13 @@ class GracefulNotFoundHandler extends ExceptionHandler
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Throwable $request
|
||||
* @param Exception $exception
|
||||
*
|
||||
* @throws Exception
|
||||
* @return RedirectResponse|\Illuminate\Http\Response|Redirector|Response
|
||||
*/
|
||||
private function handleGroup(Request $request, Exception $exception)
|
||||
private function handleGroup(Request $request, Throwable $exception)
|
||||
{
|
||||
Log::debug('404 page is probably a deleted group. Redirect to overview of group types.');
|
||||
/** @var User $user */
|
||||
|
@ -33,9 +33,9 @@ use Illuminate\Auth\AuthenticationException;
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use Illuminate\Validation\ValidationException as LaravelValidationException;
|
||||
use League\OAuth2\Server\Exception\OAuthServerException;
|
||||
use Request;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Throwable;
|
||||
/**
|
||||
* Class Handler
|
||||
*
|
||||
@ -51,7 +51,7 @@ class Handler extends ExceptionHandler
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function render($request, Exception $exception)
|
||||
public function render($request, Throwable $exception)
|
||||
{
|
||||
if ($exception instanceof LaravelValidationException && $request->expectsJson()) {
|
||||
// ignore it: controller will handle it.
|
||||
@ -119,7 +119,7 @@ class Handler extends ExceptionHandler
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function report(Exception $exception)
|
||||
public function report(Throwable $exception)
|
||||
{
|
||||
$doMailError = config('firefly.send_error_message');
|
||||
// if the user wants us to mail:
|
||||
@ -143,13 +143,13 @@ class Handler extends ExceptionHandler
|
||||
'line' => $exception->getLine(),
|
||||
'code' => $exception->getCode(),
|
||||
'version' => config('firefly.version'),
|
||||
'url' => Request::fullUrl(),
|
||||
'userAgent' => Request::userAgent(),
|
||||
'json' => Request::acceptsJson(),
|
||||
'url' => request()->fullUrl(),
|
||||
'userAgent' => request()->userAgent(),
|
||||
'json' => request()->acceptsJson(),
|
||||
];
|
||||
|
||||
// create job that will mail.
|
||||
$ipAddress = Request::ip() ?? '0.0.0.0';
|
||||
$ipAddress = request()->ip() ?? '0.0.0.0';
|
||||
$job = new MailError($userData, (string) config('firefly.site_owner'), $ipAddress, $data);
|
||||
dispatch($job);
|
||||
}
|
||||
|
@ -36,6 +36,8 @@ trait CollectorProperties
|
||||
private $hasAccountInfo;
|
||||
/** @var bool Will be true if query result includes bill information. */
|
||||
private $hasBillInformation;
|
||||
/** @var bool */
|
||||
private $hasNotesInformation;
|
||||
/** @var bool Will be true if query result contains budget info. */
|
||||
private $hasBudgetInformation;
|
||||
/** @var bool Will be true if query result contains category info. */
|
||||
|
@ -28,6 +28,7 @@ use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\Tag;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Database\Query\JoinClause;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
@ -36,6 +37,27 @@ use Illuminate\Support\Collection;
|
||||
trait MetaCollection
|
||||
{
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function withNotes(): GroupCollectorInterface
|
||||
{
|
||||
if (false === $this->hasNotesInformation) {
|
||||
// join bill table
|
||||
$this->query->leftJoin(
|
||||
'notes',
|
||||
static function (JoinClause $join) {
|
||||
$join->on('notes.noteable_id', '=', 'transaction_journals.id');
|
||||
$join->where('notes.noteable_type', '=', 'FireflyIII\Models\TransactionJournal');
|
||||
}
|
||||
);
|
||||
// add fields
|
||||
$this->fields[] = 'notes.text as notes';
|
||||
$this->hasNotesInformation = true;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Limit the search to a specific bill.
|
||||
|
@ -62,6 +62,7 @@ class GroupCollector implements GroupCollectorInterface
|
||||
$this->hasCatInformation = false;
|
||||
$this->hasBudgetInformation = false;
|
||||
$this->hasBillInformation = false;
|
||||
$this->hasNotesInformation = false;
|
||||
$this->hasJoinedTagTables = false;
|
||||
$this->hasJoinedAttTables = false;
|
||||
$this->integerFields = [
|
||||
@ -552,9 +553,14 @@ class GroupCollector implements GroupCollectorInterface
|
||||
$result['tags'] = [];
|
||||
$result['attachments'] = [];
|
||||
try {
|
||||
$result['date'] = new Carbon($result['date']);
|
||||
$result['created_at'] = new Carbon($result['created_at']);
|
||||
$result['updated_at'] = new Carbon($result['updated_at']);
|
||||
$result['date'] = new Carbon($result['date'], 'UTC');
|
||||
$result['created_at'] = new Carbon($result['created_at'], 'UTC');
|
||||
$result['updated_at'] = new Carbon($result['updated_at'], 'UTC');
|
||||
|
||||
// this is going to happen a lot:
|
||||
$result['date']->setTimezone(env('TZ'));
|
||||
$result['created_at']->setTimezone(env('TZ'));
|
||||
$result['updated_at']->setTimezone(env('TZ'));
|
||||
} catch (Exception $e) {
|
||||
Log::error($e->getMessage());
|
||||
}
|
||||
@ -681,4 +687,5 @@ class GroupCollector implements GroupCollectorInterface
|
||||
->orderBy('transaction_journals.description', 'DESC')
|
||||
->orderBy('source.amount', 'DESC');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -398,6 +398,13 @@ interface GroupCollectorInterface
|
||||
*/
|
||||
public function withCategoryInformation(): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* Will include notes.
|
||||
*
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function withNotes(): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* Add tag info.
|
||||
*
|
||||
|
@ -49,8 +49,7 @@ class EditController extends Controller
|
||||
/** @var AccountRepositoryInterface The account repository */
|
||||
private $repository;
|
||||
|
||||
/** @var AttachmentHelperInterface Helper for attachments. */
|
||||
private $attachments;
|
||||
private AttachmentHelperInterface $attachments;
|
||||
|
||||
/**
|
||||
* EditController constructor.
|
||||
|
@ -130,7 +130,6 @@ class ReconcileController extends Controller
|
||||
$startDate = clone $start;
|
||||
$startDate->subDay();
|
||||
$startBalance = round(app('steam')->balance($account, $startDate), $currency->decimal_places);
|
||||
|
||||
$endBalance = round(app('steam')->balance($account, $end), $currency->decimal_places);
|
||||
$subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $account->accountType->type));
|
||||
$subTitle = (string) trans('firefly.reconcile_account', ['account' => $account->name]);
|
||||
|
@ -46,10 +46,8 @@ class ShowController extends Controller
|
||||
{
|
||||
use UserNavigation, PeriodOverview;
|
||||
|
||||
/** @var CurrencyRepositoryInterface The currency repository */
|
||||
private $currencyRepos;
|
||||
/** @var AccountRepositoryInterface The account repository */
|
||||
private $repository;
|
||||
private CurrencyRepositoryInterface $currencyRepos;
|
||||
private AccountRepositoryInterface $repository;
|
||||
|
||||
/**
|
||||
* ShowController constructor.
|
||||
|
@ -176,4 +176,35 @@ class LoginController extends Controller
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Log the user out of the application.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function logout(Request $request)
|
||||
{
|
||||
$authGuard = config('firefly.authentication_guard');
|
||||
$logoutUri = config('firefly.custom_logout_uri');
|
||||
if ('remote_user_guard' === $authGuard && '' !== $logoutUri) {
|
||||
return redirect($logoutUri);
|
||||
}
|
||||
|
||||
$this->guard()->logout();
|
||||
|
||||
$request->session()->invalidate();
|
||||
|
||||
$request->session()->regenerateToken();
|
||||
|
||||
if ($response = $this->loggedOut($request)) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
return $request->wantsJson()
|
||||
? new \Illuminate\Http\Response('', 204)
|
||||
: redirect('/');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -212,6 +212,12 @@ class BillController extends Controller
|
||||
$bills = $unfiltered->map(
|
||||
function (Bill $bill) use ($transformer, $defaultCurrency) {
|
||||
$return = $transformer->transform($bill);
|
||||
$nextExpectedMatch = new Carbon($return['next_expected_match']);
|
||||
$return['next_expected_match_diff'] = $nextExpectedMatch->isToday()
|
||||
? trans('firefly.today')
|
||||
: $nextExpectedMatch->diffForHumans(
|
||||
today(), Carbon::DIFF_RELATIVE_TO_NOW
|
||||
);
|
||||
$currency = $bill->transactionCurrency ?? $defaultCurrency;
|
||||
$return['currency_id'] = $currency->id;
|
||||
$return['currency_name'] = $currency->name;
|
||||
|
@ -39,13 +39,13 @@ class Controller extends BaseController
|
||||
use AuthorizesRequests, DispatchesJobs, ValidatesRequests, UserNavigation, RequestInformation;
|
||||
|
||||
/** @var string Format for date and time. */
|
||||
protected $dateTimeFormat;
|
||||
protected string $dateTimeFormat;
|
||||
/** @var string Format for "23 Feb, 2016". */
|
||||
protected $monthAndDayFormat;
|
||||
protected string $monthAndDayFormat;
|
||||
/** @var string Format for "March 2018" */
|
||||
protected $monthFormat;
|
||||
protected string $monthFormat;
|
||||
/** @var string Redirect user */
|
||||
protected $redirectUri = '/';
|
||||
protected string $redirectUri = '/';
|
||||
|
||||
/**
|
||||
* Controller constructor.
|
||||
@ -55,7 +55,7 @@ class Controller extends BaseController
|
||||
public function __construct()
|
||||
{
|
||||
// is site a demo site?
|
||||
$isDemoSite = app('fireflyconfig')->get('is_demo_site', config('firefly.configuration.is_demo_site',),)->data;
|
||||
$isDemoSite = app('fireflyconfig')->get('is_demo_site', config('firefly.configuration.is_demo_site', false,),)->data;
|
||||
app('view')->share('IS_DEMO_SITE', $isDemoSite,);
|
||||
app('view')->share('DEMO_USERNAME', config('firefly.demo_username'));
|
||||
app('view')->share('DEMO_PASSWORD', config('firefly.demo_password'));
|
||||
|
@ -138,6 +138,8 @@ class DebugController extends Controller
|
||||
$appLogLevel = config('logging.level');
|
||||
$cacheDriver = config('cache.default');
|
||||
$loginProvider = config('auth.providers.users.driver');
|
||||
$bcscale = bcscale();
|
||||
$layout = env('FIREFLY_III_LAYOUT');
|
||||
|
||||
// some new vars.
|
||||
$telemetry = true === config('firefly.send_telemetry') && true === config('firefly.feature_flags.telemetry');
|
||||
@ -195,6 +197,8 @@ class DebugController extends Controller
|
||||
'drivers',
|
||||
'currentDriver',
|
||||
'loginProvider',
|
||||
'bcscale',
|
||||
'layout',
|
||||
'userAgent',
|
||||
'displayErrors',
|
||||
'installationId',
|
||||
@ -224,15 +228,14 @@ class DebugController extends Controller
|
||||
{
|
||||
$set = RouteFacade::getRoutes();
|
||||
$ignore = ['chart.', 'javascript.', 'json.', 'report-data.', 'popup.', 'debugbar.', 'attachments.download', 'attachments.preview',
|
||||
'bills.rescan', 'budgets.income', 'currencies.def', 'error', 'flush', 'help.show', 'import.file',
|
||||
'bills.rescan', 'budgets.income', 'currencies.def', 'error', 'flush', 'help.show',
|
||||
'login', 'logout', 'password.reset', 'profile.confirm-email-change', 'profile.undo-email-change',
|
||||
'register', 'report.options', 'routes', 'rule-groups.down', 'rule-groups.up', 'rules.up', 'rules.down',
|
||||
'rules.select', 'search.search', 'test-flash', 'transactions.link.delete', 'transactions.link.switch',
|
||||
'two-factor.lost', 'reports.options', 'debug', 'import.create-job', 'import.download', 'import.start', 'import.status.json',
|
||||
'two-factor.lost', 'reports.options', 'debug',
|
||||
'preferences.delete-code', 'rules.test-triggers', 'piggy-banks.remove-money', 'piggy-banks.add-money',
|
||||
'accounts.reconcile.transactions', 'accounts.reconcile.overview',
|
||||
'transactions.clone', 'two-factor.index', 'api.v1', 'installer.', 'attachments.view', 'import.create',
|
||||
'import.job.download', 'import.job.start', 'import.job.status.json', 'import.job.store', 'recurring.events',
|
||||
'transactions.clone', 'two-factor.index', 'api.v1', 'installer.', 'attachments.view', 'recurring.events',
|
||||
'recurring.suggest',
|
||||
];
|
||||
$return = ' ';
|
||||
|
@ -1,82 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* CallbackController.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\Http\Controllers\Import;
|
||||
|
||||
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Redirector;
|
||||
use Illuminate\View\View;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class CallbackController
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class CallbackController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Callback specifically for YNAB logins.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @param ImportJobRepositoryInterface $repository
|
||||
*
|
||||
* @return Factory|RedirectResponse|Redirector|View
|
||||
*/
|
||||
public function ynab(Request $request, ImportJobRepositoryInterface $repository)
|
||||
{
|
||||
$code = (string) $request->get('code');
|
||||
$jobKey = (string) $request->get('state');
|
||||
|
||||
if ('' === $code) {
|
||||
return view('error')->with('message', 'You Need A Budget did not reply with a valid authorization code. Firefly III cannot continue.');
|
||||
}
|
||||
|
||||
$importJob = $repository->findByKey($jobKey);
|
||||
|
||||
if ('' === $jobKey || null === $importJob) {
|
||||
return view('error')->with('message', 'You Need A Budget did not reply with the correct state identifier. Firefly III cannot continue.');
|
||||
}
|
||||
Log::debug(sprintf('Got a code from YNAB: %s', $code));
|
||||
|
||||
// we have a code. Make the job ready for the next step, and then redirect the user.
|
||||
$configuration = $repository->getConfiguration($importJob);
|
||||
$configuration['auth_code'] = $code;
|
||||
$repository->setConfiguration($importJob, $configuration);
|
||||
|
||||
// set stage to make the import routine take the correct action:
|
||||
$repository->setStatus($importJob, 'ready_to_run');
|
||||
$repository->setStage($importJob, 'get_access_token');
|
||||
|
||||
return redirect(route('import.job.status.index', [$importJob->key]));
|
||||
}
|
||||
|
||||
}
|
@ -1,198 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* IndexController.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\Http\Controllers\Import;
|
||||
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Import\Prerequisites\PrerequisitesInterface;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use FireflyIII\Support\Binder\ImportProvider;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Response as LaravelResponse;
|
||||
use Illuminate\Routing\Redirector;
|
||||
use Illuminate\View\View;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class IndexController
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class IndexController extends Controller
|
||||
{
|
||||
/** @var array All available providers */
|
||||
public $providers;
|
||||
/** @var ImportJobRepositoryInterface The import job repository */
|
||||
public $repository;
|
||||
/** @var UserRepositoryInterface The user repository */
|
||||
public $userRepository;
|
||||
|
||||
/**
|
||||
* IndexController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('mainTitleIcon', 'fa-archive');
|
||||
app('view')->share('title', (string) trans('firefly.import_index_title'));
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->userRepository = app(UserRepositoryInterface::class);
|
||||
$this->providers = ImportProvider::getProviders();
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new import job for $importProvider.
|
||||
*
|
||||
* @param string $importProvider
|
||||
*
|
||||
* @return RedirectResponse|Redirector
|
||||
*
|
||||
*/
|
||||
public function create(string $importProvider)
|
||||
{
|
||||
$hasPreReq = (bool) config(sprintf('import.has_prereq.%s', $importProvider));
|
||||
$hasConfig = (bool) config(sprintf('import.has_job_config.%s', $importProvider));
|
||||
$allowedForDemo = (bool) config(sprintf('import.allowed_for_demo.%s', $importProvider));
|
||||
$isDemoUser = $this->userRepository->hasRole(auth()->user(), 'demo');
|
||||
|
||||
Log::debug(sprintf('Will create job for provider "%s"', $importProvider));
|
||||
Log::debug(sprintf('Is demo user? %s', var_export($isDemoUser, true)));
|
||||
Log::debug(sprintf('Is allowed for user? %s', var_export($allowedForDemo, true)));
|
||||
Log::debug(sprintf('Has prerequisites? %s', var_export($hasPreReq, true)));
|
||||
Log::debug(sprintf('Has config? %s', var_export($hasConfig, true)));
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
if ($isDemoUser && !$allowedForDemo) {
|
||||
Log::debug('User is demo and this provider doesnt work for demo users.');
|
||||
|
||||
return redirect(route('import.index'));
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
$importJob = $this->repository->create($importProvider);
|
||||
|
||||
Log::debug(sprintf('Created job #%d for provider %s', $importJob->id, $importProvider));
|
||||
|
||||
// no prerequisites but job has config:
|
||||
if (false === $hasPreReq && false !== $hasConfig) {
|
||||
Log::debug('Provider has no prerequisites. Continue.');
|
||||
$this->repository->setStatus($importJob, 'has_prereq');
|
||||
Log::debug('Redirect to configuration.');
|
||||
|
||||
return redirect(route('import.job.configuration.index', [$importJob->key]));
|
||||
}
|
||||
|
||||
// job has prerequisites:
|
||||
Log::debug('Job provider has prerequisites.');
|
||||
/** @var PrerequisitesInterface $providerPre */
|
||||
$providerPre = app((string) config(sprintf('import.prerequisites.%s', $importProvider)));
|
||||
$providerPre->setUser($importJob->user);
|
||||
|
||||
// and are not filled in:
|
||||
if (!$providerPre->isComplete()) {
|
||||
Log::debug('Job provider prerequisites are not yet filled in. Redirect to prerequisites-page.');
|
||||
|
||||
// redirect to global prerequisites
|
||||
return redirect(route('import.prerequisites.index', [$importProvider, $importJob->key]));
|
||||
}
|
||||
Log::debug('Prerequisites are complete.');
|
||||
|
||||
// but are filled in:
|
||||
$this->repository->setStatus($importJob, 'has_prereq');
|
||||
|
||||
// and has no config:
|
||||
if (false === $hasConfig) {
|
||||
// @codeCoverageIgnoreStart
|
||||
Log::debug('Provider has no configuration. Job is ready to start.');
|
||||
$this->repository->setStatus($importJob, 'ready_to_run');
|
||||
Log::debug('Redirect to status-page.');
|
||||
|
||||
return redirect(route('import.job.status.index', [$importJob->key]));
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
// but also needs config:
|
||||
Log::debug('Job has configuration. Redirect to job-config.');
|
||||
|
||||
// Otherwise just redirect to job configuration.
|
||||
return redirect(route('import.job.configuration.index', [$importJob->key]));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a JSON file of the job's configuration and send it to the user.
|
||||
*
|
||||
* @param ImportJob $job
|
||||
*
|
||||
* @return LaravelResponse
|
||||
*/
|
||||
public function download(ImportJob $job): LaravelResponse
|
||||
{
|
||||
Log::debug('Now in download()', ['job' => $job->key]);
|
||||
$config = $this->repository->getConfiguration($job);
|
||||
// This is CSV import specific:
|
||||
$config['delimiter'] = $config['delimiter'] ?? ',';
|
||||
$config['delimiter'] = "\t" === $config['delimiter'] ? 'tab' : $config['delimiter'];
|
||||
|
||||
$result = json_encode($config, JSON_PRETTY_PRINT);
|
||||
$name = sprintf('"%s"', addcslashes('import-configuration-' . date('Y-m-d') . '.json', '"\\'));
|
||||
/** @var LaravelResponse $response */
|
||||
$response = response($result);
|
||||
$response->header('Content-disposition', 'attachment; filename=' . $name)
|
||||
->header('Content-Type', 'application/json')
|
||||
->header('Content-Description', 'File Transfer')
|
||||
->header('Connection', 'Keep-Alive')
|
||||
->header('Expires', '0')
|
||||
->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
|
||||
->header('Pragma', 'public')
|
||||
->header('Content-Length', strlen($result));
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* General import index.
|
||||
*
|
||||
* @return Factory|View
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$providers = $this->providers;
|
||||
$subTitle = (string) trans('import.index_breadcrumb');
|
||||
$subTitleIcon = 'fa-home';
|
||||
$isDemoUser = $this->userRepository->hasRole(auth()->user(), 'demo');
|
||||
|
||||
return view('import.index', compact('subTitle', 'subTitleIcon', 'providers', 'isDemoUser'));
|
||||
}
|
||||
}
|
@ -1,169 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* JobConfigurationController.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\Http\Controllers\Import;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Controllers\CreateStuff;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Routing\Redirector;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Illuminate\View\View;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class JobConfigurationController
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class JobConfigurationController extends Controller
|
||||
{
|
||||
use CreateStuff;
|
||||
/** @var ImportJobRepositoryInterface The import job repository */
|
||||
public $repository;
|
||||
|
||||
/**
|
||||
* JobConfigurationController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('mainTitleIcon', 'fa-archive');
|
||||
app('view')->share('title', (string) trans('firefly.import_index_title'));
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the job. This method is returned to until job is deemed "configured".
|
||||
*
|
||||
* @param ImportJob $importJob
|
||||
*
|
||||
* @throws FireflyException
|
||||
*
|
||||
* @return Factory|RedirectResponse|Redirector|View
|
||||
*
|
||||
*/
|
||||
public function index(ImportJob $importJob)
|
||||
{
|
||||
Log::debug('Now in JobConfigurationController::index()');
|
||||
$allowed = ['has_prereq', 'need_job_config'];
|
||||
if (null !== $importJob && !in_array($importJob->status, $allowed, true)) {
|
||||
Log::error(sprintf('Job has state "%s", but we only accept %s', $importJob->status, json_encode($allowed)));
|
||||
session()->flash('error', (string) trans('import.bad_job_status', ['status' => e($importJob->status)]));
|
||||
|
||||
return redirect(route('import.index'));
|
||||
}
|
||||
Log::debug(sprintf('Now in JobConfigurationController::index() with job "%s" and status "%s"', $importJob->key, $importJob->status));
|
||||
|
||||
// if provider has no config, just push it through:
|
||||
$importProvider = $importJob->provider;
|
||||
if (!(bool) config(sprintf('import.has_job_config.%s', $importProvider))) {
|
||||
// @codeCoverageIgnoreStart
|
||||
Log::debug('Job needs no config, is ready to run!');
|
||||
$this->repository->setStatus($importJob, 'ready_to_run');
|
||||
|
||||
return redirect(route('import.job.status.index', [$importJob->key]));
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
$configurator = $this->makeConfigurator($importJob);
|
||||
if ($configurator->configurationComplete()) {
|
||||
Log::debug('Config is complete, set status to ready_to_run.');
|
||||
$this->repository->setStatus($importJob, 'ready_to_run');
|
||||
|
||||
return redirect(route('import.job.status.index', [$importJob->key]));
|
||||
}
|
||||
|
||||
$view = $configurator->getNextView();
|
||||
$data = $configurator->getNextData();
|
||||
$subTitle = (string) trans('import.job_configuration_breadcrumb', ['key' => $importJob->key]);
|
||||
$subTitleIcon = 'fa-wrench';
|
||||
|
||||
return view($view, compact('data', 'importJob', 'subTitle', 'subTitleIcon'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the configuration. Returns to "configure" method until job is configured.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param ImportJob $importJob
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @return RedirectResponse|Redirector
|
||||
*
|
||||
*/
|
||||
public function post(Request $request, ImportJob $importJob)
|
||||
{
|
||||
// catch impossible status:
|
||||
$allowed = ['has_prereq', 'need_job_config'];
|
||||
if (null !== $importJob && !in_array($importJob->status, $allowed, true)) {
|
||||
session()->flash('error', (string) trans('import.bad_job_status', ['status' => e($importJob->status)]));
|
||||
|
||||
return redirect(route('import.index'));
|
||||
}
|
||||
|
||||
Log::debug('Now in postConfigure()', ['job' => $importJob->key]);
|
||||
$configurator = $this->makeConfigurator($importJob);
|
||||
|
||||
// is the job already configured?
|
||||
if ($configurator->configurationComplete()) {
|
||||
$this->repository->setStatus($importJob, 'ready_to_run');
|
||||
|
||||
return redirect(route('import.job.status.index', [$importJob->key]));
|
||||
}
|
||||
|
||||
// uploaded files are attached to the job.
|
||||
// the configurator can then handle them.
|
||||
$result = new MessageBag;
|
||||
|
||||
/** @var UploadedFile $upload */
|
||||
foreach ($request->allFiles() as $name => $upload) {
|
||||
$result = $this->repository->storeFileUpload($importJob, $name, $upload);
|
||||
}
|
||||
$data = $request->all();
|
||||
$messages = $configurator->configureJob($data);
|
||||
$result->merge($messages);
|
||||
|
||||
if ($messages->count() > 0) {
|
||||
$request->session()->flash('warning', $messages->first());
|
||||
}
|
||||
|
||||
// return to configure
|
||||
return redirect(route('import.job.configuration.index', [$importJob->key]));
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,240 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* JobStatusController.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\Http\Controllers\Import;
|
||||
|
||||
use Exception;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Import\Routine\RoutineInterface;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Controllers\CreateStuff;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class JobStatusController
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class JobStatusController extends Controller
|
||||
{
|
||||
use CreateStuff;
|
||||
/** @var ImportJobRepositoryInterface The import job repository */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* JobStatusController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
// set time limit to zero to prevent timeouts.
|
||||
set_time_limit(0);
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('mainTitleIcon', 'fa-archive');
|
||||
app('view')->share('title', (string) trans('firefly.import_index_title'));
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Index for job status.
|
||||
*
|
||||
* @param ImportJob $importJob
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
*/
|
||||
public function index(ImportJob $importJob)
|
||||
{
|
||||
$subTitleIcon = 'fa-gear';
|
||||
$subTitle = (string) trans('import.job_status_breadcrumb', ['key' => $importJob->key]);
|
||||
|
||||
return view('import.status', compact('importJob', 'subTitle', 'subTitleIcon'));
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON overview of job status.
|
||||
*
|
||||
* @param ImportJob $importJob
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function json(ImportJob $importJob): JsonResponse
|
||||
{
|
||||
$count = $this->repository->countTransactions($importJob);
|
||||
$json = [
|
||||
'status' => $importJob->status,
|
||||
'errors' => $importJob->errors,
|
||||
'count' => $count,
|
||||
'tag_id' => $importJob->tag_id,
|
||||
'tag_name' => null === $importJob->tag_id ? null : $importJob->tag->tag,
|
||||
'report_txt' => (string) trans('import.unknown_import_result'),
|
||||
'download_config' => false,
|
||||
'download_config_text' => '',
|
||||
];
|
||||
|
||||
if ('file' === $importJob->provider) {
|
||||
$json['download_config'] = true;
|
||||
$json['download_config_text']
|
||||
= trans('import.should_download_config', ['route' => route('import.job.download', [$importJob->key])]) . ' '
|
||||
. trans('import.share_config_file');
|
||||
}
|
||||
|
||||
// if count is zero:
|
||||
if (null !== $importJob->tag_id) {
|
||||
$count = $this->repository->countByTag($importJob);
|
||||
}
|
||||
if (0 === $count) {
|
||||
$json['report_txt'] = (string) trans('import.result_no_transactions');
|
||||
}
|
||||
if (1 === $count && null !== $importJob->tag_id) {
|
||||
$json['report_txt'] = trans(
|
||||
'import.result_one_transaction',
|
||||
['route' => route('tags.show', [$importJob->tag_id, 'all']), 'tag' => $importJob->tag->tag]
|
||||
);
|
||||
}
|
||||
if ($count > 1 && null !== $importJob->tag_id) {
|
||||
$json['report_txt'] = trans(
|
||||
'import.result_many_transactions',
|
||||
['count' => $count, 'route' => route('tags.show', [$importJob->tag_id, 'all']), 'tag' => $importJob->tag->tag]
|
||||
);
|
||||
}
|
||||
|
||||
return response()->json($json);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls to start the job.
|
||||
*
|
||||
* @param ImportJob $importJob
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function start(ImportJob $importJob): JsonResponse
|
||||
{
|
||||
Log::info('Now in JobStatusController::start');
|
||||
// catch impossible status:
|
||||
$allowed = ['ready_to_run', 'need_job_config'];
|
||||
|
||||
if (null !== $importJob && !in_array($importJob->status, $allowed, true)) {
|
||||
Log::error(sprintf('Job is not ready. Status should be in array, but is %s', $importJob->status), $allowed);
|
||||
$this->repository->setStatus($importJob, 'error');
|
||||
|
||||
return response()->json(
|
||||
['status' => 'NOK', 'message' => sprintf('JobStatusController::start expects status "ready_to_run" instead of "%s".', $importJob->status)]
|
||||
);
|
||||
}
|
||||
$importProvider = $importJob->provider;
|
||||
$key = sprintf('import.routine.%s', $importProvider);
|
||||
$className = config($key);
|
||||
if (null === $className || !class_exists($className)) {
|
||||
// @codeCoverageIgnoreStart
|
||||
$message = sprintf('Cannot find import routine class for job of type "%s".', $importProvider);
|
||||
Log::error($message);
|
||||
|
||||
return response()->json(
|
||||
['status' => 'NOK', 'message' => $message]
|
||||
);
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
/** @var RoutineInterface $routine */
|
||||
$routine = app($className);
|
||||
$routine->setImportJob($importJob);
|
||||
|
||||
Log::debug(sprintf('Created class of type %s', $className));
|
||||
|
||||
try {
|
||||
Log::debug(sprintf('Try to call %s:run()', $className));
|
||||
$routine->run();
|
||||
} catch (FireflyException|Exception $e) {
|
||||
$message = 'The import routine crashed: ' . $e->getMessage();
|
||||
Log::error($message);
|
||||
Log::error($e->getTraceAsString());
|
||||
|
||||
// set job errored out:
|
||||
$this->repository->setStatus($importJob, 'error');
|
||||
|
||||
return response()->json(['status' => 'NOK', 'message' => $message]);
|
||||
}
|
||||
|
||||
// expect nothing from routine, just return OK to user.
|
||||
Log::info('Now finished with JobStatusController::start');
|
||||
|
||||
return response()->json(['status' => 'OK', 'message' => 'stage_finished']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store does three things:
|
||||
*
|
||||
* - Store the transactions.
|
||||
* - Add them to a tag.
|
||||
*
|
||||
* @param ImportJob $importJob
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function store(ImportJob $importJob): JsonResponse
|
||||
{
|
||||
Log::info('Now in JobStatusController::store');
|
||||
// catch impossible status:
|
||||
$allowed = ['provider_finished', 'storing_data'];
|
||||
if (null !== $importJob && !in_array($importJob->status, $allowed, true)) {
|
||||
Log::error(sprintf('Job is not ready. Status should be in array, but is %s', $importJob->status), $allowed);
|
||||
|
||||
return response()->json(
|
||||
['status' => 'NOK', 'message' => sprintf('JobStatusController::start expects status "provider_finished" instead of "%s".', $importJob->status)]
|
||||
);
|
||||
}
|
||||
|
||||
// set job to be storing data:
|
||||
$this->repository->setStatus($importJob, 'storing_data');
|
||||
|
||||
try {
|
||||
$this->storeTransactions($importJob);
|
||||
} catch (FireflyException $e) {
|
||||
$message = 'The import storage routine crashed: ' . $e->getMessage();
|
||||
Log::error($message);
|
||||
Log::error($e->getTraceAsString());
|
||||
|
||||
// set job errored out:
|
||||
$this->repository->setStatus($importJob, 'error');
|
||||
|
||||
return response()->json(['status' => 'NOK', 'message' => $message]);
|
||||
}
|
||||
// set storage to be finished:
|
||||
$this->repository->setStatus($importJob, 'storage_finished');
|
||||
|
||||
Log::info('Now finished with JobStatusController::start');
|
||||
|
||||
// expect nothing from routine, just return OK to user.
|
||||
return response()->json(['status' => 'OK', 'message' => 'storage_finished']);
|
||||
}
|
||||
}
|
@ -1,177 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* PrerequisitesController.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\Http\Controllers\Import;
|
||||
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Import\Prerequisites\PrerequisitesInterface;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Redirector;
|
||||
use Illuminate\View\View;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class PrerequisitesController
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class PrerequisitesController extends Controller
|
||||
{
|
||||
|
||||
/** @var ImportJobRepositoryInterface The import job repository */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* PrerequisitesController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('mainTitleIcon', 'fa-archive');
|
||||
app('view')->share('title', (string) trans('firefly.import_index_title'));
|
||||
app('view')->share('subTitleIcon', 'fa-check');
|
||||
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will process and store import provider global prerequisites
|
||||
* such as API keys.
|
||||
*
|
||||
* @param string $importProvider
|
||||
* @param ImportJob $importJob
|
||||
*
|
||||
* @return Factory|RedirectResponse|Redirector|View
|
||||
*/
|
||||
public function index(string $importProvider, ImportJob $importJob = null)
|
||||
{
|
||||
// catch impossible status:
|
||||
$allowed = ['new'];
|
||||
if (null !== $importJob && !in_array($importJob->status, $allowed, true)) {
|
||||
Log::error(sprintf('Job has state "%s" but this Prerequisites::index() only accepts %s', $importJob->status, json_encode($allowed)));
|
||||
session()->flash('error', (string) trans('import.bad_job_status', ['status' => e($importJob->status)]));
|
||||
|
||||
return redirect(route('import.index'));
|
||||
}
|
||||
|
||||
app('view')->share('subTitle', (string) trans('import.prerequisites_breadcrumb_' . $importProvider));
|
||||
$class = (string) config(sprintf('import.prerequisites.%s', $importProvider));
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
/** @var PrerequisitesInterface $object */
|
||||
$object = app($class);
|
||||
$object->setUser($user);
|
||||
|
||||
if (null !== $importJob && $object->isComplete()) {
|
||||
// update job:
|
||||
$this->repository->setStatus($importJob, 'has_prereq');
|
||||
|
||||
// redirect to job config:
|
||||
return redirect(route('import.job.configuration.index', [$importJob->key]));
|
||||
}
|
||||
|
||||
|
||||
$view = $object->getView();
|
||||
$parameters = ['title' => (string) trans('firefly.import_index_title'), 'mainTitleIcon' => 'fa-archive', 'importJob' => $importJob];
|
||||
$parameters = array_merge($object->getViewParameters(), $parameters);
|
||||
|
||||
return view($view, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method processes the prerequisites the user has entered in the previous step.
|
||||
*
|
||||
* Whatever storePrerequisites does, it should make sure that the system is ready to continue immediately. So
|
||||
* no extra calls or stuff, except maybe to open a session
|
||||
*
|
||||
* @param Request $request
|
||||
* @param string $importProvider
|
||||
* @param ImportJob $importJob
|
||||
*
|
||||
* @return RedirectResponse|Redirector
|
||||
* @see PrerequisitesInterface::storePrerequisites
|
||||
*
|
||||
*/
|
||||
public function post(Request $request, string $importProvider, ImportJob $importJob = null)
|
||||
{
|
||||
Log::debug(sprintf('Now in postPrerequisites for %s', $importProvider));
|
||||
|
||||
// catch impossible status:
|
||||
$allowed = ['new'];
|
||||
if (null !== $importJob && !in_array($importJob->status, $allowed, true)) {
|
||||
Log::error(sprintf('Job has state "%s" but this Prerequisites::post() only accepts %s', $importJob->status, json_encode($allowed)));
|
||||
session()->flash('error', (string) trans('import.bad_job_status', ['status' => e($importJob->status)]));
|
||||
|
||||
return redirect(route('import.index'));
|
||||
}
|
||||
|
||||
|
||||
$class = (string) config(sprintf('import.prerequisites.%s', $importProvider));
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
/** @var PrerequisitesInterface $object */
|
||||
$object = app($class);
|
||||
$object->setUser($user);
|
||||
Log::debug('Going to store entered prerequisites.');
|
||||
// store post data
|
||||
$data = $request->all();
|
||||
$result = $object->storePrerequisites($data);
|
||||
Log::debug(sprintf('Result of storePrerequisites has message count: %d', $result->count()));
|
||||
|
||||
if ($result->count() > 0) {
|
||||
$request->session()->flash('error', e($result->first()));
|
||||
|
||||
// redirect back to job, if has job:
|
||||
return redirect(route('import.prerequisites.index', [$importProvider, $importJob->key ?? '']))->withInput();
|
||||
}
|
||||
|
||||
// session flash!
|
||||
$request->session()->flash('success', (string) trans('import.prerequisites_saved_for_' . $importProvider));
|
||||
|
||||
// if has job, redirect to global config for provider
|
||||
// if no job, back to index!
|
||||
if (null === $importJob) {
|
||||
return redirect(route('import.index'));
|
||||
}
|
||||
|
||||
// update job:
|
||||
$this->repository->setStatus($importJob, 'has_prereq');
|
||||
|
||||
// redirect to job config:
|
||||
return redirect(route('import.job.configuration.index', [$importJob->key]));
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
@ -95,6 +96,30 @@ class JavascriptController extends Controller
|
||||
->header('Content-Type', 'text/javascript');
|
||||
}
|
||||
|
||||
/**
|
||||
* Bit of a hack but OK.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function variablesV2(Request $request): Response
|
||||
{
|
||||
/** @var Carbon $start */
|
||||
$start = clone session('start', Carbon::now()->startOfMonth());
|
||||
/** @var Carbon $end */
|
||||
$end = clone session('end', Carbon::now()->endOfMonth());
|
||||
|
||||
$data = [
|
||||
'start' => $start->format('Y-m-d'),
|
||||
'end' => $end->format('Y-m-d'),
|
||||
];
|
||||
|
||||
return response()
|
||||
->view('javascript.variables', $data)
|
||||
->header('Content-Type', 'text/javascript');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show some common variables to be used in scripts.
|
||||
*
|
||||
|
@ -27,6 +27,7 @@ use Carbon\Carbon;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\ObjectGroup;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
@ -35,6 +36,7 @@ use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
||||
use FireflyIII\Repositories\ObjectGroup\ObjectGroupRepositoryInterface;
|
||||
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||
use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface;
|
||||
@ -342,6 +344,34 @@ class AutoCompleteController extends Controller
|
||||
return response()->json($return);
|
||||
}
|
||||
|
||||
/**
|
||||
* An auto-complete specifically for expense accounts, used when mass updating mostly.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function objectGroups(Request $request): JsonResponse
|
||||
{
|
||||
$search = $request->get('search');
|
||||
|
||||
/** @var ObjectGroupRepositoryInterface $repository */
|
||||
$repository = app(ObjectGroupRepositoryInterface::class);
|
||||
|
||||
$return = [];
|
||||
$result = $repository->search((string) $search);
|
||||
|
||||
/** @var ObjectGroup $account */
|
||||
foreach ($result as $objectGroup) {
|
||||
$return[] = [
|
||||
'id' => $objectGroup->id,
|
||||
'title' => $objectGroup->title,
|
||||
];
|
||||
}
|
||||
|
||||
return response()->json($return);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return JsonResponse
|
||||
* @codeCoverageIgnore
|
||||
|
70
app/Http/Controllers/ObjectGroup/DeleteController.php
Normal file
70
app/Http/Controllers/ObjectGroup/DeleteController.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers\ObjectGroup;
|
||||
|
||||
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Models\ObjectGroup;
|
||||
use FireflyIII\Repositories\ObjectGroup\ObjectGroupRepositoryInterface;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
|
||||
/**
|
||||
* Class DeleteController
|
||||
*/
|
||||
class DeleteController extends Controller
|
||||
{
|
||||
private ObjectGroupRepositoryInterface $repository;
|
||||
|
||||
/**
|
||||
* PiggyBankController constructor.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('mainTitleIcon', 'fa-envelope-o');
|
||||
app('view')->share('title', (string) trans('firefly.object_groups_page_title'));
|
||||
|
||||
$this->repository = app(ObjectGroupRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a piggy bank.
|
||||
*
|
||||
* @param ObjectGroup $objectGroup
|
||||
*/
|
||||
public function delete(ObjectGroup $objectGroup)
|
||||
{
|
||||
$subTitle = (string) trans('firefly.delete_object_group', ['title' => $objectGroup->title]);
|
||||
$piggyBanks = $objectGroup->piggyBanks()->count();
|
||||
|
||||
// put previous url in session
|
||||
$this->rememberPreviousUri('object-groups.delete.uri');
|
||||
|
||||
return view('object-groups.delete', compact('objectGroup', 'subTitle', 'piggyBanks'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy the piggy bank.
|
||||
*
|
||||
* @param ObjectGroup $objectGroup
|
||||
*/
|
||||
public function destroy(ObjectGroup $objectGroup): RedirectResponse
|
||||
{
|
||||
session()->flash('success', (string) trans('firefly.deleted_object_group', ['title' => $objectGroup->title]));
|
||||
app('preferences')->mark();
|
||||
$this->repository->destroy($objectGroup);
|
||||
|
||||
return redirect($this->getPreviousUri('object-groups.delete.uri'));
|
||||
}
|
||||
|
||||
}
|
87
app/Http/Controllers/ObjectGroup/EditController.php
Normal file
87
app/Http/Controllers/ObjectGroup/EditController.php
Normal file
@ -0,0 +1,87 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers\ObjectGroup;
|
||||
|
||||
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Http\Requests\ObjectGroupFormRequest;
|
||||
use FireflyIII\Models\ObjectGroup;
|
||||
use FireflyIII\Repositories\ObjectGroup\ObjectGroupRepositoryInterface;
|
||||
|
||||
/**
|
||||
* Class EditController
|
||||
*/
|
||||
class EditController extends Controller
|
||||
{
|
||||
private ObjectGroupRepositoryInterface $repository;
|
||||
|
||||
/**
|
||||
* PiggyBankController constructor.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('mainTitleIcon', 'fa-envelope-o');
|
||||
app('view')->share('title', (string) trans('firefly.object_groups_page_title'));
|
||||
|
||||
$this->repository = app(ObjectGroupRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit an object group.
|
||||
*
|
||||
* @param ObjectGroup $objectGroup
|
||||
*/
|
||||
public function edit(ObjectGroup $objectGroup)
|
||||
{
|
||||
$subTitle = (string) trans('firefly.edit_object_group', ['title' => $objectGroup->title]);
|
||||
$subTitleIcon = 'fa-pencil';
|
||||
$targetDate = null;
|
||||
$startDate = null;
|
||||
|
||||
if (true !== session('object-groups.edit.fromUpdate')) {
|
||||
$this->rememberPreviousUri('object-groups.edit.uri');
|
||||
}
|
||||
session()->forget('object-groups.edit.fromUpdate');
|
||||
|
||||
return view('object-groups.edit', compact('subTitle', 'subTitleIcon', 'objectGroup'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update a piggy bank.
|
||||
*
|
||||
* @param ObjectGroupFormRequest $request
|
||||
* @param ObjectGroup $objectGroup
|
||||
*/
|
||||
public function update(ObjectGroupFormRequest $request, ObjectGroup $objectGroup)
|
||||
{
|
||||
$data = $request->getObjectGroupData();
|
||||
$piggyBank = $this->repository->update($objectGroup, $data);
|
||||
|
||||
session()->flash('success', (string) trans('firefly.updated_object_group', ['title' => $objectGroup->title]));
|
||||
app('preferences')->mark();
|
||||
|
||||
$redirect = redirect($this->getPreviousUri('object-groups.edit.uri'));
|
||||
|
||||
if (1 === (int) $request->get('return_to_edit')) {
|
||||
// @codeCoverageIgnoreStart
|
||||
session()->put('object-groups.edit.fromUpdate', true);
|
||||
|
||||
$redirect = redirect(route('object-groups.edit', [$piggyBank->id]));
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
return $redirect;
|
||||
}
|
||||
}
|
65
app/Http/Controllers/ObjectGroup/IndexController.php
Normal file
65
app/Http/Controllers/ObjectGroup/IndexController.php
Normal file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers\ObjectGroup;
|
||||
|
||||
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Models\ObjectGroup;
|
||||
use FireflyIII\Repositories\ObjectGroup\ObjectGroupRepositoryInterface;
|
||||
use Illuminate\Http\Request;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class IndexController
|
||||
*/
|
||||
class IndexController extends Controller
|
||||
{
|
||||
private ObjectGroupRepositoryInterface $repository;
|
||||
|
||||
/**
|
||||
* IndexController constructor.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
// translations:
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('mainTitleIcon', 'fa-envelope-o');
|
||||
app('view')->share('title', (string) trans('firefly.object_groups_page_title'));
|
||||
$this->repository = app(ObjectGroupRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->repository->sort();
|
||||
$subTitle = (string) trans('firefly.object_groups_index');
|
||||
$objectGroups = $this->repository->get();
|
||||
|
||||
return view('object-groups.index', compact('subTitle', 'objectGroups'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ObjectGroup $objectGroup
|
||||
*/
|
||||
public function setOrder(Request $request, ObjectGroup $objectGroup)
|
||||
{
|
||||
Log::debug(sprintf('Found object group #%d "%s"', $objectGroup->id, $objectGroup->title));
|
||||
$newOrder = (int) $request->get('order');
|
||||
$this->repository->setOrder($objectGroup, $newOrder);
|
||||
|
||||
return response()->json([]);
|
||||
}
|
||||
|
||||
}
|
201
app/Http/Controllers/PiggyBank/AmountController.php
Normal file
201
app/Http/Controllers/PiggyBank/AmountController.php
Normal file
@ -0,0 +1,201 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers\PiggyBank;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class AmountController
|
||||
*/
|
||||
class AmountController extends Controller
|
||||
{
|
||||
|
||||
private AccountRepositoryInterface $accountRepos;
|
||||
private PiggyBankRepositoryInterface $piggyRepos;
|
||||
|
||||
/**
|
||||
* PiggyBankController constructor.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.piggyBanks'));
|
||||
app('view')->share('mainTitleIcon', 'fa-bullseye');
|
||||
|
||||
$this->piggyRepos = app(PiggyBankRepositoryInterface::class);
|
||||
$this->accountRepos = app(AccountRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add money to piggy bank.
|
||||
*
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return Factory|View
|
||||
*/
|
||||
public function add(PiggyBank $piggyBank)
|
||||
{
|
||||
$leftOnAccount = $this->piggyRepos->leftOnAccount($piggyBank, new Carbon);
|
||||
$savedSoFar = $this->piggyRepos->getCurrentAmount($piggyBank);
|
||||
$leftToSave = bcsub($piggyBank->targetamount, $savedSoFar);
|
||||
$maxAmount = min($leftOnAccount, $leftToSave);
|
||||
$currency = $this->accountRepos->getAccountCurrency($piggyBank->account) ?? app('amount')->getDefaultCurrency();
|
||||
|
||||
return view('piggy-banks.add', compact('piggyBank', 'maxAmount', 'currency'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add money to piggy bank (for mobile devices).
|
||||
*
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return Factory|View
|
||||
*/
|
||||
public function addMobile(PiggyBank $piggyBank)
|
||||
{
|
||||
/** @var Carbon $date */
|
||||
$date = session('end', new Carbon);
|
||||
$leftOnAccount = $this->piggyRepos->leftOnAccount($piggyBank, $date);
|
||||
$savedSoFar = $this->piggyRepos->getCurrentAmount($piggyBank);
|
||||
$leftToSave = bcsub($piggyBank->targetamount, $savedSoFar);
|
||||
$maxAmount = min($leftOnAccount, $leftToSave);
|
||||
$currency = $this->accountRepos->getAccountCurrency($piggyBank->account) ?? app('amount')->getDefaultCurrency();
|
||||
|
||||
return view('piggy-banks.add-mobile', compact('piggyBank', 'maxAmount', 'currency'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add money to piggy bank.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function postAdd(Request $request, PiggyBank $piggyBank): RedirectResponse
|
||||
{
|
||||
$amount = $request->get('amount') ?? '0';
|
||||
$currency = $this->accountRepos->getAccountCurrency($piggyBank->account) ?? app('amount')->getDefaultCurrency();
|
||||
// if amount is negative, make positive and continue:
|
||||
if (-1 === bccomp($amount, '0')) {
|
||||
$amount = bcmul($amount, '-1');
|
||||
}
|
||||
if ($this->piggyRepos->canAddAmount($piggyBank, $amount)) {
|
||||
$this->piggyRepos->addAmount($piggyBank, $amount);
|
||||
session()->flash(
|
||||
'success',
|
||||
(string) trans(
|
||||
'firefly.added_amount_to_piggy',
|
||||
['amount' => app('amount')->formatAnything($currency, $amount, false), 'name' => $piggyBank->name]
|
||||
)
|
||||
);
|
||||
app('preferences')->mark();
|
||||
|
||||
return redirect(route('piggy-banks.index'));
|
||||
}
|
||||
|
||||
Log::error('Cannot add ' . $amount . ' because canAddAmount returned false.');
|
||||
session()->flash(
|
||||
'error',
|
||||
(string) trans(
|
||||
'firefly.cannot_add_amount_piggy',
|
||||
['amount' => app('amount')->formatAnything($currency, $amount, false), 'name' => e($piggyBank->name)]
|
||||
)
|
||||
);
|
||||
|
||||
return redirect(route('piggy-banks.index'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove money from piggy bank.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function postRemove(Request $request, PiggyBank $piggyBank): RedirectResponse
|
||||
{
|
||||
$amount = $request->get('amount') ?? '0';
|
||||
$currency = $this->accountRepos->getAccountCurrency($piggyBank->account) ?? app('amount')->getDefaultCurrency();
|
||||
// if amount is negative, make positive and continue:
|
||||
if (-1 === bccomp($amount, '0')) {
|
||||
$amount = bcmul($amount, '-1');
|
||||
}
|
||||
if ($this->piggyRepos->canRemoveAmount($piggyBank, $amount)) {
|
||||
$this->piggyRepos->removeAmount($piggyBank, $amount);
|
||||
session()->flash(
|
||||
'success',
|
||||
(string) trans(
|
||||
'firefly.removed_amount_from_piggy',
|
||||
['amount' => app('amount')->formatAnything($currency, $amount, false), 'name' => $piggyBank->name]
|
||||
)
|
||||
);
|
||||
app('preferences')->mark();
|
||||
|
||||
return redirect(route('piggy-banks.index'));
|
||||
}
|
||||
|
||||
$amount = (string) round($request->get('amount'), 12);
|
||||
|
||||
session()->flash(
|
||||
'error',
|
||||
(string) trans(
|
||||
'firefly.cannot_remove_from_piggy',
|
||||
['amount' => app('amount')->formatAnything($currency, $amount, false), 'name' => e($piggyBank->name)]
|
||||
)
|
||||
);
|
||||
|
||||
return redirect(route('piggy-banks.index'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove money from piggy bank form.
|
||||
*
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return Factory|View
|
||||
*/
|
||||
public function remove(PiggyBank $piggyBank)
|
||||
{
|
||||
$repetition = $this->piggyRepos->getRepetition($piggyBank);
|
||||
$currency = $this->accountRepos->getAccountCurrency($piggyBank->account) ?? app('amount')->getDefaultCurrency();
|
||||
|
||||
return view('piggy-banks.remove', compact('piggyBank', 'repetition', 'currency'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove money from piggy bank (for mobile devices).
|
||||
*
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return Factory|View
|
||||
*/
|
||||
public function removeMobile(PiggyBank $piggyBank)
|
||||
{
|
||||
$repetition = $this->piggyRepos->getRepetition($piggyBank);
|
||||
$currency = $this->accountRepos->getAccountCurrency($piggyBank->account) ?? app('amount')->getDefaultCurrency();
|
||||
|
||||
return view('piggy-banks.remove-mobile', compact('piggyBank', 'repetition', 'currency'));
|
||||
}
|
||||
}
|
112
app/Http/Controllers/PiggyBank/CreateController.php
Normal file
112
app/Http/Controllers/PiggyBank/CreateController.php
Normal file
@ -0,0 +1,112 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers\PiggyBank;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Helpers\Attachments\AttachmentHelperInterface;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Http\Requests\PiggyBankFormRequest;
|
||||
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Routing\Redirector;
|
||||
use Illuminate\View\View;
|
||||
|
||||
/**
|
||||
* Class CreateController
|
||||
*/
|
||||
class CreateController extends Controller
|
||||
{
|
||||
private AttachmentHelperInterface $attachments;
|
||||
private PiggyBankRepositoryInterface $piggyRepos;
|
||||
|
||||
/**
|
||||
* PiggyBankController constructor.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.piggyBanks'));
|
||||
app('view')->share('mainTitleIcon', 'fa-bullseye');
|
||||
|
||||
$this->attachments = app(AttachmentHelperInterface::class);
|
||||
$this->piggyRepos = app(PiggyBankRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a piggy bank.
|
||||
*
|
||||
* @return Factory|View
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$subTitle = (string) trans('firefly.new_piggy_bank');
|
||||
$subTitleIcon = 'fa-plus';
|
||||
|
||||
// put previous url in session if not redirect from store (not "create another").
|
||||
if (true !== session('piggy-banks.create.fromStore')) {
|
||||
$this->rememberPreviousUri('piggy-banks.create.uri');
|
||||
}
|
||||
session()->forget('piggy-banks.create.fromStore');
|
||||
|
||||
return view('piggy-banks.create', compact('subTitle', 'subTitleIcon'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Store a new piggy bank.
|
||||
*
|
||||
* @param PiggyBankFormRequest $request
|
||||
*
|
||||
* @return RedirectResponse|Redirector
|
||||
*/
|
||||
public function store(PiggyBankFormRequest $request)
|
||||
{
|
||||
$data = $request->getPiggyBankData();
|
||||
if (null === $data['startdate']) {
|
||||
$data['startdate'] = new Carbon;
|
||||
}
|
||||
$piggyBank = $this->piggyRepos->store($data);
|
||||
|
||||
session()->flash('success', (string) trans('firefly.stored_piggy_bank', ['name' => $piggyBank->name]));
|
||||
app('preferences')->mark();
|
||||
|
||||
// store attachment(s):
|
||||
/** @var array $files */
|
||||
$files = $request->hasFile('attachments') ? $request->file('attachments') : null;
|
||||
if (null !== $files && !auth()->user()->hasRole('demo')) {
|
||||
$this->attachments->saveAttachmentsForModel($piggyBank, $files);
|
||||
}
|
||||
if (null !== $files && auth()->user()->hasRole('demo')) {
|
||||
session()->flash('info', (string) trans('firefly.no_att_demo_user'));
|
||||
}
|
||||
|
||||
if (count($this->attachments->getMessages()->get('attachments')) > 0) {
|
||||
$request->session()->flash('info', $this->attachments->getMessages()->get('attachments')); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
|
||||
$redirect = redirect($this->getPreviousUri('piggy-banks.create.uri'));
|
||||
|
||||
if (1 === (int) $request->get('create_another')) {
|
||||
// @codeCoverageIgnoreStart
|
||||
session()->put('piggy-banks.create.fromStore', true);
|
||||
|
||||
$redirect = redirect(route('piggy-banks.create'))->withInput();
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
return $redirect;
|
||||
}
|
||||
}
|
75
app/Http/Controllers/PiggyBank/DeleteController.php
Normal file
75
app/Http/Controllers/PiggyBank/DeleteController.php
Normal file
@ -0,0 +1,75 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers\PiggyBank;
|
||||
|
||||
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\View\View;
|
||||
|
||||
/**
|
||||
* Class DeleteController
|
||||
*/
|
||||
class DeleteController extends Controller
|
||||
{
|
||||
|
||||
private PiggyBankRepositoryInterface $piggyRepos;
|
||||
|
||||
/**
|
||||
* PiggyBankController constructor.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.piggyBanks'));
|
||||
app('view')->share('mainTitleIcon', 'fa-bullseye');
|
||||
|
||||
$this->piggyRepos = app(PiggyBankRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a piggy bank.
|
||||
*
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return Factory|View
|
||||
*/
|
||||
public function delete(PiggyBank $piggyBank)
|
||||
{
|
||||
$subTitle = (string) trans('firefly.delete_piggy_bank', ['name' => $piggyBank->name]);
|
||||
|
||||
// put previous url in session
|
||||
$this->rememberPreviousUri('piggy-banks.delete.uri');
|
||||
|
||||
return view('piggy-banks.delete', compact('piggyBank', 'subTitle'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy the piggy bank.
|
||||
*
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function destroy(PiggyBank $piggyBank): RedirectResponse
|
||||
{
|
||||
session()->flash('success', (string) trans('firefly.deleted_piggy_bank', ['name' => $piggyBank->name]));
|
||||
app('preferences')->mark();
|
||||
$this->piggyRepos->destroy($piggyBank);
|
||||
|
||||
return redirect($this->getPreviousUri('piggy-banks.delete.uri'));
|
||||
}
|
||||
}
|
133
app/Http/Controllers/PiggyBank/EditController.php
Normal file
133
app/Http/Controllers/PiggyBank/EditController.php
Normal file
@ -0,0 +1,133 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers\PiggyBank;
|
||||
|
||||
|
||||
use FireflyIII\Helpers\Attachments\AttachmentHelperInterface;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Http\Requests\PiggyBankFormRequest;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Routing\Redirector;
|
||||
use Illuminate\View\View;
|
||||
|
||||
/**
|
||||
* Class EditController
|
||||
*/
|
||||
class EditController extends Controller
|
||||
{
|
||||
private AttachmentHelperInterface $attachments;
|
||||
private PiggyBankRepositoryInterface $piggyRepos;
|
||||
|
||||
/**
|
||||
* PiggyBankController constructor.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.piggyBanks'));
|
||||
app('view')->share('mainTitleIcon', 'fa-bullseye');
|
||||
|
||||
$this->attachments = app(AttachmentHelperInterface::class);
|
||||
$this->piggyRepos = app(PiggyBankRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit a piggy bank.
|
||||
*
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return Factory|View
|
||||
*/
|
||||
public function edit(PiggyBank $piggyBank)
|
||||
{
|
||||
$subTitle = (string) trans('firefly.update_piggy_title', ['name' => $piggyBank->name]);
|
||||
$subTitleIcon = 'fa-pencil';
|
||||
$targetDate = null;
|
||||
$startDate = null;
|
||||
$note = $piggyBank->notes()->first();
|
||||
// Flash some data to fill the form.
|
||||
if (null !== $piggyBank->targetdate) {
|
||||
$targetDate = $piggyBank->targetdate->format('Y-m-d');
|
||||
}
|
||||
if (null !== $piggyBank->startdate) {
|
||||
$startDate = $piggyBank->startdate->format('Y-m-d');
|
||||
}
|
||||
|
||||
$preFilled = ['name' => $piggyBank->name,
|
||||
'account_id' => $piggyBank->account_id,
|
||||
'targetamount' => $piggyBank->targetamount,
|
||||
'targetdate' => $targetDate,
|
||||
'startdate' => $startDate,
|
||||
'object_group' => $piggyBank->objectGroups->first() ? $piggyBank->objectGroups->first()->title : '',
|
||||
'notes' => null === $note ? '' : $note->text,
|
||||
];
|
||||
session()->flash('preFilled', $preFilled);
|
||||
|
||||
// put previous url in session if not redirect from store (not "return_to_edit").
|
||||
if (true !== session('piggy-banks.edit.fromUpdate')) {
|
||||
$this->rememberPreviousUri('piggy-banks.edit.uri');
|
||||
}
|
||||
session()->forget('piggy-banks.edit.fromUpdate');
|
||||
|
||||
return view('piggy-banks.edit', compact('subTitle', 'subTitleIcon', 'piggyBank', 'preFilled'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update a piggy bank.
|
||||
*
|
||||
* @param PiggyBankFormRequest $request
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return RedirectResponse|Redirector
|
||||
*/
|
||||
public function update(PiggyBankFormRequest $request, PiggyBank $piggyBank)
|
||||
{
|
||||
$data = $request->getPiggyBankData();
|
||||
$piggyBank = $this->piggyRepos->update($piggyBank, $data);
|
||||
|
||||
session()->flash('success', (string) trans('firefly.updated_piggy_bank', ['name' => $piggyBank->name]));
|
||||
app('preferences')->mark();
|
||||
|
||||
// store new attachment(s):
|
||||
/** @var array $files */
|
||||
$files = $request->hasFile('attachments') ? $request->file('attachments') : null;
|
||||
if (null !== $files && !auth()->user()->hasRole('demo')) {
|
||||
$this->attachments->saveAttachmentsForModel($piggyBank, $files);
|
||||
}
|
||||
if (null !== $files && auth()->user()->hasRole('demo')) {
|
||||
session()->flash('info', (string) trans('firefly.no_att_demo_user'));
|
||||
}
|
||||
|
||||
if (count($this->attachments->getMessages()->get('attachments')) > 0) {
|
||||
$request->session()->flash('info', $this->attachments->getMessages()->get('attachments')); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
|
||||
$redirect = redirect($this->getPreviousUri('piggy-banks.edit.uri'));
|
||||
|
||||
if (1 === (int) $request->get('return_to_edit')) {
|
||||
// @codeCoverageIgnoreStart
|
||||
session()->put('piggy-banks.edit.fromUpdate', true);
|
||||
|
||||
$redirect = redirect(route('piggy-banks.edit', [$piggyBank->id]));
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
return $redirect;
|
||||
}
|
||||
|
||||
}
|
189
app/Http/Controllers/PiggyBank/IndexController.php
Normal file
189
app/Http/Controllers/PiggyBank/IndexController.php
Normal file
@ -0,0 +1,189 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers\PiggyBank;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Repositories\ObjectGroup\OrganisesObjectGroups;
|
||||
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||
use FireflyIII\Transformers\AccountTransformer;
|
||||
use FireflyIII\Transformers\PiggyBankTransformer;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
use Symfony\Component\HttpFoundation\ParameterBag;
|
||||
|
||||
/**
|
||||
* Class IndexController
|
||||
*/
|
||||
class IndexController extends Controller
|
||||
{
|
||||
use OrganisesObjectGroups;
|
||||
private PiggyBankRepositoryInterface $piggyRepos;
|
||||
|
||||
/**
|
||||
* PiggyBankController constructor.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.piggyBanks'));
|
||||
app('view')->share('mainTitleIcon', 'fa-bullseye');
|
||||
|
||||
$this->piggyRepos = app(PiggyBankRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show overview of all piggy banks.
|
||||
* TODO complicated
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return Factory|View
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$this->cleanupObjectGroups();
|
||||
$this->piggyRepos->correctOrder();
|
||||
$collection = $this->piggyRepos->getPiggyBanks();
|
||||
$accounts = [];
|
||||
/** @var Carbon $end */
|
||||
$end = session('end', Carbon::now()->endOfMonth());
|
||||
|
||||
// transform piggies using the transformer:
|
||||
$parameters = new ParameterBag;
|
||||
$parameters->set('end', $end);
|
||||
|
||||
// make piggy bank groups:
|
||||
$piggyBanks = [
|
||||
0 => [ // the index is the order, not the ID.
|
||||
'object_group_id' => 0,
|
||||
'object_group_title' => (string) trans('firefly.default_group_title_name'),
|
||||
'piggy_banks' => [],
|
||||
],
|
||||
];
|
||||
|
||||
/** @var PiggyBankTransformer $transformer */
|
||||
$transformer = app(PiggyBankTransformer::class);
|
||||
$transformer->setParameters(new ParameterBag);
|
||||
|
||||
/** @var AccountTransformer $accountTransformer */
|
||||
$accountTransformer = app(AccountTransformer::class);
|
||||
$accountTransformer->setParameters($parameters);
|
||||
/** @var PiggyBank $piggy */
|
||||
foreach ($collection as $piggy) {
|
||||
$array = $transformer->transform($piggy);
|
||||
$groupOrder = (int) $array['object_group_order'];
|
||||
// make group array if necessary:
|
||||
$piggyBanks[$groupOrder] = $piggyBanks[$groupOrder] ?? [
|
||||
'object_group_id' => $array['object_group_id'],
|
||||
'object_group_title' => $array['object_group_title'],
|
||||
'piggy_banks' => [],
|
||||
];
|
||||
|
||||
$account = $accountTransformer->transform($piggy->account);
|
||||
$accountId = (int) $account['id'];
|
||||
$array['attachments'] = $this->piggyRepos->getAttachments($piggy);
|
||||
if (!isset($accounts[$accountId])) {
|
||||
// create new:
|
||||
$accounts[$accountId] = $account;
|
||||
|
||||
// add some interesting details:
|
||||
$accounts[$accountId]['left'] = $accounts[$accountId]['current_balance'];
|
||||
$accounts[$accountId]['saved'] = 0;
|
||||
$accounts[$accountId]['target'] = 0;
|
||||
$accounts[$accountId]['to_save'] = 0;
|
||||
}
|
||||
|
||||
// calculate new interesting fields:
|
||||
$accounts[$accountId]['left'] -= $array['current_amount'];
|
||||
$accounts[$accountId]['saved'] += $array['current_amount'];
|
||||
$accounts[$accountId]['target'] += $array['target_amount'];
|
||||
$accounts[$accountId]['to_save'] += ($array['target_amount'] - $array['current_amount']);
|
||||
$array['account_name'] = $account['name'];
|
||||
$piggyBanks[$groupOrder]['piggy_banks'][] = $array;
|
||||
}
|
||||
// do a bunch of summaries.
|
||||
$piggyBanks = $this->makeSums($piggyBanks);
|
||||
|
||||
ksort($piggyBanks);
|
||||
|
||||
return view('piggy-banks.index', compact('piggyBanks', 'accounts'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $piggyBanks
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function makeSums(array $piggyBanks): array
|
||||
{
|
||||
$sums = [];
|
||||
foreach ($piggyBanks as $groupOrder => $group) {
|
||||
$groupId = $group['object_group_id'];
|
||||
foreach ($group['piggy_banks'] as $piggy) {
|
||||
$currencyId = $piggy['currency_id'];
|
||||
$sums[$groupId][$currencyId] = $sums[$groupId][$currencyId] ?? [
|
||||
'target' => '0',
|
||||
'saved' => '0',
|
||||
'left_to_save' => '0',
|
||||
'save_per_month' => '0',
|
||||
'currency_id' => $currencyId,
|
||||
'currency_code' => $piggy['currency_code'],
|
||||
'currency_symbol' => $piggy['currency_symbol'],
|
||||
'currency_decimal_places' => $piggy['currency_decimal_places'],
|
||||
];
|
||||
// target_amount
|
||||
// current_amount
|
||||
// left_to_save
|
||||
// save_per_month
|
||||
$sums[$groupId][$currencyId]['target'] = bcadd($sums[$groupId][$currencyId]['target'], (string) $piggy['target_amount']);
|
||||
$sums[$groupId][$currencyId]['saved'] = bcadd($sums[$groupId][$currencyId]['saved'], (string) $piggy['current_amount']);
|
||||
$sums[$groupId][$currencyId]['left_to_save'] = bcadd($sums[$groupId][$currencyId]['left_to_save'], (string) $piggy['left_to_save']);
|
||||
$sums[$groupId][$currencyId]['save_per_month'] = bcadd($sums[$groupId][$currencyId]['save_per_month'], (string) $piggy['save_per_month']);
|
||||
}
|
||||
}
|
||||
foreach ($piggyBanks as $groupOrder => $group) {
|
||||
$groupId = $group['object_group_id'];
|
||||
$piggyBanks[$groupOrder]['sums'] = $sums[$groupId];
|
||||
}
|
||||
|
||||
return $piggyBanks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the order of a piggy bank.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function setOrder(Request $request, PiggyBank $piggyBank): JsonResponse
|
||||
{
|
||||
$objectGroupTitle = $request->get('objectGroupTitle');
|
||||
$newOrder = (int) $request->get('order');
|
||||
$this->piggyRepos->setOrder($piggyBank, $newOrder);
|
||||
if ('' !== $objectGroupTitle) {
|
||||
$this->piggyRepos->setObjectGroup($piggyBank, $objectGroupTitle);
|
||||
}
|
||||
if ('' === $objectGroupTitle) {
|
||||
$this->piggyRepos->removeObjectGroup($piggyBank);
|
||||
}
|
||||
|
||||
return response()->json(['data' => 'OK']);
|
||||
}
|
||||
}
|
69
app/Http/Controllers/PiggyBank/ShowController.php
Normal file
69
app/Http/Controllers/PiggyBank/ShowController.php
Normal file
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers\PiggyBank;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||
use FireflyIII\Transformers\PiggyBankTransformer;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\View\View;
|
||||
use Symfony\Component\HttpFoundation\ParameterBag;
|
||||
|
||||
/**
|
||||
* Class ShowController
|
||||
*/
|
||||
class ShowController extends Controller
|
||||
{
|
||||
private PiggyBankRepositoryInterface $piggyRepos;
|
||||
|
||||
/**
|
||||
* PiggyBankController constructor.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.piggyBanks'));
|
||||
app('view')->share('mainTitleIcon', 'fa-bullseye');
|
||||
|
||||
$this->piggyRepos = app(PiggyBankRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a single piggy bank.
|
||||
*
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return Factory|View
|
||||
*/
|
||||
public function show(PiggyBank $piggyBank)
|
||||
{
|
||||
/** @var Carbon $end */
|
||||
$end = session('end', Carbon::now()->endOfMonth());
|
||||
// transform piggies using the transformer:
|
||||
$parameters = new ParameterBag;
|
||||
$parameters->set('end', $end);
|
||||
|
||||
/** @var PiggyBankTransformer $transformer */
|
||||
$transformer = app(PiggyBankTransformer::class);
|
||||
$transformer->setParameters($parameters);
|
||||
$piggy = $transformer->transform($piggyBank);
|
||||
$events = $this->piggyRepos->getEvents($piggyBank);
|
||||
$subTitle = $piggyBank->name;
|
||||
$attachments = $this->piggyRepos->getAttachments($piggyBank);
|
||||
|
||||
return view('piggy-banks.show', compact('piggyBank', 'events', 'subTitle', 'piggy', 'attachments'));
|
||||
}
|
||||
}
|
@ -1,525 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* PiggyBankController.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\Http\Controllers;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Helpers\Attachments\AttachmentHelperInterface;
|
||||
use FireflyIII\Http\Requests\PiggyBankFormRequest;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||
use FireflyIII\Transformers\AccountTransformer;
|
||||
use FireflyIII\Transformers\PiggyBankTransformer;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Routing\Redirector;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\View\View;
|
||||
use Log;
|
||||
use Symfony\Component\HttpFoundation\ParameterBag;
|
||||
|
||||
/**
|
||||
* Class PiggyBankController.
|
||||
*
|
||||
*/
|
||||
class PiggyBankController extends Controller
|
||||
{
|
||||
|
||||
/** @var AccountRepositoryInterface The account repository */
|
||||
private $accountRepos;
|
||||
/** @var CurrencyRepositoryInterface The currency repository */
|
||||
private $currencyRepos;
|
||||
/** @var PiggyBankRepositoryInterface Piggy bank repository. */
|
||||
private $piggyRepos;
|
||||
|
||||
/** @var AttachmentHelperInterface Helper for attachments. */
|
||||
private $attachments;
|
||||
|
||||
/**
|
||||
* PiggyBankController constructor.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('title', (string) trans('firefly.piggyBanks'));
|
||||
app('view')->share('mainTitleIcon', 'fa-bullseye');
|
||||
|
||||
$this->attachments = app(AttachmentHelperInterface::class);
|
||||
$this->piggyRepos = app(PiggyBankRepositoryInterface::class);
|
||||
$this->currencyRepos = app(CurrencyRepositoryInterface::class);
|
||||
$this->accountRepos = app(AccountRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add money to piggy bank.
|
||||
*
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return Factory|View
|
||||
*/
|
||||
public function add(PiggyBank $piggyBank)
|
||||
{
|
||||
$leftOnAccount = $this->piggyRepos->leftOnAccount($piggyBank, new Carbon);
|
||||
$savedSoFar = $this->piggyRepos->getCurrentAmount($piggyBank);
|
||||
$leftToSave = bcsub($piggyBank->targetamount, $savedSoFar);
|
||||
$maxAmount = min($leftOnAccount, $leftToSave);
|
||||
$currency = $this->accountRepos->getAccountCurrency($piggyBank->account) ?? app('amount')->getDefaultCurrency();
|
||||
|
||||
return view('piggy-banks.add', compact('piggyBank', 'maxAmount', 'currency'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add money to piggy bank (for mobile devices).
|
||||
*
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return Factory|View
|
||||
*/
|
||||
public function addMobile(PiggyBank $piggyBank)
|
||||
{
|
||||
/** @var Carbon $date */
|
||||
$date = session('end', new Carbon);
|
||||
$leftOnAccount = $this->piggyRepos->leftOnAccount($piggyBank, $date);
|
||||
$savedSoFar = $this->piggyRepos->getCurrentAmount($piggyBank);
|
||||
$leftToSave = bcsub($piggyBank->targetamount, $savedSoFar);
|
||||
$maxAmount = min($leftOnAccount, $leftToSave);
|
||||
$currency = $this->accountRepos->getAccountCurrency($piggyBank->account) ?? app('amount')->getDefaultCurrency();
|
||||
|
||||
return view('piggy-banks.add-mobile', compact('piggyBank', 'maxAmount', 'currency'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a piggy bank.
|
||||
*
|
||||
* @return Factory|View
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$subTitle = (string) trans('firefly.new_piggy_bank');
|
||||
$subTitleIcon = 'fa-plus';
|
||||
|
||||
// put previous url in session if not redirect from store (not "create another").
|
||||
if (true !== session('piggy-banks.create.fromStore')) {
|
||||
$this->rememberPreviousUri('piggy-banks.create.uri');
|
||||
}
|
||||
session()->forget('piggy-banks.create.fromStore');
|
||||
|
||||
return view('piggy-banks.create', compact('subTitle', 'subTitleIcon'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a piggy bank.
|
||||
*
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return Factory|View
|
||||
*/
|
||||
public function delete(PiggyBank $piggyBank)
|
||||
{
|
||||
$subTitle = (string) trans('firefly.delete_piggy_bank', ['name' => $piggyBank->name]);
|
||||
|
||||
// put previous url in session
|
||||
$this->rememberPreviousUri('piggy-banks.delete.uri');
|
||||
|
||||
return view('piggy-banks.delete', compact('piggyBank', 'subTitle'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy the piggy bank.
|
||||
*
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function destroy(PiggyBank $piggyBank): RedirectResponse
|
||||
{
|
||||
session()->flash('success', (string) trans('firefly.deleted_piggy_bank', ['name' => $piggyBank->name]));
|
||||
app('preferences')->mark();
|
||||
$this->piggyRepos->destroy($piggyBank);
|
||||
|
||||
return redirect($this->getPreviousUri('piggy-banks.delete.uri'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit a piggy bank.
|
||||
*
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return Factory|View
|
||||
*/
|
||||
public function edit(PiggyBank $piggyBank)
|
||||
{
|
||||
$subTitle = (string) trans('firefly.update_piggy_title', ['name' => $piggyBank->name]);
|
||||
$subTitleIcon = 'fa-pencil';
|
||||
$targetDate = null;
|
||||
$startDate = null;
|
||||
$note = $piggyBank->notes()->first();
|
||||
// Flash some data to fill the form.
|
||||
if (null !== $piggyBank->targetdate) {
|
||||
$targetDate = $piggyBank->targetdate->format('Y-m-d');
|
||||
}
|
||||
if (null !== $piggyBank->startdate) {
|
||||
$startDate = $piggyBank->startdate->format('Y-m-d');
|
||||
}
|
||||
|
||||
$preFilled = ['name' => $piggyBank->name,
|
||||
'account_id' => $piggyBank->account_id,
|
||||
'targetamount' => $piggyBank->targetamount,
|
||||
'targetdate' => $targetDate,
|
||||
'startdate' => $startDate,
|
||||
'notes' => null === $note ? '' : $note->text,
|
||||
];
|
||||
session()->flash('preFilled', $preFilled);
|
||||
|
||||
// put previous url in session if not redirect from store (not "return_to_edit").
|
||||
if (true !== session('piggy-banks.edit.fromUpdate')) {
|
||||
$this->rememberPreviousUri('piggy-banks.edit.uri');
|
||||
}
|
||||
session()->forget('piggy-banks.edit.fromUpdate');
|
||||
|
||||
return view('piggy-banks.edit', compact('subTitle', 'subTitleIcon', 'piggyBank', 'preFilled'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show overview of all piggy banks.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return Factory|View
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$this->piggyRepos->correctOrder();
|
||||
$collection = $this->piggyRepos->getPiggyBanks();
|
||||
$total = $collection->count();
|
||||
$page = 0 === (int) $request->get('page') ? 1 : (int) $request->get('page');
|
||||
$pageSize = (int) app('preferences')->get('listPageSize', 50)->data;
|
||||
$accounts = [];
|
||||
/** @var Carbon $end */
|
||||
$end = session('end', Carbon::now()->endOfMonth());
|
||||
|
||||
// transform piggies using the transformer:
|
||||
$parameters = new ParameterBag;
|
||||
$parameters->set('end', $end);
|
||||
$transformed = new Collection;
|
||||
|
||||
/** @var PiggyBankTransformer $transformer */
|
||||
$transformer = app(PiggyBankTransformer::class);
|
||||
$transformer->setParameters(new ParameterBag);
|
||||
|
||||
/** @var AccountTransformer $accountTransformer */
|
||||
$accountTransformer = app(AccountTransformer::class);
|
||||
$accountTransformer->setParameters($parameters);
|
||||
/** @var PiggyBank $piggy */
|
||||
foreach ($collection as $piggy) {
|
||||
$array = $transformer->transform($piggy);
|
||||
$account = $accountTransformer->transform($piggy->account);
|
||||
$accountId = (int) $account['id'];
|
||||
$array['attachments'] = $this->piggyRepos->getAttachments($piggy);
|
||||
if (!isset($accounts[$accountId])) {
|
||||
// create new:
|
||||
$accounts[$accountId] = $account;
|
||||
|
||||
// add some interesting details:
|
||||
$accounts[$accountId]['left'] = $accounts[$accountId]['current_balance'];
|
||||
$accounts[$accountId]['saved'] = 0;
|
||||
$accounts[$accountId]['target'] = 0;
|
||||
$accounts[$accountId]['to_save'] = 0;
|
||||
}
|
||||
|
||||
// calculate new interesting fields:
|
||||
$accounts[$accountId]['left'] -= $array['current_amount'];
|
||||
$accounts[$accountId]['saved'] += $array['current_amount'];
|
||||
$accounts[$accountId]['target'] += $array['target_amount'];
|
||||
$accounts[$accountId]['to_save'] += ($array['target_amount'] - $array['current_amount']);
|
||||
$array['account_name'] = $account['name'];
|
||||
$transformed->push($array);
|
||||
}
|
||||
|
||||
$transformed = $transformed->slice(($page - 1) * $pageSize, $pageSize);
|
||||
$piggyBanks = new LengthAwarePaginator($transformed, $total, $pageSize, $page);
|
||||
$piggyBanks->setPath(route('piggy-banks.index'));
|
||||
|
||||
return view('piggy-banks.index', compact('piggyBanks', 'accounts'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add money to piggy bank.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function postAdd(Request $request, PiggyBank $piggyBank): RedirectResponse
|
||||
{
|
||||
$amount = $request->get('amount') ?? '0';
|
||||
$currency = $this->accountRepos->getAccountCurrency($piggyBank->account) ?? app('amount')->getDefaultCurrency();
|
||||
// if amount is negative, make positive and continue:
|
||||
if (-1 === bccomp($amount, '0')) {
|
||||
$amount = bcmul($amount, '-1');
|
||||
}
|
||||
if ($this->piggyRepos->canAddAmount($piggyBank, $amount)) {
|
||||
$this->piggyRepos->addAmount($piggyBank, $amount);
|
||||
session()->flash(
|
||||
'success',
|
||||
(string) trans(
|
||||
'firefly.added_amount_to_piggy',
|
||||
['amount' => app('amount')->formatAnything($currency, $amount, false), 'name' => $piggyBank->name]
|
||||
)
|
||||
);
|
||||
app('preferences')->mark();
|
||||
|
||||
return redirect(route('piggy-banks.index'));
|
||||
}
|
||||
|
||||
Log::error('Cannot add ' . $amount . ' because canAddAmount returned false.');
|
||||
session()->flash(
|
||||
'error',
|
||||
(string) trans(
|
||||
'firefly.cannot_add_amount_piggy',
|
||||
['amount' => app('amount')->formatAnything($currency, $amount, false), 'name' => e($piggyBank->name)]
|
||||
)
|
||||
);
|
||||
|
||||
return redirect(route('piggy-banks.index'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove money from piggy bank.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function postRemove(Request $request, PiggyBank $piggyBank): RedirectResponse
|
||||
{
|
||||
$amount = $request->get('amount') ?? '0';
|
||||
$currency = $this->accountRepos->getAccountCurrency($piggyBank->account) ?? app('amount')->getDefaultCurrency();
|
||||
// if amount is negative, make positive and continue:
|
||||
if (-1 === bccomp($amount, '0')) {
|
||||
$amount = bcmul($amount, '-1');
|
||||
}
|
||||
if ($this->piggyRepos->canRemoveAmount($piggyBank, $amount)) {
|
||||
$this->piggyRepos->removeAmount($piggyBank, $amount);
|
||||
session()->flash(
|
||||
'success',
|
||||
(string) trans(
|
||||
'firefly.removed_amount_from_piggy',
|
||||
['amount' => app('amount')->formatAnything($currency, $amount, false), 'name' => $piggyBank->name]
|
||||
)
|
||||
);
|
||||
app('preferences')->mark();
|
||||
|
||||
return redirect(route('piggy-banks.index'));
|
||||
}
|
||||
|
||||
$amount = (string) round($request->get('amount'), 12);
|
||||
|
||||
session()->flash(
|
||||
'error',
|
||||
(string) trans(
|
||||
'firefly.cannot_remove_from_piggy',
|
||||
['amount' => app('amount')->formatAnything($currency, $amount, false), 'name' => e($piggyBank->name)]
|
||||
)
|
||||
);
|
||||
|
||||
return redirect(route('piggy-banks.index'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove money from piggy bank form.
|
||||
*
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return Factory|View
|
||||
*/
|
||||
public function remove(PiggyBank $piggyBank)
|
||||
{
|
||||
$repetition = $this->piggyRepos->getRepetition($piggyBank);
|
||||
$currency = $this->accountRepos->getAccountCurrency($piggyBank->account) ?? app('amount')->getDefaultCurrency();
|
||||
|
||||
return view('piggy-banks.remove', compact('piggyBank', 'repetition', 'currency'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove money from piggy bank (for mobile devices).
|
||||
*
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return Factory|View
|
||||
*/
|
||||
public function removeMobile(PiggyBank $piggyBank)
|
||||
{
|
||||
$repetition = $this->piggyRepos->getRepetition($piggyBank);
|
||||
$currency = $this->accountRepos->getAccountCurrency($piggyBank->account) ?? app('amount')->getDefaultCurrency();
|
||||
|
||||
return view('piggy-banks.remove-mobile', compact('piggyBank', 'repetition', 'currency'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the order of a piggy bank.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function setOrder(Request $request, PiggyBank $piggyBank): JsonResponse
|
||||
{
|
||||
$newOrder = (int) $request->get('order');
|
||||
$this->piggyRepos->setOrder($piggyBank, $newOrder);
|
||||
|
||||
return response()->json(['data' => 'OK']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a single piggy bank.
|
||||
*
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return Factory|View
|
||||
*/
|
||||
public function show(PiggyBank $piggyBank)
|
||||
{
|
||||
/** @var Carbon $end */
|
||||
$end = session('end', Carbon::now()->endOfMonth());
|
||||
// transform piggies using the transformer:
|
||||
$parameters = new ParameterBag;
|
||||
$parameters->set('end', $end);
|
||||
|
||||
/** @var PiggyBankTransformer $transformer */
|
||||
$transformer = app(PiggyBankTransformer::class);
|
||||
$transformer->setParameters($parameters);
|
||||
$piggy = $transformer->transform($piggyBank);
|
||||
$events = $this->piggyRepos->getEvents($piggyBank);
|
||||
$subTitle = $piggyBank->name;
|
||||
$attachments = $this->piggyRepos->getAttachments($piggyBank);
|
||||
|
||||
return view('piggy-banks.show', compact('piggyBank', 'events', 'subTitle', 'piggy', 'attachments'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a new piggy bank.
|
||||
*
|
||||
* @param PiggyBankFormRequest $request
|
||||
*
|
||||
* @return RedirectResponse|Redirector
|
||||
*/
|
||||
public function store(PiggyBankFormRequest $request)
|
||||
{
|
||||
$data = $request->getPiggyBankData();
|
||||
if (null === $data['startdate']) {
|
||||
$data['startdate'] = new Carbon;
|
||||
}
|
||||
$piggyBank = $this->piggyRepos->store($data);
|
||||
|
||||
session()->flash('success', (string) trans('firefly.stored_piggy_bank', ['name' => $piggyBank->name]));
|
||||
app('preferences')->mark();
|
||||
|
||||
// store attachment(s):
|
||||
/** @var array $files */
|
||||
$files = $request->hasFile('attachments') ? $request->file('attachments') : null;
|
||||
if (null !== $files && !auth()->user()->hasRole('demo')) {
|
||||
$this->attachments->saveAttachmentsForModel($piggyBank, $files);
|
||||
}
|
||||
if (null !== $files && auth()->user()->hasRole('demo')) {
|
||||
session()->flash('info',(string)trans('firefly.no_att_demo_user'));
|
||||
}
|
||||
|
||||
if (count($this->attachments->getMessages()->get('attachments')) > 0) {
|
||||
$request->session()->flash('info', $this->attachments->getMessages()->get('attachments')); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
|
||||
$redirect = redirect($this->getPreviousUri('piggy-banks.create.uri'));
|
||||
|
||||
if (1 === (int) $request->get('create_another')) {
|
||||
// @codeCoverageIgnoreStart
|
||||
session()->put('piggy-banks.create.fromStore', true);
|
||||
|
||||
$redirect = redirect(route('piggy-banks.create'))->withInput();
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
return $redirect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a piggy bank.
|
||||
*
|
||||
* @param PiggyBankFormRequest $request
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return RedirectResponse|Redirector
|
||||
*/
|
||||
public function update(PiggyBankFormRequest $request, PiggyBank $piggyBank)
|
||||
{
|
||||
$data = $request->getPiggyBankData();
|
||||
$piggyBank = $this->piggyRepos->update($piggyBank, $data);
|
||||
|
||||
session()->flash('success', (string) trans('firefly.updated_piggy_bank', ['name' => $piggyBank->name]));
|
||||
app('preferences')->mark();
|
||||
|
||||
// store new attachment(s):
|
||||
/** @var array $files */
|
||||
$files = $request->hasFile('attachments') ? $request->file('attachments') : null;
|
||||
if (null !== $files && !auth()->user()->hasRole('demo')) {
|
||||
$this->attachments->saveAttachmentsForModel($piggyBank, $files);
|
||||
}
|
||||
if (null !== $files && auth()->user()->hasRole('demo')) {
|
||||
session()->flash('info',(string)trans('firefly.no_att_demo_user'));
|
||||
}
|
||||
|
||||
if (count($this->attachments->getMessages()->get('attachments')) > 0) {
|
||||
$request->session()->flash('info', $this->attachments->getMessages()->get('attachments')); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
|
||||
$redirect = redirect($this->getPreviousUri('piggy-banks.edit.uri'));
|
||||
|
||||
if (1 === (int) $request->get('return_to_edit')) {
|
||||
// @codeCoverageIgnoreStart
|
||||
session()->put('piggy-banks.edit.fromUpdate', true);
|
||||
|
||||
$redirect = redirect(route('piggy-banks.edit', [$piggyBank->id]));
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
return $redirect;
|
||||
}
|
||||
}
|
@ -61,6 +61,8 @@ class ProfileController extends Controller
|
||||
{
|
||||
use RequestInformation, CreateStuff;
|
||||
|
||||
protected bool $externalIdentity;
|
||||
|
||||
/**
|
||||
* ProfileController constructor.
|
||||
*
|
||||
@ -78,6 +80,9 @@ class ProfileController extends Controller
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
$loginProvider = config('firefly.login_provider');
|
||||
$authGuard = config('firefly.authentication_guard');
|
||||
$this->externalIdentity = 'eloquent' === $loginProvider || 'remote_user_guard' === $authGuard;
|
||||
|
||||
$this->middleware(IsDemoUser::class)->except(['index']);
|
||||
$this->middleware(IsSandStormUser::class)->except('index');
|
||||
@ -92,13 +97,10 @@ class ProfileController extends Controller
|
||||
*/
|
||||
public function changeEmail(Request $request)
|
||||
{
|
||||
$loginProvider = config('firefly.login_provider');
|
||||
if ('eloquent' !== $loginProvider) {
|
||||
// @codeCoverageIgnoreStart
|
||||
$request->session()->flash('error', trans('firefly.login_provider_local_only', ['login_provider' => e($loginProvider)]));
|
||||
if ($this->externalIdentity) {
|
||||
$request->session()->flash('error', trans('firefly.external_user_mgt_disabled'));
|
||||
|
||||
return redirect(route('profile.index'));
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
$title = auth()->user()->email;
|
||||
@ -118,13 +120,10 @@ class ProfileController extends Controller
|
||||
*/
|
||||
public function changePassword(Request $request)
|
||||
{
|
||||
$loginProvider = config('firefly.login_provider');
|
||||
if ('eloquent' !== $loginProvider) {
|
||||
// @codeCoverageIgnoreStart
|
||||
$request->session()->flash('error', trans('firefly.login_provider_local_only', ['login_provider' => e($loginProvider)]));
|
||||
if ($this->externalIdentity) {
|
||||
$request->session()->flash('error', trans('firefly.external_user_mgt_disabled'));
|
||||
|
||||
return redirect(route('profile.index'));
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
$title = auth()->user()->email;
|
||||
@ -137,10 +136,17 @@ class ProfileController extends Controller
|
||||
/**
|
||||
* View that generates a 2FA code for the user.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return Factory|View
|
||||
*/
|
||||
public function code()
|
||||
public function code(Request $request)
|
||||
{
|
||||
if ($this->externalIdentity) {
|
||||
$request->session()->flash('error', trans('firefly.external_user_mgt_disabled'));
|
||||
|
||||
return redirect(route('profile.index'));
|
||||
}
|
||||
$domain = $this->getDomain();
|
||||
$secret = null;
|
||||
|
||||
@ -192,10 +198,9 @@ class ProfileController extends Controller
|
||||
*/
|
||||
public function confirmEmailChange(UserRepositoryInterface $repository, string $token)
|
||||
{
|
||||
$loginProvider = config('firefly.login_provider');
|
||||
if ('eloquent' !== $loginProvider) {
|
||||
if ($this->externalIdentity) {
|
||||
// @codeCoverageIgnoreStart
|
||||
throw new FireflyException('Cannot confirm email change when authentication provider is not local.');
|
||||
throw new FireflyException(trans('firefly.external_user_mgt_disabled'));
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
// find preference with this token value.
|
||||
@ -229,15 +234,14 @@ class ProfileController extends Controller
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return Factory|View
|
||||
* @return \Illuminate\Contracts\Foundation\Application|RedirectResponse|Redirector
|
||||
*/
|
||||
public function deleteAccount(Request $request)
|
||||
{
|
||||
$loginProvider = config('firefly.login_provider');
|
||||
if ('eloquent' !== $loginProvider) {
|
||||
// @codeCoverageIgnoreStart
|
||||
$request->session()->flash('warning', trans('firefly.delete_local_info_only', ['login_provider' => e($loginProvider)]));
|
||||
// @codeCoverageIgnoreEnd
|
||||
if ($this->externalIdentity) {
|
||||
$request->session()->flash('error', trans('firefly.external_user_mgt_disabled'));
|
||||
|
||||
return redirect(route('profile.index'));
|
||||
}
|
||||
$title = auth()->user()->email;
|
||||
$subTitle = (string) trans('firefly.delete_account');
|
||||
@ -251,8 +255,13 @@ class ProfileController extends Controller
|
||||
*
|
||||
* @return RedirectResponse|Redirector
|
||||
*/
|
||||
public function deleteCode()
|
||||
public function deleteCode(Request $request)
|
||||
{
|
||||
if ($this->externalIdentity) {
|
||||
$request->session()->flash('error', trans('firefly.external_user_mgt_disabled'));
|
||||
|
||||
return redirect(route('profile.index'));
|
||||
}
|
||||
/** @var UserRepositoryInterface $repository */
|
||||
$repository = app(UserRepositoryInterface::class);
|
||||
|
||||
@ -271,8 +280,14 @@ class ProfileController extends Controller
|
||||
*
|
||||
* @return RedirectResponse|Redirector
|
||||
*/
|
||||
public function enable2FA()
|
||||
public function enable2FA(Request $request)
|
||||
{
|
||||
if ($this->externalIdentity) {
|
||||
$request->session()->flash('error', trans('firefly.external_user_mgt_disabled'));
|
||||
|
||||
return redirect(route('profile.index'));
|
||||
}
|
||||
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
$enabledMFA = null !== $user->mfa_secret;
|
||||
@ -329,6 +344,12 @@ class ProfileController extends Controller
|
||||
*/
|
||||
public function newBackupCodes()
|
||||
{
|
||||
if ($this->externalIdentity) {
|
||||
$request->session()->flash('error', trans('firefly.external_user_mgt_disabled'));
|
||||
|
||||
return redirect(route('profile.index'));
|
||||
}
|
||||
|
||||
// generate recovery codes:
|
||||
$recovery = app(Recovery::class);
|
||||
$recoveryCodes = $recovery->lowercase()
|
||||
@ -354,13 +375,10 @@ class ProfileController extends Controller
|
||||
*/
|
||||
public function postChangeEmail(EmailFormRequest $request, UserRepositoryInterface $repository)
|
||||
{
|
||||
$loginProvider = config('firefly.login_provider');
|
||||
if ('eloquent' !== $loginProvider) {
|
||||
// @codeCoverageIgnoreStart
|
||||
$request->session()->flash('error', trans('firefly.login_provider_local_only', ['login_provider' => e($loginProvider)]));
|
||||
if ($this->externalIdentity) {
|
||||
$request->session()->flash('error', trans('firefly.external_user_mgt_disabled'));
|
||||
|
||||
return redirect(route('profile.index'));
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
/** @var User $user */
|
||||
@ -408,13 +426,10 @@ class ProfileController extends Controller
|
||||
*/
|
||||
public function postChangePassword(ProfileFormRequest $request, UserRepositoryInterface $repository)
|
||||
{
|
||||
$loginProvider = config('firefly.login_provider');
|
||||
if ('eloquent' !== $loginProvider) {
|
||||
// @codeCoverageIgnoreStart
|
||||
$request->session()->flash('error', trans('firefly.login_provider_local_only', ['login_provider' => e($loginProvider)]));
|
||||
if ($this->externalIdentity) {
|
||||
$request->session()->flash('error', trans('firefly.external_user_mgt_disabled'));
|
||||
|
||||
return redirect(route('profile.index'));
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
// the request has already validated both new passwords must be equal.
|
||||
@ -446,6 +461,12 @@ class ProfileController extends Controller
|
||||
*/
|
||||
public function postCode(TokenFormRequest $request)
|
||||
{
|
||||
if ($this->externalIdentity) {
|
||||
$request->session()->flash('error', trans('firefly.external_user_mgt_disabled'));
|
||||
|
||||
return redirect(route('profile.index'));
|
||||
}
|
||||
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
/** @var UserRepositoryInterface $repository */
|
||||
@ -485,6 +506,12 @@ class ProfileController extends Controller
|
||||
*/
|
||||
public function postDeleteAccount(UserRepositoryInterface $repository, DeleteAccountFormRequest $request)
|
||||
{
|
||||
if ($this->externalIdentity) {
|
||||
$request->session()->flash('error', trans('firefly.external_user_mgt_disabled'));
|
||||
|
||||
return redirect(route('profile.index'));
|
||||
}
|
||||
|
||||
if (!Hash::check($request->get('password'), auth()->user()->password)) {
|
||||
session()->flash('error', (string) trans('firefly.invalid_password'));
|
||||
|
||||
@ -506,8 +533,14 @@ class ProfileController extends Controller
|
||||
*
|
||||
* @return RedirectResponse|Redirector
|
||||
*/
|
||||
public function regenerate()
|
||||
public function regenerate(Request $request)
|
||||
{
|
||||
if ($this->externalIdentity) {
|
||||
$request->session()->flash('error', trans('firefly.external_user_mgt_disabled'));
|
||||
|
||||
return redirect(route('profile.index'));
|
||||
}
|
||||
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
$token = $user->generateAccessToken();
|
||||
@ -530,11 +563,8 @@ class ProfileController extends Controller
|
||||
*/
|
||||
public function undoEmailChange(UserRepositoryInterface $repository, string $token, string $hash)
|
||||
{
|
||||
$loginProvider = config('firefly.login_provider');
|
||||
if ('eloquent' !== $loginProvider) {
|
||||
// @codeCoverageIgnoreStart
|
||||
throw new FireflyException('Cannot confirm email change when authentication provider is not local.');
|
||||
// @codeCoverageIgnoreEnd
|
||||
if ($this->externalIdentity) {
|
||||
throw new FireflyException(trans('firefly.external_user_mgt_disabled'));
|
||||
}
|
||||
|
||||
// find preference with this token value.
|
||||
|
@ -25,6 +25,7 @@ namespace FireflyIII\Http\Controllers\Recurring;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Attachments\AttachmentHelperInterface;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Http\Requests\RecurrenceFormRequest;
|
||||
use FireflyIII\Models\RecurrenceRepetition;
|
||||
@ -47,6 +48,8 @@ class CreateController extends Controller
|
||||
/** @var RecurringRepositoryInterface Recurring repository */
|
||||
private $recurring;
|
||||
|
||||
private AttachmentHelperInterface $attachments;
|
||||
|
||||
/**
|
||||
* CreateController constructor.
|
||||
*
|
||||
@ -65,6 +68,7 @@ class CreateController extends Controller
|
||||
|
||||
$this->recurring = app(RecurringRepositoryInterface::class);
|
||||
$this->budgets = app(BudgetRepositoryInterface::class);
|
||||
$this->attachments = app(AttachmentHelperInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
@ -140,6 +144,21 @@ class CreateController extends Controller
|
||||
|
||||
$request->session()->flash('success', (string) trans('firefly.stored_new_recurrence', ['title' => $recurrence->title]));
|
||||
app('preferences')->mark();
|
||||
|
||||
// store attachment(s):
|
||||
/** @var array $files */
|
||||
$files = $request->hasFile('attachments') ? $request->file('attachments') : null;
|
||||
if (null !== $files && !auth()->user()->hasRole('demo')) {
|
||||
$this->attachments->saveAttachmentsForModel($recurrence, $files);
|
||||
}
|
||||
if (null !== $files && auth()->user()->hasRole('demo')) {
|
||||
session()->flash('info', (string) trans('firefly.no_att_demo_user'));
|
||||
}
|
||||
|
||||
if (count($this->attachments->getMessages()->get('attachments')) > 0) {
|
||||
$request->session()->flash('info', $this->attachments->getMessages()->get('attachments')); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$redirect = redirect($this->getPreviousUri('recurring.create.uri'));
|
||||
if (1 === (int) $request->get('create_another')) {
|
||||
// set value so create routine will not overwrite URL:
|
||||
|
@ -25,6 +25,7 @@ namespace FireflyIII\Http\Controllers\Recurring;
|
||||
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Attachments\AttachmentHelperInterface;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Http\Requests\RecurrenceFormRequest;
|
||||
use FireflyIII\Models\Recurrence;
|
||||
@ -49,6 +50,7 @@ class EditController extends Controller
|
||||
private $budgets;
|
||||
/** @var RecurringRepositoryInterface Recurring repository */
|
||||
private $recurring;
|
||||
private AttachmentHelperInterface $attachments;
|
||||
|
||||
/**
|
||||
* EditController constructor.
|
||||
@ -68,7 +70,7 @@ class EditController extends Controller
|
||||
|
||||
$this->recurring = app(RecurringRepositoryInterface::class);
|
||||
$this->budgets = app(BudgetRepositoryInterface::class);
|
||||
|
||||
$this->attachments = app(AttachmentHelperInterface::class);
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
@ -159,6 +161,21 @@ class EditController extends Controller
|
||||
$this->recurring->update($recurrence, $data);
|
||||
|
||||
$request->session()->flash('success', (string) trans('firefly.updated_recurrence', ['title' => $recurrence->title]));
|
||||
|
||||
// store new attachment(s):
|
||||
$files = $request->hasFile('attachments') ? $request->file('attachments') : null;
|
||||
if (null !== $files && !auth()->user()->hasRole('demo')) {
|
||||
$this->attachments->saveAttachmentsForModel($recurrence, $files);
|
||||
}
|
||||
if (null !== $files && auth()->user()->hasRole('demo')) {
|
||||
session()->flash('info', (string) trans('firefly.no_att_demo_user'));
|
||||
}
|
||||
|
||||
if (count($this->attachments->getMessages()->get('attachments')) > 0) {
|
||||
$request->session()->flash('info', $this->attachments->getMessages()->get('attachments')); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
|
||||
app('preferences')->mark();
|
||||
$redirect = redirect($this->getPreviousUri('recurrences.edit.uri'));
|
||||
if (1 === (int) $request->get('return_to_edit')) {
|
||||
|
@ -111,6 +111,8 @@ 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']);
|
||||
// lazy but OK
|
||||
$array['attachments'] = $recurrence->attachments()->count();
|
||||
|
||||
// make carbon objects out of occurrences
|
||||
foreach ($array['repetitions'] as $repIndex => $repetition) {
|
||||
|
@ -263,7 +263,7 @@ class ReportController extends Controller
|
||||
public function index(AccountRepositoryInterface $repository)
|
||||
{
|
||||
/** @var Carbon $start */
|
||||
$start = clone session('first');
|
||||
$start = clone session('first', new Carbon);
|
||||
$months = $this->helper->listOfMonths($start);
|
||||
$customFiscalYear = app('preferences')->get('customFiscalYear', 0)->data;
|
||||
$accounts = $repository->getAccountsByType(
|
||||
|
@ -128,6 +128,10 @@ class SelectController extends Controller
|
||||
*/
|
||||
public function selectTransactions(Rule $rule)
|
||||
{
|
||||
if(false===$rule->active) {
|
||||
session()->flash('warning',trans('firefly.cannot_fire_inactive_rules'));
|
||||
return redirect(route('rules.index'));
|
||||
}
|
||||
// does the user have shared accounts?
|
||||
$first = session('first', Carbon::now()->subYear())->format('Y-m-d');
|
||||
$today = Carbon::now()->format('Y-m-d');
|
||||
|
75
app/Http/Requests/ObjectGroupFormRequest.php
Normal file
75
app/Http/Requests/ObjectGroupFormRequest.php
Normal file
@ -0,0 +1,75 @@
|
||||
<?php
|
||||
/**
|
||||
* ObjectGroupFormRequest.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\Http\Requests;
|
||||
|
||||
use FireflyIII\Models\ObjectGroup;
|
||||
|
||||
/**
|
||||
* Class ObjectGroupFormRequest.
|
||||
*/
|
||||
class ObjectGroupFormRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Verify the request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
// Only allow logged in users
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data required by the controller.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getObjectGroupData(): array
|
||||
{
|
||||
return [
|
||||
'title' => $this->string('title'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Rules for this request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
/** @var ObjectGroup $piggy */
|
||||
$objectGroup = $this->route()->parameter('objectGroup');
|
||||
|
||||
$titleRule = 'required|between:1,255|uniqueObjectGroup';
|
||||
|
||||
if (null !== $objectGroup) {
|
||||
$titleRule = sprintf('required|between:1,255|uniqueObjectGroup:%d', $objectGroup->id);
|
||||
}
|
||||
|
||||
return [
|
||||
'title' => $titleRule,
|
||||
];
|
||||
}
|
||||
}
|
@ -54,6 +54,7 @@ class PiggyBankFormRequest extends Request
|
||||
'targetamount' => $this->string('targetamount'),
|
||||
'targetdate' => $this->date('targetdate'),
|
||||
'notes' => $this->nlString('notes'),
|
||||
'object_group' => $this->string('object_group'),
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -1,234 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Amount.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\Import\Converter;
|
||||
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class Amount.
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class Amount implements ConverterInterface
|
||||
{
|
||||
/**
|
||||
* Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems.
|
||||
* - Jamie Zawinski.
|
||||
*
|
||||
* @param $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function convert($value): string
|
||||
{
|
||||
if (null === $value) {
|
||||
return '0';
|
||||
}
|
||||
Log::debug(sprintf('Start with amount "%s"', $value));
|
||||
$original = $value;
|
||||
$value = $this->stripAmount((string) $value);
|
||||
$decimal = null;
|
||||
|
||||
if ($this->decimalIsDot($value)) {
|
||||
$decimal = '.';
|
||||
Log::debug(sprintf('Decimal character in "%s" seems to be a dot.', $value));
|
||||
}
|
||||
|
||||
if ($this->decimalIsComma($value)) {
|
||||
$decimal = ',';
|
||||
Log::debug(sprintf('Decimal character in "%s" seems to be a comma.', $value));
|
||||
}
|
||||
|
||||
// decimal character is null? find out if "0.1" or ".1" or "0,1" or ",1"
|
||||
if ($this->alternativeDecimalSign($value)) {
|
||||
$decimal = $this->getAlternativeDecimalSign($value);
|
||||
}
|
||||
|
||||
// decimal character still null? Search from the left for '.',',' or ' '.
|
||||
if (null === $decimal) {
|
||||
$decimal = $this->findFromLeft($value);
|
||||
}
|
||||
|
||||
// if decimal is dot, replace all comma's and spaces with nothing
|
||||
if (null !== $decimal) {
|
||||
$value = $this->replaceDecimal($decimal, $value);
|
||||
Log::debug(sprintf('Converted amount from "%s" to "%s".', $original, $value));
|
||||
}
|
||||
|
||||
if (null === $decimal) {
|
||||
// replace all:
|
||||
$search = ['.', ' ', ','];
|
||||
$value = str_replace($search, '', $value);
|
||||
Log::debug(sprintf('No decimal character found. Converted amount from "%s" to "%s".', $original, $value));
|
||||
}
|
||||
if (strpos($value, '.') === 0) {
|
||||
$value = '0' . $value;
|
||||
}
|
||||
|
||||
if (is_numeric($value)) {
|
||||
Log::debug(sprintf('Final NUMERIC value is: "%s"', $value));
|
||||
|
||||
return $value;
|
||||
}
|
||||
// @codeCoverageIgnoreStart
|
||||
Log::debug(sprintf('Final value is: "%s"', $value));
|
||||
$formatted = sprintf('%01.12f', $value);
|
||||
Log::debug(sprintf('Is formatted to : "%s"', $formatted));
|
||||
|
||||
return $formatted;
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the value has a dot or comma on an alternative place,
|
||||
* catching strings like ",1" or ".5".
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function alternativeDecimalSign(string $value): bool
|
||||
{
|
||||
$length = strlen($value);
|
||||
$altPosition = $length - 2;
|
||||
|
||||
return $length > 1 && ('.' === $value[$altPosition] || ',' === $value[$altPosition]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to see if the decimal separator is a comma.
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function decimalIsComma(string $value): bool
|
||||
{
|
||||
$length = strlen($value);
|
||||
$decimalPosition = $length - 3;
|
||||
|
||||
return $length > 2 && ',' === $value[$decimalPosition];
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to see if the decimal separator is a dot.
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function decimalIsDot(string $value): bool
|
||||
{
|
||||
$length = strlen($value);
|
||||
$decimalPosition = $length - 3;
|
||||
|
||||
return ($length > 2 && '.' === $value[$decimalPosition]) || ($length > 2 && strpos($value, '.') > $decimalPosition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search from the left for decimal sign.
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function findFromLeft(string $value): ?string
|
||||
{
|
||||
$decimal = null;
|
||||
Log::debug('Decimal is still NULL, probably number with >2 decimals. Search for a dot.');
|
||||
$res = strrpos($value, '.');
|
||||
if (!(false === $res)) {
|
||||
// blandly assume this is the one.
|
||||
Log::debug(sprintf('Searched from the left for "." in amount "%s", assume this is the decimal sign.', $value));
|
||||
$decimal = '.';
|
||||
}
|
||||
|
||||
return $decimal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the alternative decimal point used, such as a dot or a comma,
|
||||
* from strings like ",1" or "0.5".
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getAlternativeDecimalSign(string $value): string
|
||||
{
|
||||
$length = strlen($value);
|
||||
$altPosition = $length - 2;
|
||||
|
||||
return $value[$altPosition];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces other characters like thousand separators with nothing to make the decimal separator the only special
|
||||
* character in the string.
|
||||
*
|
||||
* @param string $decimal
|
||||
* @param string $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function replaceDecimal(string $decimal, string $value): string
|
||||
{
|
||||
$search = [',', ' ']; // default when decimal sign is a dot.
|
||||
if (',' === $decimal) {
|
||||
$search = ['.', ' '];
|
||||
}
|
||||
$value = str_replace($search, '', $value);
|
||||
|
||||
/** @noinspection CascadeStringReplacementInspection */
|
||||
$value = str_replace(',', '.', $value);
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip amount from weird characters.
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function stripAmount(string $value): string
|
||||
{
|
||||
if (0 === strpos($value, '--')) {
|
||||
$value = substr($value, 2);
|
||||
}
|
||||
// have to strip the € because apparantly the Postbank (DE) thinks "1.000,00 €" is a normal way to format a number.
|
||||
$value = trim((string) str_replace(['€'], '', $value));
|
||||
$str = preg_replace('/[^\-\(\)\.\,0-9 ]/', '', $value);
|
||||
$len = strlen($str);
|
||||
if ('(' === $str[0] && ')' === $str[$len - 1]) {
|
||||
$str = '-' . substr($str, 1, $len - 2);
|
||||
}
|
||||
|
||||
Log::debug(sprintf('Stripped "%s" away to "%s"', $value, $str));
|
||||
|
||||
return $str;
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* AmountCredit.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\Import\Converter;
|
||||
|
||||
/**
|
||||
* Class AmountCredit
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class AmountCredit implements ConverterInterface
|
||||
{
|
||||
/**
|
||||
* Convert an amount, always return positive.
|
||||
*
|
||||
* @param $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function convert($value): string
|
||||
{
|
||||
/** @var ConverterInterface $converter */
|
||||
$converter = app(Amount::class);
|
||||
$result = $converter->convert($value);
|
||||
$result = app('steam')->positive($result);
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* AmountDebit.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\Import\Converter;
|
||||
|
||||
/**
|
||||
* Class AmountDebit
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class AmountDebit implements ConverterInterface
|
||||
{
|
||||
/**
|
||||
* Convert amount, always return positive.
|
||||
*
|
||||
* @param $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function convert($value): string
|
||||
{
|
||||
/** @var ConverterInterface $converter */
|
||||
$converter = app(Amount::class);
|
||||
$result = $converter->convert($value);
|
||||
$result = app('steam')->positive($result);
|
||||
$result = bcmul($result, '-1');
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* AmountNegated.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\Import\Converter;
|
||||
|
||||
/**
|
||||
* Class AmountNegated
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class AmountNegated implements ConverterInterface
|
||||
{
|
||||
/**
|
||||
* Negate amount.
|
||||
*
|
||||
* @param $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function convert($value): string
|
||||
{
|
||||
/** @var ConverterInterface $converter */
|
||||
$converter = app(Amount::class);
|
||||
$result = $converter->convert($value);
|
||||
$result = bcmul($result, '-1');
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* BankDebitCredit.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\Import\Converter;
|
||||
|
||||
|
||||
use Log;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class BankDebitCredit
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class BankDebitCredit implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* Convert a value.
|
||||
*
|
||||
* @param $value
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function convert($value): int
|
||||
{
|
||||
Log::debug('Going to convert ', ['value' => $value]);
|
||||
$negative = [
|
||||
'D', // Old style Rabobank (NL). Short for "Debit"
|
||||
'A', // New style Rabobank (NL). Short for "Af"
|
||||
'DR', // https://old.reddit.com/r/FireflyIII/comments/bn2edf/generic_debitcredit_indicator/
|
||||
'Af', // ING (NL).
|
||||
'Debet', // Triodos (NL)
|
||||
'S', // "Soll", German term for debit
|
||||
'Debit', // Community America (US)
|
||||
];
|
||||
if (in_array(trim($value), $negative, true)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* ConverterInterface.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\Import\Converter;
|
||||
|
||||
/**
|
||||
* Interface ConverterInterface.
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
interface ConverterInterface
|
||||
{
|
||||
/**
|
||||
* Convert a value.
|
||||
*
|
||||
* @param $value
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
*/
|
||||
public function convert($value);
|
||||
}
|
@ -1,136 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* BunqJobConfiguration.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\Import\JobConfiguration;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Support\Import\JobConfiguration\Bunq\BunqJobConfigurationInterface;
|
||||
use FireflyIII\Support\Import\JobConfiguration\Bunq\ChooseAccountsHandler;
|
||||
use FireflyIII\Support\Import\JobConfiguration\Bunq\NewBunqJobHandler;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class BunqJobConfiguration
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class BunqJobConfiguration implements JobConfigurationInterface
|
||||
{
|
||||
/** @var BunqJobConfigurationInterface Bunq job interface */
|
||||
private $handler;
|
||||
/** @var ImportJob The import job */
|
||||
private $importJob;
|
||||
/** @var ImportJobRepositoryInterface Import job repository */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* Returns true when the initial configuration for this job is complete.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function configurationComplete(): bool
|
||||
{
|
||||
return $this->handler->configurationComplete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Store any data from the $data array into the job. Anything in the message bag will be flashed
|
||||
* as an error to the user, regardless of its content.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function configureJob(array $data): MessageBag
|
||||
{
|
||||
return $this->handler->configureJob($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the data required for the next step in the job configuration.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getNextData(): array
|
||||
{
|
||||
return $this->handler->getNextData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the view of the next step in the job configuration.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNextView(): string
|
||||
{
|
||||
return $this->handler->getNextView();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set import job.
|
||||
*
|
||||
* @param ImportJob $importJob
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
$this->handler = $this->getHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get correct handler.
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @return BunqJobConfigurationInterface
|
||||
*/
|
||||
private function getHandler(): BunqJobConfigurationInterface
|
||||
{
|
||||
Log::debug(sprintf('Now in BunqJobConfiguration::getHandler() with stage "%s"', $this->importJob->stage));
|
||||
$handler = null;
|
||||
switch ($this->importJob->stage) {
|
||||
case 'new':
|
||||
$handler = app(NewBunqJobHandler::class);
|
||||
$handler->setImportJob($this->importJob);
|
||||
break;
|
||||
case 'choose-accounts':
|
||||
/** @var ChooseAccountsHandler $handler */
|
||||
$handler = app(ChooseAccountsHandler::class);
|
||||
$handler->setImportJob($this->importJob);
|
||||
break;
|
||||
default:
|
||||
// @codeCoverageIgnoreStart
|
||||
throw new FireflyException(sprintf('Firefly III cannot create a configuration handler for stage "%s"', $this->importJob->stage));
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
return $handler;
|
||||
}
|
||||
}
|
@ -1,169 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* FakeJobConfiguration.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\Import\JobConfiguration;
|
||||
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use Illuminate\Support\MessageBag;
|
||||
|
||||
/**
|
||||
* Class FakeJobConfiguration
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class FakeJobConfiguration implements JobConfigurationInterface
|
||||
{
|
||||
/** @var ImportJob The import job */
|
||||
private $importJob;
|
||||
|
||||
/** @var ImportJobRepositoryInterface Import job repository */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* Returns true when the initial configuration for this job is complete.
|
||||
* configuration array of job must have two values:
|
||||
* 'artist' must be 'david bowie', case insensitive
|
||||
* 'song' must be 'golden years', case insensitive.
|
||||
* if stage is not "new", then album must be 'station to station'
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
*/
|
||||
public function configurationComplete(): bool
|
||||
{
|
||||
$config = $this->importJob->configuration;
|
||||
if ('new' === $this->importJob->stage) {
|
||||
return
|
||||
isset($config['artist'], $config['song'], $config['apply-rules'])
|
||||
&& 'david bowie' === strtolower($config['artist'])
|
||||
&& 'golden years' === strtolower($config['song']);
|
||||
}
|
||||
|
||||
return isset($config['album']) && 'station to station' === strtolower($config['album']);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Store any data from the $data array into the job.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return MessageBag
|
||||
*
|
||||
*/
|
||||
public function configureJob(array $data): MessageBag
|
||||
{
|
||||
$artist = strtolower($data['artist'] ?? '');
|
||||
$song = strtolower($data['song'] ?? '');
|
||||
$album = strtolower($data['album'] ?? '');
|
||||
$applyRules = isset($data['apply_rules']) ? 1 === (int) $data['apply_rules'] : null;
|
||||
$configuration = $this->importJob->configuration;
|
||||
if ('david bowie' === $artist) {
|
||||
// store artist
|
||||
$configuration['artist'] = $artist;
|
||||
}
|
||||
|
||||
if ('golden years' === $song) {
|
||||
// store song
|
||||
$configuration['song'] = $song;
|
||||
}
|
||||
|
||||
if ('station to station' === $album) {
|
||||
// store album
|
||||
$configuration['album'] = $album;
|
||||
}
|
||||
if (null !== $applyRules) {
|
||||
$configuration['apply-rules'] = $applyRules;
|
||||
}
|
||||
|
||||
$this->repository->setConfiguration($this->importJob, $configuration);
|
||||
$messages = new MessageBag();
|
||||
|
||||
if (3 !== count($configuration)) {
|
||||
$messages->add('some_key', 'Ignore this error: ' . count($configuration));
|
||||
}
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the data required for the next step in the job configuration.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @return array
|
||||
*/
|
||||
public function getNextData(): array
|
||||
{
|
||||
return [
|
||||
'rulesOptions' => [
|
||||
1 => (string) trans('firefly.yes'),
|
||||
0 => (string) trans('firefly.no'),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the view of the next step in the job configuration.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
*/
|
||||
public function getNextView(): string
|
||||
{
|
||||
// first configure artist:
|
||||
$config = $this->importJob->configuration;
|
||||
$artist = $config['artist'] ?? '';
|
||||
$song = $config['song'] ?? '';
|
||||
$album = $config['album'] ?? '';
|
||||
$applyRules = $config['apply-rules'] ?? null;
|
||||
if (null === $applyRules) {
|
||||
return 'import.fake.apply-rules';
|
||||
}
|
||||
if ('david bowie' !== strtolower($artist)) {
|
||||
return 'import.fake.enter-artist';
|
||||
}
|
||||
if ('golden years' !== strtolower($song)) {
|
||||
return 'import.fake.enter-song';
|
||||
}
|
||||
if ('new' !== $this->importJob->stage && 'station to station' !== strtolower($album)) {
|
||||
return 'import.fake.enter-album';
|
||||
}
|
||||
|
||||
return 'impossible-view'; // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
/**
|
||||
* Set import job.
|
||||
*
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
}
|
||||
}
|
@ -1,161 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* FileJobConfiguration.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\Import\JobConfiguration;
|
||||
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Support\Import\JobConfiguration\File\ConfigureMappingHandler;
|
||||
use FireflyIII\Support\Import\JobConfiguration\File\ConfigureRolesHandler;
|
||||
use FireflyIII\Support\Import\JobConfiguration\File\ConfigureUploadHandler;
|
||||
use FireflyIII\Support\Import\JobConfiguration\File\FileConfigurationInterface;
|
||||
use FireflyIII\Support\Import\JobConfiguration\File\NewFileJobHandler;
|
||||
use Illuminate\Support\MessageBag;
|
||||
|
||||
/**
|
||||
* Class FileJobConfiguration
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class FileJobConfiguration implements JobConfigurationInterface
|
||||
{
|
||||
/** @var ImportJob The import job */
|
||||
private $importJob;
|
||||
/** @var ImportJobRepositoryInterface Import job repository */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* Returns true when the initial configuration for this job is complete.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function configurationComplete(): bool
|
||||
{
|
||||
return 'ready_to_run' === $this->importJob->stage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store any data from the $data array into the job. Anything in the message bag will be flashed
|
||||
* as an error to the user, regardless of its content.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function configureJob(array $data): MessageBag
|
||||
{
|
||||
$configurator = $this->getConfigurationObject();
|
||||
$configurator->setImportJob($this->importJob);
|
||||
|
||||
return $configurator->configureJob($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the data required for the next step in the job configuration.
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @return array
|
||||
*/
|
||||
public function getNextData(): array
|
||||
{
|
||||
$configurator = $this->getConfigurationObject();
|
||||
$configurator->setImportJob($this->importJob);
|
||||
|
||||
return $configurator->getNextData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the view of the next step in the job configuration.
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @return string
|
||||
*
|
||||
*/
|
||||
public function getNextView(): string
|
||||
{
|
||||
switch ($this->importJob->stage) {
|
||||
case 'new':
|
||||
return 'import.file.new';
|
||||
case 'configure-upload':
|
||||
return 'import.file.configure-upload';
|
||||
case 'roles':
|
||||
return 'import.file.roles';
|
||||
case 'map':
|
||||
return 'import.file.map';
|
||||
default:
|
||||
// @codeCoverageIgnoreStart
|
||||
throw new FireflyException(
|
||||
sprintf('FileJobConfiguration::getNextView() cannot handle stage "%s"', $this->importJob->stage)
|
||||
);
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set import job.
|
||||
*
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the configuration handler for this specific stage.
|
||||
*
|
||||
* @throws FireflyException
|
||||
*
|
||||
* @return FileConfigurationInterface
|
||||
*/
|
||||
private function getConfigurationObject(): FileConfigurationInterface
|
||||
{
|
||||
$class = 'DoNotExist';
|
||||
switch ($this->importJob->stage) {
|
||||
case 'new': // has nothing, no file upload or anything.
|
||||
$class = NewFileJobHandler::class;
|
||||
break;
|
||||
case 'configure-upload':
|
||||
$class = ConfigureUploadHandler::class;
|
||||
break;
|
||||
case 'roles':
|
||||
$class = ConfigureRolesHandler::class;
|
||||
break;
|
||||
case 'map':
|
||||
$class = ConfigureMappingHandler::class;
|
||||
break;
|
||||
}
|
||||
if (!class_exists($class)) {
|
||||
throw new FireflyException(sprintf('Class %s does not exist in getConfigurationClass().', $class)); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
return app($class);
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* FinTSConfigurationSteps.php
|
||||
* Copyright (c) 2019 https://github.com/bnw
|
||||
*
|
||||
* 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\Import\JobConfiguration;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class FinTSConfigurationSteps
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
abstract class FinTSConfigurationSteps
|
||||
{
|
||||
public const NEW = 'new';
|
||||
public const CHOOSE_ACCOUNT = 'choose_account';
|
||||
public const GO_FOR_IMPORT = 'go-for-import';
|
||||
}
|
@ -1,137 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* FinTSJobConfiguration.php
|
||||
* Copyright (c) 2019 https://github.com/bnw
|
||||
*
|
||||
* 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\Import\JobConfiguration;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Support\Import\JobConfiguration\FinTS\ChooseAccountHandler;
|
||||
use FireflyIII\Support\Import\JobConfiguration\FinTS\FinTSConfigurationInterface;
|
||||
use FireflyIII\Support\Import\JobConfiguration\FinTS\NewFinTSJobHandler;
|
||||
use Illuminate\Support\MessageBag;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class FinTSJobConfiguration
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class FinTSJobConfiguration implements JobConfigurationInterface
|
||||
{
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
|
||||
/**
|
||||
* Returns true when the initial configuration for this job is complete.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function configurationComplete(): bool
|
||||
{
|
||||
return $this->importJob->stage === FinTSConfigurationSteps::GO_FOR_IMPORT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store any data from the $data array into the job. Anything in the message bag will be flashed
|
||||
* as an error to the user, regardless of its content.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function configureJob(array $data): MessageBag
|
||||
{
|
||||
return $this->getConfigurationObject()->configureJob($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the data required for the next step in the job configuration.
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @return array
|
||||
*/
|
||||
public function getNextData(): array
|
||||
{
|
||||
return $this->getConfigurationObject()->getNextData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the view of the next step in the job configuration.
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @return string
|
||||
*/
|
||||
public function getNextView(): string
|
||||
{
|
||||
switch ($this->importJob->stage) {
|
||||
case FinTSConfigurationSteps::NEW:
|
||||
case FinTSConfigurationSteps::CHOOSE_ACCOUNT:
|
||||
return 'import.fints.' . $this->importJob->stage;
|
||||
break;
|
||||
default:
|
||||
// @codeCoverageIgnoreStart
|
||||
throw new FireflyException(
|
||||
sprintf('FinTSJobConfiguration::getNextView() cannot handle stage "%s"', $this->importJob->stage)
|
||||
);
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the configuration handler for this specific stage.
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @return FinTSConfigurationInterface
|
||||
*/
|
||||
private function getConfigurationObject(): FinTSConfigurationInterface
|
||||
{
|
||||
$class = 'DoNotExist';
|
||||
switch ($this->importJob->stage) {
|
||||
case FinTSConfigurationSteps::NEW:
|
||||
$class = NewFinTSJobHandler::class;
|
||||
break;
|
||||
case FinTSConfigurationSteps::CHOOSE_ACCOUNT:
|
||||
$class = ChooseAccountHandler::class;
|
||||
break;
|
||||
}
|
||||
if (!class_exists($class)) {
|
||||
throw new FireflyException(sprintf('Class %s does not exist in getConfigurationClass().', $class)); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$configurator = app($class);
|
||||
$configurator->setImportJob($this->importJob);
|
||||
|
||||
return $configurator;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* JobConfigurationInterface.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\Import\JobConfiguration;
|
||||
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use Illuminate\Support\MessageBag;
|
||||
|
||||
/**
|
||||
* Interface JobConfigurationInterface.
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
interface JobConfigurationInterface
|
||||
{
|
||||
/**
|
||||
* Returns true when the initial configuration for this job is complete.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function configurationComplete(): bool;
|
||||
|
||||
/**
|
||||
* Store any data from the $data array into the job. Anything in the message bag will be flashed
|
||||
* as an error to the user, regardless of its content.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function configureJob(array $data): MessageBag;
|
||||
|
||||
/**
|
||||
* Return the data required for the next step in the job configuration.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getNextData(): array;
|
||||
|
||||
/**
|
||||
* Returns the view of the next step in the job configuration.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNextView(): string;
|
||||
|
||||
/**
|
||||
* Set import job.
|
||||
*
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void;
|
||||
}
|
@ -1,156 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SpectreJobConfiguration.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\Import\JobConfiguration;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Support\Import\JobConfiguration\Spectre\AuthenticatedHandler;
|
||||
use FireflyIII\Support\Import\JobConfiguration\Spectre\ChooseAccountsHandler;
|
||||
use FireflyIII\Support\Import\JobConfiguration\Spectre\ChooseLoginHandler;
|
||||
use FireflyIII\Support\Import\JobConfiguration\Spectre\DoAuthenticateHandler;
|
||||
use FireflyIII\Support\Import\JobConfiguration\Spectre\NewSpectreJobHandler;
|
||||
use FireflyIII\Support\Import\JobConfiguration\Spectre\SpectreJobConfigurationInterface;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class SpectreJobConfiguration
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class SpectreJobConfiguration implements JobConfigurationInterface
|
||||
{
|
||||
/** @var SpectreJobConfigurationInterface The job handler. */
|
||||
private $handler;
|
||||
/** @var ImportJob The import job */
|
||||
private $importJob;
|
||||
/** @var ImportJobRepositoryInterface Import job repository */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* Returns true when the initial configuration for this job is complete.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function configurationComplete(): bool
|
||||
{
|
||||
return $this->handler->configurationComplete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Store any data from the $data array into the job. Anything in the message bag will be flashed
|
||||
* as an error to the user, regardless of its content.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function configureJob(array $data): MessageBag
|
||||
{
|
||||
return $this->handler->configureJob($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the data required for the next step in the job configuration.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getNextData(): array
|
||||
{
|
||||
return $this->handler->getNextData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the view of the next step in the job configuration.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNextView(): string
|
||||
{
|
||||
return $this->handler->getNextView();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the import job.
|
||||
*
|
||||
* @param ImportJob $importJob
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
$this->handler = $this->getHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get correct handler.
|
||||
*
|
||||
* @throws FireflyException
|
||||
*
|
||||
* @return SpectreJobConfigurationInterface
|
||||
*/
|
||||
private function getHandler(): SpectreJobConfigurationInterface
|
||||
{
|
||||
Log::debug(sprintf('Now in SpectreJobConfiguration::getHandler() with stage "%s"', $this->importJob->stage));
|
||||
$handler = null;
|
||||
switch ($this->importJob->stage) {
|
||||
case 'new':
|
||||
/** @var NewSpectreJobHandler $handler */
|
||||
$handler = app(NewSpectreJobHandler::class);
|
||||
$handler->setImportJob($this->importJob);
|
||||
break;
|
||||
case 'do-authenticate':
|
||||
/** @var DoAuthenticateHandler $handler */
|
||||
$handler = app(DoAuthenticateHandler::class);
|
||||
$handler->setImportJob($this->importJob);
|
||||
break;
|
||||
case 'choose-login':
|
||||
/** @var ChooseLoginHandler $handler */
|
||||
$handler = app(ChooseLoginHandler::class);
|
||||
$handler->setImportJob($this->importJob);
|
||||
break;
|
||||
case 'authenticated':
|
||||
/** @var AuthenticatedHandler $handler */
|
||||
$handler = app(AuthenticatedHandler::class);
|
||||
$handler->setImportJob($this->importJob);
|
||||
break;
|
||||
case 'choose-accounts':
|
||||
/** @var ChooseAccountsHandler $handler */
|
||||
$handler = app(ChooseAccountsHandler::class);
|
||||
$handler->setImportJob($this->importJob);
|
||||
break;
|
||||
default:
|
||||
// @codeCoverageIgnoreStart
|
||||
throw new FireflyException(sprintf('Firefly III cannot create a configuration handler for stage "%s"', $this->importJob->stage));
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
return $handler;
|
||||
}
|
||||
}
|
@ -1,143 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* YnabJobConfiguration.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\Import\JobConfiguration;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Support\Import\JobConfiguration\Ynab\NewYnabJobHandler;
|
||||
use FireflyIII\Support\Import\JobConfiguration\Ynab\SelectAccountsHandler;
|
||||
use FireflyIII\Support\Import\JobConfiguration\Ynab\SelectBudgetHandler;
|
||||
use FireflyIII\Support\Import\JobConfiguration\Ynab\YnabJobConfigurationInterface;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class YnabJobConfiguration
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class YnabJobConfiguration implements JobConfigurationInterface
|
||||
{
|
||||
/** @var YnabJobConfigurationInterface The job handler. */
|
||||
private $handler;
|
||||
/** @var ImportJob The import job */
|
||||
private $importJob;
|
||||
/** @var ImportJobRepositoryInterface Import job repository */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* Returns true when the initial configuration for this job is complete.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function configurationComplete(): bool
|
||||
{
|
||||
return $this->handler->configurationComplete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Store any data from the $data array into the job. Anything in the message bag will be flashed
|
||||
* as an error to the user, regardless of its content.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function configureJob(array $data): MessageBag
|
||||
{
|
||||
return $this->handler->configureJob($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the data required for the next step in the job configuration.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getNextData(): array
|
||||
{
|
||||
return $this->handler->getNextData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the view of the next step in the job configuration.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNextView(): string
|
||||
{
|
||||
return $this->handler->getNextView();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set import job.
|
||||
*
|
||||
* @param ImportJob $importJob
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
$this->handler = $this->getHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get correct handler.
|
||||
*
|
||||
* @throws FireflyException
|
||||
*
|
||||
* @return YnabJobConfigurationInterface
|
||||
*/
|
||||
private function getHandler(): YnabJobConfigurationInterface
|
||||
{
|
||||
Log::debug(sprintf('Now in YnabJobConfiguration::getHandler() with stage "%s"', $this->importJob->stage));
|
||||
$handler = null;
|
||||
switch ($this->importJob->stage) {
|
||||
case 'new':
|
||||
/** @var NewYnabJobHandler $handler */
|
||||
$handler = app(NewYnabJobHandler::class);
|
||||
$handler->setImportJob($this->importJob);
|
||||
break;
|
||||
case 'select_budgets':
|
||||
/** @var SelectBudgetHandler $handler */
|
||||
$handler = app(SelectBudgetHandler::class);
|
||||
$handler->setImportJob($this->importJob);
|
||||
break;
|
||||
case 'select_accounts':
|
||||
$handler = app(SelectAccountsHandler::class);
|
||||
$handler->setImportJob($this->importJob);
|
||||
break;
|
||||
default:
|
||||
// @codeCoverageIgnoreStart
|
||||
throw new FireflyException(sprintf('Firefly III cannot create a YNAB configuration handler for stage "%s"', $this->importJob->stage));
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
return $handler;
|
||||
}
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* AssetAccountIbans.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\Import\Mapper;
|
||||
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
|
||||
/**
|
||||
* Class AssetAccounts.
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class AssetAccountIbans implements MapperInterface
|
||||
{
|
||||
/**
|
||||
* Get map of asset accounts.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMap(): array
|
||||
{
|
||||
/** @var AccountRepositoryInterface $accountRepository */
|
||||
$accountRepository = app(AccountRepositoryInterface::class);
|
||||
$set = $accountRepository->getAccountsByType(
|
||||
[AccountType::DEFAULT, AccountType::ASSET,
|
||||
AccountType::LOAN, AccountType::DEBT,
|
||||
AccountType::CREDITCARD, AccountType::MORTGAGE,
|
||||
]
|
||||
);
|
||||
$topList = [];
|
||||
$list = [];
|
||||
|
||||
/** @var Account $account */
|
||||
foreach ($set as $account) {
|
||||
$iban = $account->iban ?? '';
|
||||
$accountId = (int) $account->id;
|
||||
if ('' !== $iban) {
|
||||
$name = $account->iban . ' (' . $account->name . ')';
|
||||
|
||||
// is a liability?
|
||||
if (in_array($account->accountType->type, [AccountType::LOAN, AccountType::DEBT, AccountType::CREDITCARD, AccountType::MORTGAGE], true)) {
|
||||
$name = $name . ' (' . strtolower(trans('import.import_liability_select')) . ')';
|
||||
}
|
||||
|
||||
$topList[$accountId] = $name;
|
||||
}
|
||||
if ('' === $iban) {
|
||||
$name = $account->name;
|
||||
// is a liability?
|
||||
if (in_array($account->accountType->type, [AccountType::LOAN, AccountType::DEBT, AccountType::CREDITCARD, AccountType::MORTGAGE], true)) {
|
||||
$name = $name . ' (' . strtolower(trans('import.import_liability_select')) . ')';
|
||||
}
|
||||
$list[$accountId] = $name;
|
||||
}
|
||||
}
|
||||
/** @noinspection AdditionOperationOnArraysInspection */
|
||||
$list = $topList + $list;
|
||||
asort($list);
|
||||
$list = [0 => (string) trans('import.map_do_not_map')] + $list;
|
||||
|
||||
return $list;
|
||||
}
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* AssetAccounts.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\Import\Mapper;
|
||||
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
|
||||
/**
|
||||
* Class AssetAccounts.
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class AssetAccounts implements MapperInterface
|
||||
{
|
||||
/**
|
||||
* Get map of asset accounts.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMap(): array
|
||||
{
|
||||
/** @var AccountRepositoryInterface $accountRepository */
|
||||
$accountRepository = app(AccountRepositoryInterface::class);
|
||||
$set = $accountRepository->getAccountsByType(
|
||||
[AccountType::DEFAULT, AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::CREDITCARD, AccountType::MORTGAGE,]
|
||||
);
|
||||
$list = [];
|
||||
|
||||
/** @var Account $account */
|
||||
foreach ($set as $account) {
|
||||
$accountId = (int) $account->id;
|
||||
$name = $account->name;
|
||||
$iban = $account->iban ?? '';
|
||||
if ('' !== $iban) {
|
||||
$name .= ' (' . $iban . ')';
|
||||
}
|
||||
|
||||
// is a liability?
|
||||
if (in_array($account->accountType->type, [AccountType::LOAN, AccountType::DEBT, AccountType::CREDITCARD, AccountType::MORTGAGE], true)) {
|
||||
$name = trans('import.import_liability_select') . ': ' . $name;
|
||||
}
|
||||
|
||||
$list[$accountId] = $name;
|
||||
}
|
||||
asort($list);
|
||||
$list = [0 => (string) trans('import.map_do_not_map')] + $list;
|
||||
|
||||
return $list;
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Bills.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\Import\Mapper;
|
||||
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
|
||||
/**
|
||||
* Class Bills.
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class Bills implements MapperInterface
|
||||
{
|
||||
/**
|
||||
* Get map of bills.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMap(): array
|
||||
{
|
||||
/** @var BillRepositoryInterface $repository */
|
||||
$repository = app(BillRepositoryInterface::class);
|
||||
$result = $repository->getBills();
|
||||
$list = [];
|
||||
|
||||
/** @var Bill $bill */
|
||||
foreach ($result as $bill) {
|
||||
$billId = (int) $bill->id;
|
||||
$list[$billId] = $bill->name;
|
||||
}
|
||||
asort($list);
|
||||
$list = [0 => (string) trans('import.map_do_not_map')] + $list;
|
||||
|
||||
return $list;
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Budgets.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\Import\Mapper;
|
||||
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
|
||||
/**
|
||||
* Class Budgets.
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class Budgets implements MapperInterface
|
||||
{
|
||||
/**
|
||||
* Get map of budgets.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMap(): array
|
||||
{
|
||||
/** @var BudgetRepositoryInterface $repository */
|
||||
$repository = app(BudgetRepositoryInterface::class);
|
||||
$result = $repository->getActiveBudgets();
|
||||
$list = [];
|
||||
|
||||
/** @var Budget $budget */
|
||||
foreach ($result as $budget) {
|
||||
$budgetId = (int) $budget->id;
|
||||
$list[$budgetId] = $budget->name;
|
||||
}
|
||||
asort($list);
|
||||
$list = [0 => (string) trans('import.map_do_not_map')] + $list;
|
||||
|
||||
return $list;
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Categories.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\Import\Mapper;
|
||||
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||
|
||||
/**
|
||||
* Class Categories.
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class Categories implements MapperInterface
|
||||
{
|
||||
/**
|
||||
* Get map of categories.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMap(): array
|
||||
{
|
||||
/** @var CategoryRepositoryInterface $repository */
|
||||
$repository = app(CategoryRepositoryInterface::class);
|
||||
$result = $repository->getCategories();
|
||||
$list = [];
|
||||
|
||||
/** @var Category $category */
|
||||
foreach ($result as $category) {
|
||||
$categoryId = (int) $category->id;
|
||||
$list[$categoryId] = $category->name;
|
||||
}
|
||||
asort($list);
|
||||
$list = [0 => (string) trans('import.map_do_not_map')] + $list;
|
||||
|
||||
return $list;
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* MapperInterface.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\Import\Mapper;
|
||||
|
||||
/**
|
||||
* Interface MapperInterface.
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
interface MapperInterface
|
||||
{
|
||||
/**
|
||||
* Get map of objects.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMap(): array;
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* OpposingAccountIbans.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\Import\Mapper;
|
||||
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
|
||||
/**
|
||||
* Class OpposingAccounts.
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class OpposingAccountIbans implements MapperInterface
|
||||
{
|
||||
/**
|
||||
* Get map of opposing accounts.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMap(): array
|
||||
{
|
||||
/** @var AccountRepositoryInterface $accountRepository */
|
||||
$accountRepository = app(AccountRepositoryInterface::class);
|
||||
$set = $accountRepository->getAccountsByType(
|
||||
[
|
||||
AccountType::DEFAULT, AccountType::ASSET,
|
||||
AccountType::EXPENSE, AccountType::BENEFICIARY,
|
||||
AccountType::REVENUE, AccountType::LOAN, AccountType::DEBT,
|
||||
AccountType::CREDITCARD, AccountType::MORTGAGE,
|
||||
]
|
||||
);
|
||||
$topList = [];
|
||||
$list = [];
|
||||
|
||||
/** @var Account $account */
|
||||
foreach ($set as $account) {
|
||||
$iban = $account->iban ?? '';
|
||||
$accountId = (int) $account->id;
|
||||
if ('' !== $iban) {
|
||||
$name = $account->iban . ' (' . $account->name . ')';
|
||||
|
||||
// is a liability?
|
||||
if (in_array($account->accountType->type, [AccountType::LOAN, AccountType::DEBT, AccountType::CREDITCARD, AccountType::MORTGAGE], true)) {
|
||||
$name = $name . ' (' . strtolower(trans('import.import_liability_select')) . ')';
|
||||
}
|
||||
|
||||
$topList[$accountId] = $name;
|
||||
|
||||
}
|
||||
if ('' === $iban) {
|
||||
$name = $account->name;
|
||||
// is a liability?
|
||||
if (in_array($account->accountType->type, [AccountType::LOAN, AccountType::DEBT, AccountType::CREDITCARD, AccountType::MORTGAGE], true)) {
|
||||
$name = $name . ' (' . strtolower(trans('import.import_liability_select')) . ')';
|
||||
}
|
||||
$list[$accountId] = $name;
|
||||
}
|
||||
}
|
||||
/** @noinspection AdditionOperationOnArraysInspection */
|
||||
$list = $topList + $list;
|
||||
asort($list);
|
||||
$list = [0 => (string) trans('import.map_do_not_map')] + $list;
|
||||
|
||||
return $list;
|
||||
}
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* OpposingAccounts.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\Import\Mapper;
|
||||
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
|
||||
/**
|
||||
* Class OpposingAccounts.
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
*/
|
||||
class OpposingAccounts implements MapperInterface
|
||||
{
|
||||
/**
|
||||
* Get map of opposing accounts.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMap(): array
|
||||
{
|
||||
/** @var AccountRepositoryInterface $accountRepository */
|
||||
$accountRepository = app(AccountRepositoryInterface::class);
|
||||
$set = $accountRepository->getAccountsByType(
|
||||
[
|
||||
AccountType::DEFAULT, AccountType::ASSET,
|
||||
AccountType::EXPENSE, AccountType::BENEFICIARY,
|
||||
AccountType::REVENUE, AccountType::LOAN, AccountType::DEBT,
|
||||
AccountType::CREDITCARD, AccountType::MORTGAGE,
|
||||
]
|
||||
);
|
||||
$list = [];
|
||||
|
||||
/** @var Account $account */
|
||||
foreach ($set as $account) {
|
||||
$accountId = (int) $account->id;
|
||||
$name = $account->name;
|
||||
$iban = $account->iban ?? '';
|
||||
if ('' !== $iban) {
|
||||
$name .= ' (' . $iban . ')';
|
||||
}
|
||||
// is a liability?
|
||||
if (in_array($account->accountType->type, [AccountType::LOAN, AccountType::DEBT, AccountType::CREDITCARD, AccountType::MORTGAGE], true)) {
|
||||
$name = trans('import.import_liability_select') . ': ' . $name;
|
||||
}
|
||||
$list[$accountId] = $name;
|
||||
}
|
||||
asort($list);
|
||||
$list = [0 => (string) trans('import.map_do_not_map')] + $list;
|
||||
|
||||
return $list;
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Tags.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\Import\Mapper;
|
||||
|
||||
use FireflyIII\Models\Tag;
|
||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||
|
||||
/**
|
||||
* Class Tags.
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class Tags implements MapperInterface
|
||||
{
|
||||
/**
|
||||
* Get map of tags.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMap(): array
|
||||
{
|
||||
/** @var TagRepositoryInterface $repository */
|
||||
$repository = app(TagRepositoryInterface::class);
|
||||
$result = $repository->get();
|
||||
$list = [];
|
||||
|
||||
/** @var Tag $tag */
|
||||
foreach ($result as $tag) {
|
||||
$tagId = (int) $tag->id;
|
||||
$list[$tagId] = $tag->tag;
|
||||
}
|
||||
asort($list);
|
||||
$list = [0 => (string) trans('import.map_do_not_map')] + $list;
|
||||
|
||||
return $list;
|
||||
}
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* TransactionCurrencies.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\Import\Mapper;
|
||||
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
|
||||
/**
|
||||
* Class TransactionCurrencies.
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class TransactionCurrencies implements MapperInterface
|
||||
{
|
||||
/**
|
||||
* Get map of currencies.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMap(): array
|
||||
{
|
||||
/** @var CurrencyRepositoryInterface $repository */
|
||||
$repository = app(CurrencyRepositoryInterface::class);
|
||||
$currencies = $repository->get();
|
||||
$list = [];
|
||||
foreach ($currencies as $currency) {
|
||||
$currencyId = (int) $currency->id;
|
||||
$list[$currencyId] = $currency->name . ' (' . $currency->code . ')';
|
||||
}
|
||||
asort($list);
|
||||
|
||||
$list = [0 => (string) trans('import.map_do_not_map')] + $list;
|
||||
|
||||
return $list;
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* PreProcessorInterface.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\Import\MapperPreProcess;
|
||||
|
||||
/**
|
||||
* Interface PreProcessorInterface.
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
interface PreProcessorInterface
|
||||
{
|
||||
/**
|
||||
* Run preprocessor.
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function run(string $value): array;
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* TagsComma.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\Import\MapperPreProcess;
|
||||
|
||||
/**
|
||||
* Class TagsComma.
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class TagsComma implements PreProcessorInterface
|
||||
{
|
||||
/**
|
||||
* Explode and filter list of comma separated tags.
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function run(string $value): array
|
||||
{
|
||||
$set = explode(',', $value);
|
||||
$set = array_map('trim', $set);
|
||||
$set = array_filter($set, '\strlen');
|
||||
|
||||
return array_values($set);
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* TagsSpace.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\Import\MapperPreProcess;
|
||||
|
||||
/**
|
||||
* Class TagsSpace.
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class TagsSpace implements PreProcessorInterface
|
||||
{
|
||||
/**
|
||||
* Explode and filter list of space separated tags.
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function run(string $value): array
|
||||
{
|
||||
$set = explode(' ', $value);
|
||||
$set = array_map('trim', $set);
|
||||
$set = array_filter($set, '\strlen');
|
||||
|
||||
return array_values($set);
|
||||
}
|
||||
}
|
@ -1,236 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* BunqPrerequisites.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\Import\Prerequisites;
|
||||
|
||||
use bunq\Util\BunqEnumApiEnvironmentType;
|
||||
use Exception;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Services\Bunq\ApiContext;
|
||||
use FireflyIII\Services\IP\IPRetrievalInterface;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* This class contains all the routines necessary to connect to Bunq.
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class BunqPrerequisites implements PrerequisitesInterface
|
||||
{
|
||||
/** @var User The current user */
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* BunqPrerequisites constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if ('testing' === config('app.env')) {
|
||||
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns view name that allows user to fill in prerequisites.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getView(): string
|
||||
{
|
||||
return 'import.bunq.prerequisites';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns any values required for the prerequisites-view.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getViewParameters(): array
|
||||
{
|
||||
Log::debug('Now in BunqPrerequisites::getViewParameters()');
|
||||
$key = '';
|
||||
$externalIP = '';
|
||||
if ($this->hasApiKey()) {
|
||||
$key = app('preferences')->getForUser($this->user, 'bunq_api_key', null)->data;
|
||||
}
|
||||
if ($this->hasExternalIP()) {
|
||||
$externalIP = app('preferences')->getForUser($this->user, 'bunq_external_ip', null)->data;
|
||||
}
|
||||
if (!$this->hasExternalIP()) {
|
||||
/** @var IPRetrievalInterface $service */
|
||||
$service = app(IPRetrievalInterface::class);
|
||||
$externalIP = (string) $service->getIP();
|
||||
}
|
||||
|
||||
return ['api_key' => $key, 'external_ip' => $externalIP];
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate if all prerequisites have been met.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isComplete(): bool
|
||||
{
|
||||
return $this->hasApiKey() && $this->hasExternalIP() && $this->hasApiContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the user for this Prerequisites-routine. Class is expected to implement and save this.
|
||||
*
|
||||
* @param User $user
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function setUser(User $user): void
|
||||
{
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method responds to the user's submission of an API key. Should do nothing but store the value.
|
||||
*
|
||||
* Errors must be returned in the message bag under the field name they are requested by.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return MessageBag
|
||||
*
|
||||
*/
|
||||
public function storePrerequisites(array $data): MessageBag
|
||||
{
|
||||
$apiKey = $data['api_key'] ?? '';
|
||||
$externalIP = $data['external_ip'] ?? '';
|
||||
Log::debug('Storing bunq API key');
|
||||
app('preferences')->setForUser($this->user, 'bunq_api_key', $apiKey);
|
||||
app('preferences')->setForUser($this->user, 'bunq_external_ip', $externalIP);
|
||||
$environment = $this->getBunqEnvironment();
|
||||
$deviceDescription = 'Firefly III v' . config('firefly.version');
|
||||
$permittedIps = [$externalIP];
|
||||
Log::debug(sprintf('Environment for bunq is %s', $environment->getChoiceString()));
|
||||
|
||||
try {
|
||||
/** @var ApiContext $object */
|
||||
$object = app(ApiContext::class);
|
||||
$apiContext = $object->create($environment, $apiKey, $deviceDescription, $permittedIps);
|
||||
} catch (FireflyException $e) {
|
||||
$messages = new MessageBag();
|
||||
$messages->add('bunq_error', $e->getMessage());
|
||||
|
||||
return $messages;
|
||||
}
|
||||
// store context in JSON:
|
||||
try {
|
||||
$json = $apiContext->toJson();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Exception $e) {
|
||||
$messages = new MessageBag();
|
||||
$messages->add('bunq_error', $e->getMessage());
|
||||
|
||||
return $messages;
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
// and store for user:
|
||||
app('preferences')->setForUser($this->user, 'bunq_api_context', $json);
|
||||
|
||||
return new MessageBag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get correct bunq environment.
|
||||
*
|
||||
* @return BunqEnumApiEnvironmentType
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
private function getBunqEnvironment(): BunqEnumApiEnvironmentType
|
||||
{
|
||||
$env = config('firefly.bunq_use_sandbox');
|
||||
if (null === $env) {
|
||||
return BunqEnumApiEnvironmentType::PRODUCTION();
|
||||
}
|
||||
if (false === $env) {
|
||||
return BunqEnumApiEnvironmentType::PRODUCTION();
|
||||
}
|
||||
|
||||
return BunqEnumApiEnvironmentType::SANDBOX();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we have API context.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function hasApiContext(): bool
|
||||
{
|
||||
$apiContext = app('preferences')->getForUser($this->user, 'bunq_api_context', null);
|
||||
if (null === $apiContext) {
|
||||
return false;
|
||||
}
|
||||
if ('' === (string) $apiContext->data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we have the API key.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function hasApiKey(): bool
|
||||
{
|
||||
$apiKey = app('preferences')->getForUser($this->user, 'bunq_api_key', null);
|
||||
if (null === $apiKey) {
|
||||
return false;
|
||||
}
|
||||
if ('' === (string) $apiKey->data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if we have an external IP.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function hasExternalIP(): bool
|
||||
{
|
||||
$externalIP = app('preferences')->getForUser($this->user, 'bunq_external_ip', null);
|
||||
if (null === $externalIP) {
|
||||
return false;
|
||||
}
|
||||
if ('' === (string) $externalIP->data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,146 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* FakePrerequisites.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\Import\Prerequisites;
|
||||
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Log;
|
||||
use function request;
|
||||
|
||||
/**
|
||||
* This class contains all the routines necessary for the fake import provider.
|
||||
*
|
||||
* Class FakePrerequisites
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class FakePrerequisites implements PrerequisitesInterface
|
||||
{
|
||||
/** @var User The current user */
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* FakePrerequisites constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if ('testing' === config('app.env')) {
|
||||
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns view name that allows user to fill in prerequisites. Currently asks for the API key.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @return string
|
||||
*/
|
||||
public function getView(): string
|
||||
{
|
||||
return 'import.fake.prerequisites';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns any values required for the prerequisites-view.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getViewParameters(): array
|
||||
{
|
||||
$apiKey = '';
|
||||
if ($this->hasApiKey()) {
|
||||
$apiKey = app('preferences')->getForUser($this->user, 'fake_api_key', null)->data;
|
||||
}
|
||||
$oldKey = (string) request()->old('api_key');
|
||||
if ('' !== $oldKey) {
|
||||
$apiKey = request()->old('api_key'); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
return ['api_key' => $apiKey];
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate if all prerequisites have been met.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isComplete(): bool
|
||||
{
|
||||
return $this->hasApiKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the user for this Prerequisites-routine. Class is expected to implement and save this.
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function setUser(User $user): void
|
||||
{
|
||||
$this->user = $user;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Store fake prerequisites.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function storePrerequisites(array $data): MessageBag
|
||||
{
|
||||
$apiKey = $data['api_key'] ?? '';
|
||||
$messageBag = new MessageBag();
|
||||
if (32 !== strlen($apiKey)) {
|
||||
$messageBag->add('api_key', 'API key must be 32 chars.');
|
||||
|
||||
return $messageBag;
|
||||
}
|
||||
|
||||
app('preferences')->setForUser($this->user, 'fake_api_key', $apiKey);
|
||||
|
||||
return $messageBag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we have an API key.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function hasApiKey(): bool
|
||||
{
|
||||
$apiKey = app('preferences')->getForUser($this->user, 'fake_api_key', false);
|
||||
if (null === $apiKey) {
|
||||
return false;
|
||||
}
|
||||
if (null === $apiKey->data) {
|
||||
return false;
|
||||
}
|
||||
if (32 === strlen((string) $apiKey->data)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* FilePrerequisites.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\Import\Prerequisites;
|
||||
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
*
|
||||
* This class contains all the routines necessary to import from a file. Hint: there are none.
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class FilePrerequisites implements PrerequisitesInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* FilePrerequisites constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if ('testing' === config('app.env')) {
|
||||
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns view name that allows user to fill in prerequisites.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getView(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns any values required for the prerequisites-view.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getViewParameters(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate if all prerequisites have been met.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isComplete(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the user for this Prerequisites-routine. Class is expected to implement and save this.
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function setUser(User $user): void
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method responds to the user's submission of an API key. Should do nothing but store the value.
|
||||
*
|
||||
* Errors must be returned in the message bag under the field name they are requested by.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function storePrerequisites(array $data): MessageBag
|
||||
{
|
||||
return new MessageBag;
|
||||
}
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* PrerequisitesInterface.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\Import\Prerequisites;
|
||||
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Support\MessageBag;
|
||||
|
||||
/**
|
||||
* Interface PrerequisitesInterface
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
interface PrerequisitesInterface
|
||||
{
|
||||
/**
|
||||
* Returns view name that allows user to fill in prerequisites.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getView(): string;
|
||||
|
||||
/**
|
||||
* Returns any values required for the prerequisites-view.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getViewParameters(): array;
|
||||
|
||||
/**
|
||||
* Indicate if all prerequisites have been met.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isComplete(): bool;
|
||||
|
||||
/**
|
||||
* Set the user for this Prerequisites-routine. Class is expected to implement and save this.
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function setUser(User $user): void;
|
||||
|
||||
/**
|
||||
* This method responds to the user's submission of an API key. Should do nothing but store the value.
|
||||
*
|
||||
* Errors must be returned in the message bag under the field name they are requested by.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function storePrerequisites(array $data): MessageBag;
|
||||
}
|
@ -1,206 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SpectrePrerequisites.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\Import\Prerequisites;
|
||||
|
||||
use FireflyIII\Models\Preference;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* This class contains all the routines necessary to connect to Spectre.
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class SpectrePrerequisites implements PrerequisitesInterface
|
||||
{
|
||||
/** @var User The current user */
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* SpectrePrerequisites constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if ('testing' === config('app.env')) {
|
||||
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns view name that allows user to fill in prerequisites.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getView(): string
|
||||
{
|
||||
return 'import.spectre.prerequisites';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns any values required for the prerequisites-view.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getViewParameters(): array
|
||||
{
|
||||
/** @var Preference $appIdPreference */
|
||||
$appIdPreference = app('preferences')->getForUser($this->user, 'spectre_app_id', null);
|
||||
$appId = null === $appIdPreference ? '' : $appIdPreference->data;
|
||||
/** @var Preference $secretPreference */
|
||||
$secretPreference = app('preferences')->getForUser($this->user, 'spectre_secret', null);
|
||||
$secret = null === $secretPreference ? '' : $secretPreference->data;
|
||||
$publicKey = $this->getPublicKey();
|
||||
|
||||
return [
|
||||
'app_id' => $appId,
|
||||
'secret' => $secret,
|
||||
'public_key' => $publicKey,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate if all prerequisites have been met.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isComplete(): bool
|
||||
{
|
||||
return $this->hasAppId() && $this->hasSecret();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the user for this Prerequisites-routine. Class is expected to implement and save this.
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function setUser(User $user): void
|
||||
{
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method responds to the user's submission of an API key. Should do nothing but store the value.
|
||||
*
|
||||
* Errors must be returned in the message bag under the field name they are requested by.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function storePrerequisites(array $data): MessageBag
|
||||
{
|
||||
Log::debug('Storing Spectre API keys..');
|
||||
app('preferences')->setForUser($this->user, 'spectre_app_id', $data['app_id'] ?? null);
|
||||
app('preferences')->setForUser($this->user, 'spectre_secret', $data['secret'] ?? null);
|
||||
Log::debug('Done!');
|
||||
|
||||
return new MessageBag;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method creates a new public/private keypair for the user. This isn't really secure, since the key is generated on the fly with
|
||||
* no regards for HSM's, smart cards or other things. It would require some low level programming to get this right. But the private key
|
||||
* is stored encrypted in the database so it's something.
|
||||
*/
|
||||
private function createKeyPair(): void
|
||||
{
|
||||
Log::debug('Generate new Spectre key pair for user.');
|
||||
$keyConfig = [
|
||||
'digest_alg' => 'sha512',
|
||||
'private_key_bits' => 2048,
|
||||
'private_key_type' => OPENSSL_KEYTYPE_RSA,
|
||||
];
|
||||
// Create the private and public key
|
||||
$res = openssl_pkey_new($keyConfig);
|
||||
|
||||
// Extract the private key from $res to $privKey
|
||||
$privKey = '';
|
||||
openssl_pkey_export($res, $privKey);
|
||||
|
||||
// Extract the public key from $res to $pubKey
|
||||
$pubKey = openssl_pkey_get_details($res);
|
||||
|
||||
app('preferences')->setForUser($this->user, 'spectre_private_key', $privKey);
|
||||
app('preferences')->setForUser($this->user, 'spectre_public_key', $pubKey['key']);
|
||||
Log::debug('Created key pair');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a public key from the users preferences.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getPublicKey(): string
|
||||
{
|
||||
Log::debug('get public key');
|
||||
$preference = app('preferences')->getForUser($this->user, 'spectre_public_key', null);
|
||||
if (null === $preference) {
|
||||
Log::debug('public key is null');
|
||||
// create key pair
|
||||
$this->createKeyPair();
|
||||
}
|
||||
$preference = app('preferences')->getForUser($this->user, 'spectre_public_key', null);
|
||||
Log::debug('Return public key for user');
|
||||
|
||||
return $preference->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we have the App ID.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function hasAppId(): bool
|
||||
{
|
||||
$appId = app('preferences')->getForUser($this->user, 'spectre_app_id', null);
|
||||
if (null === $appId) {
|
||||
return false;
|
||||
}
|
||||
if ('' === (string) $appId->data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we have the secret.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function hasSecret(): bool
|
||||
{
|
||||
$secret = app('preferences')->getForUser($this->user, 'spectre_secret', null);
|
||||
if (null === $secret) {
|
||||
return false;
|
||||
}
|
||||
if ('' === (string) $secret->data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,159 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* YnabPrerequisites.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\Import\Prerequisites;
|
||||
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class YnabPrerequisites
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class YnabPrerequisites implements PrerequisitesInterface
|
||||
{
|
||||
/** @var User The current user */
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* YnabPrerequisites constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if ('testing' === config('app.env')) {
|
||||
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns view name that allows user to fill in prerequisites.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getView(): string
|
||||
{
|
||||
return 'import.ynab.prerequisites';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns any values required for the prerequisites-view.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getViewParameters(): array
|
||||
{
|
||||
Log::debug('Now in YnabPrerequisites::getViewParameters()');
|
||||
$clientId = '';
|
||||
$clientSecret = '';
|
||||
if ($this->hasClientId()) {
|
||||
$clientId = app('preferences')->getForUser($this->user, 'ynab_client_id', null)->data;
|
||||
}
|
||||
if ($this->hasClientSecret()) {
|
||||
$clientSecret = app('preferences')->getForUser($this->user, 'ynab_client_secret', null)->data;
|
||||
}
|
||||
|
||||
$callBackUri = route('import.callback.ynab');
|
||||
$isHttps = 0 === strpos($callBackUri, 'https://');
|
||||
|
||||
return ['client_id' => $clientId, 'client_secret' => $clientSecret, 'callback_uri' => $callBackUri, 'is_https' => $isHttps];
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate if all prerequisites have been met.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isComplete(): bool
|
||||
{
|
||||
return $this->hasClientId() && $this->hasClientSecret();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the user for this Prerequisites-routine. Class is expected to implement and save this.
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function setUser(User $user): void
|
||||
{
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method responds to the user's submission of an API key. Should do nothing but store the value.
|
||||
*
|
||||
* Errors must be returned in the message bag under the field name they are requested by.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function storePrerequisites(array $data): MessageBag
|
||||
{
|
||||
$clientId = $data['client_id'] ?? '';
|
||||
$clientSecret = $data['client_secret'] ?? '';
|
||||
Log::debug('Storing YNAB client data');
|
||||
app('preferences')->setForUser($this->user, 'ynab_client_id', $clientId);
|
||||
app('preferences')->setForUser($this->user, 'ynab_client_secret', $clientSecret);
|
||||
|
||||
return new MessageBag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we have the client ID.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function hasClientId(): bool
|
||||
{
|
||||
$clientId = app('preferences')->getForUser($this->user, 'ynab_client_id', null);
|
||||
if (null === $clientId) {
|
||||
return false;
|
||||
}
|
||||
if ('' === (string) $clientId->data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we have the client secret
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function hasClientSecret(): bool
|
||||
{
|
||||
$clientSecret = app('preferences')->getForUser($this->user, 'ynab_client_secret', null);
|
||||
if (null === $clientSecret) {
|
||||
return false;
|
||||
}
|
||||
if ('' === (string) $clientSecret->data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,118 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* BunqRoutine.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\Import\Routine;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Support\Import\Routine\Bunq\StageImportDataHandler;
|
||||
use FireflyIII\Support\Import\Routine\Bunq\StageNewHandler;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class BunqRoutine
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class BunqRoutine implements RoutineInterface
|
||||
{
|
||||
/** @var ImportJob The import job */
|
||||
private $importJob;
|
||||
|
||||
/** @var ImportJobRepositoryInterface Import job repository */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* At the end of each run(), the import routine must set the job to the expected status.
|
||||
*
|
||||
* The final status of the routine must be "provider_finished".
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
Log::info(sprintf('Now in BunqRoutine::run() with status "%s" and stage "%s".', $this->importJob->status, $this->importJob->stage));
|
||||
$valid = ['ready_to_run']; // should be only ready_to_run
|
||||
if (in_array($this->importJob->status, $valid, true)) {
|
||||
switch ($this->importJob->stage) {
|
||||
default:
|
||||
throw new FireflyException(sprintf('BunqRoutine cannot handle stage "%s".', $this->importJob->stage)); // @codeCoverageIgnore
|
||||
case 'new':
|
||||
// list all of the users accounts.
|
||||
$this->repository->setStatus($this->importJob, 'running');
|
||||
/** @var StageNewHandler $handler */
|
||||
$handler = app(StageNewHandler::class);
|
||||
$handler->setImportJob($this->importJob);
|
||||
$handler->run();
|
||||
// make user choose accounts to import from.
|
||||
$this->repository->setStage($this->importJob, 'choose-accounts');
|
||||
$this->repository->setStatus($this->importJob, 'need_job_config');
|
||||
|
||||
return;
|
||||
case 'go-for-import':
|
||||
// list all of the users accounts.
|
||||
$this->repository->setStatus($this->importJob, 'running');
|
||||
|
||||
/** @var StageImportDataHandler $handler */
|
||||
$handler = app(StageImportDataHandler::class);
|
||||
$handler->setImportJob($this->importJob);
|
||||
$handler->run();
|
||||
$transactions = $handler->getTransactions();
|
||||
// could be that more transactions will arrive in a second run.
|
||||
if (true === $handler->isStillRunning()) {
|
||||
Log::debug('Handler indicates that it is still working.');
|
||||
$this->repository->setStatus($this->importJob, 'ready_to_run');
|
||||
$this->repository->setStage($this->importJob, 'go-for-import');
|
||||
}
|
||||
$this->repository->appendTransactions($this->importJob, $transactions);
|
||||
if (false === $handler->isStillRunning()) {
|
||||
Log::info('Handler indicates that its done!');
|
||||
$this->repository->setStatus($this->importJob, 'provider_finished');
|
||||
$this->repository->setStage($this->importJob, 'final');
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new FireflyException(sprintf('bunq import routine cannot handle status "%s"', $this->importJob->status)); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the import job.
|
||||
*
|
||||
* @param ImportJob $importJob
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
}
|
||||
|
||||
}
|
@ -1,111 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* FakeRoutine.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\Import\Routine;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Support\Import\Routine\Fake\StageAhoyHandler;
|
||||
use FireflyIII\Support\Import\Routine\Fake\StageFinalHandler;
|
||||
use FireflyIII\Support\Import\Routine\Fake\StageNewHandler;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class FakeRoutine
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class FakeRoutine implements RoutineInterface
|
||||
{
|
||||
/** @var ImportJob The import job */
|
||||
private $importJob;
|
||||
/** @var ImportJobRepositoryInterface Import job repository */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* Fake import routine has three stages:
|
||||
*
|
||||
* "new": will quietly log gibberish for 15 seconds, then switch to stage "ahoy".
|
||||
* will also set status to "ready_to_run" so it will arrive here again.
|
||||
* "ahoy": will log some nonsense and then drop job into status:"need_job_config" to force it back to the job config routine.
|
||||
* "final": will do some logging, sleep for 10 seconds and then finish. Generates 5 random transactions.
|
||||
*
|
||||
* @throws FireflyException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
Log::debug(sprintf('Now in run() for fake routine with status: %s', $this->importJob->status));
|
||||
if ('ready_to_run' !== $this->importJob->status) {
|
||||
throw new FireflyException(sprintf('Fake job should have status "ready_to_run", not "%s"', $this->importJob->status)); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
switch ($this->importJob->stage) {
|
||||
default:
|
||||
throw new FireflyException(sprintf('Fake routine cannot handle stage "%s".', $this->importJob->stage)); // @codeCoverageIgnore
|
||||
case 'new':
|
||||
$this->repository->setStatus($this->importJob, 'running');
|
||||
/** @var StageNewHandler $handler */
|
||||
$handler = app(StageNewHandler::class);
|
||||
$handler->run();
|
||||
$this->repository->setStage($this->importJob, 'ahoy');
|
||||
// set job finished this step:
|
||||
$this->repository->setStatus($this->importJob, 'ready_to_run');
|
||||
|
||||
return;
|
||||
case 'ahoy':
|
||||
$this->repository->setStatus($this->importJob, 'running');
|
||||
/** @var StageAhoyHandler $handler */
|
||||
$handler = app(StageAhoyHandler::class);
|
||||
$handler->run();
|
||||
$this->repository->setStatus($this->importJob, 'need_job_config');
|
||||
$this->repository->setStage($this->importJob, 'final');
|
||||
break;
|
||||
case 'final':
|
||||
$this->repository->setStatus($this->importJob, 'running');
|
||||
/** @var StageFinalHandler $handler */
|
||||
$handler = app(StageFinalHandler::class);
|
||||
$handler->setImportJob($this->importJob);
|
||||
$transactions = $handler->getTransactions();
|
||||
$this->repository->setStatus($this->importJob, 'provider_finished');
|
||||
$this->repository->setStage($this->importJob, 'final');
|
||||
$this->repository->setTransactions($this->importJob, $transactions);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the import job.
|
||||
*
|
||||
* @param ImportJob $importJob
|
||||
*
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
}
|
||||
}
|
@ -1,99 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* FileRoutine.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\Import\Routine;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Support\Import\Routine\File\FileProcessorInterface;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class FileRoutine
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class FileRoutine implements RoutineInterface
|
||||
{
|
||||
/** @var ImportJob The import job */
|
||||
private $importJob;
|
||||
/** @var ImportJobRepositoryInterface Import job repository */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* At the end of each run(), the import routine must set the job to the expected status.
|
||||
*
|
||||
* The final status of the routine must be "provider_finished".
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
Log::debug(sprintf('Now in run() for file routine with status: %s', $this->importJob->status));
|
||||
if ('ready_to_run' === $this->importJob->status) {
|
||||
$this->repository->setStatus($this->importJob, 'running');
|
||||
// get processor, depending on file type
|
||||
// is just CSV for now.
|
||||
$processor = $this->getProcessor();
|
||||
$processor->setImportJob($this->importJob);
|
||||
$transactions = $processor->run();
|
||||
|
||||
$this->repository->setStatus($this->importJob, 'provider_finished');
|
||||
$this->repository->setStage($this->importJob, 'final');
|
||||
$this->repository->setTransactions($this->importJob, $transactions);
|
||||
|
||||
return;
|
||||
}
|
||||
throw new FireflyException(sprintf('Import routine cannot handle status "%s"', $this->importJob->status)); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the import job.
|
||||
*
|
||||
* @param ImportJob $importJob
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the appropriate file routine handler for
|
||||
* the file type of the job.
|
||||
*
|
||||
* @return FileProcessorInterface
|
||||
*/
|
||||
private function getProcessor(): FileProcessorInterface
|
||||
{
|
||||
$config = $this->repository->getConfiguration($this->importJob);
|
||||
$type = $config['file-type'] ?? 'csv';
|
||||
$class = config(sprintf('import.options.file.processors.%s', $type));
|
||||
|
||||
return app($class);
|
||||
}
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* FinTSRoutine.php
|
||||
* Copyright (c) 2019 https://github.com/bnw
|
||||
*
|
||||
* 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\Import\Routine;
|
||||
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Import\JobConfiguration\FinTSConfigurationSteps;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Support\Import\Routine\FinTS\StageImportDataHandler;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class FinTSRoutine
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class FinTSRoutine implements RoutineInterface
|
||||
{
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
/** @var ImportJobRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* At the end of each run(), the import routine must set the job to the expected status.
|
||||
*
|
||||
* The final status of the routine must be "provider_finished".
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
Log::debug(sprintf('Now in FinTSRoutine::run() with status "%s" and stage "%s".', $this->importJob->status, $this->importJob->stage));
|
||||
$valid = ['ready_to_run']; // should be only ready_to_run
|
||||
if (in_array($this->importJob->status, $valid, true)) {
|
||||
switch ($this->importJob->stage) {
|
||||
default:
|
||||
throw new FireflyException(sprintf('FinTSRoutine cannot handle stage "%s".', $this->importJob->stage)); // @codeCoverageIgnore
|
||||
case FinTSConfigurationSteps::GO_FOR_IMPORT:
|
||||
$this->repository->setStatus($this->importJob, 'running');
|
||||
/** @var StageImportDataHandler $handler */
|
||||
$handler = app(StageImportDataHandler::class);
|
||||
$handler->setImportJob($this->importJob);
|
||||
$handler->run();
|
||||
$transactions = $handler->getTransactions();
|
||||
|
||||
$this->repository->setTransactions($this->importJob, $transactions);
|
||||
$this->repository->setStatus($this->importJob, 'provider_finished');
|
||||
$this->repository->setStage($this->importJob, 'final');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ImportJob $importJob
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
}
|
||||
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* RoutineInterface.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\Import\Routine;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
|
||||
/**
|
||||
* Interface RoutineInterface
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
interface RoutineInterface
|
||||
{
|
||||
/**
|
||||
* At the end of each run(), the import routine must set the job to the expected status.
|
||||
*
|
||||
* The final status of the routine must be "provider_finished".
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function run(): void;
|
||||
|
||||
/**
|
||||
* Set the import job.
|
||||
*
|
||||
* @param ImportJob $importJob
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void;
|
||||
}
|
@ -1,128 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SpectreRoutine.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\Import\Routine;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Support\Import\Routine\Spectre\StageAuthenticatedHandler;
|
||||
use FireflyIII\Support\Import\Routine\Spectre\StageImportDataHandler;
|
||||
use FireflyIII\Support\Import\Routine\Spectre\StageNewHandler;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class SpectreRoutine
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class SpectreRoutine implements RoutineInterface
|
||||
{
|
||||
|
||||
/** @var ImportJob The import job */
|
||||
private $importJob;
|
||||
|
||||
/** @var ImportJobRepositoryInterface Import job repository */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* At the end of each run(), the import routine must set the job to the expected status.
|
||||
*
|
||||
* The final status of the routine must be "provider_finished".
|
||||
*
|
||||
* @throws FireflyException
|
||||
*
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
Log::debug(sprintf('Now in SpectreRoutine::run() with status "%s" and stage "%s".', $this->importJob->status, $this->importJob->stage));
|
||||
$valid = ['ready_to_run']; // should be only ready_to_run
|
||||
if (in_array($this->importJob->status, $valid, true)) {
|
||||
switch ($this->importJob->stage) {
|
||||
default:
|
||||
throw new FireflyException(sprintf('SpectreRoutine cannot handle stage "%s".', $this->importJob->stage)); // @codeCoverageIgnore
|
||||
case 'new':
|
||||
// list all of the users logins.
|
||||
$this->repository->setStatus($this->importJob, 'running');
|
||||
/** @var StageNewHandler $handler */
|
||||
$handler = app(StageNewHandler::class);
|
||||
$handler->setImportJob($this->importJob);
|
||||
$handler->run();
|
||||
|
||||
// if count logins is zero, go to authenticate stage
|
||||
if (0 === $handler->getCountLogins()) {
|
||||
$this->repository->setStage($this->importJob, 'do-authenticate');
|
||||
$this->repository->setStatus($this->importJob, 'ready_to_run');
|
||||
|
||||
return;
|
||||
}
|
||||
// or return to config to select login.
|
||||
$this->repository->setStage($this->importJob, 'choose-login');
|
||||
$this->repository->setStatus($this->importJob, 'need_job_config');
|
||||
break;
|
||||
case 'do-authenticate':
|
||||
// set job to require config.
|
||||
$this->repository->setStatus($this->importJob, 'need_job_config');
|
||||
|
||||
return;
|
||||
case 'authenticated':
|
||||
$this->repository->setStatus($this->importJob, 'running');
|
||||
// get accounts from login, store in job.
|
||||
/** @var StageAuthenticatedHandler $handler */
|
||||
$handler = app(StageAuthenticatedHandler::class);
|
||||
$handler->setImportJob($this->importJob);
|
||||
$handler->run();
|
||||
|
||||
// return to config to select account(s).
|
||||
$this->repository->setStage($this->importJob, 'choose-accounts');
|
||||
$this->repository->setStatus($this->importJob, 'need_job_config');
|
||||
break;
|
||||
case 'go-for-import':
|
||||
// user has chosen account mapping. Should now be ready to import data.
|
||||
$this->repository->setStatus($this->importJob, 'running');
|
||||
$this->repository->setStage($this->importJob, 'do_import');
|
||||
/** @var StageImportDataHandler $handler */
|
||||
$handler = app(StageImportDataHandler::class);
|
||||
$handler->setImportJob($this->importJob);
|
||||
$handler->run();
|
||||
$this->repository->setStatus($this->importJob, 'provider_finished');
|
||||
$this->repository->setStage($this->importJob, 'final');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the import job.
|
||||
*
|
||||
* @param ImportJob $importJob
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
}
|
||||
|
||||
}
|
@ -1,146 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* YnabRoutine.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\Import\Routine;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Support\Import\Routine\Ynab\GetAccountsHandler;
|
||||
use FireflyIII\Support\Import\Routine\Ynab\ImportDataHandler;
|
||||
use FireflyIII\Support\Import\Routine\Ynab\StageGetAccessHandler;
|
||||
use FireflyIII\Support\Import\Routine\Ynab\StageGetBudgetsHandler;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class YnabRoutine
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class YnabRoutine implements RoutineInterface
|
||||
{
|
||||
/** @var ImportJob The import job */
|
||||
private $importJob;
|
||||
|
||||
/** @var ImportJobRepositoryInterface Import job repository */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* At the end of each run(), the import routine must set the job to the expected status.
|
||||
*
|
||||
* The final status of the routine must be "provider_finished".
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
Log::debug(sprintf('Now in YNAB routine::run() with status "%s" and stage "%s".', $this->importJob->status, $this->importJob->stage));
|
||||
$valid = ['ready_to_run']; // should be only ready_to_run
|
||||
if (in_array($this->importJob->status, $valid, true)) {
|
||||
|
||||
// get access token from YNAB
|
||||
if ('get_access_token' === $this->importJob->stage) {
|
||||
// list all of the users accounts.
|
||||
$this->repository->setStatus($this->importJob, 'running');
|
||||
/** @var StageGetAccessHandler $handler */
|
||||
$handler = app(StageGetAccessHandler::class);
|
||||
$handler->setImportJob($this->importJob);
|
||||
$handler->run();
|
||||
|
||||
// back to correct stage:
|
||||
$this->repository->setStatus($this->importJob, 'ready_to_run');
|
||||
$this->repository->setStage($this->importJob, 'get_budgets');
|
||||
|
||||
return;
|
||||
}
|
||||
if ('get_budgets' === $this->importJob->stage) {
|
||||
$this->repository->setStatus($this->importJob, 'running');
|
||||
/** @var StageGetBudgetsHandler $handler */
|
||||
$handler = app(StageGetBudgetsHandler::class);
|
||||
$handler->setImportJob($this->importJob);
|
||||
$handler->run();
|
||||
|
||||
// count budgets in job, to determine next step.
|
||||
$configuration = $this->repository->getConfiguration($this->importJob);
|
||||
$budgets = $configuration['budgets'] ?? [];
|
||||
|
||||
// if more than 1 budget, select budget first.
|
||||
if (count($budgets) > 1) {
|
||||
$this->repository->setStage($this->importJob, 'select_budgets');
|
||||
$this->repository->setStatus($this->importJob, 'need_job_config');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (1 === count($budgets)) {
|
||||
$this->repository->setStatus($this->importJob, 'ready_to_run');
|
||||
$this->repository->setStage($this->importJob, 'get_accounts');
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
if ('get_accounts' === $this->importJob->stage) {
|
||||
$this->repository->setStatus($this->importJob, 'running');
|
||||
|
||||
/** @var GetAccountsHandler $handler */
|
||||
$handler = app(GetAccountsHandler::class);
|
||||
$handler->setImportJob($this->importJob);
|
||||
$handler->run();
|
||||
|
||||
$this->repository->setStage($this->importJob, 'select_accounts');
|
||||
$this->repository->setStatus($this->importJob, 'need_job_config');
|
||||
|
||||
return;
|
||||
}
|
||||
if ('go-for-import' === $this->importJob->stage) {
|
||||
$this->repository->setStatus($this->importJob, 'running');
|
||||
$this->repository->setStage($this->importJob, 'do_import');
|
||||
/** @var ImportDataHandler $handler */
|
||||
$handler = app(ImportDataHandler::class);
|
||||
$handler->setImportJob($this->importJob);
|
||||
$handler->run();
|
||||
$this->repository->setStatus($this->importJob, 'provider_finished');
|
||||
$this->repository->setStage($this->importJob, 'final');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
throw new FireflyException(sprintf('YNAB import routine cannot handle stage "%s"', $this->importJob->stage));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the import job.
|
||||
*
|
||||
* @param ImportJob $importJob
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
}
|
||||
}
|
@ -1,243 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* AbnAmroDescription.php
|
||||
* Copyright (c) 2019 Robert Horlings
|
||||
*
|
||||
* 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\Import\Specifics;
|
||||
|
||||
/**
|
||||
* Class AbnAmroDescription.
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* Parses the description from txt files for ABN AMRO bank accounts.
|
||||
*
|
||||
* Based on the logic as described in the following Gist:
|
||||
* https://gist.github.com/vDorst/68d555a6a90f62fec004
|
||||
*/
|
||||
class AbnAmroDescription implements SpecificInterface
|
||||
{
|
||||
/** @var array The current row. */
|
||||
public $row;
|
||||
|
||||
/**
|
||||
* Description of this specific fix.
|
||||
*
|
||||
* @return string
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function getDescription(): string
|
||||
{
|
||||
return 'import.specific_abn_descr';
|
||||
}
|
||||
|
||||
/**
|
||||
* Name of specific fix.
|
||||
*
|
||||
* @return string
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'import.specific_abn_name';
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the fix.
|
||||
*
|
||||
* @param array $row
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
*/
|
||||
public function run(array $row): array
|
||||
{
|
||||
$this->row = array_values($row);
|
||||
|
||||
if (!isset($row[7])) {
|
||||
return $row;
|
||||
}
|
||||
|
||||
// Try to parse the description in known formats.
|
||||
$parsed = $this->parseSepaDescription() || $this->parseTRTPDescription() || $this->parseGEABEADescription() || $this->parseABNAMRODescription();
|
||||
|
||||
// If the description could not be parsed, specify an unknown opposing
|
||||
// account, as an opposing account is required
|
||||
if (!$parsed) {
|
||||
$this->row[8] = (string) trans('firefly.unknown'); // opposing-account-name
|
||||
}
|
||||
|
||||
return $this->row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the current description with costs from ABN AMRO itself.
|
||||
*
|
||||
* @return bool true if the description is GEA/BEA-format, false otherwise
|
||||
*/
|
||||
protected function parseABNAMRODescription(): bool
|
||||
{
|
||||
// See if the current description is formatted in ABN AMRO format
|
||||
if (preg_match('/ABN AMRO.{24} (.*)/', $this->row[7], $matches)) {
|
||||
$this->row[8] = 'ABN AMRO'; // this one is new (opposing account name)
|
||||
$this->row[7] = $matches[1]; // this is the description
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the current description in GEA/BEA format.
|
||||
*
|
||||
* @return bool true if the description is GEA/BEAformat, false otherwise
|
||||
*/
|
||||
protected function parseGEABEADescription(): bool
|
||||
{
|
||||
// See if the current description is formatted in GEA/BEA format
|
||||
if (preg_match('/([BG]EA) +(NR:[a-zA-Z:0-9]+) +([0-9.\/]+) +([^,]*)/', $this->row[7], $matches)) {
|
||||
// description and opposing account will be the same.
|
||||
$this->row[8] = $matches[4]; // 'opposing-account-name'
|
||||
$this->row[7] = $matches[4]; // 'description'
|
||||
|
||||
if ('GEA' === $matches[1]) {
|
||||
$this->row[7] = 'GEA ' . $matches[4]; // 'description'
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the current description in SEPA format.
|
||||
*
|
||||
* @return bool true if the description is SEPA format, false otherwise
|
||||
*
|
||||
*/
|
||||
protected function parseSepaDescription(): bool
|
||||
{
|
||||
// See if the current description is formatted as a SEPA plain description
|
||||
if (preg_match('/^SEPA(.{28})/', $this->row[7], $matches)) {
|
||||
$type = $matches[1];
|
||||
$reference = '';
|
||||
$name = '';
|
||||
$newDescription = '';
|
||||
|
||||
// SEPA plain descriptions contain several key-value pairs, split by a colon
|
||||
preg_match_all('/([A-Za-z]+(?=:\s)):\s([A-Za-z 0-9._#-]+(?=\s|$))/', $this->row[7], $matches, PREG_SET_ORDER);
|
||||
|
||||
if (is_array($matches)) {
|
||||
foreach ($matches as $match) {
|
||||
$key = $match[1];
|
||||
$value = trim($match[2]);
|
||||
switch (strtoupper($key)) {
|
||||
case 'OMSCHRIJVING':
|
||||
$newDescription = $value;
|
||||
break;
|
||||
case 'NAAM':
|
||||
$this->row[8] = $value;
|
||||
$name = $value;
|
||||
break;
|
||||
case 'KENMERK':
|
||||
$reference = $value;
|
||||
break;
|
||||
case 'IBAN':
|
||||
$this->row[9] = $value;
|
||||
break;
|
||||
default: // @codeCoverageIgnore
|
||||
// Ignore the rest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set a new description for the current transaction. If none was given
|
||||
// set the description to type, name and reference
|
||||
$this->row[7] = $newDescription;
|
||||
if ('' === $newDescription) {
|
||||
$this->row[7] = sprintf('%s - %s (%s)', $type, $name, $reference);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the current description in TRTP format.
|
||||
*
|
||||
* @return bool true if the description is TRTP format, false otherwise
|
||||
*
|
||||
*/
|
||||
protected function parseTRTPDescription(): bool
|
||||
{
|
||||
// See if the current description is formatted in TRTP format
|
||||
if (preg_match_all('!\/([A-Z]{3,4})\/([^/]*)!', $this->row[7], $matches, PREG_SET_ORDER)) {
|
||||
$type = '';
|
||||
$name = '';
|
||||
$reference = '';
|
||||
$newDescription = '';
|
||||
|
||||
// Search for properties specified in the TRTP format. If no description
|
||||
// is provided, use the type, name and reference as new description
|
||||
if (is_array($matches)) {
|
||||
foreach ($matches as $match) {
|
||||
$key = $match[1];
|
||||
$value = trim($match[2]);
|
||||
|
||||
switch (strtoupper($key)) {
|
||||
case 'NAME':
|
||||
$this->row[8] = $value;
|
||||
break;
|
||||
case 'REMI':
|
||||
$newDescription = $value;
|
||||
break;
|
||||
case 'IBAN':
|
||||
$this->row[9] = $value;
|
||||
break;
|
||||
case 'EREF':
|
||||
$reference = $value;
|
||||
break;
|
||||
case 'TRTP':
|
||||
$type = $value;
|
||||
break;
|
||||
default: // @codeCoverageIgnore
|
||||
// Ignore the rest
|
||||
}
|
||||
}
|
||||
|
||||
// Set a new description for the current transaction. If none was given
|
||||
// set the description to type, name and reference
|
||||
$this->row[7] = $newDescription;
|
||||
if ('' === $newDescription) {
|
||||
$this->row[7] = sprintf('%s - %s (%s)', $type, $name, $reference);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Belfius.php
|
||||
* Copyright (c) 2019 Sander Kleykens <sander@kleykens.com>
|
||||
*
|
||||
* 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\Import\Specifics;
|
||||
|
||||
/**
|
||||
* Class Belfius.
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* Fixes Belfius CSV files to:
|
||||
* - Correct descriptions for recurring transactions so doubles can be detected when the equivalent incoming
|
||||
* transaction is imported.
|
||||
*
|
||||
*/
|
||||
class Belfius implements SpecificInterface
|
||||
{
|
||||
/**
|
||||
* Description of this specific fix.
|
||||
*
|
||||
* @return string
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function getDescription(): string
|
||||
{
|
||||
return 'import.specific_belfius_descr';
|
||||
}
|
||||
|
||||
/**
|
||||
* Name of specific fix.
|
||||
*
|
||||
* @return string
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'import.specific_belfius_name';
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixes the description for outgoing recurring transactions so doubles can be detected when the equivalent incoming
|
||||
* transaction is imported for another bank account.
|
||||
*
|
||||
* @return array the row containing the new description
|
||||
*/
|
||||
protected static function processRecurringTransactionDescription(array $row): array
|
||||
{
|
||||
if (!isset($row[5]) || !isset($row[14])) {
|
||||
return $row;
|
||||
}
|
||||
|
||||
$opposingAccountName = $row[5];
|
||||
$description = $row[14];
|
||||
|
||||
preg_match('/DOORLOPENDE OPDRACHT.*\s+' . preg_quote($opposingAccountName, '/') . '\s+(.+)\s+REF.\s*:/', $description, $matches);
|
||||
|
||||
if (isset($matches[1])) {
|
||||
$row[14] = $matches[1];
|
||||
}
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the fix.
|
||||
*
|
||||
* @param array $row
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
*/
|
||||
public function run(array $row): array
|
||||
{
|
||||
return Belfius::processRecurringTransactionDescription($row);
|
||||
}
|
||||
}
|
@ -1,144 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* IngBelgium.php
|
||||
* Copyright (c) 2019 Sander Kleykens <sander@kleykens.com>
|
||||
*
|
||||
* 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\Import\Specifics;
|
||||
|
||||
/**
|
||||
* Class IngBelgium.
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* Parses the description and opposing account information (IBAN and name) from CSV files for ING Belgium bank accounts.
|
||||
*
|
||||
*/
|
||||
class IngBelgium implements SpecificInterface
|
||||
{
|
||||
/**
|
||||
* Description of the current specific.
|
||||
*
|
||||
* @return string
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function getDescription(): string
|
||||
{
|
||||
return 'import.specific_ingbelgium_descr';
|
||||
}
|
||||
|
||||
/**
|
||||
* Name of the current specific.
|
||||
*
|
||||
* @return string
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'import.specific_ingbelgium_name';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the description from the transaction details and makes sure structured descriptions are in the
|
||||
* "+++090/9337/55493+++" format.
|
||||
*
|
||||
* @return string the description
|
||||
*/
|
||||
protected static function description(string $transactionDetails): string
|
||||
{
|
||||
$description = IngBelgium::parseInformationFromTransactionDetails($transactionDetails, '/Mededeling:\s*(.+)$/');
|
||||
|
||||
return IngBelgium::convertStructuredDescriptionToProperFormat($description);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the opposing account's IBAN from the transaction details.
|
||||
*
|
||||
* @return string the opposing account's IBAN
|
||||
*/
|
||||
protected static function opposingAccountIban(string $transactionDetails): string
|
||||
{
|
||||
return IngBelgium::parseInformationFromTransactionDetails($transactionDetails, '/IBAN:\s*(.+?)(?=\s+)/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the opposing account name from the transaction details.
|
||||
*
|
||||
* @return string the opposing account name
|
||||
*/
|
||||
protected static function opposingAccountName(string $transactionDetails): string
|
||||
{
|
||||
return IngBelgium::parseInformationFromTransactionDetails($transactionDetails, '/Van:\s*(.+?)(?=\s{2,})/');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the description and opposing account information (IBAN and name) from the transaction details and adds
|
||||
* them to the row of data.
|
||||
*
|
||||
* @return array the row containing the description and opposing account's IBAN
|
||||
*/
|
||||
protected static function processTransactionDetails(array $row): array
|
||||
{
|
||||
if (isset($row[9])) {
|
||||
$transactionDetails = $row[9];
|
||||
$row[11] = IngBelgium::opposingAccountName($transactionDetails);
|
||||
$row[12] = IngBelgium::opposingAccountIban($transactionDetails);
|
||||
$row[13] = IngBelgium::description($transactionDetails);
|
||||
}
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
private static function convertStructuredDescriptionToProperFormat(string $description): string
|
||||
{
|
||||
preg_match('/^\*\*\*(\d{3}\/\d{4}\/\d{5})\*\*\*$/', $description, $matches);
|
||||
if (isset($matches[1])) {
|
||||
return '+++' . $matches[1] . '+++';
|
||||
}
|
||||
|
||||
return $description;
|
||||
}
|
||||
|
||||
private static function parseInformationFromTransactionDetails(string $transactionDetails, string $regex): string
|
||||
{
|
||||
if (isset($transactionDetails)) {
|
||||
preg_match($regex, $transactionDetails, $matches);
|
||||
if (isset($matches[1])) {
|
||||
return trim($matches[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the specific code.
|
||||
*
|
||||
* @param array $row
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
*/
|
||||
public function run(array $row): array
|
||||
{
|
||||
return IngBelgium::processTransactionDetails($row);
|
||||
}
|
||||
}
|
@ -1,173 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* IngDescription.php
|
||||
* Copyright (c) 2019 https://github.com/tomwerf
|
||||
*
|
||||
* 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\Import\Specifics;
|
||||
|
||||
/**
|
||||
* Class IngDescription.
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* Parses the description from CSV files for Ing bank accounts.
|
||||
*
|
||||
* With Mutation 'InternetBankieren', 'Overschrijving', 'Verzamelbetaling' and
|
||||
* 'Incasso' the Name of Opposing account the Opposing IBAN number are in the
|
||||
* Description. This class will remove them, and add Name in description by
|
||||
* 'Betaalautomaat' so those are easily recognizable
|
||||
*/
|
||||
class IngDescription implements SpecificInterface
|
||||
{
|
||||
/** @var array The current row. */
|
||||
public $row;
|
||||
|
||||
/**
|
||||
* Description of the current specific.
|
||||
*
|
||||
* @return string
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function getDescription(): string
|
||||
{
|
||||
return 'import.specific_ing_descr';
|
||||
}
|
||||
|
||||
/**
|
||||
* Name of the current specific.
|
||||
*
|
||||
* @return string
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'import.specific_ing_name';
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the specific code.
|
||||
*
|
||||
* @param array $row
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
*/
|
||||
public function run(array $row): array
|
||||
{
|
||||
$this->row = array_values($row);
|
||||
array_push($this->row); // New column for "Valutadatum"
|
||||
if (count($this->row) >= 8) { // check if the array is correct
|
||||
switch ($this->row[4]) { // Get value for the mutation type
|
||||
case 'GT': // InternetBankieren
|
||||
case 'OV': // Overschrijving
|
||||
case 'VZ': // Verzamelbetaling
|
||||
case 'IC': // Incasso
|
||||
case 'DV': // Divers
|
||||
$this->removeIBANIngDescription(); // Remove "IBAN:", because it is already at "Tegenrekening"
|
||||
$this->removeNameIngDescription(); // Remove "Naam:", because it is already at "Naam/ Omschrijving"
|
||||
$this->removeIngDescription(); // Remove "Omschrijving", but not the value from description
|
||||
$this->moveValutadatumDescription(); // Move "Valutadatum" from description to new column
|
||||
$this->MoveSavingsAccount(); // Move savings account number and name
|
||||
break;
|
||||
case 'BA': // Betaalautomaat
|
||||
$this->moveValutadatumDescription(); // Move "Valutadatum" from description to new column
|
||||
$this->addNameIngDescription();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the Opposing name from cell 1 in the description for Betaalautomaten
|
||||
* Otherwise the description is only: 'Pasvolgnr:<nr> <date> Transactie:<NR> Term:<nr>'.
|
||||
*/
|
||||
protected function addNameIngDescription(): void
|
||||
{
|
||||
$this->row[8] = $this->row[1] . ' ' . $this->row[8];
|
||||
}
|
||||
|
||||
/**
|
||||
* Move "Valutadatum" from the description to new column.
|
||||
*/
|
||||
protected function moveValutadatumDescription(): void
|
||||
{
|
||||
$matches = [];
|
||||
if (preg_match('/Valutadatum: ([0-9-]+)/', $this->row[8], $matches)) {
|
||||
$this->row[9] = date("Ymd", strtotime($matches[1]));
|
||||
$this->row[8] = preg_replace('/Valutadatum: [0-9-]+/', '', $this->row[8]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove IBAN number out of the description
|
||||
* Default description of Description is: Naam: <OPPOS NAME> Omschrijving: <DESCRIPTION> IBAN: <OPPOS IBAN NR>.
|
||||
*/
|
||||
protected function removeIBANIngDescription(): void
|
||||
{
|
||||
// Try replace the iban number with nothing. The IBAN nr is found in the third column
|
||||
$this->row[8] = preg_replace('/\sIBAN:\s' . $this->row[3] . '/', '', $this->row[8]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove "Omschrijving" (and NOT its value) from the description.
|
||||
*/
|
||||
protected function removeIngDescription(): void
|
||||
{
|
||||
$this->row[8] = preg_replace('/Omschrijving: /', '', $this->row[8]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove "Naam" (and its value) from the description.
|
||||
*/
|
||||
protected function removeNameIngDescription(): void
|
||||
{
|
||||
$this->row[8] = preg_replace('/Naam:.*?([a-zA-Z\/]+:)/', '$1', $this->row[8]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move savings account number to column 1 and name to column 3.
|
||||
*/
|
||||
private function MoveSavingsAccount(): void
|
||||
{
|
||||
$matches = [];
|
||||
|
||||
if (preg_match('/(Naar|Van) (.*rekening) ([A-Za-z0-9]+)/', $this->row[8], $matches)) { // Search for saving acount at 'Mededelingen' column
|
||||
$this->row[1] = $this->row[1] . ' ' . $matches[2] . ' ' . $matches[3]; // Current name + Saving acount name + Acount number
|
||||
if ('' === (string) $this->row[3]) { // if Saving account number does not yet exists
|
||||
$this->row[3] = $matches[3]; // Copy savings account number
|
||||
}
|
||||
$this->row[8] = preg_replace('/(Naar|Van) (.*rekening) ([A-Za-z0-9]+)/', '', $this->row[8]); // Remove the savings account content from description
|
||||
} elseif (preg_match('/(Naar|Van) (.*rekening) ([A-Za-z0-9]+)/', $this->row[1], $matches)) { // Search for saving acount at 'Naam / Omschrijving' column
|
||||
$this->row[1] = $matches[2] . ' ' . $matches[3]; // Saving acount name + Acount number
|
||||
if ('' === (string) $this->row[3]) { // if Saving account number does not yet exists
|
||||
$this->row[3] = $matches[3]; // Copy savings account number
|
||||
}
|
||||
}
|
||||
|
||||
if ('' !== (string)$this->row[3]) { // if Saving account number exists
|
||||
if (! preg_match('/[A-Za-z]/', $this->row[3])) { // if Saving account number has no characters
|
||||
$this->row[3] = sprintf("%010d", $this->row[3]); // Make the number 10 digits
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* PresidentsChoice.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\Import\Specifics;
|
||||
|
||||
/**
|
||||
* Class PresidentsChoice.
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class PresidentsChoice implements SpecificInterface
|
||||
{
|
||||
/**
|
||||
* Description of specific.
|
||||
*
|
||||
* @return string
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function getDescription(): string
|
||||
{
|
||||
return 'import.specific_pres_descr';
|
||||
}
|
||||
|
||||
/**
|
||||
* Name of specific.
|
||||
*
|
||||
* @return string
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'import.specific_pres_name';
|
||||
}
|
||||
|
||||
/**
|
||||
* Run this specific.
|
||||
*
|
||||
* @param array $row
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function run(array $row): array
|
||||
{
|
||||
$row = array_values($row);
|
||||
// first, if column 2 is empty and 3 is not, do nothing.
|
||||
// if column 3 is empty and column 2 is not, move amount to column 3, *-1
|
||||
if (isset($row[3]) && '' === $row[3]) {
|
||||
$row[3] = bcmul($row[2], '-1');
|
||||
}
|
||||
if (isset($row[1])) {
|
||||
// copy description into column 2, which is now usable.
|
||||
$row[2] = $row[1];
|
||||
}
|
||||
|
||||
return $row;
|
||||
}
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SnsDescription.php
|
||||
* Copyright (c) 2019 hugovanduijn@gmail.com.
|
||||
*
|
||||
* 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\Import\Specifics;
|
||||
|
||||
/**
|
||||
* Class SnsDescription.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @deprecated
|
||||
*/
|
||||
class SnsDescription implements SpecificInterface
|
||||
{
|
||||
/**
|
||||
* Get description of specific.
|
||||
*
|
||||
* @return string
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function getDescription(): string
|
||||
{
|
||||
return 'import.specific_sns_descr';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name of specific.
|
||||
*
|
||||
* @return string
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'import.specific_sns_name';
|
||||
}
|
||||
|
||||
/**
|
||||
* Run specific.
|
||||
*
|
||||
* @param array $row
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function run(array $row): array
|
||||
{
|
||||
$row = array_values($row);
|
||||
if (!isset($row[17])) {
|
||||
return $row;
|
||||
}
|
||||
$row[17] = ltrim($row[17], "'");
|
||||
$row[17] = rtrim($row[17], "'");
|
||||
|
||||
return $row;
|
||||
}
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SpecificInterface.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\Import\Specifics;
|
||||
|
||||
/**
|
||||
* Interface SpecificInterface.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @deprecated
|
||||
*/
|
||||
interface SpecificInterface
|
||||
{
|
||||
/**
|
||||
* Get description.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getDescription(): string;
|
||||
|
||||
/**
|
||||
* Get name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getName(): string;
|
||||
|
||||
/**
|
||||
* Run specific.
|
||||
*
|
||||
* @param array $row
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function run(array $row): array;
|
||||
}
|
@ -1,630 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* ImportArrayStorage.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\Import\Storage;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use DB;
|
||||
use Exception;
|
||||
use FireflyIII\Events\RequestedReportOnJournals;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Models\Preference;
|
||||
use FireflyIII\Models\TransactionGroup;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||
use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface;
|
||||
use FireflyIII\TransactionRules\Engine\RuleEngine;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Creates new transactions based on arrays.
|
||||
*
|
||||
* Class ImportArrayStorage
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @deprecated
|
||||
*
|
||||
*/
|
||||
class ImportArrayStorage
|
||||
{
|
||||
/** @var int Number of hits required for a transfer to match. */
|
||||
private const REQUIRED_HITS = 4;
|
||||
/** @var bool Check for transfers during import. */
|
||||
private $checkForTransfers = false;
|
||||
/** @var TransactionGroupRepositoryInterface */
|
||||
private $groupRepos;
|
||||
/** @var ImportJob The import job */
|
||||
private $importJob;
|
||||
/** @var JournalRepositoryInterface Journal repository for storage. */
|
||||
private $journalRepos;
|
||||
/** @var string */
|
||||
private $language = 'en_US';
|
||||
/** @var ImportJobRepositoryInterface Import job repository */
|
||||
private $repository;
|
||||
/** @var array The transfers the user already has. */
|
||||
private $transfers;
|
||||
|
||||
/**
|
||||
* Set job, count transfers in the array and create the repository.
|
||||
*
|
||||
* @param ImportJob $importJob
|
||||
*/
|
||||
public function setImportJob(ImportJob $importJob): void
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->repository->setUser($importJob->user);
|
||||
|
||||
$this->countTransfers();
|
||||
|
||||
$this->journalRepos = app(JournalRepositoryInterface::class);
|
||||
$this->journalRepos->setUser($importJob->user);
|
||||
|
||||
$this->groupRepos = app(TransactionGroupRepositoryInterface::class);
|
||||
$this->groupRepos->setUser($importJob->user);
|
||||
|
||||
// get language of user.
|
||||
/** @var Preference $pref */
|
||||
$pref = app('preferences')->getForUser($importJob->user, 'language', config('firefly.default_language', 'en_US'));
|
||||
$this->language = $pref->data;
|
||||
|
||||
Log::debug('Constructed ImportArrayStorage()');
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually does the storing. Does three things.
|
||||
* - Store journals
|
||||
* - Link to tag
|
||||
* - Run rules (if set to)
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @return Collection
|
||||
*/
|
||||
public function store(): Collection
|
||||
{
|
||||
// store transactions
|
||||
$this->setStatus('storing_data');
|
||||
$collection = $this->storeGroupArray();
|
||||
$this->setStatus('stored_data');
|
||||
|
||||
// link tag:
|
||||
$this->setStatus('linking_to_tag');
|
||||
$this->linkToTag($collection);
|
||||
$this->setStatus('linked_to_tag');
|
||||
|
||||
// run rules, if configured to.
|
||||
$config = $this->importJob->configuration;
|
||||
if (isset($config['apply-rules']) && true === $config['apply-rules']) {
|
||||
$this->setStatus('applying_rules');
|
||||
$this->applyRules($collection);
|
||||
$this->setStatus('rules_applied');
|
||||
}
|
||||
|
||||
app('preferences')->mark();
|
||||
|
||||
// email about this:
|
||||
event(new RequestedReportOnJournals((int) $this->importJob->user_id, $collection));
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the users rules to the created journals.
|
||||
*
|
||||
* @param Collection $collection
|
||||
*
|
||||
*/
|
||||
private function applyRules(Collection $collection): void
|
||||
{
|
||||
Log::debug('Now in applyRules()');
|
||||
|
||||
/** @var RuleEngine $ruleEngine */
|
||||
$ruleEngine = app(RuleEngine::class);
|
||||
$ruleEngine->setUser($this->importJob->user);
|
||||
$ruleEngine->setAllRules(true);
|
||||
|
||||
// for this call, the rule engine only includes "store" rules:
|
||||
$ruleEngine->setTriggerMode(RuleEngine::TRIGGER_STORE);
|
||||
Log::debug('Start of engine loop');
|
||||
foreach ($collection as $group) {
|
||||
$this->applyRulesGroup($ruleEngine, $group);
|
||||
}
|
||||
Log::debug('End of engine loop.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RuleEngine $ruleEngine
|
||||
* @param TransactionGroup $group
|
||||
*/
|
||||
private function applyRulesGroup(RuleEngine $ruleEngine, TransactionGroup $group): void
|
||||
{
|
||||
Log::debug(sprintf('Processing group #%d', $group->id));
|
||||
foreach ($group->transactionJournals as $journal) {
|
||||
Log::debug(sprintf('Processing journal #%d from group #%d', $journal->id, $group->id));
|
||||
$ruleEngine->processTransactionJournal($journal);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Count the number of transfers in the array. If this is zero, don't bother checking for double transfers.
|
||||
*/
|
||||
private function countTransfers(): void
|
||||
{
|
||||
Log::debug('Now in countTransfers()');
|
||||
/** @var array $array */
|
||||
$array = $this->repository->getTransactions($this->importJob);
|
||||
|
||||
|
||||
$count = 0;
|
||||
foreach ($array as $index => $group) {
|
||||
|
||||
foreach ($group['transactions'] as $transaction) {
|
||||
if (strtolower(TransactionType::TRANSFER) === strtolower($transaction['type'])) {
|
||||
$count++;
|
||||
Log::debug(sprintf('Row #%d is a transfer, increase count to %d', $index + 1, $count));
|
||||
}
|
||||
}
|
||||
}
|
||||
Log::debug(sprintf('Count of transfers in import array is %d.', $count));
|
||||
if ($count > 0) {
|
||||
$this->checkForTransfers = true;
|
||||
Log::debug('Will check for duplicate transfers.');
|
||||
// get users transfers. Needed for comparison.
|
||||
$this->getTransfers();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $index
|
||||
* @param array $group
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function duplicateDetected(int $index, array $group): bool
|
||||
{
|
||||
Log::debug(sprintf('Now in duplicateDetected(%d)', $index));
|
||||
$transactions = $group['transactions'] ?? [];
|
||||
foreach ($transactions as $transaction) {
|
||||
$hash = $this->getHash($transaction);
|
||||
$existingId = $this->hashExists($hash);
|
||||
if (null !== $existingId) {
|
||||
$message = (string) trans('import.duplicate_row', ['row' => $index, 'description' => $transaction['description']]);
|
||||
$this->logDuplicateObject($transaction, $existingId);
|
||||
$this->repository->addErrorMessage($this->importJob, $message);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// do transfer detection:
|
||||
if ($this->checkForTransfers && $this->transferExists($transaction)) {
|
||||
$message = (string) trans('import.duplicate_row', ['row' => $index, 'description' => $transaction['description']]);
|
||||
$this->logDuplicateTransfer($transaction);
|
||||
$this->repository->addErrorMessage($this->importJob, $message);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get hash of transaction.
|
||||
*
|
||||
* @param array $transaction
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getHash(array $transaction): string
|
||||
{
|
||||
unset($transaction['import_hash_v2'], $transaction['original_source']);
|
||||
$json = json_encode($transaction, JSON_THROW_ON_ERROR);
|
||||
if (false === $json) {
|
||||
// @codeCoverageIgnoreStart
|
||||
/** @noinspection ForgottenDebugOutputInspection */
|
||||
Log::error('Could not encode import array.', $transaction);
|
||||
try {
|
||||
$json = random_int(1, 10000);
|
||||
} catch (Exception $e) {
|
||||
// seriously?
|
||||
Log::error(sprintf('random_int() just failed. I want a medal: %s', $e->getMessage()));
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
$hash = hash('sha256', $json);
|
||||
Log::debug(sprintf('The hash is: %s', $hash), $transaction);
|
||||
|
||||
return $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionGroup $transactionGroup
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getTransactionFromJournal(TransactionGroup $transactionGroup): array
|
||||
{
|
||||
// collect transactions using the journal collector
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
|
||||
$collector->setUser($this->importJob->user);
|
||||
$collector->setGroup($transactionGroup);
|
||||
|
||||
return $collector->getExtractedJournals();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the users transfers, so they can be compared to whatever the user is trying to import.
|
||||
*/
|
||||
private function getTransfers(): void
|
||||
{
|
||||
Log::debug('Now in getTransfers()');
|
||||
app('preferences')->mark();
|
||||
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
|
||||
$collector->setUser($this->importJob->user);
|
||||
$collector
|
||||
->setTypes([TransactionType::TRANSFER])->setLimit(10000)->setPage(1)
|
||||
->withAccountInformation();
|
||||
$this->transfers = $collector->getExtractedJournals();
|
||||
Log::debug(sprintf('Count of getTransfers() is %d', count($this->transfers)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the hash exists for the array the user wants to import.
|
||||
*
|
||||
* @param string $hash
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
private function hashExists(string $hash): ?int
|
||||
{
|
||||
$entry = $this->journalRepos->findByHash($hash);
|
||||
if (null === $entry) {
|
||||
Log::debug(sprintf('Found no transactions with hash %s.', $hash));
|
||||
|
||||
return null;
|
||||
}
|
||||
Log::info(sprintf('Found a transaction journal with an existing hash: %s', $hash));
|
||||
|
||||
return (int) $entry->transaction_journal_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Link all imported journals to a tag.
|
||||
*
|
||||
* @param Collection $collection
|
||||
*/
|
||||
private function linkToTag(Collection $collection): void
|
||||
{
|
||||
if (0 === $collection->count()) {
|
||||
return;
|
||||
}
|
||||
/** @var TagRepositoryInterface $repository */
|
||||
$repository = app(TagRepositoryInterface::class);
|
||||
$repository->setUser($this->importJob->user);
|
||||
$data = [
|
||||
'tag' => (string) trans('import.import_with_key', ['key' => $this->importJob->key]),
|
||||
'date' => new Carbon,
|
||||
'description' => null,
|
||||
'latitude' => null,
|
||||
'longitude' => null,
|
||||
'zoom_level' => null,
|
||||
'tagMode' => 'nothing',
|
||||
];
|
||||
$tag = $repository->store($data);
|
||||
|
||||
Log::debug(sprintf('Created tag #%d ("%s")', $tag->id, $tag->tag));
|
||||
Log::debug('Looping groups...');
|
||||
|
||||
// TODO double loop.
|
||||
|
||||
/** @var TransactionGroup $group */
|
||||
foreach ($collection as $group) {
|
||||
Log::debug(sprintf('Looping journals in group #%d', $group->id));
|
||||
/** @var TransactionJournal $journal */
|
||||
$journalIds = $group->transactionJournals->pluck('id')->toArray();
|
||||
$tagId = $tag->id;
|
||||
foreach ($journalIds as $journalId) {
|
||||
Log::debug(sprintf('Linking journal #%d to tag #%d...', $journalId, $tagId));
|
||||
// @codeCoverageIgnoreStart
|
||||
try {
|
||||
DB::table('tag_transaction_journal')->insert(['transaction_journal_id' => $journalId, 'tag_id' => $tagId]);
|
||||
} catch (QueryException $e) {
|
||||
Log::error(sprintf('Could not link journal #%d to tag #%d because: %s', $journalId, $tagId, $e->getMessage()));
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
Log::info(sprintf('Linked %d journals to tag #%d ("%s")', $collection->count(), $tag->id, $tag->tag));
|
||||
}
|
||||
$this->repository->setTag($this->importJob, $tag);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Log about a duplicate object (double hash).
|
||||
*
|
||||
* @param array $transaction
|
||||
* @param int $existingId
|
||||
*/
|
||||
private function logDuplicateObject(array $transaction, int $existingId): void
|
||||
{
|
||||
Log::info(
|
||||
'Transaction is a duplicate, and will not be imported (the hash exists).',
|
||||
[
|
||||
'existing' => $existingId,
|
||||
'description' => $transaction['description'] ?? '',
|
||||
'amount' => $transaction['transactions'][0]['amount'] ?? 0,
|
||||
'date' => $transaction['date'] ?? '',
|
||||
]
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Log about a duplicate transfer.
|
||||
*
|
||||
* @param array $transaction
|
||||
*/
|
||||
private function logDuplicateTransfer(array $transaction): void
|
||||
{
|
||||
Log::info(
|
||||
'Transaction is a duplicate transfer, and will not be imported (such a transfer exists already).',
|
||||
[
|
||||
'description' => $transaction['description'] ?? '',
|
||||
'amount' => $transaction['transactions'][0]['amount'] ?? 0,
|
||||
'date' => $transaction['date'] ?? '',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shorthand method to quickly set job status
|
||||
*
|
||||
* @param string $status
|
||||
*/
|
||||
private function setStatus(string $status): void
|
||||
{
|
||||
$this->repository->setStatus($this->importJob, $status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $index
|
||||
* @param array $group
|
||||
*
|
||||
* @return TransactionGroup|null
|
||||
*/
|
||||
private function storeGroup(int $index, array $group): ?TransactionGroup
|
||||
{
|
||||
Log::debug(sprintf('Going to store entry #%d', $index + 1));
|
||||
|
||||
// do some basic error catching.
|
||||
foreach ($group['transactions'] as $groupIndex => $transaction) {
|
||||
$group['transactions'][$groupIndex]['date'] = Carbon::parse($transaction['date'], config('app.timezone'));
|
||||
$group['transactions'][$groupIndex]['description'] = '' === $transaction['description'] ? '(empty description)' : $transaction['description'];
|
||||
}
|
||||
|
||||
// do duplicate detection!
|
||||
if ($this->duplicateDetected($index, $group)) {
|
||||
Log::warning(sprintf('Row #%d seems to be a imported already and will be ignored.', $index));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// store the group
|
||||
try {
|
||||
$newGroup = $this->groupRepos->store($group);
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (FireflyException $e) {
|
||||
Log::error($e->getMessage());
|
||||
Log::error($e->getTraceAsString());
|
||||
$this->repository->addErrorMessage($this->importJob, sprintf('Row #%d could not be imported. %s', $index, $e->getMessage()));
|
||||
|
||||
return null;
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
Log::debug(sprintf('Stored as group #%d', $newGroup->id));
|
||||
|
||||
// add to collection of transfers, if necessary:
|
||||
if ('transfer' === strtolower($group['transactions'][0]['type'])) {
|
||||
$journals = $this->getTransactionFromJournal($newGroup);
|
||||
Log::debug('We just stored a transfer, so add the journal to the list of transfers.');
|
||||
foreach ($journals as $newJournal) {
|
||||
$this->transfers[] = $newJournal;
|
||||
}
|
||||
Log::debug(sprintf('List length is now %d', count($this->transfers)));
|
||||
}
|
||||
|
||||
return $newGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store array as journals.
|
||||
*
|
||||
* @throws FireflyException
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
private function storeGroupArray(): Collection
|
||||
{
|
||||
/** @var array $array */
|
||||
$array = $this->repository->getTransactions($this->importJob);
|
||||
$count = count($array);
|
||||
|
||||
Log::notice(sprintf('Will now store the groups. Count of groups is %d.', $count));
|
||||
Log::notice('Going to store...');
|
||||
|
||||
$collection = new Collection;
|
||||
foreach ($array as $index => $group) {
|
||||
Log::debug(sprintf('Now store #%d', $index + 1));
|
||||
$result = $this->storeGroup($index, $group);
|
||||
if (null !== $result) {
|
||||
$collection->push($result);
|
||||
}
|
||||
}
|
||||
Log::notice(sprintf('Done storing. Firefly III has stored %d transactions.', $collection->count()));
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a transfer exists.
|
||||
*
|
||||
* @param array $transaction
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
*/
|
||||
private function transferExists(array $transaction): bool
|
||||
{
|
||||
Log::debug('transferExists() Check if transaction is a double transfer.');
|
||||
|
||||
// how many hits do we need?
|
||||
Log::debug(sprintf('System has %d existing transfers', count($this->transfers)));
|
||||
// loop over each split:
|
||||
|
||||
// check if is a transfer
|
||||
if (strtolower(TransactionType::TRANSFER) !== strtolower($transaction['type'])) {
|
||||
// @codeCoverageIgnoreStart
|
||||
Log::debug(sprintf('Is a %s, not a transfer so no.', $transaction['type']));
|
||||
|
||||
return false;
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
|
||||
Log::debug(sprintf('Required hits for transfer comparison is %d', self::REQUIRED_HITS));
|
||||
|
||||
// get the amount:
|
||||
/** @noinspection UnnecessaryCastingInspection */
|
||||
$amount = (string) ($transaction['amount'] ?? '0');
|
||||
if (bccomp($amount, '0') === -1) {
|
||||
$amount = bcmul($amount, '-1'); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
// get the description:
|
||||
//$description = '' === (string)$transaction['description'] ? $transaction['description'] : $transaction['description'];
|
||||
$description = (string) $transaction['description'];
|
||||
|
||||
// get the source and destination ID's:
|
||||
$transactionSourceIDs = [(int) $transaction['source_id'], (int) $transaction['destination_id']];
|
||||
sort($transactionSourceIDs);
|
||||
|
||||
// get the source and destination names:
|
||||
$transactionSourceNames = [(string) $transaction['source_name'], (string) $transaction['destination_name']];
|
||||
sort($transactionSourceNames);
|
||||
|
||||
// then loop all transfers:
|
||||
/** @var array $transfer */
|
||||
foreach ($this->transfers as $transfer) {
|
||||
// number of hits for this split-transfer combination:
|
||||
$hits = 0;
|
||||
Log::debug(sprintf('Now looking at transaction journal #%d', $transfer['transaction_journal_id']));
|
||||
// compare amount:
|
||||
$originalAmount = app('steam')->positive($transfer['amount']);
|
||||
Log::debug(sprintf('Amount %s compared to %s', $amount, $originalAmount));
|
||||
if (0 !== bccomp($amount, $originalAmount)) {
|
||||
Log::debug('Amount is not a match, continue with next transfer.');
|
||||
continue;
|
||||
}
|
||||
++$hits;
|
||||
Log::debug(sprintf('Comparison is a hit! (%s)', $hits));
|
||||
|
||||
// compare description:
|
||||
// $comparison = '(empty description)' === $transfer['description'] ? '' : $transfer['description'];
|
||||
$comparison = $transfer['description'];
|
||||
Log::debug(sprintf('Comparing "%s" to "%s" (original: "%s")', $description, $transfer['description'], $comparison));
|
||||
if ($description !== $comparison) {
|
||||
Log::debug('Description is not a match, continue with next transfer.');
|
||||
continue; // @codeCoverageIgnore
|
||||
}
|
||||
++$hits;
|
||||
Log::debug(sprintf('Comparison is a hit! (%s)', $hits));
|
||||
|
||||
// compare date:
|
||||
$transferDate = $transfer['date']->format('Y-m-d H:i:s');
|
||||
$transactionDate = $transaction['date']->format('Y-m-d H:i:s');
|
||||
Log::debug(sprintf('Comparing dates "%s" to "%s"', $transactionDate, $transferDate));
|
||||
if ($transactionDate !== $transferDate) {
|
||||
Log::debug('Date is not a match, continue with next transfer.');
|
||||
continue; // @codeCoverageIgnore
|
||||
}
|
||||
++$hits;
|
||||
Log::debug(sprintf('Comparison is a hit! (%s)', $hits));
|
||||
|
||||
// compare source and destination id's
|
||||
$transferSourceIDs = [(int) $transfer['source_account_id'], (int) $transfer['destination_account_id']];
|
||||
sort($transferSourceIDs);
|
||||
/** @noinspection DisconnectedForeachInstructionInspection */
|
||||
Log::debug('Comparing current transaction source+dest IDs', $transactionSourceIDs);
|
||||
Log::debug('.. with current transfer source+dest IDs', $transferSourceIDs);
|
||||
if ($transactionSourceIDs === $transferSourceIDs) {
|
||||
++$hits;
|
||||
Log::debug(sprintf('Source IDs are the same! (%d)', $hits));
|
||||
}
|
||||
if ($transactionSourceIDs !== $transferSourceIDs) {
|
||||
Log::debug('Source IDs are not the same.');
|
||||
}
|
||||
unset($transferSourceIDs);
|
||||
|
||||
// compare source and destination names
|
||||
$transferSource = [(string) ($transfer['source_account_name'] ?? ''), (string) ($transfer['destination_account_name'] ?? '')];
|
||||
sort($transferSource);
|
||||
/** @noinspection DisconnectedForeachInstructionInspection */
|
||||
Log::debug('Comparing current transaction source+dest names', $transactionSourceNames);
|
||||
Log::debug('.. with current transfer source+dest names', $transferSource);
|
||||
if ($transactionSourceNames === $transferSource && $transferSource !== ['', '']) {
|
||||
// @codeCoverageIgnoreStart
|
||||
++$hits;
|
||||
Log::debug(sprintf('Source names are the same! (%d)', $hits));
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
if ($transactionSourceNames !== $transferSource) {
|
||||
Log::debug('Source names are not the same.');
|
||||
}
|
||||
|
||||
Log::debug(sprintf('Number of hits is %d', $hits));
|
||||
if ($hits >= self::REQUIRED_HITS) {
|
||||
Log::debug(sprintf('Is more than %d, return true.', self::REQUIRED_HITS));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Log::debug('Is not an existing transfer, return false.');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -1,150 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* ImportJob.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\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Eloquent;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphMany;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
/**
|
||||
* Class ImportJob.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @deprecated
|
||||
* @property array $transactions
|
||||
* @property array $configuration
|
||||
* @property User $user
|
||||
* @property int $user_id
|
||||
* @property string $status
|
||||
* @property string $stage
|
||||
* @property string $key
|
||||
* @property string $provider
|
||||
* @property string $file_type
|
||||
* @property int $tag_id
|
||||
* @property Tag $tag
|
||||
* @property array $errors
|
||||
* @property array extended_status
|
||||
* @property int id
|
||||
* @property Carbon $created_at
|
||||
* @property Carbon $updated_at
|
||||
* @property-read Collection|Attachment[] $attachments
|
||||
* @method static Builder|ImportJob newModelQuery()
|
||||
* @method static Builder|ImportJob newQuery()
|
||||
* @method static Builder|ImportJob query()
|
||||
* @method static Builder|ImportJob whereConfiguration($value)
|
||||
* @method static Builder|ImportJob whereCreatedAt($value)
|
||||
* @method static Builder|ImportJob whereErrors($value)
|
||||
* @method static Builder|ImportJob whereExtendedStatus($value)
|
||||
* @method static Builder|ImportJob whereFileType($value)
|
||||
* @method static Builder|ImportJob whereId($value)
|
||||
* @method static Builder|ImportJob whereKey($value)
|
||||
* @method static Builder|ImportJob whereProvider($value)
|
||||
* @method static Builder|ImportJob whereStage($value)
|
||||
* @method static Builder|ImportJob whereStatus($value)
|
||||
* @method static Builder|ImportJob whereTagId($value)
|
||||
* @method static Builder|ImportJob whereTransactions($value)
|
||||
* @method static Builder|ImportJob whereUpdatedAt($value)
|
||||
* @method static Builder|ImportJob whereUserId($value)
|
||||
* @mixin Eloquent
|
||||
* @property-read int|null $attachments_count
|
||||
* @property int $id
|
||||
* @property array|null $extended_status
|
||||
*/
|
||||
class ImportJob extends Model
|
||||
{
|
||||
|
||||
/**
|
||||
* The attributes that should be casted to native types.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $casts
|
||||
= [
|
||||
'user_id' => 'int',
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'configuration' => 'array',
|
||||
'extended_status' => 'array',
|
||||
'transactions' => 'array',
|
||||
'errors' => 'array',
|
||||
];
|
||||
/** @var array Fields that can be filled */
|
||||
protected $fillable = ['key', 'user_id', 'file_type', 'provider', 'status', 'stage', 'configuration', 'extended_status', 'transactions', 'errors'];
|
||||
|
||||
/**
|
||||
* Route binder. Converts the key in the URL to the specified object (or throw 404).
|
||||
*
|
||||
* @param $value
|
||||
*
|
||||
* @throws NotFoundHttpException
|
||||
* @return mixed
|
||||
*
|
||||
*/
|
||||
public static function routeBinder(string $value): ImportJob
|
||||
{
|
||||
if (auth()->check()) {
|
||||
$key = trim($value);
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
/** @var ImportJob $importJob */
|
||||
$importJob = $user->importJobs()->where('key', $key)->first();
|
||||
if (null !== $importJob) {
|
||||
return $importJob;
|
||||
}
|
||||
}
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* @return MorphMany
|
||||
*/
|
||||
public function attachments(): MorphMany
|
||||
{
|
||||
return $this->morphMany(Attachment::class, 'attachable');
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* @return BelongsTo
|
||||
*/
|
||||
public function tag(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Tag::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* @return BelongsTo
|
||||
*/
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
}
|
@ -4,13 +4,50 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Models;
|
||||
|
||||
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
/**
|
||||
* Class ObjectGroup
|
||||
*
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\PiggyBank[] $piggyBanks
|
||||
* @property-read int|null $piggy_banks_count
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ObjectGroup newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ObjectGroup newQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ObjectGroup query()
|
||||
* @mixin \Eloquent
|
||||
* @property int $id
|
||||
* @property \Illuminate\Support\Carbon|null $created_at
|
||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||
* @property string|null $deleted_at
|
||||
* @property string $title
|
||||
* @property int $order
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ObjectGroup whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ObjectGroup whereDeletedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ObjectGroup whereId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ObjectGroup whereOrder($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ObjectGroup whereTitle($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ObjectGroup whereUpdatedAt($value)
|
||||
*/
|
||||
class ObjectGroup extends Model
|
||||
{
|
||||
protected $fillable = ['title', 'order', 'user_id'];
|
||||
|
||||
/**
|
||||
* The attributes that should be casted to native types.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'user_id' => 'integer',
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\MorphToMany
|
||||
*/
|
||||
@ -18,4 +55,34 @@ class ObjectGroup extends Model
|
||||
{
|
||||
return $this->morphedByMany(PiggyBank::class, 'object_groupable');
|
||||
}
|
||||
|
||||
/**
|
||||
* Route binder. Converts the key in the URL to the specified object (or throw 404).
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @throws NotFoundHttpException
|
||||
* @return ObjectGroup
|
||||
*/
|
||||
public static function routeBinder(string $value): ObjectGroup
|
||||
{
|
||||
if (auth()->check()) {
|
||||
$objectGroupId = (int) $value;
|
||||
$objectGroup = self::where('object_groups.id', $objectGroupId)
|
||||
->where('object_groups.user_id', auth()->user()->id)->first();
|
||||
if (null !== $objectGroup) {
|
||||
return $objectGroup;
|
||||
}
|
||||
}
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BelongsTo
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user