Accrue.Billing.Query (accrue v1.0.0)

Copy Markdown View Source

Composable Ecto.Query fragments mirroring the Accrue.Billing.Subscription predicates.

Every predicate in Accrue.Billing.Subscription has a matching query fragment here so you can filter subscriptions in the database with the same semantics as the in-memory predicates. Prefer these fragments over direct .status comparisons in where clauses — the predicates on Accrue.Billing.Subscription are the correct way to check subscription state, as direct comparisons miss edge cases like cancel_at_period_end and ended_at that the predicates cover.

All functions accept an optional queryable (default Accrue.Billing.Subscription) and compose via |>:

import Ecto.Query

from(s in Subscription, where: s.customer_id == ^id)
|> Accrue.Billing.Query.active()
|> Repo.all()

Summary

Functions

Subscriptions counted as active (includes :trialing).

Subscriptions that are terminated (:canceled, :incomplete_expired, or any ended_at).

Subscriptions that are :active with cancel_at_period_end set and a period end still in the future — i.e. the cancel hasn't landed yet.

Subscriptions eligible for a dunning sweep tick: strictly :past_due, with past_due_since older than the grace window, and with no prior dunning_sweep_attempted_at stamp.

Subscriptions that are past due or unpaid (dunning territory).

Subscriptions that are paused (legacy :paused status or non-nil pause_collection).

Subscriptions currently in trial.

Functions

active(query \\ Subscription)

@spec active(Ecto.Queryable.t()) :: Ecto.Query.t()

Subscriptions counted as active (includes :trialing).

canceled(query \\ Subscription)

@spec canceled(Ecto.Queryable.t()) :: Ecto.Query.t()

Subscriptions that are terminated (:canceled, :incomplete_expired, or any ended_at).

canceling(query \\ Subscription)

@spec canceling(Ecto.Queryable.t()) :: Ecto.Query.t()

Subscriptions that are :active with cancel_at_period_end set and a period end still in the future — i.e. the cancel hasn't landed yet.

dunning_sweep_candidates(grace_days, query \\ Subscription)

@spec dunning_sweep_candidates(pos_integer(), Ecto.Queryable.t()) :: Ecto.Query.t()

Subscriptions eligible for a dunning sweep tick: strictly :past_due, with past_due_since older than the grace window, and with no prior dunning_sweep_attempted_at stamp.

past_due(query \\ Subscription)

@spec past_due(Ecto.Queryable.t()) :: Ecto.Query.t()

Subscriptions that are past due or unpaid (dunning territory).

paused(query \\ Subscription)

@spec paused(Ecto.Queryable.t()) :: Ecto.Query.t()

Subscriptions that are paused (legacy :paused status or non-nil pause_collection).

trialing(query \\ Subscription)

@spec trialing(Ecto.Queryable.t()) :: Ecto.Query.t()

Subscriptions currently in trial.