Merge branch 'release/3.9.0'

Signed-off-by: James Cole <thegrumpydictator@gmail.com>

# Conflicts:
#	app/Helpers/Csv/Converter/BillName.php
This commit is contained in:
James Cole
2016-05-22 16:46:11 +02:00
559 changed files with 14471 additions and 12696 deletions

View File

@@ -1,9 +1,16 @@
<?php
/**
* AttachmentHelper.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Attachments;
use Auth;
use Config;
use Crypt;
use FireflyIII\Models\Attachment;
use Illuminate\Database\Eloquent\Model;
@@ -39,8 +46,8 @@ class AttachmentHelper implements AttachmentHelperInterface
*/
public function __construct()
{
$this->maxUploadSize = Config::get('firefly.maxUploadSize');
$this->allowedMimes = Config::get('firefly.allowedMimes');
$this->maxUploadSize = config('firefly.maxUploadSize');
$this->allowedMimes = config('firefly.allowedMimes');
$this->errors = new MessageBag;
$this->messages = new MessageBag;
$this->uploadDisk = Storage::disk('upload');
@@ -81,26 +88,14 @@ class AttachmentHelper implements AttachmentHelperInterface
*/
public function saveAttachmentsForModel(Model $model): bool
{
$files = null;
try {
if (Input::hasFile('attachments')) {
$files = Input::file('attachments');
}
} catch (TypeError $e) {
// Log it, do nothing else.
Log::error($e->getMessage());
$files = $this->getFiles();
if (!is_null($files) && !is_array($files)) {
$this->processFile($files, $model);
}
if (is_array($files)) {
foreach ($files as $entry) {
if (!is_null($entry)) {
$this->processFile($entry, $model);
}
}
} else {
if (!is_null($files)) {
$this->processFile($files, $model);
}
$this->processFiles($files, $model);
}
return true;
@@ -234,5 +229,39 @@ class AttachmentHelper implements AttachmentHelperInterface
return true;
}
/**
* @return array|null|UploadedFile
*/
private function getFiles()
{
$files = null;
try {
if (Input::hasFile('attachments')) {
$files = Input::file('attachments');
}
} catch (TypeError $e) {
// Log it, do nothing else.
Log::error($e->getMessage());
}
return $files;
}
/**
* @param array $files
*
* @return bool
*/
private function processFiles(array $files, Model $model): bool
{
foreach ($files as $entry) {
if (!is_null($entry)) {
$this->processFile($entry, $model);
}
}
return true;
}
}

View File

@@ -1,4 +1,12 @@
<?php
/**
* AttachmentHelperInterface.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Attachments;

View File

@@ -1,4 +1,12 @@
<?php
/**
* Account.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;

View File

@@ -1,4 +1,12 @@
<?php
/**
* Balance.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;
@@ -59,5 +67,13 @@ class Balance
return $this->balanceLines;
}
/**
* @param Collection $balanceLines
*/
public function setBalanceLines(Collection $balanceLines)
{
$this->balanceLines = $balanceLines;
}
}

View File

@@ -1,4 +1,12 @@
<?php
/**
* BalanceEntry.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;

View File

@@ -1,4 +1,12 @@
<?php
/**
* BalanceHeader.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;

View File

@@ -1,7 +1,16 @@
<?php
/**
* BalanceLine.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;
use Carbon\Carbon;
use FireflyIII\Models\Budget as BudgetModel;
use Illuminate\Support\Collection;
@@ -24,6 +33,11 @@ class BalanceLine
/** @var BudgetModel */
protected $budget;
/** @var Carbon */
protected $startDate;
/** @var Carbon */
protected $endDate;
/** @var int */
protected $role = self::ROLE_DEFAULTROLE;
@@ -113,6 +127,39 @@ class BalanceLine
return '';
}
/**
* @return Carbon
*/
public function getStartDate()
{
return $this->startDate;
}
/**
* @param Carbon $startDate
*/
public function setStartDate($startDate)
{
$this->startDate = $startDate;
}
/**
* @return Carbon
*/
public function getEndDate()
{
return $this->endDate;
}
/**
* @param Carbon $endDate
*/
public function setEndDate($endDate)
{
$this->endDate = $endDate;
}
/**
* If a BalanceLine has a budget/repetition, each BalanceEntry in this BalanceLine
* should have a "spent" value, which is the amount of money that has been spent

View File

@@ -1,4 +1,12 @@
<?php
/**
* Bill.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;

View File

@@ -1,4 +1,12 @@
<?php
/**
* BillLine.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;
@@ -141,5 +149,4 @@ class BillLine
$this->hit = $hit;
}
}

View File

@@ -1,4 +1,12 @@
<?php
/**
* Budget.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;

View File

@@ -1,4 +1,12 @@
<?php
/**
* BudgetLine.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;

View File

@@ -1,4 +1,12 @@
<?php
/**
* Category.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;

View File

@@ -1,8 +1,15 @@
<?php
/**
* Expense.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;
use Crypt;
use FireflyIII\Models\TransactionJournal;
use Illuminate\Support\Collection;
use stdClass;
@@ -33,26 +40,32 @@ class Expense
*/
public function addOrCreateExpense(TransactionJournal $entry)
{
// add each account individually:
$destinations = TransactionJournal::destinationTransactionList($entry);
$accountId = $entry->account_id;
$amount = strval(round($entry->journalAmount, 2));
if (bccomp('0', $amount) === -1) {
$amount = bcmul($amount, '-1');
foreach ($destinations as $transaction) {
$amount = strval($transaction->amount);
$account = $transaction->account;
if (bccomp('0', $amount) === -1) {
$amount = bcmul($amount, '-1');
}
$object = new stdClass;
$object->amount = $amount;
$object->name = $account->name;
$object->count = 1;
$object->id = $account->id;
// overrule some properties:
if ($this->expenses->has($account->id)) {
$object = $this->expenses->get($account->id);
$object->amount = bcadd($object->amount, $amount);
$object->count++;
}
$this->expenses->put($account->id, $object);
}
if (!$this->expenses->has($accountId)) {
$newObject = new stdClass;
$newObject->amount = $amount;
$newObject->name = Crypt::decrypt($entry->account_name);
$newObject->count = 1;
$newObject->id = $accountId;
$this->expenses->put($accountId, $newObject);
} else {
$existing = $this->expenses->get($accountId);
$existing->amount = bcadd($existing->amount, $amount);
$existing->count++;
$this->expenses->put($accountId, $existing);
}
}
/**
@@ -60,8 +73,6 @@ class Expense
*/
public function addToTotal(string $add)
{
$add = strval(round($add, 2));
if (bccomp('0', $add) === -1) {
$add = bcmul($add, '-1');

View File

@@ -1,8 +1,15 @@
<?php
/**
* Income.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;
use Crypt;
use FireflyIII\Models\TransactionJournal;
use Illuminate\Support\Collection;
use stdClass;
@@ -34,21 +41,29 @@ class Income
*/
public function addOrCreateIncome(TransactionJournal $entry)
{
// add each account individually:
$sources = TransactionJournal::sourceTransactionList($entry);
$accountId = $entry->account_id;
if (!$this->incomes->has($accountId)) {
$newObject = new stdClass;
$newObject->amount = strval(round($entry->journalAmount, 2));
$newObject->name = Crypt::decrypt($entry->account_name);
$newObject->count = 1;
$newObject->id = $accountId;
$this->incomes->put($accountId, $newObject);
} else {
$existing = $this->incomes->get($accountId);
$existing->amount = bcadd($existing->amount, $entry->journalAmount);
$existing->count++;
$this->incomes->put($accountId, $existing);
foreach ($sources as $transaction) {
$amount = strval($transaction->amount);
$account = $transaction->account;
$amount = bcmul($amount, '-1');
$object = new stdClass;
$object->amount = $amount;
$object->name = $account->name;
$object->count = 1;
$object->id = $account->id;
// overrule some properties:
if ($this->incomes->has($account->id)) {
$object = $this->incomes->get($account->id);
$object->amount = bcadd($object->amount, $amount);
$object->count++;
}
$this->incomes->put($account->id, $object);
}
}
/**

View File

@@ -1,9 +1,16 @@
<?php
/**
* AccountId.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use FireflyIII\Models\Account;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
/**
* Class AccountId
@@ -18,17 +25,10 @@ class AccountId extends BasicConverter implements ConverterInterface
*/
public function convert(): Account
{
/** @var AccountRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
// is mapped? Then it's easy!
if (isset($this->mapped[$this->index][$this->value])) {
/** @var Account $account */
$account = $repository->find($this->mapped[$this->index][$this->value]);
} else {
/** @var Account $account */
$account = $repository->find($this->value);
}
$crud = app('FireflyIII\Crud\Account\AccountCrudInterface');
$var = isset($this->mapped[$this->index][$this->value]) ? $this->mapped[$this->index][$this->value] : $this->value;
$account = $crud->find($var);
return $account;
}

View File

@@ -1,4 +1,12 @@
<?php
/**
* Amount.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;

View File

@@ -1,4 +1,12 @@
<?php
/**
* AmountComma.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;

View File

@@ -1,12 +1,20 @@
<?php
/**
* AssetAccountIban.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use Auth;
use Carbon\Carbon;
use FireflyIII\Crud\Account\AccountCrudInterface;
use FireflyIII\Models\Account;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use Log;
use FireflyIII\Models\AccountType;
/**
* Class AssetAccountIban
@@ -21,52 +29,61 @@ class AssetAccountIban extends BasicConverter implements ConverterInterface
*/
public function convert(): Account
{
/** @var AccountRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
$crud = app('FireflyIII\Crud\Account\AccountCrudInterface');
// is mapped? Then it's easy!
if (isset($this->mapped[$this->index][$this->value])) {
$account = $repository->find(intval($this->mapped[$this->index][$this->value]));
Log::debug('Found mapped account for value "' . $this->value . '". It is account #' . $account->id);
$account = $crud->find(intval($this->mapped[$this->index][$this->value]));
return $account;
}
if (strlen($this->value) > 0) {
// find or create new account:
$set = $repository->getAccounts(['Default account', 'Asset account']);
/** @var Account $entry */
foreach ($set as $entry) {
if ($entry->iban == $this->value) {
Log::debug('Found an account with the same IBAN ("' . $this->value . '"). It is account #' . $entry->id);
return $entry;
}
}
Log::debug('Found no account with the same IBAN ("' . $this->value . '"), so will create a new one.');
// create it if doesn't exist.
$accountData = [
'name' => $this->value,
'accountType' => 'asset',
'virtualBalance' => 0,
'virtualBalanceCurrency' => 1, // hard coded.
'active' => true,
'user' => Auth::user()->id,
'iban' => $this->value,
'accountNumber' => $this->value,
'accountRole' => null,
'openingBalance' => 0,
'openingBalanceDate' => new Carbon,
'openingBalanceCurrency' => 1, // hard coded.
];
$account = $repository->store($accountData);
$account = $this->searchOrCreate($crud);
return $account;
}
return new Account;
}
/**
* @param AccountCrudInterface $crud
*
* @return Account
*/
private function searchOrCreate(AccountCrudInterface $crud)
{
// find or create new account:
$set = $crud->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
/** @var Account $entry */
foreach ($set as $entry) {
if ($entry->iban == $this->value) {
return $entry;
}
}
// create it if doesn't exist.
$accountData = [
'name' => $this->value,
'accountType' => 'asset',
'virtualBalance' => 0,
'virtualBalanceCurrency' => 1, // hard coded.
'active' => true,
'user' => Auth::user()->id,
'iban' => $this->value,
'accountNumber' => $this->value,
'accountRole' => null,
'openingBalance' => 0,
'openingBalanceDate' => new Carbon,
'openingBalanceCurrency' => 1, // hard coded.
];
$account = $crud->store($accountData);
return $account;
}
}

View File

@@ -1,11 +1,19 @@
<?php
/**
* AssetAccountName.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use Auth;
use Carbon\Carbon;
use FireflyIII\Models\Account;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Models\AccountType;
/**
* Class AssetAccountName
@@ -20,27 +28,21 @@ class AssetAccountName extends BasicConverter implements ConverterInterface
*/
public function convert(): Account
{
/** @var AccountRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
$crud = app('FireflyIII\Crud\Account\AccountCrudInterface');
// is mapped? Then it's easy!
if (isset($this->mapped[$this->index][$this->value])) {
$account = $repository->find(intval($this->mapped[$this->index][$this->value]));
$account = $crud->find(intval($this->mapped[$this->index][$this->value]));
return $account;
}
// find or create new account:
$set = $repository->getAccounts(['Default account', 'Asset account']);
$set = $crud->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
/** @var Account $entry */
foreach ($set as $entry) {
if ($entry->name == $this->value) {
return $entry;
}
}
// create it if doesnt exist.
$accountData = [
'name' => $this->value,
'accountType' => 'asset',
@@ -54,10 +56,9 @@ class AssetAccountName extends BasicConverter implements ConverterInterface
'openingBalance' => 0,
'openingBalanceDate' => new Carbon,
'openingBalanceCurrency' => 1, // hard coded.
];
$account = $repository->store($accountData);
$account = $crud->store($accountData);
return $account;
}

View File

@@ -1,5 +1,4 @@
<?php
declare(strict_types = 1);
/**
* AssetAccountNumber.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
@@ -14,7 +13,7 @@ namespace FireflyIII\Helpers\Csv\Converter;
use Auth;
use Carbon\Carbon;
use FireflyIII\Models\Account;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Models\AccountType;
/**
* Class AssetAccountNumber
@@ -29,12 +28,11 @@ class AssetAccountNumber extends BasicConverter implements ConverterInterface
*/
public function convert(): Account
{
/** @var AccountRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
$crud = app('FireflyIII\Crud\Account\AccountCrudInterface');
// is mapped? Then it's easy!
if (isset($this->mapped[$this->index][$this->value])) {
$account = $repository->find(intval($this->mapped[$this->index][$this->value]));
$account = $crud->find(intval($this->mapped[$this->index][$this->value]));
return $account;
}
@@ -42,7 +40,7 @@ class AssetAccountNumber extends BasicConverter implements ConverterInterface
$value = $this->value ?? '';
if (strlen($value) > 0) {
// find or create new account:
$set = $repository->getAccounts(['Default account', 'Asset account']);
$set = $crud->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
/** @var Account $entry */
foreach ($set as $entry) {
$accountNumber = $entry->getMeta('accountNumber');
@@ -68,7 +66,7 @@ class AssetAccountNumber extends BasicConverter implements ConverterInterface
];
$account = $repository->store($accountData);
$account = $crud->store($accountData);
return $account;
}

View File

@@ -1,10 +1,20 @@
<?php
/**
* BasicConverter.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
/**
* Class BasicConverter
*
*
* @SuppressWarnings(PHPMD.NumberOfChildren)
* @package FireflyIII\Helpers\Csv\Converter
*/
class BasicConverter

View File

@@ -1,4 +1,12 @@
<?php
/**
* BillId.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
@@ -19,14 +27,9 @@ class BillId extends BasicConverter implements ConverterInterface
public function convert(): Bill
{
/** @var BillRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Bill\BillRepositoryInterface');
// is mapped? Then it's easy!
if (isset($this->mapped[$this->index][$this->value])) {
$bill = $repository->find($this->mapped[$this->index][$this->value]);
} else {
$bill = $repository->find($this->value);
}
$repository = app(BillRepositoryInterface::class);
$value = isset($this->mapped[$this->index][$this->value]) ? $this->mapped[$this->index][$this->value] : $this->value;
$bill = $repository->find($value);
return $bill;
}

View File

@@ -1,4 +1,12 @@
<?php
/**
* BillName.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
@@ -19,22 +27,21 @@ class BillName extends BasicConverter implements ConverterInterface
public function convert(): Bill
{
/** @var BillRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Bill\BillRepositoryInterface');
$repository = app(BillRepositoryInterface::class);
$bill = new Bill;
// is mapped? Then it's easy!
if (isset($this->mapped[$this->index][$this->value])) {
$bill = $repository->find($this->mapped[$this->index][$this->value]);
} else {
$bills = $repository->getBills();
/** @var Bill $bill */
foreach ($bills as $bill) {
if ($bill->name == $this->value) {
return $bill;
}
return $repository->find($this->mapped[$this->index][$this->value]);
}
$bills = $repository->getBills();
/** @var Bill $bill */
foreach ($bills as $bill) {
if ($bill->name == $this->value) {
return $bill;
}
}
return $bill;
return new Bill;
}
}

