Sort by alphabet.

This commit is contained in:
James Cole 2016-01-20 15:21:27 +01:00
parent 6938f8ab89
commit c84f4e2bc0
5 changed files with 796 additions and 803 deletions

View File

@ -34,6 +34,24 @@ class BillRepository implements BillRepositoryInterface
return $bill->delete();
}
/**
* @return Collection
*/
public function getActiveBills()
{
/** @var Collection $set */
$set = Auth::user()->bills()
->where('active', 1)
->get(
[
'bills.*',
DB::Raw('(`bills`.`amount_min` + `bills`.`amount_max` / 2) as `expectedAmount`'),
]
)->sortBy('name');
return $set;
}
/**
* Returns all journals connected to these bills in the given range. Amount paid
* is stored in "journalAmount" as a negative number.
@ -68,7 +86,6 @@ class BillRepository implements BillRepositoryInterface
return $set;
}
/**
* @return Collection
*/
@ -125,6 +142,127 @@ class BillRepository implements BillRepositoryInterface
return $set;
}
/**
* Get the total amount of money paid for the users active bills in the date range given.
* This amount will be negative (they're expenses).
*
* @param Carbon $start
* @param Carbon $end
*
* @return string
*/
public function getBillsPaidInRange(Carbon $start, Carbon $end)
{
$amount = '0';
$bills = $this->getActiveBills();
/** @var Bill $bill */
foreach ($bills as $bill) {
$ranges = $this->getRanges($bill, $start, $end);
foreach ($ranges as $range) {
$paid = $bill->transactionjournals()
->before($range['end'])
->after($range['start'])
->leftJoin(
'transactions', function (JoinClause $join) {
$join->on('transactions.transaction_journal_id', '=', 'transaction_journals.id')->where('transactions.amount', '<', 0);
}
)
->first([DB::Raw('SUM(`transactions`.`amount`) as `sum_amount`')]);
$amount = bcadd($amount, $paid->sum_amount);
}
}
return $amount;
}
/**
* Get the total amount of money due for the users active bills in the date range given. This amount will be positive.
*
* @param Carbon $start
* @param Carbon $end
*
* @return string
*/
public function getBillsUnpaidInRange(Carbon $start, Carbon $end)
{
$amount = '0';
$bills = $this->getActiveBills();
/** @var Bill $bill */
foreach ($bills as $bill) {
$ranges = $this->getRanges($bill, $start, $end);
$paidBill = '0';
foreach ($ranges as $range) {
$paid = $bill->transactionjournals()
->before($range['end'])
->after($range['start'])
->leftJoin(
'transactions', function (JoinClause $join) {
$join->on('transactions.transaction_journal_id', '=', 'transaction_journals.id')->where('transactions.amount', '>', 0);
}
)
->first([DB::Raw('SUM(`transactions`.`amount`) as `sum_amount`')]);
$paidBill = bcadd($paid->sum_amount, $paidBill);
}
if ($paidBill == 0) {
$amount = bcadd($amount, $bill->expectedAmount);
}
}
return $amount;
}
/**
* This method will tell you if you still have a CC bill to pay. Amount will be positive if the amount
* has been paid, otherwise it will be negative.
*
* @param Carbon $start
* @param Carbon $end
*
* @return string
*/
public function getCreditCardBill(Carbon $start, Carbon $end)
{
/** @var AccountRepositoryInterface $accountRepository */
$accountRepository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
$amount = '0';
$creditCards = $accountRepository->getCreditCards($end); // Find credit card accounts and possibly unpaid credit card bills.
/** @var Account $creditCard */
foreach ($creditCards as $creditCard) {
if ($creditCard->balance == 0) {
// find a transfer TO the credit card which should account for anything paid. If not, the CC is not yet used.
$set = TransactionJournal::whereIn(
'transaction_journals.id', function (Builder $q) use ($creditCard, $start, $end) {
$q->select('transaction_journals.id')
->from('transactions')
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
->where('transactions.account_id', $creditCard->id)
->where('transactions.amount', '>', 0)// this makes the filter unnecessary.
->where('transaction_journals.user_id', Auth::user()->id)
->where('transaction_journals.date', '>=', $start->format('Y-m-d'))
->where('transaction_journals.date', '<=', $end->format('Y-m-d'))
->where('transaction_types.type', TransactionType::TRANSFER);
}
)->leftJoin(
'transactions', function (JoinClause $join) {
$join->on('transactions.transaction_journal_id', '=', 'transaction_journals.id')->where('transactions.amount', '>', 0);
}
)->first([DB::Raw('SUM(`transactions`.`amount`) as `sum_amount`')]);
$amount = bcadd($amount, $set->sum_amount);
} else {
$amount = bcadd($amount, $creditCard->balance);
}
}
return $amount;
}
/**
* This method also returns the amount of the journal in "journalAmount"
* for easy access.
@ -173,8 +311,9 @@ class BillRepository implements BillRepositoryInterface
*/
public function getPossiblyRelatedJournals(Bill $bill)
{
$set = DB::table('transactions')->where('amount', '>', 0)->where('amount', '>=', $bill->amount_min)->where('amount', '<=', $bill->amount_max)->get(
['transaction_journal_id']
$set = new Collection(
DB::table('transactions')->where('amount', '>', 0)->where('amount', '>=', $bill->amount_min)->where('amount', '<=', $bill->amount_max)
->get(['transaction_journal_id'])
);
$ids = $set->pluck('transaction_journal_id')->toArray();
@ -392,6 +531,22 @@ class BillRepository implements BillRepositoryInterface
return $bill;
}
/**
* @param float $amount
* @param float $min
* @param float $max
*
* @return bool
*/
protected function doAmountMatch($amount, $min, $max)
{
if ($amount >= $min && $amount <= $max) {
return true;
}
return false;
}
/**
* @param array $matches
* @param $description
@ -413,160 +568,4 @@ class BillRepository implements BillRepositoryInterface
return $wordMatch;
}
/**
* @param float $amount
* @param float $min
* @param float $max
*
* @return bool
*/
protected function doAmountMatch($amount, $min, $max)
{
if ($amount >= $min && $amount <= $max) {
return true;
}
return false;
}
/**
* Get the total amount of money paid for the users active bills in the date range given.
* This amount will be negative (they're expenses).
*
* @param Carbon $start
* @param Carbon $end
*
* @return string
*/
public function getBillsPaidInRange(Carbon $start, Carbon $end)
{
$amount = '0';
$bills = $this->getActiveBills();
/** @var Bill $bill */
foreach ($bills as $bill) {
$ranges = $this->getRanges($bill, $start, $end);
foreach ($ranges as $range) {
$paid = $bill->transactionjournals()
->before($range['end'])
->after($range['start'])
->leftJoin(
'transactions', function (JoinClause $join) {
$join->on('transactions.transaction_journal_id', '=', 'transaction_journals.id')->where('transactions.amount', '<', 0);
}
)
->first([DB::Raw('SUM(`transactions`.`amount`) as `sum_amount`')]);
$amount = bcadd($amount, $paid->sum_amount);
}
}
return $amount;
}
/**
* @return Collection
*/
public function getActiveBills()
{
/** @var Collection $set */
$set = Auth::user()->bills()
->where('active', 1)
->get(
[
'bills.*',
DB::Raw('(`bills`.`amount_min` + `bills`.`amount_max` / 2) as `expectedAmount`'),
]
)->sortBy('name');
return $set;
}
/**
* Get the total amount of money due for the users active bills in the date range given. This amount will be positive.
*
* @param Carbon $start
* @param Carbon $end
*
* @return string
*/
public function getBillsUnpaidInRange(Carbon $start, Carbon $end)
{
$amount = '0';
$bills = $this->getActiveBills();
/** @var Bill $bill */
foreach ($bills as $bill) {
$ranges = $this->getRanges($bill, $start, $end);
$paidBill = '0';
foreach ($ranges as $range) {
$paid = $bill->transactionjournals()
->before($range['end'])
->after($range['start'])
->leftJoin(
'transactions', function (JoinClause $join) {
$join->on('transactions.transaction_journal_id', '=', 'transaction_journals.id')->where('transactions.amount', '>', 0);
}
)
->first([DB::Raw('SUM(`transactions`.`amount`) as `sum_amount`')]);
$paidBill = bcadd($paid->sum_amount, $paidBill);
}
if ($paidBill == 0) {
$amount = bcadd($amount, $bill->expectedAmount);
}
}
return $amount;
}
/**
* This method will tell you if you still have a CC bill to pay. Amount will be positive if the amount
* has been paid, otherwise it will be negative.
*
* @param Carbon $start
* @param Carbon $end
*
* @return string
*/
public function getCreditCardBill(Carbon $start, Carbon $end)
{
/** @var AccountRepositoryInterface $accountRepository */
$accountRepository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
$amount = '0';
$creditCards = $accountRepository->getCreditCards($end); // Find credit card accounts and possibly unpaid credit card bills.
/** @var Account $creditCard */
foreach ($creditCards as $creditCard) {
if ($creditCard->balance == 0) {
// find a transfer TO the credit card which should account for anything paid. If not, the CC is not yet used.
$set = TransactionJournal::whereIn(
'transaction_journals.id', function (Builder $q) use ($creditCard, $start, $end) {
$q->select('transaction_journals.id')
->from('transactions')
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
->where('transactions.account_id', $creditCard->id)
->where('transactions.amount', '>', 0)// this makes the filter unnecessary.
->where('transaction_journals.user_id', Auth::user()->id)
->where('transaction_journals.date', '>=', $start->format('Y-m-d'))
->where('transaction_journals.date', '<=', $end->format('Y-m-d'))
->where('transaction_types.type', TransactionType::TRANSFER);
}
)->leftJoin(
'transactions', function (JoinClause $join) {
$join->on('transactions.transaction_journal_id', '=', 'transaction_journals.id')->where('transactions.amount', '>', 0);
}
)->first([DB::Raw('SUM(`transactions`.`amount`) as `sum_amount`')]);
$amount = bcadd($amount, $set->sum_amount);
} else {
$amount = bcadd($amount, $creditCard->balance);
}
}
return $amount;
}
}

