Apply account credit on same-month rebook, surface credit on student page
CI / Coding Standards (pull_request) Successful in 27s
CI / Tests (PHP 8.2) (pull_request) Successful in 28s
CI / No Debug Code (pull_request) Successful in 9s
CI / Tests (PHP 8.5) (pull_request) Successful in 35s
CI / Tests (PHP 8.1) (pull_request) Successful in 37s
CI / Tests (PHP 8.3) (pull_request) Successful in 43s
CI / Static Analysis (pull_request) Successful in 51s
CI / Build Plugin Zip (pull_request) Skipped

A monthly/weekly lesson booked into a month whose billing date has
already passed is charged at booking time by LessonBooker::settle,
bypassing the daily scan where account credit is otherwise applied. So
rebooking a cancelled paid lesson within the same month charged the
family in full while their cancellation credit sat unused — billed twice
for the same slot.

Apply the payer's credit to that charge-at-booking payment for scheduled
offerings, mirroring the daily scan: a payment fully covered by credit
settles and confirms its lesson. Add PaymentService::findPayment so
settle can re-read the row after applyCredits writes to it.

Also surface the student's total account credit at the top of their
detail page when they hold a balance, so the studio sees it at a glance.

Co-authored-by: anthropic/claude-opus-4-8
This commit is contained in:
2026-09-17 15:39:53 -03:00
co-authored by anthropic/claude-opus-4-8
parent d8d842b1ef
commit e7de627752
4 changed files with 101 additions and 1 deletions
+33
View File
@@ -114,6 +114,39 @@ $renderLessons = static function (array $rows, bool $withActions = false): void
<div class="notice notice-error is-dismissible"><p><?php echo esc_html($error); ?></p></div>
<?php endif; ?>
<?php
/*
* Surface the credit balance up top the moment there is one, so the studio
* sees at a glance that this student is owed against future billing without
* scrolling to the Account credit section. Only shown when there is credit to
* report — a zero balance is not news. The full breakdown stays below.
*/
?>
<?php if ($canBilling && $creditBalance > 0) : ?>
<div class="notice notice-info inline">
<p>
<?php
printf(
/* translators: %s: total available credit, e.g. "45.00 CAD" */
esc_html__('Total account credit: %s', 'unsupervised-schedular'),
'<strong>' . esc_html(number_format_i18n($creditBalance, 2) . ' ' . $creditCurrency) . '</strong>'
);
?>
<?php if ($payer['id'] !== (int) $student->ID) : ?>
<span class="description">
<?php
printf(
/* translators: %s: name of the parent/guardian whose account holds the balance. */
esc_html__('Held on %ss account.', 'unsupervised-schedular'),
esc_html($payer['name'])
);
?>
</span>
<?php endif; ?>
</p>
</div>
<?php endif; ?>
<?php $detailUrl = static fn(int $id): string => add_query_arg(['page' => $pageSlug, 'student_id' => $id], admin_url('admin.php')); ?>
<h2><?php esc_html_e('Account', 'unsupervised-schedular'); ?></h2>