View File

@@ -1,4 +1,12 @@
<?php
/**
* BudgetId.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
@@ -19,15 +27,9 @@ class BudgetId extends BasicConverter implements ConverterInterface
public function convert(): Budget
{
/** @var BudgetRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Budget\BudgetRepositoryInterface');
// is mapped? Then it's easy!
if (isset($this->mapped[$this->index][$this->value])) {
$budget = $repository->find($this->mapped[$this->index][$this->value]);
} else {
$budget = $repository->find($this->value);
}
$repository = app(BudgetRepositoryInterface::class);
$value = isset($this->mapped[$this->index][$this->value]) ? $this->mapped[$this->index][$this->value] : $this->value;
$budget = $repository->find($value);
return $budget;
}

View File

@@ -1,4 +1,12 @@
<?php
/**
* BudgetName.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
@@ -20,14 +28,16 @@ class BudgetName extends BasicConverter implements ConverterInterface
public function convert(): Budget
{
/** @var BudgetRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Budget\BudgetRepositoryInterface');
$repository = app(BudgetRepositoryInterface::class);
// is mapped? Then it's easy!
if (isset($this->mapped[$this->index][$this->value])) {
$budget = $repository->find($this->mapped[$this->index][$this->value]);
} else {
$budget = $repository->store(['name' => $this->value, 'user' => Auth::user()->id]);
return $budget;
}
$budget = $repository->store(['name' => $this->value, 'user' => Auth::user()->id]);
return $budget;
}

View File

@@ -1,9 +1,17 @@
<?php
/**
* CategoryId.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use FireflyIII\Models\Category;
use FireflyIII\Repositories\Category\SingleCategoryRepositoryInterface;
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
/**
* Class CategoryId
@@ -18,15 +26,10 @@ class CategoryId extends BasicConverter implements ConverterInterface
*/
public function convert(): Category
{
/** @var SingleCategoryRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Category\SingleCategoryRepositoryInterface');
// is mapped? Then it's easy!
if (isset($this->mapped[$this->index][$this->value])) {
$category = $repository->find($this->mapped[$this->index][$this->value]);
} else {
$category = $repository->find($this->value);
}
/** @var CategoryRepositoryInterface $repository */
$repository = app(CategoryRepositoryInterface::class);
$value = isset($this->mapped[$this->index][$this->value]) ? $this->mapped[$this->index][$this->value] : $this->value;
$category = $repository->find($value);
return $category;
}

View File

@@ -1,10 +1,18 @@
<?php
/**
* CategoryName.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use Auth;
use FireflyIII\Models\Category;
use FireflyIII\Repositories\Category\SingleCategoryRepositoryInterface;
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
/**
* Class CategoryName
@@ -19,22 +27,23 @@ class CategoryName extends BasicConverter implements ConverterInterface
*/
public function convert(): Category
{
/** @var SingleCategoryRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Category\SingleCategoryRepositoryInterface');
/** @var CategoryRepositoryInterface $repository */
$repository = app(CategoryRepositoryInterface::class);
// is mapped? Then it's easy!
if (isset($this->mapped[$this->index][$this->value])) {
$category = $repository->find($this->mapped[$this->index][$this->value]);
} else {
$data = [
'name' => $this->value,
'user' => Auth::user()->id,
];
$category = $repository->store($data);
return $category;
}
$data = [
'name' => $this->value,
'user' => Auth::user()->id,
];
$category = $repository->store($data);
return $category;
}
}

View File

