diff --git a/app/Support/Migration/TestData.php b/app/Support/Migration/TestData.php index 5e6e0a08b5..ee367c81d5 100644 --- a/app/Support/Migration/TestData.php +++ b/app/Support/Migration/TestData.php @@ -2,6 +2,12 @@ declare(strict_types = 1); namespace FireflyIII\Support\Migration; +use Carbon\Carbon; +use Crypt; +use DB; +use Navigation; +use Storage; + /** * TestData.php * Copyright (C) 2016 thegrumpydictator@gmail.com @@ -10,30 +16,6 @@ namespace FireflyIII\Support\Migration; * of the MIT license. See the LICENSE file for details. */ -use Carbon\Carbon; -use Crypt; -use FireflyIII\Events\BudgetLimitStored; -use FireflyIII\Models\Account; -use FireflyIII\Models\AccountMeta; -use FireflyIII\Models\Attachment; -use FireflyIII\Models\Bill; -use FireflyIII\Models\Budget; -use FireflyIII\Models\BudgetLimit; -use FireflyIII\Models\Category; -use FireflyIII\Models\PiggyBank; -use FireflyIII\Models\PiggyBankEvent; -use FireflyIII\Models\Role; -use FireflyIII\Models\Rule; -use FireflyIII\Models\RuleAction; -use FireflyIII\Models\RuleGroup; -use FireflyIII\Models\RuleTrigger; -use FireflyIII\Models\Tag; -use FireflyIII\Models\Transaction; -use FireflyIII\Models\TransactionJournal; -use FireflyIII\User; -use Navigation; -use Storage; - /** * Class TestData * @@ -41,994 +23,599 @@ use Storage; */ class TestData { - + /** @var array */ + private $data = []; + /** @var Carbon */ + private $end; + /** @var Carbon */ + private $start; /** - * @param User $user - * @param array $assets + * TestData constructor. * - * @return bool + * @param array $data */ - public static function createAssetAccounts(User $user, array $assets): bool + private function __construct(array $data) { - if (count($assets) == 0) { - $assets = [ - [ - 'name' => 'TestData Checking Account', - 'iban' => 'NL11XOLA6707795988', - 'meta' => [ - 'accountRole' => 'defaultAsset', - ], - ], - [ - 'name' => 'TestData Savings', - 'iban' => 'NL96DZCO4665940223', - 'meta' => [ - 'accountRole' => 'savingAsset', - ], - ], - [ - 'name' => 'TestData Shared', - 'iban' => 'NL81RCQZ7160379858', - 'meta' => [ - 'accountRole' => 'sharedAsset', - ], - ], - [ - 'name' => 'TestData Creditcard', - 'iban' => 'NL19NRAP2367994221', - 'meta' => [ - 'accountRole' => 'ccAsset', - 'ccMonthlyPaymentDate' => '2015-05-27', - 'ccType' => 'monthlyFull', - ], - ], - [ - 'name' => 'Emergencies', - 'iban' => 'NL40UKBK3619908726', - 'meta' => [ - 'accountRole' => 'savingAsset', - ], - ], - [ - 'name' => 'STE', - 'iban' => 'NL38SRMN4325934708', - 'meta' => [ - 'accountRole' => 'savingAsset', - ], - ], - ]; - } + $this->data = $data; + $start = new Carbon; + $start->startOfYear(); + $start->subYears(2); + $end = new Carbon; - foreach ($assets as $index => $entry) { - // create account: - $account = Account::create( - [ - 'user_id' => $user->id, - 'account_type_id' => 3, - 'name' => $entry['name'], + $this->start = $start; + $this->end = $end; + } + + /** + * @param array $data + */ + public static function run(array $data) + { + $seeder = new TestData($data); + $seeder->go(); + } + + /** + * + */ + private function createAccounts() + { + if (isset($this->data['accounts']) && is_array($this->data['accounts'])) { + $insert = []; + foreach ($this->data['accounts'] as $account) { + $insert[] = [ + 'created_at' => DB::raw('NOW()'), + 'updated_at' => DB::raw('NOW()'), + 'user_id' => $account['user_id'], + 'account_type_id' => $account['account_type_id'], + 'name' => Crypt::encrypt($account['name']), 'active' => 1, 'encrypted' => 1, - 'iban' => $entry['iban'], - ] - ); - foreach ($entry['meta'] as $name => $value) { - AccountMeta::create(['account_id' => $account->id, 'name' => $name, 'data' => $value]); + 'virtual_balance' => 0, + 'iban' => $account['iban'] ?? null, + ]; + } + DB::table('accounts')->insert($insert); + } + if (isset($this->data['account-meta']) && is_array($this->data['account-meta'])) { + $insert = []; + foreach ($this->data['account-meta'] as $meta) { + $insert[] = [ + 'created_at' => DB::raw('NOW()'), + 'updated_at' => DB::raw('NOW()'), + 'account_id' => $meta['account_id'], + 'name' => $meta['name'], + 'data' => $meta['data'], + ]; + } + DB::table('account_meta')->insert($insert); + } + } + + /** + * + */ + private function createAttachments() + { + if (isset($this->data['attachments']) && is_array($this->data['attachments'])) { + $insert = []; + $disk = Storage::disk('upload'); + foreach ($this->data['attachments'] as $attachment) { + $data = Crypt::encrypt($attachment['content']); + $attachmentId = DB::table('attachments')->insertGetId( + [ + 'created_at' => DB::raw('NOW()'), + 'updated_at' => DB::raw('NOW()'), + 'attachable_id' => $attachment['attachable_id'], + 'attachable_type' => $attachment['attachable_type'], + 'user_id' => $attachment['user_id'], + 'md5' => md5($attachment['content']), + 'filename' => $attachment['filename'], + 'title' => $attachment['title'], + 'description' => $attachment['description'], + 'notes' => $attachment['notes'], + 'mime' => $attachment['mime'], + 'size' => strlen($attachment['content']), + 'uploaded' => 1, + ] + ); + + $disk->put('at-' . $attachmentId . '.data', $data); } } - - return true; - } /** - * @param User $user - * @param Carbon $start * - * @return TransactionJournal */ - public static function createAttachments(User $user, Carbon $start): TransactionJournal + private function createBills() { - - $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'); - $one = Attachment::create( - [ - 'attachable_id' => $journal->id, - 'attachable_type' => 'FireflyIII\Models\TransactionJournal', - 'user_id' => $user->id, - 'md5' => md5('Hallo'), - 'filename' => 'empty-file.txt', - 'title' => 'Empty file', - 'description' => 'This file is empty', - 'notes' => 'What notes', - 'mime' => 'text/plain', - 'size' => strlen($encrypted), - 'uploaded' => 1, - ] - ); - - - // and now attachment. - $two = Attachment::create( - [ - 'attachable_id' => $journal->id, - 'attachable_type' => 'FireflyIII\Models\TransactionJournal', - 'user_id' => $user->id, - 'md5' => md5('Ook hallo'), - 'filename' => 'empty-file-2.txt', - 'title' => 'Empty file 2', - 'description' => 'This file is empty too', - 'notes' => 'What notes do', - 'mime' => 'text/plain', - 'size' => strlen($encrypted), - 'uploaded' => 1, - ] - ); - // echo crypted data to the file. - $disk = Storage::disk('upload'); - $disk->put('at-' . $one->id . '.data', $encrypted); - $disk->put('at-' . $two->id . '.data', $encrypted); - - return $journal; + if (isset($this->data['bills']) && is_array($this->data['bills'])) { + $insert = []; + foreach ($this->data['bills'] as $bill) { + $insert[] = [ + 'created_at' => DB::raw('NOW()'), + 'updated_at' => DB::raw('NOW()'), + 'user_id' => $bill['user_id'], + 'name' => Crypt::encrypt($bill['name']), + 'match' => Crypt::encrypt($bill['match']), + 'amount_min' => $bill['amount_min'], + 'amount_max' => $bill['amount_max'], + 'date' => $bill['date'], + 'active' => $bill['active'], + 'automatch' => $bill['automatch'], + 'repeat_freq' => $bill['repeat_freq'], + 'skip' => $bill['skip'], + 'name_encrypted' => 1, + 'match_encrypted' => 1, + ]; + } + DB::table('bills')->insert($insert); + } } /** - * @param User $user * - * @return bool */ - public static function createBills(User $user): bool + private function createBudgets() { - Bill::create( - [ - 'name' => 'Rent', - 'match' => 'rent,land,lord', - 'amount_min' => 795, - 'amount_max' => 805, - 'user_id' => $user->id, - 'date' => '2015-01-01', - 'active' => 1, - 'automatch' => 1, - 'repeat_freq' => 'monthly', - 'skip' => 0, - ] - ); - Bill::create( - [ - 'name' => 'Health insurance', - 'match' => 'zilveren,kruis,health', - 'amount_min' => 120, - 'amount_max' => 140, - 'user_id' => $user->id, - 'date' => '2015-01-01', - 'active' => 1, - 'automatch' => 1, - 'repeat_freq' => 'monthly', - 'skip' => 0, - ] - ); - - return true; - - } - - /** - * @param User $user - * @param Carbon $current - * @param string $name - * @param string $amount - * - * @return BudgetLimit - */ - public static function createBudgetLimit(User $user, Carbon $current, string $name, string $amount): BudgetLimit - { - $start = clone $current; - $end = clone $current; - $budget = self::findBudget($user, $name); - $start->startOfMonth(); - $end->endOfMonth(); - - $limit = BudgetLimit::create( - [ - 'budget_id' => $budget->id, - 'startdate' => $start->format('Y-m-d'), - 'amount' => $amount, - 'repeats' => 0, - 'repeat_freq' => 'monthly', - ] - ); - // also trigger event. - $thisEnd = Navigation::addPeriod($start, 'monthly', 0); - $thisEnd->subDay(); - event(new BudgetLimitStored($limit, $thisEnd)); - - return $limit; - } - - /** - * @param User $user - * - * @return bool - */ - public static function createBudgets(User $user): bool - { - Budget::firstOrCreateEncrypted(['name' => 'Groceries', 'user_id' => $user->id]); - Budget::firstOrCreateEncrypted(['name' => 'Bills', 'user_id' => $user->id]); - Budget::firstOrCreateEncrypted(['name' => 'Car', 'user_id' => $user->id]); - - // some empty budgets. - foreach (['A'] as $letter) { - Budget::firstOrCreateEncrypted(['name' => 'Empty budget ' . $letter, 'user_id' => $user->id]); + if (isset($this->data['budgets']) && is_array($this->data['budgets'])) { + $insert = []; + foreach ($this->data['budgets'] as $budget) { + $insert[] = [ + 'created_at' => DB::raw('NOW()'), + 'updated_at' => DB::raw('NOW()'), + 'user_id' => $budget['user_id'], + 'name' => Crypt::encrypt($budget['name']), + 'encrypted' => 1, + ]; + } + DB::table('budgets')->insert($insert); } - return true; - } - - /** - * @param User $user - * @param Carbon $date - * - * @return TransactionJournal - */ - public static function createCar(User $user, Carbon $date): TransactionJournal - { - // twice: - $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); - - // 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; - } - - /** - * @param User $user - * - * @return bool - */ - public static function createCategories(User $user): bool - { - Category::firstOrCreateEncrypted(['name' => 'Groceries', 'user_id' => $user->id]); - Category::firstOrCreateEncrypted(['name' => 'Car', 'user_id' => $user->id]); - Category::firstOrCreateEncrypted(['name' => 'Reimbursements', 'user_id' => $user->id]); - Category::firstOrCreateEncrypted(['name' => 'Salary', 'user_id' => $user->id]); - - return true; - } - - /** - * @param User $user - * @param Carbon $date - * - * @return bool - * - */ - public static function createDrinksAndOthers(User $user, Carbon $date): bool - { - $start = clone $date; - $end = clone $date; - $today = new Carbon; - $start->startOfMonth(); - $end->endOfMonth(); - $current = clone $start; - while ($current < $end && $current < $today) { - - // weekly drink: - $thisDate = clone $current; - $thisDate->addDay(); - $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(); - } - - return true; - } - - /** - * @param User $user - * - * @return bool - */ - public static function createExpenseAccounts(User $user): bool - { - $expenses = ['Adobe', 'Google', 'Vitens', 'Albert Heijn', 'PLUS', 'Apple', 'Bakker', 'Belastingdienst', 'bol.com', 'Cafe Central', 'conrad.nl', - 'Coolblue', 'Shell', 'SixtyFive', 'EightyFour', 'Fiftyone', - 'DUO', 'Etos', 'FEBO', 'Greenchoice', 'Halfords', 'XS4All', 'iCentre', 'Jumper', 'Land lord']; - foreach ($expenses as $name) { - // create account: - Account::create( - [ - 'user_id' => $user->id, - 'account_type_id' => 4, - 'name' => $name, - 'active' => 1, - 'encrypted' => 1, - ] - ); - } - - return true; - - } - - /** - * @param User $user - * @param Carbon $date - * - * @return bool - * - */ - public static function createGroceries(User $user, Carbon $date): bool - { - $start = clone $date; - $end = clone $date; - $today = new Carbon; - $start->startOfMonth(); - $end->endOfMonth(); - - $stores = ['Albert Heijn', 'PLUS', 'Bakker']; - $descriptions = ['Groceries', 'Bought some groceries', 'Got groceries']; - - $current = clone $start; - while ($current < $end && $current < $today) { - // daily groceries: - $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(); - } - - return true; - } - - /** - * @param User $user - * @param string $description - * @param Carbon $date - * @param string $amount - * - * @return TransactionJournal - */ - public static function createIncome(User $user, string $description, Carbon $date, string $amount): TransactionJournal - { - $date = new Carbon($date->format('Y-m') . '-23'); // paid on 23rd. - $today = new Carbon; - if ($date >= $today) { - return new TransactionJournal; - } - - // 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 - * @param string $accountName - * - * @return bool - * - */ - public static function createPiggybanks(User $user, string $accountName): bool - { - - $account = self::findAccount($user, $accountName); - $camera = PiggyBank::create( - [ - 'account_id' => $account->id, - 'name' => 'New camera', - 'targetamount' => 1000, - 'startdate' => '2015-04-01', - 'reminder_skip' => 0, - 'remind_me' => 0, - 'order' => 1, - ] - ); - $repetition = $camera->piggyBankRepetitions()->first(); - $repetition->currentamount = 735; - $repetition->save(); - - // events: - PiggyBankEvent::create( - [ - 'piggy_bank_id' => $camera->id, - 'date' => '2015-05-01', - 'amount' => '245', - ] - ); - PiggyBankEvent::create( - [ - 'piggy_bank_id' => $camera->id, - 'date' => '2015-06-01', - 'amount' => '245', - ] - ); - PiggyBankEvent::create( - [ - 'piggy_bank_id' => $camera->id, - 'date' => '2015-07-01', - 'amount' => '245', - ] - ); - - - $phone = PiggyBank::create( - [ - 'account_id' => $account->id, - 'name' => 'New phone', - 'targetamount' => 600, - 'startdate' => '2015-04-01', - 'reminder_skip' => 0, - 'remind_me' => 0, - 'order' => 2, - ] - ); - $repetition = $phone->piggyBankRepetitions()->first(); - $repetition->currentamount = 333; - $repetition->save(); - - // events: - PiggyBankEvent::create( - [ - 'piggy_bank_id' => $phone->id, - 'date' => '2015-05-01', - 'amount' => '111', - ] - ); - PiggyBankEvent::create( - [ - 'piggy_bank_id' => $phone->id, - 'date' => '2015-06-01', - 'amount' => '111', - ] - ); - PiggyBankEvent::create( - [ - 'piggy_bank_id' => $phone->id, - 'date' => '2015-07-01', - 'amount' => '111', - ] - ); - - $couch = PiggyBank::create( - [ - 'account_id' => $account->id, - 'name' => 'New couch', - 'targetamount' => 500, - 'startdate' => '2015-04-01', - 'reminder_skip' => 0, - 'remind_me' => 0, - 'order' => 3, - ] - ); - $repetition = $couch->piggyBankRepetitions()->first(); - $repetition->currentamount = 120; - $repetition->save(); - - // events: - PiggyBankEvent::create( - [ - 'piggy_bank_id' => $couch->id, - 'date' => '2015-05-01', - 'amount' => '40', - ] - ); - PiggyBankEvent::create( - [ - 'piggy_bank_id' => $couch->id, - 'date' => '2015-06-01', - 'amount' => '40', - ] - ); - PiggyBankEvent::create( - [ - 'piggy_bank_id' => $couch->id, - 'date' => '2015-07-01', - 'amount' => '40', - ] - ); - - // empty one. - PiggyBank::create( - [ - 'account_id' => $account->id, - 'name' => 'New head set', - 'targetamount' => 500, - 'startdate' => '2015-04-01', - 'reminder_skip' => 0, - 'remind_me' => 0, - 'order' => 4, - ] - ); - - return true; - } - - /** - * @param User $user - * @param string $description - * @param Carbon $date - * @param string $amount - * - * @return TransactionJournal - */ - public static function createPower(User $user, string $description, Carbon $date, string $amount): TransactionJournal - { - $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; - - } - - /** - * @param User $user - * @param string $description - * @param Carbon $date - * @param string $amount - * - * @return TransactionJournal - */ - public static function createRent(User $user, string $description, Carbon $date, string $amount): TransactionJournal - { - $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; - - } - - /** - * @param User $user - * - * @return bool - */ - public static function createRevenueAccounts(User $user): bool - { - $revenues = ['Job', 'Belastingdienst', 'Bank', 'KPN', 'Google', 'Work SixtyFive', 'Work EightyFour','Work Fiftyone']; - foreach ($revenues as $name) { - // create account: - Account::create( - [ - 'user_id' => $user->id, - 'account_type_id' => 5, - 'name' => $name, - 'active' => 1, - 'encrypted' => 1, - ] - ); - } - - return true; - } - - /** - * @param User $user - * - * @return RuleGroup - */ - public static function createRules(User $user): RuleGroup - { - $group = RuleGroup::create( - [ - 'user_id' => $user->id, - 'order' => 1, - 'title' => trans('firefly.default_rule_group_name'), - 'description' => trans('firefly.default_rule_group_description'), - 'active' => 1, - ] - ); - $rule = Rule::create( - [ - 'user_id' => $user->id, - 'rule_group_id' => $group->id, - 'order' => 1, - 'active' => 1, - 'stop_processing' => 0, - 'title' => trans('firefly.default_rule_name'), - 'description' => trans('firefly.default_rule_description'), - ] - ); - - // three triggers: - RuleTrigger::create( - [ - 'rule_id' => $rule->id, - 'order' => 1, - 'active' => 1, - 'stop_processing' => 0, - 'trigger_type' => 'user_action', - 'trigger_value' => 'store-journal', - ] - ); - RuleTrigger::create( - [ - 'rule_id' => $rule->id, - 'order' => 2, - 'active' => 1, - 'stop_processing' => 0, - 'trigger_type' => 'description_is', - 'trigger_value' => trans('firefly.default_rule_trigger_description'), - ] - ); - RuleTrigger::create( - [ - 'rule_id' => $rule->id, - 'order' => 3, - 'active' => 1, - 'stop_processing' => 0, - 'trigger_type' => 'from_account_is', - 'trigger_value' => trans('firefly.default_rule_trigger_from_account'), - ] - ); - - // two actions: - RuleAction::create( - [ - 'rule_id' => $rule->id, - 'order' => 1, - 'active' => 1, - 'action_type' => 'prepend_description', - 'action_value' => trans('firefly.default_rule_action_prepend'), - ] - ); - RuleAction::create( - [ - 'rule_id' => $rule->id, - 'order' => 1, - 'active' => 1, - 'action_type' => 'set_category', - 'action_value' => trans('firefly.default_rule_action_set_category'), - ] - ); - - return $group; - } - - /** - * @param User $user - * @param Carbon $date - * - * @return TransactionJournal - */ - public static function createSavings(User $user, Carbon $date): TransactionJournal - { - $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; - - } - - /** - * @param User $user - * @param string $description - * @param Carbon $date - * @param string $amount - * - * @return TransactionJournal - */ - public static function createTV(User $user, string $description, Carbon $date, string $amount): TransactionJournal - { - $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; - - } - - /** - * @param User $user - * @param Carbon $date - * - * @return Tag - */ - public static function createTags(User $user, Carbon $date): Tag - { - $title = 'SomeTag' . $date->month . '.' . $date->year . '.nothing'; - - $tag = Tag::create( - [ - 'user_id' => $user->id, - 'tag' => $title, - 'tagMode' => 'nothing', - 'date' => $date->format('Y-m-d'), - - - ] - ); - - return $tag; - } - - /** - * @param TransactionJournal $journal - * @param Account $from - * @param Account $to - * @param string $amount - * - * @return bool - */ - public static function createTransactions(TransactionJournal $journal, Account $from, Account $to, string $amount): bool - { - Transaction::create( - [ - 'account_id' => $from->id, - 'transaction_journal_id' => $journal->id, - 'amount' => bcmul($amount, '-1'), - - ] - ); - Transaction::create( - [ - 'account_id' => $to->id, - 'transaction_journal_id' => $journal->id, - 'amount' => $amount, - - ] - ); - - return true; - } - - /** - * @return User - */ - public static function createUsers(): User - { - $user = User::create(['email' => 'thegrumpydictator@gmail.com', 'password' => bcrypt('james'), 'reset' => null, 'remember_token' => null]); - User::create(['email' => 'thegrumpydictator+empty@gmail.com', 'password' => bcrypt('james'), 'reset' => null, 'remember_token' => null]); - User::create(['email' => 'thegrumpydictator+deleteme@gmail.com', 'password' => bcrypt('james'), 'reset' => null, 'remember_token' => null]); - - - $admin = Role::where('name', 'owner')->first(); - $user->attachRole($admin); - - return $user; - } - - /** - * @param User $user - * @param string $description - * @param Carbon $date - * @param string $amount - * - * @return TransactionJournal - */ - public static function createWater(User $user, string $description, Carbon $date, string $amount): TransactionJournal - { - $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; - - } - - /** - * @param User $user - * @param $name - * - * @return Account - */ - public static function findAccount(User $user, string $name): Account - { - /** @var Account $account */ - foreach ($user->accounts()->get() as $account) { - if ($account->name == $name) { - return $account; + if (isset($this->data['budget-limits']) && is_array($this->data['budget-limits'])) { + foreach ($this->data['budget-limits'] as $limit) { + $amount = rand($limit['amount_min'], $limit['amount_max']); + $limitId = DB::table('budget_limits')->insertGetId( + [ + 'created_at' => DB::raw('NOW()'), + 'updated_at' => DB::raw('NOW()'), + 'budget_id' => $limit['budget_id'], + 'startdate' => $limit['startdate'], + 'amount' => $amount, + 'repeats' => 0, + 'repeat_freq' => $limit['repeat_freq'], + ] + ); + + DB::table('limit_repetitions')->insert( + [ + 'created_at' => DB::raw('NOW()'), + 'updated_at' => DB::raw('NOW()'), + 'budget_limit_id' => $limitId, + 'startdate' => $limit['startdate'], + 'enddate' => Navigation::endOfPeriod(new Carbon($limit['startdate']), $limit['repeat_freq'])->format('Y-m-d'), + 'amount' => $amount, + ] + ); } } + if (isset($this->data['monthly-limits']) && is_array($this->data['monthly-limits'])) { + $current = clone $this->start; + while ($current <= $this->end) { + foreach ($this->data['monthly-limits'] as $limit) { + $amount = rand($limit['amount_min'], $limit['amount_max']); + $limitId = DB::table('budget_limits')->insertGetId( + [ + 'created_at' => DB::raw('NOW()'), + 'updated_at' => DB::raw('NOW()'), + 'budget_id' => $limit['budget_id'], + 'startdate' => $current->format('Y-m-d'), + 'amount' => $amount, + 'repeats' => 0, + 'repeat_freq' => 'monthly', + ] + ); - return new Account; + DB::table('limit_repetitions')->insert( + [ + 'created_at' => DB::raw('NOW()'), + 'updated_at' => DB::raw('NOW()'), + 'budget_limit_id' => $limitId, + 'startdate' => $current->format('Y-m-d'), + 'enddate' => Navigation::endOfPeriod($current, 'monthly')->format('Y-m-d'), + 'amount' => $amount, + ] + ); + } + + $current->addMonth(); + } + + } } /** - * @param User $user - * @param $name * - * @return Budget */ - public static function findBudget(User $user, string $name): Budget + private function createCategories() { - /** @var Budget $budget */ - foreach (Budget::get() as $budget) { - if ($budget->name == $name && $user->id == $budget->user_id) { - return $budget; + if (isset($this->data['categories']) && is_array($this->data['categories'])) { + $insert = []; + foreach ($this->data['categories'] as $category) { + $insert[] = [ + 'created_at' => DB::raw('NOW()'), + 'updated_at' => DB::raw('NOW()'), + 'user_id' => $category['user_id'], + 'name' => Crypt::encrypt($category['name']), + 'encrypted' => 1, + ]; } + DB::table('categories')->insert($insert); + } + } + + /** + * + */ + private function createJournals() + { + $current = clone $this->start; + $transactions = []; + while ($current <= $this->end) { + $date = $current->format('Y-m-'); + $month = $current->format('F'); + + // run all monthly withdrawals: + if (isset($this->data['monthly-withdrawals']) && is_array($this->data['monthly-withdrawals'])) { + foreach ($this->data['monthly-withdrawals'] as $withdrawal) { + $description = str_replace(':month', $month, $withdrawal['description']); + $journalId = DB::table('transaction_journals')->insertGetId( + [ + 'created_at' => DB::raw('NOW()'), + 'updated_at' => DB::raw('NOW()'), + 'user_id' => $withdrawal['user_id'], + 'transaction_type_id' => 1, + 'bill_id' => $withdrawal['bill_id'] ?? null, + 'transaction_currency_id' => 1, + 'description' => Crypt::encrypt($description), + 'completed' => 1, + 'date' => $date . $withdrawal['day-of-month'], + 'interest_date' => $withdrawal['interest_date'] ?? null, + 'book_date' => $withdrawal['book_date'] ?? null, + 'process_date' => $withdrawal['process_date'] ?? null, + 'encrypted' => 1, + 'order' => 0, + 'tag_count' => 0, + ] + ); + $amount = (rand($withdrawal['min_amount'] * 100, $withdrawal['max_amount'] * 100)) / 100; + $transactions[] = [ + 'created_at' => DB::raw('NOW()'), + 'updated_at' => DB::raw('NOW()'), + 'transaction_journal_id' => $journalId, + 'account_id' => $withdrawal['source_id'], + 'amount' => $amount * -1, + ]; + $transactions[] = [ + 'created_at' => DB::raw('NOW()'), + 'updated_at' => DB::raw('NOW()'), + 'transaction_journal_id' => $journalId, + 'account_id' => $withdrawal['destination_id'], + 'amount' => $amount, + ]; + + // link to budget if set. + if (isset($withdrawal['budget_id'])) { + DB::table('budget_transaction_journal')->insert( + [ + 'budget_id' => $withdrawal['budget_id'], + 'transaction_journal_id' => $journalId, + + ] + ); + } + // link to category if set. + if (isset($withdrawal['category_id'])) { + DB::table('category_transaction_journal')->insert( + [ + 'category_id' => $withdrawal['category_id'], + 'transaction_journal_id' => $journalId, + + ] + ); + } + } + } + + // run all monthly deposits: + if (isset($this->data['monthly-deposits']) && is_array($this->data['monthly-deposits'])) { + foreach ($this->data['monthly-deposits'] as $deposit) { + $description = str_replace(':month', $month, $deposit['description']); + $journalId = DB::table('transaction_journals')->insertGetId( + [ + 'created_at' => DB::raw('NOW()'), + 'updated_at' => DB::raw('NOW()'), + 'user_id' => $deposit['user_id'], + 'transaction_type_id' => 2, + 'bill_id' => $deposit['bill_id'] ?? null, + 'transaction_currency_id' => 1, + 'description' => Crypt::encrypt($description), + 'completed' => 1, + 'date' => $date . $deposit['day-of-month'], + 'interest_date' => $deposit['interest_date'] ?? null, + 'book_date' => $deposit['book_date'] ?? null, + 'process_date' => $deposit['process_date'] ?? null, + 'encrypted' => 1, + 'order' => 0, + 'tag_count' => 0, + ] + ); + $amount = (rand($deposit['min_amount'] * 100, $deposit['max_amount'] * 100)) / 100; + $transactions[] = [ + 'created_at' => DB::raw('NOW()'), + 'updated_at' => DB::raw('NOW()'), + 'transaction_journal_id' => $journalId, + 'account_id' => $deposit['source_id'], + 'amount' => $amount * -1, + ]; + $transactions[] = [ + 'created_at' => DB::raw('NOW()'), + 'updated_at' => DB::raw('NOW()'), + 'transaction_journal_id' => $journalId, + 'account_id' => $deposit['destination_id'], + 'amount' => $amount, + ]; + + // link to category if set. + if (isset($deposit['category_id'])) { + DB::table('category_transaction_journal')->insert( + [ + 'category_id' => $deposit['category_id'], + 'transaction_journal_id' => $journalId, + + ] + ); + } + } + } + + // run all monthly transfers: + if (isset($this->data['monthly-transfers']) && is_array($this->data['monthly-transfers'])) { + foreach ($this->data['monthly-transfers'] as $transfer) { + $description = str_replace(':month', $month, $transfer['description']); + $journalId = DB::table('transaction_journals')->insertGetId( + [ + 'created_at' => DB::raw('NOW()'), + 'updated_at' => DB::raw('NOW()'), + 'user_id' => $transfer['user_id'], + 'transaction_type_id' => 3, + 'bill_id' => $transfer['bill_id'] ?? null, + 'transaction_currency_id' => 1, + 'description' => Crypt::encrypt($description), + 'completed' => 1, + 'date' => $date . $transfer['day-of-month'], + 'interest_date' => $transfer['interest_date'] ?? null, + 'book_date' => $transfer['book_date'] ?? null, + 'process_date' => $transfer['process_date'] ?? null, + 'encrypted' => 1, + 'order' => 0, + 'tag_count' => 0, + ] + ); + $amount = (rand($transfer['min_amount'] * 100, $transfer['max_amount'] * 100)) / 100; + $transactions[] = [ + 'created_at' => DB::raw('NOW()'), + 'updated_at' => DB::raw('NOW()'), + 'transaction_journal_id' => $journalId, + 'account_id' => $transfer['source_id'], + 'amount' => $amount * -1, + ]; + $transactions[] = [ + 'created_at' => DB::raw('NOW()'), + 'updated_at' => DB::raw('NOW()'), + 'transaction_journal_id' => $journalId, + 'account_id' => $transfer['destination_id'], + 'amount' => $amount, + ]; + // link to category if set. + if (isset($transfer['category_id'])) { + DB::table('category_transaction_journal')->insert( + [ + 'category_id' => $transfer['category_id'], + 'transaction_journal_id' => $journalId, + + ] + ); + } + } + } + + $current->addMonth(); } - return Budget::firstOrCreateEncrypted(['name' => $name, 'user_id' => $user->id]); + DB::table('transactions')->insert($transactions); } /** - * @param User $user - * @param $name * - * @return Category */ - public static function findCategory(User $user, string $name): Category + private function createPiggyBanks() { - /** @var Category $category */ - foreach (Category::get() as $category) { - if ($category->name == $name && $user->id == $category->user_id) { - return $category; + if (isset($this->data['piggy-banks']) && is_array($this->data['piggy-banks'])) { + foreach ($this->data['piggy-banks'] as $piggyBank) { + $piggyId = DB::table('piggy_banks')->insertGetId( + [ + 'created_at' => DB::raw('NOW()'), + 'updated_at' => DB::raw('NOW()'), + 'account_id' => $piggyBank['account_id'], + 'name' => Crypt::encrypt($piggyBank['name']), + 'targetamount' => $piggyBank['targetamount'], + 'startdate' => $piggyBank['startdate'], + 'reminder_skip' => 0, + 'remind_me' => 0, + 'order' => $piggyBank['order'], + 'encrypted' => 1, + ] + ); + if (isset($piggyBank['currentamount'])) { + DB::table('piggy_bank_repetitions')->insert( + [ + 'created_at' => DB::raw('NOW()'), + 'updated_at' => DB::raw('NOW()'), + 'piggy_bank_id' => $piggyId, + 'startdate' => $piggyBank['startdate'], + 'currentamount' => $piggyBank['currentamount'], + ] + ); + } } } - - return Category::firstOrCreateEncrypted(['name' => $name, 'user_id' => $user->id]); } /** - * @param User $user - * @param Carbon $date * - * @return TransactionJournal */ - public static function openingBalanceSavings(User $user, Carbon $date): TransactionJournal + private function createRules() { - // opposing account for opening balance: - $opposing = Account::create( - [ - 'user_id' => $user->id, - 'account_type_id' => 6, - 'name' => 'Opposing for savings', - 'active' => 1, - 'encrypted' => 1, - ] - ); - - // savings - $savings = TestData::findAccount($user, 'TestData Savings'); - - $journal = TransactionJournal::create( - [ - 'user_id' => $user->id, - 'transaction_type_id' => 4, - 'transaction_currency_id' => 1, - 'description' => 'Opening balance for savings account', - 'completed' => 1, - 'date' => $date->format('Y-m-d'), - ] - ); - self::createTransactions($journal, $opposing, $savings, '10000'); - - return $journal; + if (isset($this->data['rule-groups']) && is_array($this->data['rule-groups'])) { + $insert = []; + foreach ($this->data['rule-groups'] as $group) { + $insert[] = [ + 'created_at' => DB::raw('NOW()'), + 'updated_at' => DB::raw('NOW()'), + 'user_id' => $group['user_id'], + 'order' => $group['order'], + 'title' => $group['title'], + 'description' => $group['description'], + 'active' => 1, + ]; + } + DB::table('rule_groups')->insert($insert); + } + if (isset($this->data['rules']) && is_array($this->data['rules'])) { + $insert = []; + foreach ($this->data['rules'] as $rule) { + $insert[] = [ + 'created_at' => DB::raw('NOW()'), + 'updated_at' => DB::raw('NOW()'), + 'user_id' => $rule['user_id'], + 'rule_group_id' => $rule['rule_group_id'], + 'order' => $rule['order'], + 'active' => $rule['active'], + 'stop_processing' => $rule['stop_processing'], + 'title' => $rule['title'], + 'description' => $rule['description'], + ]; + } + DB::table('rules')->insert($insert); + } + if (isset($this->data['rule-triggers']) && is_array($this->data['rule-triggers'])) { + $insert = []; + foreach ($this->data['rule-triggers'] as $trigger) { + $insert[] = [ + 'created_at' => DB::raw('NOW()'), + 'updated_at' => DB::raw('NOW()'), + 'rule_id' => $trigger['rule_id'], + 'order' => $trigger['order'], + 'active' => $trigger['active'], + 'stop_processing' => $trigger['stop_processing'], + 'trigger_type' => $trigger['trigger_type'], + 'trigger_value' => $trigger['trigger_value'], + ]; + } + DB::table('rule_triggers')->insert($insert); + } + if (isset($this->data['rule-actions']) && is_array($this->data['rule-actions'])) { + $insert = []; + foreach ($this->data['rule-actions'] as $action) { + $insert[] = [ + 'created_at' => DB::raw('NOW()'), + 'updated_at' => DB::raw('NOW()'), + 'rule_id' => $action['rule_id'], + 'order' => $action['order'], + 'active' => $action['active'], + 'stop_processing' => $action['stop_processing'], + 'action_type' => $action['action_type'], + 'action_value' => $action['action_value'], + ]; + } + DB::table('rule_actions')->insert($insert); + } } + /** + * + */ + private function createTags() + { + if (isset($this->data['tags']) && is_array($this->data['tags'])) { + $insert = []; + foreach ($this->data['tags'] as $tag) { + $insert[] + = [ + 'created_at' => DB::raw('NOW()'), + 'updated_at' => DB::raw('NOW()'), + 'user_id' => $tag['user_id'], + 'tag' => Crypt::encrypt($tag['tag']), + 'tagMode' => $tag['tagMode'], + 'date' => $tag['date'] ?? null, + ]; + + } + DB::table('tags')->insert($insert); + } + } + + /** + * + */ + private function createUsers() + { + if (isset($this->data['users']) && is_array($this->data['users'])) { + $insert = []; + foreach ($this->data['users'] as $user) { + $insert[] + = [ + 'created_at' => DB::raw('NOW()'), + 'updated_at' => DB::raw('NOW()'), + 'email' => $user['email'], + 'password' => bcrypt($user['password']), + ]; + + } + DB::table('users')->insert($insert); + } + if (isset($this->data['roles']) && is_array($this->data['roles'])) { + $insert = []; + foreach ($this->data['roles'] as $role) { + $insert[] + = [ + 'user_id' => $role['user_id'], + 'role_id' => $role['role'], + ]; + } + DB::table('role_user')->insert($insert); + } + } + + /** + * + */ + private function go() + { + $this->createUsers(); + $this->createAccounts(); + $this->createBills(); + $this->createBudgets(); + $this->createCategories(); + $this->createPiggyBanks(); + $this->createRules(); + $this->createTags(); + $this->createJournals(); + $this->createAttachments(); + } } diff --git a/config/filesystems.php b/config/filesystems.php index 70e2a2c488..e41406cf51 100644 --- a/config/filesystems.php +++ b/config/filesystems.php @@ -48,14 +48,18 @@ return [ 'root' => storage_path('app'), ], - 'upload' => [ + 'upload' => [ 'driver' => 'local', 'root' => storage_path('upload'), ], - 'export' => [ + 'export' => [ 'driver' => 'local', 'root' => storage_path('export'), ], + 'database' => [ + 'driver' => 'local', + 'root' => storage_path('database'), + ], 'ftp' => [ 'driver' => 'ftp', diff --git a/database/seeds/DatabaseSeeder.php b/database/seeds/DatabaseSeeder.php index 8975b71238..9892663a49 100644 --- a/database/seeds/DatabaseSeeder.php +++ b/database/seeds/DatabaseSeeder.php @@ -21,10 +21,7 @@ class DatabaseSeeder extends Seeder $this->call('TransactionCurrencySeeder'); $this->call('TransactionTypeSeeder'); $this->call('PermissionSeeder'); - - if (App::environment() == 'testing') { - $this->call('TestDataSeeder'); - } + $this->call('TestDataSeeder'); } } diff --git a/database/seeds/TestDataSeeder.php b/database/seeds/TestDataSeeder.php index 1fe98fffe5..c0f18618c6 100644 --- a/database/seeds/TestDataSeeder.php +++ b/database/seeds/TestDataSeeder.php @@ -9,8 +9,6 @@ declare(strict_types = 1); */ use Carbon\Carbon; -use FireflyIII\Events\BudgetLimitStored; -use FireflyIII\Models\BudgetLimit; use FireflyIII\Support\Migration\TestData; use Illuminate\Database\Seeder; @@ -19,19 +17,11 @@ use Illuminate\Database\Seeder; */ class TestDataSeeder extends Seeder { - /** @var Carbon */ - public $end; - /** @var Carbon */ - public $start; - /** * TestDataSeeder constructor. */ public function __construct() { - $this->start = Carbon::create()->subYears(2)->startOfYear(); - $this->end = Carbon::now(); - } /** @@ -41,12 +31,13 @@ class TestDataSeeder extends Seeder */ public function run() { - - $current = clone $this->start; - while ($current < $this->end) { - $month = $current->format('F Y'); - - $current->addMonth(); + $disk = Storage::disk('database'); + $env = App::environment(); + $fileName = 'seed.' . $env . '.json'; + if ($disk->exists($fileName)) { + $file = json_decode($disk->get($fileName), true); + // run the file: + TestData::run($file); } } } diff --git a/storage/database/seed.local.json b/storage/database/seed.local.json index 2b6a8f17ce..7fd523c7ed 100644 --- a/storage/database/seed.local.json +++ b/storage/database/seed.local.json @@ -16,7 +16,7 @@ "roles": [ { "user_id": 1, - "role": "owner" + "role": 1 } ], "accounts": [ @@ -73,8 +73,7 @@ { "user_id": 1, "account_type_id": 4, - "name": "PLUS", - "0": "Apple" + "name": "PLUS" }, { "user_id": 1, @@ -290,69 +289,81 @@ { "name": "Another Empty Budget", "user_id": 1 + }, + { + "name": "Going out", + "user_id": 1 } ], "budget-limits": [ { "budget_id": 1, - "startdate": "2016-05-01", - "amount": 196, - "repeats": 0, + "startdate": "2016-04-01", + "amount_min": 100, + "amount_max": 200, "repeat_freq": "daily" }, { "budget_id": 1, "startdate": "2016-05-01", - "amount": 154, - "repeats": 0, + "amount_min": 100, + "amount_max": 200, "repeat_freq": "weekly" }, { "budget_id": 1, - "startdate": "2016-05-01", - "amount": 159, - "repeats": 0, + "startdate": "2016-06-01", + "amount_min": 100, + "amount_max": 200, "repeat_freq": "monthly" }, { "budget_id": 1, - "startdate": "2016-05-01", - "amount": 157, - "repeats": 0, + "startdate": "2016-07-01", + "amount_min": 100, + "amount_max": 200, "repeat_freq": "quarterly" }, { "budget_id": 1, - "startdate": "2016-05-01", - "amount": 190, - "repeats": 0, + "startdate": "2016-08-01", + "amount_min": 100, + "amount_max": 200, "repeat_freq": "half-year" }, { "budget_id": 1, - "startdate": "2016-05-01", - "amount": 145, - "repeats": 0, + "startdate": "2016-09-01", + "amount_min": 100, + "amount_max": 200, "repeat_freq": "yearly" } ], "monthly-limits": [ { "budget_id": 1, - "amount": 100 + "amount_min": 200, + "amount_max": 200 }, { "budget_id": 2, - "amount": 100 + "amount_min": 1000, + "amount_max": 1000 }, { "budget_id": 3, - "amount": 100 + "amount_min": 200, + "amount_max": 200 + }, + { + "budget_id": 6, + "amount_min": 100, + "amount_max": 100 } ], "categories": [ { - "name": "Groceries", + "name": "Daily groceries", "user_id": 1 }, { @@ -366,6 +377,14 @@ { "name": "Salary", "user_id": 1 + }, + { + "name": "Bills", + "user_id": 1 + }, + { + "name": "Going out", + "user_id": 1 } ], "piggy-banks": [ @@ -497,6 +516,7 @@ "rule_id": 1, "order": 1, "active": 1, + "stop_processing": 0, "action_type": "prepend_description", "action_value": "Bought the world from " }, @@ -504,6 +524,7 @@ "rule_id": 1, "order": 2, "active": 1, + "stop_processing": 0, "action_type": "set_category", "action_value": "Large expenses" } @@ -584,179 +605,214 @@ ], "monthly-deposits": [ { - "user": 1, + "user_id": 1, "day-of-month": 24, "description": "Salary in :month", - "source": "Job", - "destination": "Checking Account", - "min_amount": 2000, - "max_amount": 2100 + "source_id": 30, + "destination_id": 1, + "min_amount": 1500, + "max_amount": 1700, + "category_id": 4 } ], "monthly-transfers": [ { - "user": 1, + "user_id": 1, "day-of-month": 28, "description": "Saving money for :month", - "source": "Checking Account", - "destination": "Savings Account", + "source_id": 1, + "destination_id": 3, "min_amount": 150, "max_amount": 150 } ], "monthly-withdrawals": [ { - "user": 1, - "day-of-month": 2, + "user_id": 1, + "day-of-month": "02", "description": "Rent for :month", - "source": "Checking Account", - "destination": "Land lord", + "source_id": 1, + "destination_id": 29, "min_amount": 800, - "max_amount": 800 + "max_amount": 800, + "category_id": 5, + "budget_id": 2 }, { - "user": 1, - "day-of-month": 4, + "user_id": 1, + "day-of-month": "04", "description": "Water bill :month", - "source": "Checking Account", - "destination": "Land lord", - "min_amount": 800, - "max_amount": 800 + "source_id": 1, + "destination_id": 8, + "min_amount": 8, + "max_amount": 12, + "category_id": 5, + "budget_id": 2 }, { - "user": 1, - "day-of-month": 6, + "user_id": 1, + "day-of-month": "06", "description": "TV bill :month", - "source": "Checking Account", - "destination": "Land lord", - "min_amount": 800, - "max_amount": 800 + "source_id": 1, + "destination_id": 26, + "min_amount": 50, + "max_amount": 60, + "category_id": 5, + "budget_id": 2 }, { - "user": 1, - "day-of-month": 8, + "user_id": 1, + "day-of-month": "08", "description": "Power bill :month", - "source": "Checking Account", - "destination": "Land lord", - "min_amount": 800, - "max_amount": 800 + "source_id": 1, + "destination_id": 24, + "min_amount": 75, + "max_amount": 90, + "category_id": 5, + "budget_id": 2 }, { - "user": 1, - "day-of-month": 7, + "user_id": 1, + "day-of-month": "07", "description": "Bought gas", - "source": "Checking Account", - "destination": "Shell", + "source_id": 1, + "destination_id": 17, "min_amount": 40, - "max_amount": 50 + "max_amount": 50, + "category_id": 2, + "budget_id": 3 }, { - "user": 1, + "user_id": 1, "day-of-month": 17, "description": "Filled the car up again", - "source": "Checking Account", - "destination": "Shell", + "source_id": 1, + "destination_id": 17, "min_amount": 40, - "max_amount": 50 + "max_amount": 50, + "category_id": 2, + "budget_id": 3 }, { - "user": 1, + "user_id": 1, "day-of-month": 27, "description": "Needed gas again", - "source": "Checking Account", - "destination": "Shell", + "source_id": 1, + "destination_id": 17, "min_amount": 45, - "max_amount": 55 + "max_amount": 55, + "category_id": 2, + "budget_id": 3 }, { - "user": 1, - "day-of-month": 2, + "user_id": 1, + "day-of-month": "02", "description": "Groceries", - "source": "Checking Account", - "destination": "Albert Heijn", + "source_id": 1, + "destination_id": 9, "min_amount": 15, - "max_amount": 25 + "max_amount": 25, + "category_id": 1, + "budget_id": 1 }, { - "user": 1, - "day-of-month": 6, + "user_id": 1, + "day-of-month": "06", "description": "Groceries", - "source": "Checking Account", - "destination": "PLUS", + "source_id": 1, + "destination_id": 10, "min_amount": 15, - "max_amount": 25 + "max_amount": 25, + "category_id": 1, + "budget_id": 1 }, { - "user": 1, - "day-of-month": 8, + "user_id": 1, + "day-of-month": "08", "description": "Groceries", - "source": "Checking Account", - "destination": "Bakker", + "source_id": 1, + "destination_id": 11, "min_amount": 15, - "max_amount": 25 + "max_amount": 25, + "category_id": 1, + "budget_id": 1 }, { - "user": 1, + "user_id": 1, "day-of-month": 11, "description": "Groceries", - "source": "Checking Account", - "destination": "Albert Heijn", + "source_id": 1, + "destination_id": 9, "min_amount": 15, - "max_amount": 25 + "max_amount": 25, + "category_id": 1, + "budget_id": 1 }, { - "user": 1, + "user_id": 1, "day-of-month": 15, "description": "Groceries", - "source": "Checking Account", - "destination": "PLUS", + "source_id": 1, + "destination_id": 10, "min_amount": 15, - "max_amount": 25 + "max_amount": 25, + "category_id": 1, + "budget_id": 1 }, { - "user": 1, + "user_id": 1, "day-of-month": 19, "description": "Groceries", - "source": "Checking Account", - "destination": "Albert Heijn", + "source_id": 1, + "destination_id": 11, "min_amount": 15, - "max_amount": 25 + "max_amount": 25, + "category_id": 1, + "budget_id": 1 }, { - "user": 1, + "user_id": 1, "day-of-month": 23, "description": "Groceries", - "source": "Checking Account", - "destination": "Bakker", + "source_id": 1, + "destination_id": 9, "min_amount": 15, - "max_amount": 25 + "max_amount": 25, + "category_id": 1, + "budget_id": 1 }, { - "user": 1, + "user_id": 1, "day-of-month": 26, "description": "Groceries", - "source": "Checking Account", - "destination": "Albert Heijn", + "source_id": 1, + "destination_id": 10, "min_amount": 15, - "max_amount": 25 + "max_amount": 25, + "category_id": 1, + "budget_id": 1 }, { - "user": 1, - "day-of-month": 23, + "user_id": 1, + "day-of-month": 13, "description": "Going out for drinks", - "source": "Checking Account", - "destination": "Cafe Central", + "source_id": 1, + "destination_id": 14, "min_amount": 15, - "max_amount": 36 + "max_amount": 36, + "category_id": 6, + "budget_id": 6 }, { - "user": 1, + "user_id": 1, "day-of-month": 26, "description": "Going out for drinks again", - "source": "Checking Account", - "destination": "Cafe Central", + "source_id": 1, + "destination_id": 14, "min_amount": 15, - "max_amount": 36 + "max_amount": 36, + "category_id": 6, + "budget_id": 6 } ], "attachments": [ @@ -777,7 +833,7 @@ "attachable_type": "FireflyIII\\Models\\TransactionJournal", "user_id": 1, "content": "This is attachment number two.", - "filename": "empty-file.txt", + "filename": "empty-file2.txt", "title": "Empty file", "description": "This file is empty", "notes": "Some notes",