<commit_before><?php
/**
 * BillController.php
 * Copyright (c) 2019 <EMAIL>
 *
 * 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/>.
 */
declare(strict_types=1);

namespace FireflyIII\Http\Controllers\Chart;

use Carbon\Carbon;
use FireflyIII\Generator\Chart\Basic\GeneratorInterface;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Models\Bill;
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\CacheProperties;
use Illuminate\Http\JsonResponse;
use JsonException;

/**
 * Class BillController.
 */
class BillController extends Controller
{
    /** @var GeneratorInterface Chart generation methods. */
    protected $generator;

    /**
     * BillController constructor.
     *
     * @codeCoverageIgnore
     */
    public function __construct()
    {
        parent::__construct();
        $this->generator = app(GeneratorInterface::class);
    }

    /**
     * Shows all bills and whether or not they've been paid this month (pie chart).
     *
     * @param BillRepositoryInterface $repository
     *
     * @return JsonResponse
     */
    public function frontpage(BillRepositoryInterface $repository): JsonResponse
    {
        $start = session('start', Carbon::now()->startOfMonth());
        $end   = session('end', Carbon::now()->endOfMonth());
        $cache = new CacheProperties;
        $cache->addProperty($start);
        $cache->addProperty($end);
        $cache->addProperty('chart.bill.frontpage');
        if ($cache->has()) {
            return response()->json($cache->get());
        }
        /** @var CurrencyRepositoryInterface $currencyRepository */
        $currencyRepository = app(CurrencyRepositoryInterface::class);

        $chartData  = [];
        $currencies = [];
        $paid       = $repository->getBillsPaidInRangePerCurrency($start, $end);   // will be a negative amount.
        $unpaid     = $repository->getBillsUnpaidInRangePerCurrency($start, $end); // will be a positive amount.

        foreach ($paid as $currencyId => $amount) {
            $currencies[$currencyId] = $currencies[$currencyId] ?? $currencyRepository->find($currencyId);
            $label                   = (string) trans('firefly.paid_in_currency', ['currency' => $currencies[$currencyId]->name]);
            $chartData[$label]       = ['amount'        => $amount, 'currency_symbol' => $currencies[$currencyId]->symbol,
                                        'currency_code' => $currencies[$currencyId]->code];
        }
        foreach ($unpaid as $currencyId => $amount) {
            $currencies[$currencyId] = $currencies[$currencyId] ?? $currencyRepository->find($currencyId);
            $label                   = (string) trans('firefly.unpaid_in_currency', ['currency' => $currencies[$currencyId]->name]);
            $chartData[$label]       = ['amount'        => $amount, 'currency_symbol' => $currencies[$currencyId]->symbol,
                                        'currency_code' => $currencies[$currencyId]->code];
        }

        $data = $this->generator->multiCurrencyPieChart($chartData);
        $cache->store($data);

        return response()->json($data);
    }

    /**
     * Shows overview for a single bill.
     *
     * @param Bill $bill
     *
     * @return JsonResponse
     * @throws \FireflyIII\Exceptions\FireflyException
     */
    public function single(Bill $bill): JsonResponse
    {
        $cache = new CacheProperties;
        $cache->addProperty('chart.bill.single');
        $cache->addProperty($bill->id);
        if ($cache->has()) {
            return response()->json($cache->get());
        }
        $locale = app('steam')->getLocale();

        /** @var GroupCollectorInterface $collector */
        $collector = app(GroupCollectorInterface::class);
        $journals  = $collector->setBill($bill)->getExtractedJournals();

        // sort the other way around:
        usort(
            $journals,
            static function (array $left, array $right) {
                if ($left['date']->gt($right['date'])) {
                    return 1;
                }
                if ($left['date']->lt($right['date'])) {
                    return -1;
                }

                return 0;
            }
        );

        $chartData = [
            ['type'          => 'line', 'label' => (string) trans('firefly.min-amount'), 'currency_symbol' => $bill->transactionCurrency->symbol,
             'currency_code' => $bill->transactionCurrency->code, 'entries' => []],
            ['type'          => 'line', 'label' => (string) trans('firefly.max-amount'), 'currency_symbol' => $bill->transactionCurrency->symbol,
             'currency_code' => $bill->transactionCurrency->code, 'entries' => []],
            ['type'          => 'bar', 'label' => (string) trans('firefly.journal-amount'), 'currency_symbol' => $bill->transactionCurrency->symbol,
             'currency_code' => $bill->transactionCurrency->code, 'entries' => []],
        ];

        foreach ($journals as $journal) {
            $date                           = $journal['date']->isoFormat((string) trans('config.month_and_day_js', [], $locale));
            $chartData[0]['entries'][$date] = $bill->amount_min; // minimum amount of bill
            $chartData[1]['entries'][$date] = $bill->amount_max; // maximum amount of bill

            // append amount because there are more than one per moment:
            if (!array_key_exists($date, $chartData[2]['entries'])) {
                $chartData[2]['entries'][$date] = '0';
            }
            $amount                         = bcmul($journal['amount'], '-1');
            $chartData[2]['entries'][$date] = bcadd($chartData[2]['entries'][$date], $amount);  // amount of journal
        }

        $data = $this->generator->multiSet($chartData);
        $cache->store($data);

        return response()->json($data);
    }
}<commit_msg>Fix #6556<commit_after><?php
/**
 * BillController.php
 * Copyright (c) 2019 <EMAIL>
 *
 * 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/>.
 */
declare(strict_types=1);

namespace FireflyIII\Http\Controllers\Chart;

