feat(billing): charge a mid-month joiner for trainings, not for days
Proration counted remaining days on a hardcoded 30-day month, a unit the
academy never sold. A programme meeting Sunday and Tuesday holds no
sessions over a long weekend, so someone joining on the 22nd was billed a
third of a month for perhaps two trainings — and the calendar never
noticed. September 2026, Sun+Tue: three of the month's nine sessions
remain on the 22nd, not nine of thirty days.
SessionCountService counts from the timetable rather than from
training_sessions, because the generator only materialises rows about a
week ahead and counting rows would under-report the rest of the month —
exactly the question proration asks. Its rules are the generator's,
deliberately identical: an active schedule row naming the weekday,
effective that day, with no training-affecting holiday on it.
The desk now chooses per registration: شهر كامل, نص شهر, or باقي تمرينات
الشهر. The mode is settable from the browser by design, and safe to be —
the academy setting remains the gate, and an unrecognised value falls back
to the default rather than being honoured. Joining after the month's last
session owes nothing for that month, so no invoice is raised at all; a
zero-total one is what AccountAnomalyScanner reports as corruption.
Also: a branch whose takings never pass through the system. A partner-run
site bills nobody — participants enrol unbilled, enrolments are marked
waived, and the branch's income is entered afterwards on the
external-revenue screen. Skipping the invoice rather than writing a zero
one, for the same reason as above. The guard sits before the renewal
command's adoption step, not after: those enrolments carry no billing date
precisely because they are off the cycle, and adoption would read that as
an oversight and put every one of them onto it.
Fixes a latent crash on the way: BranchSettingsService called
app('current_academy') unguarded, which throws rather than returning null
outside a request. The renewal command binds no academy, so asking it the
billing question from the console would have taken the nightly run down.
Co-Authored-By:
Claude Opus 5 (1M context) <noreply@anthropic.com>
Showing
This diff is collapsed.
Please register or sign in to comment