mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-11-18 15:39:50 +00:00
Add code for budgets
This commit is contained in:
56
app/Api/V2/Controllers/Controller.php
Normal file
56
app/Api/V2/Controllers/Controller.php
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Controller.php
|
||||||
|
* Copyright (c) 2022 james@firefly-iii.org
|
||||||
|
*
|
||||||
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace FireflyIII\Api\V2\Controllers;
|
||||||
|
|
||||||
|
use FireflyIII\Transformers\AbstractTransformer;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Routing\Controller as BaseController;
|
||||||
|
use League\Fractal\Manager;
|
||||||
|
use League\Fractal\Resource\Item;
|
||||||
|
use League\Fractal\Serializer\JsonApiSerializer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Controller
|
||||||
|
*/
|
||||||
|
class Controller extends BaseController
|
||||||
|
{
|
||||||
|
protected const CONTENT_TYPE = 'application/vnd.api+json';
|
||||||
|
/**
|
||||||
|
* Returns a JSON API object and returns it.
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param Model $object
|
||||||
|
* @param AbstractTransformer $transformer
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
final protected function jsonApiObject(string $key, Model $object, AbstractTransformer $transformer): array
|
||||||
|
{
|
||||||
|
// create some objects:
|
||||||
|
$manager = new Manager;
|
||||||
|
$baseUrl = request()->getSchemeAndHttpHost() . '/api/v2';
|
||||||
|
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||||
|
|
||||||
|
$resource = new Item($object, $transformer, $key);
|
||||||
|
return $manager->createData($resource)->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -62,4 +62,17 @@ class SumController extends Controller
|
|||||||
return response()->json($converted);
|
return response()->json($converted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param DateRequest $request
|
||||||
|
* @return JsonResponse
|
||||||
|
*/
|
||||||
|
public function spent(DateRequest $request): JsonResponse
|
||||||
|
{
|
||||||
|
$data = $request->getAll();
|
||||||
|
$result = $this->repository->spentInPeriod($data['start'], $data['end']);
|
||||||
|
$converted = $this->cerSum(array_values($result));
|
||||||
|
|
||||||
|
return response()->json($converted);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
46
app/Api/V2/Controllers/System/PreferencesController.php
Normal file
46
app/Api/V2/Controllers/System/PreferencesController.php
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* PreferencesController.php
|
||||||
|
* Copyright (c) 2022 james@firefly-iii.org
|
||||||
|
*
|
||||||
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace FireflyIII\Api\V2\Controllers\System;
|
||||||
|
|
||||||
|
use FireflyIII\Api\V2\Controllers\Controller;
|
||||||
|
use FireflyIII\Models\Preference;
|
||||||
|
use FireflyIII\Transformers\PreferenceTransformer;
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class PreferencesController
|
||||||
|
*/
|
||||||
|
class PreferencesController extends Controller
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Preference $preference
|
||||||
|
* @return JsonResponse
|
||||||
|
*/
|
||||||
|
public function get(Preference $preference): JsonResponse
|
||||||
|
{
|
||||||
|
return response()
|
||||||
|
->json($this->jsonApiObject('preferences', $preference, new PreferenceTransformer))
|
||||||
|
->header('Content-Type', self::CONTENT_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -26,6 +26,8 @@ use Carbon\Carbon;
|
|||||||
use DB;
|
use DB;
|
||||||
use Exception;
|
use Exception;
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Models\Attachment;
|
use FireflyIII\Models\Attachment;
|
||||||
use FireflyIII\Models\AutoBudget;
|
use FireflyIII\Models\AutoBudget;
|
||||||
use FireflyIII\Models\Budget;
|
use FireflyIII\Models\Budget;
|
||||||
@@ -34,6 +36,8 @@ use FireflyIII\Models\Note;
|
|||||||
use FireflyIII\Models\RecurrenceTransactionMeta;
|
use FireflyIII\Models\RecurrenceTransactionMeta;
|
||||||
use FireflyIII\Models\RuleAction;
|
use FireflyIII\Models\RuleAction;
|
||||||
use FireflyIII\Models\RuleTrigger;
|
use FireflyIII\Models\RuleTrigger;
|
||||||
|
use FireflyIII\Models\TransactionType;
|
||||||
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||||
use FireflyIII\Services\Internal\Destroy\BudgetDestroyService;
|
use FireflyIII\Services\Internal\Destroy\BudgetDestroyService;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
@@ -126,15 +130,64 @@ class BudgetRepository implements BudgetRepositoryInterface
|
|||||||
$return[$currency->id]['sum'] = bcadd($return[$currency->id]['sum'], $amount);
|
$return[$currency->id]['sum'] = bcadd($return[$currency->id]['sum'], $amount);
|
||||||
Log::debug(sprintf('Amount per day: %s (%s over %d days). Total amount for %d days: %s',
|
Log::debug(sprintf('Amount per day: %s (%s over %d days). Total amount for %d days: %s',
|
||||||
bcdiv((string) $limit->amount, (string) $total),
|
bcdiv((string) $limit->amount, (string) $total),
|
||||||
$limit->amount,
|
$limit->amount,
|
||||||
$total,
|
$total,
|
||||||
$days,
|
$days,
|
||||||
$amount));
|
$amount));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
public function getActiveBudgets(): Collection
|
||||||
|
{
|
||||||
|
return $this->user->budgets()->where('active', true)
|
||||||
|
->orderBy('order', 'ASC')
|
||||||
|
->orderBy('name', 'ASC')
|
||||||
|
->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How many days of this budget limit are between start and end?
|
||||||
|
*
|
||||||
|
* @param BudgetLimit $limit
|
||||||
|
* @param Carbon $start
|
||||||
|
* @param Carbon $end
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
private function daysInOverlap(BudgetLimit $limit, Carbon $start, Carbon $end): int
|
||||||
|
{
|
||||||
|
// start1 = $start
|
||||||
|
// start2 = $limit->start_date
|
||||||
|
// start1 = $end
|
||||||
|
// start2 = $limit->end_date
|
||||||
|
|
||||||
|
// limit is larger than start and end (inclusive)
|
||||||
|
// |-----------|
|
||||||
|
// |----------------|
|
||||||
|
if ($start->gte($limit->start_date) && $end->lte($limit->end_date)) {
|
||||||
|
return $start->diffInDays($end) + 1; // add one day
|
||||||
|
}
|
||||||
|
// limit starts earlier and limit ends first:
|
||||||
|
// |-----------|
|
||||||
|
// |-------|
|
||||||
|
if ($limit->start_date->lte($start) && $limit->end_date->lte($end)) {
|
||||||
|
// return days in the range $start-$limit_end
|
||||||
|
return $start->diffInDays($limit->end_date) + 1; // add one day, the day itself
|
||||||
|
}
|
||||||
|
// limit starts later and limit ends earlier
|
||||||
|
// |-----------|
|
||||||
|
// |-------|
|
||||||
|
if ($limit->start_date->gte($start) && $limit->end_date->gte($end)) {
|
||||||
|
// return days in the range $limit_start - $end
|
||||||
|
return $limit->start_date->diffInDays($end) + 1; // add one day, the day itself
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
@@ -161,17 +214,6 @@ class BudgetRepository implements BudgetRepositoryInterface
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Collection
|
|
||||||
*/
|
|
||||||
public function getActiveBudgets(): Collection
|
|
||||||
{
|
|
||||||
return $this->user->budgets()->where('active', true)
|
|
||||||
->orderBy('order', 'ASC')
|
|
||||||
->orderBy('name', 'ASC')
|
|
||||||
->get();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Budget $budget
|
* @param Budget $budget
|
||||||
*
|
*
|
||||||
@@ -385,6 +427,69 @@ class BudgetRepository implements BudgetRepositoryInterface
|
|||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function spentInPeriod(Carbon $start, Carbon $end): array
|
||||||
|
{
|
||||||
|
Log::debug(sprintf('Now in %s', __METHOD__));
|
||||||
|
$start->startOfDay();
|
||||||
|
$end->endOfDay();
|
||||||
|
|
||||||
|
// exclude specific liabilities
|
||||||
|
$repository = app(AccountRepositoryInterface::class);
|
||||||
|
$repository->setUser($this->user);
|
||||||
|
$subset = $repository->getAccountsByType(config('firefly.valid_liabilities'));
|
||||||
|
$selection = new Collection;
|
||||||
|
/** @var Account $account */
|
||||||
|
foreach ($subset as $account) {
|
||||||
|
if ('credit' === $repository->getMetaValue($account, 'liability_direction')) {
|
||||||
|
$selection->push($account);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// start collecting:
|
||||||
|
/** @var GroupCollectorInterface $collector */
|
||||||
|
$collector = app(GroupCollectorInterface::class);
|
||||||
|
$collector->setUser($this->user)
|
||||||
|
->setRange($start, $end)
|
||||||
|
->excludeDestinationAccounts($selection)
|
||||||
|
->setTypes([TransactionType::WITHDRAWAL])
|
||||||
|
->setBudgets($this->getActiveBudgets());
|
||||||
|
|
||||||
|
$journals = $collector->getExtractedJournals();
|
||||||
|
$array = [];
|
||||||
|
|
||||||
|
foreach ($journals as $journal) {
|
||||||
|
$currencyId = (int) $journal['currency_id'];
|
||||||
|
$array[$currencyId] = $array[$currencyId] ?? [
|
||||||
|
'id' => (string) $currencyId,
|
||||||
|
'name' => $journal['currency_name'],
|
||||||
|
'symbol' => $journal['currency_symbol'],
|
||||||
|
'code' => $journal['currency_code'],
|
||||||
|
'decimal_places' => $journal['currency_decimal_places'],
|
||||||
|
'sum' => '0',
|
||||||
|
];
|
||||||
|
$array[$currencyId]['sum'] = bcadd($array[$currencyId]['sum'], app('steam')->negative($journal['amount']));
|
||||||
|
|
||||||
|
// also do foreign amount:
|
||||||
|
$foreignId = (int) $journal['foreign_currency_id'];
|
||||||
|
if (0 !== $foreignId) {
|
||||||
|
$array[$foreignId] = $array[$foreignId] ?? [
|
||||||
|
'id' => (string) $foreignId,
|
||||||
|
'name' => $journal['foreign_currency_name'],
|
||||||
|
'symbol' => $journal['foreign_currency_symbol'],
|
||||||
|
'code' => $journal['foreign_currency_code'],
|
||||||
|
'decimal_places' => $journal['foreign_currency_decimal_places'],
|
||||||
|
'sum' => '0',
|
||||||
|
];
|
||||||
|
$array[$foreignId]['sum'] = bcadd($array[$foreignId]['sum'], app('steam')->negative($journal['foreign_amount']));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $array;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $data
|
* @param array $data
|
||||||
*
|
*
|
||||||
@@ -652,42 +757,4 @@ class BudgetRepository implements BudgetRepositoryInterface
|
|||||||
|
|
||||||
$autoBudget->save();
|
$autoBudget->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* How many days of this budget limit are between start and end?
|
|
||||||
*
|
|
||||||
* @param BudgetLimit $limit
|
|
||||||
* @param Carbon $start
|
|
||||||
* @param Carbon $end
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
private function daysInOverlap(BudgetLimit $limit, Carbon $start, Carbon $end): int
|
|
||||||
{
|
|
||||||
// start1 = $start
|
|
||||||
// start2 = $limit->start_date
|
|
||||||
// start1 = $end
|
|
||||||
// start2 = $limit->end_date
|
|
||||||
|
|
||||||
// limit is larger than start and end (inclusive)
|
|
||||||
// |-----------|
|
|
||||||
// |----------------|
|
|
||||||
if ($start->gte($limit->start_date) && $end->lte($limit->end_date)) {
|
|
||||||
return $start->diffInDays($end) + 1; // add one day
|
|
||||||
}
|
|
||||||
// limit starts earlier and limit ends first:
|
|
||||||
// |-----------|
|
|
||||||
// |-------|
|
|
||||||
if ($limit->start_date->lte($start) && $limit->end_date->lte($end)) {
|
|
||||||
// return days in the range $start-$limit_end
|
|
||||||
return $start->diffInDays($limit->end_date) + 1; // add one day, the day itself
|
|
||||||
}
|
|
||||||
// limit starts later and limit ends earlier
|
|
||||||
// |-----------|
|
|
||||||
// |-------|
|
|
||||||
if ($limit->start_date->gte($start) && $limit->end_date->gte($end)) {
|
|
||||||
// return days in the range $limit_start - $end
|
|
||||||
return $limit->start_date->diffInDays($end) + 1; // add one day, the day itself
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -185,6 +185,16 @@ interface BudgetRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function setUser(User $user);
|
public function setUser(User $user);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used in the v2 API to calculate the amount of money spent in all active budgets.
|
||||||
|
*
|
||||||
|
* @param Carbon $start
|
||||||
|
* @param Carbon $end
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function spentInPeriod(Carbon $start, Carbon $end): array;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $data
|
* @param array $data
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -288,7 +288,7 @@ class OperationsRepository implements OperationsRepositoryInterface
|
|||||||
* @param Collection|null $accounts
|
* @param Collection|null $accounts
|
||||||
* @param Collection|null $budgets
|
* @param Collection|null $budgets
|
||||||
* @param TransactionCurrency|null $currency
|
* @param TransactionCurrency|null $currency
|
||||||
*
|
* @deprecated
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function sumExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $budgets = null, ?TransactionCurrency $currency = null
|
public function sumExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $budgets = null, ?TransactionCurrency $currency = null
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ interface OperationsRepositoryInterface
|
|||||||
public function spentInPeriodMc(Collection $budgets, Collection $accounts, Carbon $start, Carbon $end): array;
|
public function spentInPeriodMc(Collection $budgets, Collection $accounts, Carbon $start, Carbon $end): array;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @deprecated
|
||||||
* @param Carbon $start
|
* @param Carbon $start
|
||||||
* @param Carbon $end
|
* @param Carbon $end
|
||||||
* @param Collection|null $accounts
|
* @param Collection|null $accounts
|
||||||
@@ -101,4 +102,5 @@ interface OperationsRepositoryInterface
|
|||||||
public function sumExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $budgets = null, ?TransactionCurrency $currency = null
|
public function sumExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $budgets = null, ?TransactionCurrency $currency = null
|
||||||
): array;
|
): array;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
12
frontend/src/api/v2/budgets/sum.js
vendored
12
frontend/src/api/v2/budgets/sum.js
vendored
@@ -29,10 +29,10 @@ export default class Sum {
|
|||||||
return api.get(url, {params: {start: startStr, end: endStr}});
|
return api.get(url, {params: {start: startStr, end: endStr}});
|
||||||
}
|
}
|
||||||
|
|
||||||
// /*paid(start, end) {
|
spent(start, end) {
|
||||||
// let url = 'api/v2/bills/sum/paid';
|
let url = 'api/v2/budgets/sum/spent';
|
||||||
// let startStr = format(start, 'y-MM-dd');
|
let startStr = format(start, 'y-MM-dd');
|
||||||
// let endStr = format(end, 'y-MM-dd');
|
let endStr = format(end, 'y-MM-dd');
|
||||||
// return api.get(url, {params: {start: startStr, end: endStr}});
|
return api.get(url, {params: {start: startStr, end: endStr}});
|
||||||
// }*/
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
<q-card bordered>
|
<q-card bordered>
|
||||||
<q-item>
|
<q-item>
|
||||||
<q-item-section>
|
<q-item-section>
|
||||||
<q-item-label><strong>Spend</strong></q-item-label>
|
<q-item-label><strong>To spend and left</strong></q-item-label>
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
</q-item>
|
</q-item>
|
||||||
<q-separator/>
|
<q-separator/>
|
||||||
@@ -48,6 +48,10 @@
|
|||||||
<span :title="formatAmount(this.currency, this.budgetedAmount)">Budgeted</span>:
|
<span :title="formatAmount(this.currency, this.budgetedAmount)">Budgeted</span>:
|
||||||
<span v-for="(budget, index) in budgeted"><span v-if="budget.native">(</span>{{ formatAmount(budget.code, budget.sum) }}<span v-if="budget.native">)</span><span
|
<span v-for="(budget, index) in budgeted"><span v-if="budget.native">(</span>{{ formatAmount(budget.code, budget.sum) }}<span v-if="budget.native">)</span><span
|
||||||
v-if="index+1 !== budgeted.length">, </span></span>
|
v-if="index+1 !== budgeted.length">, </span></span>
|
||||||
|
<br>
|
||||||
|
<span :title="formatAmount(this.currency, this.spentAmount)">Spent</span>:
|
||||||
|
<span v-for="(budget, index) in spent"><span v-if="budget.native">(</span>{{ formatAmount(budget.code, budget.sum) }}<span v-if="budget.native">)</span><span
|
||||||
|
v-if="index+1 !== budgeted.length">, </span></span>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
@@ -118,7 +122,7 @@ export default {
|
|||||||
const sum = new Sum;
|
const sum = new Sum;
|
||||||
this.currency = this.store.getCurrencyCode;
|
this.currency = this.store.getCurrencyCode;
|
||||||
sum.budgeted(start, end).then((response) => this.parseBudgetedResponse(response.data));
|
sum.budgeted(start, end).then((response) => this.parseBudgetedResponse(response.data));
|
||||||
//sum.paid(start, end).then((response) => this.parsePaidResponse(response.data));
|
sum.spent(start, end).then((response) => this.parseSpentResponse(response.data));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// TODO this method is recycled a lot.
|
// TODO this method is recycled a lot.
|
||||||
@@ -143,6 +147,24 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
parseSpentResponse: function (data) {
|
||||||
|
for (let i in data) {
|
||||||
|
if (data.hasOwnProperty(i)) {
|
||||||
|
const current = data[i];
|
||||||
|
const hasNative = current.native_id !== current.id && parseFloat(current.native_sum) !== 0.0;
|
||||||
|
this.spent.push(
|
||||||
|
{
|
||||||
|
sum: current.sum,
|
||||||
|
code: current.code,
|
||||||
|
native: hasNative
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (hasNative || current.native_id === current.id) {
|
||||||
|
this.spentAmount = this.spentAmount + (parseFloat(current.native_sum) * -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -46,14 +46,14 @@ Route::group(
|
|||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* V2 API route for bills.
|
* V2 API route for budgets.
|
||||||
*/
|
*/
|
||||||
Route::group(
|
Route::group(
|
||||||
['namespace' => 'FireflyIII\Api\V2\Controllers\Model\Budget', 'prefix' => 'v2/budgets',
|
['namespace' => 'FireflyIII\Api\V2\Controllers\Model\Budget', 'prefix' => 'v2/budgets',
|
||||||
'as' => 'api.v2.budgets',],
|
'as' => 'api.v2.budgets',],
|
||||||
static function () {
|
static function () {
|
||||||
Route::get('sum/budgeted', ['uses' => 'SumController@budgeted', 'as' => 'sum.budgeted']);
|
Route::get('sum/budgeted', ['uses' => 'SumController@budgeted', 'as' => 'sum.budgeted']);
|
||||||
Route::get('sum/unpaid', ['uses' => 'SumController@unpaid', 'as' => 'sum.unpaid']);
|
Route::get('sum/spent', ['uses' => 'SumController@spent', 'as' => 'sum.spent']);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user