@@ -1,4 +1,12 @@
<?php
/**
* ConverterInterface.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;

View File

@@ -1,4 +1,12 @@
<?php
/**
* CurrencyCode.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
@@ -19,15 +27,17 @@ class CurrencyCode extends BasicConverter implements ConverterInterface
public function convert(): TransactionCurrency
{
/** @var CurrencyRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Currency\CurrencyRepositoryInterface');
$repository = app(CurrencyRepositoryInterface::class);
if (isset($this->mapped[$this->index][$this->value])) {
$currency = $repository->find($this->mapped[$this->index][$this->value]);
} else {
$currency = $repository->findByCode($this->value);
$currency = $repository->find(intval($this->mapped[$this->index][$this->value]));
return $currency;
}
$currency = $repository->findByCode($this->value);
return $currency;
}
}

View File

@@ -1,4 +1,12 @@
<?php
/**
* CurrencyId.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
@@ -19,13 +27,9 @@ class CurrencyId extends BasicConverter implements ConverterInterface
public function convert(): TransactionCurrency
{
/** @var CurrencyRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Currency\CurrencyRepositoryInterface');
if (isset($this->mapped[$this->index][$this->value])) {
$currency = $repository->find($this->mapped[$this->index][$this->value]);
} else {
$currency = $repository->find($this->value);
}
$repository = app(CurrencyRepositoryInterface::class);
$value = isset($this->mapped[$this->index][$this->value]) ? $this->mapped[$this->index][$this->value] : $this->value;
$currency = $repository->find($value);
return $currency;
}

View File

@@ -1,4 +1,12 @@
<?php
/**
* CurrencyName.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
@@ -19,14 +27,15 @@ class CurrencyName extends BasicConverter implements ConverterInterface
public function convert(): TransactionCurrency
{
/** @var CurrencyRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Currency\CurrencyRepositoryInterface');
$repository = app(CurrencyRepositoryInterface::class);
if (isset($this->mapped[$this->index][$this->value])) {
$currency = $repository->find($this->mapped[$this->index][$this->value]);
} else {
$currency = $repository->findByName($this->value);
return $currency;
}
$currency = $repository->findByName($this->value);
return $currency;
}

View File

@@ -1,4 +1,12 @@
<?php
/**
* CurrencySymbol.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
@@ -19,14 +27,17 @@ class CurrencySymbol extends BasicConverter implements ConverterInterface
public function convert(): TransactionCurrency
{
/** @var CurrencyRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Currency\CurrencyRepositoryInterface');
$repository = app(CurrencyRepositoryInterface::class);
if (isset($this->mapped[$this->index][$this->value])) {
$currency = $repository->find($this->mapped[$this->index][$this->value]);
} else {
$currency = $repository->findBySymbol($this->value);
return $currency;
}
$currency = $repository->findBySymbol($this->value);
return $currency;
}
}

View File

@@ -1,4 +1,12 @@
<?php
/**
* Date.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;

View File

@@ -1,4 +1,12 @@
<?php
/**
* Description.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;

View File

@@ -1,5 +1,4 @@
<?php
declare(strict_types = 1);
/**
* INGDebetCredit.php
* Copyright (C) 2016 thegrumpydictator@gmail.com

View File

@@ -1,4 +1,12 @@
<?php
/**
* Ignore.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;

View File

@@ -1,9 +1,17 @@
<?php
/**
* OpposingAccountIban.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use FireflyIII\Crud\Account\AccountCrudInterface;
use FireflyIII\Models\Account;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
/**
* Class OpposingAccountIban
@@ -20,28 +28,37 @@ class OpposingAccountIban extends BasicConverter implements ConverterInterface
*/
public function convert()
{
/** @var AccountRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
$crud = app('FireflyIII\Crud\Account\AccountCrudInterface');
if (isset($this->mapped[$this->index][$this->value])) {
$account = $repository->find($this->mapped[$this->index][$this->value]);
$account = $crud->find($this->mapped[$this->index][$this->value]);
return $account;
} else {
if (strlen($this->value) > 0) {
}
$set = $repository->getAccounts([]);
/** @var Account $account */
foreach ($set as $account) {
if ($account->iban == $this->value) {
return $this->findAccount($crud);
}
return $account;
}
/**
* @param AccountCrudInterface $crud
*
* @return Account|string
*/
private function findAccount(AccountCrudInterface $crud)
{
if (strlen($this->value) > 0) {
$set = $crud->getAccountsByType([]);
/** @var Account $account */
foreach ($set as $account) {
if ($account->iban == $this->value) {
return $account;
}
}
return $this->value;
}
return $this->value;
}
}

View File

@@ -1,9 +1,16 @@
<?php
/**
* OpposingAccountId.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use FireflyIII\Models\Account;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
/**
* Class OpposingAccountId
@@ -19,17 +26,10 @@ class OpposingAccountId extends BasicConverter implements ConverterInterface
*/
public function convert(): Account
{
/** @var AccountRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
if (isset($this->mapped[$this->index][$this->value])) {
$account = $repository->find($this->mapped[$this->index][$this->value]);
} else {
$account = $repository->find($this->value);
}
$crud = app('FireflyIII\Crud\Account\AccountCrudInterface');
$value = isset($this->mapped[$this->index][$this->value]) ? $this->mapped[$this->index][$this->value] : $this->value;
$account = $crud->find($value);
return $account;
}
}

View File

@@ -1,9 +1,16 @@
<?php
/**
* OpposingAccountName.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use FireflyIII\Models\Account;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
/**
* Class OpposingAccountName
@@ -20,15 +27,15 @@ class OpposingAccountName extends BasicConverter implements ConverterInterface
*/
public function convert()
{
/** @var AccountRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
$crud = app('FireflyIII\Crud\Account\AccountCrudInterface');
if (isset($this->mapped[$this->index][$this->value])) {
$account = $repository->find($this->mapped[$this->index][$this->value]);
$account = $crud->find($this->mapped[$this->index][$this->value]);
return $account;
} else {
return $this->value;
}
return $this->value;
}
}

View File

@@ -1,4 +1,12 @@
<?php
/**
* RabobankDebetCredit.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;

View File

@@ -1,4 +1,12 @@
<?php
/**
* TagsComma.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
@@ -19,7 +27,7 @@ class TagsComma extends BasicConverter implements ConverterInterface
public function convert(): Collection
{
/** @var TagRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Tag\TagRepositoryInterface');
$repository = app(TagRepositoryInterface::class);
$tags = new Collection;
$strings = explode(',', $this->value);
@@ -33,8 +41,10 @@ class TagsComma extends BasicConverter implements ConverterInterface
'zoomLevel' => null,
'tagMode' => 'nothing',
];
$tag = $repository->store($data); // should validate first?
$tags->push($tag);
if (strlen($string) > 0) {
$tag = $repository->store($data); // should validate first?
$tags->push($tag);
}
}
$tags = $tags->merge($this->data['tags']);

View File

@@ -1,4 +1,12 @@
<?php
/**
* TagsSpace.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
@@ -19,7 +27,7 @@ class TagsSpace extends BasicConverter implements ConverterInterface
public function convert(): Collection
{
/** @var TagRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Tag\TagRepositoryInterface');
$repository = app(TagRepositoryInterface::class);
$tags = new Collection;
@@ -34,8 +42,10 @@ class TagsSpace extends BasicConverter implements ConverterInterface
'zoomLevel' => null,
'tagMode' => 'nothing',
];
$tag = $repository->store($data); // should validate first?
$tags->push($tag);
if (strlen($string) > 0) {
$tag = $repository->store($data); // should validate first?
$tags->push($tag);
}
}
$tags = $tags->merge($this->data['tags']);

View File

@@ -1,4 +1,12 @@
<?php
/**
* Data.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv;
@@ -72,7 +80,8 @@ class Data
}
/**
* FIXME may return null
* FIXxME may return null
*
* @return string
*/
public function getCsvFileLocation(): string
@@ -91,7 +100,8 @@ class Data
}
/**
* FIXME may return null
* FIXxME may return null
*
* @return string
*/
public function getDateFormat(): string
@@ -110,7 +120,8 @@ class Data
}
/**
* FIXME may return null
* FIXxME may return null
*
* @return string
*/
public function getDelimiter(): string

View File