View File

@ -16,15 +16,42 @@ interface BillRepositoryInterface
{
/**
* This method will tell you if you still have a CC bill to pay. Amount will be negative if the amount
* has been paid
* @param Bill $bill
*
* @return mixed
*/
public function destroy(Bill $bill);
/**
* @return Collection
*/
public function getActiveBills();
/**
* Returns all journals connected to these bills in the given range. Amount paid
* is stored in "journalAmount" as a negative number.
*
* @param Collection $bills
* @param Carbon $start
* @param Carbon $end
*
* @return string
* @return Collection
*/
public function getCreditCardBill(Carbon $start, Carbon $end);
public function getAllJournalsInRange(Collection $bills, Carbon $start, Carbon $end);
/**
* @return Collection
*/
public function getBills();
/**
* Gets the bills which have some kind of relevance to the accounts mentioned.
*
* @param Collection $accounts
*
* @return Collection
*/
public function getBillsForAccounts(Collection $accounts);
/**
* Get the total amount of money paid for the users active bills in the date range given.
@ -47,44 +74,15 @@ interface BillRepositoryInterface
public function getBillsUnpaidInRange(Carbon $start, Carbon $end);
/**
* @return Collection
*/
public function getActiveBills();
/**
* @param Bill $bill
* This method will tell you if you still have a CC bill to pay. Amount will be negative if the amount
* has been paid
*
* @return mixed
*/
public function destroy(Bill $bill);
/**
* Returns all journals connected to these bills in the given range. Amount paid
* is stored in "journalAmount" as a negative number.
*
* @param Collection $bills
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
* @return string
*/
public function getAllJournalsInRange(Collection $bills, Carbon $start, Carbon $end);
/**
* @return Collection
*/
public function getBills();
/**
* Gets the bills which have some kind of relevance to the accounts mentioned.
*
* @param Collection $accounts
*
* @return Collection
*/
public function getBillsForAccounts(Collection $accounts);
public function getCreditCardBill(Carbon $start, Carbon $end);
/**
* @param Bill $bill

View File

@ -25,6 +25,19 @@ use Input;
class BudgetRepository extends ComponentRepository implements BudgetRepositoryInterface
{
/**
* @param Budget $budget
* @param Carbon $start
* @param Carbon $end
* @param Collection $accounts
*
* @return string
*/
public function balanceInPeriod(Budget $budget, Carbon $start, Carbon $end, Collection $accounts)
{
return $this->commonBalanceInPeriod($budget, $start, $end, $accounts);
}
/**
* @return void
*/
@ -35,6 +48,299 @@ class BudgetRepository extends ComponentRepository implements BudgetRepositoryIn
}
/**
* @param Budget $budget
*
* @return boolean
*/
public function destroy(Budget $budget)
{
$budget->delete();
return true;
}
/**
* @param Budget $budget
*
* @return Carbon
*/
public function firstActivity(Budget $budget)
{
$first = $budget->transactionjournals()->orderBy('date', 'ASC')->first();
if ($first) {
return $first->date;
}
return new Carbon;
}
/**
* @return Collection
*/
public function getActiveBudgets()
{
/** @var Collection $set */
$set = Auth::user()->budgets()->where('active', 1)->get();
$set = $set->sortBy(
function (Budget $budget) {
return strtolower($budget->name);
}
);
return $set;
}
/**
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function getAllBudgetLimitRepetitions(Carbon $start, Carbon $end)
{
/** @var Collection $repetitions */
return LimitRepetition::
leftJoin('budget_limits', 'limit_repetitions.budget_limit_id', '=', 'budget_limits.id')
->leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id')
->where('limit_repetitions.startdate', '<=', $end->format('Y-m-d 00:00:00'))
->where('limit_repetitions.startdate', '>=', $start->format('Y-m-d 00:00:00'))
->where('budgets.user_id', Auth::user()->id)
->get(['limit_repetitions.*', 'budget_limits.budget_id']);
}
/**
* Get the budgeted amounts for each budgets in each year.
*
* @param Collection $budgets
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function getBudgetedPerYear(Collection $budgets, Carbon $start, Carbon $end)
{
$budgetIds = $budgets->pluck('id')->toArray();
$set = Auth::user()->budgets()
->leftJoin('budget_limits', 'budgets.id', '=', 'budget_limits.budget_id')
->leftJoin('limit_repetitions', 'limit_repetitions.budget_limit_id', '=', 'budget_limits.id')
->where('limit_repetitions.startdate', '>=', $start->format('Y-m-d'))
->where('limit_repetitions.enddate', '<=', $end->format('Y-m-d'))
->groupBy('budgets.id')
->groupBy('dateFormatted')
->whereIn('budgets.id', $budgetIds)
->get(
[
'budgets.*',
DB::Raw('DATE_FORMAT(`limit_repetitions`.`startdate`,"%Y") as `dateFormatted`'),
DB::Raw('SUM(`limit_repetitions`.`amount`) as `budgeted`'),
]
);
return $set;
}
/**
* @return Collection
*/
public function getBudgets()
{
/** @var Collection $set */
$set = Auth::user()->budgets()->get();
$set = $set->sortBy(
function (Budget $budget) {
return strtolower($budget->name);
}
);
return $set;
}
/**
* Returns an array with every budget in it and the expenses for each budget
* per month.
*
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return array
*/
public function getBudgetsAndExpensesPerMonth(Collection $accounts, Carbon $start, Carbon $end)
{
$ids = $accounts->pluck('id')->toArray();
/** @var Collection $set */
$set = Auth::user()->budgets()
->leftJoin('budget_transaction_journal', 'budgets.id', '=', 'budget_transaction_journal.budget_id')
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'budget_transaction_journal.transaction_journal_id')
->leftJoin(
'transactions', function (JoinClause $join) {
$join->on('transactions.transaction_journal_id', '=', 'transaction_journals.id')->where('transactions.amount', '<', 0);
}
)
->groupBy('budgets.id')
->groupBy('dateFormatted')
->where('transaction_journals.date', '>=', $start->format('Y-m-d'))
->where('transaction_journals.date', '<=', $end->format('Y-m-d'))
->whereIn('transactions.account_id', $ids)
->get(
[
'budgets.*',
DB::Raw('DATE_FORMAT(`transaction_journals`.`date`, "%Y-%m") AS `dateFormatted`'),
DB::Raw('SUM(`transactions`.`amount`) AS `sumAmount`'),
]
);
$set = $set->sortBy(
function (Budget $budget) {
return strtolower($budget->name);
}
);
$return = [];
foreach ($set as $budget) {
$id = $budget->id;
if (!isset($return[$id])) {
$return[$id] = [
'budget' => $budget,
'entries' => [],
];
}
// store each entry:
$return[$id]['entries'][$budget->dateFormatted] = $budget->sumAmount;
}
return $return;
}
/**
* Returns an array with every budget in it and the expenses for each budget
* per year for.
*
* @param Collection $budgets
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @SuppressWarnings(PHPMD.ExcessiveMethodLength) // it's a query.
*
* @return array
*/
public function getBudgetsAndExpensesPerYear(Collection $budgets, Collection $accounts, Carbon $start, Carbon $end)
{
$ids = $accounts->pluck('id')->toArray();
$budgetIds = $budgets->pluck('id')->toArray();
/** @var Collection $set */
$set = Auth::user()->budgets()
->leftJoin('budget_transaction_journal', 'budgets.id', '=', 'budget_transaction_journal.budget_id')
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'budget_transaction_journal.transaction_journal_id')
->leftJoin(
'transactions', function (JoinClause $join) {
$join->on('transactions.transaction_journal_id', '=', 'transaction_journals.id')->where('transactions.amount', '<', 0);
}
)
->groupBy('budgets.id')
->groupBy('dateFormatted')
->where('transaction_journals.date', '>=', $start->format('Y-m-d'))
->where('transaction_journals.date', '<=', $end->format('Y-m-d'))
->whereIn('transactions.account_id', $ids)
->whereIn('budgets.id', $budgetIds)
->get(
[
'budgets.*',
DB::Raw('DATE_FORMAT(`transaction_journals`.`date`, "%Y") AS `dateFormatted`'),
DB::Raw('SUM(`transactions`.`amount`) AS `sumAmount`'),
]
);
$set = $set->sortBy(
function (Budget $budget) {
return strtolower($budget->name);
}
);
$return = [];
foreach ($set as $budget) {
$id = $budget->id;
if (!isset($return[$id])) {
$return[$id] = [
'budget' => $budget,
'entries' => [],
];
}
// store each entry:
$return[$id]['entries'][$budget->dateFormatted] = $budget->sumAmount;
}
return $return;
}
/**
* Returns a list of budgets, budget limits and limit repetitions
* (doubling any of them in a left join)
*
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function getBudgetsAndLimitsInRange(Carbon $start, Carbon $end)
{
/** @var Collection $set */
$set = Auth::user()
->budgets()
->leftJoin('budget_limits', 'budget_limits.budget_id', '=', 'budgets.id')
->leftJoin('limit_repetitions', 'limit_repetitions.budget_limit_id', '=', 'budget_limits.id')
->where(
function (Builder $query) use ($start, $end) {
$query->where(
function (Builder $query) use ($start, $end) {
$query->where('limit_repetitions.startdate', '>=', $start->format('Y-m-d'));
$query->where('limit_repetitions.startdate', '<=', $end->format('Y-m-d'));
}
);
$query->orWhere(
function (Builder $query) {
$query->whereNull('limit_repetitions.startdate');
$query->whereNull('limit_repetitions.enddate');
}
);
}
)
->get(['budgets.*', 'limit_repetitions.startdate', 'limit_repetitions.enddate', 'limit_repetitions.amount']);
$set = $set->sortBy(
function (Budget $budget) {
return strtolower($budget->name);
}
);
return $set;
}
/**
* @param Budget $budget
* @param Carbon $start
* @param Carbon $end
*
* @return LimitRepetition|null
*/
public function getCurrentRepetition(Budget $budget, Carbon $start, Carbon $end)
{
$data = $budget->limitrepetitions()
->where('limit_repetitions.startdate', $start->format('Y-m-d 00:00:00'))
->where('limit_repetitions.enddate', $end->format('Y-m-d 00:00:00'))
->first(['limit_repetitions.*']);
return $data;
}
/**
* Returns the expenses for this budget grouped per day, with the date
* in "date" (a string, not a Carbon) and the amount in "dailyAmount".
@ -96,179 +402,6 @@ class BudgetRepository extends ComponentRepository implements BudgetRepositoryIn
return $set;
}
/**
* @param Budget $budget
*
* @return boolean
*/
public function destroy(Budget $budget)
{
$budget->delete();
return true;
}
/**
* @return Collection
*/
public function getActiveBudgets()
{
/** @var Collection $set */
$set = Auth::user()->budgets()->where('active', 1)->get();
$set = $set->sortBy(
function (Budget $budget) {
return strtolower($budget->name);
}
);
return $set;
}
/**
* Returns a list of budgets, budget limits and limit repetitions
* (doubling any of them in a left join)
*
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function getBudgetsAndLimitsInRange(Carbon $start, Carbon $end)
{
/** @var Collection $set */
$set = Auth::user()
->budgets()
->leftJoin('budget_limits', 'budget_limits.budget_id', '=', 'budgets.id')
->leftJoin('limit_repetitions', 'limit_repetitions.budget_limit_id', '=', 'budget_limits.id')
->where(
function (Builder $query) use ($start, $end) {
$query->where(
function (Builder $query) use ($start, $end) {
$query->where('limit_repetitions.startdate', '>=', $start->format('Y-m-d'));
$query->where('limit_repetitions.startdate', '<=', $end->format('Y-m-d'));
}
);
$query->orWhere(
function (Builder $query) {
$query->whereNull('limit_repetitions.startdate');
$query->whereNull('limit_repetitions.enddate');
}
);
}
)
->get(['budgets.*', 'limit_repetitions.startdate', 'limit_repetitions.enddate', 'limit_repetitions.amount']);
$set = $set->sortBy(
function (Budget $budget) {
return strtolower($budget->name);
}
);
return $set;
}
/**
* @param Budget $budget
*
* @return Carbon
*/
public function firstActivity(Budget $budget)
{
$first = $budget->transactionjournals()->orderBy('date', 'ASC')->first();
if ($first) {
return $first->date;
}
return new Carbon;
}
/**
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function getAllBudgetLimitRepetitions(Carbon $start, Carbon $end)
{
/** @var Collection $repetitions */
return LimitRepetition::
leftJoin('budget_limits', 'limit_repetitions.budget_limit_id', '=', 'budget_limits.id')
->leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id')
->where('limit_repetitions.startdate', '<=', $end->format('Y-m-d 00:00:00'))
->where('limit_repetitions.startdate', '>=', $start->format('Y-m-d 00:00:00'))
->where('budgets.user_id', Auth::user()->id)
->get(['limit_repetitions.*', 'budget_limits.budget_id']);
}
/**
* Returns an array with the following key:value pairs:
*
* yyyy-mm-dd:<amount>
*
* Where yyyy-mm-dd is the date and <amount> is the money spent using DEPOSITS in the $budget
* from all the users accounts.
*
* @param Budget $budget
* @param Carbon $start
* @param Carbon $end
*
* @return array
*/
public function spentPerDay(Budget $budget, Carbon $start, Carbon $end)
{
/** @var Collection $query */
$query = $budget->transactionJournals()
->transactionTypes([TransactionType::WITHDRAWAL])
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->where('transactions.amount', '<', 0)
->before($end)
->after($start)
->groupBy('dateFormatted')->get(['transaction_journals.date as dateFormatted', DB::Raw('SUM(`transactions`.`amount`) AS `sum`')]);
$return = [];
foreach ($query->toArray() as $entry) {
$return[$entry['dateFormatted']] = $entry['sum'];
}
return $return;
}
/**
* @return Collection
*/
public function getBudgets()
{
/** @var Collection $set */
$set = Auth::user()->budgets()->get();
$set = $set->sortBy(
function (Budget $budget) {
return strtolower($budget->name);
}
);
return $set;
}
/**
* @param Budget $budget
* @param Carbon $start
* @param Carbon $end
*
* @return LimitRepetition|null
*/
public function getCurrentRepetition(Budget $budget, Carbon $start, Carbon $end)
{
$data = $budget->limitrepetitions()
->where('limit_repetitions.startdate', $start->format('Y-m-d 00:00:00'))
->where('limit_repetitions.enddate', $end->format('Y-m-d 00:00:00'))
->first(['limit_repetitions.*']);
return $data;
}
/**
* @param Budget $budget
*
@ -284,64 +417,6 @@ class BudgetRepository extends ComponentRepository implements BudgetRepositoryIn
return Carbon::now()->startOfYear();
}
/**
* Returns an array with every budget in it and the expenses for each budget
* per month.
*
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return array
*/
public function getBudgetsAndExpensesPerMonth(Collection $accounts, Carbon $start, Carbon $end)
{
$ids = $accounts->pluck('id')->toArray();
/** @var Collection $set */
$set = Auth::user()->budgets()
->leftJoin('budget_transaction_journal', 'budgets.id', '=', 'budget_transaction_journal.budget_id')
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'budget_transaction_journal.transaction_journal_id')
->leftJoin(
'transactions', function (JoinClause $join) {
$join->on('transactions.transaction_journal_id', '=', 'transaction_journals.id')->where('transactions.amount', '<', 0);
}
)
->groupBy('budgets.id')
->groupBy('dateFormatted')
->where('transaction_journals.date', '>=', $start->format('Y-m-d'))
->where('transaction_journals.date', '<=', $end->format('Y-m-d'))
->whereIn('transactions.account_id', $ids)
->get(
[
'budgets.*',
DB::Raw('DATE_FORMAT(`transaction_journals`.`date`, "%Y-%m") AS `dateFormatted`'),
DB::Raw('SUM(`transactions`.`amount`) AS `sumAmount`'),
]
);
$set = $set->sortBy(
function (Budget $budget) {
return strtolower($budget->name);
}
);
$return = [];
foreach ($set as $budget) {
$id = $budget->id;
if (!isset($return[$id])) {
$return[$id] = [
'budget' => $budget,
'entries' => [],
];
}
// store each entry:
$return[$id]['entries'][$budget->dateFormatted] = $budget->sumAmount;
}
return $return;
}
/**
* @return Collection
*/
@ -448,187 +523,6 @@ class BudgetRepository extends ComponentRepository implements BudgetRepositoryIn
return $entry->journalAmount;
}
/**
* @param Budget $budget
* @param Carbon $start
* @param Carbon $end
* @param Collection $accounts
*
* @return string
*/
public function balanceInPeriod(Budget $budget, Carbon $start, Carbon $end, Collection $accounts)
{
return $this->commonBalanceInPeriod($budget, $start, $end, $accounts);
}
/**
* @param array $data
*
* @return Budget
*/
public function store(array $data)
{
$newBudget = new Budget(
[
'user_id' => $data['user'],
'name' => $data['name'],
]
);
$newBudget->save();
return $newBudget;
}
/**
* @param Budget $budget
* @param array $data
*
* @return Budget
*/
public function update(Budget $budget, array $data)
{
// update the account:
$budget->name = $data['name'];
$budget->active = $data['active'];
$budget->save();
return $budget;
}
/**
* @param Budget $budget
* @param Carbon $date
* @param $amount
*
* @return BudgetLimit
*/
public function updateLimitAmount(Budget $budget, Carbon $date, $amount)
{
// there should be a budget limit for this startdate:
/** @var BudgetLimit $limit */
$limit = $budget->budgetlimits()->where('budget_limits.startdate', $date)->first(['budget_limits.*']);
if (!$limit) {
// if not, create one!
$limit = new BudgetLimit;
$limit->budget()->associate($budget);
$limit->startdate = $date;
$limit->amount = $amount;
$limit->repeat_freq = 'monthly';
$limit->repeats = 0;
$limit->save();
// likewise, there should be a limit repetition to match the end date
// (which is always the end of the month) but that is caught by an event.
} else {
if ($amount > 0) {
$limit->amount = $amount;
$limit->save();
} else {
$limit->delete();
}
}
return $limit;
}
/**
* Get the budgeted amounts for each budgets in each year.
*
* @param Collection $budgets
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function getBudgetedPerYear(Collection $budgets, Carbon $start, Carbon $end)
{
$budgetIds = $budgets->pluck('id')->toArray();
$set = Auth::user()->budgets()
->leftJoin('budget_limits', 'budgets.id', '=', 'budget_limits.budget_id')
->leftJoin('limit_repetitions', 'limit_repetitions.budget_limit_id', '=', 'budget_limits.id')
->where('limit_repetitions.startdate', '>=', $start->format('Y-m-d'))
->where('limit_repetitions.enddate', '<=', $end->format('Y-m-d'))
->groupBy('budgets.id')
->groupBy('dateFormatted')
->whereIn('budgets.id', $budgetIds)
->get(
[
'budgets.*',
DB::Raw('DATE_FORMAT(`limit_repetitions`.`startdate`,"%Y") as `dateFormatted`'),
DB::Raw('SUM(`limit_repetitions`.`amount`) as `budgeted`'),
]
);
return $set;
}
/**
* Returns an array with every budget in it and the expenses for each budget
* per year for.
*
* @param Collection $budgets
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @SuppressWarnings(PHPMD.ExcessiveMethodLength) // it's a query.
*
* @return array
*/
public function getBudgetsAndExpensesPerYear(Collection $budgets, Collection $accounts, Carbon $start, Carbon $end)
{
$ids = $accounts->pluck('id')->toArray();
$budgetIds = $budgets->pluck('id')->toArray();
/** @var Collection $set */
$set = Auth::user()->budgets()
->leftJoin('budget_transaction_journal', 'budgets.id', '=', 'budget_transaction_journal.budget_id')
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'budget_transaction_journal.transaction_journal_id')
->leftJoin(
'transactions', function (JoinClause $join) {
$join->on('transactions.transaction_journal_id', '=', 'transaction_journals.id')->where('transactions.amount', '<', 0);
}
)
->groupBy('budgets.id')
->groupBy('dateFormatted')
->where('transaction_journals.date', '>=', $start->format('Y-m-d'))
->where('transaction_journals.date', '<=', $end->format('Y-m-d'))
->whereIn('transactions.account_id', $ids)
->whereIn('budgets.id', $budgetIds)
->get(
[
'budgets.*',
DB::Raw('DATE_FORMAT(`transaction_journals`.`date`, "%Y") AS `dateFormatted`'),
DB::Raw('SUM(`transactions`.`amount`) AS `sumAmount`'),
]
);
$set = $set->sortBy(
function (Budget $budget) {
return strtolower($budget->name);
}
);
$return = [];
foreach ($set as $budget) {
$id = $budget->id;
if (!isset($return[$id])) {
$return[$id] = [
'budget' => $budget,
'entries' => [],
];
}
// store each entry:
$return[$id]['entries'][$budget->dateFormatted] = $budget->sumAmount;
}
return $return;
}
/**
* Returns an array with the following key:value pairs:
*
@ -727,4 +621,109 @@ class BudgetRepository extends ComponentRepository implements BudgetRepositoryIn
return $set;
}
/**
* Returns an array with the following key:value pairs:
*
* yyyy-mm-dd:<amount>
*
* Where yyyy-mm-dd is the date and <amount> is the money spent using DEPOSITS in the $budget
* from all the users accounts.
*
* @param Budget $budget
* @param Carbon $start
* @param Carbon $end
*
* @return array
*/
public function spentPerDay(Budget $budget, Carbon $start, Carbon $end)
{
/** @var Collection $query */
$query = $budget->transactionJournals()
->transactionTypes([TransactionType::WITHDRAWAL])
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->where('transactions.amount', '<', 0)
->before($end)
->after($start)
->groupBy('dateFormatted')->get(['transaction_journals.date as dateFormatted', DB::Raw('SUM(`transactions`.`amount`) AS `sum`')]);
$return = [];
foreach ($query->toArray() as $entry) {
$return[$entry['dateFormatted']] = $entry['sum'];
}
return $return;
}
/**
* @param array $data
*
* @return Budget
*/
public function store(array $data)
{
$newBudget = new Budget(
[
'user_id' => $data['user'],
'name' => $data['name'],
]
);
$newBudget->save();
return $newBudget;
}
/**
* @param Budget $budget
* @param array $data
*
* @return Budget
*/
public function update(Budget $budget, array $data)
{
// update the account:
$budget->name = $data['name'];
$budget->active = $data['active'];
$budget->save();
return $budget;
}
/**
* @param Budget $budget
* @param Carbon $date
* @param $amount
*
* @return BudgetLimit
*/
public function updateLimitAmount(Budget $budget, Carbon $date, $amount)
{
// there should be a budget limit for this startdate:
/** @var BudgetLimit $limit */
$limit = $budget->budgetlimits()->where('budget_limits.startdate', $date)->first(['budget_limits.*']);
if (!$limit) {
// if not, create one!
$limit = new BudgetLimit;
$limit->budget()->associate($budget);
$limit->startdate = $date;
$limit->amount = $amount;
$limit->repeat_freq = 'monthly';
$limit->repeats = 0;
$limit->save();
// likewise, there should be a limit repetition to match the end date
// (which is always the end of the month) but that is caught by an event.
} else {
if ($amount > 0) {
$limit->amount = $amount;
$limit->save();
} else {
$limit->delete();
}
}
return $limit;
}
}

