mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-01-26 16:26:35 -06:00
Support any bill in any range.
This commit is contained in:
parent
65a5107854
commit
0619adb0cd
@ -12,6 +12,7 @@ use Redirect;
|
||||
use Session;
|
||||
use URL;
|
||||
use View;
|
||||
use Input;
|
||||
|
||||
/**
|
||||
* Class BillController
|
||||
@ -168,6 +169,10 @@ class BillController extends Controller
|
||||
$bill = $repository->store($billData);
|
||||
Session::flash('success', 'Bill "' . e($bill->name) . '" stored.');
|
||||
|
||||
if (intval(Input::get('create_another')) === 1) {
|
||||
return Redirect::route('bills.create')->withInput();
|
||||
}
|
||||
|
||||
return Redirect::route('bills.index');
|
||||
|
||||
}
|
||||
@ -195,6 +200,10 @@ class BillController extends Controller
|
||||
|
||||
$bill = $repository->update($bill, $billData);
|
||||
|
||||
if (intval(Input::get('return_to_edit')) === 1) {
|
||||
return Redirect::route('bills.edit', $bill->id);
|
||||
}
|
||||
|
||||
Session::flash('success', 'Bill "' . e($bill->name) . '" updated.');
|
||||
|
||||
return Redirect::route('bills.index');
|
||||
|
@ -3,7 +3,6 @@
|
||||
use App;
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use Crypt;
|
||||
use DB;
|
||||
use Exception;
|
||||
use FireflyIII\Helpers\Report\ReportQueryInterface;
|
||||
@ -16,6 +15,7 @@ use FireflyIII\Models\LimitRepetition;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use Grumpydictator\Gchart\GChart;
|
||||
use Illuminate\Database\Query\Builder as QueryBuilder;
|
||||
@ -311,49 +311,45 @@ class GoogleChartController extends Controller
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function billsOverview(GChart $chart)
|
||||
public function billsOverview(GChart $chart, BillRepositoryInterface $repository)
|
||||
{
|
||||
$chart->addColumn('Name', 'string');
|
||||
$chart->addColumn('Amount', 'number');
|
||||
|
||||
|
||||
$paid = ['items' => [], 'amount' => 0];
|
||||
$unpaid = ['items' => [], 'amount' => 0];
|
||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
||||
|
||||
$chart->addColumn('Name', 'string');
|
||||
$chart->addColumn('Amount', 'number');
|
||||
$bills = Auth::user()->bills()->where('active', 1)->get();
|
||||
|
||||
$set = Bill::
|
||||
leftJoin(
|
||||
'transaction_journals', function (JoinClause $join) use ($start, $end) {
|
||||
$join->on('bills.id', '=', 'transaction_journals.bill_id')
|
||||
->where('transaction_journals.date', '>=', $start->format('Y-m-d'))
|
||||
->where('transaction_journals.date', '<=', $end->format('Y-m-d'));
|
||||
}
|
||||
)
|
||||
->leftJoin(
|
||||
'transactions', function (JoinClause $join) {
|
||||
$join->on('transaction_journals.id', '=', 'transactions.transaction_journal_id')->where('transactions.amount', '>', 0);
|
||||
}
|
||||
)
|
||||
->where('active', 1)
|
||||
->groupBy('bills.id')
|
||||
->get(
|
||||
['bills.id', 'bills.name', 'transaction_journals.description',
|
||||
'transaction_journals.encrypted',
|
||||
'transaction_journals.id as journalId',
|
||||
\DB::Raw('SUM(`bills`.`amount_min` + `bills`.`amount_max`) / 2 as `averageAmount`'),
|
||||
'transactions.amount AS actualAmount']
|
||||
);
|
||||
/** @var Bill $bill */
|
||||
foreach ($bills as $bill) {
|
||||
$ranges = $repository->getRanges($bill, $start, $end);
|
||||
|
||||
foreach ($ranges as $range) {
|
||||
// paid a bill in this range?
|
||||
$count = $bill->transactionjournals()->before($range['end'])->after($range['start'])->count();
|
||||
if ($count == 0) {
|
||||
$unpaid['items'][] = $bill->name . ' (' . $range['start']->format('jS M Y') . ')';
|
||||
$unpaid['amount'] += ($bill->amount_max + $bill->amount_min / 2);
|
||||
|
||||
} else {
|
||||
$journal = $bill->transactionjournals()->with('transactions')->before($range['end'])->after($range['start'])->first();
|
||||
$paid['items'][] = $journal->description;
|
||||
$amount = 0;
|
||||
foreach ($journal->transactions as $t) {
|
||||
if (floatval($t->amount) > 0) {
|
||||
$amount = floatval($t->amount);
|
||||
}
|
||||
}
|
||||
$paid['amount'] += $amount;
|
||||
}
|
||||
|
||||
foreach ($set as $entry) {
|
||||
if (intval($entry->journalId) == 0) {
|
||||
$unpaid['items'][] = $entry->name;
|
||||
$unpaid['amount'] += floatval($entry->averageAmount);
|
||||
} else {
|
||||
$description = intval($entry->encrypted) == 1 ? Crypt::decrypt($entry->description) : $entry->description;
|
||||
$paid['items'][] = $description;
|
||||
$paid['amount'] += floatval($entry->actualAmount);
|
||||
}
|
||||
}
|
||||
|
||||
$chart->addRow('Unpaid: ' . join(', ', $unpaid['items']), $unpaid['amount']);
|
||||
$chart->addRow('Paid: ' . join(', ', $paid['items']), $paid['amount']);
|
||||
$chart->generate();
|
||||
|
@ -1,18 +1,12 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: sander
|
||||
* Date: 25/02/15
|
||||
* Time: 07:40
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Repositories\Bill;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Navigation;
|
||||
use Log;
|
||||
use Navigation;
|
||||
|
||||
/**
|
||||
* Class BillRepository
|
||||
@ -21,6 +15,54 @@ use Log;
|
||||
*/
|
||||
class BillRepository implements BillRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* 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
|
||||
* you give 1st and the 31st of that month as argument, you'll get one response, matching the range of your bill.
|
||||
*
|
||||
* @param Bill $bill
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getRanges(Bill $bill, Carbon $start, Carbon $end)
|
||||
{
|
||||
$startOfBill = $bill->date;
|
||||
$startOfBill = Navigation::startOfPeriod($startOfBill, $bill->repeat_freq);
|
||||
|
||||
|
||||
// all periods of this bill up until the current period:
|
||||
$billStarts = [];
|
||||
while ($startOfBill < $end) {
|
||||
|
||||
$endOfBill = Navigation::endOfPeriod($startOfBill, $bill->repeat_freq);
|
||||
|
||||
$billStarts[] = [
|
||||
'start' => clone $startOfBill,
|
||||
'end' => clone $endOfBill,
|
||||
];
|
||||
// actually the next one:
|
||||
$startOfBill = Navigation::addPeriod($startOfBill, $bill->repeat_freq, $bill->skip);
|
||||
|
||||
}
|
||||
// for each
|
||||
$validRanges = [];
|
||||
foreach ($billStarts as $dateEntry) {
|
||||
if ($dateEntry['end'] > $start && $dateEntry['start'] < $end) {
|
||||
// count transactions for bill in this range (not relevant yet!):
|
||||
// $count = $bill->transactionjournals()->before($dateEntry['end'])->after($dateEntry['start'])->count();
|
||||
// if ($count == 0) {
|
||||
$validRanges[] = $dateEntry;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
return $validRanges;
|
||||
// echo $bill->name;
|
||||
// var_dump($validRanges);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
*
|
||||
@ -28,6 +70,7 @@ class BillRepository implements BillRepositoryInterface
|
||||
*/
|
||||
public function nextExpectedMatch(Bill $bill)
|
||||
{
|
||||
|
||||
$finalDate = null;
|
||||
if ($bill->active == 0) {
|
||||
return $finalDate;
|
||||
@ -113,7 +156,7 @@ class BillRepository implements BillRepositoryInterface
|
||||
$wordMatch = true;
|
||||
Log::debug('word match is true');
|
||||
} else {
|
||||
Log::debug('Count: ' . $count.', count(matches): ' . count($matches));
|
||||
Log::debug('Count: ' . $count . ', count(matches): ' . count($matches));
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,13 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: sander
|
||||
* Date: 25/02/15
|
||||
* Time: 07:40
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Repositories\Bill;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
|
||||
@ -25,6 +20,19 @@ interface BillRepositoryInterface {
|
||||
*/
|
||||
public function nextExpectedMatch(Bill $bill);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* you give 1st and the 31st of that month as argument, you'll get one response, matching the range of your bill.
|
||||
*
|
||||
* @param Bill $bill
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getRanges(Bill $bill, Carbon $start, Carbon $end);
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
|
@ -298,15 +298,15 @@ class Navigation
|
||||
$date = clone $theDate;
|
||||
|
||||
$functionMap = [
|
||||
'daily' => 'startOfDay',
|
||||
'week' => 'startOfWeek',
|
||||
'weekly' => 'startOfWeek',
|
||||
'month' => 'startOfMonth',
|
||||
'monthly' => 'startOfMonth',
|
||||
'quarter' => 'firstOfQuarter',
|
||||
'quartly' => 'firstOfQuarter',
|
||||
'year' => 'startOfYear',
|
||||
'yearly' => 'startOfYear',
|
||||
'daily' => 'startOfDay',
|
||||
'week' => 'startOfWeek',
|
||||
'weekly' => 'startOfWeek',
|
||||
'month' => 'startOfMonth',
|
||||
'monthly' => 'startOfMonth',
|
||||
'quarter' => 'firstOfQuarter',
|
||||
'quarterly' => 'firstOfQuarter',
|
||||
'year' => 'startOfYear',
|
||||
'yearly' => 'startOfYear',
|
||||
];
|
||||
if (isset($functionMap[$repeatFreq])) {
|
||||
$function = $functionMap[$repeatFreq];
|
||||
|
Loading…
Reference in New Issue
Block a user