@@ -1,9 +1,16 @@
<?php
/**
* Importer.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv;
use Auth;
use Config;
use FireflyIII\Events\TransactionJournalStored;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Csv\Converter\ConverterInterface;
@@ -109,7 +116,6 @@ class Importer
foreach ($this->data->getReader() as $index => $row) {
if ($this->parseRow($index)) {
Log::debug('--- Importing row ' . $index);
$this->rows++;
$result = $this->importRow($row);
if (!($result instanceof TransactionJournal)) {
@@ -120,7 +126,6 @@ class Importer
$this->journals->push($result);
event(new TransactionJournalStored($result, 0));
}
Log::debug('---');
}
}
}
@@ -226,10 +231,9 @@ class Importer
$data = $this->getFiller(); // These fields are necessary to create a new transaction journal. Some are optional
foreach ($row as $index => $value) {
$role = $this->roles[$index] ?? '_ignore';
$class = Config::get('csv.roles.' . $role . '.converter');
$field = Config::get('csv.roles.' . $role . '.field');
$class = config('csv.roles.' . $role . '.converter');
$field = config('csv.roles.' . $role . '.field');
Log::debug('Column #' . $index . ' (role: ' . $role . ') : converter ' . $class . ' stores its data into field ' . $field . ':');
// here would be the place where preprocessors would fire.
@@ -283,19 +287,17 @@ class Importer
if ($specifix->getProcessorType() == SpecifixInterface::POST_PROCESSOR) {
$specifix->setData($this->importData);
$specifix->setRow($this->importRow);
Log::debug('Now post-process specifix named ' . $className . ':');
$this->importData = $specifix->fix();
}
}
$set = Config::get('csv.post_processors');
$set = config('csv.post_processors');
foreach ($set as $className) {
/** @var PostProcessorInterface $postProcessor */
$postProcessor = app('FireflyIII\Helpers\Csv\PostProcessing\\' . $className);
$array = $this->importData ?? [];
$postProcessor->setData($array);
Log::debug('Now post-process processor named ' . $className . ':');
$this->importData = $postProcessor->process();
}
@@ -363,7 +365,7 @@ class Importer
private function getFiller()
{
$filler = [];
foreach (Config::get('csv.roles') as $role) {
foreach (config('csv.roles') as $role) {
if (isset($role['field'])) {
$fieldName = $role['field'];
$filler[$fieldName] = null;

View File

@@ -1,4 +1,12 @@
<?php
/**
* AnyAccount.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Mapper;

View File

@@ -1,4 +1,12 @@
<?php
/**
* AssetAccount.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Mapper;

View File

@@ -1,4 +1,12 @@
<?php
/**
* Bill.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Mapper;

View File

@@ -1,4 +1,12 @@
<?php
/**
* Budget.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Mapper;

View File

@@ -1,4 +1,12 @@
<?php
/**
* Category.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Mapper;

View File

@@ -1,4 +1,12 @@
<?php
/**
* MapperInterface.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Mapper;

View File

@@ -1,4 +1,12 @@
<?php
/**
* Tag.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Mapper;

View File

@@ -1,4 +1,12 @@
<?php
/**
* TransactionCurrency.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Mapper;

View File

@@ -1,4 +1,12 @@
<?php
/**
* Amount.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\PostProcessing;

View File

@@ -1,12 +1,20 @@
<?php
/**
* AssetAccount.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\PostProcessing;
use Auth;
use Carbon\Carbon;
use FireflyIII\Crud\Account\AccountCrudInterface;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
use Log;
use Validator;
/**
@@ -206,7 +214,6 @@ class AssetAccount implements PostProcessorInterface
$accounts = Auth::user()->accounts()->where('account_type_id', $accountType->id)->get();
foreach ($accounts as $entry) {
if ($entry->name == $this->data['asset-account-name']) {
Log::debug('Found an asset account with this name (#' . $entry->id . ': ******)');
return $entry;
}
@@ -231,6 +238,9 @@ class AssetAccount implements PostProcessorInterface
*/
private function parseAccountNumberString()
{
/** @var AccountCrudInterface $crud */
$crud = app(AccountCrudInterface::class);
$accountNumber = $this->data['asset-account-number'] ?? '';
$accountType = $this->getAccountType();
$accounts = Auth::user()->accounts()->with(['accountmeta'])->where('account_type_id', $accountType->id)->get();
@@ -238,14 +248,11 @@ class AssetAccount implements PostProcessorInterface
foreach ($accounts as $entry) {
$metaFieldValue = $entry->getMeta('accountNumber');
if ($metaFieldValue === $accountNumber && $metaFieldValue !== '') {
Log::debug('Found an asset account with this account number (#' . $entry->id . ')');
return $entry;
}
}
// create new if not exists and return that one:
/** @var \FireflyIII\Repositories\Account\AccountRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
$accountData = [
'name' => $accountNumber,
'accountType' => 'asset',
@@ -260,7 +267,7 @@ class AssetAccount implements PostProcessorInterface
'openingBalanceDate' => new Carbon,
'openingBalanceCurrency' => 1, // hard coded.
];
$account = $repository->store($accountData);
$account = $crud->store($accountData);
return $account;
}

View File

@@ -1,4 +1,12 @@
<?php
/**
* Bill.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\PostProcessing;

View File

@@ -1,4 +1,12 @@
<?php
/**
* Currency.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\PostProcessing;

View File

@@ -1,4 +1,12 @@
<?php
/**
* Description.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\PostProcessing;

View File

@@ -1,11 +1,18 @@
<?php
/**
* OpposingAccount.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\PostProcessing;
use Auth;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
use Log;
use Validator;
/**
@@ -54,19 +61,36 @@ class OpposingAccount implements PostProcessorInterface
$this->data = $data;
}
/**
* @return array|null
*/
protected function checkIbanString()
{
$rules = ['iban' => 'iban'];
$iban = $this->data['opposing-account-iban'];
$check = ['iban' => $iban];
$validator = Validator::make($check, $rules);
if (is_string($iban) && strlen($iban) > 0 && !$validator->fails()) {
$this->data['opposing-account-object'] = $this->parseIbanString();
return $this->data;
}
return null;
}
/**
* @return array
*/
protected function checkIdNameObject()
{
if ($this->data['opposing-account-id'] instanceof Account) { // first priority. try to find the account based on ID, if any
Log::debug('OpposingAccountPostProcession: opposing-account-id is an Account.');
$this->data['opposing-account-object'] = $this->data['opposing-account-id'];
return $this->data;
}
if ($this->data['opposing-account-iban'] instanceof Account) { // second: try to find the account based on IBAN, if any.
Log::debug('OpposingAccountPostProcession: opposing-account-iban is an Account.');
$this->data['opposing-account-object'] = $this->data['opposing-account-iban'];
return $this->data;
@@ -78,16 +102,16 @@ class OpposingAccount implements PostProcessorInterface
/**
* @return array|null
*/
protected function checkIbanString()
protected function checkNameString()
{
$rules = ['iban' => 'iban'];
$iban = $this->data['opposing-account-iban'];
$check = ['iban' => $iban];
$validator = Validator::make($check, $rules);
if (is_string($iban) && strlen($iban) > 0 && !$validator->fails()) {
if ($this->data['opposing-account-name'] instanceof Account) { // third: try to find account based on name, if any.
$this->data['opposing-account-object'] = $this->data['opposing-account-name'];
Log::debug('OpposingAccountPostProcession: opposing-account-iban is a string (******).');
$this->data['opposing-account-object'] = $this->parseIbanString();
return $this->data;
}
if (is_string($this->data['opposing-account-name'])) {
$this->data['opposing-account-object'] = $this->parseNameString();
return $this->data;
}
@@ -95,26 +119,6 @@ class OpposingAccount implements PostProcessorInterface
return null;
}
/**
* @return Account|null
*/
protected function parseIbanString()
{
// create by name and/or iban.
$accounts = Auth::user()->accounts()->get();
foreach ($accounts as $entry) {
if ($entry->iban == $this->data['opposing-account-iban']) {
Log::debug('OpposingAccountPostProcession: opposing-account-iban matches an Account.');
return $entry;
}
}
$account = $this->createAccount();
return $account;
}
/**
* @return Account|null
*/
@@ -134,7 +138,6 @@ class OpposingAccount implements PostProcessorInterface
'active' => true,
]
);
Log::debug('OpposingAccountPostProcession: created a new account.');
return $account;
}
@@ -150,34 +153,32 @@ class OpposingAccount implements PostProcessorInterface
// create expense account:
return AccountType::where('type', 'Expense account')->first();
} else {
// create revenue account:
return AccountType::where('type', 'Revenue account')->first();
}
// create revenue account:
return AccountType::where('type', 'Revenue account')->first();
}
/**
* @return array|null
* @return Account|null
*/
protected function checkNameString()
protected function parseIbanString()
{
if ($this->data['opposing-account-name'] instanceof Account) { // third: try to find account based on name, if any.
Log::debug('OpposingAccountPostProcession: opposing-account-name is an Account.');
$this->data['opposing-account-object'] = $this->data['opposing-account-name'];
// create by name and/or iban.
$accounts = Auth::user()->accounts()->get();
foreach ($accounts as $entry) {
if ($entry->iban == $this->data['opposing-account-iban']) {
return $this->data;
return $entry;
}
}
if (is_string($this->data['opposing-account-name'])) {
$account = $this->createAccount();
$this->data['opposing-account-object'] = $this->parseNameString();
return $this->data;
}
return null;
return $account;
}
/**
@@ -189,7 +190,6 @@ class OpposingAccount implements PostProcessorInterface
$accounts = Auth::user()->accounts()->where('account_type_id', $accountType->id)->get();
foreach ($accounts as $entry) {
if ($entry->name == $this->data['opposing-account-name']) {
Log::debug('Found an account with this name (#' . $entry->id . ': ******)');
return $entry;
}

View File

@@ -1,4 +1,12 @@
<?php
/**
* PostProcessorInterface.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\PostProcessing;

View File

@@ -1,9 +1,15 @@
<?php
/**
* AbnAmroDescription.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Specifix;
use Log;
/**
* Parses the description from txt files for ABN AMRO bank accounts.
*
@@ -71,7 +77,6 @@ class AbnAmroDescription extends Specifix implements SpecifixInterface
{
// See if the current description is formatted in ABN AMRO format
if (preg_match('/ABN AMRO.{24} (.*)/', $this->data['description'], $matches)) {
Log::debug('AbnAmroSpecifix: Description is structured as costs from ABN AMRO itself.');
$this->data['opposing-account-name'] = 'ABN AMRO';
$this->data['description'] = $matches[1];
@@ -91,15 +96,13 @@ class AbnAmroDescription extends Specifix implements SpecifixInterface
{
// 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->data['description'], $matches)) {
Log::debug('AbnAmroSpecifix: Description is structured as GEA or BEA format.');
// description and opposing account will be the same.
$this->data['opposing-account-name'] = $matches[4];
$this->data['description'] = $matches[4];
if ($matches[1] == 'GEA') {
$this->data['description'] = 'GEA ' . $matches[4];
} else {
$this->data['description'] = $matches[4];
}
return true;
@@ -117,7 +120,6 @@ class AbnAmroDescription extends Specifix implements SpecifixInterface
{
// See if the current description is formatted as a SEPA plain description
if (preg_match('/^SEPA(.{28})/', $this->data['description'], $matches)) {
Log::debug('AbnAmroSpecifix: Description is structured as SEPA plain description.');
$type = $matches[1];
$reference = '';
@@ -131,13 +133,13 @@ class AbnAmroDescription extends Specifix implements SpecifixInterface
foreach ($matches as $match) {
$key = $match[1];
$value = trim($match[2]);
Log::debug('SEPA: ' . $key . ' - ' . $value);
switch (strtoupper($key)) {
case 'OMSCHRIJVING':
$newDescription = $value;
break;
case 'NAAM':
$this->data['opposing-account-name'] = $name = $value;
$this->data['opposing-account-name'] = $value;
$name = $value;
break;
case 'KENMERK':
$reference = $value;
@@ -153,9 +155,8 @@ class AbnAmroDescription extends Specifix implements SpecifixInterface
// Set a new description for the current transaction. If none was given
// set the description to type, name and reference
if ($newDescription) {
$this->data['description'] = $newDescription;
} else {
$this->data['description'] = $newDescription;
if (strlen($newDescription) === 0) {
$this->data['description'] = sprintf('%s - %s (%s)', $type, $name, $reference);
}
@@ -174,7 +175,6 @@ class AbnAmroDescription extends Specifix implements SpecifixInterface
{
// See if the current description is formatted in TRTP format
if (preg_match_all('!\/([A-Z]{3,4})\/([^/]*)!', $this->data['description'], $matches, PREG_SET_ORDER)) {
Log::debug('AbnAmroSpecifix: Description is structured as TRTP format.');
$type = '';
$name = '';
@@ -211,9 +211,8 @@ class AbnAmroDescription extends Specifix implements SpecifixInterface
// Set a new description for the current transaction. If none was given
// set the description to type, name and reference
if ($newDescription) {
$this->data['description'] = $newDescription;
} else {
$this->data['description'] = $newDescription;
if (strlen($newDescription) === 0) {
$this->data['description'] = sprintf('%s - %s (%s)', $type, $name, $reference);
}
}

View File

@@ -1,4 +1,12 @@
<?php
/**
* Dummy.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Specifix;

View File

@@ -1,9 +1,15 @@
<?php
/**
* RabobankDescription.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Specifix;
use Log;
/**
* Class RabobankDescription
*
@@ -58,14 +64,10 @@ class RabobankDescription extends Specifix implements SpecifixInterface
*/
protected function rabobankFixEmptyOpposing()
{
Log::debug('RaboSpecifix: Opposing account name is "******".');
if (is_string($this->data['opposing-account-name']) && strlen($this->data['opposing-account-name']) == 0) {
Log::debug('RaboSpecifix: opp-name is zero length, changed to: "******"');
$this->data['opposing-account-name'] = $this->row[10];
Log::debug('Description was: "******".');
$this->data['description'] = trim(str_replace($this->row[10], '', $this->data['description']));
Log::debug('Description is now: "******".');
}
}

View File

@@ -1,5 +1,4 @@
<?php
declare(strict_types = 1);
/**
* Specifix.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
@@ -8,6 +7,8 @@ declare(strict_types = 1);
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Specifix;
/**

View File

@@ -1,4 +1,12 @@
<?php
/**
* SpecifixInterface.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Specifix;

View File

@@ -1,9 +1,16 @@
<?php
/**
* Wizard.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv;
use Auth;
use Config;
use Crypt;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Csv\Mapper\MapperInterface;
@@ -61,18 +68,14 @@ class Wizard implements WizardInterface
*/
public function processSelectedMapping(array $roles, array $map): array
{
$configRoles = Config::get('csv.roles');
$configRoles = config('csv.roles');
$maps = [];
if (is_array($map)) {
$keys = array_keys($map);
foreach ($keys as $index) {
if (isset($roles[$index])) {
$name = $roles[$index];
if ($configRoles[$name]['mappable']) {
$maps[$index] = $name;
}
$keys = array_keys($map);
foreach ($keys as $index) {
if (isset($roles[$index])) {
$name = $roles[$index];
if ($configRoles[$name]['mappable']) {
$maps[$index] = $name;
}
}
}
@@ -134,7 +137,7 @@ class Wizard implements WizardInterface
$options = [];
foreach ($map as $index => $columnRole) {
$mapper = Config::get('csv.roles.' . $columnRole . '.mapper');
$mapper = config('csv.roles.' . $columnRole . '.mapper');
if (is_null($mapper)) {
throw new FireflyException('Cannot map field of type "' . $columnRole . '".');
}

View File

@@ -1,4 +1,12 @@
<?php
/**
* WizardInterface.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv;

View File

@@ -1,4 +1,12 @@
<?php
/**
* FiscalHelper.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers;
@@ -24,11 +32,7 @@ class FiscalHelper implements FiscalHelperInterface
*/
public function __construct()
{
if (Preferences::get('customFiscalYear', 0)->data) {
$this->useCustomFiscalYear = true;
} else {
$this->useCustomFiscalYear = false;
}
$this->useCustomFiscalYear = Preferences::get('customFiscalYear', false)->data;
}
/**
@@ -44,9 +48,10 @@ class FiscalHelper implements FiscalHelperInterface
// add 1 year and sub 1 day
$endDate->addYear();
$endDate->subDay();
} else {
$endDate->endOfYear();
return $endDate;
}
$endDate->endOfYear();
return $endDate;
@@ -70,9 +75,10 @@ class FiscalHelper implements FiscalHelperInterface
if ($startDate > $date) {
$startDate->subYear();
}
} else {
$startDate->startOfYear();
return $startDate;
}
$startDate->startOfYear();
return $startDate;
}

View File

@@ -1,4 +1,12 @@
<?php
/**
* FiscalHelperInterface.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers;

View File

@@ -1,10 +1,17 @@
<?php
/**
* Help.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Help;
use Cache;
use League\CommonMark\CommonMarkConverter;
use Log;
use Requests;
use Route;
@@ -44,11 +51,9 @@ class Help implements HelpInterface
'title' => $title,
];
Log::debug('Going to get from Github: ' . $uri);
$result = Requests::get($uri);
Log::debug('Status code was ' . $result->status_code . '.');
if ($result->status_code === 200) {
$content['text'] = $result->body;
@@ -56,7 +61,6 @@ class Help implements HelpInterface
if (strlen(trim($content['text'])) == 0) {
Log::debug('No actual help text for this route (even though a page was found).');
$content['text'] = '<p>' . strval(trans('firefly.route_has_no_help')) . '</p>';
}
$converter = new CommonMarkConverter();

View File

@@ -1,4 +1,12 @@
<?php
/**
* HelpInterface.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Help;

View File

@@ -1,5 +1,4 @@
<?php
declare(strict_types = 1);
/**
* AccountReportHelper.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
@@ -8,6 +7,8 @@ declare(strict_types = 1);
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Report;
use Carbon\Carbon;
@@ -24,9 +25,62 @@ use Illuminate\Support\Collection;
*/
class AccountReportHelper implements AccountReportHelperInterface
{
/**
* @param Account $account
* @param Collection $startSet
* @param Collection $endSet
* @param Collection $backupSet
*
* @return Account
*/
public static function reportFilter(Account $account, Collection $startSet, Collection $endSet, Collection $backupSet)
{
// The balance for today always incorporates transactions made on today. So to get todays "start" balance, we sub one day.
$account->startBalance = '0';
$account->endBalance = '0';
$currentStart = $startSet->filter(
function (Account $entry) use ($account) {
return $account->id == $entry->id;
}
);
$currentBackup = $backupSet->filter( // grab entry from current backup as well:
function (Account $entry) use ($account) {
return $account->id == $entry->id;
}
);
// first try to set from backup
if (!is_null($currentBackup->first())) {
$account->startBalance = $currentBackup->first()->balance;
}
// overrule with data from start
if (!is_null($currentStart->first())) {
$account->startBalance = $currentStart->first()->balance;
}
$currentEnd = $endSet->filter(
function (Account $entry) use ($account) {
return $account->id == $entry->id;
}
);
if (!is_null($currentEnd->first())) {
$account->endBalance = $currentEnd->first()->balance;
}
return $account;
}
/**
* This method generates a full report for the given period on all
* given accounts
* given accounts.
*
* a special consideration for accounts that did exist on this exact day.
* we also grab the balance from today just in case, to see if that changes things.
* it's a fall back for users who (rightly so) start keeping score at the first of
* the month and find the first report lacking / broken.
*
* @param Carbon $start
* @param Carbon $end
@@ -40,88 +94,18 @@ class AccountReportHelper implements AccountReportHelperInterface
$endAmount = '0';
$diff = '0';
$ids = $accounts->pluck('id')->toArray();
$yesterday = clone $start;
$yesterday = clone $start;
$yesterday->subDay();
// get balances for start.
$startSet = Account::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id')
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->whereIn('accounts.id', $ids)
->whereNull('transaction_journals.deleted_at')
->whereNull('transactions.deleted_at')
->where('transaction_journals.date', '<=', $yesterday->format('Y-m-d'))
->groupBy('accounts.id')
->get(['accounts.id', DB::raw('SUM(`transactions`.`amount`) as `balance`')]);
// a special consideration for accounts that did exist on this exact day.
// we also grab the balance from today just in case, to see if that changes things.
// it's a fall back for users who (rightly so) start keeping score at the first of
// the month and find the first report lacking / broken.
$backupSet = Account::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id')
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->whereIn('accounts.id', $ids)
->whereNull('transaction_journals.deleted_at')
->whereNull('transactions.deleted_at')
->where('transaction_journals.date', '<=', $start->format('Y-m-d'))
->groupBy('accounts.id')
->get(['accounts.id', DB::raw('SUM(`transactions`.`amount`) as `balance`')]);
// and end:
$endSet = Account::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id')
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->whereIn('accounts.id', $ids)
->whereNull('transaction_journals.deleted_at')
->whereNull('transactions.deleted_at')
->where('transaction_journals.date', '<=', $end->format('Y-m-d'))
->groupBy('accounts.id')
->get(['accounts.id', DB::raw('SUM(`transactions`.`amount`) as `balance`')]);
$startSet = $this->getSet($ids, $yesterday); // get balances for start.
$backupSet = $this->getSet($ids, $start);
$endSet = $this->getSet($ids, $end);
$accounts->each(
function (Account $account) use ($startSet, $endSet, $backupSet) {
/**
* The balance for today always incorporates transactions
* made on today. So to get todays "start" balance, we sub one
* day.
*/
//
$account->startBalance = '0';
$account->endBalance = '0';
$currentStart = $startSet->filter(
function (Account $entry) use ($account) {
return $account->id == $entry->id;
}
);
// grab entry from current backup as well:
$currentBackup = $backupSet->filter(
function (Account $entry) use ($account) {
return $account->id == $entry->id;
}
);
if ($currentStart->first()) {
$account->startBalance = $currentStart->first()->balance;
} else {
if (is_null($currentStart->first()) && !is_null($currentBackup->first())) {
$account->startBalance = $currentBackup->first()->balance;
}
}
$currentEnd = $endSet->filter(
function (Account $entry) use ($account) {
return $account->id == $entry->id;
}
);
if ($currentEnd->first()) {
$account->endBalance = $currentEnd->first()->balance;
}
return self::reportFilter($account, $startSet, $endSet, $backupSet);
}
);
// summarize:
foreach ($accounts as $account) {
$startAmount = bcadd($startAmount, $account->startBalance);
@@ -137,4 +121,22 @@ class AccountReportHelper implements AccountReportHelperInterface
return $object;
}
/**
* @param array $ids
* @param Carbon $date
*
* @return Collection
*/
private function getSet(array $ids, Carbon $date): Collection
{
return Account::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id')
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->whereIn('accounts.id', $ids)
->whereNull('transaction_journals.deleted_at')
->whereNull('transactions.deleted_at')
->where('transaction_journals.date', '<=', $date->format('Y-m-d'))
->groupBy('accounts.id')
->get(['accounts.id', DB::raw('SUM(`transactions`.`amount`) as `balance`')]);
}
}

View File

@@ -1,5 +1,4 @@
<?php
declare(strict_types = 1);
/**
* AccountReportHelperInterface.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
@@ -8,6 +7,8 @@ declare(strict_types = 1);
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Report;
use Carbon\Carbon;

View File

@@ -1,5 +1,4 @@
<?php
declare(strict_types = 1);
/**
* BalanceReportHelper.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
@@ -8,22 +7,25 @@ declare(strict_types = 1);
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Report;
use Auth;
use Carbon\Carbon;
use DB;
use FireflyIII\Helpers\Collection\Balance;
use FireflyIII\Helpers\Collection\BalanceEntry;
use FireflyIII\Helpers\Collection\BalanceHeader;
use FireflyIII\Helpers\Collection\BalanceLine;
use FireflyIII\Models\Budget;
use FireflyIII\Models\Budget as BudgetModel;
use FireflyIII\Models\LimitRepetition;
use FireflyIII\Models\Tag;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
use Illuminate\Database\Query\JoinClause;
use Illuminate\Support\Collection;
/**
* Class BalanceReportHelper
*
@@ -34,20 +36,16 @@ class BalanceReportHelper implements BalanceReportHelperInterface
/** @var BudgetRepositoryInterface */
protected $budgetRepository;
/** @var TagRepositoryInterface */
protected $tagRepository;
/**
* ReportHelper constructor.
*
*
* @param BudgetRepositoryInterface $budgetRepository
* @param TagRepositoryInterface $tagRepository
*/
public function __construct(BudgetRepositoryInterface $budgetRepository, TagRepositoryInterface $tagRepository)
public function __construct(BudgetRepositoryInterface $budgetRepository)
{
$this->budgetRepository = $budgetRepository;
$this->tagRepository = $tagRepository;
}
@@ -61,56 +59,105 @@ class BalanceReportHelper implements BalanceReportHelperInterface
public function getBalanceReport(Carbon $start, Carbon $end, Collection $accounts): Balance
{
$balance = new Balance;
// build a balance header:
$header = new BalanceHeader;
$budgets = $this->budgetRepository->getBudgetsAndLimitsInRange($start, $end);
$spentData = $this->budgetRepository->spentPerBudgetPerAccount($budgets, $accounts, $start, $end);
$header = new BalanceHeader;
$limitRepetitions = $this->budgetRepository->getAllBudgetLimitRepetitions($start, $end);
foreach ($accounts as $account) {
$header->addAccount($account);
}
/** @var BudgetModel $budget */
foreach ($budgets as $budget) {
$balance->addBalanceLine($this->createBalanceLine($budget, $accounts, $spentData));
/** @var LimitRepetition $repetition */
foreach ($limitRepetitions as $repetition) {
$budget = $this->budgetRepository->find($repetition->budget_id);
$line = $this->createBalanceLine($budget, $repetition, $accounts);
$balance->addBalanceLine($line);
}
$noBudgetLine = $this->createNoBudgetLine($accounts, $start, $end);
$coveredByTagLine = $this->createTagsBalanceLine($accounts, $start, $end);
$leftUnbalancedLine = $this->createLeftUnbalancedLine($noBudgetLine, $coveredByTagLine);
$balance->addBalanceLine($this->createEmptyBalanceLine($accounts, $spentData));
$balance->addBalanceLine($this->createTagsBalanceLine($accounts, $start, $end));
$balance->addBalanceLine($this->createDifferenceBalanceLine($accounts, $spentData, $start, $end));
$balance->addBalanceLine($noBudgetLine);
$balance->addBalanceLine($coveredByTagLine);
$balance->addBalanceLine($leftUnbalancedLine);
$balance->setBalanceHeader($header);
// remove budgets without expenses from balance lines:
$balance = $this->removeUnusedBudgets($balance);
return $balance;
}
/**
* This method collects all transfers that are part of a "balancing act" tag
* and groups the amounts of those transfers by their destination account.
*
* This is used to indicate which expenses, usually outside of budgets, have been
* corrected by transfers from a savings account.
*
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
private function allCoveredByBalancingActs(Collection $accounts, Carbon $start, Carbon $end): Collection
{
$ids = $accounts->pluck('id')->toArray();
$set = Auth::user()->tags()
->leftJoin('tag_transaction_journal', 'tag_transaction_journal.tag_id', '=', 'tags.id')
->leftJoin('transaction_journals', 'tag_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
->leftJoin('transaction_types', 'transaction_journals.transaction_type_id', '=', 'transaction_types.id')
->leftJoin(
'transactions AS t_source', function (JoinClause $join) {
$join->on('transaction_journals.id', '=', 't_source.transaction_journal_id')->where('t_source.amount', '<', 0);
}
)
->leftJoin(
'transactions AS t_destination', function (JoinClause $join) {
$join->on('transaction_journals.id', '=', 't_destination.transaction_journal_id')->where('t_destination.amount', '>', 0);
}
)
->where('tags.tagMode', 'balancingAct')
->where('transaction_types.type', TransactionType::TRANSFER)
->where('transaction_journals.date', '>=', $start->format('Y-m-d'))
->where('transaction_journals.date', '<=', $end->format('Y-m-d'))
->whereNull('transaction_journals.deleted_at')
->whereIn('t_source.account_id', $ids)
->whereIn('t_destination.account_id', $ids)
->groupBy('t_destination.account_id')
->get(
[
't_destination.account_id',
DB::raw('SUM(`t_destination`.`amount`) as `sum`'),
]
);
return $set;
}
/**
* @param Budget $budget
* @param Collection $accounts
* @param Collection $spentData
* @param Budget $budget
* @param LimitRepetition $repetition
* @param Collection $accounts
*
* @return BalanceLine
*/
private function createBalanceLine(BudgetModel $budget, Collection $accounts, Collection $spentData): BalanceLine
private function createBalanceLine(Budget $budget, LimitRepetition $repetition, Collection $accounts): BalanceLine
{
$line = new BalanceLine;
$line = new BalanceLine;
$budget->amount = $repetition->amount;
$line->setBudget($budget);
$line->setStartDate($repetition->startdate);
$line->setEndDate($repetition->enddate);
// loop accounts:
foreach ($accounts as $account) {
$balanceEntry = new BalanceEntry;
$balanceEntry->setAccount($account);
// get spent:
$entry = $spentData->filter(
function (TransactionJournal $model) use ($budget, $account) {
return $model->account_id == $account->id && $model->budget_id == $budget->id;
}
$spent = $this->budgetRepository->spentInPeriod(
new Collection([$budget]), new Collection([$account]), $repetition->startdate, $repetition->enddate
);
$spent = '0';
if (!is_null($entry->first())) {
$spent = $entry->first()->spent;
}
$balanceEntry->setSpent($spent);
$line->addBalanceEntry($balanceEntry);
}
@@ -119,75 +166,53 @@ class BalanceReportHelper implements BalanceReportHelperInterface
}
/**
* @param Collection $accounts
* @param Collection $spentData
* @param Carbon $start
* @param Carbon $end
*
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @param BalanceLine $noBudgetLine
* @param BalanceLine $coveredByTagLine
*
* @return BalanceLine
*/
private function createDifferenceBalanceLine(Collection $accounts, Collection $spentData, Carbon $start, Carbon $end): BalanceLine
private function createLeftUnbalancedLine(BalanceLine $noBudgetLine, BalanceLine $coveredByTagLine): BalanceLine
{
$diff = new BalanceLine;
$tagsLeft = $this->tagRepository->allCoveredByBalancingActs($accounts, $start, $end);
$line = new BalanceLine;
$line->setRole(BalanceLine::ROLE_DIFFROLE);
$noBudgetEntries = $noBudgetLine->getBalanceEntries();
$tagEntries = $coveredByTagLine->getBalanceEntries();
$diff->setRole(BalanceLine::ROLE_DIFFROLE);
foreach ($accounts as $account) {
$entry = $spentData->filter(
function (TransactionJournal $model) use ($account) {
return $model->account_id == $account->id && is_null($model->budget_id);
foreach ($noBudgetEntries as $entry) {
$account = $entry->getAccount();
$tagEntry = $tagEntries->filter(
function (BalanceEntry $current) use ($account) {
return $current->getAccount()->id === $account->id;
}
);
$spent = '0';
if (!is_null($entry->first())) {
$spent = $entry->first()->spent;
if ($tagEntry->first()) {
// found corresponding entry. As we should:
$newEntry = new BalanceEntry;
$newEntry->setAccount($account);
$spent = bcadd($tagEntry->first()->getLeft(), $entry->getSpent());
$newEntry->setSpent($spent);
$line->addBalanceEntry($newEntry);
}
$leftEntry = $tagsLeft->filter(
function (Tag $tag) use ($account) {
return $tag->account_id == $account->id;
}
);
$left = '0';
if (!is_null($leftEntry->first())) {
$left = $leftEntry->first()->sum;
}
$diffValue = bcadd($spent, $left);
// difference:
$diffEntry = new BalanceEntry;
$diffEntry->setAccount($account);
$diffEntry->setSpent($diffValue);
$diff->addBalanceEntry($diffEntry);
}
return $diff;
return $line;
}
/**
* @param Collection $accounts
* @param Collection $spentData
* @param Carbon $start
* @param Carbon $end
*
* @return BalanceLine
*/
private function createEmptyBalanceLine(Collection $accounts, Collection $spentData): BalanceLine
private function createNoBudgetLine(Collection $accounts, Carbon $start, Carbon $end): BalanceLine
{
$empty = new BalanceLine;
foreach ($accounts as $account) {
$entry = $spentData->filter(
function (TransactionJournal $model) use ($account) {
return $model->account_id == $account->id && is_null($model->budget_id);
}
);
$spent = '0';
if (!is_null($entry->first())) {
$spent = $entry->first()->spent;
}
$spent = $this->budgetRepository->spentInPeriodWithoutBudget(new Collection([$account]), $start, $end);
// budget
$budgetEntry = new BalanceEntry;
$budgetEntry->setAccount($account);
@@ -209,7 +234,7 @@ class BalanceReportHelper implements BalanceReportHelperInterface
private function createTagsBalanceLine(Collection $accounts, Carbon $start, Carbon $end): BalanceLine
{
$tags = new BalanceLine;
$tagsLeft = $this->tagRepository->allCoveredByBalancingActs($accounts, $start, $end);
$tagsLeft = $this->allCoveredByBalancingActs($accounts, $start, $end);
$tags->setRole(BalanceLine::ROLE_TAGROLE);
@@ -235,4 +260,33 @@ class BalanceReportHelper implements BalanceReportHelperInterface
return $tags;
}
/**
* @param Balance $balance
*
* @return Balance
*/
private function removeUnusedBudgets(Balance $balance): Balance
{
$set = $balance->getBalanceLines();
$newSet = new Collection;
foreach ($set as $entry) {
if (!is_null($entry->getBudget()->id)) {
$sum = '0';
foreach ($entry->getBalanceEntries() as $balanceEntry) {
$sum = bcadd($sum, $balanceEntry->getSpent());
}
if (bccomp($sum, '0') === -1) {
$newSet->push($entry);
}
continue;
}
$newSet->push($entry);
}
$balance->setBalanceLines($newSet);
return $balance;
}
}

View File

@@ -1,5 +1,4 @@
<?php
declare(strict_types = 1);
/**
* BalanceReportHelperInterface.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
@@ -8,6 +7,8 @@ declare(strict_types = 1);
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Report;
use Carbon\Carbon;

View File

@@ -1,5 +1,4 @@
<?php
declare(strict_types = 1);
/**
* BudgetReportHelper.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
@@ -8,13 +7,17 @@ declare(strict_types = 1);
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Report;
use Carbon\Carbon;
use FireflyIII\Helpers\Collection\Budget as BudgetCollection;
use FireflyIII\Helpers\Collection\BudgetLine;
use FireflyIII\Models\Budget;
use FireflyIII\Models\LimitRepetition;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use Illuminate\Support\Collection;
/**
@@ -24,6 +27,18 @@ use Illuminate\Support\Collection;
*/
class BudgetReportHelper implements BudgetReportHelperInterface
{
/** @var BudgetRepositoryInterface */
private $repository;
/**
* BudgetReportHelper constructor.
*
* @param BudgetRepositoryInterface $repository
*/
public function __construct(BudgetRepositoryInterface $repository)
{
$this->repository = $repository;
}
/**
* @param Carbon $start
@@ -35,25 +50,17 @@ class BudgetReportHelper implements BudgetReportHelperInterface
public function getBudgetReport(Carbon $start, Carbon $end, Collection $accounts): BudgetCollection
{
$object = new BudgetCollection;
/** @var \FireflyIII\Repositories\Budget\BudgetRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Budget\BudgetRepositoryInterface');
$set = $repository->getBudgets();
$allRepetitions = $repository->getAllBudgetLimitRepetitions($start, $end);
$allTotalSpent = $repository->spentAllPerDayForAccounts($accounts, $start, $end);
$set = $this->repository->getBudgets();
/** @var Budget $budget */
foreach ($set as $budget) {
$repetitions = $allRepetitions->filter(
function (LimitRepetition $rep) use ($budget) {
return $rep->budget_id == $budget->id;
}
);
$totalSpent = $allTotalSpent[$budget->id] ?? [];
$repetitions = $budget->limitrepetitions()->before($end)->after($start)->get();
// no repetition(s) for this budget:
if ($repetitions->count() == 0) {
// spent for budget in time range:
$spent = $this->repository->spentInPeriod(new Collection([$budget]), $accounts, $start, $end);
$spent = array_sum($totalSpent);
if ($spent > 0) {
$budgetLine = new BudgetLine;
$budgetLine->setBudget($budget);
@@ -63,32 +70,23 @@ class BudgetReportHelper implements BudgetReportHelperInterface
}
continue;
}
// one or more repetitions for budget:
/** @var LimitRepetition $repetition */
foreach ($repetitions as $repetition) {
$data = $this->calculateExpenses($budget, $repetition, $accounts);
$budgetLine = new BudgetLine;
$budgetLine->setBudget($budget);
$budgetLine->setRepetition($repetition);
$expenses = $this->getSumOfRange($start, $end, $totalSpent);
// 200 en -100 is 100, vergeleken met 0 === 1
// 200 en -200 is 0, vergeleken met 0 === 0
// 200 en -300 is -100, vergeleken met 0 === -1
$left = bccomp(bcadd($repetition->amount, $expenses), '0') === 1 ? bcadd($repetition->amount, $expenses) : '0';
$spent = bccomp(bcadd($repetition->amount, $expenses), '0') === 1 ? $expenses : '0';
$overspent = bccomp(bcadd($repetition->amount, $expenses), '0') === 1 ? '0' : bcadd($expenses, $repetition->amount);
$budgetLine->setLeft($left);
$budgetLine->setSpent($expenses);
$budgetLine->setOverspent($overspent);
$budgetLine->setLeft($data['left']);
$budgetLine->setSpent($data['expenses']);
$budgetLine->setOverspent($data['overspent']);
$budgetLine->setBudgeted($repetition->amount);
$object->addBudgeted($repetition->amount);
$object->addSpent($spent);
$object->addLeft($left);
$object->addOverspent($overspent);
$object->addSpent($data['spent']);
$object->addLeft($data['left']);
$object->addOverspent($data['overspent']);
$object->addBudgetLine($budgetLine);
}
@@ -96,7 +94,8 @@ class BudgetReportHelper implements BudgetReportHelperInterface
}
// stuff outside of budgets:
$noBudget = $repository->getWithoutBudgetSum($accounts, $start, $end);
$noBudget = $this->repository->spentInPeriodWithoutBudget($accounts, $start, $end);
$budgetLine = new BudgetLine;
$budgetLine->setOverspent($noBudget);
$budgetLine->setSpent($noBudget);
@@ -107,7 +106,37 @@ class BudgetReportHelper implements BudgetReportHelperInterface
}
/**
* Take the array as returned by SingleCategoryRepositoryInterface::spentPerDay and SingleCategoryRepositoryInterface::earnedByDay
* @param Carbon $start
* @param Carbon $end
* @param Collection $accounts
*
* @return Collection
*/
public function getBudgetsWithExpenses(Carbon $start, Carbon $end, Collection $accounts): Collection
{
/** @var BudgetRepositoryInterface $repository */
$repository = app(BudgetRepositoryInterface::class);
$budgets = $repository->getActiveBudgets();
$set = new Collection;
/** @var Budget $budget */
foreach ($budgets as $budget) {
$total = $repository->spentInPeriod(new Collection([$budget]), $accounts, $start, $end);
if (bccomp($total, '0') === -1) {
$set->push($budget);
}
}
$set = $set->sortBy(
function (Budget $budget) {
return $budget->name;
}
);
return $set;
}
/**
* Take the array as returned by CategoryRepositoryInterface::spentPerDay and CategoryRepositoryInterface::earnedByDay
* and sum up everything in the array in the given range.
*
* @param Carbon $start
@@ -132,4 +161,24 @@ class BudgetReportHelper implements BudgetReportHelperInterface
return $sum;
}
/**
* @param Budget $budget
* @param LimitRepetition $repetition
* @param Collection $accounts
*
* @return array
*/
private function calculateExpenses(Budget $budget, LimitRepetition $repetition, Collection $accounts): array
{
$array = [];
$expenses = $this->repository->spentInPeriod(new Collection([$budget]), $accounts, $repetition->startdate, $repetition->enddate);
$array['left'] = bccomp(bcadd($repetition->amount, $expenses), '0') === 1 ? bcadd($repetition->amount, $expenses) : '0';
$array['spent'] = bccomp(bcadd($repetition->amount, $expenses), '0') === 1 ? $expenses : '0';
$array['overspent'] = bccomp(bcadd($repetition->amount, $expenses), '0') === 1 ? '0' : bcadd($expenses, $repetition->amount);
$array['expenses'] = $expenses;
return $array;
}
}

View File

@@ -1,5 +1,4 @@
<?php
declare(strict_types = 1);
/**
* BudgetReportHelperInterface.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
@@ -8,6 +7,8 @@ declare(strict_types = 1);
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Report;
@@ -30,4 +31,14 @@ interface BudgetReportHelperInterface
* @return BudgetCollection
*/
public function getBudgetReport(Carbon $start, Carbon $end, Collection $accounts): BudgetCollection;
/**
* @param Carbon $start
* @param Carbon $end
* @param Collection $accounts
*
* @return Collection
*/
public function getBudgetsWithExpenses(Carbon $start, Carbon $end, Collection $accounts): Collection;
}

View File

@@ -1,4 +1,12 @@
<?php
/**
* ReportHelper.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Report;
@@ -11,9 +19,13 @@ use FireflyIII\Helpers\Collection\Expense;
use FireflyIII\Helpers\Collection\Income;
use FireflyIII\Helpers\FiscalHelperInterface;
use FireflyIII\Models\Bill;
use FireflyIII\Models\Category;
use FireflyIII\Models\Tag;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Query\JoinClause;
@@ -29,8 +41,6 @@ class ReportHelper implements ReportHelperInterface
/** @var BudgetRepositoryInterface */
protected $budgetRepository;
/** @var ReportQueryInterface */
protected $query;
/** @var TagRepositoryInterface */
protected $tagRepository;
@@ -38,13 +48,11 @@ class ReportHelper implements ReportHelperInterface
* ReportHelper constructor.
*
*
* @param ReportQueryInterface $query
* @param BudgetRepositoryInterface $budgetRepository
* @param TagRepositoryInterface $tagRepository
*/
public function __construct(ReportQueryInterface $query, BudgetRepositoryInterface $budgetRepository, TagRepositoryInterface $tagRepository)
public function __construct(BudgetRepositoryInterface $budgetRepository, TagRepositoryInterface $tagRepository)
{
$this->query = $query;
$this->budgetRepository = $budgetRepository;
$this->tagRepository = $tagRepository;
}
@@ -63,8 +71,8 @@ class ReportHelper implements ReportHelperInterface
*/
public function getBillReport(Carbon $start, Carbon $end, Collection $accounts): BillCollection
{
/** @var \FireflyIII\Repositories\Bill\BillRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Bill\BillRepositoryInterface');
/** @var BillRepositoryInterface $repository */
$repository = app(BillRepositoryInterface::class);
$bills = $repository->getBillsForAccounts($accounts);
$journals = $repository->getAllJournalsInRange($bills, $start, $end);
$collection = new BillCollection;
@@ -73,10 +81,10 @@ class ReportHelper implements ReportHelperInterface
foreach ($bills as $bill) {
$billLine = new BillLine;
$billLine->setBill($bill);
$billLine->setActive(intval($bill->active) == 1);
$billLine->setActive(intval($bill->active) === 1);
$billLine->setMin($bill->amount_min);
$billLine->setMax($bill->amount_max);
$billLine->setHit(false);
// is hit in period?
$entry = $journals->filter(
@@ -89,13 +97,11 @@ class ReportHelper implements ReportHelperInterface
$billLine->setTransactionJournalId($first->id);
$billLine->setAmount($first->journalAmount);
$billLine->setHit(true);
} else {
$billLine->setHit(false);
}
if (!(!$billLine->isHit() && !$billLine->isActive())) {
$collection->addBill($billLine);
}
if ($billLine->isActive()) {
$collection->addBill($billLine);
}
}
return $collection;
@@ -111,15 +117,15 @@ class ReportHelper implements ReportHelperInterface
public function getCategoryReport(Carbon $start, Carbon $end, Collection $accounts): CategoryCollection
{
$object = new CategoryCollection;
/** @var CategoryRepositoryInterface $repository */
$repository = app(CategoryRepositoryInterface::class);
$categories = $repository->getCategories();
/**
* GET CATEGORIES:
*/
/** @var \FireflyIII\Repositories\Category\CategoryRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Category\CategoryRepositoryInterface');
$set = $repository->spentForAccountsPerMonth($accounts, $start, $end);
foreach ($set as $category) {
/** @var Category $category */
foreach ($categories as $category) {
$spent = $repository->spentInPeriod(new Collection([$category]), $accounts, $start, $end);
// CategoryCollection expects the amount in $spent:
$category->spent = $spent;
$object->addCategory($category);
}
@@ -138,10 +144,14 @@ class ReportHelper implements ReportHelperInterface
public function getExpenseReport(Carbon $start, Carbon $end, Collection $accounts): Expense
{
$object = new Expense;
$set = $this->query->expense($accounts, $start, $end);
/** @var AccountRepositoryInterface $repos */
$repos = app(AccountRepositoryInterface::class);
$journals = $repos->expensesInPeriod($accounts, $start, $end);
foreach ($set as $entry) {
$object->addToTotal($entry->journalAmount); // can be positive, if it's a transfer
/** @var TransactionJournal $entry */
foreach ($journals as $entry) {
$amount = TransactionJournal::amount($entry);
$object->addToTotal($amount);
$object->addOrCreateExpense($entry);
}
@@ -160,10 +170,13 @@ class ReportHelper implements ReportHelperInterface
public function getIncomeReport(Carbon $start, Carbon $end, Collection $accounts): Income
{
$object = new Income;
$set = $this->query->income($accounts, $start, $end);
/** @var AccountRepositoryInterface $repos */
$repos = app(AccountRepositoryInterface::class);
$journals = $repos->incomesInPeriod($accounts, $start, $end);
foreach ($set as $entry) {
$object->addToTotal($entry->journalAmount);
foreach ($journals as $entry) {
$amount = TransactionJournal::amount($entry);
$object->addToTotal($amount);
$object->addOrCreateIncome($entry);
}
@@ -178,7 +191,7 @@ class ReportHelper implements ReportHelperInterface
public function listOfMonths(Carbon $date): array
{
/** @var FiscalHelperInterface $fiscalHelper */
$fiscalHelper = app('FireflyIII\Helpers\FiscalHelperInterface');
$fiscalHelper = app(FiscalHelperInterface::class);
$start = clone $date;
$start->startOfMonth();
$end = Carbon::now();
@@ -186,9 +199,7 @@ class ReportHelper implements ReportHelperInterface
$months = [];
while ($start <= $end) {
// current year:
$year = $fiscalHelper->endOfFiscalYear($start)->year;
$year = $fiscalHelper->endOfFiscalYear($start)->year; // current year
if (!isset($months[$year])) {
$months[$year] = [
'fiscal_start' => $fiscalHelper->startOfFiscalYear($start)->format('Y-m-d'),
@@ -201,7 +212,6 @@ class ReportHelper implements ReportHelperInterface
$currentEnd = clone $start;
$currentEnd->endOfMonth();
$months[$year]['months'][] = [
'formatted' => $start->formatLocalized('%B %Y'),
'start' => $start->format('Y-m-d'),
@@ -210,8 +220,7 @@ class ReportHelper implements ReportHelperInterface
'year' => $year,
];
// to make the hop to the next month properly:
$start = clone $currentEnd;
$start = clone $currentEnd; // to make the hop to the next month properly
$start->addDay();
}
@@ -259,17 +268,14 @@ class ReportHelper implements ReportHelperInterface
/** @var Tag $entry */
foreach ($set as $entry) {
// less than zero? multiply to be above zero.
$amount = $entry->amount;
$id = intval($entry->id);
if (!isset($collection[$id])) {
$collection[$id] = [
'id' => $id,
'tag' => $entry->tag,
'amount' => $amount,
];
} else {
$collection[$id]['amount'] = bcadd($collection[$id]['amount'], $amount);
}
$amount = $entry->amount;
$id = intval($entry->id);
$previousAmount = $collection[$id]['amount'] ?? '0';
$collection[$id] = [
'id' => $id,
'tag' => $entry->tag,
'amount' => bcadd($previousAmount, $amount),
];
}
// cleanup collection (match "fonts")
@@ -286,7 +292,7 @@ class ReportHelper implements ReportHelperInterface
}
/**
* Take the array as returned by SingleCategoryRepositoryInterface::spentPerDay and SingleCategoryRepositoryInterface::earnedByDay
* Take the array as returned by CategoryRepositoryInterface::spentPerDay and CategoryRepositoryInterface::earnedByDay
* and sum up everything in the array in the given range.
*
* @param Carbon $start

View File

@@ -1,4 +1,12 @@
<?php
/**
* ReportHelperInterface.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Report;

View File

@@ -1,179 +0,0 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Report;
use Auth;
use Carbon\Carbon;
use DB;
use FireflyIII\Models\TransactionType;
use Illuminate\Database\Query\JoinClause;
use Illuminate\Support\Collection;
/**
* Class ReportQuery
*
* @package FireflyIII\Helpers\Report
*/
class ReportQuery implements ReportQueryInterface
{
/**
* Returns an array of the amount of money spent in the given accounts (on withdrawals, opening balances and transfers)
* grouped by month like so: "2015-01" => '123.45'
*
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return array
*/
public function earnedPerMonth(Collection $accounts, Carbon $start, Carbon $end): array
{
$ids = $accounts->pluck('id')->toArray();
$query = Auth::user()->transactionjournals()
->leftJoin(
'transactions AS t_from', function (JoinClause $join) {
$join->on('transaction_journals.id', '=', 't_from.transaction_journal_id')->where('t_from.amount', '<', 0);
}
)
->leftJoin(
'transactions AS t_to', function (JoinClause $join) {
$join->on('transaction_journals.id', '=', 't_to.transaction_journal_id')->where('t_to.amount', '>', 0);
}
)
->whereIn('t_to.account_id', $ids)
->whereNotIn('t_from.account_id', $ids)
->after($start)
->before($end)
->transactionTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER, TransactionType::OPENING_BALANCE])
->groupBy('dateFormatted')
->get(
[
DB::raw('DATE_FORMAT(`transaction_journals`.`date`,"%Y-%m") AS `dateFormatted`'),
DB::raw('SUM(`t_to`.`amount`) AS `sum`'),
]
);
$array = [];
foreach ($query as $result) {
$array[$result->dateFormatted] = $result->sum;
}
return $array;
}
/**
* This method returns all the "out" transaction journals for the given account and given period. The amount
* is stored in "journalAmount".
*
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function expense(Collection $accounts, Carbon $start, Carbon $end): Collection
{
$ids = $accounts->pluck('id')->toArray();
$set = Auth::user()->transactionjournals()
->leftJoin(
'transactions as t_from', function (JoinClause $join) {
$join->on('t_from.transaction_journal_id', '=', 'transaction_journals.id')->where('t_from.amount', '<', 0);
}
)
->leftJoin(
'transactions as t_to', function (JoinClause $join) {
$join->on('t_to.transaction_journal_id', '=', 'transaction_journals.id')->where('t_to.amount', '>', 0);
}
)
->leftJoin('accounts', 't_to.account_id', '=', 'accounts.id')
->transactionTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER])
->before($end)
->after($start)
->whereIn('t_from.account_id', $ids)
->whereNotIn('t_to.account_id', $ids)
->get(['transaction_journals.*', 't_from.amount as journalAmount', 'accounts.id as account_id', 'accounts.name as account_name']);
return $set;
}
/**
* This method returns all the "in" transaction journals for the given account and given period. The amount
* is stored in "journalAmount".
*
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function income(Collection $accounts, Carbon $start, Carbon $end): Collection
{
$ids = $accounts->pluck('id')->toArray();
$set = Auth::user()->transactionjournals()
->leftJoin(
'transactions as t_from', function (JoinClause $join) {
$join->on('t_from.transaction_journal_id', '=', 'transaction_journals.id')->where('t_from.amount', '<', 0);
}
)
->leftJoin(
'transactions as t_to', function (JoinClause $join) {
$join->on('t_to.transaction_journal_id', '=', 'transaction_journals.id')->where('t_to.amount', '>', 0);
}
)
->leftJoin('accounts', 't_from.account_id', '=', 'accounts.id')
->transactionTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER])
->before($end)
->after($start)
->whereIn('t_to.account_id', $ids)
->whereNotIn('t_from.account_id', $ids)
->get(['transaction_journals.*', 't_to.amount as journalAmount', 'accounts.id as account_id', 'accounts.name as account_name']);
return $set;
}
/**
* Returns an array of the amount of money spent in the given accounts (on withdrawals, opening balances and transfers)
* grouped by month like so: "2015-01" => '123.45'
*
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return array
*/
public function spentPerMonth(Collection $accounts, Carbon $start, Carbon $end): array
{
$ids = $accounts->pluck('id')->toArray();
$query = Auth::user()->transactionjournals()
->leftJoin(
'transactions AS t_from', function (JoinClause $join) {
$join->on('transaction_journals.id', '=', 't_from.transaction_journal_id')->where('t_from.amount', '<', 0);
}
)
->leftJoin(
'transactions AS t_to', function (JoinClause $join) {
$join->on('transaction_journals.id', '=', 't_to.transaction_journal_id')->where('t_to.amount', '>', 0);
}
)
->whereIn('t_from.account_id', $ids)
->whereNotIn('t_to.account_id', $ids)
->after($start)
->before($end)
->transactionTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER, TransactionType::OPENING_BALANCE])
->groupBy('dateFormatted')
->get(
[
DB::raw('DATE_FORMAT(`transaction_journals`.`date`,"%Y-%m") AS `dateFormatted`'),
DB::raw('SUM(`t_from`.`amount`) AS `sum`'),
]
);
$array = [];
foreach ($query as $result) {
$array[$result->dateFormatted] = $result->sum;
}
return $array;
}
}

View File

@@ -1,66 +0,0 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Report;
use Carbon\Carbon;
use Illuminate\Support\Collection;
/**
* Interface ReportQueryInterface
*
* @package FireflyIII\Helpers\Report
*/
interface ReportQueryInterface
{
/**
* Returns an array of the amount of money spent in the given accounts (on withdrawals, opening balances and transfers)
* grouped by month like so: "2015-01" => '123.45'
*
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return array
*/
public function earnedPerMonth(Collection $accounts, Carbon $start, Carbon $end): array;
/**
* This method returns all the "out" transaction journals for the given account and given period. The amount
* is stored in "journalAmount".
*
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function expense(Collection $accounts, Carbon $start, Carbon $end): Collection;
/**
* This method returns all the "in" transaction journals for the given account and given period. The amount
* is stored in "journalAmount".
*
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function income(Collection $accounts, Carbon $start, Carbon $end): Collection;
/**
* Returns an array of the amount of money spent in the given accounts (on withdrawals, opening balances and transfers)
* grouped by month like so: "2015-01" => '123.45'
*
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return array
*/
public function spentPerMonth(Collection $accounts, Carbon $start, Carbon $end): array;
}