Org Web Adapter

hungryroot/jira/be_7663_is_customized_gate_rollover_credits.org

ID
be7663-is-customized-gate-rollover-credits

BE-7663 Add is_customized gate to recalculate_adjustments_for_rollover_credits

- source :: https://hungryroot.atlassian.net/browse/BE-7663

- tags :: Hungryroot API Project

- status :: Status - Complete

At cutoff, rollover credits were being recalculated for uncustomized orders when they

shouldn't have been. BE-7548 added a DC gate; this ticket adds a hard gate on

=order.is_customized= so standard recurring uncustomized orders never enter

=recalculate_adjustments_for_rollover_credits=.

The gate lives in =app/services/api/order.py= inside =submit_order=:

#+begin_src python

needs_rollover_recalc = needs_rollover_recalc and (

order.should_calculate_rollover_credits_post_shuffle or order.is_customized

)

#+end_src

=should_calculate_rollover_credits_post_shuffle= is True for flex credits, budget range,

PAYG, and free-first-box rollover orders — the DC from BE-7548 is no longer referenced

here and has no effect.

Test

Find a standard uncustomized RECURRING order and manufacture the bug scenario by giving

the customer rollover credits manually:

#+begin_src python

from app.models import Order

from order_financials.const import PriceCalculationVersion

order = (

Order.objects.select_related("customer")

.filter(

is_customized=False,

status__in=[20], # RECURRING

rollover_credits=0,

)

.exclude(price_calculation_version=PriceCalculationVersion.PAY_AS_YOU_GO)

.first()

)

print("should_calculate_post_shuffle:", order.should_calculate_rollover_credits_post_shuffle)

# Must be False — if True, pick a different order (flex/budget-range/first-box)

order.customer.rollover_credits = 4

order.customer.save()

#+end_src

Inspect the gate logic:

#+begin_src python

from app.models import Order

order = Order.objects.select_related("customer").get(pk=order.id)

customer_has_rollover_credits = order.customer.rollover_credits > 0

too_many_applied = order.customer.rollover_credits < order.rollover_credits

needs_rollover_recalc = customer_has_rollover_credits or too_many_applied

gated = needs_rollover_recalc and (

order.should_calculate_rollover_credits_post_shuffle or order.is_customized

)

print("customer rollover_credits:", order.customer.rollover_credits)

print("order rollover_credits:", order.rollover_credits)

print("is_customized:", order.is_customized)

print("should_calculate_post_shuffle:", order.should_calculate_rollover_credits_post_shuffle)

print("needs_rollover_recalc (raw):", needs_rollover_recalc)

print("would recalculate (gated):", gated)

# Expect: would recalculate (gated): False

#+end_src

Flip =is_customized= to confirm the allow path:

#+begin_src python

order.is_customized = True

order.save()

# Re-run inspection — expect: would recalculate (gated): True

#+end_src

Clean up when done:

#+begin_src python

order.customer.rollover_credits = 0

order.customer.save()

order.is_customized = False

order.save()

#+end_src