mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-23 14:26:58 +00:00
Huge change to bills and paid/unpaid/cc boxes.
This commit is contained in:
@@ -14,12 +14,12 @@ interface BillChartGenerator
|
|||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Collection $paid
|
* @param string $paid
|
||||||
* @param Collection $unpaid
|
* @param string $unpaid
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function frontpage(Collection $paid, Collection $unpaid);
|
public function frontpage($paid, $unpaid);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Bill $bill
|
* @param Bill $bill
|
||||||
|
@@ -2,11 +2,8 @@
|
|||||||
|
|
||||||
namespace FireflyIII\Generator\Chart\Bill;
|
namespace FireflyIII\Generator\Chart\Bill;
|
||||||
|
|
||||||
use Config;
|
|
||||||
use FireflyIII\Models\Bill;
|
use FireflyIII\Models\Bill;
|
||||||
use FireflyIII\Models\TransactionJournal;
|
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Preferences;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ChartJsBillChartGenerator
|
* Class ChartJsBillChartGenerator
|
||||||
@@ -17,42 +14,23 @@ class ChartJsBillChartGenerator implements BillChartGenerator
|
|||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Collection $paid
|
* @param string $paid
|
||||||
* @param Collection $unpaid
|
* @param string $unpaid
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function frontpage(Collection $paid, Collection $unpaid)
|
public function frontpage($paid, $unpaid)
|
||||||
{
|
{
|
||||||
$paidDescriptions = [];
|
|
||||||
$paidAmount = 0;
|
|
||||||
$unpaidDescriptions = [];
|
|
||||||
$unpaidAmount = 0;
|
|
||||||
bcscale(2);
|
bcscale(2);
|
||||||
|
|
||||||
/** @var TransactionJournal $entry */
|
|
||||||
foreach ($paid as $entry) { // loop paid and create single entry:
|
|
||||||
$paidDescriptions[] = $entry->description;
|
|
||||||
$paidAmount = bcadd($paidAmount, $entry->amount_positive);
|
|
||||||
}
|
|
||||||
/** @var Bill $entry */
|
|
||||||
foreach ($unpaid as $entry) { // loop unpaid:
|
|
||||||
$description = $entry[0]->name . ' (' . $entry[1]->format('jS M Y') . ')';
|
|
||||||
$amount = bcdiv(bcadd($entry[0]->amount_max, $entry[0]->amount_min), 2);
|
|
||||||
$unpaidDescriptions[] = $description;
|
|
||||||
$unpaidAmount = bcadd($unpaidAmount, $amount);
|
|
||||||
unset($amount, $description);
|
|
||||||
}
|
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
[
|
[
|
||||||
'value' => $unpaidAmount,
|
'value' => $unpaid,
|
||||||
'color' => 'rgba(53, 124, 165,0.7)',
|
'color' => 'rgba(53, 124, 165,0.7)',
|
||||||
'highlight' => 'rgba(53, 124, 165,0.9)',
|
'highlight' => 'rgba(53, 124, 165,0.9)',
|
||||||
'label' => trans('firefly.unpaid'),
|
'label' => trans('firefly.unpaid'),
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'value' => $paidAmount,
|
'value' => $paid * -1, // paid is negative, must be positive.
|
||||||
'color' => 'rgba(0, 141, 76, 0.7)',
|
'color' => 'rgba(0, 141, 76, 0.7)',
|
||||||
'highlight' => 'rgba(0, 141, 76, 0.9)',
|
'highlight' => 'rgba(0, 141, 76, 0.9)',
|
||||||
'label' => trans('firefly.paid'),
|
'label' => trans('firefly.paid'),
|
||||||
@@ -71,7 +49,7 @@ class ChartJsBillChartGenerator implements BillChartGenerator
|
|||||||
public function single(Bill $bill, Collection $entries)
|
public function single(Bill $bill, Collection $entries)
|
||||||
{
|
{
|
||||||
// language:
|
// language:
|
||||||
$format = trans('config.month');
|
$format = trans('config.month');
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'count' => 3,
|
'count' => 3,
|
||||||
|
@@ -33,7 +33,7 @@ class BillController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows all bills and whether or not theyve been paid this month (pie chart).
|
* Shows all bills and whether or not they've been paid this month (pie chart).
|
||||||
*
|
*
|
||||||
* @param BillRepositoryInterface $repository
|
* @param BillRepositoryInterface $repository
|
||||||
*
|
*
|
||||||
@@ -41,28 +41,24 @@ class BillController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function frontpage(BillRepositoryInterface $repository)
|
public function frontpage(BillRepositoryInterface $repository)
|
||||||
{
|
{
|
||||||
$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());
|
||||||
$cache = new CacheProperties(); // chart properties for cache:
|
$paid = $repository->getBillsPaidInRange($start, $end); // will be a negative amount.
|
||||||
$cache->addProperty($start);
|
$unpaid = $repository->getBillsUnpaidInRange($start, $end); // will be a positive amount.
|
||||||
$cache->addProperty($end);
|
$creditCardDue = $repository->getCreditCardBill($start, $end);
|
||||||
$cache->addProperty('bills');
|
|
||||||
$cache->addProperty('frontpage');
|
if ($creditCardDue < 0) {
|
||||||
if ($cache->has()) {
|
// expenses are negative (bill not yet paid),
|
||||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
$creditCardDue = bcmul($creditCardDue, '-1');
|
||||||
|
$unpaid = bcadd($unpaid, $creditCardDue);
|
||||||
|
} else {
|
||||||
|
// if more than zero, the bill has been paid: (transfer = positive).
|
||||||
|
// amount must be negative to be added to $paid:
|
||||||
|
$paid = bcadd($paid, $creditCardDue);
|
||||||
}
|
}
|
||||||
|
|
||||||
$set = $repository->getBillsForChart($start, $end);
|
|
||||||
|
|
||||||
// optionally expand this set with credit card data
|
|
||||||
$set = $repository->getCreditCardInfoForChart($set, $start, $end);
|
|
||||||
$paid = $set->get('paid');
|
|
||||||
$unpaid = $set->get('unpaid');
|
|
||||||
|
|
||||||
|
|
||||||
// build chart:
|
// build chart:
|
||||||
$data = $this->generator->frontpage($paid, $unpaid);
|
$data = $this->generator->frontpage($paid, $unpaid);
|
||||||
$cache->store($data);
|
|
||||||
|
|
||||||
return Response::json($data);
|
return Response::json($data);
|
||||||
}
|
}
|
||||||
|
@@ -3,15 +3,12 @@
|
|||||||
use Amount;
|
use Amount;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use FireflyIII\Helpers\Report\ReportQueryInterface;
|
use FireflyIII\Helpers\Report\ReportQueryInterface;
|
||||||
use FireflyIII\Models\Account;
|
|
||||||
use FireflyIII\Models\Bill;
|
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||||
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
||||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||||
use FireflyIII\Support\CacheProperties;
|
use FireflyIII\Support\CacheProperties;
|
||||||
use Illuminate\Support\Collection;
|
|
||||||
use Preferences;
|
use Preferences;
|
||||||
use Response;
|
use Response;
|
||||||
use Session;
|
use Session;
|
||||||
@@ -75,29 +72,18 @@ class JsonController extends Controller
|
|||||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
$end = Session::get('end', Carbon::now()->endOfMonth());
|
||||||
bcscale(2);
|
bcscale(2);
|
||||||
|
|
||||||
// works for json too!
|
/*
|
||||||
$cache = new CacheProperties;
|
* Since both this method and the chart use the exact same data, we can suffice
|
||||||
$cache->addProperty($start);
|
* with calling the one method in the bill repository that will get this amount.
|
||||||
$cache->addProperty($end);
|
*/
|
||||||
$cache->addProperty('box-bills-paid');
|
$amount = $repository->getBillsPaidInRange($start, $end); // will be a negative amount.
|
||||||
if ($cache->has()) {
|
$creditCardDue = $repository->getCreditCardBill($start, $end);
|
||||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
if ($creditCardDue >= 0) {
|
||||||
|
$amount = bcadd($amount, $creditCardDue);
|
||||||
}
|
}
|
||||||
// get amount from bills
|
$amount = $amount * -1;
|
||||||
$amount = $repository->billsPaidInRange($start, $end)->sum('paid');
|
|
||||||
|
|
||||||
// add credit card bill.
|
|
||||||
$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.
|
|
||||||
$amount = bcadd($amount, $accountRepository->getTransfersInRange($creditCard, $start, $end)->sum('amount'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$data = ['box' => 'bills-paid', 'amount' => Amount::format($amount, false), 'amount_raw' => $amount];
|
$data = ['box' => 'bills-paid', 'amount' => Amount::format($amount, false), 'amount_raw' => $amount];
|
||||||
$cache->store($data);
|
|
||||||
|
|
||||||
return Response::json($data);
|
return Response::json($data);
|
||||||
}
|
}
|
||||||
@@ -108,59 +94,21 @@ class JsonController extends Controller
|
|||||||
*
|
*
|
||||||
* @return \Symfony\Component\HttpFoundation\Response
|
* @return \Symfony\Component\HttpFoundation\Response
|
||||||
*/
|
*/
|
||||||
public function boxBillsUnpaid(BillRepositoryInterface $repository, AccountRepositoryInterface $accountRepository)
|
public function boxBillsUnpaid(BillRepositoryInterface $repository)
|
||||||
{
|
{
|
||||||
$amount = 0;
|
|
||||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
|
||||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
|
||||||
bcscale(2);
|
bcscale(2);
|
||||||
|
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||||
|
$end = Session::get('end', Carbon::now()->endOfMonth());
|
||||||
|
$amount = $repository->getBillsUnpaidInRange($start, $end); // will be a positive amount.
|
||||||
|
$creditCardDue = $repository->getCreditCardBill($start, $end);
|
||||||
|
|
||||||
// works for json too!
|
if ($creditCardDue < 0) {
|
||||||
$cache = new CacheProperties;
|
// expenses are negative (bill not yet paid),
|
||||||
$cache->addProperty($start);
|
$creditCardDue = bcmul($creditCardDue, '-1');
|
||||||
$cache->addProperty($end);
|
$amount = bcadd($amount, $creditCardDue);
|
||||||
$cache->addProperty('box-bills-unpaid');
|
|
||||||
if ($cache->has()) {
|
|
||||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
|
||||||
}
|
|
||||||
|
|
||||||
$bills = $repository->getActiveBills();
|
|
||||||
$unpaid = new Collection; // bills
|
|
||||||
|
|
||||||
/** @var Bill $bill */
|
|
||||||
foreach ($bills as $bill) {
|
|
||||||
$ranges = $repository->getRanges($bill, $start, $end);
|
|
||||||
|
|
||||||
foreach ($ranges as $range) {
|
|
||||||
$journals = $repository->getJournalsInRange($bill, $range['start'], $range['end']);
|
|
||||||
if ($journals->count() == 0) {
|
|
||||||
$unpaid->push([$bill, $range['start']]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unset($bill, $bills, $range, $ranges);
|
|
||||||
|
|
||||||
$creditCards = $accountRepository->getCreditCards($end);
|
|
||||||
|
|
||||||
/** @var Account $creditCard */
|
|
||||||
foreach ($creditCards as $creditCard) {
|
|
||||||
$date = new Carbon($creditCard->getMeta('ccMonthlyPaymentDate'));
|
|
||||||
if ($creditCard->balance < 0) {
|
|
||||||
// unpaid! create a fake bill that matches the amount.
|
|
||||||
$description = $creditCard->name;
|
|
||||||
$fakeAmount = $creditCard->balance * -1;
|
|
||||||
$fakeBill = $repository->createFakeBill($description, $date, $fakeAmount);
|
|
||||||
$unpaid->push([$fakeBill, $date]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/** @var Bill $entry */
|
|
||||||
foreach ($unpaid as $entry) {
|
|
||||||
$current = bcdiv(bcadd($entry[0]->amount_max, $entry[0]->amount_min), 2);
|
|
||||||
$amount = bcadd($amount, $current);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = ['box' => 'bills-unpaid', 'amount' => Amount::format($amount, false), 'amount_raw' => $amount];
|
$data = ['box' => 'bills-unpaid', 'amount' => Amount::format($amount, false), 'amount_raw' => $amount];
|
||||||
$cache->store($data);
|
|
||||||
|
|
||||||
return Response::json($data);
|
return Response::json($data);
|
||||||
}
|
}
|
||||||
|
@@ -41,6 +41,7 @@ use Illuminate\Database\Eloquent\Model;
|
|||||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereMatchEncrypted($value)
|
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereMatchEncrypted($value)
|
||||||
* @property \Carbon\Carbon $nextExpectedMatch
|
* @property \Carbon\Carbon $nextExpectedMatch
|
||||||
* @property \Carbon\Carbon $lastFoundMatch
|
* @property \Carbon\Carbon $lastFoundMatch
|
||||||
|
* @property-read string $expectedAmount
|
||||||
*/
|
*/
|
||||||
class Bill extends Model
|
class Bill extends Model
|
||||||
{
|
{
|
||||||
|
@@ -353,36 +353,6 @@ class AccountRepository implements AccountRepositoryInterface
|
|||||||
return $accounts;
|
return $accounts;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all transfers TO this account in this range.
|
|
||||||
*
|
|
||||||
* @param Account $account
|
|
||||||
* @param Carbon $start
|
|
||||||
* @param Carbon $end
|
|
||||||
*
|
|
||||||
* @return Collection
|
|
||||||
*/
|
|
||||||
public function getTransfersInRange(Account $account, Carbon $start, Carbon $end)
|
|
||||||
{
|
|
||||||
$set = TransactionJournal::whereIn(
|
|
||||||
'id', function (Builder $q) use ($account, $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', $account->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);
|
|
||||||
|
|
||||||
}
|
|
||||||
)->get();
|
|
||||||
|
|
||||||
return $set;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Account $account
|
* @param Account $account
|
||||||
* @param Carbon $date
|
* @param Carbon $date
|
||||||
|
@@ -76,18 +76,6 @@ interface AccountRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function getPiggyBankAccounts();
|
public function getPiggyBankAccounts();
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all transfers TO this account in this range.
|
|
||||||
*
|
|
||||||
* @param Account $account
|
|
||||||
* @param Carbon $start
|
|
||||||
* @param Carbon $end
|
|
||||||
*
|
|
||||||
* @return Collection
|
|
||||||
*/
|
|
||||||
public function getTransfersInRange(Account $account, Carbon $start, Carbon $end);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Preference $preference
|
* @param Preference $preference
|
||||||
*
|
*
|
||||||
|
@@ -9,11 +9,14 @@ use FireflyIII\Models\Account;
|
|||||||
use FireflyIII\Models\Bill;
|
use FireflyIII\Models\Bill;
|
||||||
use FireflyIII\Models\Transaction;
|
use FireflyIII\Models\Transaction;
|
||||||
use FireflyIII\Models\TransactionJournal;
|
use FireflyIII\Models\TransactionJournal;
|
||||||
|
use FireflyIII\Models\TransactionType;
|
||||||
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
|
use FireflyIII\Support\CacheProperties;
|
||||||
|
use Illuminate\Database\Query\Builder;
|
||||||
use Illuminate\Database\Query\JoinClause;
|
use Illuminate\Database\Query\JoinClause;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Log;
|
use Log;
|
||||||
use Navigation;
|
use Navigation;
|
||||||
use Steam;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class BillRepository
|
* Class BillRepository
|
||||||
@@ -22,53 +25,6 @@ use Steam;
|
|||||||
*/
|
*/
|
||||||
class BillRepository implements BillRepositoryInterface
|
class BillRepository implements BillRepositoryInterface
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @deprecated
|
|
||||||
* Returns the sum of all payments connected to this bill between the dates.
|
|
||||||
*
|
|
||||||
* @param Bill $bill
|
|
||||||
* @param Carbon $start
|
|
||||||
* @param Carbon $end
|
|
||||||
*
|
|
||||||
* @return integer
|
|
||||||
*/
|
|
||||||
public function billPaymentsInRange(Bill $bill, Carbon $start, Carbon $end)
|
|
||||||
{
|
|
||||||
$amount = 0;
|
|
||||||
$journals = $bill->transactionjournals()->before($end)->after($start)->get();
|
|
||||||
/** @var TransactionJournal $journal */
|
|
||||||
foreach ($journals as $journal) {
|
|
||||||
$amount += $journal->amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a fake bill to help the chart controller.
|
|
||||||
*
|
|
||||||
* @param string $description
|
|
||||||
* @param Carbon $date
|
|
||||||
* @param float $amount
|
|
||||||
*
|
|
||||||
* @return Bill
|
|
||||||
*/
|
|
||||||
public function createFakeBill($description, Carbon $date, $amount)
|
|
||||||
{
|
|
||||||
$bill = new Bill;
|
|
||||||
$bill->name = $description;
|
|
||||||
$bill->match = $description;
|
|
||||||
$bill->amount_min = $amount;
|
|
||||||
$bill->amount_max = $amount;
|
|
||||||
$bill->date = $date;
|
|
||||||
$bill->repeat_freq = 'monthly';
|
|
||||||
$bill->skip = 0;
|
|
||||||
$bill->automatch = false;
|
|
||||||
$bill->active = false;
|
|
||||||
|
|
||||||
return $bill;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Bill $bill
|
* @param Bill $bill
|
||||||
@@ -80,16 +36,6 @@ class BillRepository implements BillRepositoryInterface
|
|||||||
return $bill->delete();
|
return $bill->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Collection
|
|
||||||
*/
|
|
||||||
public function getActiveBills()
|
|
||||||
{
|
|
||||||
/** @var Collection $set */
|
|
||||||
$set = Auth::user()->bills()->where('active', 1)->get()->sortBy('name');
|
|
||||||
|
|
||||||
return $set;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Collection
|
* @return Collection
|
||||||
@@ -168,6 +114,8 @@ class BillRepository implements BillRepositoryInterface
|
|||||||
/**
|
/**
|
||||||
* Get all journals that were recorded on this bill between these dates.
|
* Get all journals that were recorded on this bill between these dates.
|
||||||
*
|
*
|
||||||
|
* @deprecated
|
||||||
|
*
|
||||||
* @param Bill $bill
|
* @param Bill $bill
|
||||||
* @param Carbon $start
|
* @param Carbon $start
|
||||||
* @param Carbon $end
|
* @param Carbon $end
|
||||||
@@ -448,109 +396,166 @@ class BillRepository implements BillRepositoryInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a collection of paid bills and a collection of unpaid bills to be used
|
* Get the total amount of money paid for the users active bills in the date range given.
|
||||||
* in the pie chart on the front page.
|
* This amount will be negative (they're expenses).
|
||||||
*
|
*
|
||||||
* @param Carbon $start
|
* @param Carbon $start
|
||||||
* @param Carbon $end
|
* @param Carbon $end
|
||||||
*
|
*
|
||||||
* @return Collection
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getBillsForChart(Carbon $start, Carbon $end)
|
public function getBillsPaidInRange(Carbon $start, Carbon $end)
|
||||||
{
|
{
|
||||||
$paid = new Collection;
|
$cache = new CacheProperties;
|
||||||
$unpaid = new Collection;
|
$cache->addProperty($start);
|
||||||
|
$cache->addProperty($end);
|
||||||
|
$cache->addProperty('bills-paid-in-range');
|
||||||
|
if ($cache->has()) {
|
||||||
|
//return $cache->get(); // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
$amount = '0';
|
||||||
|
$bills = $this->getActiveBills();
|
||||||
|
|
||||||
$bills = $this->getActiveBills();
|
|
||||||
/** @var Bill $bill */
|
/** @var Bill $bill */
|
||||||
foreach ($bills as $bill) {
|
foreach ($bills as $bill) {
|
||||||
$ranges = $this->getRanges($bill, $start, $end);
|
$ranges = $this->getRanges($bill, $start, $end);
|
||||||
|
|
||||||
foreach ($ranges as $range) {
|
foreach ($ranges as $range) {
|
||||||
// paid a bill in this range?
|
$paid = $bill->transactionjournals()
|
||||||
$journals = $this->getJournalsInRange($bill, $range['start'], $range['end']);
|
->before($range['end'])
|
||||||
if ($journals->count() == 0) {
|
->after($range['start'])
|
||||||
$unpaid->push([$bill, $range['start']]);
|
->leftJoin(
|
||||||
} else {
|
'transactions', function (JoinClause $join) {
|
||||||
$paid = $paid->merge($journals);
|
$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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$set = new Collection;
|
$cache->store($amount);
|
||||||
$set->put('paid', $paid);
|
|
||||||
$set->put('unpaid', $unpaid);
|
|
||||||
|
|
||||||
return $set;
|
return $amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes the paid/unpaid bills collection set up before and expands it using
|
|
||||||
* credit cards the user might have.
|
|
||||||
*
|
|
||||||
* @param Collection $set
|
|
||||||
* @param Carbon $start
|
|
||||||
* @param Carbon $end
|
|
||||||
*
|
|
||||||
* @return Collection
|
* @return Collection
|
||||||
*/
|
*/
|
||||||
public function getCreditCardInfoForChart(Collection $set, Carbon $start, Carbon $end)
|
public function getActiveBills()
|
||||||
{
|
{
|
||||||
|
/** @var Collection $set */
|
||||||
$accounts = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
|
$set = Auth::user()->bills()
|
||||||
$creditCards = $accounts->getCreditCards($end);
|
->where('active', 1)
|
||||||
$paid = $set->get('paid');
|
->get(
|
||||||
$unpaid = $set->get('unpaid');
|
[
|
||||||
|
'bills.*',
|
||||||
foreach ($creditCards as $creditCard) {
|
DB::Raw('(`bills`.`amount_min` + `bills`.`amount_max` / 2) as `expectedAmount`')
|
||||||
$date = new Carbon($creditCard->getMeta('ccMonthlyPaymentDate'));
|
]
|
||||||
if ($creditCard->balance < 0) {
|
)->sortBy('name');
|
||||||
// unpaid! create a fake bill that matches the amount.
|
|
||||||
$description = $creditCard->name;
|
|
||||||
$amount = $creditCard->balance * -1;
|
|
||||||
$fakeBill = $this->createFakeBill($description, $date, $amount);
|
|
||||||
unset($description, $amount);
|
|
||||||
$unpaid->push([$fakeBill, $date]);
|
|
||||||
}
|
|
||||||
if ($creditCard->balance == 0) {
|
|
||||||
// find transfer(s) TO the credit card which should account for
|
|
||||||
// anything paid. If not, the CC is not yet used.
|
|
||||||
$journals = $accounts->getTransfersInRange($creditCard, $start, $end);
|
|
||||||
$paid = $paid->merge($journals);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$set = new Collection;
|
|
||||||
$set->put('paid', $paid);
|
|
||||||
$set->put('unpaid', $unpaid);
|
|
||||||
|
|
||||||
return $set;
|
return $set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns all active bills which have been paid for in the given range,
|
* Get the total amount of money due for the users active bills in the date range given. This amount will be positive.
|
||||||
* with the field "paid" indicating how much the bill was for.
|
|
||||||
*
|
*
|
||||||
* @param Carbon $start
|
* @param Carbon $start
|
||||||
* @param Carbon $end
|
* @param Carbon $end
|
||||||
*
|
*
|
||||||
* @return Collection
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function billsPaidInRange(Carbon $start, Carbon $end)
|
public function getBillsUnpaidInRange(Carbon $start, Carbon $end)
|
||||||
{
|
{
|
||||||
$set = Auth::user()->bills()
|
$cache = new CacheProperties;
|
||||||
->leftJoin('transaction_journals', 'transaction_journals.bill_id', '=', 'bills.id')
|
$cache->addProperty($start);
|
||||||
->leftJoin(
|
$cache->addProperty($end);
|
||||||
'transactions', function (JoinClause $join) {
|
$cache->addProperty('bills-unpaid-in-range');
|
||||||
$join->on('transactions.transaction_journal_id', '=', 'transaction_journals.id')->where('transactions.amount', '>', 0);
|
if ($cache->has()) {
|
||||||
}
|
//return $cache->get(); // @codeCoverageIgnore
|
||||||
)
|
}
|
||||||
->where('transaction_journals.date', '>=', $start->format('Y-m-d'))
|
$amount = '0';
|
||||||
->where('transaction_journals.date', '<=', $end->format('Y-m-d'))
|
$bills = $this->getActiveBills();
|
||||||
->where('bills.active', 1)
|
|
||||||
->groupBy('bills.id')->get(
|
/** @var Bill $bill */
|
||||||
['bills.*', DB::Raw('SUM(`transactions`.`amount`) as `paid`')]
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$cache->store($amount);
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
|
||||||
|
$cache = new CacheProperties;
|
||||||
|
$cache->addProperty($start);
|
||||||
|
$cache->addProperty($end);
|
||||||
|
$cache->addProperty('credit-card-bill');
|
||||||
|
if ($cache->has()) {
|
||||||
|
//return $cache->get(); // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
/** @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;
|
||||||
|
|
||||||
return $set;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,61 +16,41 @@ interface BillRepositoryInterface
|
|||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes the paid/unpaid bills collection set up before and expands it using
|
* This method will tell you if you still have a CC bill to pay. Amount will be negative if the amount
|
||||||
* credit cards the user might have.
|
* has been paid
|
||||||
*
|
|
||||||
* @param Collection $set
|
|
||||||
* @param Carbon $start
|
|
||||||
* @param Carbon $end
|
|
||||||
*
|
|
||||||
* @return Collection
|
|
||||||
*/
|
|
||||||
public function getCreditCardInfoForChart(Collection $set, Carbon $start, Carbon $end);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a collection of paid bills and a collection of unpaid bills to be used
|
|
||||||
* in the pie chart on the front page.
|
|
||||||
*
|
*
|
||||||
* @param Carbon $start
|
* @param Carbon $start
|
||||||
* @param Carbon $end
|
* @param Carbon $end
|
||||||
*
|
*
|
||||||
* @return Collection
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getBillsForChart(Carbon $start, Carbon $end);
|
public function getCreditCardBill(Carbon $start, Carbon $end);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated
|
* Get the total amount of money paid for the users active bills in the date range given.
|
||||||
* Returns the sum of all payments connected to this bill between the dates.
|
|
||||||
*
|
|
||||||
* @param Bill $bill
|
|
||||||
* @param Carbon $start
|
|
||||||
* @param Carbon $end
|
|
||||||
*
|
|
||||||
* @return float
|
|
||||||
*/
|
|
||||||
public function billPaymentsInRange(Bill $bill, Carbon $start, Carbon $end);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method returns all active bills which have been paid for in the given range,
|
|
||||||
* with the field "paid" indicating how much the bill was for.
|
|
||||||
*
|
*
|
||||||
* @param Carbon $start
|
* @param Carbon $start
|
||||||
* @param Carbon $end
|
* @param Carbon $end
|
||||||
*
|
*
|
||||||
* @return Collection
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function billsPaidInRange(Carbon $start, Carbon $end);
|
public function getBillsPaidInRange(Carbon $start, Carbon $end);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a fake bill to help the chart controller.
|
* Get the total amount of money due for the users active bills in the date range given.
|
||||||
*
|
*
|
||||||
* @param string $description
|
* @param Carbon $start
|
||||||
* @param Carbon $date
|
* @param Carbon $end
|
||||||
* @param float $amount
|
|
||||||
*
|
*
|
||||||
* @return Bill
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function createFakeBill($description, Carbon $date, $amount);
|
public function getBillsUnpaidInRange(Carbon $start, Carbon $end);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
public function getActiveBills();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Bill $bill
|
* @param Bill $bill
|
||||||
@@ -79,11 +59,6 @@ interface BillRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function destroy(Bill $bill);
|
public function destroy(Bill $bill);
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Collection
|
|
||||||
*/
|
|
||||||
public function getActiveBills();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Collection
|
* @return Collection
|
||||||
*/
|
*/
|
||||||
@@ -126,7 +101,7 @@ interface BillRepositoryInterface
|
|||||||
/**
|
/**
|
||||||
* Every bill repeats itself weekly, monthly or yearly (or whatever). This method takes a date-range (usually the view-range of Firefly itself)
|
* Every bill repeats itself weekly, monthly or yearly (or whatever). This method takes a date-range (usually the view-range of Firefly itself)
|
||||||
* and returns date ranges that fall within the given range; those ranges are the bills expected. When a bill is due on the 14th of the month and
|
* and returns date ranges that fall within the given range; those ranges are the bills expected. When a bill is due on the 14th of the month and
|
||||||
* you give 1st and the 31st of that month as argument, you'll get one response, matching the range of your bill.
|
* you give 1st and the 31st of that month as argument, you'll get one response, matching the range of your bill (from the 14th to the 31th).
|
||||||
*
|
*
|
||||||
* @param Bill $bill
|
* @param Bill $bill
|
||||||
* @param Carbon $start
|
* @param Carbon $start
|
||||||
|
Reference in New Issue
Block a user