Time specific settings?
I have an application that has the concept of a "Period". It is a CTE model with monthly, quarterly & yearly periods. Our application has transactional data that accrual on specific dates. We do a bunch of math & such to the data in background jobs to build reports & such. I would like to come up with a nice model for settings that are used by the calculations. Does anyone have any patterns or links to good articles on time series settings? I wish that Laravel had the concept of a related model using time frames as "foreign keys".
I have the following scopes
/**
* Scope accrued between using a period.
*
* @param Builder $query
* @param Period|iterable|int $period
*
* @return Builder
*
* @throws InvalidArgumentException
* @throws InvalidFormatException
* @throws ModelNotFoundException
*/
public function scopeForPeriod(Builder $query, Period|iterable|int $period): Builder
{
// If given an array/collection, then loop them all to apply
if (is_iterable($period)) {
// Group all of them in a where so that they become orWhere unless inverse, then where
return $query->where(
fn(Builder $q) => Collection::wrap($period)->each(
fn($n) => $q->orWhere->forPeriod($n),
),
);
}
if (is_int($period)) {
$period = Period::findOrFail($period);
}
return $this->scopeAccruedBetween($query, $period->start_at, $period->end_at);
}
/**
* Scope BetweenDates to a specific value.
*
* @param Builder $query
* @param Carbon|CarbonImmutable|DateTime|int|string|null $start_at
* @param Carbon|CarbonImmutable|DateTime|int|string|null $end_at
*
* @return Builder
*/
public function scopeAccruedBetween(
Builder $query,
Carbon|CarbonImmutable|DateTime|int|string|null $start_at = null,
Carbon|CarbonImmutable|DateTime|int|string|null $end_at = null,
): Builder {
return match (true) {
is_null($start_at) && is_null($end_at) => $query,
is_null($start_at) => $query->where('accrual_date', '<=', carbonize($end_at)),
is_null($end_at) => $query->where('accrual_date', '>=', carbonize($start_at)),
default => $query->whereBetween('accrual_date', [
carbonize($start_at),
carbonize($end_at),
])
};
}
That allows me to get access to the "related" models from the Period via accessor...
/**
* Accessor for Compensations.
*
* @return Collection
*/
public function getCompensationsAttribute(): Collection
{
return $this->compensationsQuery->get();
}
/**
* Accessor for Compensations Query.
*
* @return Builder
*/
public function getCompensationsQueryAttribute(): Builder
{
return Compensation::forPeriod($this);
}
I am thinking of doing something simular for Settings, but I just think that there might be a better way.
Anyhow, hoping that one of you may have a good suggestion.
Please or to participate in this conversation.