use Carbon\Carbon;
use FireflyIII\Generator\Chart\Basic\GeneratorInterface;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Models\Bill;
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\CacheProperties;
use Illuminate\Http\JsonResponse;

/**
 * Class BillController.
 */
class BillController extends Controller
{
    /** @var GeneratorInterface Chart generation methods. */
    protected $generator;

    /**
     * BillController constructor.
     *
     * @codeCoverageIgnore
     */
    public function __construct()
    {
        parent::__construct();
        $this->generator = app(GeneratorInterface::class);
    }

    /**
     * Shows all bills and whether or not they've been paid this month (pie chart).
     *
     * @param BillRepositoryInterface $repository
     *
     * @return JsonResponse
     */
    public function frontpage(BillRepositoryInterface $repository): JsonResponse
    {
        $start = session('start', Carbon::now()->startOfMonth());
        $end   = session('end', Carbon::now()->endOfMonth());
        $cache = new CacheProperties;
        $cache->addProperty($start);
        $cache->addProperty($end);
        $cache->addProperty('chart.bill.frontpage');
        if ($cache->has()) {
            return response()->json($cache->get());
        }
        /** @var CurrencyRepositoryInterface $currencyRepository */
        $currencyRepository = app(CurrencyRepositoryInterface::class);

        $chartData  = [];
        $currencies = [];
        $paid       = $repository->getBillsPaidInRangePerCurrency($start, $end);   // will be a negative amount.
        $unpaid     = $repository->getBillsUnpaidInRangePerCurrency($start, $end); // will be a positive amount.

        foreach ($paid as $currencyId => $amount) {
            $currencies[$currencyId] = $currencies[$currencyId] ?? $currencyRepository->find($currencyId);
            $label                   = (string) trans('firefly.paid_in_currency', ['currency' => $currencies[$currencyId]->name]);
            $chartData[$label]       = ['amount'        => $amount, 'currency_symbol' => $currencies[$currencyId]->symbol,
                                        'currency_code' => $currencies[$currencyId]->code];
        }
        foreach ($unpaid as $currencyId => $amount) {
            $currencies[$currencyId] = $currencies[$currencyId] ?? $currencyRepository->find($currencyId);
            $label                   = (string) trans('firefly.unpaid_in_currency', ['currency' => $currencies[$currencyId]->name]);
            $chartData[$label]       = ['amount'        => $amount, 'currency_symbol' => $currencies[$currencyId]->symbol,
                                        'currency_code' => $currencies[$currencyId]->code];
        }

        $data = $this->generator->multiCurrencyPieChart($chartData);
        $cache->store($data);

        return response()->json($data);
    }

    /**
     * Shows overview for a single bill.
     *
     * @param Bill $bill
     *
     * @return JsonResponse
     * @throws \FireflyIII\Exceptions\FireflyException
     */
    public function single(Bill $bill): JsonResponse
    {
        $cache = new CacheProperties;
        $cache->addProperty('chart.bill.single');
        $cache->addProperty($bill->id);
        if ($cache->has()) {
            return response()->json($cache->get());
        }
        $locale = app('steam')->getLocale();

        /** @var GroupCollectorInterface $collector */
        $collector = app(GroupCollectorInterface::class);
        $journals  = $collector->setBill($bill)->getExtractedJournals();

        // sort the other way around:
        usort(
            $journals,
            static function (array $left, array $right) {
                if ($left['date']->gt($right['date'])) {
                    return 1;
                }
                if ($left['date']->lt($right['date'])) {
                    return -1;
                }

                return 0;
            }
        );

        $chartData  = [
            ['type'          => 'line', 'label' => (string) trans('firefly.min-amount'), 'currency_symbol' => $bill->transactionCurrency->symbol,
             'currency_code' => $bill->transactionCurrency->code, 'entries' => []],
            ['type'          => 'line', 'label' => (string) trans('firefly.max-amount'), 'currency_symbol' => $bill->transactionCurrency->symbol,
             'currency_code' => $bill->transactionCurrency->code, 'entries' => []],
            ['type'          => 'bar', 'label' => (string) trans('firefly.journal-amount'), 'currency_symbol' => $bill->transactionCurrency->symbol,
             'currency_code' => $bill->transactionCurrency->code, 'entries' => []],
        ];
        $currencyId = (int) $bill->transaction_currency_id;
        foreach ($journals as $journal) {
            $date                           = $journal['date']->isoFormat((string) trans('config.month_and_day_js', [], $locale));
            $chartData[0]['entries'][$date] = $bill->amount_min; // minimum amount of bill
            $chartData[1]['entries'][$date] = $bill->amount_max; // maximum amount of bill

            // append amount because there are more than one per moment:
            if (!array_key_exists($date, $chartData[2]['entries'])) {
                $chartData[2]['entries'][$date] = '0';
            }
            $amount = bcmul($journal['amount'], '-1');
            if ($currencyId === $journal['foreign_currency_id']) {
                $amount = bcmul($journal['foreign_amount'], '-1');
            }


            $chartData[2]['entries'][$date] = bcadd($chartData[2]['entries'][$date], $amount);  // amount of journal
        }

        $data = $this->generator->multiSet($chartData);
        $cache->store($data);

        return response()->json($data);
    }
}
{'fraction_non_alphanumeric': 0.14698298091799897, 'fraction_numerical': 0.002873351506667649, 'mean_word_length': 2.5385818561001043, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 164, 'https://': 4, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4929914', 'n_tokens_mistral': 3683, 'n_tokens_neox': 3575, 'n_words': 824}