mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Refactor and split category repository.
This commit is contained in:
parent
7eb9086a28
commit
e5269bb312
@ -28,6 +28,8 @@ use Carbon\Carbon;
|
||||
use FireflyIII\Api\V1\Controllers\Controller;
|
||||
use FireflyIII\Api\V1\Requests\DateRequest;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||
use FireflyIII\Repositories\Category\NoCategoryRepositoryInterface;
|
||||
use FireflyIII\Repositories\Category\OperationsRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Collection;
|
||||
@ -40,8 +42,15 @@ class CategoryController extends Controller
|
||||
/** @var CategoryRepositoryInterface */
|
||||
private $categoryRepository;
|
||||
|
||||
/** @var OperationsRepositoryInterface */
|
||||
private $opsRepository;
|
||||
|
||||
/** @var NoCategoryRepositoryInterface */
|
||||
private $noCatRepository;
|
||||
|
||||
/**
|
||||
* AccountController constructor.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
@ -52,7 +61,11 @@ class CategoryController extends Controller
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
$this->categoryRepository = app(CategoryRepositoryInterface::class);
|
||||
$this->opsRepository = app(OperationsRepositoryInterface::class);
|
||||
$this->noCatRepository = app(NoCategoryRepositoryInterface::class);
|
||||
$this->categoryRepository->setUser($user);
|
||||
$this->opsRepository->setUser($user);
|
||||
$this->noCatRepository->setUser($user);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
@ -78,8 +91,8 @@ class CategoryController extends Controller
|
||||
|
||||
|
||||
$tempData = [];
|
||||
$spent = $this->categoryRepository->spentInPeriodPerCurrency(new Collection, new Collection, $start, $end);
|
||||
$earned = $this->categoryRepository->earnedInPeriodPerCurrency(new Collection, new Collection, $start, $end);
|
||||
$spent = $this->opsRepository->spentInPeriodPerCurrency(new Collection, new Collection, $start, $end);
|
||||
$earned = $this->opsRepository->earnedInPeriodPerCurrency(new Collection, new Collection, $start, $end);
|
||||
$categories = [];
|
||||
|
||||
// earned:
|
||||
@ -110,7 +123,7 @@ class CategoryController extends Controller
|
||||
}
|
||||
|
||||
// earned with no category:
|
||||
$noCategory = $this->categoryRepository->earnedInPeriodPcWoCategory(new Collection, $start, $end);
|
||||
$noCategory = $this->noCatRepository->earnedInPeriodPcWoCategory(new Collection, $start, $end);
|
||||
foreach ($noCategory as $currencyId => $income) {
|
||||
$categoryName = (string)trans('firefly.no_category');
|
||||
// find or make set for currency:
|
||||
@ -164,7 +177,9 @@ class CategoryController extends Controller
|
||||
}
|
||||
|
||||
// spent with no category
|
||||
$noCategory = $this->categoryRepository->spentInPeriodPcWoCategory(new Collection, $start, $end);
|
||||
$noCategory = $this->noCatRepository->spentInPeriodPcWoCategory(new Collection, $start, $end);
|
||||
|
||||
|
||||
foreach ($noCategory as $currencyId => $expense) {
|
||||
$categoryName = (string)trans('firefly.no_category');
|
||||
// find or make set for currency:
|
||||
|
@ -31,6 +31,8 @@ use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||
use FireflyIII\Repositories\Category\NoCategoryRepositoryInterface;
|
||||
use FireflyIII\Repositories\Category\OperationsRepositoryInterface;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
use FireflyIII\Support\Chart\Category\WholePeriodChartGenerator;
|
||||
@ -52,6 +54,7 @@ class CategoryController extends Controller
|
||||
|
||||
/**
|
||||
* CategoryController constructor.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
@ -81,10 +84,10 @@ class CategoryController extends Controller
|
||||
if ($cache->has()) {
|
||||
return response()->json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
$start = $repository->firstUseDate($category) ?? $this->getDate();
|
||||
$range = app('preferences')->get('viewRange', '1M')->data;
|
||||
$start = app('navigation')->startOfPeriod($start, $range);
|
||||
$end = $this->getDate();
|
||||
$start = $repository->firstUseDate($category) ?? $this->getDate();
|
||||
$range = app('preferences')->get('viewRange', '1M')->data;
|
||||
$start = app('navigation')->startOfPeriod($start, $range);
|
||||
$end = $this->getDate();
|
||||
|
||||
Log::debug(sprintf('Full range is %s to %s', $start->format('Y-m-d'), $end->format('Y-m-d')));
|
||||
|
||||
@ -101,12 +104,9 @@ class CategoryController extends Controller
|
||||
/**
|
||||
* Shows the category chart on the front page.
|
||||
*
|
||||
* @param CategoryRepositoryInterface $repository
|
||||
* @param AccountRepositoryInterface $accountRepository
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function frontPage(CategoryRepositoryInterface $repository, AccountRepositoryInterface $accountRepository): JsonResponse
|
||||
public function frontPage(): JsonResponse
|
||||
{
|
||||
$start = session('start', Carbon::now()->startOfMonth());
|
||||
$end = session('end', Carbon::now()->endOfMonth());
|
||||
@ -122,7 +122,19 @@ class CategoryController extends Controller
|
||||
// currency repos:
|
||||
/** @var CurrencyRepositoryInterface $currencyRepository */
|
||||
$currencyRepository = app(CurrencyRepositoryInterface::class);
|
||||
$currencies = [];
|
||||
/** @var CategoryRepositoryInterface $repository */
|
||||
$repository = app(CategoryRepositoryInterface::class);
|
||||
|
||||
/** @var AccountRepositoryInterface $accountRepository */
|
||||
$accountRepository = app(AccountRepositoryInterface::class);
|
||||
|
||||
/** @var OperationsRepositoryInterface $opsRepository */
|
||||
$opsRepository = app(OperationsRepositoryInterface::class);
|
||||
|
||||
/** @var NoCategoryRepositoryInterface $noCatRepository */
|
||||
$noCatRepository = app(NoCategoryRepositoryInterface::class);
|
||||
|
||||
$currencies = [];
|
||||
|
||||
|
||||
$chartData = [];
|
||||
@ -132,7 +144,7 @@ class CategoryController extends Controller
|
||||
|
||||
/** @var Category $category */
|
||||
foreach ($categories as $category) {
|
||||
$spentArray = $repository->spentInPeriodPerCurrency(new Collection([$category]), $accounts, $start, $end);
|
||||
$spentArray = $opsRepository->spentInPeriodPerCurrency(new Collection([$category]), $accounts, $start, $end);
|
||||
foreach ($spentArray as $categoryId => $spentInfo) {
|
||||
foreach ($spentInfo['spent'] as $currencyId => $row) {
|
||||
$spent = $row['spent'];
|
||||
@ -150,7 +162,7 @@ class CategoryController extends Controller
|
||||
}
|
||||
|
||||
// no category per currency:
|
||||
$noCategory = $repository->spentInPeriodPcWoCategory(new Collection, $start, $end);
|
||||
$noCategory = $noCatRepository->spentInPeriodPcWoCategory(new Collection, $start, $end);
|
||||
foreach ($noCategory as $currencyId => $spent) {
|
||||
$currencies[$currencyId] = $currencies[$currencyId] ?? $currencyRepository->findNull($currencyId);
|
||||
$tempData[] = [
|
||||
@ -212,13 +224,16 @@ class CategoryController extends Controller
|
||||
$cache->addProperty($accounts->pluck('id')->toArray());
|
||||
$cache->addProperty($category);
|
||||
if ($cache->has()) {
|
||||
return response()->json($cache->get());// @codeCoverageIgnore
|
||||
return response()->json($cache->get());// @codeCoverageIgnore
|
||||
}
|
||||
$repository = app(CategoryRepositoryInterface::class);
|
||||
$expenses = $repository->periodExpenses(new Collection([$category]), $accounts, $start, $end);
|
||||
$income = $repository->periodIncome(new Collection([$category]), $accounts, $start, $end);
|
||||
$periods = app('navigation')->listOfPeriods($start, $end);
|
||||
$chartData = [
|
||||
|
||||
/** @var OperationsRepositoryInterface $opsRepository */
|
||||
$opsRepository = app(OperationsRepositoryInterface::class);
|
||||
|
||||
$expenses = $opsRepository->periodExpenses(new Collection([$category]), $accounts, $start, $end);
|
||||
$income = $opsRepository->periodIncome(new Collection([$category]), $accounts, $start, $end);
|
||||
$periods = app('navigation')->listOfPeriods($start, $end);
|
||||
$chartData = [
|
||||
[
|
||||
'label' => (string)trans('firefly.spent'),
|
||||
'entries' => [],
|
||||
@ -256,8 +271,6 @@ class CategoryController extends Controller
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Chart for period for transactions without a category.
|
||||
*
|
||||
@ -279,11 +292,14 @@ class CategoryController extends Controller
|
||||
if ($cache->has()) {
|
||||
return response()->json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
$repository = app(CategoryRepositoryInterface::class);
|
||||
$expenses = $repository->periodExpensesNoCategory($accounts, $start, $end);
|
||||
$income = $repository->periodIncomeNoCategory($accounts, $start, $end);
|
||||
$periods = app('navigation')->listOfPeriods($start, $end);
|
||||
$chartData = [
|
||||
|
||||
/** @var NoCategoryRepositoryInterface $noCatRepository */
|
||||
$noCatRepository = app(NoCategoryRepositoryInterface::class);
|
||||
|
||||
$expenses = $noCatRepository->periodExpensesNoCategory($accounts, $start, $end);
|
||||
$income = $noCatRepository->periodIncomeNoCategory($accounts, $start, $end);
|
||||
$periods = app('navigation')->listOfPeriods($start, $end);
|
||||
$chartData = [
|
||||
[
|
||||
'label' => (string)trans('firefly.spent'),
|
||||
'entries' => [],
|
||||
|
@ -26,6 +26,8 @@ use Carbon\Carbon;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||
use FireflyIII\Repositories\Category\NoCategoryRepositoryInterface;
|
||||
use FireflyIII\Repositories\Category\OperationsRepositoryInterface;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
use FireflyIII\Support\Http\Controllers\BasicDataSupport;
|
||||
use Illuminate\Support\Collection;
|
||||
@ -60,9 +62,13 @@ class CategoryController extends Controller
|
||||
}
|
||||
/** @var CategoryRepositoryInterface $repository */
|
||||
$repository = app(CategoryRepositoryInterface::class);
|
||||
|
||||
/** @var OperationsRepositoryInterface $opsRepository */
|
||||
$opsRepository = app(OperationsRepositoryInterface::class);
|
||||
|
||||
$categories = $repository->getCategories();
|
||||
$data = $repository->periodExpenses($categories, $accounts, $start, $end);
|
||||
$data[0] = $repository->periodExpensesNoCategory($accounts, $start, $end);
|
||||
$data = $opsRepository->periodExpenses($categories, $accounts, $start, $end);
|
||||
$data[0] = $opsRepository->periodExpensesNoCategory($accounts, $start, $end);
|
||||
$report = $this->filterPeriodReport($data);
|
||||
|
||||
// depending on the carbon format (a reliable way to determine the general date difference)
|
||||
@ -114,9 +120,16 @@ class CategoryController extends Controller
|
||||
}
|
||||
/** @var CategoryRepositoryInterface $repository */
|
||||
$repository = app(CategoryRepositoryInterface::class);
|
||||
|
||||
/** @var OperationsRepositoryInterface $opsRepository */
|
||||
$opsRepository = app(OperationsRepositoryInterface::class);
|
||||
|
||||
/** @var NoCategoryRepositoryInterface $noCatRepository */
|
||||
$noCatRepository = app(NoCategoryRepositoryInterface::class);
|
||||
|
||||
$categories = $repository->getCategories();
|
||||
$data = $repository->periodIncome($categories, $accounts, $start, $end);
|
||||
$data[0] = $repository->periodIncomeNoCategory($accounts, $start, $end);
|
||||
$data = $opsRepository->periodIncome($categories, $accounts, $start, $end);
|
||||
$data[0] = $noCatRepository->periodIncomeNoCategory($accounts, $start, $end);
|
||||
$report = $this->filterPeriodReport($data);
|
||||
|
||||
// depending on the carbon format (a reliable way to determine the general date difference)
|
||||
@ -169,6 +182,10 @@ class CategoryController extends Controller
|
||||
|
||||
/** @var CategoryRepositoryInterface $repository */
|
||||
$repository = app(CategoryRepositoryInterface::class);
|
||||
|
||||
/** @var OperationsRepositoryInterface $opsRepository */
|
||||
$opsRepository = app(OperationsRepositoryInterface::class);
|
||||
|
||||
$categories = $repository->getCategories();
|
||||
$report = [
|
||||
'categories' => [],
|
||||
@ -176,8 +193,8 @@ class CategoryController extends Controller
|
||||
];
|
||||
/** @var Category $category */
|
||||
foreach ($categories as $category) {
|
||||
$spent = $repository->spentInPeriod($category, $accounts, $start, $end);
|
||||
$earned = $repository->earnedInPeriod($category, $accounts, $start, $end);
|
||||
$spent = $opsRepository->spentInPeriod($category, $accounts, $start, $end);
|
||||
$earned = $opsRepository->earnedInPeriod($category, $accounts, $start, $end);
|
||||
if (0 === count($spent) && 0 === count($earned)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -24,6 +24,10 @@ namespace FireflyIII\Providers;
|
||||
|
||||
use FireflyIII\Repositories\Category\CategoryRepository;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||
use FireflyIII\Repositories\Category\NoCategoryRepository;
|
||||
use FireflyIII\Repositories\Category\NoCategoryRepositoryInterface;
|
||||
use FireflyIII\Repositories\Category\OperationsRepository;
|
||||
use FireflyIII\Repositories\Category\OperationsRepositoryInterface;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
@ -47,7 +51,7 @@ class CategoryServiceProvider extends ServiceProvider
|
||||
{
|
||||
$this->app->bind(
|
||||
CategoryRepositoryInterface::class,
|
||||
function (Application $app) {
|
||||
static function (Application $app) {
|
||||
/** @var CategoryRepository $repository */
|
||||
$repository = app(CategoryRepository::class);
|
||||
if ($app->auth->check()) {
|
||||
@ -57,5 +61,31 @@ class CategoryServiceProvider extends ServiceProvider
|
||||
return $repository;
|
||||
}
|
||||
);
|
||||
|
||||
$this->app->bind(
|
||||
OperationsRepositoryInterface::class,
|
||||
static function (Application $app) {
|
||||
/** @var OperationsRepository $repository */
|
||||
$repository = app(OperationsRepository::class);
|
||||
if ($app->auth->check()) {
|
||||
$repository->setUser(auth()->user());
|
||||
}
|
||||
|
||||
return $repository;
|
||||
}
|
||||
);
|
||||
|
||||
$this->app->bind(
|
||||
NoCategoryRepositoryInterface::class,
|
||||
static function (Application $app) {
|
||||
/** @var NoCategoryRepository $repository */
|
||||
$repository = app(NoCategoryRepository::class);
|
||||
if ($app->auth->check()) {
|
||||
$repository->setUser(auth()->user());
|
||||
}
|
||||
|
||||
return $repository;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -24,22 +24,15 @@ namespace FireflyIII\Repositories\Category;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Factory\CategoryFactory;
|
||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Services\Internal\Destroy\CategoryDestroyService;
|
||||
use FireflyIII\Services\Internal\Update\CategoryUpdateService;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
use Navigation;
|
||||
|
||||
/**
|
||||
* Class CategoryRepository.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
class CategoryRepository implements CategoryRepositoryInterface
|
||||
{
|
||||
@ -73,175 +66,29 @@ class CategoryRepository implements CategoryRepositoryInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $categories
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* Find a category.
|
||||
*
|
||||
* @return array
|
||||
* @param string $name
|
||||
*
|
||||
* @return Category|null
|
||||
*/
|
||||
public function earnedInPeriod(Category $category, Collection $accounts, Carbon $start, Carbon $end): array
|
||||
public function findByName(string $name): ?Category
|
||||
{
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$categories = $this->user->categories()->get(['categories.*']);
|
||||
|
||||
// TODO no longer need to loop like this
|
||||
|
||||
$collector->setUser($this->user);
|
||||
$collector->setRange($start, $end)->setTypes([TransactionType::DEPOSIT])->setCategory($category);
|
||||
|
||||
if ($accounts->count() > 0) {
|
||||
$collector->setAccounts($accounts);
|
||||
}
|
||||
// collect and group results:
|
||||
$array = $collector->getExtractedJournals();
|
||||
$return = [];
|
||||
|
||||
foreach ($array as $journal) {
|
||||
$currencyCode = $journal['currency_code'];
|
||||
if (!isset($return[$currencyCode])) {
|
||||
$return[$currencyCode] = [
|
||||
'currency_id' => $journal['currency_id'],
|
||||
'currency_code' => $journal['currency_code'],
|
||||
'currency_name' => $journal['currency_name'],
|
||||
'currency_symbol' => $journal['currency_symbol'],
|
||||
'currency_decimal_places' => $journal['currency_decimal_places'],
|
||||
'earned' => '0',
|
||||
];
|
||||
foreach ($categories as $category) {
|
||||
if ($category->name === $name) {
|
||||
return $category;
|
||||
}
|
||||
|
||||
// also extract foreign currency information:
|
||||
if (null !== $journal['foreign_currency_id']) {
|
||||
$currencyCode = $journal['foreign_currency_code'];
|
||||
if (!isset($return[$currencyCode])) {
|
||||
$return[$currencyCode] = [
|
||||
'currency_id' => $journal['foreign_currency_id'],
|
||||
'currency_code' => $journal['foreign_currency_code'],
|
||||
'currency_name' => $journal['foreign_currency_name'],
|
||||
'currency_symbol' => $journal['foreign_currency_symbol'],
|
||||
'currency_decimal_places' => $journal['foreign_currency_decimal_places'],
|
||||
'earned' => '0',
|
||||
];
|
||||
}
|
||||
$return[$currencyCode]['earned'] = bcadd($return[$currencyCode]['earned'], app('steam')->positive($journal['foreign_amount']));
|
||||
}
|
||||
$return[$currencyCode]['earned'] = bcadd($return[$currencyCode]['earned'], app('steam')->positive($journal['amount']));
|
||||
}
|
||||
|
||||
return $return;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* A very cryptic method name that means:
|
||||
*
|
||||
* Get me the amount earned in this period, grouped per currency, where no category was set.
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function earnedInPeriodPcWoCategory(Collection $accounts, Carbon $start, Carbon $end): array
|
||||
{
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
|
||||
$collector->setUser($this->user);
|
||||
$collector->setRange($start, $end)->setTypes([TransactionType::DEPOSIT])->withoutCategory();
|
||||
|
||||
if ($accounts->count() > 0) {
|
||||
$collector->setAccounts($accounts);
|
||||
}
|
||||
$journals = $collector->getExtractedJournals();
|
||||
$return = [];
|
||||
|
||||
foreach ($journals as $journal) {
|
||||
$currencyId = (int)$journal['currency_id'];
|
||||
if (!isset($return[$currencyId])) {
|
||||
$return[$currencyId] = [
|
||||
'earned' => '0',
|
||||
'currency_id' => $currencyId,
|
||||
'currency_symbol' => $journal['currency_symbol'],
|
||||
'currency_code' => $journal['currency_code'],
|
||||
'currency_decimal_places' => $journal['currency_decimal_places'],
|
||||
];
|
||||
}
|
||||
$return[$currencyId]['earned'] = bcadd($return[$currencyId]['earned'], $journal['amount']);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $categories
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function earnedInPeriodPerCurrency(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): array
|
||||
{
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
|
||||
$collector->setUser($this->user);
|
||||
$collector->setRange($start, $end)->setTypes([TransactionType::DEPOSIT]);
|
||||
|
||||
if ($categories->count() > 0) {
|
||||
$collector->setCategories($categories);
|
||||
}
|
||||
if (0 === $categories->count()) {
|
||||
$collector->setCategories($this->getCategories());
|
||||
}
|
||||
|
||||
if ($accounts->count() > 0) {
|
||||
$collector->setAccounts($accounts);
|
||||
}
|
||||
$journals = $collector->getExtractedJournals();
|
||||
$return = [];
|
||||
foreach ($journals as $journal) {
|
||||
$categoryId = (int)$journal['category_id'];
|
||||
$currencyId = (int)$journal['currency_id'];
|
||||
$name = $journal['category_name'];
|
||||
// make array for category:
|
||||
if (!isset($return[$categoryId])) {
|
||||
$return[$categoryId] = [
|
||||
'name' => $name,
|
||||
'earned' => [],
|
||||
];
|
||||
}
|
||||
if (!isset($return[$categoryId]['earned'][$currencyId])) {
|
||||
$return[$categoryId]['earned'][$currencyId] = [
|
||||
'earned' => '0',
|
||||
'currency_id' => $currencyId,
|
||||
'currency_symbol' => $journal['currency_symbol'],
|
||||
'currency_code' => $journal['currency_code'],
|
||||
'currency_decimal_places' => $journal['currency_decimal_places'],
|
||||
];
|
||||
}
|
||||
$return[$categoryId]['earned'][$currencyId]['earned']
|
||||
= bcadd($return[$categoryId]['earned'][$currencyId]['earned'], $journal['amount']);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all the categories belonging to a user.
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getCategories(): Collection
|
||||
{
|
||||
/** @var Collection $set */
|
||||
$set = $this->user->categories()->orderBy('name', 'ASC')->get();
|
||||
|
||||
return $set;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|null $categoryId
|
||||
* @param int|null $categoryId
|
||||
* @param string|null $categoryName
|
||||
*
|
||||
* @return Category|null
|
||||
@ -279,46 +126,6 @@ class CategoryRepository implements CategoryRepositoryInterface
|
||||
return $this->user->categories()->find($categoryId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Find a category.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return Category|null
|
||||
*/
|
||||
public function findByName(string $name): ?Category
|
||||
{
|
||||
$categories = $this->user->categories()->get(['categories.*']);
|
||||
|
||||
// TODO no longer need to loop like this
|
||||
|
||||
foreach ($categories as $category) {
|
||||
if ($category->name === $name) {
|
||||
return $category;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return Category
|
||||
*/
|
||||
public function store(array $data): Category
|
||||
{
|
||||
/** @var CategoryFactory $factory */
|
||||
$factory = app(CategoryFactory::class);
|
||||
$factory->setUser($this->user);
|
||||
|
||||
return $factory->findOrCreate(null, $data['name']);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
*
|
||||
@ -360,7 +167,20 @@ class CategoryRepository implements CategoryRepositoryInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
* Returns a list of all the categories belonging to a user.
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getCategories(): Collection
|
||||
{
|
||||
/** @var Collection $set */
|
||||
$set = $this->user->categories()->orderBy('name', 'ASC')->get();
|
||||
|
||||
return $set;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return Carbon|null
|
||||
@ -389,174 +209,6 @@ class CategoryRepository implements CategoryRepositoryInterface
|
||||
return $lastJournalDate;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param Collection $categories
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function periodExpenses(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): array
|
||||
{
|
||||
$carbonFormat = Navigation::preferredCarbonFormat($start, $end);
|
||||
$data = [];
|
||||
// prep data array:
|
||||
/** @var Category $category */
|
||||
foreach ($categories as $category) {
|
||||
$data[$category->id] = [
|
||||
'name' => $category->name,
|
||||
'sum' => '0',
|
||||
'entries' => [],
|
||||
];
|
||||
}
|
||||
|
||||
// get all transactions:
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
|
||||
$collector->setAccounts($accounts)->setRange($start, $end);
|
||||
$collector->setCategories($categories)->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER])
|
||||
->withAccountInformation()->withCategoryInformation();
|
||||
$journals = $collector->getExtractedJournals();
|
||||
|
||||
// loop transactions:
|
||||
|
||||
foreach ($journals as $journal) {
|
||||
$categoryId = (int)$journal['category_id'];
|
||||
$date = $journal['date']->format($carbonFormat);
|
||||
$data[$categoryId]['entries'][$date] = bcadd($data[$categoryId]['entries'][$date] ?? '0', $journal['amount']);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function periodExpensesNoCategory(Collection $accounts, Carbon $start, Carbon $end): array
|
||||
{
|
||||
$carbonFormat = Navigation::preferredCarbonFormat($start, $end);
|
||||
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
|
||||
$collector->setAccounts($accounts)->setRange($start, $end)->withAccountInformation();
|
||||
$collector->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER]);
|
||||
$collector->withoutCategory();
|
||||
$journals = $collector->getExtractedJournals();
|
||||
$result = [
|
||||
'entries' => [],
|
||||
'name' => (string)trans('firefly.no_category'),
|
||||
'sum' => '0',
|
||||
];
|
||||
|
||||
/** @var array $journal */
|
||||
foreach ($journals as $journal) {
|
||||
$date = $journal['date']->format($carbonFormat);
|
||||
|
||||
if (!isset($result['entries'][$date])) {
|
||||
$result['entries'][$date] = '0';
|
||||
}
|
||||
$result['entries'][$date] = bcadd($result['entries'][$date], $journal['amount']);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* TODO not multi currency aware.
|
||||
* @param Collection $categories
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function periodIncome(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): array
|
||||
{
|
||||
$carbonFormat = Navigation::preferredCarbonFormat($start, $end);
|
||||
$data = [];
|
||||
// prep data array:
|
||||
/** @var Category $category */
|
||||
foreach ($categories as $category) {
|
||||
$data[$category->id] = [
|
||||
'name' => $category->name,
|
||||
'sum' => '0',
|
||||
'entries' => [],
|
||||
];
|
||||
}
|
||||
|
||||
// get all transactions:
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
|
||||
$collector->setAccounts($accounts)->setRange($start, $end);
|
||||
$collector->setCategories($categories)->setTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER])
|
||||
->withAccountInformation();
|
||||
$journals = $collector->getExtractedJournals();
|
||||
|
||||
// loop transactions:
|
||||
/** @var array $journal */
|
||||
foreach ($journals as $journal) {
|
||||
$categoryId = (int)$journal['category_id'];
|
||||
$date = $journal['date']->format($carbonFormat);
|
||||
$data[$categoryId]['entries'][$date] = bcadd($data[$categoryId]['entries'][$date] ?? '0', bcmul($journal['amount'],'-1'));
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function periodIncomeNoCategory(Collection $accounts, Carbon $start, Carbon $end): array
|
||||
{
|
||||
Log::debug('Now in periodIncomeNoCategory()');
|
||||
$carbonFormat = Navigation::preferredCarbonFormat($start, $end);
|
||||
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
|
||||
$collector->setAccounts($accounts)->setRange($start, $end)->withAccountInformation();
|
||||
$collector->setTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER]);
|
||||
$collector->withoutCategory();
|
||||
$journals = $collector->getExtractedJournals();
|
||||
$result = [
|
||||
'entries' => [],
|
||||
'name' => (string)trans('firefly.no_category'),
|
||||
'sum' => '0',
|
||||
];
|
||||
Log::debug('Looping transactions..');
|
||||
|
||||
foreach ($journals as $journal) {
|
||||
$date = $journal['date']->format($carbonFormat);
|
||||
|
||||
if (!isset($result['entries'][$date])) {
|
||||
$result['entries'][$date] = '0';
|
||||
}
|
||||
$result['entries'][$date] = bcadd($result['entries'][$date], bcmul($journal['amount'],'-1'));
|
||||
}
|
||||
Log::debug('Done looping transactions..');
|
||||
Log::debug('Finished periodIncomeNoCategory()');
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $query
|
||||
*
|
||||
@ -581,166 +233,22 @@ class CategoryRepository implements CategoryRepositoryInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the amount spent in a category, for a set of accounts, in a specific period.
|
||||
* @param array $data
|
||||
*
|
||||
* @param Category $category
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
* @return Category
|
||||
*/
|
||||
public function spentInPeriod(Category $category, Collection $accounts, Carbon $start, Carbon $end): array
|
||||
public function store(array $data): Category
|
||||
{
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setUser($this->user);
|
||||
$collector->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL])->setCategory($category);
|
||||
/** @var CategoryFactory $factory */
|
||||
$factory = app(CategoryFactory::class);
|
||||
$factory->setUser($this->user);
|
||||
|
||||
if ($accounts->count() > 0) {
|
||||
$collector->setAccounts($accounts);
|
||||
}
|
||||
// collect and group results:
|
||||
$array = $collector->getExtractedJournals();
|
||||
$return = [];
|
||||
|
||||
foreach ($array as $journal) {
|
||||
$currencyCode = $journal['currency_code'];
|
||||
if (!isset($return[$currencyCode])) {
|
||||
$return[$currencyCode] = [
|
||||
'currency_id' => $journal['currency_id'],
|
||||
'currency_code' => $journal['currency_code'],
|
||||
'currency_name' => $journal['currency_name'],
|
||||
'currency_symbol' => $journal['currency_symbol'],
|
||||
'currency_decimal_places' => $journal['currency_decimal_places'],
|
||||
'spent' => '0',
|
||||
];
|
||||
}
|
||||
|
||||
// also extract foreign currency information:
|
||||
if (null !== $journal['foreign_currency_id']) {
|
||||
$currencyCode = $journal['foreign_currency_code'];
|
||||
if (!isset($return[$currencyCode])) {
|
||||
$return[$currencyCode] = [
|
||||
'currency_id' => $journal['foreign_currency_id'],
|
||||
'currency_code' => $journal['foreign_currency_code'],
|
||||
'currency_name' => $journal['foreign_currency_name'],
|
||||
'currency_symbol' => $journal['foreign_currency_symbol'],
|
||||
'currency_decimal_places' => $journal['foreign_currency_decimal_places'],
|
||||
'spent' => '0',
|
||||
];
|
||||
}
|
||||
$return[$currencyCode]['spent'] = bcadd($return[$currencyCode]['spent'], $journal['foreign_amount']);
|
||||
}
|
||||
$return[$currencyCode]['spent'] = bcadd($return[$currencyCode]['spent'], $journal['amount']);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* A very cryptic method name that means:
|
||||
*
|
||||
* Get me the amount spent in this period, grouped per currency, where no category was set.
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function spentInPeriodPcWoCategory(Collection $accounts, Carbon $start, Carbon $end): array
|
||||
{
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
|
||||
$collector->setUser($this->user);
|
||||
$collector->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL])->withoutCategory();
|
||||
|
||||
if ($accounts->count() > 0) {
|
||||
$collector->setAccounts($accounts);
|
||||
}
|
||||
|
||||
$set = $collector->getExtractedJournals();
|
||||
$return = [];
|
||||
/** @var array $journal */
|
||||
foreach ($set as $journal) {
|
||||
$currencyId = (int)$journal['currency_id'];
|
||||
if (!isset($return[$currencyId])) {
|
||||
$return[$currencyId] = [
|
||||
'spent' => '0',
|
||||
'currency_id' => $currencyId,
|
||||
'currency_symbol' => $journal['currency_symbol'],
|
||||
'currency_code' => $journal['currency_code'],
|
||||
'currency_decimal_places' => $journal['currency_decimal_places'],
|
||||
];
|
||||
}
|
||||
$return[$currencyId]['spent'] = bcadd($return[$currencyId]['spent'], $journal['amount']);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $categories
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function spentInPeriodPerCurrency(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): array
|
||||
{
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setUser($this->user);
|
||||
$collector->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL]);
|
||||
|
||||
if ($categories->count() > 0) {
|
||||
$collector->setCategories($categories);
|
||||
}
|
||||
if (0 === $categories->count()) {
|
||||
$collector->setCategories($this->getCategories());
|
||||
}
|
||||
|
||||
if ($accounts->count() > 0) {
|
||||
$collector->setAccounts($accounts);
|
||||
}
|
||||
|
||||
$set = $collector->getExtractedJournals();
|
||||
$return = [];
|
||||
/** @var array $journal */
|
||||
foreach ($set as $journal) {
|
||||
$categoryId = (int)$journal['category_id'];
|
||||
$currencyId = (int)$journal['currency_id'];
|
||||
$name = $journal['category_name'];
|
||||
|
||||
// make array for category:
|
||||
if (!isset($return[$categoryId])) {
|
||||
$return[$categoryId] = [
|
||||
'name' => $name,
|
||||
'spent' => [],
|
||||
];
|
||||
}
|
||||
if (!isset($return[$categoryId]['spent'][$currencyId])) {
|
||||
$return[$categoryId]['spent'][$currencyId] = [
|
||||
'spent' => '0',
|
||||
'currency_id' => $currencyId,
|
||||
'currency_symbol' => $journal['currency_symbol'],
|
||||
'currency_code' => $journal['currency_code'],
|
||||
'currency_decimal_places' => $journal['currency_decimal_places'],
|
||||
];
|
||||
}
|
||||
$return[$categoryId]['spent'][$currencyId]['spent']
|
||||
= bcadd($return[$categoryId]['spent'][$currencyId]['spent'], $journal['amount']);
|
||||
}
|
||||
|
||||
return $return;
|
||||
return $factory->findOrCreate(null, $data['name']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
* @param array $data
|
||||
* @param array $data
|
||||
*
|
||||
* @return Category
|
||||
*/
|
||||
@ -752,25 +260,6 @@ class CategoryRepository implements CategoryRepositoryInterface
|
||||
return $service->update($category, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO does not take currencies into account.
|
||||
*
|
||||
* @param array $journals
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function sumJournals(array $journals): string
|
||||
{
|
||||
$sum = '0';
|
||||
/** @var array $journal */
|
||||
foreach ($journals as $journal) {
|
||||
$amount = (string)$journal['amount'];
|
||||
$sum = bcadd($sum, $amount);
|
||||
}
|
||||
|
||||
return $sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
*
|
||||
@ -809,7 +298,7 @@ class CategoryRepository implements CategoryRepositoryInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
* @param Category $category
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return Carbon|null
|
||||
@ -833,7 +322,7 @@ class CategoryRepository implements CategoryRepositoryInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
* @param Category $category
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return Carbon|null
|
||||
@ -857,4 +346,5 @@ class CategoryRepository implements CategoryRepositoryInterface
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -33,14 +33,6 @@ use Illuminate\Support\Collection;
|
||||
interface CategoryRepositoryInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param int|null $categoryId
|
||||
* @param string|null $categoryName
|
||||
*
|
||||
* @return Category|null
|
||||
*/
|
||||
public function findCategory( ?int $categoryId, ?string $categoryName): ?Category;
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
*
|
||||
@ -48,41 +40,6 @@ interface CategoryRepositoryInterface
|
||||
*/
|
||||
public function destroy(Category $category): bool;
|
||||
|
||||
/**
|
||||
* Returns the amount earned in a category, for a set of accounts, in a specific period.
|
||||
*
|
||||
* @param Category $category
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function earnedInPeriod(Category $category, Collection $accounts, Carbon $start, Carbon $end): array;
|
||||
|
||||
/**
|
||||
* A very cryptic method name that means:
|
||||
*
|
||||
* Get me the amount earned in this period, grouped per currency, where no category was set.
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function earnedInPeriodPcWoCategory(Collection $accounts, Carbon $start, Carbon $end): array;
|
||||
|
||||
/**
|
||||
* @param Collection $categories
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function earnedInPeriodPerCurrency(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): array;
|
||||
|
||||
/**
|
||||
* Find a category.
|
||||
*
|
||||
@ -92,6 +49,14 @@ interface CategoryRepositoryInterface
|
||||
*/
|
||||
public function findByName(string $name): ?Category;
|
||||
|
||||
/**
|
||||
* @param int|null $categoryId
|
||||
* @param string|null $categoryName
|
||||
*
|
||||
* @return Category|null
|
||||
*/
|
||||
public function findCategory(?int $categoryId, ?string $categoryName): ?Category;
|
||||
|
||||
/**
|
||||
* Find a category or return NULL
|
||||
*
|
||||
@ -124,8 +89,6 @@ interface CategoryRepositoryInterface
|
||||
*/
|
||||
public function getCategories(): Collection;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return most recent transaction(journal) date or null when never used before.
|
||||
*
|
||||
@ -136,52 +99,6 @@ interface CategoryRepositoryInterface
|
||||
*/
|
||||
public function lastUseDate(Category $category, Collection $accounts): ?Carbon;
|
||||
|
||||
/**
|
||||
* TODO not multi-currency
|
||||
* @param Collection $categories
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function periodExpenses(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): array;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* TODO not multi-currency
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function periodExpensesNoCategory(Collection $accounts, Carbon $start, Carbon $end): array;
|
||||
|
||||
/**
|
||||
* TODO not multi-currency
|
||||
* @param Collection $categories
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function periodIncome(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): array;
|
||||
|
||||
/**
|
||||
* TODO not multi-currency
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function periodIncomeNoCategory(Collection $accounts, Carbon $start, Carbon $end): array;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param string $query
|
||||
*
|
||||
@ -189,48 +106,11 @@ interface CategoryRepositoryInterface
|
||||
*/
|
||||
public function searchCategory(string $query): Collection;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
*/
|
||||
public function setUser(User $user);
|
||||
|
||||
/**
|
||||
* Returns the amount spent in a category, for a set of accounts, in a specific period.
|
||||
*
|
||||
* @param Category $category
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function spentInPeriod(Category $category, Collection $accounts, Carbon $start, Carbon $end): array;
|
||||
|
||||
/**
|
||||
* A very cryptic method name that means:
|
||||
*
|
||||
* Get me the amount spent in this period, grouped per currency, where no category was set.
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function spentInPeriodPcWoCategory(Collection $accounts, Carbon $start, Carbon $end): array;
|
||||
|
||||
/**
|
||||
* @param Collection $categories
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function spentInPeriodPerCurrency(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): array;
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
|
228
app/Repositories/Category/NoCategoryRepository.php
Normal file
228
app/Repositories/Category/NoCategoryRepository.php
Normal file
@ -0,0 +1,228 @@
|
||||
<?php
|
||||
/**
|
||||
* NoCategoryRepository.php
|
||||
* Copyright (c) 2019 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Repositories\Category;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class NoCategoryRepository
|
||||
*/
|
||||
class NoCategoryRepository implements NoCategoryRepositoryInterface
|
||||
{
|
||||
/** @var User */
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if ('testing' === config('app.env')) {
|
||||
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
*/
|
||||
public function setUser(User $user): void
|
||||
{
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A very cryptic method name that means:
|
||||
*
|
||||
* Get me the amount earned in this period, grouped per currency, where no category was set.
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function earnedInPeriodPcWoCategory(Collection $accounts, Carbon $start, Carbon $end): array
|
||||
{
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
|
||||
$collector->setUser($this->user);
|
||||
$collector->setRange($start, $end)->setTypes([TransactionType::DEPOSIT])->withoutCategory();
|
||||
|
||||
if ($accounts->count() > 0) {
|
||||
$collector->setAccounts($accounts);
|
||||
}
|
||||
$journals = $collector->getExtractedJournals();
|
||||
$return = [];
|
||||
|
||||
foreach ($journals as $journal) {
|
||||
$currencyId = (int)$journal['currency_id'];
|
||||
if (!isset($return[$currencyId])) {
|
||||
$return[$currencyId] = [
|
||||
'earned' => '0',
|
||||
'currency_id' => $currencyId,
|
||||
'currency_symbol' => $journal['currency_symbol'],
|
||||
'currency_code' => $journal['currency_code'],
|
||||
'currency_decimal_places' => $journal['currency_decimal_places'],
|
||||
];
|
||||
}
|
||||
$return[$currencyId]['earned'] = bcadd($return[$currencyId]['earned'], $journal['amount']);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function periodExpensesNoCategory(Collection $accounts, Carbon $start, Carbon $end): array
|
||||
{
|
||||
$carbonFormat = Navigation::preferredCarbonFormat($start, $end);
|
||||
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
|
||||
$collector->setAccounts($accounts)->setRange($start, $end)->withAccountInformation();
|
||||
$collector->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER]);
|
||||
$collector->withoutCategory();
|
||||
$journals = $collector->getExtractedJournals();
|
||||
$result = [
|
||||
'entries' => [],
|
||||
'name' => (string)trans('firefly.no_category'),
|
||||
'sum' => '0',
|
||||
];
|
||||
|
||||
/** @var array $journal */
|
||||
foreach ($journals as $journal) {
|
||||
$date = $journal['date']->format($carbonFormat);
|
||||
|
||||
if (!isset($result['entries'][$date])) {
|
||||
$result['entries'][$date] = '0';
|
||||
}
|
||||
$result['entries'][$date] = bcadd($result['entries'][$date], $journal['amount']);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function periodIncomeNoCategory(Collection $accounts, Carbon $start, Carbon $end): array
|
||||
{
|
||||
Log::debug('Now in periodIncomeNoCategory()');
|
||||
$carbonFormat = Navigation::preferredCarbonFormat($start, $end);
|
||||
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
|
||||
$collector->setAccounts($accounts)->setRange($start, $end)->withAccountInformation();
|
||||
$collector->setTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER]);
|
||||
$collector->withoutCategory();
|
||||
$journals = $collector->getExtractedJournals();
|
||||
$result = [
|
||||
'entries' => [],
|
||||
'name' => (string)trans('firefly.no_category'),
|
||||
'sum' => '0',
|
||||
];
|
||||
Log::debug('Looping transactions..');
|
||||
|
||||
foreach ($journals as $journal) {
|
||||
$date = $journal['date']->format($carbonFormat);
|
||||
|
||||
if (!isset($result['entries'][$date])) {
|
||||
$result['entries'][$date] = '0';
|
||||
}
|
||||
$result['entries'][$date] = bcadd($result['entries'][$date], bcmul($journal['amount'],'-1'));
|
||||
}
|
||||
Log::debug('Done looping transactions..');
|
||||
Log::debug('Finished periodIncomeNoCategory()');
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A very cryptic method name that means:
|
||||
*
|
||||
* Get me the amount spent in this period, grouped per currency, where no category was set.
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function spentInPeriodPcWoCategory(Collection $accounts, Carbon $start, Carbon $end): array
|
||||
{
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
|
||||
$collector->setUser($this->user);
|
||||
$collector->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL])->withoutCategory();
|
||||
|
||||
if ($accounts->count() > 0) {
|
||||
$collector->setAccounts($accounts);
|
||||
}
|
||||
|
||||
$set = $collector->getExtractedJournals();
|
||||
$return = [];
|
||||
/** @var array $journal */
|
||||
foreach ($set as $journal) {
|
||||
$currencyId = (int)$journal['currency_id'];
|
||||
if (!isset($return[$currencyId])) {
|
||||
$return[$currencyId] = [
|
||||
'spent' => '0',
|
||||
'currency_id' => $currencyId,
|
||||
'currency_symbol' => $journal['currency_symbol'],
|
||||
'currency_code' => $journal['currency_code'],
|
||||
'currency_decimal_places' => $journal['currency_decimal_places'],
|
||||
];
|
||||
}
|
||||
$return[$currencyId]['spent'] = bcadd($return[$currencyId]['spent'], $journal['amount']);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
}
|
99
app/Repositories/Category/NoCategoryRepositoryInterface.php
Normal file
99
app/Repositories/Category/NoCategoryRepositoryInterface.php
Normal file
@ -0,0 +1,99 @@
|
||||
<?php
|
||||
/**
|
||||
* NoCategoryRepositoryInterface.php
|
||||
* Copyright (c) 2019 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Repositories\Category;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface NoCategoryRepositoryInterface
|
||||
*
|
||||
* @package FireflyIII\Repositories\Category
|
||||
*/
|
||||
interface NoCategoryRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* @param User $user
|
||||
*/
|
||||
public function setUser(User $user): void;
|
||||
|
||||
/**
|
||||
* A very cryptic method name that means:
|
||||
*
|
||||
* Get me the amount earned in this period, grouped per currency, where no category was set.
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
* @deprecated
|
||||
*/
|
||||
public function earnedInPeriodPcWoCategory(Collection $accounts, Carbon $start, Carbon $end): array;
|
||||
|
||||
|
||||
/**
|
||||
* TODO not multi-currency
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
* @deprecated
|
||||
*/
|
||||
public function periodExpensesNoCategory(Collection $accounts, Carbon $start, Carbon $end): array;
|
||||
|
||||
|
||||
/**
|
||||
* TODO not multi-currency
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
* @deprecated
|
||||
*/
|
||||
public function periodIncomeNoCategory(Collection $accounts, Carbon $start, Carbon $end): array;
|
||||
|
||||
/**
|
||||
* A very cryptic method name that means:
|
||||
*
|
||||
* Get me the amount spent in this period, grouped per currency, where no category was set.
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
* @deprecated
|
||||
*
|
||||
*/
|
||||
public function spentInPeriodPcWoCategory(Collection $accounts, Carbon $start, Carbon $end): array;
|
||||
|
||||
|
||||
}
|
375
app/Repositories/Category/OperationsRepository.php
Normal file
375
app/Repositories/Category/OperationsRepository.php
Normal file
@ -0,0 +1,375 @@
|
||||
<?php
|
||||
/**
|
||||
* OperationsRepository.php
|
||||
* Copyright (c) 2019 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Repositories\Category;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class OperationsRepository
|
||||
*/
|
||||
class OperationsRepository implements OperationsRepositoryInterface
|
||||
{
|
||||
/** @var User */
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if ('testing' === config('app.env')) {
|
||||
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function earnedInPeriod(Category $category, Collection $accounts, Carbon $start, Carbon $end): array
|
||||
{
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
|
||||
|
||||
$collector->setUser($this->user);
|
||||
$collector->setRange($start, $end)->setTypes([TransactionType::DEPOSIT])->setCategory($category);
|
||||
|
||||
if ($accounts->count() > 0) {
|
||||
$collector->setAccounts($accounts);
|
||||
}
|
||||
// collect and group results:
|
||||
$array = $collector->getExtractedJournals();
|
||||
$return = [];
|
||||
|
||||
foreach ($array as $journal) {
|
||||
$currencyCode = $journal['currency_code'];
|
||||
if (!isset($return[$currencyCode])) {
|
||||
$return[$currencyCode] = [
|
||||
'currency_id' => $journal['currency_id'],
|
||||
'currency_code' => $journal['currency_code'],
|
||||
'currency_name' => $journal['currency_name'],
|
||||
'currency_symbol' => $journal['currency_symbol'],
|
||||
'currency_decimal_places' => $journal['currency_decimal_places'],
|
||||
'earned' => '0',
|
||||
];
|
||||
}
|
||||
|
||||
// also extract foreign currency information:
|
||||
if (null !== $journal['foreign_currency_id']) {
|
||||
$currencyCode = $journal['foreign_currency_code'];
|
||||
if (!isset($return[$currencyCode])) {
|
||||
$return[$currencyCode] = [
|
||||
'currency_id' => $journal['foreign_currency_id'],
|
||||
'currency_code' => $journal['foreign_currency_code'],
|
||||
'currency_name' => $journal['foreign_currency_name'],
|
||||
'currency_symbol' => $journal['foreign_currency_symbol'],
|
||||
'currency_decimal_places' => $journal['foreign_currency_decimal_places'],
|
||||
'earned' => '0',
|
||||
];
|
||||
}
|
||||
$return[$currencyCode]['earned'] = bcadd($return[$currencyCode]['earned'], app('steam')->positive($journal['foreign_amount']));
|
||||
}
|
||||
$return[$currencyCode]['earned'] = bcadd($return[$currencyCode]['earned'], app('steam')->positive($journal['amount']));
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $categories
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function earnedInPeriodPerCurrency(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): array
|
||||
{
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
|
||||
$collector->setUser($this->user);
|
||||
$collector->setRange($start, $end)->setTypes([TransactionType::DEPOSIT]);
|
||||
|
||||
if ($categories->count() > 0) {
|
||||
$collector->setCategories($categories);
|
||||
}
|
||||
if (0 === $categories->count()) {
|
||||
$collector->setCategories($this->getCategories());
|
||||
}
|
||||
|
||||
if ($accounts->count() > 0) {
|
||||
$collector->setAccounts($accounts);
|
||||
}
|
||||
$journals = $collector->getExtractedJournals();
|
||||
$return = [];
|
||||
foreach ($journals as $journal) {
|
||||
$categoryId = (int)$journal['category_id'];
|
||||
$currencyId = (int)$journal['currency_id'];
|
||||
$name = $journal['category_name'];
|
||||
// make array for category:
|
||||
if (!isset($return[$categoryId])) {
|
||||
$return[$categoryId] = [
|
||||
'name' => $name,
|
||||
'earned' => [],
|
||||
];
|
||||
}
|
||||
if (!isset($return[$categoryId]['earned'][$currencyId])) {
|
||||
$return[$categoryId]['earned'][$currencyId] = [
|
||||
'earned' => '0',
|
||||
'currency_id' => $currencyId,
|
||||
'currency_symbol' => $journal['currency_symbol'],
|
||||
'currency_code' => $journal['currency_code'],
|
||||
'currency_decimal_places' => $journal['currency_decimal_places'],
|
||||
];
|
||||
}
|
||||
$return[$categoryId]['earned'][$currencyId]['earned']
|
||||
= bcadd($return[$categoryId]['earned'][$currencyId]['earned'], $journal['amount']);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $categories
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function periodExpenses(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): array
|
||||
{
|
||||
$carbonFormat = Navigation::preferredCarbonFormat($start, $end);
|
||||
$data = [];
|
||||
// prep data array:
|
||||
/** @var Category $category */
|
||||
foreach ($categories as $category) {
|
||||
$data[$category->id] = [
|
||||
'name' => $category->name,
|
||||
'sum' => '0',
|
||||
'entries' => [],
|
||||
];
|
||||
}
|
||||
|
||||
// get all transactions:
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
|
||||
$collector->setAccounts($accounts)->setRange($start, $end);
|
||||
$collector->setCategories($categories)->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER])
|
||||
->withAccountInformation()->withCategoryInformation();
|
||||
$journals = $collector->getExtractedJournals();
|
||||
|
||||
// loop transactions:
|
||||
|
||||
foreach ($journals as $journal) {
|
||||
$categoryId = (int)$journal['category_id'];
|
||||
$date = $journal['date']->format($carbonFormat);
|
||||
$data[$categoryId]['entries'][$date] = bcadd($data[$categoryId]['entries'][$date] ?? '0', $journal['amount']);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO not multi currency aware.
|
||||
*
|
||||
* @param Collection $categories
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function periodIncome(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): array
|
||||
{
|
||||
$carbonFormat = Navigation::preferredCarbonFormat($start, $end);
|
||||
$data = [];
|
||||
// prep data array:
|
||||
/** @var Category $category */
|
||||
foreach ($categories as $category) {
|
||||
$data[$category->id] = [
|
||||
'name' => $category->name,
|
||||
'sum' => '0',
|
||||
'entries' => [],
|
||||
];
|
||||
}
|
||||
|
||||
// get all transactions:
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
|
||||
$collector->setAccounts($accounts)->setRange($start, $end);
|
||||
$collector->setCategories($categories)->setTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER])
|
||||
->withAccountInformation();
|
||||
$journals = $collector->getExtractedJournals();
|
||||
|
||||
// loop transactions:
|
||||
/** @var array $journal */
|
||||
foreach ($journals as $journal) {
|
||||
$categoryId = (int)$journal['category_id'];
|
||||
$date = $journal['date']->format($carbonFormat);
|
||||
$data[$categoryId]['entries'][$date] = bcadd($data[$categoryId]['entries'][$date] ?? '0', bcmul($journal['amount'], '-1'));
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
*/
|
||||
public function setUser(User $user): void
|
||||
{
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the amount spent in a category, for a set of accounts, in a specific period.
|
||||
*
|
||||
* @param Category $category
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function spentInPeriod(Category $category, Collection $accounts, Carbon $start, Carbon $end): array
|
||||
{
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setUser($this->user);
|
||||
$collector->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL])->setCategory($category);
|
||||
|
||||
if ($accounts->count() > 0) {
|
||||
$collector->setAccounts($accounts);
|
||||
}
|
||||
// collect and group results:
|
||||
$array = $collector->getExtractedJournals();
|
||||
$return = [];
|
||||
|
||||
foreach ($array as $journal) {
|
||||
$currencyCode = $journal['currency_code'];
|
||||
if (!isset($return[$currencyCode])) {
|
||||
$return[$currencyCode] = [
|
||||
'currency_id' => $journal['currency_id'],
|
||||
'currency_code' => $journal['currency_code'],
|
||||
'currency_name' => $journal['currency_name'],
|
||||
'currency_symbol' => $journal['currency_symbol'],
|
||||
'currency_decimal_places' => $journal['currency_decimal_places'],
|
||||
'spent' => '0',
|
||||
];
|
||||
}
|
||||
|
||||
// also extract foreign currency information:
|
||||
if (null !== $journal['foreign_currency_id']) {
|
||||
$currencyCode = $journal['foreign_currency_code'];
|
||||
if (!isset($return[$currencyCode])) {
|
||||
$return[$currencyCode] = [
|
||||
'currency_id' => $journal['foreign_currency_id'],
|
||||
'currency_code' => $journal['foreign_currency_code'],
|
||||
'currency_name' => $journal['foreign_currency_name'],
|
||||
'currency_symbol' => $journal['foreign_currency_symbol'],
|
||||
'currency_decimal_places' => $journal['foreign_currency_decimal_places'],
|
||||
'spent' => '0',
|
||||
];
|
||||
}
|
||||
$return[$currencyCode]['spent'] = bcadd($return[$currencyCode]['spent'], $journal['foreign_amount']);
|
||||
}
|
||||
$return[$currencyCode]['spent'] = bcadd($return[$currencyCode]['spent'], $journal['amount']);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $categories
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function spentInPeriodPerCurrency(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): array
|
||||
{
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setUser($this->user);
|
||||
$collector->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL]);
|
||||
|
||||
if ($categories->count() > 0) {
|
||||
$collector->setCategories($categories);
|
||||
}
|
||||
if (0 === $categories->count()) {
|
||||
$collector->setCategories($this->getCategories());
|
||||
}
|
||||
|
||||
if ($accounts->count() > 0) {
|
||||
$collector->setAccounts($accounts);
|
||||
}
|
||||
|
||||
$set = $collector->getExtractedJournals();
|
||||
$return = [];
|
||||
/** @var array $journal */
|
||||
foreach ($set as $journal) {
|
||||
$categoryId = (int)$journal['category_id'];
|
||||
$currencyId = (int)$journal['currency_id'];
|
||||
$name = $journal['category_name'];
|
||||
|
||||
// make array for category:
|
||||
if (!isset($return[$categoryId])) {
|
||||
$return[$categoryId] = [
|
||||
'name' => $name,
|
||||
'spent' => [],
|
||||
];
|
||||
}
|
||||
if (!isset($return[$categoryId]['spent'][$currencyId])) {
|
||||
$return[$categoryId]['spent'][$currencyId] = [
|
||||
'spent' => '0',
|
||||
'currency_id' => $currencyId,
|
||||
'currency_symbol' => $journal['currency_symbol'],
|
||||
'currency_code' => $journal['currency_code'],
|
||||
'currency_decimal_places' => $journal['currency_decimal_places'],
|
||||
];
|
||||
}
|
||||
$return[$categoryId]['spent'][$currencyId]['spent']
|
||||
= bcadd($return[$categoryId]['spent'][$currencyId]['spent'], $journal['amount']);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
}
|
114
app/Repositories/Category/OperationsRepositoryInterface.php
Normal file
114
app/Repositories/Category/OperationsRepositoryInterface.php
Normal file
@ -0,0 +1,114 @@
|
||||
<?php
|
||||
/**
|
||||
* OperationsRepositoryInterface.php
|
||||
* Copyright (c) 2019 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Repositories\Category;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface OperationsRepositoryInterface
|
||||
*
|
||||
* @package FireflyIII\Repositories\Category
|
||||
*/
|
||||
interface OperationsRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* Returns the amount earned in a category, for a set of accounts, in a specific period.
|
||||
*
|
||||
* @param Category $category
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
* @deprecated
|
||||
*
|
||||
*/
|
||||
public function earnedInPeriod(Category $category, Collection $accounts, Carbon $start, Carbon $end): array;
|
||||
|
||||
/**
|
||||
* @param Collection $categories
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
* @deprecated
|
||||
*/
|
||||
public function earnedInPeriodPerCurrency(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): array;
|
||||
|
||||
/**
|
||||
* @param Collection $categories
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
* @deprecated
|
||||
*/
|
||||
public function periodExpenses(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): array;
|
||||
|
||||
/**
|
||||
* @param Collection $categories
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
* @deprecated
|
||||
*/
|
||||
public function periodIncome(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): array;
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
*/
|
||||
public function setUser(User $user): void;
|
||||
|
||||
/**
|
||||
* Returns the amount spent in a category, for a set of accounts, in a specific period.
|
||||
*
|
||||
* @param Category $category
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
* @deprecated
|
||||
*
|
||||
*/
|
||||
public function spentInPeriod(Category $category, Collection $accounts, Carbon $start, Carbon $end): array;
|
||||
|
||||
/**
|
||||
* @param Collection $categories
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
* @deprecated
|
||||
*/
|
||||
public function spentInPeriodPerCurrency(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): array;
|
||||
}
|
@ -27,6 +27,7 @@ use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||
use FireflyIII\Repositories\Category\OperationsRepositoryInterface;
|
||||
|
||||
/**
|
||||
* Class WholePeriodChartGenerator
|
||||
@ -45,6 +46,9 @@ class WholePeriodChartGenerator
|
||||
/** @var CategoryRepositoryInterface $repository */
|
||||
$repository = app(CategoryRepositoryInterface::class);
|
||||
|
||||
/** @var OperationsRepositoryInterface $opsRepository */
|
||||
$opsRepository = app(OperationsRepositoryInterface::class);
|
||||
|
||||
/** @var AccountRepositoryInterface $accountRepository */
|
||||
$accountRepository = app(AccountRepositoryInterface::class);
|
||||
|
||||
@ -61,8 +65,8 @@ class WholePeriodChartGenerator
|
||||
while ($current <= $end) {
|
||||
$key = $current->format('Y-m-d');
|
||||
$currentEnd = app('navigation')->endOfPeriod($current, $step);
|
||||
$spent[$key] = $repository->spentInPeriod($category, $accounts, $current, $currentEnd);
|
||||
$earned[$key] = $repository->earnedInPeriod($category, $accounts, $current, $currentEnd);
|
||||
$spent[$key] = $opsRepository->spentInPeriod($category, $accounts, $current, $currentEnd);
|
||||
$earned[$key] = $opsRepository->earnedInPeriod($category, $accounts, $current, $currentEnd);
|
||||
$current = app('navigation')->addPeriod($current, $step, 0);
|
||||
}
|
||||
$currencies = $this->extractCurrencies($spent) + $this->extractCurrencies($earned);
|
||||
|
@ -26,6 +26,7 @@ namespace FireflyIII\Transformers;
|
||||
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||
use FireflyIII\Repositories\Category\OperationsRepositoryInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
|
||||
@ -34,6 +35,8 @@ use Log;
|
||||
*/
|
||||
class CategoryTransformer extends AbstractTransformer
|
||||
{
|
||||
/** @var OperationsRepositoryInterface */
|
||||
private $opsRepository;
|
||||
/** @var CategoryRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
@ -44,7 +47,8 @@ class CategoryTransformer extends AbstractTransformer
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->repository = app(CategoryRepositoryInterface::class);
|
||||
$this->repository = app(CategoryRepositoryInterface::class);
|
||||
$this->opsRepository = app(OperationsRepositoryInterface::class);
|
||||
if ('testing' === config('app.env')) {
|
||||
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
|
||||
}
|
||||
@ -60,13 +64,15 @@ class CategoryTransformer extends AbstractTransformer
|
||||
public function transform(Category $category): array
|
||||
{
|
||||
$this->repository->setUser($category->user);
|
||||
$this->opsRepository->setUser($category->user);
|
||||
|
||||
$spent = [];
|
||||
$earned = [];
|
||||
$start = $this->parameters->get('start');
|
||||
$end = $this->parameters->get('end');
|
||||
if (null !== $start && null !== $end) {
|
||||
$earned = array_values($this->repository->earnedInPeriod($category, new Collection, $start, $end));
|
||||
$spent = array_values($this->repository->spentInPeriod($category, new Collection, $start, $end));
|
||||
$earned = array_values($this->opsRepository->earnedInPeriod($category, new Collection, $start, $end));
|
||||
$spent = array_values($this->opsRepository->spentInPeriod($category, new Collection, $start, $end));
|
||||
}
|
||||
$data = [
|
||||
'id' => (int)$category->id,
|
||||
|
Loading…
Reference in New Issue
Block a user