View File

@ -17,22 +17,30 @@ interface BudgetRepositoryInterface
{
/**
*
* Same as ::spentInPeriod but corrects journals for a set of accounts
*
* @param Budget $budget
* @param Carbon $start
* @param Carbon $end
* @param Collection $accounts
*
* @return string
*/
public function balanceInPeriod(Budget $budget, Carbon $start, Carbon $end, Collection $accounts);
/**
* @return void
*/
public function cleanupBudgets();
/**
* Returns the expenses for this budget grouped per day, with the date
* in "date" (a string, not a Carbon) and the amount in "dailyAmount".
*
* @param Budget $budget
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
* @return boolean
*/
public function getExpensesPerDay(Budget $budget, Carbon $start, Carbon $end);
public function destroy(Budget $budget);
/**
* @param Budget $budget
@ -42,72 +50,33 @@ interface BudgetRepositoryInterface
public function firstActivity(Budget $budget);
/**
* Returns the expenses for this budget grouped per month, with the date
* in "date" (a string, not a Carbon) and the amount in "dailyAmount".
*
* @param Budget $budget
* @return Collection
*/
public function getActiveBudgets();
/**
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function getExpensesPerMonth(Budget $budget, Carbon $start, Carbon $end);
public function getAllBudgetLimitRepetitions(Carbon $start, Carbon $end);
/**
* Returns a list of expenses (in the field "spent", grouped per budget per account.
* Get the budgeted amounts for each budgets in each year.
*
* @param Collection $budgets
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function spentPerBudgetPerAccount(Collection $budgets, Collection $accounts, Carbon $start, Carbon $end);
public function getBudgetedPerYear(Collection $budgets, Carbon $start, Carbon $end);
/**
* Returns an array with the following key:value pairs:
*
* yyyy-mm-dd:<amount>
*
* Where yyyy-mm-dd is the date and <amount> is the money spent using WITHDRAWALS in the $budget
* from all the users accounts.
*
* @param Budget $budget
* @param Carbon $start
* @param Carbon $end
*
* @return array
* @return Collection
*/
public function spentPerDay(Budget $budget, Carbon $start, Carbon $end);
/**
* Returns an array with the following key:value pairs:
*
* yyyy-mm-dd:<array>
*
* That array contains:
*
* budgetid:<amount>
*
* Where yyyy-mm-dd is the date and <amount> is the money spent using WITHDRAWALS in the $budget
* from the given users accounts..
*
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return array
*/
public function spentAllPerDayForAccounts(Collection $accounts, Carbon $start, Carbon $end);
/**
* @param Budget $budget
*
* @return boolean
*/
public function destroy(Budget $budget);
public function getBudgets();
/**
* Returns an array with every budget in it and the expenses for each budget
@ -134,35 +103,6 @@ interface BudgetRepositoryInterface
*/
public function getBudgetsAndExpensesPerYear(Collection $budgets, Collection $accounts, Carbon $start, Carbon $end);
/**
* @return Collection
*/
public function getActiveBudgets();
/**
* Get the budgeted amounts for each budgets in each year.
*
* @param Collection $budgets
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function getBudgetedPerYear(Collection $budgets, Carbon $start, Carbon $end);
/**
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function getAllBudgetLimitRepetitions(Carbon $start, Carbon $end);
/**
* @return Collection
*/
public function getBudgets();
/**
* Returns a list of budgets, budget limits and limit repetitions
* (doubling any of them in a left join)
@ -183,6 +123,30 @@ interface BudgetRepositoryInterface
*/
public function getCurrentRepetition(Budget $budget, Carbon $start, Carbon $end);
/**
* Returns the expenses for this budget grouped per day, with the date
* in "date" (a string, not a Carbon) and the amount in "dailyAmount".
*
* @param Budget $budget
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function getExpensesPerDay(Budget $budget, Carbon $start, Carbon $end);
/**
* Returns the expenses for this budget grouped per month, with the date
* in "date" (a string, not a Carbon) and the amount in "dailyAmount".
*
* @param Budget $budget
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function getExpensesPerMonth(Budget $budget, Carbon $start, Carbon $end);
/**
* @param Budget $budget
*
@ -223,17 +187,52 @@ interface BudgetRepositoryInterface
public function getWithoutBudgetSum(Carbon $start, Carbon $end);
/**
* Returns an array with the following key:value pairs:
*
* Same as ::spentInPeriod but corrects journals for a set of accounts
* yyyy-mm-dd:<array>
*
* That array contains:
*
* budgetid:<amount>
*
* Where yyyy-mm-dd is the date and <amount> is the money spent using WITHDRAWALS in the $budget
* from the given users accounts..
*
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return array
*/
public function spentAllPerDayForAccounts(Collection $accounts, Carbon $start, Carbon $end);
/**
* Returns a list of expenses (in the field "spent", grouped per budget per account.
*
* @param Collection $budgets
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function spentPerBudgetPerAccount(Collection $budgets, Collection $accounts, Carbon $start, Carbon $end);
/**
* Returns an array with the following key:value pairs:
*
* yyyy-mm-dd:<amount>
*
* Where yyyy-mm-dd is the date and <amount> is the money spent using WITHDRAWALS in the $budget
* from all the users accounts.
*
* @param Budget $budget
* @param Carbon $start
* @param Carbon $end
* @param Collection $accounts
*
* @return string
* @return array
*/
public function balanceInPeriod(Budget $budget, Carbon $start, Carbon $end, Collection $accounts);
public function spentPerDay(Budget $budget, Carbon $start, Carbon $end);
/**
* @param array $data

View File

@ -19,91 +19,6 @@ use Illuminate\Support\Collection;
class CategoryRepository implements CategoryRepositoryInterface
{
/**
* Returns a list of all the categories belonging to a user.
*
* @return Collection
*/
public function listCategories()
{
/** @var Collection $set */
$set = Auth::user()->categories()->orderBy('name', 'ASC')->get();
$set = $set->sortBy(
function (Category $category) {
return strtolower($category->name);
}
);
return $set;
}
/**
* Returns a list of transaction journals in the range (all types, all accounts) that have no category
* associated to them.
*
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function listNoCategory(Carbon $start, Carbon $end)
{
return Auth::user()
->transactionjournals()
->leftJoin('category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
->whereNull('category_transaction_journal.id')
->before($end)
->after($start)
->orderBy('transaction_journals.date', 'DESC')
->orderBy('transaction_journals.order', 'ASC')
->orderBy('transaction_journals.id', 'DESC')
->get(['transaction_journals.*']);
}
/**
* This method returns a very special collection for each category:
*
* category, year, expense/earned, amount
*
* categories can be duplicated.
*
* @param Collection $categories
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function listMultiYear(Collection $categories, Collection $accounts, Carbon $start, Carbon $end)
{
$set = Auth::user()->categories()
->leftJoin('category_transaction_journal', 'category_transaction_journal.category_id', '=', 'categories.id')
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'category_transaction_journal.transaction_journal_id')
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->whereIn('transaction_types.type', [TransactionType::DEPOSIT, TransactionType::WITHDRAWAL])
->whereIn('transactions.account_id', $accounts->pluck('id')->toArray())
->whereIn('categories.id', $categories->pluck('id')->toArray())
->where('transaction_journals.date', '>=', $start->format('Y-m-d'))
->where('transaction_journals.date', '<=', $end->format('Y-m-d'))
->groupBy('categories.id')
->groupBy('transaction_types.type')
->groupBy('dateFormatted')
->get(
[
'categories.*',
DB::Raw('DATE_FORMAT(`transaction_journals`.`date`,"%Y") as `dateFormatted`'),
'transaction_types.type',
DB::Raw('SUM(`amount`) as `sum`'),
]
);
return $set;
}
/**
* Returns a collection of Categories appended with the amount of money that has been earned
* in these categories, based on the $accounts involved, in period X, grouped per month.
@ -154,6 +69,90 @@ class CategoryRepository implements CategoryRepositoryInterface
}
/**
* Returns a list of all the categories belonging to a user.
*
* @return Collection
*/
public function listCategories()
{
/** @var Collection $set */
$set = Auth::user()->categories()->orderBy('name', 'ASC')->get();
$set = $set->sortBy(
function (Category $category) {
return strtolower($category->name);
}
);
return $set;
}
/**
* This method returns a very special collection for each category:
*
* category, year, expense/earned, amount
*
* categories can be duplicated.
*
* @param Collection $categories
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function listMultiYear(Collection $categories, Collection $accounts, Carbon $start, Carbon $end)
{
$set = Auth::user()->categories()
->leftJoin('category_transaction_journal', 'category_transaction_journal.category_id', '=', 'categories.id')
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'category_transaction_journal.transaction_journal_id')
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->whereIn('transaction_types.type', [TransactionType::DEPOSIT, TransactionType::WITHDRAWAL])
->whereIn('transactions.account_id', $accounts->pluck('id')->toArray())
->whereIn('categories.id', $categories->pluck('id')->toArray())
->where('transaction_journals.date', '>=', $start->format('Y-m-d'))
->where('transaction_journals.date', '<=', $end->format('Y-m-d'))
->groupBy('categories.id')
->groupBy('transaction_types.type')
->groupBy('dateFormatted')
->get(
[
'categories.*',
DB::Raw('DATE_FORMAT(`transaction_journals`.`date`,"%Y") as `dateFormatted`'),
'transaction_types.type',
DB::Raw('SUM(`amount`) as `sum`'),
]
);
return $set;
}
/**
* Returns a list of transaction journals in the range (all types, all accounts) that have no category
* associated to them.
*
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function listNoCategory(Carbon $start, Carbon $end)
{
return Auth::user()
->transactionjournals()
->leftJoin('category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
->whereNull('category_transaction_journal.id')
->before($end)
->after($start)
->orderBy('transaction_journals.date', 'DESC')
->orderBy('transaction_journals.order', 'ASC')
->orderBy('transaction_journals.id', 'DESC')
->get(['transaction_journals.*']);
}
/**
* Returns a collection of Categories appended with the amount of money that has been spent
* in these categories, based on the $accounts involved, in period X, grouped per month.
@ -206,6 +205,20 @@ class CategoryRepository implements CategoryRepositoryInterface
return $collection;
}
/**
* Returns the total amount of money related to transactions without any category connected to
* it. Returns either the earned amount.
*
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return string
*/
public function sumEarnedNoCategory(Collection $accounts, Carbon $start, Carbon $end)
{
return $this->sumNoCategory($accounts, $start, $end, Query::EARNED);
}
/**
* Returns the total amount of money related to transactions without any category connected to
@ -222,21 +235,6 @@ class CategoryRepository implements CategoryRepositoryInterface
return $this->sumNoCategory($accounts, $start, $end, Query::SPENT);
}
/**
* Returns the total amount of money related to transactions without any category connected to
* it. Returns either the earned amount.
*
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return string
*/
public function sumEarnedNoCategory(Collection $accounts, Carbon $start, Carbon $end)
{
return $this->sumNoCategory($accounts, $start, $end, Query::EARNED);
}
/**
* Returns the total amount of money related to transactions without any category connected to
* it. Returns either the earned or the spent amount.