diff --git a/app/Crud/Split/Journal.php b/app/Crud/Split/Journal.php index 0f9b6dbc1a..c81c65edf1 100644 --- a/app/Crud/Split/Journal.php +++ b/app/Crud/Split/Journal.php @@ -54,40 +54,6 @@ class Journal implements JournalInterface return true; } - /** - * @param array $data - * - * @return TransactionJournal - */ - public function storeJournal(array $data) : TransactionJournal - { - // find transaction type. - $transactionType = TransactionType::where('type', ucfirst($data['what']))->first(); - $journal = new TransactionJournal( - [ - 'user_id' => $this->user->id, - 'transaction_type_id' => $transactionType->id, - 'transaction_currency_id' => $data['journal_currency_id'], - 'description' => $data['journal_description'], - 'completed' => 0, - 'date' => $data['date'], - 'interest_date' => $data['interest_date'], - 'book_date' => $data['book_date'], - 'process_date' => $data['process_date'], - ] - ); - $journal->save(); - - foreach ($data['transactions'] as $transaction) { - $this->storeTransaction($journal, $transaction); - } - - $journal->completed = true; - $journal->save(); - - return $journal; - } - /** * @param TransactionJournal $journal * @param array $transaction @@ -101,32 +67,20 @@ class Journal implements JournalInterface // store transaction one way: /** @var Transaction $one */ - $one = Transaction::create( // first transaction. - [ - 'account_id' => $sourceAccount->id, - 'transaction_journal_id' => $journal->id, - 'amount' => $transaction['amount'] * -1, - 'description' => $transaction['description'], - ] + $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']] ); - // store transaction the other way: - $two = Transaction::create( // first transaction. - [ - 'account_id' => $destinationAccount->id, - 'transaction_journal_id' => $journal->id, - 'amount' => $transaction['amount'], - 'description' => $transaction['description'], - ] - ); - - // store or get category and connect: if (strlen($transaction['category']) > 0) { $category = Category::firstOrCreateEncrypted(['name' => $transaction['category'], 'user_id' => $journal->user_id]); $one->categories()->save($category); $two->categories()->save($category); } - // store or get budget if (intval($transaction['budget_id']) > 0) { $budget = Budget::find($transaction['budget_id']); $one->budgets()->save($budget); @@ -134,14 +88,11 @@ class Journal implements JournalInterface } if ($transaction['piggy_bank_id'] > 0) { - // add some extra meta information to the transaction data - $transaction['transaction_journal_id'] = $journal->id; - $transaction['date'] = $journal->date->format('Y-m-d'); + $transaction['date'] = $journal->date->format('Y-m-d'); event(new TransactionStored($transaction)); } return new Collection([$one, $two]); - } /** @@ -215,20 +166,20 @@ class Journal implements JournalInterface $destinationAccount = Account::where('user_id', $this->user->id)->where('id', $data['destination_account_id'])->first(['accounts.*']); if (strlen($data['source_account_name']) > 0) { - $fromType = AccountType::where('type', 'Revenue account')->first(); - $fromAccount = Account::firstOrCreateEncrypted( - ['user_id' => $this->user->id, 'account_type_id' => $fromType->id, 'name' => $data['source_account_name'], 'active' => 1] + $sourceType = AccountType::where('type', 'Revenue account')->first(); + $sourceAccount = Account::firstOrCreateEncrypted( + ['user_id' => $this->user->id, 'account_type_id' => $sourceType->id, 'name' => $data['source_account_name'], 'active' => 1] ); - return [$fromAccount, $destinationAccount]; - } else { - $fromType = AccountType::where('type', 'Cash account')->first(); - $fromAccount = Account::firstOrCreateEncrypted( - ['user_id' => $this->user->id, 'account_type_id' => $fromType->id, 'name' => 'Cash account', 'active' => 1] - ); + return [$sourceAccount, $destinationAccount]; } - return [$fromAccount, $destinationAccount]; + $sourceType = AccountType::where('type', 'Cash account')->first(); + $sourceAccount = Account::firstOrCreateEncrypted( + ['user_id' => $this->user->id, 'account_type_id' => $sourceType->id, 'name' => 'Cash account', 'active' => 1] + ); + + return [$sourceAccount, $destinationAccount]; } /** diff --git a/app/Crud/Split/JournalInterface.php b/app/Crud/Split/JournalInterface.php index d4a111f14d..f7542b4434 100644 --- a/app/Crud/Split/JournalInterface.php +++ b/app/Crud/Split/JournalInterface.php @@ -27,13 +27,6 @@ interface JournalInterface */ public function markAsComplete(TransactionJournal $journal); - /** - * @param array $data - * - * @return TransactionJournal - */ - public function storeJournal(array $data) : TransactionJournal; - /** * @param TransactionJournal $journal * @param array $transaction diff --git a/app/Export/Exporter/CsvExporter.php b/app/Export/Exporter/CsvExporter.php index c7256ccb47..a42cfd5467 100644 --- a/app/Export/Exporter/CsvExporter.php +++ b/app/Export/Exporter/CsvExporter.php @@ -13,6 +13,7 @@ namespace FireflyIII\Export\Exporter; use FireflyIII\Export\Entry\Entry; use FireflyIII\Export\Entry\EntryAccount; use FireflyIII\Models\ExportJob; +use Illuminate\Support\Collection; use League\Csv\Writer; use SplFileObject; @@ -55,92 +56,33 @@ class CsvExporter extends BasicExporter implements ExporterInterface // necessary for CSV writer: $fullPath = storage_path('export') . DIRECTORY_SEPARATOR . $this->fileName; + $writer = Writer::createFromPath(new SplFileObject($fullPath, 'a+'), 'w'); + $rows = []; - // create CSV writer: - $writer = Writer::createFromPath(new SplFileObject($fullPath, 'a+'), 'w'); - - // all rows: - $rows = []; - - /* - * Count the maximum number of sources and destinations - * each entry has. May need to expand the number of export fields: - */ - $maxSourceAccounts = 1; - $maxDestinationAccounts = 1; + // Count the maximum number of sources and destinations each entry has. May need to expand the number of export fields: + $maxSourceAccounts = 1; + $maxDestAccounts = 1; /** @var Entry $entry */ foreach ($this->getEntries() as $entry) { - $sources = $entry->sourceAccounts->count(); - $destinations = $entry->destinationAccounts->count(); - $maxSourceAccounts = max($maxSourceAccounts, $sources); - $maxDestinationAccounts = max($maxDestinationAccounts, $destinations); + $sources = $entry->sourceAccounts->count(); + $destinations = $entry->destinationAccounts->count(); + $maxSourceAccounts = max($maxSourceAccounts, $sources); + $maxDestAccounts = max($maxDestAccounts, $destinations); } + $rows[] = array_keys($this->getFieldsAndTypes($maxSourceAccounts, $maxDestAccounts)); - // add header: - $rows[] = array_keys($this->getFieldsAndTypes($maxSourceAccounts, $maxDestinationAccounts)); - - // then the rest: /** @var Entry $entry */ foreach ($this->getEntries() as $entry) { // order is defined in Entry::getFieldsAndTypes. - $current = [ - $entry->description, - $entry->amount, - $entry->date]; - for ($i = 0; $i < $maxSourceAccounts; $i++) { - /** @var EntryAccount $source */ - $source = $entry->sourceAccounts->get($i); - $currentId = ''; - $currentName = ''; - $currentIban = ''; - $currentType = ''; - $currentNumber = ''; - if ($source) { - $currentId = $source->accountId; - $currentName = $source->name; - $currentIban = $source->iban; - $currentType = $source->type; - $currentNumber = $source->number; - } - $current[] = $currentId; - $current[] = $currentName; - $current[] = $currentIban; - $current[] = $currentType; - $current[] = $currentNumber; - } - unset($source); - for ($i = 0; $i < $maxDestinationAccounts; $i++) { - /** @var EntryAccount $destination */ - $destination = $entry->destinationAccounts->get($i); - $currentId = ''; - $currentName = ''; - $currentIban = ''; - $currentType = ''; - $currentNumber = ''; - if ($destination) { - $currentId = $destination->accountId; - $currentName = $destination->name; - $currentIban = $destination->iban; - $currentType = $destination->type; - $currentNumber = $destination->number; - } - $current[] = $currentId; - $current[] = $currentName; - $current[] = $currentIban; - $current[] = $currentType; - $current[] = $currentNumber; - } - unset($destination); - - - $current[] = $entry->budget->budgetId; - $current[] = $entry->budget->name; - $current[] = $entry->category->categoryId; - $current[] = $entry->category->name; - $current[] = $entry->bill->billId; - $current[] = $entry->bill->name; - $rows[] = $current; - + $current = [$entry->description, $entry->amount, $entry->date]; + $sourceData = $this->getAccountData($maxSourceAccounts, $entry->sourceAccounts); + $current = array_merge($current, $sourceData); + $destData = $this->getAccountData($maxDestAccounts, $entry->destinationAccounts); + $current = array_merge($current, $destData); + $rest = [$entry->budget->budgetId, $entry->budget->name, $entry->category->categoryId, $entry->category->name, $entry->bill->billId, + $entry->bill->name]; + $current = array_merge($current, $rest); + $rows[] = $current; } $writer->insertAll($rows); @@ -148,6 +90,44 @@ class CsvExporter extends BasicExporter implements ExporterInterface } /** + * @param int $max + * @param Collection $accounts + * + * @return array + */ + private function getAccountData(int $max, Collection $accounts): array + { + $current = []; + for ($i = 0; $i < $max; $i++) { + /** @var EntryAccount $source */ + $source = $accounts->get($i); + $currentId = ''; + $currentName = ''; + $currentIban = ''; + $currentType = ''; + $currentNumber = ''; + if ($source) { + $currentId = $source->accountId; + $currentName = $source->name; + $currentIban = $source->iban; + $currentType = $source->type; + $currentNumber = $source->number; + } + $current[] = $currentId; + $current[] = $currentName; + $current[] = $currentIban; + $current[] = $currentType; + $current[] = $currentNumber; + } + unset($source); + + return $current; + } + + /** + * @param int $sources + * @param int $destinations + * * @return array */ private function getFieldsAndTypes(int $sources, int $destinations): array diff --git a/app/Helpers/Report/BalanceReportHelper.php b/app/Helpers/Report/BalanceReportHelper.php index a4d7d5d3ea..13e082ea41 100644 --- a/app/Helpers/Report/BalanceReportHelper.php +++ b/app/Helpers/Report/BalanceReportHelper.php @@ -18,12 +18,10 @@ use FireflyIII\Helpers\Collection\BalanceEntry; use FireflyIII\Helpers\Collection\BalanceHeader; use FireflyIII\Helpers\Collection\BalanceLine; use FireflyIII\Models\Budget; -use FireflyIII\Models\Budget as BudgetModel; use FireflyIII\Models\LimitRepetition; use FireflyIII\Models\Tag; use FireflyIII\Models\TransactionType; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; -use FireflyIII\Repositories\Tag\TagRepositoryInterface; use Illuminate\Database\Query\JoinClause; use Illuminate\Support\Collection; @@ -37,20 +35,16 @@ class BalanceReportHelper implements BalanceReportHelperInterface /** @var BudgetRepositoryInterface */ protected $budgetRepository; - /** @var TagRepositoryInterface */ - protected $tagRepository; /** * ReportHelper constructor. * * * @param BudgetRepositoryInterface $budgetRepository - * @param TagRepositoryInterface $tagRepository */ - public function __construct(BudgetRepositoryInterface $budgetRepository, TagRepositoryInterface $tagRepository) + public function __construct(BudgetRepositoryInterface $budgetRepository) { $this->budgetRepository = $budgetRepository; - $this->tagRepository = $tagRepository; } @@ -148,13 +142,11 @@ class BalanceReportHelper implements BalanceReportHelperInterface * * @return BalanceLine */ - private function createBalanceLine(BudgetModel $budget, LimitRepetition $repetition, Collection $accounts): BalanceLine + private function createBalanceLine(Budget $budget, LimitRepetition $repetition, Collection $accounts): BalanceLine { $line = new BalanceLine; $budget->amount = $repetition->amount; $line->setBudget($budget); - - $line->setStartDate($repetition->startdate); $line->setEndDate($repetition->enddate); @@ -185,7 +177,6 @@ class BalanceReportHelper implements BalanceReportHelperInterface $noBudgetEntries = $noBudgetLine->getBalanceEntries(); $tagEntries = $coveredByTagLine->getBalanceEntries(); - /** @var BalanceEntry $entry */ foreach ($noBudgetEntries as $entry) { $account = $entry->getAccount(); $tagEntry = $tagEntries->filter( @@ -221,7 +212,6 @@ class BalanceReportHelper implements BalanceReportHelperInterface foreach ($accounts as $account) { $spent = $this->budgetRepository->spentInPeriodWithoutBudget(new Collection([$account]), $start, $end); - //$spent ='0'; // budget $budgetEntry = new BalanceEntry; $budgetEntry->setAccount($account); @@ -278,11 +268,9 @@ class BalanceReportHelper implements BalanceReportHelperInterface { $set = $balance->getBalanceLines(); $newSet = new Collection; - /** @var BalanceLine $entry */ foreach ($set as $entry) { if (!is_null($entry->getBudget()->id)) { $sum = '0'; - /** @var BalanceEntry $balanceEntry */ foreach ($entry->getBalanceEntries() as $balanceEntry) { $sum = bcadd($sum, $balanceEntry->getSpent()); } diff --git a/app/Helpers/Report/BudgetReportHelper.php b/app/Helpers/Report/BudgetReportHelper.php index 9c5d658f81..946756ccd5 100644 --- a/app/Helpers/Report/BudgetReportHelper.php +++ b/app/Helpers/Report/BudgetReportHelper.php @@ -16,7 +16,6 @@ use FireflyIII\Helpers\Collection\Budget as BudgetCollection; use FireflyIII\Helpers\Collection\BudgetLine; use FireflyIII\Models\Budget; use FireflyIII\Models\LimitRepetition; -use FireflyIII\Models\TransactionJournal; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use Illuminate\Support\Collection; @@ -27,6 +26,18 @@ use Illuminate\Support\Collection; */ class BudgetReportHelper implements BudgetReportHelperInterface { + /** @var BudgetRepositoryInterface */ + private $repository; + + /** + * BudgetReportHelper constructor. + * + * @param BudgetRepositoryInterface $repository + */ + public function __construct(BudgetRepositoryInterface $repository) + { + $this->repository = $repository; + } /** * @param Carbon $start @@ -38,9 +49,7 @@ class BudgetReportHelper implements BudgetReportHelperInterface public function getBudgetReport(Carbon $start, Carbon $end, Collection $accounts): BudgetCollection { $object = new BudgetCollection; - /** @var BudgetRepositoryInterface $repository */ - $repository = app(BudgetRepositoryInterface::class); - $set = $repository->getBudgets(); + $set = $this->repository->getBudgets(); /** @var Budget $budget */ foreach ($set as $budget) { @@ -49,7 +58,7 @@ class BudgetReportHelper implements BudgetReportHelperInterface // no repetition(s) for this budget: if ($repetitions->count() == 0) { // spent for budget in time range: - $spent = $repository->spentInPeriod(new Collection([$budget]), $accounts, $start, $end); + $spent = $this->repository->spentInPeriod(new Collection([$budget]), $accounts, $start, $end); if ($spent > 0) { $budgetLine = new BudgetLine; @@ -63,24 +72,20 @@ class BudgetReportHelper implements BudgetReportHelperInterface // one or more repetitions for budget: /** @var LimitRepetition $repetition */ foreach ($repetitions as $repetition) { + $data = $this->calculateExpenses($budget, $repetition, $accounts); $budgetLine = new BudgetLine; $budgetLine->setBudget($budget); $budgetLine->setRepetition($repetition); - $expenses = $repository->spentInPeriod(new Collection([$budget]), $accounts, $repetition->startdate, $repetition->enddate); - $left = bccomp(bcadd($repetition->amount, $expenses), '0') === 1 ? bcadd($repetition->amount, $expenses) : '0'; - $spent = bccomp(bcadd($repetition->amount, $expenses), '0') === 1 ? $expenses : '0'; - $overspent = bccomp(bcadd($repetition->amount, $expenses), '0') === 1 ? '0' : bcadd($expenses, $repetition->amount); - - $budgetLine->setLeft($left); - $budgetLine->setSpent($expenses); - $budgetLine->setOverspent($overspent); + $budgetLine->setLeft($data['left']); + $budgetLine->setSpent($data['expenses']); + $budgetLine->setOverspent($data['overspent']); $budgetLine->setBudgeted($repetition->amount); $object->addBudgeted($repetition->amount); - $object->addSpent($spent); - $object->addLeft($left); - $object->addOverspent($overspent); + $object->addSpent($data['spent']); + $object->addLeft($data['left']); + $object->addOverspent($data['overspent']); $object->addBudgetLine($budgetLine); } @@ -88,12 +93,8 @@ class BudgetReportHelper implements BudgetReportHelperInterface } // stuff outside of budgets: - $outsideBudget = $repository->journalsInPeriodWithoutBudget($accounts, $start, $end); - $noBudget = '0'; - /** @var TransactionJournal $journal */ - foreach ($outsideBudget as $journal) { - $noBudget = bcadd($noBudget, TransactionJournal::amount($journal)); - } + + $noBudget = $this->repository->spentInPeriodWithoutBudget($accounts, $start, $end); $budgetLine = new BudgetLine; $budgetLine->setOverspent($noBudget); $budgetLine->setSpent($noBudget); @@ -159,4 +160,23 @@ class BudgetReportHelper implements BudgetReportHelperInterface return $sum; } + + /** + * @param Budget $budget + * @param LimitRepetition $repetition + * @param Collection $accounts + * + * @return array + */ + private function calculateExpenses(Budget $budget, LimitRepetition $repetition, Collection $accounts): array + { + $array = []; + $expenses = $this->repository->spentInPeriod(new Collection([$budget]), $accounts, $repetition->startdate, $repetition->enddate); + $array['left'] = bccomp(bcadd($repetition->amount, $expenses), '0') === 1 ? bcadd($repetition->amount, $expenses) : '0'; + $array['spent'] = bccomp(bcadd($repetition->amount, $expenses), '0') === 1 ? $expenses : '0'; + $array['overspent'] = bccomp(bcadd($repetition->amount, $expenses), '0') === 1 ? '0' : bcadd($expenses, $repetition->amount); + + return $array; + + } }