diff --git a/app/Console/Commands/EncryptFile.php b/app/Console/Commands/EncryptFile.php new file mode 100644 index 0000000000..3d68deacf5 --- /dev/null +++ b/app/Console/Commands/EncryptFile.php @@ -0,0 +1,69 @@ +argument('file'); + if (!file_exists($file)) { + $this->error(sprintf('File "%s" does not seem to exist.', $file)); + + return; + } + $content = file_get_contents($file); + $content = Crypt::encrypt($content); + $newName = $this->argument('key') . '.upload'; + + $path = storage_path('upload') . '/' . $newName; + file_put_contents($path, $content); + $this->line(sprintf('Encrypted "%s" and put it in "%s"', $file, $path)); + + } +} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 5e9147a429..25b79b71eb 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -11,6 +11,7 @@ declare(strict_types = 1); namespace FireflyIII\Console; +use FireflyIII\Console\Commands\EncryptFile; use FireflyIII\Console\Commands\Import; use FireflyIII\Console\Commands\UpgradeFireflyInstructions; use FireflyIII\Console\Commands\VerifyDatabase; @@ -53,5 +54,6 @@ class Kernel extends ConsoleKernel UpgradeFireflyInstructions::class, VerifyDatabase::class, Import::class, + EncryptFile::class, ]; } diff --git a/app/Crud/Account/AccountCrud.php b/app/Crud/Account/AccountCrud.php index 075374efe5..787ced7bbf 100644 --- a/app/Crud/Account/AccountCrud.php +++ b/app/Crud/Account/AccountCrud.php @@ -103,7 +103,7 @@ class AccountCrud implements AccountCrudInterface } /** @var Collection $accounts */ - $accounts = $query->get(); + $accounts = $query->get(['accounts.*']); if ($accounts->count() > 0) { return $accounts->first(); } @@ -126,7 +126,7 @@ class AccountCrud implements AccountCrudInterface $query->whereIn('account_types.type', $types); } - $accounts = $query->get(); + $accounts = $query->get(['accounts.*']); /** @var Account $account */ foreach ($accounts as $account) { if ($account->iban === $iban) { @@ -145,20 +145,23 @@ class AccountCrud implements AccountCrudInterface */ public function findByName(string $name, array $types): Account { - $query = $this->user->accounts()->where('iban', '!=', ""); + $query = $this->user->accounts(); + Log::debug('Now in findByName()', ['name' => $name, 'types' => $types]); if (count($types) > 0) { $query->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id'); $query->whereIn('account_types.type', $types); } - $accounts = $query->get(); + $accounts = $query->get(['accounts.*']); + Log::debug(sprintf('Total set count is %d ', $accounts->count())); /** @var Account $account */ foreach ($accounts as $account) { if ($account->name === $name) { - return $account; + Log::debug('Account name is an exact match. ', ['db' => $account->name, 'source' => $name,'id' => $account->id]); } } + Log::warning('Found nothing in findByName()', ['name' => $name, 'types' => $types]); return new Account; } @@ -285,11 +288,11 @@ class AccountCrud implements AccountCrudInterface { $type = AccountType::whereType($type)->first(); if (!is_null($type)) { - $account->account_type_id = $type->id; + $account->accountType()->associate($type); $account->save(); } - return $account; + return $this->find($account->id); } diff --git a/app/Http/Controllers/Auth/AuthController.php b/app/Http/Controllers/Auth/AuthController.php index 11ec64cfbf..e66c2561e9 100644 --- a/app/Http/Controllers/Auth/AuthController.php +++ b/app/Http/Controllers/Auth/AuthController.php @@ -64,6 +64,7 @@ class AuthController extends Controller */ public function login(Request $request) { + $this->validate($request, [$this->loginUsername() => 'required', 'password' => 'required',]); $throttles = $this->isUsingThrottlesLoginsTrait(); diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index 48ad6319a0..c70d974824 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -119,6 +119,7 @@ class HomeController extends Controller */ public function index(ARI $repository, AccountCrudInterface $crud) { + $types = config('firefly.accountTypesByIdentifier.asset'); $count = $repository->countAccounts($types); diff --git a/app/Http/Controllers/NewUserController.php b/app/Http/Controllers/NewUserController.php index 3c7dcd4102..81c2e05dda 100644 --- a/app/Http/Controllers/NewUserController.php +++ b/app/Http/Controllers/NewUserController.php @@ -42,6 +42,7 @@ class NewUserController extends Controller */ public function index(ARI $repository) { + View::share('title', 'Welcome to Firefly!'); View::share('mainTitleIcon', 'fa-fire'); diff --git a/app/Import/Converter/AssetAccountName.php b/app/Import/Converter/AssetAccountName.php index 5b309c7702..af293656be 100644 --- a/app/Import/Converter/AssetAccountName.php +++ b/app/Import/Converter/AssetAccountName.php @@ -36,6 +36,7 @@ class AssetAccountName extends BasicConverter implements ConverterInterface if (strlen($value) === 0) { $this->setCertainty(0); + return new Account; } @@ -49,6 +50,7 @@ class AssetAccountName extends BasicConverter implements ConverterInterface if (!is_null($account->id)) { Log::debug('Found account by ID', ['id' => $account->id]); $this->setCertainty(100); + return $account; } } @@ -56,7 +58,7 @@ class AssetAccountName extends BasicConverter implements ConverterInterface // not mapped? Still try to find it first: $account = $repository->findByName($value, [AccountType::ASSET]); if (!is_null($account->id)) { - Log::debug('Found account by name', ['id' => $account->id]); + Log::debug('Found asset account by name', ['value' => $value, 'id' => $account->id]); return $account; } @@ -68,6 +70,8 @@ class AssetAccountName extends BasicConverter implements ConverterInterface ); $this->setCertainty(100); + Log::debug('Created new asset account ', ['name' => $account->name, 'id' => $account->id]); + return $account; diff --git a/app/Import/Converter/BillName.php b/app/Import/Converter/BillName.php index 6cb443c367..9d06e13105 100644 --- a/app/Import/Converter/BillName.php +++ b/app/Import/Converter/BillName.php @@ -66,7 +66,7 @@ class BillName extends BasicConverter implements ConverterInterface 'name' => $value, 'match' => $value, 'amount_min' => 1, - 'user_id' => $this->user->id, + 'user' => $this->user->id, 'amount_max' => 10, 'date' => date('Ymd'), 'repeat_freq' => 'monthly', diff --git a/app/Import/Converter/BudgetName.php b/app/Import/Converter/BudgetName.php index 59bcaf8bbb..bee601b682 100644 --- a/app/Import/Converter/BudgetName.php +++ b/app/Import/Converter/BudgetName.php @@ -64,7 +64,7 @@ class BudgetName extends BasicConverter implements ConverterInterface $budget = $repository->store( [ 'name' => $value, - 'user_id' => $this->user->id, + 'user' => $this->user->id, ] ); $this->setCertainty(100); diff --git a/app/Import/Converter/CategoryName.php b/app/Import/Converter/CategoryName.php index ac4f5ce720..8d09d271b8 100644 --- a/app/Import/Converter/CategoryName.php +++ b/app/Import/Converter/CategoryName.php @@ -64,7 +64,7 @@ class CategoryName extends BasicConverter implements ConverterInterface $category = $repository->store( [ 'name' => $value, - 'user_id' => $this->user->id, + 'user' => $this->user->id, ] ); $this->setCertainty(100); diff --git a/app/Import/Converter/OpposingAccountName.php b/app/Import/Converter/OpposingAccountName.php index 9d8b4d8623..b45a28cdb5 100644 --- a/app/Import/Converter/OpposingAccountName.php +++ b/app/Import/Converter/OpposingAccountName.php @@ -54,7 +54,7 @@ class OpposingAccountName extends BasicConverter implements ConverterInterface // not mapped? Still try to find it first: $account = $repository->findByName($value, []); if (!is_null($account->id)) { - Log::debug('Found account by name', ['id' => $account->id]); + Log::debug('Found opposing account by name', ['id' => $account->id]); Log::warning( 'The match between name and account is uncertain because the type of transactions may not have been determined.', ['id' => $account->id, 'name' => $value] @@ -70,6 +70,8 @@ class OpposingAccountName extends BasicConverter implements ConverterInterface ); $this->setCertainty(100); + Log::debug('Created new opposing account ', ['name' => $account->name, 'id' => $account->id]); + return $account; } } \ No newline at end of file diff --git a/app/Import/ImportStorage.php b/app/Import/ImportStorage.php index 178c6bdb25..a5c72a2ffe 100644 --- a/app/Import/ImportStorage.php +++ b/app/Import/ImportStorage.php @@ -58,6 +58,7 @@ class ImportStorage public function store() { foreach ($this->entries as $entry) { + Log::debug('--- import store start ---'); $this->storeSingle($entry); } @@ -80,9 +81,17 @@ class ImportStorage /** * @param ImportEntry $entry + * + * @throws FireflyException */ private function storeSingle(ImportEntry $entry) { + if ($entry->valid === false) { + Log::error('Cannot import entry, because valid=false'); + + return; + } + Log::debug('Going to store entry!'); $billId = is_null($entry->fields['bill']) ? null : $entry->fields['bill']->id; $journalData = [ @@ -145,7 +154,8 @@ class ImportStorage $one = Transaction::create($sourceData); $two = Transaction::create($destinationData); - Log::debug('Created transactions', ['source' => $one->id,'destination' => $two->id]); + Log::debug('Created transaction 1', ['id' => $one->id, 'account' => $one->account_id,'account_name' => $source->name]); + Log::debug('Created transaction 2', ['id' => $two->id, 'account' => $two->account_id,'account_name' => $destination->name]); $journal->completed = 1; $journal->save(); @@ -153,6 +163,5 @@ class ImportStorage // now attach budget and so on. - } } \ No newline at end of file diff --git a/app/Import/ImportValidator.php b/app/Import/ImportValidator.php index e53a503bac..527f407a8a 100644 --- a/app/Import/ImportValidator.php +++ b/app/Import/ImportValidator.php @@ -50,8 +50,10 @@ class ImportValidator */ public function clean(): Collection { + $newCollection = new Collection; /** @var ImportEntry $entry */ foreach ($this->entries as $entry) { + Log::debug('--- import validator start ---'); /* * X Adds the date (today) if no date is present. * X Determins the types of accounts involved (asset, expense, revenue). @@ -59,15 +61,20 @@ class ImportValidator * - Determins the currency of the transaction. * X Adds a default description if there isn't one present. */ - $this->checkAmount($entry); - $this->setDate($entry); - $this->setAssetAccount($entry); - $this->setOpposingAccount($entry); - $this->cleanDescription($entry); - $this->setTransactionType($entry); - $this->setTransactionCurrency($entry); + $entry = $this->checkAmount($entry); + $entry = $this->setDate($entry); + $entry = $this->setAssetAccount($entry); + Log::debug(sprintf('Opposing account is of type %s', $entry->fields['opposing-account']->accountType->type)); + $entry = $this->setOpposingAccount($entry); + Log::debug(sprintf('Opposing account is of type %s', $entry->fields['opposing-account']->accountType->type)); + $entry = $this->cleanDescription($entry); + $entry = $this->setTransactionType($entry); + $entry = $this->setTransactionCurrency($entry); + + $newCollection->push($entry); } - return $this->entries; + + return $newCollection; } /** @@ -88,42 +95,52 @@ class ImportValidator /** * @param ImportEntry $entry + * + * @return ImportEntry */ - private function checkAmount(ImportEntry $entry) + private function checkAmount(ImportEntry $entry): ImportEntry { if ($entry->fields['amount'] == 0) { $entry->valid = false; Log::error('Amount of transaction is zero, cannot handle.'); + + return $entry; } Log::debug('Amount is OK.'); + + return $entry; } /** * @param ImportEntry $entry + * + * @return ImportEntry */ - private function cleanDescription(ImportEntry $entry) + private function cleanDescription(ImportEntry $entry): ImportEntry { if (!isset($entry->fields['description'])) { Log::debug('Set empty transaction description because field was not set.'); $entry->fields['description'] = '(empty transaction description)'; - return; + return $entry; } if (is_null($entry->fields['description'])) { Log::debug('Set empty transaction description because field was null.'); $entry->fields['description'] = '(empty transaction description)'; - return; + return $entry; } if (strlen($entry->fields['description']) == 0) { Log::debug('Set empty transaction description because field was empty.'); $entry->fields['description'] = '(empty transaction description)'; - return; + return $entry; } Log::debug('Transaction description is OK.'); $entry->fields['description'] = trim($entry->fields['description']); + + return $entry; } /** @@ -136,6 +153,8 @@ class ImportValidator { $accountType = $account->accountType->type; if ($accountType === $type) { + Log::debug(sprintf('Account %s already of type %s', $account->name, $type)); + return $account; } // find it first by new type: @@ -144,7 +163,9 @@ class ImportValidator $result = $repository->findByName($account->name, [$type]); if (is_null($result->id)) { // can convert account: + Log::debug(sprintf('No account named %s of type %s, will convert.', $account->name, $type)); $result = $repository->updateAccountType($account, $type); + } return $result; @@ -194,29 +215,36 @@ class ImportValidator /** * @param ImportEntry $entry + * + * @return ImportEntry */ - private function setAssetAccount(ImportEntry $entry) + private function setAssetAccount(ImportEntry $entry): ImportEntry { if (is_null($entry->fields['asset-account'])) { if (!is_null($this->defaultImportAccount)) { Log::debug('Set asset account from default asset account'); $entry->fields['asset-account'] = $this->defaultImportAccount; - return; + return $entry; } // default import is null? should not happen. Entry cannot be imported. // set error message and block. $entry->valid = false; Log::error('Cannot import entry. Asset account is NULL and import account is also NULL.'); + } - Log::debug('Asset account is OK.'); + Log::debug('Asset account is OK.', ['id' => $entry->fields['asset-account']->id, 'name' => $entry->fields['asset-account']->name]); + + return $entry; } /** * @param ImportEntry $entry + * + * @return ImportEntry */ - private function setDate(ImportEntry $entry) + private function setDate(ImportEntry $entry): ImportEntry { if (is_null($entry->fields['date-transaction'])) { // empty date field? find alternative. @@ -226,24 +254,26 @@ class ImportValidator Log::debug(sprintf('Copied date-transaction from %s.', $alternative)); $entry->fields['date-transaction'] = clone $entry->fields[$alternative]; - return; + return $entry; } } // date is still null at this point Log::debug('Set date-transaction to today.'); $entry->fields['date-transaction'] = new Carbon; - return; + return $entry; } Log::debug('Date-transaction is OK'); - + return $entry; } /** * @param ImportEntry $entry + * + * @return ImportEntry */ - private function setOpposingAccount(ImportEntry $entry) + private function setOpposingAccount(ImportEntry $entry): ImportEntry { // empty opposing account. Create one based on amount. if (is_null($entry->fields['opposing-account'])) { @@ -253,12 +283,12 @@ class ImportValidator Log::debug('Created fallback expense account'); $entry->fields['opposing-account'] = $this->fallbackExpenseAccount(); - return; + return $entry; } Log::debug('Created fallback revenue account'); $entry->fields['opposing-account'] = $this->fallbackRevenueAccount(); - return; + return $entry; } // opposing is of type "import". Convert to correct type (by amount): @@ -268,14 +298,14 @@ class ImportValidator $entry->fields['opposing-account'] = $account; Log::debug('Converted import account to expense account'); - return; + return $entry; } if ($type == AccountType::IMPORT && $entry->fields['amount'] > 0) { $account = $this->convertAccount($entry->fields['opposing-account'], AccountType::REVENUE); $entry->fields['opposing-account'] = $account; Log::debug('Converted import account to revenue account'); - return; + return $entry; } // amount < 0, but opposing is revenue if ($type == AccountType::REVENUE && $entry->fields['amount'] < 0) { @@ -283,7 +313,7 @@ class ImportValidator $entry->fields['opposing-account'] = $account; Log::debug('Converted revenue account to expense account'); - return; + return $entry; } // amount > 0, but opposing is expense @@ -292,45 +322,65 @@ class ImportValidator $entry->fields['opposing-account'] = $account; Log::debug('Converted expense account to revenue account'); - return; + return $entry; } // account type is OK Log::debug('Opposing account is OK.'); + return $entry; + } /** * @param ImportEntry $entry + * + * @return ImportEntry */ - private function setTransactionCurrency(ImportEntry $entry) + private function setTransactionCurrency(ImportEntry $entry): ImportEntry { if (is_null($entry->fields['currency'])) { /** @var CurrencyRepositoryInterface $repository */ $repository = app(CurrencyRepositoryInterface::class); $entry->fields['currency'] = $repository->findByCode(env('DEFAULT_CURRENCY', 'EUR')); Log::debug('Set currency to EUR'); - return; + + return $entry; } Log::debug('Currency is OK'); + + return $entry; } /** * @param ImportEntry $entry + * + * @return ImportEntry */ - private function setTransactionType(ImportEntry $entry) + private function setTransactionType(ImportEntry $entry): ImportEntry { + Log::debug(sprintf('Opposing account is of type %s', $entry->fields['opposing-account']->accountType->type)); $type = $entry->fields['opposing-account']->accountType->type; switch ($type) { case AccountType::EXPENSE: $entry->fields['transaction-type'] = TransactionType::whereType(TransactionType::WITHDRAWAL)->first(); - break; + Log::debug('Transaction type is now withdrawal.'); + + return $entry; case AccountType::REVENUE: $entry->fields['transaction-type'] = TransactionType::whereType(TransactionType::DEPOSIT)->first(); - break; + Log::debug('Transaction type is now deposit.'); + + return $entry; case AccountType::ASSET: $entry->fields['transaction-type'] = TransactionType::whereType(TransactionType::TRANSFER)->first(); - break; + Log::debug('Transaction type is now transfer.'); + + return $entry; } + Log::error(sprintf('Opposing account is of type %s, cannot handle this.', $type)); + $entry->valid = false; + + return $entry; } diff --git a/app/Import/Importer/CsvImporter.php b/app/Import/Importer/CsvImporter.php index 8abaab2024..f2e630d5c7 100644 --- a/app/Import/Importer/CsvImporter.php +++ b/app/Import/Importer/CsvImporter.php @@ -48,6 +48,7 @@ class CsvImporter implements ImporterInterface $collection = new Collection; foreach ($results as $index => $row) { if ($index >= $start) { + Log::debug('----- import entry build start --'); Log::debug(sprintf('Now going to import row %d.', $index)); $importEntry = $this->importSingleRow($index, $row); $collection->push($importEntry); diff --git a/app/Models/Account.php b/app/Models/Account.php index fdb7b3c2e9..2c8313c0b2 100644 --- a/app/Models/Account.php +++ b/app/Models/Account.php @@ -301,8 +301,8 @@ class Account extends Model */ public function setNameAttribute($value) { - $this->attributes['name'] = Crypt::encrypt($value); - $this->attributes['encrypted'] = true; + $this->attributes['name'] = $value; + $this->attributes['encrypted'] = false; } /** diff --git a/app/Providers/CrudServiceProvider.php b/app/Providers/CrudServiceProvider.php index cfb30450e3..815236b605 100644 --- a/app/Providers/CrudServiceProvider.php +++ b/app/Providers/CrudServiceProvider.php @@ -58,7 +58,7 @@ class CrudServiceProvider extends ServiceProvider if (!isset($arguments[0]) && !$app->auth->check()) { throw new FireflyException('There is no user present.'); } - Log::debug('AccountCrud constructor, run with default arguments.', $arguments); + // Log::debug('AccountCrud constructor, run with default arguments.', $arguments); return app('FireflyIII\Crud\Account\AccountCrud', $arguments); } diff --git a/app/Repositories/Bill/BillRepository.php b/app/Repositories/Bill/BillRepository.php index 6ea9f802af..51e0d4301a 100644 --- a/app/Repositories/Bill/BillRepository.php +++ b/app/Repositories/Bill/BillRepository.php @@ -81,7 +81,7 @@ class BillRepository implements BillRepositoryInterface */ public function findByName(string $name) : Bill { - $bills = $this->user->bills()->get(); + $bills = $this->user->bills()->get(['bills.*']); /** @var Bill $bill */ foreach ($bills as $bill) { diff --git a/app/Repositories/Budget/BudgetRepository.php b/app/Repositories/Budget/BudgetRepository.php index 8498fa037d..88bb56912a 100644 --- a/app/Repositories/Budget/BudgetRepository.php +++ b/app/Repositories/Budget/BudgetRepository.php @@ -94,7 +94,7 @@ class BudgetRepository implements BudgetRepositoryInterface */ public function findByName(string $name): Budget { - $budgets = $this->user->budgets()->get(); + $budgets = $this->user->budgets()->get(['budgets.*']); /** @var Budget $budget */ foreach ($budgets as $budget) { if ($budget->name === $name) { diff --git a/app/Repositories/Category/CategoryRepository.php b/app/Repositories/Category/CategoryRepository.php index 9cd4024928..e0a662b355 100644 --- a/app/Repositories/Category/CategoryRepository.php +++ b/app/Repositories/Category/CategoryRepository.php @@ -110,7 +110,7 @@ class CategoryRepository implements CategoryRepositoryInterface */ public function findByName(string $name) : Category { - $categories = $this->user->categories()->get(); + $categories = $this->user->categories()->get(['categories.*']); foreach ($categories as $category) { if ($category->name === $name) { return $category; diff --git a/app/Repositories/ExportJob/ExportJobRepository.php b/app/Repositories/ExportJob/ExportJobRepository.php index fe4f54f4f3..009aadbf6e 100644 --- a/app/Repositories/ExportJob/ExportJobRepository.php +++ b/app/Repositories/ExportJob/ExportJobRepository.php @@ -99,7 +99,7 @@ class ExportJobRepository implements ExportJobRepositoryInterface */ public function findByKey(string $key): ExportJob { - $result = $this->user->exportJobs()->where('key', $key)->first(); + $result = $this->user->exportJobs()->where('key', $key)->first(['export_jobs.*']); if (is_null($result)) { return new ExportJob; } diff --git a/app/Repositories/ImportJob/ImportJobRepository.php b/app/Repositories/ImportJob/ImportJobRepository.php index 4e281d83c6..15c02b5e60 100644 --- a/app/Repositories/ImportJob/ImportJobRepository.php +++ b/app/Repositories/ImportJob/ImportJobRepository.php @@ -71,7 +71,7 @@ class ImportJobRepository implements ImportJobRepositoryInterface */ public function findByKey(string $key): ImportJob { - $result = $this->user->importJobs()->where('key', $key)->first(); + $result = $this->user->importJobs()->where('key', $key)->first(['import_jobs.*']); if (is_null($result)) { return new ImportJob; } diff --git a/app/Support/Migration/TestData.php b/app/Support/Migration/TestData.php index 4b72873c21..d3e59f9cdd 100644 --- a/app/Support/Migration/TestData.php +++ b/app/Support/Migration/TestData.php @@ -244,6 +244,26 @@ class TestData DB::table('categories')->insert($insert); } + /** + * + */ + private function createImportJobs() + { + $insert = []; + foreach ($this->data['import-jobs'] as $job) { + $insert[] = [ + 'created_at' => $this->time, + 'updated_at' => $this->time, + 'user_id' => $job['user_id'], + 'file_type' => $job['file_type'], + 'key' => $job['key'], + 'status' => $job['status'], + 'configuration' => json_encode($job['configuration']), + ]; + } + DB::table('import_jobs')->insert($insert); + } + /** * */ @@ -640,14 +660,14 @@ class TestData foreach ($this->data['piggy-banks'] as $piggyBank) { $piggyId = DB::table('piggy_banks')->insertGetId( [ - 'created_at' => $this->time, - 'updated_at' => $this->time, - 'account_id' => $piggyBank['account_id'], - 'name' => Crypt::encrypt($piggyBank['name']), - 'targetamount' => $piggyBank['targetamount'], - 'startdate' => $piggyBank['startdate'], - 'order' => $piggyBank['order'], - 'encrypted' => 1, + 'created_at' => $this->time, + 'updated_at' => $this->time, + 'account_id' => $piggyBank['account_id'], + 'name' => Crypt::encrypt($piggyBank['name']), + 'targetamount' => $piggyBank['targetamount'], + 'startdate' => $piggyBank['startdate'], + 'order' => $piggyBank['order'], + 'encrypted' => 1, ] ); if (isset($piggyBank['currentamount'])) { @@ -808,6 +828,7 @@ class TestData $this->createMultiWithdrawals(); $this->createMultiDeposits(); $this->createMultiTransfers(); + $this->createImportJobs(); } } diff --git a/storage/database/.gitignore b/storage/database/.gitignore index 79a5312b13..2f8355d95c 100644 --- a/storage/database/.gitignore +++ b/storage/database/.gitignore @@ -1,4 +1,3 @@ * !.gitignore -!seed.local.json -!seed.split.json \ No newline at end of file +!seed.*.json \ No newline at end of file diff --git a/storage/database/seed.import-test.json b/storage/database/seed.import-test.json new file mode 100644 index 0000000000..47cde9a977 --- /dev/null +++ b/storage/database/seed.import-test.json @@ -0,0 +1,72 @@ +{ + "users": [ + { + "email": "thegrumpydictator@gmail.com", + "password": "james" + } + ], + "roles": [ + { + "user_id": 1, + "role": 1 + } + ], + "accounts": [], + "account-meta": [], + "bills": [], + "budgets": [], + "budget-limits": [], + "monthly-limits": [], + "categories": [], + "piggy-banks": [], + "piggy-events": [], + "rule-groups": [], + "rules": [], + "rule-triggers": [], + "rule-actions": [], + "tags": [], + "monthly-deposits": [], + "monthly-transfers": [], + "monthly-withdrawals": [], + "attachments": [], + "multi-withdrawals": [], + "multi-deposits": [], + "multi-transfers": [], + "import-jobs": [ + { + "user_id": 1, + "key": "testImport", + "file_type": "csv", + "status": "settings_complete", + "configuration": { + "has-headers": false, + "date-format": "Ymd", + "delimiter": ",", + "import-account": 0, + "specifics": [], + "column-count": 7, + "column-roles": [ + "account-name", + "opposing-name", + "amount", + "date-transaction", + "category-name", + "budget-name", + "description" + ], + "column-do-mapping": [ + false, + false, + false, + false, + false, + false, + false + ], + "column-roles-complete": false, + "column-mapping-config": [], + "column-mapping-complete": false + } + } + ] +} \ No newline at end of file diff --git a/storage/database/seed.local.json b/storage/database/seed.local.json index 0a22dcf358..463b1119ff 100644 --- a/storage/database/seed.local.json +++ b/storage/database/seed.local.json @@ -1006,5 +1006,6 @@ 9 ] } - ] + ], + "import-jobs": [] } \ No newline at end of file diff --git a/storage/database/seed.split.json b/storage/database/seed.split.json index aa276339e7..2a60692705 100644 --- a/storage/database/seed.split.json +++ b/storage/database/seed.split.json @@ -297,5 +297,6 @@ 3 ] } - ] + ], + "import-jobs": [] } \ No newline at end of file diff --git a/storage/database/seed.testing.json b/storage/database/seed.testing.json new file mode 100644 index 0000000000..5dbaaaf5e9 --- /dev/null +++ b/storage/database/seed.testing.json @@ -0,0 +1,1011 @@ +{ + "users": [ + { + "email": "thegrumpydictator@gmail.com", + "password": "james" + }, + { + "email": "thegrumpydictator+empty@gmail.com", + "password": "james" + }, + { + "email": "thegrumpydictator+deleteme@gmail.com", + "password": "james" + } + ], + "roles": [ + { + "user_id": 1, + "role": 1 + } + ], + "accounts": [ + { + "user_id": 1, + "account_type_id": 3, + "name": "Checking Account", + "iban": "NL11XOLA6707795988" + }, + { + "user_id": 1, + "account_type_id": 3, + "name": "Alternate Checking Account", + "iban": "NL40UKBK3619908726" + }, + { + "user_id": 1, + "account_type_id": 3, + "name": "Savings Account", + "iban": "NL96DZCO4665940223" + }, + { + "user_id": 1, + "account_type_id": 3, + "name": "Shared Checking Account", + "iban": "NL81RCQZ7160379858" + }, + { + "user_id": 1, + "account_type_id": 3, + "name": "Emergency Savings Account", + "iban": "NL38SRMN4325934708" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "Adobe" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "Google" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "Vitens" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "Albert Heijn" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "PLUS" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "Bakker" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "Belastingdienst" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "bol.com" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "Cafe Central" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "conrad.nl" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "Coolblue" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "Shell" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "SixtyFive" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "EightyFour" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "Fiftyone" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "DUO" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "Etos" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "FEBO" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "Greenchoice" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "Halfords" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "XS4All" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "iCentre" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "Jumper" + }, + { + "user_id": 1, + "account_type_id": 4, + "name": "Land lord" + }, + { + "user_id": 1, + "account_type_id": 5, + "name": "Job" + }, + { + "user_id": 1, + "account_type_id": 5, + "name": "Belastingdienst" + }, + { + "user_id": 1, + "account_type_id": 5, + "name": "Bank" + }, + { + "user_id": 1, + "account_type_id": 5, + "name": "KPN" + }, + { + "user_id": 1, + "account_type_id": 5, + "name": "Google" + }, + { + "user_id": 1, + "account_type_id": 5, + "name": "Work SixtyFive" + }, + { + "user_id": 1, + "account_type_id": 5, + "name": "Work EightyFour" + }, + { + "user_id": 1, + "account_type_id": 5, + "name": "Work Fiftyone" + }, + { + "user_id": 1, + "account_type_id": 6, + "name": "Opposing for Savings Account" + }, + { + "user_id": 1, + "account_type_id": 6, + "name": "Opposing for Emergency Savings Account" + } + ], + "account-meta": [ + { + "account_id": 1, + "name": "accountRole", + "data": "\"defaultAsset\"" + }, + { + "account_id": 2, + "name": "accountRole", + "data": "\"defaultAsset\"" + }, + { + "account_id": 3, + "name": "accountRole", + "data": "\"savingAsset\"" + }, + { + "account_id": 4, + "name": "accountRole", + "data": "\"sharedAsset\"" + } + ], + "bills": [ + { + "name": "Rent", + "match": "rent,land,lord", + "amount_min": 795, + "amount_max": 805, + "user_id": 1, + "date": "2015-01-01", + "active": 1, + "automatch": 1, + "repeat_freq": "monthly", + "skip": 0 + }, + { + "name": "Health insurance", + "match": "insurer,insurance,health", + "amount_min": 120, + "amount_max": 140, + "user_id": 1, + "date": "2015-01-01", + "active": 1, + "automatch": 1, + "repeat_freq": "monthly", + "skip": 0 + } + ], + "budgets": [ + { + "name": "Groceries", + "user_id": 1 + }, + { + "name": "Bills", + "user_id": 1 + }, + { + "name": "Car", + "user_id": 1 + }, + { + "name": "One Empty Budget", + "user_id": 1 + }, + { + "name": "Another Empty Budget", + "user_id": 1 + }, + { + "name": "Going out", + "user_id": 1 + }, + { + "name": "Multi budget A", + "user_id": 1 + }, + { + "name": "Multi budget B", + "user_id": 1 + }, + { + "name": "Multi budget C", + "user_id": 1 + } + ], + "budget-limits": [ + { + "budget_id": 1, + "startdate": "2016-04-01", + "amount_min": 100, + "amount_max": 200, + "repeat_freq": "daily" + }, + { + "budget_id": 1, + "startdate": "2016-05-01", + "amount_min": 100, + "amount_max": 200, + "repeat_freq": "weekly" + }, + { + "budget_id": 1, + "startdate": "2016-06-01", + "amount_min": 100, + "amount_max": 200, + "repeat_freq": "monthly" + }, + { + "budget_id": 1, + "startdate": "2016-07-01", + "amount_min": 100, + "amount_max": 200, + "repeat_freq": "quarterly" + }, + { + "budget_id": 1, + "startdate": "2016-08-01", + "amount_min": 100, + "amount_max": 200, + "repeat_freq": "half-year" + }, + { + "budget_id": 1, + "startdate": "2016-09-01", + "amount_min": 100, + "amount_max": 200, + "repeat_freq": "yearly" + } + ], + "monthly-limits": [ + { + "budget_id": 1, + "amount_min": 200, + "amount_max": 200 + }, + { + "budget_id": 2, + "amount_min": 1000, + "amount_max": 1000 + }, + { + "budget_id": 3, + "amount_min": 200, + "amount_max": 200 + }, + { + "budget_id": 6, + "amount_min": 100, + "amount_max": 100 + } + ], + "categories": [ + { + "name": "Daily groceries", + "user_id": 1 + }, + { + "name": "Car", + "user_id": 1 + }, + { + "name": "Reimbursements", + "user_id": 1 + }, + { + "name": "Salary", + "user_id": 1 + }, + { + "name": "Bills", + "user_id": 1 + }, + { + "name": "Going out", + "user_id": 1 + }, + { + "name": "Multi category A", + "user_id": 1 + }, + { + "name": "Multi category B", + "user_id": 1 + }, + { + "name": "Multi category C", + "user_id": 1 + } + ], + "piggy-banks": [ + { + "account_id": 3, + "name": "New camera", + "targetamount": 1000, + "startdate": "2015-04-01", + "reminder_skip": 0, + "remind_me": 0, + "order": 1, + "currentamount": 735 + }, + { + "account_id": 3, + "name": "New phone", + "targetamount": 600, + "startdate": "2015-04-01", + "reminder_skip": 0, + "remind_me": 0, + "order": 2, + "currentamount": 333 + }, + { + "account_id": 3, + "name": "New couch", + "targetamount": 500, + "startdate": "2015-04-01", + "reminder_skip": 0, + "remind_me": 0, + "order": 3, + "currentamount": 120 + } + ], + "piggy-events": [ + { + "piggy_bank_id": 1, + "date": "2015-05-01", + "amount": 245 + }, + { + "piggy_bank_id": 1, + "date": "2015-06-02", + "amount": 245 + }, + { + "piggy_bank_id": 1, + "date": "2015-07-03", + "amount": 245 + }, + { + "piggy_bank_id": 2, + "date": "2015-08-04", + "amount": 111 + }, + { + "piggy_bank_id": 2, + "date": "2015-09-05", + "amount": 111 + }, + { + "piggy_bank_id": 2, + "date": "2015-10-06", + "amount": 111 + }, + { + "piggy_bank_id": 3, + "date": "2015-11-07", + "amount": 40 + }, + { + "piggy_bank_id": 3, + "date": "2015-12-08", + "amount": 40 + }, + { + "piggy_bank_id": 3, + "date": "2016-01-09", + "amount": 40 + } + ], + "rule-groups": [ + { + "user_id": 1, + "order": 1, + "title": "Default rules", + "description": "All your rules not in a particular group." + } + ], + "rules": [ + { + "user_id": 1, + "rule_group_id": 1, + "order": 1, + "active": 1, + "stop_processing": 0, + "title": "Your first default rule", + "description": "This rule is an example. You can safely delete it." + } + ], + "rule-triggers": [ + { + "rule_id": 1, + "order": 1, + "active": 1, + "stop_processing": 0, + "trigger_type": "user_action", + "trigger_value": "store-journal" + }, + { + "rule_id": 1, + "order": 2, + "active": 1, + "stop_processing": 0, + "trigger_type": "description_is", + "trigger_value": "The Man Who Sold the World" + }, + { + "rule_id": 1, + "order": 3, + "active": 1, + "stop_processing": 0, + "trigger_type": "from_account_is", + "trigger_value": "David Bowie" + } + ], + "rule-actions": [ + { + "rule_id": 1, + "order": 1, + "active": 1, + "stop_processing": 0, + "action_type": "prepend_description", + "action_value": "Bought the world from " + }, + { + "rule_id": 1, + "order": 2, + "active": 1, + "stop_processing": 0, + "action_type": "set_category", + "action_value": "Large expenses" + } + ], + "tags": [ + { + "user_id": 1, + "tag": "TagJanuary", + "tagMode": "nothing", + "date": "2015-01-01" + }, + { + "user_id": 1, + "tag": "TagFebruary", + "tagMode": "nothing", + "date": "2015-02-02" + }, + { + "user_id": 1, + "tag": "TagMarch", + "tagMode": "nothing", + "date": "2015-03-03" + }, + { + "user_id": 1, + "tag": "TagApril", + "tagMode": "nothing", + "date": "2015-04-04" + }, + { + "user_id": 1, + "tag": "TagMay", + "tagMode": "nothing", + "date": "2015-05-05" + }, + { + "user_id": 1, + "tag": "TagJune", + "tagMode": "nothing", + "date": "2015-06-06" + }, + { + "user_id": 1, + "tag": "TagJuly", + "tagMode": "nothing", + "date": "2015-07-07" + }, + { + "user_id": 1, + "tag": "TagAugust", + "tagMode": "nothing", + "date": "2015-08-08" + }, + { + "user_id": 1, + "tag": "TagSeptember", + "tagMode": "nothing", + "date": "2015-09-09" + }, + { + "user_id": 1, + "tag": "TagOctober", + "tagMode": "nothing", + "date": "2015-10-10" + }, + { + "user_id": 1, + "tag": "TagNovember", + "tagMode": "nothing", + "date": "2015-11-11" + }, + { + "user_id": 1, + "tag": "TagDecember", + "tagMode": "nothing", + "date": "2015-12-12" + } + ], + "monthly-deposits": [ + { + "user_id": 1, + "day-of-month": 24, + "description": "Salary in :month", + "source_id": 30, + "destination_id": 1, + "min_amount": 1500, + "max_amount": 1700, + "category_id": 4 + } + ], + "monthly-transfers": [ + { + "user_id": 1, + "day-of-month": 28, + "description": "Saving money for :month", + "source_id": 1, + "destination_id": 3, + "min_amount": 150, + "max_amount": 150 + } + ], + "monthly-withdrawals": [ + { + "user_id": 1, + "day-of-month": "02", + "description": "Rent for :month", + "source_id": 1, + "destination_id": 29, + "min_amount": 800, + "max_amount": 800, + "category_id": 5, + "budget_id": 2 + }, + { + "user_id": 1, + "day-of-month": "04", + "description": "Water bill :month", + "source_id": 1, + "destination_id": 8, + "min_amount": 8, + "max_amount": 12, + "category_id": 5, + "budget_id": 2 + }, + { + "user_id": 1, + "day-of-month": "06", + "description": "TV bill :month", + "source_id": 1, + "destination_id": 26, + "min_amount": 50, + "max_amount": 60, + "category_id": 5, + "budget_id": 2 + }, + { + "user_id": 1, + "day-of-month": "08", + "description": "Power bill :month", + "source_id": 1, + "destination_id": 24, + "min_amount": 75, + "max_amount": 90, + "category_id": 5, + "budget_id": 2 + }, + { + "user_id": 1, + "day-of-month": "07", + "description": "Bought gas", + "source_id": 1, + "destination_id": 17, + "min_amount": 40, + "max_amount": 50, + "category_id": 2, + "budget_id": 3 + }, + { + "user_id": 1, + "day-of-month": 17, + "description": "Filled the car up again", + "source_id": 1, + "destination_id": 17, + "min_amount": 40, + "max_amount": 50, + "category_id": 2, + "budget_id": 3 + }, + { + "user_id": 1, + "day-of-month": 27, + "description": "Needed gas again", + "source_id": 1, + "destination_id": 17, + "min_amount": 45, + "max_amount": 55, + "category_id": 2, + "budget_id": 3 + }, + { + "user_id": 1, + "day-of-month": "02", + "description": "Groceries", + "source_id": 1, + "destination_id": 9, + "min_amount": 15, + "max_amount": 25, + "category_id": 1, + "budget_id": 1 + }, + { + "user_id": 1, + "day-of-month": "06", + "description": "Groceries", + "source_id": 1, + "destination_id": 10, + "min_amount": 15, + "max_amount": 25, + "category_id": 1, + "budget_id": 1 + }, + { + "user_id": 1, + "day-of-month": "08", + "description": "Groceries", + "source_id": 1, + "destination_id": 11, + "min_amount": 15, + "max_amount": 25, + "category_id": 1, + "budget_id": 1 + }, + { + "user_id": 1, + "day-of-month": 11, + "description": "Groceries", + "source_id": 1, + "destination_id": 9, + "min_amount": 15, + "max_amount": 25, + "category_id": 1, + "budget_id": 1 + }, + { + "user_id": 1, + "day-of-month": 15, + "description": "Groceries", + "source_id": 1, + "destination_id": 10, + "min_amount": 15, + "max_amount": 25, + "category_id": 1, + "budget_id": 1 + }, + { + "user_id": 1, + "day-of-month": 19, + "description": "Groceries", + "source_id": 1, + "destination_id": 11, + "min_amount": 15, + "max_amount": 25, + "category_id": 1, + "budget_id": 1 + }, + { + "user_id": 1, + "day-of-month": 23, + "description": "Groceries", + "source_id": 1, + "destination_id": 9, + "min_amount": 15, + "max_amount": 25, + "category_id": 1, + "budget_id": 1 + }, + { + "user_id": 1, + "day-of-month": 26, + "description": "Groceries", + "source_id": 1, + "destination_id": 10, + "min_amount": 15, + "max_amount": 25, + "category_id": 1, + "budget_id": 1 + }, + { + "user_id": 1, + "day-of-month": 13, + "description": "Going out for drinks", + "source_id": 1, + "destination_id": 14, + "min_amount": 15, + "max_amount": 36, + "category_id": 6, + "budget_id": 6 + }, + { + "user_id": 1, + "day-of-month": 26, + "description": "Going out for drinks again", + "source_id": 1, + "destination_id": 14, + "min_amount": 15, + "max_amount": 36, + "category_id": 6, + "budget_id": 6 + } + ], + "attachments": [ + { + "attachable_id": 1, + "attachable_type": "FireflyIII\\Models\\TransactionJournal", + "user_id": 1, + "content": "This is attachment number one.", + "filename": "empty-file.txt", + "title": "Empty file", + "description": "This file is empty", + "notes": "Some notes", + "mime": "text\/plain", + "uploaded": 1 + }, + { + "attachable_id": 2, + "attachable_type": "FireflyIII\\Models\\TransactionJournal", + "user_id": 1, + "content": "This is attachment number two.", + "filename": "empty-file2.txt", + "title": "Empty file", + "description": "This file is empty", + "notes": "Some notes", + "mime": "text\/plain", + "uploaded": 1 + } + ], + "multi-withdrawals": [ + { + "user_id": 1, + "date": "2016-03-12", + "description": "Even multi-withdrawal (50, 50)", + "destination_ids": [ + 18, + 19 + ], + "source_id": 1, + "amounts": [ + 50, + 50 + ], + "category_ids": [ + 7, + 8, + 9 + ], + "budget_ids": [ + 7, + 8, + 9 + ] + }, + { + "user_id": 1, + "date": "2016-05-12", + "description": "Uneven multi-withdrawal (15,34,51)", + "destination_ids": [ + 18, + 19, + 20 + ], + "source_id": 1, + "amounts": [ + 14, + 35, + 51 + ], + "category_ids": [ + 7, + 8, + 9 + ], + "budget_ids": [ + 7, + 8, + 9 + ] + } + ], + "multi-deposits": [ + { + "user_id": 1, + "date": "2016-03-02", + "description": "Even multi-deposit (50, 50)", + "source_ids": [ + 35, + 36 + ], + "destination_id": 1, + "amounts": [ + 50, + 50 + ], + "category_ids": [ + 7, + 8, + 9 + ] + }, + { + "user_id": 1, + "date": "2016-05-02", + "description": "Uneven multi-deposit (15,34,51)", + "source_ids": [ + 35, + 36, + 37 + ], + "destination_id": 1, + "amounts": [ + 14, + 35, + 51 + ], + "category_ids": [ + 7, + 8, + 9 + ] + } + ], + "multi-transfers": [ + { + "user_id": 1, + "date": "2016-03-02", + "description": "Even multi-transfer (50, 50)", + "source_ids": [ + 4, + 4 + ], + "destination_ids": [ + 5, + 5 + ], + "amounts": [ + 50, + 50 + ], + "category_ids": [ + 7, + 8 + ] + }, + { + "user_id": 1, + "date": "2016-05-02", + "description": "Uneven multi-transfer (15,34,51)", + "source_ids": [ + 4, + 4, + 4 + ], + "destination_ids": [ + 5, + 5, + 5 + ], + "amounts": [ + 14, + 35, + 51 + ], + "category_ids": [ + 7, + 8, + 9 + ] + } + ], + "import-jobs": [] +} \ No newline at end of file