Export data in API.

This commit is contained in:
James Cole
2021-03-04 06:28:16 +01:00
parent fcf578784f
commit 711999f589
8 changed files with 412 additions and 47 deletions

View File

@@ -0,0 +1,209 @@
<?php
/*
* AccountController.php
* Copyright (c) 2021 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/>.
*/
namespace FireflyIII\Api\V1\Controllers\Data\Export;
use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Data\Export\ExportRequest;
use FireflyIII\Support\Export\ExportDataGenerator;
use FireflyIII\User;
use Illuminate\Http\Response as LaravelResponse;
/**
* Class ExportController
*/
class ExportController extends Controller
{
private ExportDataGenerator $exporter;
/**
* ExportController constructor.
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
/** @var User $user */
$user = auth()->user();
/** @var ExportDataGenerator $exporter */
$this->exporter = app(ExportDataGenerator::class);
$this->exporter->setUser($user);
return $next($request);
}
);
}
/**
* @param ExportRequest $request
*
* @return LaravelResponse
* @throws \League\Csv\CannotInsertRecord
*/
public function accounts(ExportRequest $request): LaravelResponse
{
$this->exporter->setExportAccounts(true);
return $this->returnExport('accounts');
}
/**
* @param ExportRequest $request
*
* @return LaravelResponse
* @throws \League\Csv\CannotInsertRecord
*/
public function bills(ExportRequest $request): LaravelResponse
{
$this->exporter->setExportBills(true);
return $this->returnExport('bills');
}
/**
* @param ExportRequest $request
*
* @return LaravelResponse
* @throws \League\Csv\CannotInsertRecord
*/
public function budgets(ExportRequest $request): LaravelResponse
{
$this->exporter->setExportBudgets(true);
return $this->returnExport('budgets');
}
/**
* @param ExportRequest $request
*
* @return LaravelResponse
* @throws \League\Csv\CannotInsertRecord
*/
public function categories(ExportRequest $request): LaravelResponse
{
$this->exporter->setExportCategories(true);
return $this->returnExport('categories');
}
/**
* @param ExportRequest $request
*
* @return LaravelResponse
* @throws \League\Csv\CannotInsertRecord
*/
public function piggyBanks(ExportRequest $request): LaravelResponse
{
$this->exporter->setExportPiggies(true);
return $this->returnExport('piggies');
}
/**
* @param ExportRequest $request
*
* @return LaravelResponse
* @throws \League\Csv\CannotInsertRecord
*/
public function recurring(ExportRequest $request): LaravelResponse
{
$this->exporter->setExportRecurring(true);
return $this->returnExport('recurrences');
}
/**
* @param ExportRequest $request
*
* @return LaravelResponse
* @throws \League\Csv\CannotInsertRecord
*/
public function rules(ExportRequest $request): LaravelResponse
{
$this->exporter->setExportRules(true);
return $this->returnExport('rules');
}
/**
* @param ExportRequest $request
*
* @return LaravelResponse
* @throws \League\Csv\CannotInsertRecord
*/
public function tags(ExportRequest $request): LaravelResponse
{
$this->exporter->setExportTags(true);
return $this->returnExport('tags');
}
/**
* @param ExportRequest $request
*
* @return LaravelResponse
* @throws \League\Csv\CannotInsertRecord
*/
public function transactions(ExportRequest $request): LaravelResponse
{
$params = $request->getAll();
$this->exporter->setStart($params['start']);
$this->exporter->setEnd($params['end']);
$this->exporter->setAccounts($params['accounts']);
$this->exporter->setExportTransactions(true);
return $this->returnExport('transactions');
}
/**
* @param string $key
*
* @return LaravelResponse
* @throws \League\Csv\CannotInsertRecord
*/
private function returnExport(string $key): LaravelResponse
{
$date = date('Y-m-d-H-i-s');
$fileName = sprintf('%s-export-%s.csv', $date, $key);
$data = $this->exporter->export();
/** @var LaravelResponse $response */
$response = response($data[$key]);
$response
->header('Content-Description', 'File Transfer')
->header('Content-Type', 'application/octet-stream')
->header('Content-Disposition', 'attachment; filename=' . $fileName)
->header('Content-Transfer-Encoding', 'binary')
->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($data[$key]));
return $response;
}
}

View File

@@ -135,7 +135,7 @@ class AccountController extends Controller
'name' => $accountNames[$accountId],
'difference' => bcmul($diff, '-1'),
'difference_float' => ((float)$diff) * -1,
'currency_id' => $currencyId,
'currency_id' => (string) $currencyId,
'currency_code' => $currencies[$currencyId]->code,
];
}

View File

