Merge branch 'develop' of github.com:JC5/firefly-iii into develop

This commit is contained in:
James Cole
2016-02-16 13:25:48 +01:00
35 changed files with 744 additions and 516 deletions
+4 -7
View File
@@ -2,6 +2,7 @@
declare(strict_types = 1);
namespace FireflyIII\Exceptions;
use Auth;
use ErrorException;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
@@ -13,7 +14,7 @@ use Mail;
use Request;
use Swift_TransportException;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Auth;
/**
* Class Handler
*
@@ -68,14 +69,11 @@ class Handler extends ExceptionHandler
if ($exception instanceof FireflyException || $exception instanceof ErrorException) {
// log
Log::error($exception->getMessage());
// mail?
try {
$email = env('SITE_OWNER');
$user = Auth::user();
$args = [
$user = Auth::user();
$args = [
'errorMessage' => $exception->getMessage(),
'stacktrace' => $exception->getTraceAsString(),
'file' => $exception->getFile(),
@@ -99,7 +97,6 @@ class Handler extends ExceptionHandler
// could also not mail! :o
Log::error($e->getMessage());
}
}
parent::report($exception);
+1 -1
View File
@@ -20,7 +20,7 @@ class AmountComma extends BasicConverter implements ConverterInterface
$value = str_replace(',', '.', $this->value);
if (is_numeric($value)) {
return floatval($value);
return $value;
}
return '0';
+21 -12
View File
@@ -3,8 +3,8 @@ declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use Auth;
use Carbon\Carbon;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
/**
* Class AssetAccountIban
@@ -27,20 +27,29 @@ class AssetAccountIban extends BasicConverter implements ConverterInterface
}
if (strlen($this->value) > 0) {
// find or create new account:
$account = $this->findAccount();
$accountType = AccountType::where('type', 'Asset account')->first();
$account = $this->findAccount();
if (is_null($account)) {
// create it if doesn't exist.
$account = Account::firstOrCreateEncrypted( // TODO use repository
[
'name' => $this->value,
'iban' => $this->value,
'user_id' => Auth::user()->id,
'account_type_id' => $accountType->id,
'active' => 1,
]
);
$repository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
$accountData = [
'name' => $this->value,
'accountType' => 'asset',
'virtualBalance' => 0,
'virtualBalanceCurrency' => 1, // hard coded.
'active' => true,
'user' => Auth::user()->id,
'iban' => null,
'accountNumber' => $this->value,
'accountRole' => null,
'openingBalance' => 0,
'openingBalanceDate' => new Carbon,
'openingBalanceCurrency' => 1, // hard coded.
];
$account = $repository->store($accountData);
}
return $account;
+20 -10
View File
@@ -3,6 +3,7 @@ declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use Auth;
use Carbon\Carbon;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
@@ -26,7 +27,6 @@ class AssetAccountName extends BasicConverter implements ConverterInterface
return $account;
}
// find or create new account:
$accountType = AccountType::where('type', 'Asset account')->first();
$set = Auth::user()->accounts()->accountTypeIn(['Asset account', 'Default account'])->get();
/** @var Account $entry */
foreach ($set as $entry) {
@@ -36,15 +36,25 @@ class AssetAccountName extends BasicConverter implements ConverterInterface
}
// create it if doesnt exist.
$account = Account::firstOrCreateEncrypted( // TODO use repository
[
'name' => $this->value,
'iban' => '',
'user_id' => Auth::user()->id,
'account_type_id' => $accountType->id,
'active' => 1,
]
);
$repository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
$accountData = [
'name' => $this->value,
'accountType' => 'asset',
'virtualBalance' => 0,
'virtualBalanceCurrency' => 1, // hard coded.
'active' => true,
'user' => Auth::user()->id,
'iban' => null,
'accountNumber' => $this->value,
'accountRole' => null,
'openingBalance' => 0,
'openingBalanceDate' => new Carbon,
'openingBalanceCurrency' => 1, // hard coded.
];
$account = $repository->store($accountData);
return $account;
}
@@ -48,7 +48,7 @@ class AssetAccountNumber extends BasicConverter implements ConverterInterface
'name' => $this->value,
'accountType' => 'asset',
'virtualBalance' => 0,
'virtualBalanceCurrency' => 1, // TODO hard coded.
'virtualBalanceCurrency' => 1, // hard coded.
'active' => true,
'user' => Auth::user()->id,
'iban' => null,
@@ -56,7 +56,7 @@ class AssetAccountNumber extends BasicConverter implements ConverterInterface
'accountRole' => null,
'openingBalance' => 0,
'openingBalanceDate' => new Carbon,
'openingBalanceCurrency' => 1, // TODO hard coded.
'openingBalanceCurrency' => 1, // hard coded.
];
+3 -8
View File
@@ -20,15 +20,10 @@ class BudgetName extends BasicConverter implements ConverterInterface
{
// is mapped? Then it's easy!
if (isset($this->mapped[$this->index][$this->value])) {
$budget = Auth::user()->budgets()->find($this->mapped[$this->index][$this->value]);
$budget = Auth::user()->budgets()->find($this->mapped[$this->index][$this->value]); // see issue #180
} else {
$budget = Budget::firstOrCreateEncrypted( // TODO use repository
[
'name' => $this->value,
'user_id' => Auth::user()->id,
'active' => true,
]
);
$repository = app('FireflyIII\Repositories\Budget\BudgetRepositoryInterface');
$budget = $repository->store(['name' => $this->value, 'user' => Auth::user()->id]);
}
return $budget;
+1 -1
View File
@@ -22,7 +22,7 @@ class CategoryName extends BasicConverter implements ConverterInterface
if (isset($this->mapped[$this->index][$this->value])) {
$category = Auth::user()->categories()->find($this->mapped[$this->index][$this->value]);
} else {
$category = Category::firstOrCreateEncrypted( // TODO use repository
$category = Category::firstOrCreateEncrypted( // See issue #180
[
'name' => $this->value,
'user_id' => Auth::user()->id,
+1 -1
View File
@@ -23,7 +23,7 @@ class TagsComma extends BasicConverter implements ConverterInterface
$strings = explode(',', $this->value);
foreach ($strings as $string) {
$tag = Tag::firstOrCreateEncrypted( // TODO use repository
$tag = Tag::firstOrCreateEncrypted( // See issue #180
[
'tag' => $string,
'tagMode' => 'nothing',
+1 -1
View File
@@ -23,7 +23,7 @@ class TagsSpace extends BasicConverter implements ConverterInterface
$strings = explode(' ', $this->value);
foreach ($strings as $string) {
$tag = Tag::firstOrCreateEncrypted( // TODO use repository
$tag = Tag::firstOrCreateEncrypted( // See issue #180
[
'tag' => $string,
'tagMode' => 'nothing',
@@ -154,9 +154,9 @@ class AssetAccount implements PostProcessorInterface
$name = $this->data['asset-account-name'] ?? '';
$iban = $this->data['asset-account-iban'] ?? '';
// create if not exists: // TODO should be through repository.
// create if not exists: // See issue #180
$name = strlen($name) > 0 ? $name : $iban;
$account = Account::firstOrCreateEncrypted( // TODO use repository
$account = Account::firstOrCreateEncrypted(
[
'user_id' => Auth::user()->id,
'account_type_id' => $accountType->id,
@@ -211,7 +211,8 @@ class AssetAccount implements PostProcessorInterface
return $entry;
}
}
// create if not exists: // TODO use repository
// create if not exists:
// See issue #180
$account = Account::firstOrCreateEncrypted(
[
'user_id' => Auth::user()->id,
@@ -249,7 +250,7 @@ class AssetAccount implements PostProcessorInterface
'name' => $accountNumber,
'accountType' => 'asset',
'virtualBalance' => 0,
'virtualBalanceCurrency' => 1, // TODO hard coded.
'virtualBalanceCurrency' => 1, // hard coded.
'active' => true,
'user' => Auth::user()->id,
'iban' => null,
@@ -257,7 +258,7 @@ class AssetAccount implements PostProcessorInterface
'accountRole' => null,
'openingBalance' => 0,
'openingBalanceDate' => new Carbon,
'openingBalanceCurrency' => 1, // TODO hard coded.
'openingBalanceCurrency' => 1, // hard coded.
];
$account = $repository->store($accountData);
@@ -125,7 +125,7 @@ class OpposingAccount implements PostProcessorInterface
// create if not exists:
$name = is_string($this->data['opposing-account-name']) && strlen($this->data['opposing-account-name']) > 0 ? $this->data['opposing-account-name']
: $this->data['opposing-account-iban'];
$account = Account::firstOrCreateEncrypted( // TODO use repository
$account = Account::firstOrCreateEncrypted( // See issue #180
[
'user_id' => Auth::user()->id,
'account_type_id' => $accountType->id,
@@ -195,7 +195,7 @@ class OpposingAccount implements PostProcessorInterface
}
}
// create if not exists:
$account = Account::firstOrCreateEncrypted( // TODO use repository
$account = Account::firstOrCreateEncrypted( // See issue #180
[
'user_id' => Auth::user()->id,
'account_type_id' => $accountType->id,
@@ -23,6 +23,10 @@ use stdClass;
*/
class CategoryController extends Controller
{
const MAKE_POSITIVE = -1;
const KEEP_POSITIVE = 1;
/** @var \FireflyIII\Generator\Chart\Category\CategoryChartGeneratorInterface */
protected $generator;
@@ -134,32 +138,8 @@ class CategoryController extends Controller
return $category->name;
}
);
$entries = new Collection;
while ($start < $end) { // filter the set:
$row = [clone $start];
$currentSet = $set->filter( // get possibly relevant entries from the big $set
function (Category $category) use ($start) {
return $category->dateFormatted == $start->format('Y-m');
}
);
/** @var Category $category */
foreach ($categories as $category) { // check for each category if its in the current set.
$entry = $currentSet->filter( // if its in there, use the value.
function (Category $cat) use ($category) {
return ($cat->id == $category->id);
}
)->first();
if (!is_null($entry)) {
$row[] = round($entry->earned, 2);
} else {
$row[] = 0;
}
}
$entries->push($row);
$start->addMonth();
}
$data = $this->generator->earnedInPeriod($categories, $entries);
$entries = $this->filterCollection($start, $end, $set, $categories);
$data = $this->generator->earnedInPeriod($categories, $entries);
$cache->store($data);
return $data;
@@ -340,42 +320,58 @@ class CategoryController extends Controller
return Response::json($cache->get()); // @codeCoverageIgnore
}
$set = $repository->spentForAccountsPerMonth($accounts, $start, $end);
$categories = $set->unique('id')->sortBy(
function (Category $category) {
return $category->name;
}
);
$entries = new Collection;
$entries = $this->filterCollection($start, $end, $set, $categories);
$data = $this->generator->spentInPeriod($categories, $entries);
$cache->store($data);
return $data;
}
/**
* @param Carbon $start
* @param Carbon $end
* @param Collection $set
* @param Collection $categories
*
* @return Collection
*/
private function filterCollection(Carbon $start, Carbon $end, Collection $set, Collection $categories): Collection
{
$entries = new Collection;
while ($start < $end) { // filter the set:
$row = [clone $start];
$currentSet = $set->filter(// get possibly relevant entries from the big $set
$currentSet = $set->filter( // get possibly relevant entries from the big $set
function (Category $category) use ($start) {
return $category->dateFormatted == $start->format('Y-m');
}
);
/** @var Category $category */
foreach ($categories as $category) {// check for each category if its in the current set.
$entry = $currentSet->filter(// if its in there, use the value.
foreach ($categories as $category) { // check for each category if its in the current set.
$entry = $currentSet->filter( // if its in there, use the value.
function (Category $cat) use ($category) {
return ($cat->id == $category->id);
}
)->first();
if (!is_null($entry)) {
$row[] = round(($entry->spent * -1), 2);
$row[] = round($entry->earned, 2);
} else {
$row[] = 0;
}
}
$entries->push($row);
$start->addMonth();
}
$data = $this->generator->spentInPeriod($categories, $entries);
$cache->store($data);
return $data;
return $entries;
}
/**
@@ -419,5 +415,4 @@ class CategoryController extends Controller
return $data;
}
}
+2 -2
View File
@@ -187,8 +187,8 @@ class PiggyBankController extends Controller
'name' => $account->name,
'balance' => Steam::balance($account, $end, true),
'leftForPiggyBanks' => $repository->leftOnAccount($account, $end),
'sumOfSaved' => $piggyBank->savedSoFar,
'sumOfTargets' => round($piggyBank->targetamount, 2),
'sumOfSaved' => strval($piggyBank->savedSoFar),
'sumOfTargets' => strval(round($piggyBank->targetamount, 2)),
'leftToSave' => $piggyBank->leftToSave,
];
} else {
+2 -43
View File
@@ -4,7 +4,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Controllers;
use Auth;
use Carbon\Carbon;
use FireflyIII\Http\Requests\TagFormRequest;
use FireflyIII\Models\Preference;
use FireflyIII\Models\Tag;
@@ -233,26 +232,7 @@ class TagController extends Controller
*/
public function store(TagFormRequest $request, TagRepositoryInterface $repository)
{
if (Input::get('setTag') == 'true') {
$latitude = $request->get('latitude');
$longitude = $request->get('longitude');
$zoomLevel = $request->get('zoomLevel');
} else {
$latitude = null;
$longitude = null;
$zoomLevel = null;
}
$date = $request->get('date') ?? '';
$data = [
'tag' => $request->get('tag'),
'date' => strlen($date) > 0 ? new Carbon($date) : null,
'description' => $request->get('description') ?? '',
'latitude' => $latitude,
'longitude' => $longitude,
'zoomLevel' => $zoomLevel,
'tagMode' => $request->get('tagMode'),
];
$data = $request->collectTagData();
$repository->store($data);
Session::flash('success', 'The tag has been created!');
@@ -279,28 +259,7 @@ class TagController extends Controller
*/
public function update(TagFormRequest $request, TagRepositoryInterface $repository, Tag $tag)
{
if (Input::get('setTag') == 'true') {
$latitude = $request->get('latitude');
$longitude = $request->get('longitude');
$zoomLevel = $request->get('zoomLevel');
} else {
$latitude = null;
$longitude = null;
$zoomLevel = null;
}
$date = $request->get('date') ?? '';
$data = [
'tag' => $request->get('tag'),
'date' => strlen($date) > 0 ? new Carbon($date) : null,
'description' => $request->get('description') ?? '',
'latitude' => $latitude,
'longitude' => $longitude,
'zoomLevel' => $zoomLevel,
'tagMode' => $request->get('tagMode'),
];
$data = $request->collectTagData();
$repository->update($tag, $data);
Session::flash('success', 'Tag "' . e($data['tag']) . '" updated.');
+32
View File
@@ -3,6 +3,7 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Requests;
use Auth;
use Carbon\Carbon;
use FireflyIII\Models\Tag;
use Input;
@@ -23,6 +24,37 @@ class TagFormRequest extends Request
return Auth::check();
}
/**
* @return array
*/
public function collectTagData() :array
{
if (Input::get('setTag') == 'true') {
$latitude = $this->get('latitude');
$longitude = $this->get('longitude');
$zoomLevel = $this->get('zoomLevel');
} else {
$latitude = null;
$longitude = null;
$zoomLevel = null;
}
$date = $this->get('date') ?? '';
$data = [
'tag' => $this->get('tag'),
'date' => strlen($date) > 0 ? new Carbon($date) : null,
'description' => $this->get('description') ?? '',
'latitude' => $latitude,
'longitude' => $longitude,
'zoomLevel' => $zoomLevel,
'tagMode' => $this->get('tagMode'),
];
return $data;
}
/**
* @return array
*/
-21
View File
@@ -1,21 +0,0 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Models;
use Zizaco\Entrust\EntrustPermission;
/**
* FireflyIII\Models\Permission
*
* @property integer $id
* @property string $name
* @property string $display_name
* @property string $description
* @property \Carbon\Carbon $created_at
* @property \Carbon\Carbon $updated_at
* @property-read \Illuminate\Database\Eloquent\Collection|Role[] $roles
*/
class Permission extends EntrustPermission
{
}
+12 -14
View File
@@ -3,21 +3,19 @@ declare(strict_types = 1);
namespace FireflyIII\Models;
use Zizaco\Entrust\EntrustRole;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
/**
* FireflyIII\Models\Role
*
* @property integer $id
* @property string $name
* @property string $display_name
* @property string $description
* @property \Carbon\Carbon $created_at
* @property \Carbon\Carbon $updated_at
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\User[] $users
* @property-read \Illuminate\Database\Eloquent\Collection|Permission[] $perms
*/
class Role extends EntrustRole
class Role extends Model
{
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function users(): BelongsToMany
{
return $this->belongsToMany('FireflyIII\User');
}
}
@@ -333,7 +333,7 @@ class AccountRepository implements AccountRepositoryInterface
$balance = Steam::balance($account, $date, true);
/** @var PiggyBank $p */
foreach ($account->piggyBanks()->get() as $p) {
$balance = bcsub($p->currentRelevantRep()->currentamount, $balance);
$balance = bcsub($balance, $p->currentRelevantRep()->currentamount);
}
return $balance;
@@ -544,7 +544,7 @@ class AccountRepository implements AccountRepositoryInterface
* @return bool
*/
private function storeMetadata(Account $account, array $data): bool
{
{
foreach ($this->validFields as $field) {
if (isset($data[$field])) {
$metaData = new AccountMeta(
+40 -58
View File
@@ -207,47 +207,10 @@ class RuleRepository implements RuleRepositoryInterface
$rule->save();
// start storing triggers:
$order = 1;
$stopProcessing = false;
$triggerValues = [
'action' => 'user_action',
'value' => $data['trigger'],
'stopProcessing' => $stopProcessing,
'order' => $order,
];
$this->storeTrigger($rule, $triggerValues);
foreach ($data['rule-triggers'] as $index => $trigger) {
$value = $data['rule-trigger-values'][$index];
$stopProcessing = isset($data['rule-trigger-stop'][$index]) ? true : false;
$triggerValues = [
'action' => $trigger,
'value' => $value,
'stopProcessing' => $stopProcessing,
'order' => $order,
];
$this->storeTrigger($rule, $triggerValues);
$order++;
}
$this->storeTriggers($rule, $data);
// same for actions.
$order = 1;
foreach ($data['rule-actions'] as $index => $action) {
$value = $data['rule-action-values'][$index];
$stopProcessing = isset($data['rule-action-stop'][$index]) ? true : false;
$actionValues = [
'action' => $action,
'value' => $value,
'stopProcessing' => $stopProcessing,
'order' => $order,
];
$this->storeAction($rule, $actionValues);
}
$this->storeActions($rule, $data);
return $rule;
}
@@ -315,6 +278,44 @@ class RuleRepository implements RuleRepositoryInterface
$rule->ruleActions()->delete();
// recreate triggers:
$this->storeTriggers($rule, $data);
// recreate actions:
$this->storeActions($rule, $data);
return $rule;
}
/**
* @param Rule $rule
* @param array $data
*/
private function storeActions(Rule $rule, array $data)
{
$order = 1;
foreach ($data['rule-actions'] as $index => $action) {
$value = $data['rule-action-values'][$index];
$stopProcessing = isset($data['rule-action-stop'][$index]) ? true : false;
$actionValues = [
'action' => $action,
'value' => $value,
'stopProcessing' => $stopProcessing,
'order' => $order,
];
$this->storeAction($rule, $actionValues);
}
}
/**
* @param Rule $rule
* @param array $data
*/
private function storeTriggers(Rule $rule, array $data)
{
$order = 1;
$stopProcessing = false;
@@ -340,24 +341,5 @@ class RuleRepository implements RuleRepositoryInterface
$this->storeTrigger($rule, $triggerValues);
$order++;
}
// recreate actions:
$order = 1;
foreach ($data['rule-actions'] as $index => $action) {
$value = $data['rule-action-values'][$index];
$stopProcessing = isset($data['rule-action-stop'][$index]) ? true : false;
$actionValues = [
'action' => $action,
'value' => $value,
'stopProcessing' => $stopProcessing,
'order' => $order,
];
$this->storeAction($rule, $actionValues);
}
return $rule;
}
}
+168 -209
View File
@@ -30,7 +30,6 @@ use FireflyIII\Models\Tag;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\User;
use Log;
/**
* Class TestData
@@ -90,20 +89,16 @@ class TestData
public static function createAttachments(User $user, Carbon $start): TransactionJournal
{
$toAccount = TestData::findAccount($user, 'TestData Checking Account');
$fromAccount = TestData::findAccount($user, 'Job');
$journal = TransactionJournal::create(
[
'user_id' => $user->id,
'transaction_type_id' => 2,
'transaction_currency_id' => 1,
'description' => 'Some journal for attachment',
'completed' => 1,
'date' => $start->format('Y-m-d'),
]
);
self::createTransactions($journal, $fromAccount, $toAccount, '100');
$args = [
'user' => $user,
'description' => 'Some journal for attachment',
'date' => $start,
'from' => 'Job',
'to' => 'TestData Checking Account',
'amount' => '100',
'transaction_type' => 2,
];
$journal = self::createJournal($args);
// and now attachments
$encrypted = Crypt::encrypt('I are secret');
@@ -245,45 +240,24 @@ class TestData
public static function createCar(User $user, Carbon $date): TransactionJournal
{
// twice:
$date = new Carbon($date->format('Y-m') . '-10'); // paid on 10th
$fromAccount = TestData::findAccount($user, 'TestData Checking Account');
$toAccount = TestData::findAccount($user, 'Shell');
$category = Category::firstOrCreateEncrypted(['name' => 'Car', 'user_id' => $user->id]);
$budget = Budget::firstOrCreateEncrypted(['name' => 'Car', 'user_id' => $user->id]);
$amount = strval(rand(4000, 5000) / 100);
$journal = TransactionJournal::create(
[
'user_id' => $user->id,
'transaction_type_id' => 1,
'transaction_currency_id' => 1,
'description' => 'Bought gas',
'completed' => 1,
'date' => $date,
]
);
self::createTransactions($journal, $fromAccount, $toAccount, $amount);
$amount = strval(rand(4000, 5000) / 100);
$args = [
'user' => $user,
'description' => 'Bought gas',
'date' => new Carbon($date->format('Y-m') . '-10'),// paid on 10th
'from' => 'TestData Checking Account',
'to' => 'Shell',
'amount' => $amount,
'category' => 'Car',
'budget' => 'Car',
];
self::createJournal($args);
$journal->categories()->save($category);
$journal->budgets()->save($budget);
// and again!
$date = new Carbon($date->format('Y-m') . '-20'); // paid on 20th
$amount = rand(4000, 5000) / 100;
$journal = TransactionJournal::create(
[
'user_id' => $user->id,
'transaction_type_id' => 1,
'transaction_currency_id' => 1,
'description' => 'Gas for car',
'completed' => 1,
'date' => $date,
]
);
self::createTransactions($journal, $fromAccount, $toAccount, strval($amount));
// and again!
// again!
$args['date'] = new Carbon($date->format('Y-m') . '-20'); // paid on 20th
$args['amount'] = strval(rand(4000, 5000) / 100);
$args['description'] = 'Gas for car';
$journal = self::createJournal($args);
return $journal;
}
@@ -322,28 +296,18 @@ class TestData
// weekly drink:
$thisDate = clone $current;
$thisDate->addDay();
$fromAccount = TestData::findAccount($user, 'TestData Checking Account');
$toAccount = TestData::findAccount($user, 'Cafe Central');
$category = Category::firstOrCreateEncrypted(['name' => 'Drinks', 'user_id' => $user->id]);
$budget = Budget::firstOrCreateEncrypted(['name' => 'Going out', 'user_id' => $user->id]);
$amount = strval(rand(1500, 3600) / 100);
$journal = TransactionJournal::create(
[
'user_id' => $user->id,
'transaction_type_id' => 1,
'transaction_currency_id' => 1,
'description' => 'Going out for drinks',
'completed' => 1,
'date' => $thisDate,
]
);
self::createTransactions($journal, $fromAccount, $toAccount, $amount);
$journal->categories()->save($category);
$journal->budgets()->save($budget);
// shopping at some (online) shop:
$amount = strval(rand(1500, 3600) / 100);
$args = [
'user' => $user,
'description' => 'Going out for drinks',
'date' => $thisDate,
'from' => 'TestData Checking Account',
'to' => 'Cafe Central',
'amount' => $amount,
'category' => 'Drinks',
'budget' => 'Going out',
];
self::createJournal($args);
$current->addWeek();
}
@@ -395,36 +359,25 @@ class TestData
$start->startOfMonth();
$end->endOfMonth();
$fromAccount = TestData::findAccount($user, 'TestData Checking Account');
$stores = ['Albert Heijn', 'PLUS', 'Bakker'];
$descriptions = ['Groceries', 'Bought some groceries', 'Got groceries'];
$category = Category::firstOrCreateEncrypted(['name' => 'Daily groceries', 'user_id' => $user->id]);
$budget = Budget::firstOrCreateEncrypted(['name' => 'Groceries', 'user_id' => $user->id]);
$current = clone $start;
while ($current < $end && $current < $today) {
// daily groceries:
$toAccount = TestData::findAccount($user, $stores[rand(0, count($stores) - 1)]);
$journal = TransactionJournal::create(
[
'user_id' => $user->id,
'transaction_type_id' => 1,
'transaction_currency_id' => 1,
'description' => $descriptions[rand(0, count($descriptions) - 1)],
'completed' => 1,
'date' => $current,
]
);
if ($journal->id) {
$number = (string)round((rand(1500, 2500) / 100), 2);
$amount = $number;//'10';//strval((rand(1500, 2500) / 100));
self::createTransactions($journal, $fromAccount, $toAccount, $amount);
$journal->categories()->save($category);
$journal->budgets()->save($budget);
}
$amount = (string)round((rand(1500, 2500) / 100), 2);
$args = [
'user' => $user,
'description' => $descriptions[rand(0, count($descriptions) - 1)],
'date' => $current,
'from' => 'TestData Checking Account',
'to' => $stores[rand(0, count($stores) - 1)],
'amount' => $amount,
'category' => 'Daily groceries',
'budget' => 'Groceries',
];
self::createJournal($args);
$current->addDay();
}
@@ -446,28 +399,54 @@ class TestData
if ($date >= $today) {
return new TransactionJournal;
}
$toAccount = TestData::findAccount($user, 'TestData Checking Account');
$fromAccount = TestData::findAccount($user, 'Job');
$category = Category::firstOrCreateEncrypted(['name' => 'Salary', 'user_id' => $user->id]);
// create journal:
$journal = TransactionJournal::create(
[
'user_id' => $user->id,
'transaction_type_id' => 2,
'transaction_currency_id' => 1,
'description' => $description,
'completed' => 1,
'date' => $date,
]
);
self::createTransactions($journal, $fromAccount, $toAccount, $amount);
$journal->categories()->save($category);
// create journal:
$args = [
'user' => $user,
'description' => $description,
'date' => $date,
'from' => 'Job',
'to' => 'TestData Checking Account',
'amount' => $amount,
'category' => 'Salary',
'transaction_type' => 2,
];
$journal = self::createJournal($args);
return $journal;
}
/**
* @param array $opt
*
* @return TransactionJournal
*/
public static function createJournal(array $opt): TransactionJournal
{
$type = $opt['transaction_type'] ?? 1;
$journal = TransactionJournal::create(
[
'user_id' => $opt['user']->id,
'transaction_type_id' => $type,
'transaction_currency_id' => 1,
'description' => $opt['description'],
'completed' => 1,
'date' => $opt['date'],
]
);
self::createTransactions($journal, self::findAccount($opt['user'], $opt['from']), self::findAccount($opt['user'], $opt['to']), $opt['amount']);
if (isset($opt['category'])) {
$journal->categories()->save(self::findCategory($opt['user'], $opt['category']));
}
if (isset($opt['budget'])) {
$journal->budgets()->save(self::findBudget($opt['user'], $opt['budget']));
}
return $journal;
}
/**
* @param User $user
*
@@ -620,24 +599,17 @@ class TestData
*/
public static function createPower(User $user, string $description, Carbon $date, string $amount): TransactionJournal
{
$date = new Carbon($date->format('Y-m') . '-06'); // paid on 10th
$fromAccount = TestData::findAccount($user, 'TestData Checking Account');
$toAccount = TestData::findAccount($user, 'Greenchoice');
$category = Category::firstOrCreateEncrypted(['name' => 'House', 'user_id' => $user->id]);
$budget = Budget::firstOrCreateEncrypted(['name' => 'Bills', 'user_id' => $user->id]);
$journal = TransactionJournal::create(
[
'user_id' => $user->id,
'transaction_type_id' => 1,
'transaction_currency_id' => 1,
'description' => $description,
'completed' => 1,
'date' => $date,
]
);
self::createTransactions($journal, $fromAccount, $toAccount, $amount);
$journal->categories()->save($category);
$journal->budgets()->save($budget);
$args = [
'user' => $user,
'description' => $description,
'date' => new Carbon($date->format('Y-m') . '-06'),// paid on 10th
'from' => 'TestData Checking Account',
'to' => 'Greenchoice',
'amount' => $amount,
'category' => 'House',
'budget' => 'Bills',
];
$journal = self::createJournal($args);
return $journal;
@@ -653,25 +625,17 @@ class TestData
*/
public static function createRent(User $user, string $description, Carbon $date, string $amount): TransactionJournal
{
$fromAccount = TestData::findAccount($user, 'TestData Checking Account');
$toAccount = TestData::findAccount($user, 'Land lord');
$category = Category::firstOrCreateEncrypted(['name' => 'Rent', 'user_id' => $user->id]);
$budget = Budget::firstOrCreateEncrypted(['name' => 'Bills', 'user_id' => $user->id]);
$journal = TransactionJournal::create(
[
'user_id' => $user->id,
'transaction_type_id' => 1,
'transaction_currency_id' => 1,
'bill_id' => 1,
'description' => $description,
'completed' => 1,
'date' => $date,
]
);
self::createTransactions($journal, $fromAccount, $toAccount, $amount);
$journal->categories()->save($category);
$journal->budgets()->save($budget);
$args = [
'user' => $user,
'description' => $description,
'date' => $date,
'from' => 'TestData Checking Account',
'to' => 'Land lord',
'amount' => $amount,
'category' => 'Rent',
'budget' => 'Bills',
];
$journal = self::createJournal($args);
return $journal;
@@ -792,24 +756,17 @@ class TestData
*/
public static function createSavings(User $user, Carbon $date): TransactionJournal
{
$date = new Carbon($date->format('Y-m') . '-24'); // paid on 24th.
$toAccount = TestData::findAccount($user, 'TestData Savings');
$fromAccount = TestData::findAccount($user, 'TestData Checking Account');
$category = Category::firstOrCreateEncrypted(['name' => 'Money management', 'user_id' => $user->id]);
// create journal:
$journal = TransactionJournal::create(
[
'user_id' => $user->id,
'transaction_type_id' => 3,
'transaction_currency_id' => 1,
'description' => 'Save money',
'completed' => 1,
'date' => $date,
]
);
self::createTransactions($journal, $fromAccount, $toAccount, '150');
$journal->categories()->save($category);
$args = [
'user' => $user,
'description' => 'Save money',
'date' => new Carbon($date->format('Y-m') . '-24'),// paid on 24th.
'from' => 'TestData Checking Account',
'to' => 'TestData Savings',
'amount' => '150',
'category' => 'Money management',
'transaction_type' => 3,
];
$journal = self::createJournal($args);
return $journal;
@@ -825,25 +782,17 @@ class TestData
*/
public static function createTV(User $user, string $description, Carbon $date, string $amount): TransactionJournal
{
$date = new Carbon($date->format('Y-m') . '-15'); // paid on 10th
$fromAccount = TestData::findAccount($user, 'TestData Checking Account');
$toAccount = TestData::findAccount($user, 'XS4All');
$category = Category::firstOrCreateEncrypted(['name' => 'House', 'user_id' => $user->id]);
$budget = Budget::firstOrCreateEncrypted(['name' => 'Bills', 'user_id' => $user->id]);
$journal = TransactionJournal::create(
[
'user_id' => $user->id,
'transaction_type_id' => 1,
'transaction_currency_id' => 1,
'description' => $description,
'completed' => 1,
'date' => $date,
]
);
self::createTransactions($journal, $fromAccount, $toAccount, $amount);
$journal->categories()->save($category);
$journal->budgets()->save($budget);
$args = [
'user' => $user,
'description' => $description,
'date' => new Carbon($date->format('Y-m') . '-15'),
'from' => 'TestData Checking Account',
'to' => 'XS4All',
'amount' => $amount,
'category' => 'House',
'budget' => 'Bills',
];
$journal = self::createJournal($args);
return $journal;
@@ -883,8 +832,6 @@ class TestData
*/
public static function createTransactions(TransactionJournal $journal, Account $from, Account $to, string $amount): bool
{
Log::debug('---- Transaction From: ' . bcmul($amount, '-1'));
Log::debug('---- Transaction To : ' . $amount);
Transaction::create(
[
'account_id' => $from->id,
@@ -931,24 +878,17 @@ class TestData
*/
public static function createWater(User $user, string $description, Carbon $date, string $amount): TransactionJournal
{
$date = new Carbon($date->format('Y-m') . '-10'); // paid on 10th
$fromAccount = TestData::findAccount($user, 'TestData Checking Account');
$toAccount = TestData::findAccount($user, 'Vitens');
$category = Category::firstOrCreateEncrypted(['name' => 'House', 'user_id' => $user->id]);
$budget = Budget::firstOrCreateEncrypted(['name' => 'Bills', 'user_id' => $user->id]);
$journal = TransactionJournal::create(
[
'user_id' => $user->id,
'transaction_type_id' => 1,
'transaction_currency_id' => 1,
'description' => $description,
'completed' => 1,
'date' => $date,
]
);
self::createTransactions($journal, $fromAccount, $toAccount, $amount);
$journal->categories()->save($category);
$journal->budgets()->save($budget);
$args = [
'user' => $user,
'description' => $description,
'date' => new Carbon($date->format('Y-m') . '-10'), // paid on 10th
'from' => 'TestData Checking Account',
'to' => 'Vitens',
'amount' => $amount,
'category' => 'House',
'budget' => 'Bills',
];
$journal = self::createJournal($args);
return $journal;
@@ -987,7 +927,25 @@ class TestData
}
}
return new Budget;
return Budget::firstOrCreateEncrypted(['name' => $name, 'user_id' => $user->id]);
}
/**
* @param User $user
* @param $name
*
* @return Category
*/
public static function findCategory(User $user, string $name): Category
{
/** @var Category $category */
foreach (Category::get() as $category) {
if ($category->name == $name && $user->id == $category->user_id) {
return $category;
}
}
return Category::firstOrCreateEncrypted(['name' => $name, 'user_id' => $user->id]);
}
/**
@@ -1023,6 +981,7 @@ class TestData
]
);
self::createTransactions($journal, $opposing, $savings, '10000');
return $journal;
}
+68 -7
View File
@@ -3,10 +3,10 @@ declare(strict_types = 1);
namespace FireflyIII;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Zizaco\Entrust\Traits\EntrustUserTrait;
/**
* Class User
@@ -32,11 +32,10 @@ use Zizaco\Entrust\Traits\EntrustUserTrait;
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\Role[] $roles
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\RuleGroup[] $ruleGroups
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\Rule[] $rules
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\ExportJob[] $exportjobs
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\ExportJob[] $exportjobs
*/
class User extends Authenticatable
{
use EntrustUserTrait;
/**
* The attributes that are mass assignable.
@@ -44,16 +43,12 @@ class User extends Authenticatable
* @var array
*/
protected $fillable = ['email', 'password', 'blocked', 'blocked_code'];
/**
* The attributes excluded from the model's JSON form.
*
* @var array
*/
protected $hidden = ['password', 'remember_token'];
/**
* The database table used by the model.
*
@@ -69,6 +64,26 @@ class User extends Authenticatable
return $this->hasMany('FireflyIII\Models\Account');
}
/**
* Alias to eloquent many-to-many relation's attach() method.
*
* Full credit goes to: https://github.com/Zizaco/entrust
*
* @param mixed $role
*/
public function attachRole($role)
{
if (is_object($role)) {
$role = $role->getKey();
}
if (is_array($role)) {
$role = $role['id'];
}
$this->roles()->attach($role);
}
/**
* @return HasMany
*/
@@ -109,6 +124,44 @@ class User extends Authenticatable
return $this->hasMany('FireflyIII\Models\ExportJob');
}
/**
* Checks if the user has a role by its name.
*
* Full credit goes to: https://github.com/Zizaco/entrust
*
* @param string|array $name Role name or array of role names.
* @param bool $requireAll All roles in the array are required.
*
* @return bool
*/
public function hasRole($name, $requireAll = false)
{
if (is_array($name)) {
foreach ($name as $roleName) {
$hasRole = $this->hasRole($roleName);
if ($hasRole && !$requireAll) {
return true;
} elseif (!$hasRole && $requireAll) {
return false;
}
}
// If we've made it this far and $requireAll is FALSE, then NONE of the roles were found
// If we've made it this far and $requireAll is TRUE, then ALL of the roles were found.
// Return the value of $requireAll;
return $requireAll;
} else {
foreach ($this->roles as $role) {
if ($role->name == $name) {
return true;
}
}
}
return false;
}
/**
* @return HasManyThrough
*/
@@ -125,6 +178,14 @@ class User extends Authenticatable
return $this->hasMany('FireflyIII\Models\Preference');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function roles(): BelongsToMany
{
return $this->belongsToMany('FireflyIII\Models\Role');
}
/**
* @return HasMany
*/
+7
View File
@@ -199,6 +199,13 @@ class FireflyValidator extends Validator
return false;
}
/**
* @param $attribute
* @param $value
* @param $parameters
*
* @return bool
*/
public function validateUniqueAccountNumberForUser($attribute, $value, $parameters): bool
{
$accountId = $this->data['id'] ?? 0;