Problem/Motivation
The amount an order is charged is summed per line from the resolved payment policy, but a policy prices one unit and nothing multiplies it by the line quantity. A line holding two tickets at 20.00 is summarized at 40.00 and the gateway is asked for 20.00.
PaymentPolicyResolver::transactionAmountDueNow() sums one PaymentPolicy per consuming line, and PaymentPolicy::amountDueNow() returns the amount for one unit (modules/yoyaku_payment/src/PaymentPolicy.php). The order summary does multiply, in PaymentSummaryHooks::fillPrices(), which is why the two figures disagree, and the docblock introducing the stamped unit price says readers multiply (modules/yoyaku_payment/src/Hook/BookingPaymentHooks.php). The bookings table column in PaymentUiHooks::addBookingPriceColumn() is documented as the line total and shows the unit figure too.
Nothing detects it: no test asserts transactionAmountDueNow(), PaymentPolicyResolverTest only holds lines of quantity 1, and the signed shown-amount check on the payment step compares the displayed figure against resolve(), which derives from the same sum, so it agrees with itself.
Placed bookings are one line per place, so a seated flow is unaffected. The exposure is the unplaced path, where one line carries a quantity.
Steps to reproduce
- Give a resource a price and set it to collect the full price online.
- Hold one line of that resource with a quantity of 2.
- Compare the order summary total with
transactionAmountDueNow().
The summary reads twice the price; the amount due reads once.
Proposed resolution
Pair each memoized line policy with the quantity of the line it came from, so no summation site can lose it, and multiply in transactionAmountDueNow(). Make the quantity a required argument of PaymentPolicy::amountDueNow() rather than one defaulting to a single unit, so a caller cannot silently omit it again. Multiply in the bookings table column. Add the first test that asserts the charged amount against a line of quantity 2, and a second for two lines of several units each.
The guarantee and the no-show fee are left exactly as they are, per line and unscaled. Whether either should follow the quantity is a separate question, filed as its own issue.
User interface changes
None, beyond the bookings table showing the line total it already claims to show.
API changes
PaymentPolicy::amountDueNow() takes a required quantity.
Data model changes
None.
Issue fork yoyaku-3615260
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #4
mably commented