A tariff that wants its own price has to give up inheriting everything else with it. payment_inherit is one boolean for the whole payment field group, so turning it off to set a price also detaches the collection mode, the collection value, the security deposit and the no-show fee.
PaymentPolicyResolver::forBooking() picks a single source and reads every value from it: a tariff that does not inherit is the source, otherwise the resource is (yoyaku_payment/src/PaymentPolicyResolver.php:41-63, then policyFor() at :246). There is no per-field fallback, so a detached tariff answers every payment question from its own fields, which hold nothing but their base field defaults.
Those defaults are not neutral (yoyaku_payment/src/Hook/BookingPaymentHooks.php:149-219). collect_mode is required and defaults to full, so a detached tariff takes the whole price online even when the resource takes a percentage. caution_enabled defaults to off and noshow_fee to 0, so the same tariff holds no security deposit and charges no no-show fee even when the resource does both.
Example. A resource priced at 20.00 collects 30% online, holds a 50.00 deposit and charges a 10.00 no-show fee. A reduced tariff is given its own price of 12.00, which means unticking inheritance. That visitor is charged 12.00 up front instead of 3.60, leaves no deposit, and carries no no-show fee.
Why it goes unnoticed: editors fill the tariff's fields by copying what the resource had, so it can be made to match by hand on the day it is entered. The failure is silent and delayed, because changing the resource later leaves every non-inheriting tariff on the old policy with nothing on screen saying so. The admin price column prints "Inherited" for an inheriting tariff, which reports the price and says nothing about the deposit.
Proposed fix: make each value its own override, with empty meaning inherit, the pattern the resource already uses against its resource type ("Leave empty to inherit the resource type" on the cancellation, settlement and booking-mode fields). A tariff then overrides a price by typing a price, and nothing else moves. collect_mode loses its required flag on the tariff, since empty has to be expressible there.
At the same time, drop the security deposit fields from the tariff: caution_enabled, caution_amount and caution_mode. A deposit guarantees the thing being reserved, not the audience paying for it, so the resource is its only sensible owner. Collection mode, collection value and the no-show fee stay overridable per tariff, because "groups pay in full while individuals pay a percentage" and "the free tariff still carries a no-show fee" are real cases.
This changes shipped behavior. A site that switched inheritance off and left the fields at their defaults is collecting the full price today with no deposit, and would start following the resource instead. Pre-1.0 means no update hook, so the change belongs in the release notes, and payment_inherit is removed rather than deprecated.
Issue fork yoyaku-3614391
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 #2
mably commentedComment #5
mably commentedComment #7
mably commentedMerged to 1.x as
aaf67f7.Two notes on what shipped against the proposal above. The collection mode and its amount are inherited as a pair rather than field by field, because the amount reads as currency or as a percentage depending on the mode, so a tariff asking for a percentage would otherwise take the resource's fixed 50.00 as 50%. And the security deposit is no longer overridable on a tariff at all, rather than being an override that is usually left empty: a deposit guarantees the resource being reserved, not the audience paying for it.
Pre-1.0, so no update hook. A site that switched inheritance off and left the fields at their defaults was collecting the full price with no deposit, and will start following the resource after reinstalling.