/** * @covers FireflyIII\Models\Category::firstOrCreateEncrypted */ public function testFirstOrCreateEncryptedNew() { $category = FactoryMuffin::create('FireflyIII\\Models\\Category'); $search = ['name' => 'Some category name', 'user_id' => $category->user_id]; $result = Category::firstOrCreateEncrypted($search); $this->assertNotEquals($result->id, $category->id); }
/** * @covers FireflyIII\Repositories\Category\CategoryRepository::destroy */ public function testDestroy() { $category = FactoryMuffin::create('FireflyIII\\Models\\Category'); $this->object->destroy($category); $count = Category::where('id', $category->id)->whereNull('deleted_at')->count(); $this->assertEquals(0, $count); }
/** * @param TransactionJournal $journal * * @return bool */ public function act(TransactionJournal $journal) : bool { $name = $this->action->action_value; $category = Category::firstOrCreateEncrypted(['name' => $name, 'user_id' => $journal->user->id]); $journal->categories()->sync([$category->id]); Log::debug(sprintf('RuleAction SetCategory set the category of journal #%d to budget #%d ("%s").', $journal->id, $category->id, $category->name)); return true; }
/** * @return array */ public function rules() { $nameRule = 'required|between:1,100|uniqueObjectForUser:categories,name'; if (Category::find(Input::get('id'))) { $nameRule = 'required|between:1,100|uniqueObjectForUser:categories,name,' . intval(Input::get('id')); } return ['name' => $nameRule]; }
/** * @return bool */ public function act() { $name = $this->action->action_value; $category = Category::firstOrCreateEncrypted(['name' => $name, 'user_id' => Auth::user()->id]); Log::debug('Will set category "' . $name . '" (#' . $category->id . ') on journal #' . $this->journal->id . '.'); $this->journal->categories()->sync([$category->id]); return true; }
/** * @return Category */ public function convert() { // is mapped? Then it's easy! if (isset($this->mapped[$this->index][$this->value])) { $category = Auth::user()->categories()->find($this->mapped[$this->index][$this->value]); } else { $category = Category::firstOrCreateEncrypted(['name' => $this->value, 'user_id' => Auth::user()->id]); } return $category; }
/** * @param $value * @param $route * * @return mixed */ public static function routeBinder($value, $route) : Collection { if (auth()->check()) { $ids = explode(',', $value); /** @var \Illuminate\Support\Collection $object */ $object = Category::whereIn('id', $ids)->where('user_id', auth()->user()->id)->get(); // add empty category if applicable. if (in_array('0', $ids)) { $object->push(new Category()); } if ($object->count() > 0) { return $object; } } throw new NotFoundHttpException(); }
/** * @param array $fields * * @return Category */ public static function firstOrCreateEncrypted(array $fields) { // everything but the name: $query = Category::orderBy('id'); $search = $fields; unset($search['name']); foreach ($search as $name => $value) { $query->where($name, $value); } $set = $query->get(['categories.*']); /** @var Category $category */ foreach ($set as $category) { if ($category->name == $fields['name']) { return $category; } } // create it! $category = Category::create($fields); return $category; }
/** * @param TransactionJournal $journal * @param array $transaction * * @return Collection */ public function storeTransaction(TransactionJournal $journal, array $transaction) : Collection { // store accounts (depends on type) list($sourceAccount, $destinationAccount) = $this->storeAccounts($journal->transactionType->type, $transaction); // store transaction one way: /** @var Transaction $one */ $one = Transaction::create(['account_id' => $sourceAccount->id, 'transaction_journal_id' => $journal->id, 'amount' => $transaction['amount'] * -1, 'description' => $transaction['description']]); $two = Transaction::create(['account_id' => $destinationAccount->id, 'transaction_journal_id' => $journal->id, 'amount' => $transaction['amount'], 'description' => $transaction['description']]); if (strlen($transaction['category']) > 0) { $category = Category::firstOrCreateEncrypted(['name' => $transaction['category'], 'user_id' => $journal->user_id]); $one->categories()->save($category); $two->categories()->save($category); } if (intval($transaction['budget_id']) > 0) { $budget = Budget::find($transaction['budget_id']); $one->budgets()->save($budget); $two->budgets()->save($budget); } if ($transaction['piggy_bank_id'] > 0) { $transaction['date'] = $journal->date->format('Y-m-d'); event(new TransactionStored($transaction)); } return new Collection([$one, $two]); }
/** * @param User $user */ private function createCategories(User $user) { Category::firstOrCreateEncrypted(['name' => 'Groceries', 'user_id' => $user->id]); Category::firstOrCreateEncrypted(['name' => 'Car', 'user_id' => $user->id]); }
} } throw new NotFoundHttpException(); }); Route::bind('piggyBank', function ($value) { if (Auth::check()) { $object = PiggyBank::where('piggy_banks.id', $value)->leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.account_id')->where('accounts.user_id', Auth::user()->id)->first(['piggy_banks.*']); if ($object) { return $object; } } throw new NotFoundHttpException(); }); Route::bind('category', function ($value) { if (Auth::check()) { $object = Category::where('id', $value)->where('user_id', Auth::user()->id)->first(); if ($object) { return $object; } } throw new NotFoundHttpException(); }); Route::bind('tag', function ($value) { if (Auth::check()) { $object = Tag::where('id', $value)->where('user_id', Auth::user()->id)->first(); if ($object) { return $object; } } throw new NotFoundHttpException(); });
/** * * Corrected for tags. * * @param Category $category * @param Carbon $date * * @return float */ public function earnedOnDaySumCorrected(Category $category, Carbon $date) { return $category->transactionjournals()->transactionTypes(['Deposit'])->onDate($date)->get(['transaction_journals.*'])->sum('amount'); }
private function moveCategoriesBack() { Category::get()->each(function (Category $category) { Component::firstOrCreate(['name' => $category->name, 'user_id' => $category->user_id, 'class' => 'Category']); }); }
/** * Calculate how much is earned in this period. * * @param Category $category * @param Collection $accounts * @param Carbon $start * @param Carbon $end * * @return string */ public function earnedInPeriodForAccounts(Category $category, Collection $accounts, Carbon $start, Carbon $end) { $accountIds = []; foreach ($accounts as $account) { $accountIds[] = $account->id; } $sum = $category->transactionjournals()->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')->before($end)->whereIn('transactions.account_id', $accountIds)->transactionTypes([TransactionType::DEPOSIT])->after($start)->get(['transaction_journals.*'])->sum('amount'); return $sum; }
/** * @param TransactionJournal $journal * @param array $data * * @return TransactionJournal */ public function update(TransactionJournal $journal, array $data) { // update actual journal. $journal->transaction_currency_id = $data['amount_currency_id']; $journal->description = $data['description']; $journal->date = $data['date']; // unlink all categories, recreate them: $journal->categories()->detach(); if (strlen($data['category']) > 0) { $category = Category::firstOrCreateEncrypted(['name' => $data['category'], 'user_id' => $data['user']]); $journal->categories()->save($category); } // unlink all budgets and recreate them: $journal->budgets()->detach(); if (intval($data['budget_id']) > 0) { /** @var \FireflyIII\Models\Budget $budget */ $budget = Budget::find($data['budget_id']); $journal->budgets()->save($budget); } // store accounts (depends on type) list($from, $to) = $this->storeAccounts($journal->transactionType, $data); // update the from and to transaction. /** @var Transaction $transaction */ foreach ($journal->transactions()->get() as $transaction) { if (floatval($transaction->amount) < 0) { // this is the from transaction, negative amount: $transaction->amount = $data['amount'] * -1; $transaction->account_id = $from->id; $transaction->save(); } if (floatval($transaction->amount) > 0) { $transaction->amount = $data['amount']; $transaction->account_id = $to->id; $transaction->save(); } } $journal->save(); // update tags: if (isset($data['tags']) && is_array($data['tags'])) { $this->updateTags($journal, $data['tags']); } return $journal; }
/** * This method returns the sum of the journals in the category, optionally * limited by a start or end date. * * @param Category $category * @param Carbon $start * @param Carbon $end * * @return string */ public function journalsSum(Category $category, Carbon $start = null, Carbon $end = null) { $query = $category->transactionJournals()->orderBy('transaction_journals.date', 'DESC')->orderBy('transaction_journals.order', 'ASC')->orderBy('transaction_journals.id', 'DESC'); if (!is_null($start)) { $query->after($start); } if (!is_null($end)) { $query->before($end); } return $query->get(['transaction_journals.*'])->sum('correct_amount'); }
/** * @return Twig_SimpleFunction */ public function journalCategories() : Twig_SimpleFunction { return new Twig_SimpleFunction('journalCategories', function (TransactionJournal $journal) : string { $cache = new CacheProperties(); $cache->addProperty($journal->id); $cache->addProperty('transaction-journal'); $cache->addProperty('category-string'); if ($cache->has()) { return $cache->get(); } $categories = []; // get all categories for the journal itself (easy): foreach ($journal->categories as $category) { $categories[] = '<a href="' . route('categories.show', [$category->id]) . '" title="' . e($category->name) . '">' . e($category->name) . '</a>'; } if (count($categories) === 0) { $set = Category::distinct()->leftJoin('category_transaction', 'categories.id', '=', 'category_transaction.category_id')->leftJoin('transactions', 'category_transaction.transaction_id', '=', 'transactions.id')->leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')->where('categories.user_id', $journal->user_id)->where('transaction_journals.id', $journal->id)->get(['categories.*']); /** @var Category $category */ foreach ($set as $category) { $categories[] = '<a href="' . route('categories.show', [$category->id]) . '" title="' . e($category->name) . '">' . e($category->name) . '</a>'; } } $string = join(', ', array_unique($categories)); $cache->store($string); return $string; }); }
/** * @param $name * * @return Category|null */ protected function findCategory($name) { // account $user = User::whereEmail('*****@*****.**')->first(); /** @var Category $category */ foreach (Category::get() as $category) { if ($category->name == $name && $user->id == $category->user_id) { return $category; break; } } return null; }
public function moveCategories() { Component::where('class', 'Category')->get()->each(function (Component $c) { $entry = ['user_id' => $c->user_id, 'name' => $c->name]; $category = Category::firstOrCreate($entry); Log::debug('Migrated category #' . $category->id . ': ' . $category->name); // create entry in category_transaction_journal $connections = DB::table('component_transaction_journal')->where('component_id', $c->id)->get(); foreach ($connections as $connection) { DB::table('category_transaction_journal')->insert(['category_id' => $category->id, 'transaction_journal_id' => $connection->transaction_journal_id]); } }); }
/** * @param Category $category * @param array $data * * @return Category */ public function update(Category $category, array $data) { // update the account: $category->name = $data['name']; $category->save(); return $category; }
/** * Reports on categories without any transactions. */ private function reportCategories() { $set = Category::leftJoin('category_transaction_journal', 'categories.id', '=', 'category_transaction_journal.category_id')->leftJoin('users', 'categories.user_id', '=', 'users.id')->distinct()->whereNull('category_transaction_journal.category_id')->whereNull('categories.deleted_at')->get(['categories.id', 'categories.name', 'categories.user_id', 'users.email']); /** @var stdClass $entry */ foreach ($set as $entry) { $line = 'Notice: User #' . $entry->user_id . ' (' . $entry->email . ') has category #' . $entry->id . ' ("' . Crypt::decrypt($entry->name) . '") which has no transactions.'; $this->line($line); } }
/** * @param $name * * @return Category|null */ protected function findCategory($name) { /** @var Category $category */ foreach (Category::get() as $category) { if ($category->name == $name && $this->user->id == $category->user_id) { return $category; break; } } return null; }
/** * @param TransactionJournal $journal * @param array $data * * @return TransactionJournal */ public function update(TransactionJournal $journal, array $data) : TransactionJournal { // update actual journal. $journal->transaction_currency_id = $data['amount_currency_id_amount']; $journal->description = $data['description']; $journal->date = $data['date']; // unlink all categories, recreate them: $journal->categories()->detach(); if (strlen($data['category']) > 0) { $category = Category::firstOrCreateEncrypted(['name' => $data['category'], 'user_id' => $data['user']]); $journal->categories()->save($category); } // unlink all budgets and recreate them: $journal->budgets()->detach(); if (intval($data['budget_id']) > 0 && $journal->transactionType->type !== TransactionType::TRANSFER) { /** @var \FireflyIII\Models\Budget $budget */ $budget = Budget::where('user_id', $this->user->id)->where('id', $data['budget_id'])->first(); $journal->budgets()->save($budget); } // store accounts (depends on type) list($fromAccount, $toAccount) = $this->storeAccounts($journal->transactionType, $data); // update the from and to transaction. /** @var Transaction $transaction */ foreach ($journal->transactions()->get() as $transaction) { if ($transaction->amount < 0) { // this is the from transaction, negative amount: $transaction->amount = $data['amount'] * -1; $transaction->account_id = $fromAccount->id; $transaction->save(); } if ($transaction->amount > 0) { $transaction->amount = $data['amount']; $transaction->account_id = $toAccount->id; $transaction->save(); } } $journal->save(); // update tags: if (isset($data['tags']) && is_array($data['tags'])) { $this->updateTags($journal, $data['tags']); } // update meta fields: $result = $journal->save(); if ($result) { foreach ($data as $key => $value) { if (in_array($key, $this->validMetaFields)) { $journal->setMeta($key, $value); continue; } Log::debug(sprintf('Could not store meta field "%s" with value "%s" for journal #%d', json_encode($key), json_encode($value), $journal->id)); } return $journal; } return $journal; }