Age | Commit message (Collapse) | Author |
|
This change moves the processing of individual subscriptions to their
own isolated jobs. The tasks of these individual jobs will be:
- Deactivate/Cancel subscriptions pending one of those operations
- Clear any past failed installment if it's configured to do so
- Create a new installment for the subscription cycle
- Enqueue a job to process any actionable installment for the
subscription
Given we've moved the concern of queueing the installment processing,
that part can be removed safely from the main processor job. The final
part of the change also touches the main processor job, whose task is
now to collect any actionable subscription and any subscription with
an actionable installment to enqueue them for individual processing.
|
|
Because it's very business-specific, this kind of change should be done
at the application level in a decorator, rather than embedding it in the
extension.
|
|
Instead of attempting to process multiple installments at a time, which
increases the chances something might go wrong, we are now only processing
one installment at a time.
This also improves the extension's performance, because the installments
can be processed in parallel.
|
|
The processor was way too complicated, taking on too many responsibilities.
As a result, it was complex to reason about and it was a very brittle part
of the extension.
The new processor simply does two things: it finds all actionable
subscriptions and ensures to take the appropriate action on them (e.g.,
cancel, deactivate), including creating the new installment for later.
Then, it finds all the actionable installments (including the ones that
were just created), and schedules them for asynchronous processing.
One side effect of this refactoring is that installments are not grouped
by address and payment method/source anymore: each installment will always
correspond to a new order. Any logistics-related optimizations should be
implemented by the individual store.
|
|
Anyone who cancels their subscription with a failed installment will
still have an order created the next time installments are created.
This is because installments don't check the status of their associated
subscriptions before being processed.
This update will ensure that only installments with active subscriptions
are processed.
|
|
This implements a configuration to ignore past unfulfilled installments
for subscriptions upon installments creations. Since failed installments
(e.g. because of an expired credit card) are retried indefinitely, they
can overlap and also be retried after another subscription cycle began.
In this particular case, a customer who fixes their payment method after
a new cycle, would be charged for double (or X times as much based on
how long it passed) and sent double the quantity of the same product.
Because in some cases this is not desirable, this adds a switch to skip
any failed past installment when a new installment gets created under
the same subscription.
|
|
|
|
classes. Thanks to @ejdraper
|
|
|
|
|
|
While processing subscriptions, after the actionalble date has been
advanced, if the next actionable date is after the
subscriptions#end_date then deactivate the subscription.
|
|
Subscriptions are grouped together by user and and by shipping address.
A user has 3 subscriptions (A, B and C). A and B have the same shipping
address, but C will be shipped to a different location.
The processor will group and process installments for A and B together
and they will be fulfilled by the same order.
A second order will be created to fulfill C.
|
|
The processor looks up a number of users, subscriptions and installments
and passes them off to an Active Job.
Before we were doing a number of n+1 queries and relying on the rails
global id when passing objects to the consolidated installments.
This commit removes the greedy queries and passes a list of ids to the
active job object so that all affected objects can be looked up in a
single query
|
|
When the subscription is processed its successive skip count should be
reset to 0
|
|
Config minimum cancellation notice
|
|
If the processor processed a subscription in the pending_cancellation
state, it cancels the subscription after creating one last installment
for it
|
|
When an installment is created for a subscrption, the subscription
should have its actionable date advanced.
|
|
Something about the inheritance from the singleton class here is
interrupting normal rails constant lookup.
As an interm fix, use the fully qualified class names
|
|
This class looks up all actionable subscriptions and installments,
groups them by user and schedules them to be reprocessed.
|