mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Merge branch 'release/3.5.2'
This commit is contained in:
commit
8b9607f9b5
@ -33,7 +33,7 @@ class ChartJsBillChartGenerator implements BillChartGenerator
|
|||||||
/** @var TransactionJournal $entry */
|
/** @var TransactionJournal $entry */
|
||||||
foreach ($paid as $entry) { // loop paid and create single entry:
|
foreach ($paid as $entry) { // loop paid and create single entry:
|
||||||
$paidDescriptions[] = $entry->description;
|
$paidDescriptions[] = $entry->description;
|
||||||
$paidAmount = bcadd($paidAmount, $entry->amount);
|
$paidAmount = bcadd($paidAmount, $entry->amount_positive);
|
||||||
}
|
}
|
||||||
/** @var Bill $entry */
|
/** @var Bill $entry */
|
||||||
foreach ($unpaid as $entry) { // loop unpaid:
|
foreach ($unpaid as $entry) { // loop unpaid:
|
||||||
@ -91,7 +91,7 @@ class ChartJsBillChartGenerator implements BillChartGenerator
|
|||||||
$data['labels'][] = $entry->date->formatLocalized($format);
|
$data['labels'][] = $entry->date->formatLocalized($format);
|
||||||
$minAmount[] = round($bill->amount_min, 2);
|
$minAmount[] = round($bill->amount_min, 2);
|
||||||
$maxAmount[] = round($bill->amount_max, 2);
|
$maxAmount[] = round($bill->amount_max, 2);
|
||||||
$actualAmount[] = round($entry->amount, 2);
|
$actualAmount[] = round(($entry->amount * -1), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
$data['datasets'][] = [
|
$data['datasets'][] = [
|
||||||
|
@ -31,7 +31,7 @@ interface CategoryChartGenerator
|
|||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function month(Collection $entries);
|
public function period(Collection $entries);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -17,16 +17,12 @@ class ChartJsCategoryChartGenerator implements CategoryChartGenerator
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Collection $entries
|
* @param Collection $entries
|
||||||
* @param string $dateFormat
|
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function all(Collection $entries, $dateFormat = 'month')
|
public function all(Collection $entries)
|
||||||
{
|
{
|
||||||
|
|
||||||
// language:
|
|
||||||
$language = Preferences::get('language', 'en')->data;
|
|
||||||
$format = Config::get('firefly.' . $dateFormat . '.' . $language);
|
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'count' => 2,
|
'count' => 2,
|
||||||
@ -44,15 +40,12 @@ class ChartJsCategoryChartGenerator implements CategoryChartGenerator
|
|||||||
];
|
];
|
||||||
|
|
||||||
foreach ($entries as $entry) {
|
foreach ($entries as $entry) {
|
||||||
$data['labels'][] = $entry[0]->formatLocalized($format);
|
$data['labels'][] = $entry[1];
|
||||||
$amount = round($entry[1], 2);
|
$spent = round($entry[2], 2);
|
||||||
if ($amount > 0) {
|
$earned = round($entry[3], 2);
|
||||||
$data['datasets'][0]['data'][] = null;
|
|
||||||
$data['datasets'][1]['data'][] = $amount;
|
$data['datasets'][0]['data'][] = $spent == 0 ? null : $spent * -1;
|
||||||
} else {
|
$data['datasets'][1]['data'][] = $earned == 0 ? null : $earned;
|
||||||
$data['datasets'][0]['data'][] = $amount * -1;
|
|
||||||
$data['datasets'][1]['data'][] = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
@ -78,7 +71,7 @@ class ChartJsCategoryChartGenerator implements CategoryChartGenerator
|
|||||||
foreach ($entries as $entry) {
|
foreach ($entries as $entry) {
|
||||||
if ($entry['sum'] != 0) {
|
if ($entry['sum'] != 0) {
|
||||||
$data['labels'][] = $entry['name'];
|
$data['labels'][] = $entry['name'];
|
||||||
$data['datasets'][0]['data'][] = round($entry['sum'], 2);
|
$data['datasets'][0]['data'][] = round(($entry['sum'] * -1), 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,9 +85,9 @@ class ChartJsCategoryChartGenerator implements CategoryChartGenerator
|
|||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function month(Collection $entries)
|
public function period(Collection $entries)
|
||||||
{
|
{
|
||||||
return $this->all($entries, 'monthAndDay');
|
return $this->all($entries);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ class ConnectJournalToPiggyBank
|
|||||||
}
|
}
|
||||||
bcscale(2);
|
bcscale(2);
|
||||||
|
|
||||||
$amount = $journal->actual_amount;
|
$amount = $journal->amount_positive;
|
||||||
// if piggy account matches source account, the amount is positive
|
// if piggy account matches source account, the amount is positive
|
||||||
if ($piggyBank->account_id == $journal->source_account->id) {
|
if ($piggyBank->account_id == $journal->source_account->id) {
|
||||||
$amount = $amount * -1;
|
$amount = $amount * -1;
|
||||||
|
@ -33,11 +33,10 @@ class Expense
|
|||||||
*/
|
*/
|
||||||
public function addOrCreateExpense(TransactionJournal $entry)
|
public function addOrCreateExpense(TransactionJournal $entry)
|
||||||
{
|
{
|
||||||
|
|
||||||
$accountId = $entry->account_id;
|
$accountId = $entry->account_id;
|
||||||
if (!$this->expenses->has($accountId)) {
|
if (!$this->expenses->has($accountId)) {
|
||||||
$newObject = new stdClass;
|
$newObject = new stdClass;
|
||||||
$newObject->amount = strval(round($entry->amount, 2));
|
$newObject->amount = strval(round($entry->amount_positive, 2));
|
||||||
$newObject->name = $entry->name;
|
$newObject->name = $entry->name;
|
||||||
$newObject->count = 1;
|
$newObject->count = 1;
|
||||||
$newObject->id = $accountId;
|
$newObject->id = $accountId;
|
||||||
@ -45,7 +44,7 @@ class Expense
|
|||||||
} else {
|
} else {
|
||||||
bcscale(2);
|
bcscale(2);
|
||||||
$existing = $this->expenses->get($accountId);
|
$existing = $this->expenses->get($accountId);
|
||||||
$existing->amount = bcadd($existing->amount, $entry->amount);
|
$existing->amount = bcadd($existing->amount, $entry->amount_positive);
|
||||||
$existing->count++;
|
$existing->count++;
|
||||||
$this->expenses->put($accountId, $existing);
|
$this->expenses->put($accountId, $existing);
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ class Income
|
|||||||
$accountId = $entry->account_id;
|
$accountId = $entry->account_id;
|
||||||
if (!$this->incomes->has($accountId)) {
|
if (!$this->incomes->has($accountId)) {
|
||||||
$newObject = new stdClass;
|
$newObject = new stdClass;
|
||||||
$newObject->amount = strval(round($entry->amount, 2));
|
$newObject->amount = strval(round($entry->amount_positive, 2));
|
||||||
$newObject->name = $entry->name;
|
$newObject->name = $entry->name;
|
||||||
$newObject->count = 1;
|
$newObject->count = 1;
|
||||||
$newObject->id = $accountId;
|
$newObject->id = $accountId;
|
||||||
@ -46,7 +46,7 @@ class Income
|
|||||||
} else {
|
} else {
|
||||||
bcscale(2);
|
bcscale(2);
|
||||||
$existing = $this->incomes->get($accountId);
|
$existing = $this->incomes->get($accountId);
|
||||||
$existing->amount = bcadd($existing->amount, $entry->amount);
|
$existing->amount = bcadd($existing->amount, $entry->amount_positive);
|
||||||
$existing->count++;
|
$existing->count++;
|
||||||
$this->incomes->put($accountId, $existing);
|
$this->incomes->put($accountId, $existing);
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,7 @@ class ReportHelper implements ReportHelperInterface
|
|||||||
$line->setBudget($budget);
|
$line->setBudget($budget);
|
||||||
|
|
||||||
// get budget amount for current period:
|
// get budget amount for current period:
|
||||||
$rep = $repository->getCurrentRepetition($budget, $start);
|
$rep = $repository->getCurrentRepetition($budget, $start, $end);
|
||||||
$line->setRepetition($rep);
|
$line->setRepetition($rep);
|
||||||
|
|
||||||
// loop accounts:
|
// loop accounts:
|
||||||
@ -279,6 +279,7 @@ class ReportHelper implements ReportHelperInterface
|
|||||||
$budgetLine->setBudget($budget);
|
$budgetLine->setBudget($budget);
|
||||||
$budgetLine->setRepetition($repetition);
|
$budgetLine->setRepetition($repetition);
|
||||||
$expenses = $repository->balanceInPeriod($budget, $repetition->startdate, $repetition->enddate, $shared);
|
$expenses = $repository->balanceInPeriod($budget, $repetition->startdate, $repetition->enddate, $shared);
|
||||||
|
$expenses = $expenses * -1;
|
||||||
$left = $expenses < $repetition->amount ? bcsub($repetition->amount, $expenses) : 0;
|
$left = $expenses < $repetition->amount ? bcsub($repetition->amount, $expenses) : 0;
|
||||||
$spent = $expenses > $repetition->amount ? 0 : $expenses;
|
$spent = $expenses > $repetition->amount ? 0 : $expenses;
|
||||||
$overspent = $expenses > $repetition->amount ? bcsub($expenses, $repetition->amount) : 0;
|
$overspent = $expenses > $repetition->amount ? bcsub($expenses, $repetition->amount) : 0;
|
||||||
@ -350,7 +351,7 @@ class ReportHelper implements ReportHelperInterface
|
|||||||
$object = new Expense;
|
$object = new Expense;
|
||||||
$set = $this->query->expenseInPeriodCorrected($start, $end, $shared);
|
$set = $this->query->expenseInPeriodCorrected($start, $end, $shared);
|
||||||
foreach ($set as $entry) {
|
foreach ($set as $entry) {
|
||||||
$object->addToTotal($entry->amount);
|
$object->addToTotal($entry->amount_positive);
|
||||||
$object->addOrCreateExpense($entry);
|
$object->addOrCreateExpense($entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -371,7 +372,7 @@ class ReportHelper implements ReportHelperInterface
|
|||||||
$object = new Income;
|
$object = new Income;
|
||||||
$set = $this->query->incomeInPeriodCorrected($start, $end, $shared);
|
$set = $this->query->incomeInPeriodCorrected($start, $end, $shared);
|
||||||
foreach ($set as $entry) {
|
foreach ($set as $entry) {
|
||||||
$object->addToTotal($entry->amount);
|
$object->addToTotal($entry->amount_positive);
|
||||||
$object->addOrCreateIncome($entry);
|
$object->addOrCreateIncome($entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@ class ReportQuery implements ReportQueryInterface
|
|||||||
function (Builder $q) { // and transfers from a shared account.
|
function (Builder $q) { // and transfers from a shared account.
|
||||||
$q->where('transaction_types.type', 'Transfer');
|
$q->where('transaction_types.type', 'Transfer');
|
||||||
$q->where('acm_to.data', '=', '"sharedAsset"');
|
$q->where('acm_to.data', '=', '"sharedAsset"');
|
||||||
|
$q->where('acm_from.data', '!=', '"sharedAsset"');
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -69,15 +70,6 @@ class ReportQuery implements ReportQueryInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
$data = $data->filter(
|
|
||||||
function (TransactionJournal $journal) {
|
|
||||||
if ($journal->amount != 0) {
|
|
||||||
return $journal;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
@ -164,6 +156,7 @@ class ReportQuery implements ReportQueryInterface
|
|||||||
function (Builder $q) {
|
function (Builder $q) {
|
||||||
$q->where('transaction_types.type', 'Transfer');
|
$q->where('transaction_types.type', 'Transfer');
|
||||||
$q->where('acm_from.data', '=', '"sharedAsset"');
|
$q->where('acm_from.data', '=', '"sharedAsset"');
|
||||||
|
$q->where('acm_to.data','!=','"sharedAsset"');
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ use FireflyIII\Models\Budget;
|
|||||||
use FireflyIII\Models\LimitRepetition;
|
use FireflyIII\Models\LimitRepetition;
|
||||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||||
use Input;
|
use Input;
|
||||||
|
use Navigation;
|
||||||
use Preferences;
|
use Preferences;
|
||||||
use Response;
|
use Response;
|
||||||
use Session;
|
use Session;
|
||||||
@ -140,20 +141,23 @@ class BudgetController extends Controller
|
|||||||
$inactive = $repository->getInactiveBudgets();
|
$inactive = $repository->getInactiveBudgets();
|
||||||
$spent = '0';
|
$spent = '0';
|
||||||
$budgeted = '0';
|
$budgeted = '0';
|
||||||
|
$range = Preferences::get('viewRange', '1M')->data;
|
||||||
|
$start = Navigation::startOfPeriod(Session::get('start', new Carbon), $range);
|
||||||
|
$end = Navigation::endOfPeriod($start, $range);
|
||||||
|
$key = 'budgetIncomeTotal' . $start->format('Ymd') . $end->format('Ymd');
|
||||||
|
$budgetIncomeTotal = Preferences::get($key, 1000)->data;
|
||||||
|
$period = Navigation::periodShow($start, $range);
|
||||||
bcscale(2);
|
bcscale(2);
|
||||||
/**
|
/**
|
||||||
* Do some cleanup:
|
* Do some cleanup:
|
||||||
*/
|
*/
|
||||||
$repository->cleanupBudgets();
|
$repository->cleanupBudgets();
|
||||||
|
|
||||||
|
|
||||||
// loop the budgets:
|
// loop the budgets:
|
||||||
/** @var Budget $budget */
|
/** @var Budget $budget */
|
||||||
foreach ($budgets as $budget) {
|
foreach ($budgets as $budget) {
|
||||||
$date = Session::get('start', Carbon::now()->startOfMonth());
|
$budget->spent = $repository->balanceInPeriod($budget, $start, $end);
|
||||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
$budget->currentRep = $repository->getCurrentRepetition($budget, $start, $end);
|
||||||
$budget->spent = $repository->balanceInPeriod($budget, $date, $end);
|
|
||||||
$budget->currentRep = $repository->getCurrentRepetition($budget, $date);
|
|
||||||
if ($budget->currentRep) {
|
if ($budget->currentRep) {
|
||||||
$budgeted = bcadd($budgeted, $budget->currentRep->amount);
|
$budgeted = bcadd($budgeted, $budget->currentRep->amount);
|
||||||
}
|
}
|
||||||
@ -161,13 +165,12 @@ class BudgetController extends Controller
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$dateAsString = Session::get('start', Carbon::now()->startOfMonth())->format('FY');
|
|
||||||
$budgetIncomeTotal = Preferences::get('budgetIncomeTotal' . $dateAsString, 1000)->data;
|
|
||||||
$budgetMaximum = Preferences::get('budgetMaximum', 1000)->data;
|
$budgetMaximum = Preferences::get('budgetMaximum', 1000)->data;
|
||||||
$defaultCurrency = Amount::getDefaultCurrency();
|
$defaultCurrency = Amount::getDefaultCurrency();
|
||||||
|
|
||||||
return view(
|
return view(
|
||||||
'budgets.index', compact('budgetMaximum', 'budgetIncomeTotal', 'defaultCurrency', 'inactive', 'budgets', 'spent', 'budgeted')
|
'budgets.index', compact('budgetMaximum','period', 'range', 'budgetIncomeTotal', 'defaultCurrency', 'inactive', 'budgets', 'spent', 'budgeted')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,8 +181,9 @@ class BudgetController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function noBudget(BudgetRepositoryInterface $repository)
|
public function noBudget(BudgetRepositoryInterface $repository)
|
||||||
{
|
{
|
||||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
$range = Preferences::get('viewRange', '1M')->data;
|
||||||
$end = Session::get('end', Carbon::now()->startOfMonth());
|
$start = Navigation::startOfPeriod(Session::get('start', new Carbon), $range);
|
||||||
|
$end = Navigation::endOfPeriod($start, $range);
|
||||||
$list = $repository->getWithoutBudget($start, $end);
|
$list = $repository->getWithoutBudget($start, $end);
|
||||||
$subTitle = trans(
|
$subTitle = trans(
|
||||||
'firefly.without_budget_between',
|
'firefly.without_budget_between',
|
||||||
@ -194,9 +198,12 @@ class BudgetController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function postUpdateIncome()
|
public function postUpdateIncome()
|
||||||
{
|
{
|
||||||
|
$range = Preferences::get('viewRange', '1M')->data;
|
||||||
|
$start = Navigation::startOfPeriod(Session::get('start', new Carbon), $range);
|
||||||
|
$end = Navigation::endOfPeriod($start, $range);
|
||||||
|
$key = 'budgetIncomeTotal' . $start->format('Ymd') . $end->format('Ymd');
|
||||||
|
|
||||||
$date = Session::get('start', Carbon::now()->startOfMonth())->format('FY');
|
Preferences::set($key, intval(Input::get('amount')));
|
||||||
Preferences::set('budgetIncomeTotal' . $date, intval(Input::get('amount')));
|
|
||||||
Preferences::mark();
|
Preferences::mark();
|
||||||
|
|
||||||
return redirect(route('budgets.index'));
|
return redirect(route('budgets.index'));
|
||||||
@ -297,8 +304,11 @@ class BudgetController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function updateIncome()
|
public function updateIncome()
|
||||||
{
|
{
|
||||||
$date = Session::get('start', Carbon::now()->startOfMonth())->format('FY');
|
$range = Preferences::get('viewRange', '1M')->data;
|
||||||
$amount = Preferences::get('budgetIncomeTotal' . $date, 1000);
|
$start = Navigation::startOfPeriod(Session::get('start', new Carbon), $range);
|
||||||
|
$end = Navigation::endOfPeriod($start, $range);
|
||||||
|
$key = 'budgetIncomeTotal' . $start->format('Ymd') . $end->format('Ymd');
|
||||||
|
$amount = Preferences::get($key, 1000);
|
||||||
|
|
||||||
return view('budgets.income', compact('amount'));
|
return view('budgets.income', compact('amount'));
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,11 @@ use Carbon\Carbon;
|
|||||||
use FireflyIII\Http\Requests\CategoryFormRequest;
|
use FireflyIII\Http\Requests\CategoryFormRequest;
|
||||||
use FireflyIII\Models\Category;
|
use FireflyIII\Models\Category;
|
||||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||||
|
use FireflyIII\Support\CacheProperties;
|
||||||
use Illuminate\Pagination\LengthAwarePaginator;
|
use Illuminate\Pagination\LengthAwarePaginator;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
use Input;
|
use Input;
|
||||||
|
use Navigation;
|
||||||
use Preferences;
|
use Preferences;
|
||||||
use Session;
|
use Session;
|
||||||
use URL;
|
use URL;
|
||||||
@ -139,6 +142,31 @@ class CategoryController extends Controller
|
|||||||
return view('categories.noCategory', compact('list', 'subTitle'));
|
return view('categories.noCategory', compact('list', 'subTitle'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param CategoryRepositoryInterface $repository
|
||||||
|
* @param Category $category
|
||||||
|
*
|
||||||
|
* @return \Illuminate\View\View
|
||||||
|
*/
|
||||||
|
public function showWithDate(CategoryRepositoryInterface $repository, Category $category, $date)
|
||||||
|
{
|
||||||
|
$carbon = new Carbon($date);
|
||||||
|
$range = Preferences::get('viewRange', '1M')->data;
|
||||||
|
$start = Navigation::startOfPeriod($carbon, $range);
|
||||||
|
$end = Navigation::endOfPeriod($carbon, $range);
|
||||||
|
$subTitle = $category->name;
|
||||||
|
|
||||||
|
$hideCategory = true; // used in list.
|
||||||
|
$page = intval(Input::get('page'));
|
||||||
|
|
||||||
|
$set = $repository->getJournalsInRange($category, $page, $start, $end);
|
||||||
|
$count = $repository->countJournalsInRange($category, $start, $end);
|
||||||
|
$journals = new LengthAwarePaginator($set, $count, 50, $page);
|
||||||
|
$journals->setPath('categories/show/' . $category->id . '/' . $date);
|
||||||
|
|
||||||
|
return view('categories.show_with_date', compact('category', 'journals', 'hideCategory', 'subTitle', 'carbon'));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param CategoryRepositoryInterface $repository
|
* @param CategoryRepositoryInterface $repository
|
||||||
* @param Category $category
|
* @param Category $category
|
||||||
@ -151,12 +179,47 @@ class CategoryController extends Controller
|
|||||||
$page = intval(Input::get('page'));
|
$page = intval(Input::get('page'));
|
||||||
$set = $repository->getJournals($category, $page);
|
$set = $repository->getJournals($category, $page);
|
||||||
$count = $repository->countJournals($category);
|
$count = $repository->countJournals($category);
|
||||||
$totalSum = $repository->journalsSum($category);
|
$subTitle = $category->name;
|
||||||
$periodSum = $repository->journalsSum($category, Session::get('start'), Session::get('end'));
|
|
||||||
$journals = new LengthAwarePaginator($set, $count, 50, $page);
|
$journals = new LengthAwarePaginator($set, $count, 50, $page);
|
||||||
$journals->setPath('categories/show/' . $category->id);
|
$journals->setPath('categories/show/' . $category->id);
|
||||||
|
|
||||||
return view('categories.show', compact('category', 'journals', 'hideCategory', 'totalSum', 'periodSum'));
|
// list of ranges for list of periods:
|
||||||
|
|
||||||
|
// oldest transaction in category:
|
||||||
|
$start = $repository->getFirstActivityDate($category);
|
||||||
|
$range = Preferences::get('viewRange', '1M')->data;
|
||||||
|
$start = Navigation::startOfPeriod($start, $range);
|
||||||
|
$end = Navigation::endOfX(new Carbon, $range);
|
||||||
|
$entries = new Collection;
|
||||||
|
|
||||||
|
// chart properties for cache:
|
||||||
|
$cache = new CacheProperties();
|
||||||
|
$cache->addProperty($start);
|
||||||
|
$cache->addProperty($end);
|
||||||
|
$cache->addProperty('category-show');
|
||||||
|
$cache->addProperty($category->id);
|
||||||
|
if ($cache->has()) {
|
||||||
|
$entries = $cache->get();
|
||||||
|
} else {
|
||||||
|
|
||||||
|
while ($end >= $start) {
|
||||||
|
$end = Navigation::startOfPeriod($end, $range);
|
||||||
|
$currentEnd = Navigation::endOfPeriod($end, $range);
|
||||||
|
|
||||||
|
// here do something.
|
||||||
|
$spent = $repository->spentInPeriod($category, $end, $currentEnd);
|
||||||
|
$earned = $repository->earnedInPeriod($category, $end, $currentEnd);
|
||||||
|
$dateStr = $end->format('Y-m-d');
|
||||||
|
$dateName = Navigation::periodShow($end, $range);
|
||||||
|
$entries->push([$dateStr, $dateName, $spent, $earned]);
|
||||||
|
|
||||||
|
$end = Navigation::subtractPeriod($end, $range, 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
$cache->store($entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
return view('categories.show', compact('category', 'journals', 'entries', 'hideCategory', 'subTitle'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -68,7 +68,7 @@ class BudgetController extends Controller
|
|||||||
$end->subDay();
|
$end->subDay();
|
||||||
$chartDate = clone $end;
|
$chartDate = clone $end;
|
||||||
$chartDate->startOfMonth();
|
$chartDate->startOfMonth();
|
||||||
$spent = $repository->balanceInPeriod($budget, $first, $end);
|
$spent = $repository->balanceInPeriod($budget, $first, $end) * -1;
|
||||||
$entries->push([$chartDate, $spent]);
|
$entries->push([$chartDate, $spent]);
|
||||||
$first = Navigation::addPeriod($first, $range, 0);
|
$first = Navigation::addPeriod($first, $range, 0);
|
||||||
}
|
}
|
||||||
@ -156,13 +156,13 @@ class BudgetController extends Controller
|
|||||||
foreach ($budgets as $budget) {
|
foreach ($budgets as $budget) {
|
||||||
$repetitions = $repository->getBudgetLimitRepetitions($budget, $start, $end);
|
$repetitions = $repository->getBudgetLimitRepetitions($budget, $start, $end);
|
||||||
if ($repetitions->count() == 0) {
|
if ($repetitions->count() == 0) {
|
||||||
$expenses = $repository->balanceInPeriod($budget, $start, $end, true);
|
$expenses = $repository->balanceInPeriod($budget, $start, $end, true) * -1;
|
||||||
$allEntries->push([$budget->name, 0, 0, $expenses, 0, 0]);
|
$allEntries->push([$budget->name, 0, 0, $expenses, 0, 0]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/** @var LimitRepetition $repetition */
|
/** @var LimitRepetition $repetition */
|
||||||
foreach ($repetitions as $repetition) {
|
foreach ($repetitions as $repetition) {
|
||||||
$expenses = $repository->balanceInPeriod($budget, $repetition->startdate, $repetition->enddate, true);
|
$expenses = $repository->balanceInPeriod($budget, $repetition->startdate, $repetition->enddate, true) * -1;
|
||||||
// $left can be less than zero.
|
// $left can be less than zero.
|
||||||
// $overspent can be more than zero ( = overspending)
|
// $overspent can be more than zero ( = overspending)
|
||||||
|
|
||||||
|
@ -65,11 +65,16 @@ class CategoryController extends Controller
|
|||||||
|
|
||||||
while ($start <= $end) {
|
while ($start <= $end) {
|
||||||
$currentEnd = Navigation::endOfPeriod($start, $range);
|
$currentEnd = Navigation::endOfPeriod($start, $range);
|
||||||
$spent = $repository->balanceInPeriod($category, $start, $currentEnd);
|
$spent = $repository->spentInPeriod($category, $start, $currentEnd);
|
||||||
$entries->push([clone $start, $spent]);
|
$earned = $repository->earnedInPeriod($category, $start, $currentEnd);
|
||||||
|
$date = Navigation::periodShow($start, $range);
|
||||||
|
$entries->push([clone $start, $date, $spent, $earned]);
|
||||||
$start = Navigation::addPeriod($start, $range, 0);
|
$start = Navigation::addPeriod($start, $range, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// limit the set to the last 40:
|
||||||
|
$entries = $entries->reverse();
|
||||||
|
$entries = $entries->slice(0, 48);
|
||||||
|
$entries = $entries->reverse();
|
||||||
|
|
||||||
$data = $this->generator->all($entries);
|
$data = $this->generator->all($entries);
|
||||||
$cache->store($data);
|
$cache->store($data);
|
||||||
@ -111,7 +116,7 @@ class CategoryController extends Controller
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ($left['sum'] < $right['sum']) ? 1 : -1;
|
return ($left['sum'] < $right['sum']) ? -1 : 1;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
$set = new Collection($array);
|
$set = new Collection($array);
|
||||||
@ -127,7 +132,7 @@ class CategoryController extends Controller
|
|||||||
*
|
*
|
||||||
* @return \Symfony\Component\HttpFoundation\Response
|
* @return \Symfony\Component\HttpFoundation\Response
|
||||||
*/
|
*/
|
||||||
public function month(CategoryRepositoryInterface $repository, Category $category)
|
public function currentPeriod(CategoryRepositoryInterface $repository, Category $category)
|
||||||
{
|
{
|
||||||
$start = clone Session::get('start', Carbon::now()->startOfMonth());
|
$start = clone Session::get('start', Carbon::now()->startOfMonth());
|
||||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
$end = Session::get('end', Carbon::now()->endOfMonth());
|
||||||
@ -138,7 +143,7 @@ class CategoryController extends Controller
|
|||||||
$cache->addProperty($end);
|
$cache->addProperty($end);
|
||||||
$cache->addProperty($category->id);
|
$cache->addProperty($category->id);
|
||||||
$cache->addProperty('category');
|
$cache->addProperty('category');
|
||||||
$cache->addProperty('month');
|
$cache->addProperty('currentPeriod');
|
||||||
if ($cache->has()) {
|
if ($cache->has()) {
|
||||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||||
}
|
}
|
||||||
@ -147,12 +152,56 @@ class CategoryController extends Controller
|
|||||||
|
|
||||||
while ($start <= $end) {
|
while ($start <= $end) {
|
||||||
$spent = $repository->spentOnDaySumCorrected($category, $start);
|
$spent = $repository->spentOnDaySumCorrected($category, $start);
|
||||||
|
$earned = $repository->earnedOnDaySumCorrected($category, $start);
|
||||||
$entries->push([clone $start, $spent]);
|
$date = Navigation::periodShow($start, '1D');
|
||||||
|
$entries->push([clone $start, $date, $spent, $earned]);
|
||||||
$start->addDay();
|
$start->addDay();
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = $this->generator->month($entries);
|
$data = $this->generator->period($entries);
|
||||||
|
$cache->store($data);
|
||||||
|
|
||||||
|
return Response::json($data);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param CategoryRepositoryInterface $repository
|
||||||
|
* @param Category $category
|
||||||
|
*
|
||||||
|
* @return \Symfony\Component\HttpFoundation\Response
|
||||||
|
*/
|
||||||
|
public function specificPeriod(CategoryRepositoryInterface $repository, Category $category, $date)
|
||||||
|
{
|
||||||
|
$carbon = new Carbon($date);
|
||||||
|
$range = Preferences::get('viewRange', '1M')->data;
|
||||||
|
$start = Navigation::startOfPeriod($carbon, $range);
|
||||||
|
$end = Navigation::endOfPeriod($carbon, $range);
|
||||||
|
|
||||||
|
// chart properties for cache:
|
||||||
|
$cache = new CacheProperties;
|
||||||
|
$cache->addProperty($start);
|
||||||
|
$cache->addProperty($end);
|
||||||
|
$cache->addProperty($category->id);
|
||||||
|
$cache->addProperty('category');
|
||||||
|
$cache->addProperty('specificPeriod');
|
||||||
|
$cache->addProperty($date);
|
||||||
|
if ($cache->has()) {
|
||||||
|
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
$entries = new Collection;
|
||||||
|
|
||||||
|
|
||||||
|
while ($start <= $end) {
|
||||||
|
$spent = $repository->spentOnDaySumCorrected($category, $start);
|
||||||
|
$earned = $repository->earnedOnDaySumCorrected($category, $start);
|
||||||
|
$theDate = Navigation::periodShow($start, '1D');
|
||||||
|
$entries->push([clone $start, $theDate, $spent, $earned]);
|
||||||
|
$start->addDay();
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $this->generator->period($entries);
|
||||||
$cache->store($data);
|
$cache->store($data);
|
||||||
|
|
||||||
return Response::json($data);
|
return Response::json($data);
|
||||||
|
@ -9,6 +9,7 @@ use FireflyIII\Http\Controllers\Controller;
|
|||||||
use FireflyIII\Support\CacheProperties;
|
use FireflyIII\Support\CacheProperties;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Response;
|
use Response;
|
||||||
|
use Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ReportController
|
* Class ReportController
|
||||||
@ -62,8 +63,8 @@ class ReportController extends Controller
|
|||||||
$month = clone $start;
|
$month = clone $start;
|
||||||
$month->endOfMonth();
|
$month->endOfMonth();
|
||||||
// total income and total expenses:
|
// total income and total expenses:
|
||||||
$incomeSum = $query->incomeInPeriodCorrected($start, $month, $shared)->sum('amount');
|
$incomeSum = $query->incomeInPeriodCorrected($start, $month, $shared)->sum('amount_positive');
|
||||||
$expenseSum = $query->expenseInPeriodCorrected($start, $month, $shared)->sum('amount');
|
$expenseSum = $query->expenseInPeriodCorrected($start, $month, $shared)->sum('amount_positive');
|
||||||
|
|
||||||
$entries->push([clone $start, $incomeSum, $expenseSum]);
|
$entries->push([clone $start, $incomeSum, $expenseSum]);
|
||||||
$start->addMonth();
|
$start->addMonth();
|
||||||
@ -110,8 +111,18 @@ class ReportController extends Controller
|
|||||||
$month = clone $start;
|
$month = clone $start;
|
||||||
$month->endOfMonth();
|
$month->endOfMonth();
|
||||||
// total income and total expenses:
|
// total income and total expenses:
|
||||||
$income = bcadd($income, $query->incomeInPeriodCorrected($start, $month, $shared)->sum('amount'));
|
$currentIncome = $query->incomeInPeriodCorrected($start, $month, $shared)->sum('amount_positive');
|
||||||
$expense = bcadd($expense, $query->expenseInPeriodCorrected($start, $month, $shared)->sum('amount'));
|
$currentExpense = $query->expenseInPeriodCorrected($start, $month, $shared)->sum('amount_positive');
|
||||||
|
|
||||||
|
Log::debug('Date ['.$month->format('M Y').']: income = ['.$income.' + '.$currentIncome.'], out = ['.$expense.' + '.$currentExpense.']');
|
||||||
|
|
||||||
|
$income = bcadd($income, $currentIncome);
|
||||||
|
$expense = bcadd($expense, $currentExpense);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$count++;
|
$count++;
|
||||||
$start->addMonth();
|
$start->addMonth();
|
||||||
}
|
}
|
||||||
|
@ -93,6 +93,8 @@ class JsonController extends Controller
|
|||||||
}
|
}
|
||||||
unset($bill, $bills);
|
unset($bill, $bills);
|
||||||
|
|
||||||
|
$amount = $amount * -1; // make the amount positive again.
|
||||||
|
|
||||||
$creditCards = $accountRepository->getCreditCards(); // Find credit card accounts and possibly unpaid credit card bills.
|
$creditCards = $accountRepository->getCreditCards(); // Find credit card accounts and possibly unpaid credit card bills.
|
||||||
/** @var Account $creditCard */
|
/** @var Account $creditCard */
|
||||||
foreach ($creditCards as $creditCard) {
|
foreach ($creditCards as $creditCard) {
|
||||||
@ -219,6 +221,7 @@ class JsonController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
$amount = $reportQuery->expenseInPeriodCorrected($start, $end, true)->sum('amount');
|
$amount = $reportQuery->expenseInPeriodCorrected($start, $end, true)->sum('amount');
|
||||||
|
$amount = $amount * -1;
|
||||||
|
|
||||||
$data = ['box' => 'out', 'amount' => Amount::format($amount, false), 'amount_raw' => $amount];
|
$data = ['box' => 'out', 'amount' => Amount::format($amount, false), 'amount_raw' => $amount];
|
||||||
$cache->store($data);
|
$cache->store($data);
|
||||||
|
@ -179,7 +179,7 @@ class TransactionController extends Controller
|
|||||||
$preFilled['piggy_bank_id'] = $journal->piggyBankEvents()->orderBy('date', 'DESC')->first()->piggy_bank_id;
|
$preFilled['piggy_bank_id'] = $journal->piggyBankEvents()->orderBy('date', 'DESC')->first()->piggy_bank_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
$preFilled['amount'] = $journal->actual_amount;
|
$preFilled['amount'] = $journal->amount_positive;
|
||||||
|
|
||||||
if ($journal->transactionType->type == 'Withdrawal') {
|
if ($journal->transactionType->type == 'Withdrawal') {
|
||||||
$preFilled['account_id'] = $journal->source_account->id;
|
$preFilled['account_id'] = $journal->source_account->id;
|
||||||
|
@ -154,6 +154,19 @@ Breadcrumbs::register(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Breadcrumbs::register(
|
||||||
|
'categories.show.date', function (Generator $breadcrumbs, Category $category, Carbon $date) {
|
||||||
|
|
||||||
|
// get current period preference.
|
||||||
|
$range = Preferences::get('viewRange', '1M')->data;
|
||||||
|
|
||||||
|
$breadcrumbs->parent('categories.index');
|
||||||
|
$breadcrumbs->push(e($category->name), route('categories.show', [$category->id]));
|
||||||
|
$breadcrumbs->push(Navigation::periodShow($date, $range), route('categories.show.date', [$category->id, $date->format('Y-m-d')]));
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
Breadcrumbs::register(
|
Breadcrumbs::register(
|
||||||
'categories.noCategory', function (Generator $breadcrumbs, $subTitle) {
|
'categories.noCategory', function (Generator $breadcrumbs, $subTitle) {
|
||||||
$breadcrumbs->parent('categories.index');
|
$breadcrumbs->parent('categories.index');
|
||||||
|
@ -244,6 +244,7 @@ Route::group(
|
|||||||
Route::get('/categories/edit/{category}', ['uses' => 'CategoryController@edit', 'as' => 'categories.edit']);
|
Route::get('/categories/edit/{category}', ['uses' => 'CategoryController@edit', 'as' => 'categories.edit']);
|
||||||
Route::get('/categories/delete/{category}', ['uses' => 'CategoryController@delete', 'as' => 'categories.delete']);
|
Route::get('/categories/delete/{category}', ['uses' => 'CategoryController@delete', 'as' => 'categories.delete']);
|
||||||
Route::get('/categories/show/{category}', ['uses' => 'CategoryController@show', 'as' => 'categories.show']);
|
Route::get('/categories/show/{category}', ['uses' => 'CategoryController@show', 'as' => 'categories.show']);
|
||||||
|
Route::get('/categories/show/{category}/{date}', ['uses' => 'CategoryController@showWithDate', 'as' => 'categories.show.date']);
|
||||||
Route::get('/categories/list/noCategory', ['uses' => 'CategoryController@noCategory', 'as' => 'categories.noCategory']);
|
Route::get('/categories/list/noCategory', ['uses' => 'CategoryController@noCategory', 'as' => 'categories.noCategory']);
|
||||||
Route::post('/categories/store', ['uses' => 'CategoryController@store', 'as' => 'categories.store']);
|
Route::post('/categories/store', ['uses' => 'CategoryController@store', 'as' => 'categories.store']);
|
||||||
Route::post('/categories/update/{category}', ['uses' => 'CategoryController@update', 'as' => 'categories.update']);
|
Route::post('/categories/update/{category}', ['uses' => 'CategoryController@update', 'as' => 'categories.update']);
|
||||||
@ -307,7 +308,8 @@ Route::group(
|
|||||||
Route::get('/chart/category/earned-in-year/{year}/{shared?}', ['uses' => 'Chart\CategoryController@earnedInYear'])->where(
|
Route::get('/chart/category/earned-in-year/{year}/{shared?}', ['uses' => 'Chart\CategoryController@earnedInYear'])->where(
|
||||||
['year' => '[0-9]{4}', 'shared' => 'shared']
|
['year' => '[0-9]{4}', 'shared' => 'shared']
|
||||||
);
|
);
|
||||||
Route::get('/chart/category/{category}/month', ['uses' => 'Chart\CategoryController@month']); // should be period.
|
Route::get('/chart/category/{category}/period', ['uses' => 'Chart\CategoryController@currentPeriod']);
|
||||||
|
Route::get('/chart/category/{category}/period/{date}', ['uses' => 'Chart\CategoryController@specificPeriod']);
|
||||||
Route::get('/chart/category/{category}/all', ['uses' => 'Chart\CategoryController@all']);
|
Route::get('/chart/category/{category}/all', ['uses' => 'Chart\CategoryController@all']);
|
||||||
|
|
||||||
// piggy banks:
|
// piggy banks:
|
||||||
|
@ -39,8 +39,8 @@ use Illuminate\Database\Eloquent\Model;
|
|||||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereSkip($value)
|
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereSkip($value)
|
||||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereNameEncrypted($value)
|
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereNameEncrypted($value)
|
||||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereMatchEncrypted($value)
|
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereMatchEncrypted($value)
|
||||||
* @property-read \Carbon\Carbon $nextExpectedMatch
|
* @property \Carbon\Carbon $nextExpectedMatch
|
||||||
* @property-read \Carbon\Carbon $lastFoundMatch
|
* @property \Carbon\Carbon $lastFoundMatch
|
||||||
*/
|
*/
|
||||||
class Bill extends Model
|
class Bill extends Model
|
||||||
{
|
{
|
||||||
|
@ -69,6 +69,7 @@ use Watson\Validating\ValidatingTrait;
|
|||||||
* @property string $name
|
* @property string $name
|
||||||
* @property-read string $symbol
|
* @property-read string $symbol
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\Attachment[] $attachments
|
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\Attachment[] $attachments
|
||||||
|
* @property-read mixed $amount_positive
|
||||||
*/
|
*/
|
||||||
class TransactionJournal extends Model
|
class TransactionJournal extends Model
|
||||||
{
|
{
|
||||||
@ -120,7 +121,7 @@ class TransactionJournal extends Model
|
|||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getActualAmountAttribute()
|
public function getAmountPositiveAttribute()
|
||||||
{
|
{
|
||||||
$amount = '0';
|
$amount = '0';
|
||||||
/** @var Transaction $t */
|
/** @var Transaction $t */
|
||||||
@ -146,18 +147,11 @@ class TransactionJournal extends Model
|
|||||||
}
|
}
|
||||||
|
|
||||||
bcscale(2);
|
bcscale(2);
|
||||||
$set = $this->transactions->sortByDesc('amount');
|
$type = $this->transactionType->type;
|
||||||
$amount = $set->first()->amount;
|
$transaction = $this->transactions->sortByDesc('amount')->first();
|
||||||
|
$amount = $transaction->amount;
|
||||||
if (intval($this->tag_count) === 1) {
|
if ($type == 'Withdrawal') {
|
||||||
// get amount for single tag:
|
$amount = $amount * -1;
|
||||||
$amount = $this->amountByTag($this->tags()->first(), $amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (intval($this->tag_count) > 1) {
|
|
||||||
// get amount for either tag.
|
|
||||||
$amount = $this->amountByTags($amount);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
$cache->store($amount);
|
$cache->store($amount);
|
||||||
|
|
||||||
@ -176,7 +170,7 @@ class TransactionJournal extends Model
|
|||||||
if ($this->transactionType->type == 'Withdrawal') {
|
if ($this->transactionType->type == 'Withdrawal') {
|
||||||
$others = $tag->transactionJournals()->transactionTypes(['Deposit'])->get();
|
$others = $tag->transactionJournals()->transactionTypes(['Deposit'])->get();
|
||||||
foreach ($others as $other) {
|
foreach ($others as $other) {
|
||||||
$amount = bcsub($amount, $other->actual_amount);
|
$amount = bcsub($amount, $other->amount_positive);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $amount;
|
return $amount;
|
||||||
@ -199,7 +193,7 @@ class TransactionJournal extends Model
|
|||||||
if ($this->transactionType->type == 'Withdrawal') {
|
if ($this->transactionType->type == 'Withdrawal') {
|
||||||
$transfer = $tag->transactionJournals()->transactionTypes(['Transfer'])->first();
|
$transfer = $tag->transactionJournals()->transactionTypes(['Transfer'])->first();
|
||||||
if ($transfer) {
|
if ($transfer) {
|
||||||
$amount = bcsub($amount, $transfer->actual_amount);
|
$amount = bcsub($amount, $transfer->amount_positive);
|
||||||
|
|
||||||
return $amount;
|
return $amount;
|
||||||
}
|
}
|
||||||
@ -260,21 +254,6 @@ class TransactionJournal extends Model
|
|||||||
return $amount;
|
return $amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getCorrectAmountAttribute()
|
|
||||||
{
|
|
||||||
|
|
||||||
switch ($this->transactionType->type) {
|
|
||||||
case 'Deposit':
|
|
||||||
return $this->transactions()->where('amount', '>', 0)->first()->amount;
|
|
||||||
case 'Withdrawal':
|
|
||||||
return $this->transactions()->where('amount', '<', 0)->first()->amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->transactions()->where('amount', '>', 0)->first()->amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @codeCoverageIgnore
|
* @codeCoverageIgnore
|
||||||
|
@ -9,6 +9,7 @@ use FireflyIII\Models\Bill;
|
|||||||
use FireflyIII\Models\Transaction;
|
use FireflyIII\Models\Transaction;
|
||||||
use FireflyIII\Models\TransactionJournal;
|
use FireflyIII\Models\TransactionJournal;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
use Log;
|
||||||
use Navigation;
|
use Navigation;
|
||||||
use Steam;
|
use Steam;
|
||||||
|
|
||||||
@ -97,7 +98,10 @@ class BillRepository implements BillRepositoryInterface
|
|||||||
|
|
||||||
$set = $set->sortBy(
|
$set = $set->sortBy(
|
||||||
function (Bill $bill) {
|
function (Bill $bill) {
|
||||||
return strtolower($bill->name);
|
|
||||||
|
$int = $bill->active == 1 ? 0 : 1;
|
||||||
|
|
||||||
|
return $int . strtolower($bill->name);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -150,7 +154,9 @@ class BillRepository implements BillRepositoryInterface
|
|||||||
}
|
}
|
||||||
$journals = new Collection;
|
$journals = new Collection;
|
||||||
if (count($ids) > 0) {
|
if (count($ids) > 0) {
|
||||||
$journals = Auth::user()->transactionjournals()->whereIn('id', $ids)->get();
|
$journals = Auth::user()->transactionjournals()->transactionTypes(['Withdrawal'])->whereIn('transaction_journals.id', $ids)->get(
|
||||||
|
['transaction_journals.*']
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $journals;
|
return $journals;
|
||||||
@ -273,7 +279,8 @@ class BillRepository implements BillRepositoryInterface
|
|||||||
$matches = explode(',', $bill->match);
|
$matches = explode(',', $bill->match);
|
||||||
$description = strtolower($journal->description) . ' ' . strtolower($journal->destination_account->name);
|
$description = strtolower($journal->description) . ' ' . strtolower($journal->destination_account->name);
|
||||||
$wordMatch = $this->doWordMatch($matches, $description);
|
$wordMatch = $this->doWordMatch($matches, $description);
|
||||||
$amountMatch = $this->doAmountMatch($journal->amount, $bill->amount_min, $bill->amount_max);
|
$amountMatch = $this->doAmountMatch($journal->amount_positive, $bill->amount_min, $bill->amount_max);
|
||||||
|
Log::debug('Journal #' . $journal->id . ' has description "' . $description . '"');
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If both, update!
|
* If both, update!
|
||||||
@ -283,6 +290,8 @@ class BillRepository implements BillRepositoryInterface
|
|||||||
$journal->save();
|
$journal->save();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
} else {
|
||||||
|
Log::debug('Wordmatch: ' . (($wordMatch) ? 'true' : 'false') . ' AmountMatch: ' . (($amountMatch) ? 'true' : 'false'));
|
||||||
}
|
}
|
||||||
if ($bill->id == $journal->bill_id) {
|
if ($bill->id == $journal->bill_id) {
|
||||||
// if no match, but bill used to match, remove it:
|
// if no match, but bill used to match, remove it:
|
||||||
|
@ -55,7 +55,7 @@ class BudgetRepository extends ComponentRepository implements BudgetRepositoryIn
|
|||||||
bcscale(2);
|
bcscale(2);
|
||||||
$sum = $budget->transactionjournals()->transactionTypes(['Withdrawal'])->onDate($date)->get(['transaction_journals.*'])->sum('amount');
|
$sum = $budget->transactionjournals()->transactionTypes(['Withdrawal'])->onDate($date)->get(['transaction_journals.*'])->sum('amount');
|
||||||
|
|
||||||
return bcmul($sum, -1);
|
return $sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -122,20 +122,26 @@ class BudgetRepository extends ComponentRepository implements BudgetRepositoryIn
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Budget $budget
|
* @param Budget $budget
|
||||||
* @param Carbon $date
|
* @param Carbon $start
|
||||||
|
* @param Carbon $end
|
||||||
*
|
*
|
||||||
* @return LimitRepetition|null
|
* @return LimitRepetition|null
|
||||||
*/
|
*/
|
||||||
public function getCurrentRepetition(Budget $budget, Carbon $date)
|
public function getCurrentRepetition(Budget $budget, Carbon $start, Carbon $end)
|
||||||
{
|
{
|
||||||
$cache = new CacheProperties;
|
$cache = new CacheProperties;
|
||||||
$cache->addProperty($budget->id);
|
$cache->addProperty($budget->id);
|
||||||
$cache->addProperty($date);
|
$cache->addProperty($start);
|
||||||
|
$cache->addProperty($end);
|
||||||
|
|
||||||
$cache->addProperty('getCurrentRepetition');
|
$cache->addProperty('getCurrentRepetition');
|
||||||
if ($cache->has()) {
|
if ($cache->has()) {
|
||||||
return $cache->get(); // @codeCoverageIgnore
|
return $cache->get(); // @codeCoverageIgnore
|
||||||
}
|
}
|
||||||
$data = $budget->limitrepetitions()->where('limit_repetitions.startdate', $date)->first(['limit_repetitions.*']);
|
$data = $budget->limitrepetitions()
|
||||||
|
->where('limit_repetitions.startdate', $start)
|
||||||
|
->where('limit_repetitions.enddate', $end)
|
||||||
|
->first(['limit_repetitions.*']);
|
||||||
$cache->store($data);
|
$cache->store($data);
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
|
@ -65,11 +65,12 @@ interface BudgetRepositoryInterface
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Budget $budget
|
* @param Budget $budget
|
||||||
* @param Carbon $date
|
* @param Carbon $start
|
||||||
|
* @param Carbon $end
|
||||||
*
|
*
|
||||||
* @return LimitRepetition|null
|
* @return LimitRepetition|null
|
||||||
*/
|
*/
|
||||||
public function getCurrentRepetition(Budget $budget, Carbon $date);
|
public function getCurrentRepetition(Budget $budget, Carbon $start, Carbon $end);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Budget $budget
|
* @param Budget $budget
|
||||||
|
@ -8,6 +8,7 @@ use Crypt;
|
|||||||
use FireflyIII\Models\Category;
|
use FireflyIII\Models\Category;
|
||||||
use FireflyIII\Models\TransactionJournal;
|
use FireflyIII\Models\TransactionJournal;
|
||||||
use FireflyIII\Repositories\Shared\ComponentRepository;
|
use FireflyIII\Repositories\Shared\ComponentRepository;
|
||||||
|
use FireflyIII\Support\CacheProperties;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -199,7 +200,7 @@ class CategoryRepository extends ComponentRepository implements CategoryReposito
|
|||||||
*/
|
*/
|
||||||
public function spentOnDaySumCorrected(Category $category, Carbon $date)
|
public function spentOnDaySumCorrected(Category $category, Carbon $date)
|
||||||
{
|
{
|
||||||
return $category->transactionjournals()->onDate($date)->get(['transaction_journals.*'])->sum('correct_amount');
|
return $category->transactionjournals()->transactionTypes(['Withdrawal'])->onDate($date)->get(['transaction_journals.*'])->sum('amount');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -259,7 +260,113 @@ class CategoryRepository extends ComponentRepository implements CategoryReposito
|
|||||||
$query->before($end);
|
$query->before($end);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $query->get(['transaction_journals.*'])->sum('correct_amount');
|
return $query->get(['transaction_journals.*'])->sum('amount');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Category $category
|
||||||
|
* @param \Carbon\Carbon $start
|
||||||
|
* @param \Carbon\Carbon $end
|
||||||
|
*
|
||||||
|
* @param bool $shared
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function spentInPeriod(Category $category, Carbon $start, Carbon $end)
|
||||||
|
{
|
||||||
|
$cache = new CacheProperties; // we must cache this.
|
||||||
|
$cache->addProperty($category->id);
|
||||||
|
$cache->addProperty($start);
|
||||||
|
$cache->addProperty($end);
|
||||||
|
$cache->addProperty('spentInPeriod');
|
||||||
|
|
||||||
|
if ($cache->has()) {
|
||||||
|
return $cache->get(); // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
|
||||||
|
$sum = $category->transactionjournals()->transactionTypes(['Withdrawal'])->before($end)->after($start)->get(['transaction_journals.*'])->sum(
|
||||||
|
'amount'
|
||||||
|
);
|
||||||
|
|
||||||
|
$cache->store($sum);
|
||||||
|
|
||||||
|
return $sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Category $category
|
||||||
|
* @param \Carbon\Carbon $start
|
||||||
|
* @param \Carbon\Carbon $end
|
||||||
|
*
|
||||||
|
* @param bool $shared
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function earnedInPeriod(Category $category, Carbon $start, Carbon $end)
|
||||||
|
{
|
||||||
|
$cache = new CacheProperties; // we must cache this.
|
||||||
|
$cache->addProperty($category->id);
|
||||||
|
$cache->addProperty($start);
|
||||||
|
$cache->addProperty($end);
|
||||||
|
$cache->addProperty('earnedInPeriod');
|
||||||
|
|
||||||
|
if ($cache->has()) {
|
||||||
|
return $cache->get(); // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
|
||||||
|
$sum = $category->transactionjournals()->transactionTypes(['Deposit'])->before($end)->after($start)->get(['transaction_journals.*'])->sum(
|
||||||
|
'amount'
|
||||||
|
);
|
||||||
|
|
||||||
|
$cache->store($sum);
|
||||||
|
|
||||||
|
return $sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Category $category
|
||||||
|
* @param int $page
|
||||||
|
*
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
public function getJournalsInRange(Category $category, $page, Carbon $start, Carbon $end)
|
||||||
|
{
|
||||||
|
$offset = $page > 0 ? $page * 50 : 0;
|
||||||
|
|
||||||
|
return $category->transactionJournals()
|
||||||
|
->after($start)
|
||||||
|
->before($end)
|
||||||
|
->withRelevantData()->take(50)->offset($offset)
|
||||||
|
->orderBy('transaction_journals.date', 'DESC')
|
||||||
|
->orderBy('transaction_journals.order', 'ASC')
|
||||||
|
->orderBy('transaction_journals.id', 'DESC')
|
||||||
|
->get(
|
||||||
|
['transaction_journals.*']
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Category $category
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function countJournalsInRange(Category $category, Carbon $start, Carbon $end)
|
||||||
|
{
|
||||||
|
return $category->transactionJournals()->before($end)->after($start)->count();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Corrected for tags.
|
||||||
|
*
|
||||||
|
* @param Category $category
|
||||||
|
* @param Carbon $date
|
||||||
|
*
|
||||||
|
* @return float
|
||||||
|
*/
|
||||||
|
public function earnedOnDaySumCorrected(Category $category, Carbon $date)
|
||||||
|
{
|
||||||
|
return $category->transactionjournals()->transactionTypes(['Deposit'])->onDate($date)->get(['transaction_journals.*'])->sum('amount');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,13 @@ interface CategoryRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function countJournals(Category $category);
|
public function countJournals(Category $category);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Category $category
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function countJournalsInRange(Category $category, Carbon $start, Carbon $end);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Category $category
|
* @param Category $category
|
||||||
*
|
*
|
||||||
@ -57,6 +64,14 @@ interface CategoryRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function getJournals(Category $category, $page);
|
public function getJournals(Category $category, $page);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Category $category
|
||||||
|
* @param int $page
|
||||||
|
*
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
public function getJournalsInRange(Category $category, $page, Carbon $start, Carbon $end);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns the sum of the journals in the category, optionally
|
* This method returns the sum of the journals in the category, optionally
|
||||||
* limited by a start or end date.
|
* limited by a start or end date.
|
||||||
@ -97,6 +112,28 @@ interface CategoryRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function balanceInPeriod(Category $category, Carbon $start, Carbon $end, $shared = false);
|
public function balanceInPeriod(Category $category, Carbon $start, Carbon $end, $shared = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Category $category
|
||||||
|
* @param \Carbon\Carbon $start
|
||||||
|
* @param \Carbon\Carbon $end
|
||||||
|
*
|
||||||
|
* @param bool $shared
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function spentInPeriod(Category $category, Carbon $start, Carbon $end);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Category $category
|
||||||
|
* @param \Carbon\Carbon $start
|
||||||
|
* @param \Carbon\Carbon $end
|
||||||
|
*
|
||||||
|
* @param bool $shared
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function earnedInPeriod(Category $category, Carbon $start, Carbon $end);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Corrected for tags.
|
* Corrected for tags.
|
||||||
@ -108,6 +145,17 @@ interface CategoryRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function spentOnDaySumCorrected(Category $category, Carbon $date);
|
public function spentOnDaySumCorrected(Category $category, Carbon $date);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Corrected for tags.
|
||||||
|
*
|
||||||
|
* @param Category $category
|
||||||
|
* @param Carbon $date
|
||||||
|
*
|
||||||
|
* @return float
|
||||||
|
*/
|
||||||
|
public function earnedOnDaySumCorrected(Category $category, Carbon $date);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $data
|
* @param array $data
|
||||||
*
|
*
|
||||||
|
@ -39,7 +39,7 @@ class ComponentRepository
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($shared === true) { // shared is true: always ignore transfers between accounts!
|
if ($shared === true) { // shared is true: always ignore transfers between accounts!
|
||||||
$sum = $object->transactionjournals()->transactionTypes(['Withdrawal'])->before($end)->after($start)
|
$sum = $object->transactionjournals()->transactionTypes(['Withdrawal', 'Deposit', 'Opening balance'])->before($end)->after($start)
|
||||||
->get(['transaction_journals.*'])->sum('amount');
|
->get(['transaction_journals.*'])->sum('amount');
|
||||||
} else {
|
} else {
|
||||||
// do something else, SEE budgets.
|
// do something else, SEE budgets.
|
||||||
@ -52,7 +52,7 @@ class ComponentRepository
|
|||||||
'account_meta', function (JoinClause $join) {
|
'account_meta', function (JoinClause $join) {
|
||||||
$join->on('account_meta.account_id', '=', 'accounts.id')->where('account_meta.name', '=', 'accountRole');
|
$join->on('account_meta.account_id', '=', 'accounts.id')->where('account_meta.name', '=', 'accountRole');
|
||||||
}
|
}
|
||||||
)->where('account_meta.data', '!=', '"sharedAsset"')->get(['transaction_journals.*'])->sum('correct_amount');
|
)->where('account_meta.data', '!=', '"sharedAsset"')->get(['transaction_journals.*'])->sum('amount');
|
||||||
}
|
}
|
||||||
|
|
||||||
$cache->store($sum);
|
$cache->store($sum);
|
||||||
|
@ -99,24 +99,21 @@ class Amount
|
|||||||
} else {
|
} else {
|
||||||
$symbol = $journal->symbol;
|
$symbol = $journal->symbol;
|
||||||
}
|
}
|
||||||
$amount = $journal->amount;
|
|
||||||
if ($journal->transactionType->type == 'Withdrawal') {
|
|
||||||
$amount = $amount * -1;
|
|
||||||
}
|
|
||||||
if ($journal->transactionType->type == 'Transfer' && $coloured) {
|
if ($journal->transactionType->type == 'Transfer' && $coloured) {
|
||||||
$txt = '<span class="text-info">' . $this->formatWithSymbol($symbol, $amount, false) . '</span>';
|
$txt = '<span class="text-info">' . $this->formatWithSymbol($symbol, $journal->amount_positive, false) . '</span>';
|
||||||
$cache->store($txt);
|
$cache->store($txt);
|
||||||
|
|
||||||
return $txt;
|
return $txt;
|
||||||
}
|
}
|
||||||
if ($journal->transactionType->type == 'Transfer' && !$coloured) {
|
if ($journal->transactionType->type == 'Transfer' && !$coloured) {
|
||||||
$txt = $this->formatWithSymbol($symbol, $amount, false);
|
$txt = $this->formatWithSymbol($symbol, $journal->amount_positive, false);
|
||||||
$cache->store($txt);
|
$cache->store($txt);
|
||||||
|
|
||||||
return $txt;
|
return $txt;
|
||||||
}
|
}
|
||||||
|
|
||||||
$txt = $this->formatWithSymbol($symbol, $amount, $coloured);
|
$txt = $this->formatWithSymbol($symbol, $journal->amount, $coloured);
|
||||||
$cache->store($txt);
|
$cache->store($txt);
|
||||||
|
|
||||||
return $txt;
|
return $txt;
|
||||||
|
@ -106,16 +106,21 @@ class Navigation
|
|||||||
*
|
*
|
||||||
* @return Carbon
|
* @return Carbon
|
||||||
*/
|
*/
|
||||||
public function endOfX(Carbon $theCurrentEnd, $repeatFreq, Carbon $maxDate)
|
public function endOfX(Carbon $theCurrentEnd, $repeatFreq, Carbon $maxDate = null)
|
||||||
{
|
{
|
||||||
$functionMap = [
|
$functionMap = [
|
||||||
|
'1D' => 'endOfDay',
|
||||||
'daily' => 'endOfDay',
|
'daily' => 'endOfDay',
|
||||||
|
'1W' => 'endOfWeek',
|
||||||
'week' => 'endOfWeek',
|
'week' => 'endOfWeek',
|
||||||
'weekly' => 'endOfWeek',
|
'weekly' => 'endOfWeek',
|
||||||
'month' => 'endOfMonth',
|
'month' => 'endOfMonth',
|
||||||
|
'1M' => 'endOfMonth',
|
||||||
'monthly' => 'endOfMonth',
|
'monthly' => 'endOfMonth',
|
||||||
|
'3M' => 'lastOfQuarter',
|
||||||
'quarter' => 'lastOfQuarter',
|
'quarter' => 'lastOfQuarter',
|
||||||
'quarterly' => 'lastOfQuarter',
|
'quarterly' => 'lastOfQuarter',
|
||||||
|
'1Y' => 'endOfYear',
|
||||||
'year' => 'endOfYear',
|
'year' => 'endOfYear',
|
||||||
'yearly' => 'endOfYear',
|
'yearly' => 'endOfYear',
|
||||||
];
|
];
|
||||||
@ -128,7 +133,7 @@ class Navigation
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($currentEnd > $maxDate) {
|
if (!is_null($maxDate) && $currentEnd > $maxDate) {
|
||||||
return clone $maxDate;
|
return clone $maxDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,12 +150,17 @@ class Navigation
|
|||||||
public function periodShow(Carbon $date, $repeatFrequency)
|
public function periodShow(Carbon $date, $repeatFrequency)
|
||||||
{
|
{
|
||||||
$formatMap = [
|
$formatMap = [
|
||||||
|
'1D' => '%e %B %Y',
|
||||||
'daily' => '%e %B %Y',
|
'daily' => '%e %B %Y',
|
||||||
|
'1W' => 'Week %W, %Y',
|
||||||
'week' => 'Week %W, %Y',
|
'week' => 'Week %W, %Y',
|
||||||
'weekly' => 'Week %W, %Y',
|
'weekly' => 'Week %W, %Y',
|
||||||
|
'3M' => '%B %Y',
|
||||||
'quarter' => '%B %Y',
|
'quarter' => '%B %Y',
|
||||||
|
'1M' => '%B %Y',
|
||||||
'month' => '%B %Y',
|
'month' => '%B %Y',
|
||||||
'monthly' => '%B %Y',
|
'monthly' => '%B %Y',
|
||||||
|
'1Y' => '%Y',
|
||||||
'year' => '%Y',
|
'year' => '%Y',
|
||||||
'yearly' => '%Y',
|
'yearly' => '%Y',
|
||||||
|
|
||||||
@ -218,12 +228,15 @@ class Navigation
|
|||||||
public function subtractPeriod(Carbon $theDate, $repeatFreq, $subtract = 1)
|
public function subtractPeriod(Carbon $theDate, $repeatFreq, $subtract = 1)
|
||||||
{
|
{
|
||||||
$date = clone $theDate;
|
$date = clone $theDate;
|
||||||
|
// 1D 1W 1M 3M 6M 1Y
|
||||||
$functionMap = [
|
$functionMap = [
|
||||||
|
'1D' => 'subDays',
|
||||||
'daily' => 'subDays',
|
'daily' => 'subDays',
|
||||||
'week' => 'subWeeks',
|
'week' => 'subWeeks',
|
||||||
|
'1W' => 'subWeeks',
|
||||||
'weekly' => 'subWeeks',
|
'weekly' => 'subWeeks',
|
||||||
'month' => 'subMonths',
|
'month' => 'subMonths',
|
||||||
|
'1M' => 'subMonths',
|
||||||
'monthly' => 'subMonths',
|
'monthly' => 'subMonths',
|
||||||
'year' => 'subYears',
|
'year' => 'subYears',
|
||||||
'yearly' => 'subYears',
|
'yearly' => 'subYears',
|
||||||
|
@ -181,7 +181,7 @@ class Journal extends Twig_Extension
|
|||||||
if ($tag->tagMode == 'balancingAct') {
|
if ($tag->tagMode == 'balancingAct') {
|
||||||
// return tag formatted for a "balancing act", even if other
|
// return tag formatted for a "balancing act", even if other
|
||||||
// tags are present.
|
// tags are present.
|
||||||
$amount = app('amount')->format($journal->actual_amount, false);
|
$amount = app('amount')->format($journal->amount_positive, false);
|
||||||
$string = '<a href="' . route('tags.show', [$tag->id]) . '" class="label label-success" title="' . $amount
|
$string = '<a href="' . route('tags.show', [$tag->id]) . '" class="label label-success" title="' . $amount
|
||||||
. '"><i class="fa fa-fw fa-refresh"></i> ' . $tag->tag . '</a>';
|
. '"><i class="fa fa-fw fa-refresh"></i> ' . $tag->tag . '</a>';
|
||||||
|
|
||||||
|
@ -272,7 +272,8 @@ class FireflyValidator extends Validator
|
|||||||
$exclude = isset($parameters[2]) ? intval($parameters[2]) : 0;
|
$exclude = isset($parameters[2]) ? intval($parameters[2]) : 0;
|
||||||
|
|
||||||
// get entries from table
|
// get entries from table
|
||||||
$set = DB::table($table)->where('user_id', Auth::user()->id)->where('id', '!=', $exclude)->get([$field]);
|
$set = DB::table($table)->where('user_id', Auth::user()->id)
|
||||||
|
->where('id', '!=', $exclude)->get([$field]);
|
||||||
|
|
||||||
foreach ($set as $entry) {
|
foreach ($set as $entry) {
|
||||||
$fieldValue = $this->tryDecrypt($entry->$field);
|
$fieldValue = $this->tryDecrypt($entry->$field);
|
||||||
@ -296,6 +297,7 @@ class FireflyValidator extends Validator
|
|||||||
{
|
{
|
||||||
$exclude = isset($parameters[0]) ? $parameters[0] : null;
|
$exclude = isset($parameters[0]) ? $parameters[0] : null;
|
||||||
$query = DB::table('piggy_banks');
|
$query = DB::table('piggy_banks');
|
||||||
|
$query->whereNull('piggy_banks.deleted_at');
|
||||||
$query->leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.account_id');
|
$query->leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.account_id');
|
||||||
$query->where('accounts.user_id', Auth::user()->id);
|
$query->where('accounts.user_id', Auth::user()->id);
|
||||||
if (!is_null($exclude)) {
|
if (!is_null($exclude)) {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
'chart' => 'chartjs',
|
'chart' => 'chartjs',
|
||||||
'version' => '3.5.1',
|
'version' => '3.5.2',
|
||||||
'index_periods' => ['1D', '1W', '1M', '3M', '6M', '1Y', 'custom'],
|
'index_periods' => ['1D', '1W', '1M', '3M', '6M', '1Y', 'custom'],
|
||||||
'budget_periods' => ['daily', 'weekly', 'monthly', 'quarterly', 'half-year', 'yearly'],
|
'budget_periods' => ['daily', 'weekly', 'monthly', 'quarterly', 'half-year', 'yearly'],
|
||||||
'csv_import_enabled' => true,
|
'csv_import_enabled' => true,
|
||||||
|
@ -13,6 +13,7 @@ var fixHelper = function (e, ui) {
|
|||||||
$(function () {
|
$(function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
if (typeof(lineChart) === "function" && typeof accountID !== 'undefined') {
|
if (typeof(lineChart) === "function" && typeof accountID !== 'undefined') {
|
||||||
|
|
||||||
lineChart('chart/account/' + accountID, 'overview-chart');
|
lineChart('chart/account/' + accountID, 'overview-chart');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,6 +27,8 @@ $(function () {
|
|||||||
handle: '.handle'
|
handle: '.handle'
|
||||||
}
|
}
|
||||||
).disableSelection();
|
).disableSelection();
|
||||||
|
} else {
|
||||||
|
console.log('its null');
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -34,6 +37,7 @@ $(function () {
|
|||||||
function sortStop(event, ui) {
|
function sortStop(event, ui) {
|
||||||
"use strict";
|
"use strict";
|
||||||
var current = $(ui.item);
|
var current = $(ui.item);
|
||||||
|
console.log('sort stop');
|
||||||
var thisDate = current.data('date');
|
var thisDate = current.data('date');
|
||||||
var originalBG = current.css('backgroundColor');
|
var originalBG = current.css('backgroundColor');
|
||||||
|
|
||||||
|
@ -1,11 +1,19 @@
|
|||||||
/* globals $, categoryID, columnChart */
|
/* globals $, categoryID, columnChart, categoryDate */
|
||||||
$(function () {
|
$(function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
if (typeof categoryID !== 'undefined') {
|
if (typeof categoryID !== 'undefined') {
|
||||||
|
// more splits:
|
||||||
|
if ($('#all').length > 0) {
|
||||||
columnChart('chart/category/' + categoryID + '/all', 'all');
|
columnChart('chart/category/' + categoryID + '/all', 'all');
|
||||||
columnChart('chart/category/' + categoryID + '/month', 'month');
|
}
|
||||||
|
if ($('#period').length > 0) {
|
||||||
|
columnChart('chart/category/' + categoryID + '/period', 'period');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (typeof categoryID !== 'undefined' && typeof categoryDate !== undefined) {
|
||||||
|
columnChart('chart/category/' + categoryID + '/period/' + categoryDate, 'period-specific-period');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @version: 2.0.8
|
* @version: 2.0.11
|
||||||
* @author: Dan Grossman http://www.dangrossman.info/
|
* @author: Dan Grossman http://www.dangrossman.info/
|
||||||
* @copyright: Copyright (c) 2012-2015 Dan Grossman. All rights reserved.
|
* @copyright: Copyright (c) 2012-2015 Dan Grossman. All rights reserved.
|
||||||
* @license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php
|
* @license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php
|
||||||
@ -53,6 +53,7 @@
|
|||||||
this.timePickerIncrement = 1;
|
this.timePickerIncrement = 1;
|
||||||
this.timePickerSeconds = false;
|
this.timePickerSeconds = false;
|
||||||
this.linkedCalendars = true;
|
this.linkedCalendars = true;
|
||||||
|
this.autoUpdateInput = true;
|
||||||
this.ranges = {};
|
this.ranges = {};
|
||||||
|
|
||||||
this.opens = 'right';
|
this.opens = 'right';
|
||||||
@ -245,9 +246,15 @@
|
|||||||
if (typeof options.autoApply === 'boolean')
|
if (typeof options.autoApply === 'boolean')
|
||||||
this.autoApply = options.autoApply;
|
this.autoApply = options.autoApply;
|
||||||
|
|
||||||
|
if (typeof options.autoUpdateInput === 'boolean')
|
||||||
|
this.autoUpdateInput = options.autoUpdateInput;
|
||||||
|
|
||||||
if (typeof options.linkedCalendars === 'boolean')
|
if (typeof options.linkedCalendars === 'boolean')
|
||||||
this.linkedCalendars = options.linkedCalendars;
|
this.linkedCalendars = options.linkedCalendars;
|
||||||
|
|
||||||
|
if (typeof options.isInvalidDate === 'function')
|
||||||
|
this.isInvalidDate = options.isInvalidDate;
|
||||||
|
|
||||||
// update day names order to firstDay
|
// update day names order to firstDay
|
||||||
if (this.locale.firstDay != 0) {
|
if (this.locale.firstDay != 0) {
|
||||||
var iterator = this.locale.firstDay;
|
var iterator = this.locale.firstDay;
|
||||||
@ -332,7 +339,6 @@
|
|||||||
}
|
}
|
||||||
list += '<li>' + this.locale.customRangeLabel + '</li>';
|
list += '<li>' + this.locale.customRangeLabel + '</li>';
|
||||||
list += '</ul>';
|
list += '</ul>';
|
||||||
this.container.find('.ranges ul').remove();
|
|
||||||
this.container.find('.ranges').prepend(list);
|
this.container.find('.ranges').prepend(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -371,7 +377,15 @@
|
|||||||
this.container.addClass('show-calendar');
|
this.container.addClass('show-calendar');
|
||||||
}
|
}
|
||||||
|
|
||||||
this.container.removeClass('opensleft opensright').addClass('opens' + this.opens);
|
this.container.addClass('opens' + this.opens);
|
||||||
|
|
||||||
|
//swap the position of the predefined ranges if opens right
|
||||||
|
if (typeof options.ranges !== 'undefined' && this.opens == 'right') {
|
||||||
|
var ranges = this.container.find('.ranges');
|
||||||
|
var html = ranges.clone();
|
||||||
|
ranges.remove();
|
||||||
|
this.container.find('.calendar.left').parent().prepend(html);
|
||||||
|
}
|
||||||
|
|
||||||
//apply CSS classes and labels to buttons
|
//apply CSS classes and labels to buttons
|
||||||
this.container.find('.applyBtn, .cancelBtn').addClass(this.buttonClasses);
|
this.container.find('.applyBtn, .cancelBtn').addClass(this.buttonClasses);
|
||||||
@ -396,8 +410,8 @@
|
|||||||
.on('change.daterangepicker', 'select.monthselect', $.proxy(this.monthOrYearChanged, this))
|
.on('change.daterangepicker', 'select.monthselect', $.proxy(this.monthOrYearChanged, this))
|
||||||
.on('change.daterangepicker', 'select.hourselect,select.minuteselect,select.secondselect,select.ampmselect', $.proxy(this.timeChanged, this))
|
.on('change.daterangepicker', 'select.hourselect,select.minuteselect,select.secondselect,select.ampmselect', $.proxy(this.timeChanged, this))
|
||||||
.on('click.daterangepicker', '.daterangepicker_input input', $.proxy(this.showCalendars, this))
|
.on('click.daterangepicker', '.daterangepicker_input input', $.proxy(this.showCalendars, this))
|
||||||
.on('keyup.daterangepicker', '.daterangepicker_input input', $.proxy(this.formInputsChanged, this))
|
//.on('keyup.daterangepicker', '.daterangepicker_input input', $.proxy(this.formInputsChanged, this))
|
||||||
.on('change.daterangepicker', '.daterangepicker_input input', $.proxy(this.updateFormInputs, this));
|
.on('change.daterangepicker', '.daterangepicker_input input', $.proxy(this.formInputsChanged, this));
|
||||||
|
|
||||||
this.container.find('.ranges')
|
this.container.find('.ranges')
|
||||||
.on('click.daterangepicker', 'button.applyBtn', $.proxy(this.clickApply, this))
|
.on('click.daterangepicker', 'button.applyBtn', $.proxy(this.clickApply, this))
|
||||||
@ -410,7 +424,7 @@
|
|||||||
this.element.on({
|
this.element.on({
|
||||||
'click.daterangepicker': $.proxy(this.show, this),
|
'click.daterangepicker': $.proxy(this.show, this),
|
||||||
'focus.daterangepicker': $.proxy(this.show, this),
|
'focus.daterangepicker': $.proxy(this.show, this),
|
||||||
'keyup.daterangepicker': $.proxy(this.controlChanged, this),
|
'keyup.daterangepicker': $.proxy(this.elementChanged, this),
|
||||||
'keydown.daterangepicker': $.proxy(this.keydown, this)
|
'keydown.daterangepicker': $.proxy(this.keydown, this)
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -421,10 +435,10 @@
|
|||||||
// if attached to a text input, set the initial value
|
// if attached to a text input, set the initial value
|
||||||
//
|
//
|
||||||
|
|
||||||
if (this.element.is('input') && !this.singleDatePicker) {
|
if (this.element.is('input') && !this.singleDatePicker && this.autoUpdateInput) {
|
||||||
this.element.val(this.startDate.format(this.locale.format) + this.locale.separator + this.endDate.format(this.locale.format));
|
this.element.val(this.startDate.format(this.locale.format) + this.locale.separator + this.endDate.format(this.locale.format));
|
||||||
this.element.trigger('change');
|
this.element.trigger('change');
|
||||||
} else if (this.element.is('input')) {
|
} else if (this.element.is('input') && this.autoUpdateInput) {
|
||||||
this.element.val(this.startDate.format(this.locale.format));
|
this.element.val(this.startDate.format(this.locale.format));
|
||||||
this.element.trigger('change');
|
this.element.trigger('change');
|
||||||
}
|
}
|
||||||
@ -454,6 +468,9 @@
|
|||||||
if (this.maxDate && this.startDate.isAfter(this.maxDate))
|
if (this.maxDate && this.startDate.isAfter(this.maxDate))
|
||||||
this.startDate = this.maxDate;
|
this.startDate = this.maxDate;
|
||||||
|
|
||||||
|
if (!this.isShowing)
|
||||||
|
this.updateElement();
|
||||||
|
|
||||||
this.updateMonthsInView();
|
this.updateMonthsInView();
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -479,9 +496,16 @@
|
|||||||
if (this.dateLimit && this.startDate.clone().add(this.dateLimit).isBefore(this.endDate))
|
if (this.dateLimit && this.startDate.clone().add(this.dateLimit).isBefore(this.endDate))
|
||||||
this.endDate = this.startDate.clone().add(this.dateLimit);
|
this.endDate = this.startDate.clone().add(this.dateLimit);
|
||||||
|
|
||||||
|
if (!this.isShowing)
|
||||||
|
this.updateElement();
|
||||||
|
|
||||||
this.updateMonthsInView();
|
this.updateMonthsInView();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
isInvalidDate: function() {
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
updateView: function() {
|
updateView: function() {
|
||||||
if (this.timePicker) {
|
if (this.timePicker) {
|
||||||
this.renderTimePicker('left');
|
this.renderTimePicker('left');
|
||||||
@ -506,12 +530,23 @@
|
|||||||
|
|
||||||
updateMonthsInView: function() {
|
updateMonthsInView: function() {
|
||||||
if (this.endDate) {
|
if (this.endDate) {
|
||||||
|
|
||||||
|
//if both dates are visible already, do nothing
|
||||||
|
if (this.leftCalendar.month && this.rightCalendar.month &&
|
||||||
|
(this.startDate.format('YYYY-MM') == this.leftCalendar.month.format('YYYY-MM') || this.startDate.format('YYYY-MM') == this.rightCalendar.month.format('YYYY-MM'))
|
||||||
|
&&
|
||||||
|
(this.endDate.format('YYYY-MM') == this.leftCalendar.month.format('YYYY-MM') || this.endDate.format('YYYY-MM') == this.rightCalendar.month.format('YYYY-MM'))
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.leftCalendar.month = this.startDate.clone().date(2);
|
this.leftCalendar.month = this.startDate.clone().date(2);
|
||||||
if (!this.linkedCalendars && (this.endDate.month() != this.startDate.month() || this.endDate.year() != this.startDate.year())) {
|
if (!this.linkedCalendars && (this.endDate.month() != this.startDate.month() || this.endDate.year() != this.startDate.year())) {
|
||||||
this.rightCalendar.month = this.endDate.clone().date(2);
|
this.rightCalendar.month = this.endDate.clone().date(2);
|
||||||
} else {
|
} else {
|
||||||
this.rightCalendar.month = this.startDate.clone().date(2).add(1, 'month');
|
this.rightCalendar.month = this.startDate.clone().date(2).add(1, 'month');
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (this.leftCalendar.month.format('YYYY-MM') != this.startDate.format('YYYY-MM') && this.rightCalendar.month.format('YYYY-MM') != this.startDate.format('YYYY-MM')) {
|
if (this.leftCalendar.month.format('YYYY-MM') != this.startDate.format('YYYY-MM') && this.rightCalendar.month.format('YYYY-MM') != this.startDate.format('YYYY-MM')) {
|
||||||
this.leftCalendar.month = this.startDate.clone().date(2);
|
this.leftCalendar.month = this.startDate.clone().date(2);
|
||||||
@ -622,7 +657,7 @@
|
|||||||
startDay = daysInLastMonth - 6;
|
startDay = daysInLastMonth - 6;
|
||||||
|
|
||||||
// Possible patch for issue #626 https://github.com/dangrossman/bootstrap-daterangepicker/issues/626
|
// Possible patch for issue #626 https://github.com/dangrossman/bootstrap-daterangepicker/issues/626
|
||||||
var curDate = moment([lastYear, lastMonth, startDay, 12, minute, second]); // .utcOffset(this.timeZone);
|
var curDate = moment([lastYear, lastMonth, startDay, 12, minute, second]).utcOffset(this.timeZone); // .utcOffset(this.timeZone);
|
||||||
|
|
||||||
var col, row;
|
var col, row;
|
||||||
for (var i = 0, col = 0, row = 0; i < 42; i++, col++, curDate = moment(curDate).add(24, 'hour')) {
|
for (var i = 0, col = 0, row = 0; i < 42; i++, col++, curDate = moment(curDate).add(24, 'hour')) {
|
||||||
@ -769,6 +804,10 @@
|
|||||||
if (maxDate && calendar[row][col].isAfter(maxDate, 'day'))
|
if (maxDate && calendar[row][col].isAfter(maxDate, 'day'))
|
||||||
classes.push('off', 'disabled');
|
classes.push('off', 'disabled');
|
||||||
|
|
||||||
|
//don't allow selection of date if a custom function decides it's invalid
|
||||||
|
if (this.isInvalidDate(calendar[row][col]))
|
||||||
|
classes.push('off', 'disabled');
|
||||||
|
|
||||||
//highlight the currently selected start date
|
//highlight the currently selected start date
|
||||||
if (calendar[row][col].format('YYYY-MM-DD') == this.startDate.format('YYYY-MM-DD'))
|
if (calendar[row][col].format('YYYY-MM-DD') == this.startDate.format('YYYY-MM-DD'))
|
||||||
classes.push('active', 'start-date');
|
classes.push('active', 'start-date');
|
||||||
@ -805,7 +844,7 @@
|
|||||||
|
|
||||||
renderTimePicker: function(side) {
|
renderTimePicker: function(side) {
|
||||||
|
|
||||||
var selected, minDate, maxDate = this.maxDate;
|
var html, selected, minDate, maxDate = this.maxDate;
|
||||||
|
|
||||||
if (this.dateLimit && (!this.maxDate || this.startDate.clone().add(this.dateLimit).isAfter(this.maxDate)))
|
if (this.dateLimit && (!this.maxDate || this.startDate.clone().add(this.dateLimit).isAfter(this.maxDate)))
|
||||||
maxDate = this.startDate.clone().add(this.dateLimit);
|
maxDate = this.startDate.clone().add(this.dateLimit);
|
||||||
@ -936,6 +975,11 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
updateFormInputs: function() {
|
updateFormInputs: function() {
|
||||||
|
|
||||||
|
//ignore mouse movements while an above-calendar text input has focus
|
||||||
|
if (this.container.find('input[name=daterangepicker_start]').is(":focus") || this.container.find('input[name=daterangepicker_end]').is(":focus"))
|
||||||
|
return;
|
||||||
|
|
||||||
this.container.find('input[name=daterangepicker_start]').val(this.startDate.format(this.locale.format));
|
this.container.find('input[name=daterangepicker_start]').val(this.startDate.format(this.locale.format));
|
||||||
if (this.endDate)
|
if (this.endDate)
|
||||||
this.container.find('input[name=daterangepicker_end]').val(this.endDate.format(this.locale.format));
|
this.container.find('input[name=daterangepicker_end]').val(this.endDate.format(this.locale.format));
|
||||||
@ -945,6 +989,7 @@
|
|||||||
} else {
|
} else {
|
||||||
this.container.find('button.applyBtn').attr('disabled', 'disabled');
|
this.container.find('button.applyBtn').attr('disabled', 'disabled');
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
move: function() {
|
move: function() {
|
||||||
@ -1044,13 +1089,7 @@
|
|||||||
this.callback(this.startDate, this.endDate, this.chosenLabel);
|
this.callback(this.startDate, this.endDate, this.chosenLabel);
|
||||||
|
|
||||||
//if picker is attached to a text input, update it
|
//if picker is attached to a text input, update it
|
||||||
if (this.element.is('input') && !this.singleDatePicker) {
|
this.updateElement();
|
||||||
this.element.val(this.startDate.format(this.locale.format) + this.locale.separator + this.endDate.format(this.locale.format));
|
|
||||||
this.element.trigger('change');
|
|
||||||
} else if (this.element.is('input')) {
|
|
||||||
this.element.val(this.startDate.format(this.locale.format));
|
|
||||||
this.element.trigger('change');
|
|
||||||
}
|
|
||||||
|
|
||||||
$(document).off('.daterangepicker');
|
$(document).off('.daterangepicker');
|
||||||
this.container.hide();
|
this.container.hide();
|
||||||
@ -1092,6 +1131,11 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
hoverRange: function(e) {
|
hoverRange: function(e) {
|
||||||
|
|
||||||
|
//ignore mouse movements while an above-calendar text input has focus
|
||||||
|
if (this.container.find('input[name=daterangepicker_start]').is(":focus") || this.container.find('input[name=daterangepicker_end]').is(":focus"))
|
||||||
|
return;
|
||||||
|
|
||||||
var label = e.target.innerHTML;
|
var label = e.target.innerHTML;
|
||||||
if (label == this.locale.customRangeLabel) {
|
if (label == this.locale.customRangeLabel) {
|
||||||
this.updateView();
|
this.updateView();
|
||||||
@ -1100,6 +1144,7 @@
|
|||||||
this.container.find('input[name=daterangepicker_start]').val(dates[0].format(this.locale.format));
|
this.container.find('input[name=daterangepicker_start]').val(dates[0].format(this.locale.format));
|
||||||
this.container.find('input[name=daterangepicker_end]').val(dates[1].format(this.locale.format));
|
this.container.find('input[name=daterangepicker_end]').val(dates[1].format(this.locale.format));
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
clickRange: function(e) {
|
clickRange: function(e) {
|
||||||
@ -1148,6 +1193,10 @@
|
|||||||
|
|
||||||
hoverDate: function(e) {
|
hoverDate: function(e) {
|
||||||
|
|
||||||
|
//ignore mouse movements while an above-calendar text input has focus
|
||||||
|
if (this.container.find('input[name=daterangepicker_start]').is(":focus") || this.container.find('input[name=daterangepicker_end]').is(":focus"))
|
||||||
|
return;
|
||||||
|
|
||||||
//ignore dates that can't be selected
|
//ignore dates that can't be selected
|
||||||
if (!$(e.target).hasClass('available')) return;
|
if (!$(e.target).hasClass('available')) return;
|
||||||
|
|
||||||
@ -1355,8 +1404,8 @@
|
|||||||
|
|
||||||
formInputsChanged: function(e) {
|
formInputsChanged: function(e) {
|
||||||
var isRight = $(e.target).closest('.calendar').hasClass('right');
|
var isRight = $(e.target).closest('.calendar').hasClass('right');
|
||||||
var start = moment(this.container.find('input[name="daterangepicker_start"]').val(), this.locale.format);
|
var start = moment(this.container.find('input[name="daterangepicker_start"]').val(), this.locale.format).utcOffset(this.timeZone);
|
||||||
var end = moment(this.container.find('input[name="daterangepicker_end"]').val(), this.locale.format);
|
var end = moment(this.container.find('input[name="daterangepicker_end"]').val(), this.locale.format).utcOffset(this.timeZone);
|
||||||
|
|
||||||
if (start.isValid() && end.isValid()) {
|
if (start.isValid() && end.isValid()) {
|
||||||
|
|
||||||
@ -1381,7 +1430,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
controlChanged: function() {
|
elementChanged: function() {
|
||||||
if (!this.element.is('input')) return;
|
if (!this.element.is('input')) return;
|
||||||
if (!this.element.val().length) return;
|
if (!this.element.val().length) return;
|
||||||
|
|
||||||
@ -1411,6 +1460,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
updateElement: function() {
|
||||||
|
if (this.element.is('input') && !this.singleDatePicker && this.autoUpdateInput) {
|
||||||
|
this.element.val(this.startDate.format(this.locale.format) + this.locale.separator + this.endDate.format(this.locale.format));
|
||||||
|
this.element.trigger('change');
|
||||||
|
} else if (this.element.is('input') && this.autoUpdateInput) {
|
||||||
|
this.element.val(this.startDate.format(this.locale.format));
|
||||||
|
this.element.trigger('change');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
remove: function() {
|
remove: function() {
|
||||||
this.container.remove();
|
this.container.remove();
|
||||||
this.element.off('.daterangepicker');
|
this.element.off('.daterangepicker');
|
||||||
|
@ -1,36 +1,46 @@
|
|||||||
/* globals token, start, end, dateRangeURL, everything, firstDate, moment, currentMonthName, $, previousMonthName, nextMonthName, applyLabel, cancelLabel, toLabel, customRangeLabel, fromLabel, */
|
/* globals token, dateRangeConfig, $, */
|
||||||
$(function () {
|
$(function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
$('.currencySelect').click(currencySelect);
|
$('.currencySelect').click(currencySelect);
|
||||||
|
|
||||||
var ranges = {};
|
var ranges = {};
|
||||||
ranges[currentMonthName] = [moment().startOf('month'), moment().endOf('month')];
|
// range for the current month:
|
||||||
ranges[previousMonthName] = [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')];
|
ranges[dateRangeConfig.currentMonth] = [moment().startOf('month'), moment().endOf('month')];
|
||||||
ranges[nextMonthName] = [moment().add(1, 'month').startOf('month'), moment().add(1, 'month').endOf('month')];
|
|
||||||
ranges[everything] = [firstDate, moment()];
|
// range for the previous month:
|
||||||
$('#daterange').daterangepicker(
|
ranges[dateRangeConfig.previousMonth] = [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')];
|
||||||
|
|
||||||
|
// range for the next month:
|
||||||
|
ranges[dateRangeConfig.nextMonth] = [moment().add(1, 'month').startOf('month'), moment().add(1, 'month').endOf('month')];
|
||||||
|
|
||||||
|
// range for everything:
|
||||||
|
ranges[dateRangeConfig.everything] = [dateRangeConfig.firstDate, moment()];
|
||||||
|
|
||||||
|
|
||||||
|
// build the data range:
|
||||||
|
$('#daterange').text(dateRangeConfig.linkTitle).daterangepicker(
|
||||||
{
|
{
|
||||||
ranges: ranges,
|
ranges: ranges,
|
||||||
opens: 'left',
|
opens: 'left',
|
||||||
locale: {
|
locale: {
|
||||||
applyLabel: applyLabel,
|
applyLabel: dateRangeConfig.applyLabel,
|
||||||
cancelLabel: cancelLabel,
|
cancelLabel: dateRangeConfig.cancelLabel,
|
||||||
fromLabel: fromLabel,
|
fromLabel: dateRangeConfig.fromLabel,
|
||||||
toLabel: toLabel,
|
toLabel: dateRangeConfig.toLabel,
|
||||||
weekLabel: 'W',
|
weekLabel: 'W',
|
||||||
customRangeLabel: customRangeLabel,
|
customRangeLabel: dateRangeConfig.customRangeLabel,
|
||||||
daysOfWeek: moment.weekdaysMin(),
|
daysOfWeek: moment.weekdaysMin(),
|
||||||
monthNames: moment.monthsShort(),
|
monthNames: moment.monthsShort(),
|
||||||
firstDay: moment.localeData()._week.dow
|
firstDay: moment.localeData()._week.dow
|
||||||
},
|
},
|
||||||
format: 'DD-MM-YYYY',
|
format: 'YYYY-MM-DD',
|
||||||
startDate: start,
|
startDate: dateRangeConfig.startDate,
|
||||||
endDate: end
|
endDate: dateRangeConfig.endDate
|
||||||
},
|
},
|
||||||
function (start, end, label) {
|
function (start, end, label) {
|
||||||
|
|
||||||
// send post.
|
// send post.
|
||||||
$.post(dateRangeURL, {
|
$.post(dateRangeConfig.URL, {
|
||||||
start: start.format('YYYY-MM-DD'),
|
start: start.format('YYYY-MM-DD'),
|
||||||
end: end.format('YYYY-MM-DD'),
|
end: end.format('YYYY-MM-DD'),
|
||||||
label: label,
|
label: label,
|
||||||
|
@ -47,7 +47,7 @@ function getBoxAmounts() {
|
|||||||
var boxes = ['in', 'out', 'bills-unpaid', 'bills-paid'];
|
var boxes = ['in', 'out', 'bills-unpaid', 'bills-paid'];
|
||||||
for (var x in boxes) {
|
for (var x in boxes) {
|
||||||
var box = boxes[x];
|
var box = boxes[x];
|
||||||
$.getJSON('/json/box/' + box).success(putData).fail(failData);
|
$.getJSON('json/box/' + box).success(putData).fail(failData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
6
public/js/moment.min.js
vendored
Normal file → Executable file
6
public/js/moment.min.js
vendored
Normal file → Executable file
File diff suppressed because one or more lines are too long
@ -1,15 +1,12 @@
|
|||||||
/* globals $, lineChart, token, piggyBankID */
|
/* globals $, lineChart, token, piggyBankID */
|
||||||
|
|
||||||
// Return a helper with preserved width of cells
|
// Return a helper with preserved width of cells
|
||||||
var fixHelper = function (e, tr) {
|
var fixHelper = function (e, ui) {
|
||||||
"use strict";
|
"use strict";
|
||||||
var $originals = tr.children();
|
ui.children().each(function () {
|
||||||
var $helper = tr.clone();
|
$(this).width($(this).width());
|
||||||
$helper.children().each(function (index) {
|
|
||||||
// Set helper cell sizes to match the original sizes
|
|
||||||
$(this).width($originals.eq(index).width());
|
|
||||||
});
|
});
|
||||||
return $helper;
|
return ui;
|
||||||
};
|
};
|
||||||
|
|
||||||
$(function () {
|
$(function () {
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
User-agent: *
|
User-agent: *
|
||||||
Disallow:
|
Disallow: /
|
@ -34,7 +34,7 @@ return [
|
|||||||
'new_expense_account' => 'Nieuwe crediteur',
|
'new_expense_account' => 'Nieuwe crediteur',
|
||||||
'new_revenue_account' => 'Nieuwe debiteur',
|
'new_revenue_account' => 'Nieuwe debiteur',
|
||||||
'new_budget' => 'Nieuw budget',
|
'new_budget' => 'Nieuw budget',
|
||||||
'new_bill' => 'Nieuwe rekening',
|
'new_bill' => 'Nieuw contract',
|
||||||
|
|
||||||
// tags
|
// tags
|
||||||
'store_new_tag' => 'Sla tag op',
|
'store_new_tag' => 'Sla tag op',
|
||||||
|
@ -23,9 +23,8 @@
|
|||||||
<small>{{ 'budgeted'|_ }}: <span id="budgetedAmount" class="text-success">{{ budgeted|formatAmountPlain }}</span></small>
|
<small>{{ 'budgeted'|_ }}: <span id="budgetedAmount" class="text-success">{{ budgeted|formatAmountPlain }}</span></small>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-6 col-md-4 col-sm-3" style="text-align:right;">
|
<div class="col-lg-6 col-md-4 col-sm-3" style="text-align:right;">
|
||||||
<small>{{ trans('firefly.availableIn',{date : Session.get('start').formatLocalized(monthFormat) }) }}:
|
<small>{{ trans('firefly.availableIn',{date : period }) }}:
|
||||||
<a href="#" class="updateIncome"><span id="budgetIncomeTotal"
|
<a href="#" class="updateIncome"><span id="budgetIncomeTotal" data-value="{{ budgetIncomeTotal }}">{{ budgetIncomeTotal|formatAmount }}</span></a>
|
||||||
data-value="{{ budgetIncomeTotal }}">{{ budgetIncomeTotal|formatAmount }}</span></a>
|
|
||||||
</small>
|
</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -44,7 +43,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-6 col-md-4 col-sm-3">
|
<div class="col-lg-6 col-md-4 col-sm-3">
|
||||||
<small>{{ 'spent'|_ }}: {{ spent|formatAmount }}</small>
|
<small>{{ 'spent'|_ }}: <span class="text-danger">{{ (spent*-1)|formatAmountPlain }}</span></small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -77,11 +76,26 @@
|
|||||||
<div class="box-body">
|
<div class="box-body">
|
||||||
<p>
|
<p>
|
||||||
<a href="{{ route('budgets.noBudget') }}">
|
<a href="{{ route('budgets.noBudget') }}">
|
||||||
{{ trans('firefly.transactionsWithoutBudgetDate', {date: Session.get('start').formatLocalized(monthFormat)}) }}
|
{{ trans('firefly.transactionsWithoutBudgetDate', {date: period|lower }) }}
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-header with-border">
|
||||||
|
<h3 class="box-title">{{ 'createBudget'|_ }}</h3>
|
||||||
|
|
||||||
|
<!-- ACTIONS MENU -->
|
||||||
|
<div class="box-tools pull-right">
|
||||||
|
<button class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="box-body">
|
||||||
|
<a href="{{ route('budgets.create') }}" class="btn btn-success pull-right">{{ 'createBudget'|_ }}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -130,28 +144,14 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="width:50%;">{{ 'spent'|_ }}</td>
|
<td style="width:50%;">{{ 'spent'|_ }}</td>
|
||||||
<td>{{ budget.spent|formatAmount }}</td>
|
<td><span class="text-danger">{{ (budget.spent*-1)|formatAmountPlain }}</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<div class="col-lg-3 col-sm-4 col-md-6">
|
|
||||||
<div class="box">
|
|
||||||
<div class="box-header with-border">
|
|
||||||
<h3 class="box-title">{{ 'createBudget'|_ }}</h3>
|
|
||||||
|
|
||||||
<!-- ACTIONS MENU -->
|
|
||||||
<div class="box-tools pull-right">
|
|
||||||
<button class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="box-body">
|
|
||||||
<a href="{{ route('budgets.create') }}" class="btn btn-success pull-right">{{ 'createBudget'|_ }}</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% if inactive|length > 0 %}
|
{% if inactive|length > 0 %}
|
||||||
<div class="col-lg-3 col-sm-4 col-md-6">
|
<div class="col-lg-3 col-sm-4 col-md-6">
|
||||||
<div class="box">
|
<div class="box">
|
||||||
@ -179,7 +179,7 @@
|
|||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
// actually spent bar data:
|
// actually spent bar data:
|
||||||
var spent = {{ spent }};
|
var spent = {{ spent * -1 }};
|
||||||
var currencySymbol = "{{ getCurrencySymbol()|raw }}";
|
var currencySymbol = "{{ getCurrencySymbol()|raw }}";
|
||||||
|
|
||||||
// budgeted data:
|
// budgeted data:
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
|
|
||||||
{% for limit in limits %}
|
{% for limit in limits %}
|
||||||
{% for rep in limit.limitRepetitions %}
|
{% for rep in limit.limitRepetitions %}
|
||||||
|
{% set spentInRep = (spentInRepetitionCorrected(rep)*-1) %}
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div class="box-header with-border">
|
<div class="box-header with-border">
|
||||||
<h3 class="box-title"><a href="{{ route('budgets.show',[budget.id,rep.id]) }}">{{ rep.startdate.formatLocalized(monthFormat) }}</a>
|
<h3 class="box-title"><a href="{{ route('budgets.show',[budget.id,rep.id]) }}">{{ rep.startdate.formatLocalized(monthFormat) }}</a>
|
||||||
@ -61,15 +62,15 @@
|
|||||||
{{ 'amount'|_ }}: {{ rep.amount|formatAmount }}
|
{{ 'amount'|_ }}: {{ rep.amount|formatAmount }}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-6 col-md-6 col-sm-6">
|
<div class="col-lg-6 col-md-6 col-sm-6">
|
||||||
{{ 'spent'|_ }}: {{ spentInRepetitionCorrected(rep)|formatAmount }}
|
{{ 'spent'|_ }}: <span class="text-danger">{{ spentInRep|formatAmountPlain }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-12 col-md-12 col-sm-12">
|
<div class="col-lg-12 col-md-12 col-sm-12">
|
||||||
{% set overspent = spentInRepetitionCorrected(rep) > rep.amount %}
|
{% set overspent = spentInRep > rep.amount %}
|
||||||
|
|
||||||
{% if overspent %}
|
{% if overspent %}
|
||||||
{% set spent = spentInRepetitionCorrected(rep) %}
|
{% set pct = (spentInRep != 0 ? (rep.amount / spentInRep)*100 : 0) %}
|
||||||
{% set pct = (spent != 0 ? (rep.amount / spent)*100 : 0) %}
|
|
||||||
<div class="progress progress-striped">
|
<div class="progress progress-striped">
|
||||||
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="{{ pct|round }}" aria-valuemin="0"
|
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="{{ pct|round }}" aria-valuemin="0"
|
||||||
aria-valuemax="100" style="width: {{ pct|round }}%;"></div>
|
aria-valuemax="100" style="width: {{ pct|round }}%;"></div>
|
||||||
@ -78,7 +79,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
{% set amount = rep.amount %}
|
{% set amount = rep.amount %}
|
||||||
{% set pct = (amount != 0 ? (spentInRepetitionCorrected(rep) / amount)*100 : 0) %}
|
{% set pct = (amount != 0 ? ((spentInRep / amount)*100) : 0) %}
|
||||||
<div class="progress progress-striped">
|
<div class="progress progress-striped">
|
||||||
<div class="progress-bar progress-bar-info" role="progressbar" aria-valuenow="{{ pct|round }}" aria-valuemin="0"
|
<div class="progress-bar progress-bar-info" role="progressbar" aria-valuenow="{{ pct|round }}" aria-valuemin="0"
|
||||||
aria-valuemax="100" style="width: {{ pct|round }}%;"></div>
|
aria-valuemax="100" style="width: {{ pct|round }}%;"></div>
|
||||||
|
@ -13,10 +13,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="box-body">
|
<div class="box-body">
|
||||||
{% if Config.get('firefly.chart') == 'google' %}
|
{% if Config.get('firefly.chart') == 'google' %}
|
||||||
<div id="month"></div>
|
<div id="period"></div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if Config.get('firefly.chart') == 'chartjs' %}
|
{% if Config.get('firefly.chart') == 'chartjs' %}
|
||||||
<canvas id="month" style="width:100%;height:350px;"></canvas>
|
<canvas id="period" style="width:100%;height:350px;"></canvas>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -38,17 +38,46 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-12 col-md-12">
|
<div class="col-lg-8 col-md-8 col-sm-12 col-xs-12">
|
||||||
|
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div class="box-header with-border">
|
<div class="box-header with-border">
|
||||||
<h3 class="box-title">{{ 'transactions'|_ }}</h3>
|
<h3 class="box-title">{{ 'transactions'|_ }}</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-body no-padding">
|
<div class="box-body no-padding">
|
||||||
{% include 'list/journals' with {showPageSum: true, showTotalSum: true, showPeriodSum: true} %}
|
{% include 'list/journals' %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-lg-4 col-md-4 col-sm-12 col-xs-12">
|
||||||
|
{% for entry in entries %}
|
||||||
|
{% if entry[2] != 0 or entry[3] != 0 %}
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-header with-border">
|
||||||
|
<h3 class="box-title"><a href="{{ route('categories.show.date',[category.id,entry[0]]) }}">{{ entry[1] }}</a>
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
<div class="box-body no-padding">
|
||||||
|
<table class="table table-hover">
|
||||||
|
{% if entry[2] != 0 %}
|
||||||
|
<tr>
|
||||||
|
<td colspan="33%">{{ 'spent'|_ }}</td>
|
||||||
|
<td colspan="67%">{{ entry[2]|formatAmount }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
{% if entry[3] != 0 %}
|
||||||
|
<tr>
|
||||||
|
<td colspan="33%">{{ 'earned'|_ }}</td>
|
||||||
|
<td colspan="67%">{{ entry[3]|formatAmount }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
62
resources/twig/categories/show_with_date.twig
Normal file
62
resources/twig/categories/show_with_date.twig
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
{% extends "./layout/default.twig" %}
|
||||||
|
|
||||||
|
{% block breadcrumbs %}
|
||||||
|
{{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName, category, carbon) }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12 col-md-12 col-sm-12">
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-header with-border">
|
||||||
|
<h3 class="box-title">{{ 'overview'|_ }} (period)</h3>
|
||||||
|
</div>
|
||||||
|
<div class="box-body">
|
||||||
|
{% if Config.get('firefly.chart') == 'google' %}
|
||||||
|
<div id="period-specific-period"></div>
|
||||||
|
{% endif %}
|
||||||
|
{% if Config.get('firefly.chart') == 'chartjs' %}
|
||||||
|
<canvas id="period-specific-period" style="width:100%;height:350px;"></canvas>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
||||||
|
<p><a href="{{ route('categories.show',[category.id]) }}">Back to all periods</a></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
||||||
|
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-header with-border">
|
||||||
|
<h3 class="box-title">{{ 'transactions'|_ }}</h3>
|
||||||
|
</div>
|
||||||
|
<div class="box-body no-padding">
|
||||||
|
{% include 'list/journals' %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
{% block scripts %}
|
||||||
|
<script type="text/javascript">
|
||||||
|
var categoryID = {{ category.id }};
|
||||||
|
var categoryDate = "{{ carbon.format('Y-m-d') }}";
|
||||||
|
</script>
|
||||||
|
<!-- load the libraries and scripts necessary for Google Charts: -->
|
||||||
|
{% if Config.get('firefly.chart') == 'google' %}
|
||||||
|
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
|
||||||
|
<script type="text/javascript" src="js/gcharts.js"></script>
|
||||||
|
{% endif %}
|
||||||
|
{% if Config.get('firefly.chart') == 'chartjs' %}
|
||||||
|
<script type="text/javascript" src="js/Chart.min.js"></script>
|
||||||
|
<script type="text/javascript" src="js/charts.js"></script>
|
||||||
|
{% endif %}
|
||||||
|
<script type="text/javascript" src="js/categories.js"></script>
|
||||||
|
|
||||||
|
{% endblock %}
|
@ -19,7 +19,7 @@
|
|||||||
<ul>
|
<ul>
|
||||||
<li style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;font-size:13px;">
|
<li style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;font-size:13px;">
|
||||||
If you have forgotten your password already, please reset it using
|
If you have forgotten your password already, please reset it using
|
||||||
<a style="color:#337ab7" href="{{ address }}password/email">the password reset tool</a>.
|
<a style="color:#337ab7" href="{{ address }}/password/email">the password reset tool</a>.
|
||||||
</li>
|
</li>
|
||||||
<li style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;font-size:13px;">
|
<li style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;font-size:13px;">
|
||||||
There is a help-icon in the top right corner of each page. If you need help, click it!
|
There is a help-icon in the top right corner of each page. If you need help, click it!
|
||||||
|
@ -12,7 +12,7 @@ Firefly III:
|
|||||||
{{ address }}
|
{{ address }}
|
||||||
|
|
||||||
Password reset:
|
Password reset:
|
||||||
{{ address }}password/email
|
{{ address }}/password/email
|
||||||
|
|
||||||
Documentation:
|
Documentation:
|
||||||
https://github.com/JC5/firefly-iii/wiki/First-use
|
https://github.com/JC5/firefly-iii/wiki/First-use
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
|
<meta name="robots" content="noindex, nofolllow, noarchive, noodp, NoImageIndex, noydir">
|
||||||
<title>Firefly
|
<title>Firefly
|
||||||
{% if title != "Firefly" %}
|
{% if title != "Firefly" %}
|
||||||
// {{ title }}
|
// {{ title }}
|
||||||
@ -12,6 +13,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</title>
|
</title>
|
||||||
<base href="{{ route('index') }}/">
|
<base href="{{ route('index') }}/">
|
||||||
|
|
||||||
<meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'>
|
<meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'>
|
||||||
<link href="bootstrap/css/bootstrap.min.css" rel="stylesheet" type="text/css"/>
|
<link href="bootstrap/css/bootstrap.min.css" rel="stylesheet" type="text/css"/>
|
||||||
<link href="font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css"/>
|
<link href="font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css"/>
|
||||||
@ -159,28 +161,30 @@
|
|||||||
<script src="js/bootstrap-tour.min.js" type="text/javascript"></script>
|
<script src="js/bootstrap-tour.min.js" type="text/javascript"></script>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
var start = "{{Session.get('start').format('d-m-Y')}}";
|
|
||||||
var end = "{{Session.get('end').format('d-m-Y')}}";
|
// date range picker configuration:
|
||||||
var titleString = "{{Session.get('start').formatLocalized(monthAndDayFormat)}} - {{Session.get('end').formatLocalized(monthAndDayFormat)}}";
|
var dateRangeConfig = {
|
||||||
var dateRangeURL = "{{route('daterange')}}";
|
startDate: moment("{{Session.get('start').format('Y-m-d')}}"),
|
||||||
|
endDate: moment("{{Session.get('end').format('Y-m-d')}}"),
|
||||||
|
linkTitle: "{{Session.get('start').formatLocalized(monthAndDayFormat)}} - {{Session.get('end').formatLocalized(monthAndDayFormat)}}",
|
||||||
|
URL: "{{route('daterange')}}",
|
||||||
|
firstDate: moment("{{Session.get('first').format('Y-m-d')}}"),
|
||||||
|
currentMonth: "{{ currentMonthName }}",
|
||||||
|
previousMonth: "{{ previousMonthName }}",
|
||||||
|
nextMonth: "{{ nextMonthName }}",
|
||||||
|
everything: '{{ 'everything'|_ }}',
|
||||||
|
customRangeLabel: '{{ 'customRange'|_ }}',
|
||||||
|
applyLabel: '{{ 'apply'|_ }}',
|
||||||
|
cancelLabel: '{{ 'cancel'|_ }}',
|
||||||
|
fromLabel: '{{ 'from'|_ }}',
|
||||||
|
toLabel: '{{ 'to'|_ }}'
|
||||||
|
};
|
||||||
|
|
||||||
var token = "{{csrf_token()}}";
|
var token = "{{csrf_token()}}";
|
||||||
var firstDate = moment("{{Session.get('first').format('Y-m-d')}}");
|
|
||||||
var currentMonthName = "{{ currentMonthName }}";
|
|
||||||
var previousMonthName = "{{ previousMonthName }}";
|
|
||||||
var language = "{{ language }}";
|
var language = "{{ language }}";
|
||||||
|
|
||||||
// translations:
|
|
||||||
var everything = '{{ 'everything'|_ }}';
|
|
||||||
var customRangeLabel = '{{ 'customRange'|_ }}';
|
|
||||||
var applyLabel = '{{ 'apply'|_ }}';
|
|
||||||
var cancelLabel = '{{ 'cancel'|_ }}';
|
|
||||||
var fromLabel = '{{ 'from'|_ }}';
|
|
||||||
var toLabel = '{{ 'to'|_ }}';
|
|
||||||
|
|
||||||
var nextMonthName = "{{ nextMonthName }}";
|
|
||||||
var currencyCode = '{{getCurrencyCode() }}';
|
var currencyCode = '{{getCurrencyCode() }}';
|
||||||
var currencySymbol = '{{getCurrencySymbol()|raw }}';
|
var currencySymbol = '{{getCurrencySymbol()|raw }}';
|
||||||
$('#daterange').text(titleString);
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/javascript" src="js/firefly.js"></script>
|
<script type="text/javascript" src="js/firefly.js"></script>
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
|
<meta name="robots" content="noindex, nofolllow, noarchive, noodp, NoImageIndex, noydir">
|
||||||
<title>Firefly III</title>
|
<title>Firefly III</title>
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'>
|
<meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'>
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
|
<meta name="robots" content="noindex, nofolllow, noarchive, noodp, NoImageIndex, noydir">
|
||||||
<title>Firefly III</title>
|
<title>Firefly III</title>
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'>
|
<meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{{ journals.render|raw }}
|
{{ journals.render|raw }}
|
||||||
|
|
||||||
<table class="table table-hover">
|
<table class="table table-hover {% if sorting %}sortable-table{% endif %}">
|
||||||
<thead>
|
<thead>
|
||||||
<tr class="ignore">
|
<tr class="ignore">
|
||||||
<th class="hidden-xs" colspan="2"> </th>
|
<th class="hidden-xs" colspan="2"> </th>
|
||||||
@ -40,7 +40,7 @@
|
|||||||
<td colspan="7"><em>Invalid journal: Found {{ journal.transactions|length }} transaction(s)</em></td>
|
<td colspan="7"><em>Invalid journal: Found {{ journal.transactions|length }} transaction(s)</em></td>
|
||||||
</tr>
|
</tr>
|
||||||
{% else %}
|
{% else %}
|
||||||
{% set _sum = _sum + journal.correct_amount %}
|
{% set _sum = _sum + journal.amount %}
|
||||||
<tr class="drag" data-date="{{ journal.date.format('Y-m-d') }}" data-id="{{ journal.id }}">
|
<tr class="drag" data-date="{{ journal.date.format('Y-m-d') }}" data-id="{{ journal.id }}">
|
||||||
<td class="hidden-xs">
|
<td class="hidden-xs">
|
||||||
<div class="btn-group btn-group-xs">
|
<div class="btn-group btn-group-xs">
|
||||||
@ -64,11 +64,7 @@
|
|||||||
|
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{% if not hideTags %}
|
{{ journal.amount|formatAmount }}
|
||||||
{{ relevantTags(journal)|raw }}
|
|
||||||
{% else %}
|
|
||||||
{{ journal.correct_amount|formatAmount }}
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
</td>
|
||||||
<td class="hidden-sm hidden-xs">
|
<td class="hidden-sm hidden-xs">
|
||||||
{{ journal.date.formatLocalized(monthAndDayFormat) }}
|
{{ journal.date.formatLocalized(monthAndDayFormat) }}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th>{{ 'name'|_ }}</th>
|
<th>{{ 'name'|_ }}</th>
|
||||||
<th>{{ 'balanceStart'|_ }}</th>
|
<th>{{ 'balanceStart'|_ }}</th>
|
||||||
<th>{{ 'balanceStart'|_ }}</th>
|
<th>{{ 'balanceEnd'|_ }}</th>
|
||||||
<th>{{ 'difference'|_ }}</th>
|
<th>{{ 'difference'|_ }}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
@ -87,7 +87,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-body table-responsive no-padding">
|
<div class="box-body table-responsive no-padding">
|
||||||
{% include 'list/journals.twig' with {'journals': tag.transactionjournals} %}
|
{% include 'list/journals.twig' with {'journals': tag.transactionjournals, 'showPageSum' : true} %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user