@@ -35,12 +35,9 @@ use FireflyIII\User;
use Illuminate\Http\JsonResponse;
/**
* Class DateController
*
* Shows income information grouped or limited by date.
* Ie. all income grouped by revenue + currency.
* Class AccountController
*/
class DateController extends Controller
class AccountController extends Controller
{
use ApiSupport;
@@ -72,9 +69,11 @@ class DateController extends Controller
}
/**
* @param DateRequest $request
*
* @return JsonResponse
*/
public function basic(DateRequest $request): JsonResponse
public function revenue(DateRequest $request): JsonResponse
{
// parameters for chart:
$dates = $request->getAll();

View File

@@ -0,0 +1,80 @@
<?php
/*
* ExportRequest.php
* Copyright (c) 2021 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/>.
*/
namespace FireflyIII\Api\V1\Requests\Data\Export;
use Carbon\Carbon;
use FireflyIII\Models\AccountType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Collection;
/**
* Class ExportRequest
*/
class ExportRequest extends FormRequest
{
use ChecksLogin, ConvertsDataTypes;
/**
* The rules that the incoming request must be matched against.
*
* @return array
*/
public function rules(): array
{
return [
'type' => 'in:csv',
'accounts' => 'min:1',
'start' => 'date|before:end',
'end' => 'date|after:start',
];
}
public function getAll(): array
{
$result = [
'start' => $this->date('start') ?? Carbon::now()->subYear(),
'end' => $this->date('end') ?? Carbon::now(),
'type' => $this->string('type'),
];
$parts = explode(',', $this->string('accounts'));
$repository = app(AccountRepositoryInterface::class);
$repository->setUser(auth()->user());
$accounts = new Collection;
foreach ($parts as $part) {
$accountId = (int)$part;
if (0 !== $accountId) {
$account = $repository->findNull($accountId);
if (null !== $account && AccountType::ASSET === $account->accountType->type) {
$accounts->push($account);
}
}
}
$result['accounts'] = $accounts;
return $result;
}
}

View File

@@ -111,8 +111,12 @@ class ExportData extends Command
/** @var ExportDataGenerator $exporter */
$exporter = app(ExportDataGenerator::class);
$exporter->setUser($this->user);
$exporter->setStart($options['start']);
$exporter->setEnd($options['end']);
$exporter->setAccounts($options['accounts']);
$exporter->setExportTransactions($options['export']['transactions']);
$exporter->setExportAccounts($options['export']['accounts']);
$exporter->setExportBudgets($options['export']['budgets']);

View File

@@ -50,6 +50,7 @@ use FireflyIII\Repositories\Rule\RuleRepositoryInterface;
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface;
use FireflyIII\User;
use Illuminate\Support\Collection;
use League\Csv\Writer;
/**
@@ -57,35 +58,24 @@ use League\Csv\Writer;
*/
class ExportDataGenerator
{
/** @var Carbon */
private $end;
/** @var bool */
private $exportTransactions;
/** @var Carbon */
private $start;
/** @var bool */
private $exportAccounts;
/** @var bool */
private $exportBudgets;
/** @var bool */
private $exportCategories;
/** @var bool */
private $exportTags;
/** @var bool */
private $exportRecurring;
/** @var bool */
private $exportRules;
/** @var bool */
private $exportBills;
/** @var bool */
private $exportPiggies;
/** @var User */
private $user;
private Carbon $end;
private bool $exportTransactions;
private Carbon $start;
private bool $exportAccounts;
private bool $exportBudgets;
private bool $exportCategories;
private bool $exportTags;
private bool $exportRecurring;
private bool $exportRules;
private bool $exportBills;
private bool $exportPiggies;
private User $user;
private Collection $accounts;
public function __construct()
{
$this->start = today(config('app.timezone'));
$this->accounts = new Collection;
$this->start = today(config('app.timezone'));
$this->start->subYear();
$this->end = today(config('app.timezone'));
$this->exportTransactions = false;
@@ -107,6 +97,14 @@ class ExportDataGenerator
$this->user = $user;
}
/**
* @param Collection $accounts
*/
public function setAccounts(Collection $accounts): void
{
$this->accounts = $accounts;
}
/**
* @return array
* @throws \League\Csv\CannotInsertRecord
@@ -506,7 +504,7 @@ class ExportDataGenerator
$currency ? $currency->code : null,
$piggy->targetamount,
$repetition ? $repetition->currentamount : null,
$piggy->startdate->format('Y-m-d'),
$piggy->startdate ? $piggy->startdate->format('Y-m-d') : null,
$piggy->targetdate ? $piggy->targetdate->format('Y-m-d') : null,
$piggy->order,
$piggy->active,
@@ -670,6 +668,10 @@ class ExportDataGenerator
$collector->setUser($this->user);
$collector->setRange($this->start, $this->end)->withAccountInformation()->withCategoryInformation()->withBillInformation()
->withBudgetInformation()->withTagInformation()->withNotes();
if(0 !== $this->accounts->count()) {
$collector->setAccounts($this->accounts);
}
$journals = $collector->getExtractedJournals();
// get repository for meta data: