mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-10-12 23:45:10 +00:00
Support any bill in any range.
This commit is contained in:
@@ -12,6 +12,7 @@ use Redirect;
|
|||||||
use Session;
|
use Session;
|
||||||
use URL;
|
use URL;
|
||||||
use View;
|
use View;
|
||||||
|
use Input;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class BillController
|
* Class BillController
|
||||||
@@ -168,6 +169,10 @@ class BillController extends Controller
|
|||||||
$bill = $repository->store($billData);
|
$bill = $repository->store($billData);
|
||||||
Session::flash('success', 'Bill "' . e($bill->name) . '" stored.');
|
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');
|
return Redirect::route('bills.index');
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -195,6 +200,10 @@ class BillController extends Controller
|
|||||||
|
|
||||||
$bill = $repository->update($bill, $billData);
|
$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.');
|
Session::flash('success', 'Bill "' . e($bill->name) . '" updated.');
|
||||||
|
|
||||||
return Redirect::route('bills.index');
|
return Redirect::route('bills.index');
|
||||||
|
@@ -3,7 +3,6 @@
|
|||||||
use App;
|
use App;
|
||||||
use Auth;
|
use Auth;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Crypt;
|
|
||||||
use DB;
|
use DB;
|
||||||
use Exception;
|
use Exception;
|
||||||
use FireflyIII\Helpers\Report\ReportQueryInterface;
|
use FireflyIII\Helpers\Report\ReportQueryInterface;
|
||||||
@@ -16,6 +15,7 @@ use FireflyIII\Models\LimitRepetition;
|
|||||||
use FireflyIII\Models\PiggyBank;
|
use FireflyIII\Models\PiggyBank;
|
||||||
use FireflyIII\Models\Transaction;
|
use FireflyIII\Models\Transaction;
|
||||||
use FireflyIII\Models\TransactionJournal;
|
use FireflyIII\Models\TransactionJournal;
|
||||||
|
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||||
use Grumpydictator\Gchart\GChart;
|
use Grumpydictator\Gchart\GChart;
|
||||||
use Illuminate\Database\Query\Builder as QueryBuilder;
|
use Illuminate\Database\Query\Builder as QueryBuilder;
|
||||||
@@ -311,49 +311,45 @@ class GoogleChartController extends Controller
|
|||||||
*
|
*
|
||||||
* @return \Symfony\Component\HttpFoundation\Response
|
* @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];
|
$paid = ['items' => [], 'amount' => 0];
|
||||||
$unpaid = ['items' => [], 'amount' => 0];
|
$unpaid = ['items' => [], 'amount' => 0];
|
||||||
$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());
|
||||||
|
|
||||||
$chart->addColumn('Name', 'string');
|
$bills = Auth::user()->bills()->where('active', 1)->get();
|
||||||
$chart->addColumn('Amount', 'number');
|
|
||||||
|
|
||||||
$set = Bill::
|
/** @var Bill $bill */
|
||||||
leftJoin(
|
foreach ($bills as $bill) {
|
||||||
'transaction_journals', function (JoinClause $join) use ($start, $end) {
|
$ranges = $repository->getRanges($bill, $start, $end);
|
||||||
$join->on('bills.id', '=', 'transaction_journals.bill_id')
|
|
||||||
->where('transaction_journals.date', '>=', $start->format('Y-m-d'))
|
foreach ($ranges as $range) {
|
||||||
->where('transaction_journals.date', '<=', $end->format('Y-m-d'));
|
// paid a bill in this range?
|
||||||
}
|
$count = $bill->transactionjournals()->before($range['end'])->after($range['start'])->count();
|
||||||
)
|
if ($count == 0) {
|
||||||
->leftJoin(
|
$unpaid['items'][] = $bill->name . ' (' . $range['start']->format('jS M Y') . ')';
|
||||||
'transactions', function (JoinClause $join) {
|
$unpaid['amount'] += ($bill->amount_max + $bill->amount_min / 2);
|
||||||
$join->on('transaction_journals.id', '=', 'transactions.transaction_journal_id')->where('transactions.amount', '>', 0);
|
|
||||||
}
|
} else {
|
||||||
)
|
$journal = $bill->transactionjournals()->with('transactions')->before($range['end'])->after($range['start'])->first();
|
||||||
->where('active', 1)
|
$paid['items'][] = $journal->description;
|
||||||
->groupBy('bills.id')
|
$amount = 0;
|
||||||
->get(
|
foreach ($journal->transactions as $t) {
|
||||||
['bills.id', 'bills.name', 'transaction_journals.description',
|
if (floatval($t->amount) > 0) {
|
||||||
'transaction_journals.encrypted',
|
$amount = floatval($t->amount);
|
||||||
'transaction_journals.id as journalId',
|
}
|
||||||
\DB::Raw('SUM(`bills`.`amount_min` + `bills`.`amount_max`) / 2 as `averageAmount`'),
|
}
|
||||||
'transactions.amount AS actualAmount']
|
$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('Unpaid: ' . join(', ', $unpaid['items']), $unpaid['amount']);
|
||||||
$chart->addRow('Paid: ' . join(', ', $paid['items']), $paid['amount']);
|
$chart->addRow('Paid: ' . join(', ', $paid['items']), $paid['amount']);
|
||||||
$chart->generate();
|
$chart->generate();
|
||||||
|
@@ -1,18 +1,12 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
|
||||||
* Created by PhpStorm.
|
|
||||||
* User: sander
|
|
||||||
* Date: 25/02/15
|
|
||||||
* Time: 07:40
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace FireflyIII\Repositories\Bill;
|
namespace FireflyIII\Repositories\Bill;
|
||||||
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use FireflyIII\Models\Bill;
|
use FireflyIII\Models\Bill;
|
||||||
use FireflyIII\Models\TransactionJournal;
|
use FireflyIII\Models\TransactionJournal;
|
||||||
use Navigation;
|
|
||||||
use Log;
|
use Log;
|
||||||
|
use Navigation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class BillRepository
|
* Class BillRepository
|
||||||
@@ -21,6 +15,54 @@ use Log;
|
|||||||
*/
|
*/
|
||||||
class BillRepository implements BillRepositoryInterface
|
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
|
* @param Bill $bill
|
||||||
*
|
*
|
||||||
@@ -28,6 +70,7 @@ class BillRepository implements BillRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function nextExpectedMatch(Bill $bill)
|
public function nextExpectedMatch(Bill $bill)
|
||||||
{
|
{
|
||||||
|
|
||||||
$finalDate = null;
|
$finalDate = null;
|
||||||
if ($bill->active == 0) {
|
if ($bill->active == 0) {
|
||||||
return $finalDate;
|
return $finalDate;
|
||||||
@@ -113,7 +156,7 @@ class BillRepository implements BillRepositoryInterface
|
|||||||
$wordMatch = true;
|
$wordMatch = true;
|
||||||
Log::debug('word match is true');
|
Log::debug('word match is true');
|
||||||
} else {
|
} else {
|
||||||
Log::debug('Count: ' . $count.', count(matches): ' . count($matches));
|
Log::debug('Count: ' . $count . ', count(matches): ' . count($matches));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,13 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
|
||||||
* Created by PhpStorm.
|
|
||||||
* User: sander
|
|
||||||
* Date: 25/02/15
|
|
||||||
* Time: 07:40
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace FireflyIII\Repositories\Bill;
|
namespace FireflyIII\Repositories\Bill;
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
use FireflyIII\Models\Bill;
|
use FireflyIII\Models\Bill;
|
||||||
use FireflyIII\Models\TransactionJournal;
|
use FireflyIII\Models\TransactionJournal;
|
||||||
|
|
||||||
@@ -25,6 +20,19 @@ interface BillRepositoryInterface {
|
|||||||
*/
|
*/
|
||||||
public function nextExpectedMatch(Bill $bill);
|
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
|
* @param array $data
|
||||||
*
|
*
|
||||||
|
@@ -298,15 +298,15 @@ class Navigation
|
|||||||
$date = clone $theDate;
|
$date = clone $theDate;
|
||||||
|
|
||||||
$functionMap = [
|
$functionMap = [
|
||||||
'daily' => 'startOfDay',
|
'daily' => 'startOfDay',
|
||||||
'week' => 'startOfWeek',
|
'week' => 'startOfWeek',
|
||||||
'weekly' => 'startOfWeek',
|
'weekly' => 'startOfWeek',
|
||||||
'month' => 'startOfMonth',
|
'month' => 'startOfMonth',
|
||||||
'monthly' => 'startOfMonth',
|
'monthly' => 'startOfMonth',
|
||||||
'quarter' => 'firstOfQuarter',
|
'quarter' => 'firstOfQuarter',
|
||||||
'quartly' => 'firstOfQuarter',
|
'quarterly' => 'firstOfQuarter',
|
||||||
'year' => 'startOfYear',
|
'year' => 'startOfYear',
|
||||||
'yearly' => 'startOfYear',
|
'yearly' => 'startOfYear',
|
||||||
];
|
];
|
||||||
if (isset($functionMap[$repeatFreq])) {
|
if (isset($functionMap[$repeatFreq])) {
|
||||||
$function = $functionMap[$repeatFreq];
|
$function = $functionMap[$repeatFreq];
|
||||||
|
Reference in New Issue
Block a user