Files
firefly-iii/app/Http/Controllers/Account/ReconcileController.php

212 lines
9.0 KiB
PHP
Raw Normal View History

2017-11-15 06:29:49 +01:00
<?php
/**
* ReconcileController.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
2017-12-17 14:41:58 +01:00
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
2017-11-15 06:29:49 +01:00
*/
2018-07-08 12:08:53 +02:00
/** @noinspection CallableParameterUseCaseInTypeContextInspection */
2017-11-15 06:29:49 +01:00
declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Account;
use Carbon\Carbon;
2019-06-22 13:09:11 +02:00
use Exception;
2017-11-15 06:29:49 +01:00
use FireflyIII\Http\Controllers\Controller;
2018-02-23 15:13:01 +01:00
use FireflyIII\Http\Requests\ReconciliationStoreRequest;
2017-11-15 06:29:49 +01:00
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
2017-11-22 16:54:49 +01:00
use FireflyIII\Models\Transaction;
2017-11-22 17:49:06 +01:00
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
2017-11-15 06:29:49 +01:00
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
2017-11-22 16:54:49 +01:00
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Support\Http\Controllers\UserNavigation;
2018-02-23 15:13:01 +01:00
use Log;
2017-11-15 06:29:49 +01:00
/**
2017-11-15 12:25:49 +01:00
* Class ReconcileController.
2017-11-15 06:29:49 +01:00
*/
class ReconcileController extends Controller
{
use UserNavigation;
/** @var AccountRepositoryInterface The account repository */
2018-07-15 15:45:45 +02:00
private $accountRepos;
/** @var CurrencyRepositoryInterface The currency repository */
2018-03-25 09:01:43 +02:00
private $currencyRepos;
/** @var JournalRepositoryInterface Journals and transactions overview */
private $repository;
2017-11-15 06:29:49 +01:00
/**
* ReconcileController constructor.
2019-06-22 13:09:11 +02:00
* @codeCoverageIgnore
2017-11-15 06:29:49 +01:00
*/
public function __construct()
{
parent::__construct();
// translations:
$this->middleware(
function ($request, $next) {
2017-12-16 19:46:36 +01:00
app('view')->share('mainTitleIcon', 'fa-credit-card');
2018-07-15 09:38:49 +02:00
app('view')->share('title', (string)trans('firefly.accounts'));
2018-03-25 09:01:43 +02:00
$this->repository = app(JournalRepositoryInterface::class);
$this->accountRepos = app(AccountRepositoryInterface::class);
$this->currencyRepos = app(CurrencyRepositoryInterface::class);
2017-11-15 06:29:49 +01:00
return $next($request);
}
);
}
/**
* Reconciliation overview.
*
2019-06-22 13:09:11 +02:00
* @param Account $account
2017-11-15 06:29:49 +01:00
* @param Carbon|null $start
* @param Carbon|null $end
*
2017-11-25 15:20:53 +01:00
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|\Illuminate\View\View
2019-06-22 13:09:11 +02:00
* @throws Exception
2017-11-15 06:29:49 +01:00
*/
public function reconcile(Account $account, Carbon $start = null, Carbon $end = null)
{
2017-11-15 12:25:49 +01:00
if (AccountType::INITIAL_BALANCE === $account->accountType->type) {
2017-11-15 06:29:49 +01:00
return $this->redirectToOriginalAccount($account);
}
2017-11-22 17:49:06 +01:00
if (AccountType::ASSET !== $account->accountType->type) {
2018-07-15 09:38:49 +02:00
session()->flash('error', (string)trans('firefly.must_be_asset_account'));
2017-11-22 17:49:06 +01:00
2019-06-22 13:09:11 +02:00
return redirect(route('accounts.index', [config(sprintf('firefly.shortNamesByFullName.%s', $account->accountType->type))]));
2017-11-15 06:29:49 +01:00
}
2019-06-22 13:09:11 +02:00
$currency = $this->accountRepos->getAccountCurrency($account) ?? app('amount')->getDefaultCurrency();
2017-11-15 06:29:49 +01:00
// no start or end:
$range = app('preferences')->get('viewRange', '1M')->data;
2017-11-15 06:29:49 +01:00
// get start and end
2017-11-15 12:25:49 +01:00
if (null === $start && null === $end) {
2018-07-27 04:46:21 +02:00
/** @var Carbon $start */
$start = clone session('start', app('navigation')->startOfPeriod(new Carbon, $range));
2018-07-27 04:46:21 +02:00
/** @var Carbon $end */
2018-08-06 19:14:30 +02:00
$end = clone session('end', app('navigation')->endOfPeriod(new Carbon, $range));
2017-11-15 06:29:49 +01:00
}
2017-11-15 12:25:49 +01:00
if (null === $end) {
2018-07-27 04:46:21 +02:00
/** @var Carbon $end */
$end = app('navigation')->endOfPeriod($start, $range);
2017-11-15 06:29:49 +01:00
}
$startDate = clone $start;
2019-06-22 13:09:11 +02:00
$startDate->subDay();
2017-11-15 06:29:49 +01:00
$startBalance = round(app('steam')->balance($account, $startDate), $currency->decimal_places);
$endBalance = round(app('steam')->balance($account, $end), $currency->decimal_places);
2019-06-22 13:09:11 +02:00
$subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $account->accountType->type));
2018-07-15 09:38:49 +02:00
$subTitle = (string)trans('firefly.reconcile_account', ['account' => $account->name]);
2017-11-15 06:29:49 +01:00
// various links
$transactionsUri = route('accounts.reconcile.transactions', [$account->id, '%start%', '%end%']);
$overviewUri = route('accounts.reconcile.overview', [$account->id, '%start%', '%end%']);
$indexUri = route('accounts.reconcile', [$account->id, '%start%', '%end%']);
2019-06-22 13:09:11 +02:00
$objectType = 'asset';
2018-04-24 19:26:16 +02:00
2019-06-22 13:09:11 +02:00
return view('accounts.reconcile.index',
compact('account', 'currency', 'objectType',
'subTitleIcon', 'start', 'end', 'subTitle', 'startBalance', 'endBalance',
'transactionsUri', 'overviewUri', 'indexUri'));
2017-11-15 06:29:49 +01:00
}
2017-11-22 17:49:06 +01:00
/**
* Submit a new reconciliation.
*
2018-02-23 15:13:01 +01:00
* @param ReconciliationStoreRequest $request
2019-06-22 13:09:11 +02:00
* @param Account $account
* @param Carbon $start
* @param Carbon $end
2017-11-25 15:20:53 +01:00
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
2017-11-22 17:49:06 +01:00
*/
2018-07-08 12:08:53 +02:00
public function submit(ReconciliationStoreRequest $request, Account $account, Carbon $start, Carbon $end)
2017-11-22 17:49:06 +01:00
{
2018-02-23 15:13:01 +01:00
Log::debug('In ReconcileController::submit()');
$data = $request->getAll();
2017-11-22 17:49:06 +01:00
/** @var Transaction $transaction */
2018-02-23 15:13:01 +01:00
foreach ($data['transactions'] as $transactionId) {
2018-07-08 12:08:53 +02:00
$this->repository->reconcileById((int)$transactionId);
2017-11-22 17:49:06 +01:00
}
2018-02-23 15:13:01 +01:00
Log::debug('Reconciled all transactions.');
2017-11-22 17:49:06 +01:00
// create reconciliation transaction (if necessary):
2018-02-23 15:13:01 +01:00
if ('create' === $data['reconcile']) {
// get "opposing" account.
2018-03-25 09:01:43 +02:00
$reconciliation = $this->accountRepos->getReconciliation($account);
2018-07-13 06:12:39 +02:00
$difference = $data['difference'];
$source = $reconciliation;
$destination = $account;
2018-07-08 07:59:58 +02:00
if (1 === bccomp($difference, '0')) {
2018-02-23 15:13:01 +01:00
// amount is positive. Add it to reconciliation?
$source = $account;
$destination = $reconciliation;
}
// data for journal
$description = trans(
'firefly.reconcilliation_transaction_title',
['from' => $start->formatLocalized($this->monthAndDayFormat), 'to' => $end->formatLocalized($this->monthAndDayFormat)]
);
$journalData = [
'type' => 'Reconciliation',
'description' => $description,
'user' => auth()->user()->id,
'date' => $data['end'],
'bill_id' => null,
'bill_name' => null,
'piggy_bank_id' => null,
'piggy_bank_name' => null,
'tags' => null,
'interest_date' => null,
'transactions' => [[
2018-04-02 15:10:40 +02:00
'currency_id' => (int)$this->accountRepos->getMetaValue($account, 'currency_id'),
2018-02-23 15:13:01 +01:00
'currency_code' => null,
'description' => null,
'amount' => app('steam')->positive($difference),
'source_id' => $source->id,
'source_name' => null,
'destination_id' => $destination->id,
'destination_name' => null,
'reconciled' => true,
'identifier' => 0,
'foreign_currency_id' => null,
'foreign_currency_code' => null,
'foreign_amount' => null,
'budget_id' => null,
'budget_name' => null,
'category_id' => null,
'category_name' => null,
],
],
'notes' => implode(', ', $data['transactions']),
2017-11-22 17:49:06 +01:00
];
2018-02-23 15:13:01 +01:00
2018-07-08 12:08:53 +02:00
$this->repository->store($journalData);
2017-11-22 17:49:06 +01:00
}
2018-02-23 15:13:01 +01:00
Log::debug('End of routine.');
2018-07-08 12:08:53 +02:00
app('preferences')->mark();
2018-07-15 09:38:49 +02:00
session()->flash('success', (string)trans('firefly.reconciliation_stored'));
2017-11-22 17:49:06 +01:00
return redirect(route('accounts.show', [$account->id]));
}
2017-11-15 10:52:29 +01:00
}