mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-10-12 15:35:15 +00:00
🤖 Auto commit for release 'develop' on 2025-07-31
This commit is contained in:
@@ -87,7 +87,7 @@ class ShowController extends Controller
|
|||||||
$enrichment->setNative($this->nativeCurrency);
|
$enrichment->setNative($this->nativeCurrency);
|
||||||
$enrichment->setStart($this->parameters->get('start'));
|
$enrichment->setStart($this->parameters->get('start'));
|
||||||
$enrichment->setEnd($this->parameters->get('end'));
|
$enrichment->setEnd($this->parameters->get('end'));
|
||||||
$bills = $enrichment->enrich($bills);
|
$bills = $enrichment->enrich($bills);
|
||||||
|
|
||||||
/** @var BillTransformer $transformer */
|
/** @var BillTransformer $transformer */
|
||||||
$transformer = app(BillTransformer::class);
|
$transformer = app(BillTransformer::class);
|
||||||
|
@@ -53,11 +53,11 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
|||||||
$paidDates = $this->paidDates;
|
$paidDates = $this->paidDates;
|
||||||
$payDates = $this->payDates;
|
$payDates = $this->payDates;
|
||||||
$this->collection = $this->collection->map(function (Bill $item) use ($notes, $objectGroups, $paidDates, $payDates) {
|
$this->collection = $this->collection->map(function (Bill $item) use ($notes, $objectGroups, $paidDates, $payDates) {
|
||||||
$id = (int)$item->id;
|
$id = (int)$item->id;
|
||||||
$currency = $item->transactionCurrency;
|
$currency = $item->transactionCurrency;
|
||||||
$nem = $this->getNextExpectedMatch($payDates[$id] ?? []);
|
$nem = $this->getNextExpectedMatch($payDates[$id] ?? []);
|
||||||
|
|
||||||
$meta = [
|
$meta = [
|
||||||
'notes' => null,
|
'notes' => null,
|
||||||
'object_group_id' => null,
|
'object_group_id' => null,
|
||||||
'object_group_title' => null,
|
'object_group_title' => null,
|
||||||
@@ -66,9 +66,9 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
|||||||
'paid_dates' => $this->filterPaidDates($paidDates[$id] ?? []),
|
'paid_dates' => $this->filterPaidDates($paidDates[$id] ?? []),
|
||||||
'pay_dates' => $payDates[$id] ?? [],
|
'pay_dates' => $payDates[$id] ?? [],
|
||||||
'nem' => $nem,
|
'nem' => $nem,
|
||||||
'nem_diff' => $this->getNextExpectedMatchDiff($nem, $payDates[$id] ?? [])
|
'nem_diff' => $this->getNextExpectedMatchDiff($nem, $payDates[$id] ?? []),
|
||||||
];
|
];
|
||||||
$amounts = [
|
$amounts = [
|
||||||
'amount_min' => Steam::bcround($item->amount_min, $currency->decimal_places),
|
'amount_min' => Steam::bcround($item->amount_min, $currency->decimal_places),
|
||||||
'amount_max' => Steam::bcround($item->amount_max, $currency->decimal_places),
|
'amount_max' => Steam::bcround($item->amount_max, $currency->decimal_places),
|
||||||
'average' => Steam::bcround(bcdiv(bcadd($item->amount_min, $item->amount_max), '2'), $currency->decimal_places),
|
'average' => Steam::bcround(bcdiv(bcadd($item->amount_min, $item->amount_max), '2'), $currency->decimal_places),
|
||||||
@@ -117,9 +117,10 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
|||||||
private function collectNotes(): void
|
private function collectNotes(): void
|
||||||
{
|
{
|
||||||
$notes = Note::query()->whereIn('noteable_id', $this->subscriptionIds)
|
$notes = Note::query()->whereIn('noteable_id', $this->subscriptionIds)
|
||||||
->whereNotNull('notes.text')
|
->whereNotNull('notes.text')
|
||||||
->where('notes.text', '!=', '')
|
->where('notes.text', '!=', '')
|
||||||
->where('noteable_type', Bill::class)->get(['notes.noteable_id', 'notes.text'])->toArray();
|
->where('noteable_type', Bill::class)->get(['notes.noteable_id', 'notes.text'])->toArray()
|
||||||
|
;
|
||||||
foreach ($notes as $note) {
|
foreach ($notes as $note) {
|
||||||
$this->notes[(int)$note['noteable_id']] = (string)$note['text'];
|
$this->notes[(int)$note['noteable_id']] = (string)$note['text'];
|
||||||
}
|
}
|
||||||
@@ -158,10 +159,11 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
|||||||
|
|
||||||
private function collectObjectGroups(): void
|
private function collectObjectGroups(): void
|
||||||
{
|
{
|
||||||
$set = DB::table('object_groupables')
|
$set = DB::table('object_groupables')
|
||||||
->whereIn('object_groupable_id', $this->subscriptionIds)
|
->whereIn('object_groupable_id', $this->subscriptionIds)
|
||||||
->where('object_groupable_type', Bill::class)
|
->where('object_groupable_type', Bill::class)
|
||||||
->get(['object_groupable_id', 'object_group_id']);
|
->get(['object_groupable_id', 'object_group_id'])
|
||||||
|
;
|
||||||
|
|
||||||
$ids = array_unique($set->pluck('object_group_id')->toArray());
|
$ids = array_unique($set->pluck('object_group_id')->toArray());
|
||||||
|
|
||||||
@@ -183,6 +185,7 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
|||||||
if (null === $this->start || null === $this->end) {
|
if (null === $this->start || null === $this->end) {
|
||||||
Log::debug('Parameters are NULL, return empty array');
|
Log::debug('Parameters are NULL, return empty array');
|
||||||
$this->paidDates = [];
|
$this->paidDates = [];
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,8 +198,8 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
|||||||
$start->subDay();
|
$start->subDay();
|
||||||
|
|
||||||
/** @var Carbon $end */
|
/** @var Carbon $end */
|
||||||
$end = clone $this->end;
|
$end = clone $this->end;
|
||||||
$searchEnd = clone $end;
|
$searchEnd = clone $end;
|
||||||
|
|
||||||
// move the search dates to the start of the day.
|
// move the search dates to the start of the day.
|
||||||
$searchStart->startOfDay();
|
$searchStart->startOfDay();
|
||||||
@@ -206,13 +209,13 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
|||||||
Log::debug(sprintf('Search parameters are: start: %s, end: %s', $searchStart->format('Y-m-d H:i:s'), $searchEnd->format('Y-m-d H:i:s')));
|
Log::debug(sprintf('Search parameters are: start: %s, end: %s', $searchStart->format('Y-m-d H:i:s'), $searchEnd->format('Y-m-d H:i:s')));
|
||||||
|
|
||||||
// Get from database when bills were paid.
|
// Get from database when bills were paid.
|
||||||
$set = $this->user->transactionJournals()
|
$set = $this->user->transactionJournals()
|
||||||
->whereIn('bill_id', $this->subscriptionIds)
|
->whereIn('bill_id', $this->subscriptionIds)
|
||||||
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
||||||
->leftJoin('transaction_currencies AS currency', 'currency.id', '=', 'transactions.transaction_currency_id')
|
->leftJoin('transaction_currencies AS currency', 'currency.id', '=', 'transactions.transaction_currency_id')
|
||||||
->leftJoin('transaction_currencies AS foreign_currency', 'foreign_currency.id', '=', 'transactions.foreign_currency_id')
|
->leftJoin('transaction_currencies AS foreign_currency', 'foreign_currency.id', '=', 'transactions.foreign_currency_id')
|
||||||
->where('transactions.amount', '>', 0)
|
->where('transactions.amount', '>', 0)
|
||||||
->before($searchEnd)->after($searchStart)->get(
|
->before($searchEnd)->after($searchStart)->get(
|
||||||
[
|
[
|
||||||
'transaction_journals.id',
|
'transaction_journals.id',
|
||||||
'transaction_journals.date',
|
'transaction_journals.date',
|
||||||
@@ -226,7 +229,8 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
|||||||
'transactions.amount',
|
'transactions.amount',
|
||||||
'transactions.foreign_amount',
|
'transactions.foreign_amount',
|
||||||
]
|
]
|
||||||
);
|
)
|
||||||
|
;
|
||||||
Log::debug(sprintf('Count %d entries in set', $set->count()));
|
Log::debug(sprintf('Count %d entries in set', $set->count()));
|
||||||
|
|
||||||
// for each bill, do a loop.
|
// for each bill, do a loop.
|
||||||
@@ -234,13 +238,13 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
|||||||
foreach ($this->collection as $subscription) {
|
foreach ($this->collection as $subscription) {
|
||||||
// Grab from array the most recent payment. If none exist, fall back to the start date and pretend *that* was the last paid date.
|
// Grab from array the most recent payment. If none exist, fall back to the start date and pretend *that* was the last paid date.
|
||||||
Log::debug(sprintf('Grab last paid date from function, return %s if it comes up with nothing.', $start->format('Y-m-d')));
|
Log::debug(sprintf('Grab last paid date from function, return %s if it comes up with nothing.', $start->format('Y-m-d')));
|
||||||
$lastPaidDate = $this->lastPaidDate($subscription, $set, $start);
|
$lastPaidDate = $this->lastPaidDate($subscription, $set, $start);
|
||||||
Log::debug(sprintf('Result of lastPaidDate is %s', $lastPaidDate->format('Y-m-d')));
|
Log::debug(sprintf('Result of lastPaidDate is %s', $lastPaidDate->format('Y-m-d')));
|
||||||
|
|
||||||
// At this point the "next match" is exactly after the last time the bill was paid.
|
// At this point the "next match" is exactly after the last time the bill was paid.
|
||||||
$result = [];
|
$result = [];
|
||||||
foreach ($set as $entry) {
|
foreach ($set as $entry) {
|
||||||
$array = [
|
$array = [
|
||||||
'transaction_group_id' => (string)$entry->transaction_group_id,
|
'transaction_group_id' => (string)$entry->transaction_group_id,
|
||||||
'transaction_journal_id' => (string)$entry->id,
|
'transaction_journal_id' => (string)$entry->id,
|
||||||
'date' => $entry->date->toAtomString(),
|
'date' => $entry->date->toAtomString(),
|
||||||
@@ -286,7 +290,7 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
|||||||
return $default;
|
return $default;
|
||||||
}
|
}
|
||||||
|
|
||||||
$latest = $filtered->first()->date;
|
$latest = $filtered->first()->date;
|
||||||
|
|
||||||
/** @var TransactionJournal $journal */
|
/** @var TransactionJournal $journal */
|
||||||
foreach ($filtered as $journal) {
|
foreach ($filtered as $journal) {
|
||||||
@@ -326,12 +330,12 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
|||||||
{
|
{
|
||||||
/** @var Bill $subscription */
|
/** @var Bill $subscription */
|
||||||
foreach ($this->collection as $subscription) {
|
foreach ($this->collection as $subscription) {
|
||||||
$id = (int)$subscription->id;
|
$id = (int)$subscription->id;
|
||||||
$lastPaidDate = $this->getLastPaidDate($paidDates[$id] ?? []);
|
$lastPaidDate = $this->getLastPaidDate($paidDates[$id] ?? []);
|
||||||
$payDates = $this->calculator->getPayDates($this->start, $this->end, $subscription->date, $subscription->repeat_freq, $subscription->skip, $lastPaidDate);
|
$payDates = $this->calculator->getPayDates($this->start, $this->end, $subscription->date, $subscription->repeat_freq, $subscription->skip, $lastPaidDate);
|
||||||
$payDatesFormatted = [];
|
$payDatesFormatted = [];
|
||||||
foreach ($payDates as $string) {
|
foreach ($payDates as $string) {
|
||||||
$date = Carbon::createFromFormat('!Y-m-d', $string, config('app.timezone'));
|
$date = Carbon::createFromFormat('!Y-m-d', $string, config('app.timezone'));
|
||||||
if (!$date instanceof Carbon) {
|
if (!$date instanceof Carbon) {
|
||||||
$date = today(config('app.timezone'));
|
$date = today(config('app.timezone'));
|
||||||
}
|
}
|
||||||
@@ -345,6 +349,7 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
|||||||
{
|
{
|
||||||
return array_map(function (array $entry) {
|
return array_map(function (array $entry) {
|
||||||
unset($entry['date_object']);
|
unset($entry['date_object']);
|
||||||
|
|
||||||
return $entry;
|
return $entry;
|
||||||
}, $entries);
|
}, $entries);
|
||||||
}
|
}
|
||||||
@@ -360,7 +365,7 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
|||||||
if (!$nemDate instanceof Carbon) {
|
if (!$nemDate instanceof Carbon) {
|
||||||
$nemDate = today(config('app.timezone'));
|
$nemDate = today(config('app.timezone'));
|
||||||
}
|
}
|
||||||
$nem = $nemDate;
|
$nem = $nemDate;
|
||||||
|
|
||||||
// nullify again when it's outside the current view range.
|
// nullify again when it's outside the current view range.
|
||||||
if (
|
if (
|
||||||
@@ -372,6 +377,7 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
|||||||
$firstPayDate = null;
|
$firstPayDate = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $nem;
|
return $nem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -380,7 +386,7 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
|||||||
if (null === $nem) {
|
if (null === $nem) {
|
||||||
return trans('firefly.not_expected_period');
|
return trans('firefly.not_expected_period');
|
||||||
}
|
}
|
||||||
$nemDiff = trans('firefly.not_expected_period');;
|
$nemDiff = trans('firefly.not_expected_period');
|
||||||
// converting back and forth is bad code but OK.
|
// converting back and forth is bad code but OK.
|
||||||
if ($nem->isToday()) {
|
if ($nem->isToday()) {
|
||||||
$nemDiff = trans('firefly.today');
|
$nemDiff = trans('firefly.today');
|
||||||
@@ -388,7 +394,7 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
|||||||
|
|
||||||
$current = $payDates[0] ?? null;
|
$current = $payDates[0] ?? null;
|
||||||
if (null !== $current && !$nem->isToday()) {
|
if (null !== $current && !$nem->isToday()) {
|
||||||
$temp2 = Carbon::parse($current, config('app.timezone'));
|
$temp2 = Carbon::parse($current, config('app.timezone'));
|
||||||
if (!$temp2 instanceof Carbon) {
|
if (!$temp2 instanceof Carbon) {
|
||||||
$temp2 = today(config('app.timezone'));
|
$temp2 = today(config('app.timezone'));
|
||||||
}
|
}
|
||||||
@@ -399,4 +405,3 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
|||||||
return $nemDiff;
|
return $nemDiff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -45,7 +45,6 @@ class BillTransformer extends AbstractTransformer
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Transform the bill.
|
* Transform the bill.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public function transform(Bill $bill): array
|
public function transform(Bill $bill): array
|
||||||
{
|
{
|
||||||
@@ -53,53 +52,51 @@ class BillTransformer extends AbstractTransformer
|
|||||||
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'id' => $bill->id,
|
'id' => $bill->id,
|
||||||
'created_at' => $bill->created_at->toAtomString(),
|
'created_at' => $bill->created_at->toAtomString(),
|
||||||
'updated_at' => $bill->updated_at->toAtomString(),
|
'updated_at' => $bill->updated_at->toAtomString(),
|
||||||
'currency_id' => (string)$bill->transaction_currency_id,
|
'currency_id' => (string)$bill->transaction_currency_id,
|
||||||
'currency_code' => $currency->code,
|
'currency_code' => $currency->code,
|
||||||
'currency_symbol' => $currency->symbol,
|
'currency_symbol' => $currency->symbol,
|
||||||
'currency_decimal_places' => $currency->decimal_places,
|
'currency_decimal_places' => $currency->decimal_places,
|
||||||
|
|
||||||
'native_currency_id' => (string)$this->native->id,
|
'native_currency_id' => (string)$this->native->id,
|
||||||
'native_currency_code' => $this->native->code,
|
'native_currency_code' => $this->native->code,
|
||||||
'native_currency_symbol' => $this->native->symbol,
|
'native_currency_symbol' => $this->native->symbol,
|
||||||
'native_currency_decimal_places' => $this->native->decimal_places,
|
'native_currency_decimal_places' => $this->native->decimal_places,
|
||||||
|
|
||||||
'name' => $bill->name,
|
'name' => $bill->name,
|
||||||
'amount_min' => $bill->amounts['amount_min'],
|
'amount_min' => $bill->amounts['amount_min'],
|
||||||
'amount_max' => $bill->amounts['amount_max'],
|
'amount_max' => $bill->amounts['amount_max'],
|
||||||
'amount_avg' => $bill->amounts['average'],
|
'amount_avg' => $bill->amounts['average'],
|
||||||
'date' => $bill->date->toAtomString(),
|
'date' => $bill->date->toAtomString(),
|
||||||
'end_date' => $bill->end_date?->toAtomString(),
|
'end_date' => $bill->end_date?->toAtomString(),
|
||||||
'extension_date' => $bill->extension_date?->toAtomString(),
|
'extension_date' => $bill->extension_date?->toAtomString(),
|
||||||
'repeat_freq' => $bill->repeat_freq,
|
'repeat_freq' => $bill->repeat_freq,
|
||||||
'skip' => $bill->skip,
|
'skip' => $bill->skip,
|
||||||
'active' => $bill->active,
|
'active' => $bill->active,
|
||||||
'order' => $bill->order,
|
'order' => $bill->order,
|
||||||
'notes' => $bill->meta['notes'],
|
'notes' => $bill->meta['notes'],
|
||||||
'object_group_id' => $bill->meta['object_group_id'],
|
'object_group_id' => $bill->meta['object_group_id'],
|
||||||
'object_group_order' => $bill->meta['object_group_order'],
|
'object_group_order' => $bill->meta['object_group_order'],
|
||||||
'object_group_title' => $bill->meta['object_group_title'],
|
'object_group_title' => $bill->meta['object_group_title'],
|
||||||
|
|
||||||
|
|
||||||
'paid_dates' => $bill->meta['paid_dates'],
|
'paid_dates' => $bill->meta['paid_dates'],
|
||||||
'pay_dates' => $bill->meta['pay_dates'],
|
'pay_dates' => $bill->meta['pay_dates'],
|
||||||
'next_expected_match' => $bill->meta['nem']?->toAtomString(),
|
'next_expected_match' => $bill->meta['nem']?->toAtomString(),
|
||||||
'next_expected_match_diff' => $bill->meta['nem_diff'],
|
'next_expected_match_diff' => $bill->meta['nem_diff'],
|
||||||
|
|
||||||
// these fields need work:
|
// these fields need work:
|
||||||
// 'next_expected_match' => $nem,
|
// 'next_expected_match' => $nem,
|
||||||
// 'next_expected_match_diff' => $nemDiff,
|
// 'next_expected_match_diff' => $nemDiff,
|
||||||
// 'pay_dates' => $payDatesFormatted,
|
// 'pay_dates' => $payDatesFormatted,
|
||||||
'links' => [
|
'links' => [
|
||||||
[
|
[
|
||||||
'rel' => 'self',
|
'rel' => 'self',
|
||||||
'uri' => '/bills/' . $bill->id,
|
'uri' => '/bills/'.$bill->id,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -79,7 +79,7 @@ return [
|
|||||||
// see cer.php for exchange rates feature flag.
|
// see cer.php for exchange rates feature flag.
|
||||||
],
|
],
|
||||||
'version' => 'develop/2025-07-31',
|
'version' => 'develop/2025-07-31',
|
||||||
'build_time' => 1753936691,
|
'build_time' => 1753939947,
|
||||||
'api_version' => '2.1.0', // field is no longer used.
|
'api_version' => '2.1.0', // field is no longer used.
|
||||||
'db_version' => 26,
|
'db_version' => 26,
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user