Some query optimisations.

This commit is contained in:
James Cole
2015-12-27 07:59:00 +01:00
parent f5e5659c1f
commit 67a178591d
3 changed files with 39 additions and 25 deletions

View File

@@ -15,7 +15,6 @@ use Illuminate\Support\Collection;
use Preferences; use Preferences;
use Response; use Response;
use Session; use Session;
use Steam;
/** /**
* Class JsonController * Class JsonController
@@ -72,8 +71,8 @@ class JsonController extends Controller
*/ */
public function boxBillsPaid(BillRepositoryInterface $repository, AccountRepositoryInterface $accountRepository) public function boxBillsPaid(BillRepositoryInterface $repository, AccountRepositoryInterface $accountRepository)
{ {
$start = Session::get('start', Carbon::now()->startOfMonth()); $start = Session::get('start', Carbon::now()->startOfMonth());
$end = Session::get('end', Carbon::now()->endOfMonth()); $end = Session::get('end', Carbon::now()->endOfMonth());
bcscale(2); bcscale(2);
// works for json too! // works for json too!
@@ -88,11 +87,10 @@ class JsonController extends Controller
$amount = $repository->billsPaidInRange($start, $end)->sum('paid'); $amount = $repository->billsPaidInRange($start, $end)->sum('paid');
// add credit card bill. // add credit card bill.
$creditCards = $accountRepository->getCreditCards(); // Find credit card accounts and possibly unpaid credit card bills. $creditCards = $accountRepository->getCreditCards($end); // Find credit card accounts and possibly unpaid credit card bills.
/** @var Account $creditCard */ /** @var Account $creditCard */
foreach ($creditCards as $creditCard) { foreach ($creditCards as $creditCard) {
$balance = Steam::balance($creditCard, $end, true); // if the balance is not zero, the monthly payment is still underway. if ($creditCard->balance == 0) {
if ($balance == 0) {
// find a transfer TO the credit card which should account for // find a transfer TO the credit card which should account for
// anything paid. If not, the CC is not yet used. // anything paid. If not, the CC is not yet used.
$amount = bcadd($amount, $accountRepository->getTransfersInRange($creditCard, $start, $end)->sum('amount')); $amount = bcadd($amount, $accountRepository->getTransfersInRange($creditCard, $start, $end)->sum('amount'));
@@ -142,14 +140,15 @@ class JsonController extends Controller
} }
unset($bill, $bills, $range, $ranges); unset($bill, $bills, $range, $ranges);
$creditCards = $accountRepository->getCreditCards(); $creditCards = $accountRepository->getCreditCards($end);
/** @var Account $creditCard */
foreach ($creditCards as $creditCard) { foreach ($creditCards as $creditCard) {
$balance = Steam::balance($creditCard, $end, true); $date = new Carbon($creditCard->getMeta('ccMonthlyPaymentDate'));
$date = new Carbon($creditCard->getMeta('ccMonthlyPaymentDate')); if ($creditCard->balance < 0) {
if ($balance < 0) {
// unpaid! create a fake bill that matches the amount. // unpaid! create a fake bill that matches the amount.
$description = $creditCard->name; $description = $creditCard->name;
$fakeAmount = $balance * -1; $fakeAmount = $creditCard->balance * -1;
$fakeBill = $repository->createFakeBill($description, $date, $fakeAmount); $fakeBill = $repository->createFakeBill($description, $date, $fakeAmount);
$unpaid->push([$fakeBill, $date]); $unpaid->push([$fakeBill, $date]);
} }

View File

@@ -106,18 +106,32 @@ class AccountRepository implements AccountRepositoryInterface
/** /**
* This method returns the users credit cards, along with some basic information about the
* balance they have on their CC. To be used in the JSON boxes on the front page that say
* how many bills there are still left to pay. The balance will be saved in field "balance".
*
* To get the balance, the field "date" is necessary.
*
* @param Carbon $date
*
* @return Collection * @return Collection
*/ */
public function getCreditCards() public function getCreditCards(Carbon $date)
{ {
return Auth::user()->accounts() return Auth::user()->accounts()
->hasMetaValue('accountRole', 'ccAsset') ->hasMetaValue('accountRole', 'ccAsset')
->hasMetaValue('ccType', 'monthlyFull') ->hasMetaValue('ccType', 'monthlyFull')
->leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id')
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->whereNull('transactions.deleted_at')
->where('transaction_journals.date', '<=', $date->format('Y-m-d'))
->groupBy('accounts.id')
->get( ->get(
[ [
'accounts.*', 'accounts.*',
'ccType.data as ccType', 'ccType.data as ccType',
'accountRole.data as accountRole' 'accountRole.data as accountRole',
DB::Raw('SUM(`transactions`.`amount`) AS `balance`')
] ]
); );
} }
@@ -350,13 +364,14 @@ class AccountRepository implements AccountRepositoryInterface
*/ */
public function getTransfersInRange(Account $account, Carbon $start, Carbon $end) public function getTransfersInRange(Account $account, Carbon $start, Carbon $end)
{ {
$set = TransactionJournal::whereIn( $set = TransactionJournal::whereIn(
'id', function (Builder $q) use ($account, $start, $end) { 'id', function (Builder $q) use ($account, $start, $end) {
$q->select('transaction_journals.id') $q->select('transaction_journals.id')
->from('transactions') ->from('transactions')
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') ->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
->where('transactions.account_id', $account->id) ->where('transactions.account_id', $account->id)
->where('transactions.amount', '>', 0)// this makes the filter unnecessary.
->where('transaction_journals.user_id', Auth::user()->id) ->where('transaction_journals.user_id', Auth::user()->id)
->where('transaction_journals.date', '>=', $start->format('Y-m-d')) ->where('transaction_journals.date', '>=', $start->format('Y-m-d'))
->where('transaction_journals.date', '<=', $end->format('Y-m-d')) ->where('transaction_journals.date', '<=', $end->format('Y-m-d'))
@@ -364,17 +379,8 @@ class AccountRepository implements AccountRepositoryInterface
} }
)->get(); )->get();
$filtered = $set->filter(
function (TransactionJournal $journal) use ($account) {
if ($journal->destination_account->id == $account->id) {
return $journal;
}
return null; return $set;
}
);
return $filtered;
} }
/** /**

View File

@@ -26,6 +26,7 @@ interface AccountRepositoryInterface
/** /**
* @param $accountId * @param $accountId
*
* @deprecated * @deprecated
* *
* @return Account * @return Account
@@ -56,9 +57,17 @@ interface AccountRepositoryInterface
public function getFirstTransaction(TransactionJournal $journal, Account $account); public function getFirstTransaction(TransactionJournal $journal, Account $account);
/** /**
* This method returns the users credit cards, along with some basic information about the
* balance they have on their CC. To be used in the JSON boxes on the front page that say
* how many bills there are still left to pay. The balance will be saved in field "balance".
*
* To get the balance, the field "date" is necessary.
*
* @param Carbon $date
*
* @return Collection * @return Collection
*/ */
public function getCreditCards(); public function getCreditCards(Carbon $date);
/** /**
* Get the accounts of a user that have piggy banks connected to them. * Get the accounts of a user that have piggy banks connected to them.