-
-
Notifications
You must be signed in to change notification settings - Fork 3
Write the refund and money-handling journeys as readable stories #1931
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
3002bde
WIP: move the money journeys to Cucumber — coverage not yet checked
claude 6f1880b
Cover the money-page reading helpers
claude 208ca93
Add the two money stories to the catalog test
claude 33f3344
Cover an order that carries an extra charge
claude a468be5
Kill seven surviving ledger mutants
claude 647e0ef
Split the money steps and fail loudly on a missing booking
claude fec22b4
Kill eight surviving accounting mutants
claude 846386f
Fold the adjustment direction checks into one
claude f65c879
Prove each correction kind keys its own event
claude 1323546
Assert a correction is filed under its own kind
claude 07fd7a5
Drop a stale comment from the money drivers
claude 6ce2c67
Address the second Codex review round
claude 8436475
Correct income through its own form and read each breakdown row
claude 478f6cd
Merge remote-tracking branch 'origin/main' into claude/convert-tests-…
claude 5b09373
Book and correct through the rendered forms everywhere
claude 2999063
Give the split payment its own story, and prove the money came back
claude 9b25198
Assert the correction leg count directly
claude File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| @story:payments.free-bookings | ||
| @owner:payments @risk:medium | ||
| @actor:organiser @actor:customer | ||
| @edition:managed @edition:self-hosted | ||
| Feature: A free booking costs nothing | ||
| A listing given away for free must never invent money, whatever fees the site | ||
| charges on its paid listings. | ||
|
|
||
| @rule:payments.a-free-booking-records-no-money | ||
| @surface:admin | ||
| Rule: A free booking records no money at all | ||
| Even with a booking fee set up, nothing is charged and nothing is recorded. | ||
|
|
||
| @case:payment.free-booking-records-no-money | ||
| Scenario: A customer books a free place while a booking fee is set up | ||
| Given the site adds a 10 percent booking fee | ||
| When a customer books a free Free Meetup place | ||
| Then no money is recorded for the booking | ||
| And no booking fee is recorded |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| @story:payments.income-figures-explained | ||
| @owner:payments @risk:medium | ||
| @actor:organiser | ||
| @edition:managed @edition:self-hosted | ||
| Feature: An organiser can see how a listing's income adds up | ||
| A listing shows two income figures. The page must explain, line by line, how | ||
| each one is worked out, so they can never quietly disagree. | ||
|
|
||
| @rule:payments.the-income-figures-are-explained | ||
| @surface:admin | ||
| Rule: The listing page explains how its income figures are worked out | ||
| Sales, corrections and refunds are each listed with their own sign, so the | ||
| two income figures can never quietly disagree. | ||
|
|
||
| @case:payment.income-breakdown-explains-the-figures | ||
| Scenario: The organiser reads the money breakdown after a correction and a refund | ||
| Given a customer paid 50.00 for a Reconciled place | ||
| And the organiser corrected the Reconciled income to 40.00 | ||
| When the organiser refunds the booking | ||
| Then the Reconciled page breaks the money down line by line | ||
| And the breakdown links to the Reconciled money record |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| @story:payments.one-payment-many-listings | ||
| @owner:payments @risk:high | ||
| @actor:organiser @actor:customer | ||
| @edition:managed @edition:self-hosted | ||
| Feature: One payment can cover places on several listings | ||
| A customer buying places on more than one listing pays once. Each listing must | ||
| earn only its own part of that payment. | ||
|
|
||
| @rule:payments.one-payment-pays-each-listing-its-share | ||
| @surface:admin | ||
| Rule: One payment covering two listings pays each its own share | ||
| A customer buying places on two listings at once pays once, and each | ||
| listing earns only its own part. | ||
|
|
||
| @case:payment.one-payment-two-listings | ||
| Scenario: A customer pays once for a place on each of two listings | ||
| Given Part One costs 30.00 and Part Two costs 20.00 | ||
| When a customer pays 50.00 for one place on each | ||
| Then Part One has earned 30.00 and Part Two has earned 20.00 | ||
| And both places belong to the same order | ||
| And each listing's page shows its own earnings |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| @story:payments.refunding-a-booking | ||
| @owner:payments @risk:high | ||
| @actor:organiser @actor:customer | ||
| @edition:managed @edition:self-hosted | ||
| Feature: An organiser refunds a booking | ||
| When an organiser refunds a booking, the customer gets back everything they | ||
| paid — the ticket, any booking fee, and any service charge. The organiser's | ||
| own figures must agree with the money that actually moved. | ||
|
|
||
| @rule:payments.refund-hands-the-money-back | ||
| @surface:admin | ||
| Rule: A refund hands back the money and undoes the sale | ||
| The listing stops counting the sale, the customer owes nothing, and the | ||
| money goes back where it came from. | ||
|
|
||
| @case:payment.refund-undoes-the-sale | ||
| Scenario: The organiser refunds a paid place | ||
| Given a customer paid 45.00 for a Concert place | ||
| When the organiser refunds the booking | ||
| Then the customer is handed back 45.00 once | ||
| And the Concert has earned nothing and the customer owes nothing | ||
| And the booking page says the booking is fully paid | ||
|
|
||
| @rule:payments.a-booking-is-refunded-once-only | ||
| @surface:admin | ||
| Rule: A booking can only be refunded once | ||
| A second attempt is refused before any money moves, so nobody is paid twice. | ||
|
|
||
| @case:payment.second-refund-is-refused | ||
| Scenario: The organiser tries to refund the same booking twice | ||
| Given a customer's paid Concert place was already refunded | ||
| When the organiser tries to refund it again | ||
| Then the organiser is told it was already refunded | ||
| And the payment provider is not asked again | ||
| And the customer was handed money back only once | ||
|
|
||
| @rule:payments.a-booking-fee-is-its-own-income | ||
| @surface:admin | ||
| Rule: A booking fee is counted apart from the ticket, and comes back too | ||
| The fee the site charges is its own income, not the listing's, and a refund | ||
| returns it with the ticket. | ||
|
|
||
| @case:payment.booking-fee-is-counted-apart | ||
| Scenario: A customer pays a booking fee | ||
| Given the site adds a 10 percent booking fee | ||
| When a customer pays 55.00 for a 50.00 Fee Day place | ||
| Then the Fee Day place has earned 50.00 and the booking fee has earned 5.00 | ||
| And the customer owes nothing | ||
|
|
||
| @case:payment.booking-fee-comes-back | ||
| Scenario: The organiser refunds a booking that paid a booking fee | ||
| Given a customer paid a 10 percent booking fee on a 50.00 Fee Day place | ||
| When the organiser refunds the booking | ||
| Then the Fee Day place and the booking fee have both earned nothing | ||
| And the site is holding none of the customer's money | ||
|
|
||
| @rule:payments.a-service-charge-earns-and-returns | ||
| @surface:admin | ||
| Rule: A service charge earns its own money, and comes back on a refund | ||
| An extra charge added at checkout is tracked on its own, and the organiser | ||
| can see what it earned. | ||
|
|
||
| @case:payment.service-charge-earns-its-own-money | ||
| Scenario: A customer pays a service charge | ||
| Given a Talk place costs 50.00 and adds a 10 percent Service charge | ||
| When a customer pays for one Talk place | ||
| Then the Service charge has earned 5.00 | ||
| And the organiser's pages show the Service charge earnings | ||
|
|
||
| @case:payment.service-charge-comes-back | ||
| Scenario: The organiser refunds a booking that paid a service charge | ||
| Given a customer paid a 10 percent Service charge on a 50.00 Talk place | ||
| When the organiser refunds the booking | ||
| Then the Service charge has earned nothing | ||
| And the customer has the whole 55.00 back | ||
| And no money is left unaccounted for | ||
|
|
||
| @rule:payments.money-is-never-created-or-destroyed | ||
| @surface:admin | ||
| Rule: Money is never created or destroyed | ||
| However many sales, corrections and refunds happen, the books still add up. | ||
|
|
||
| @case:payment.mixed-sequence-still-adds-up | ||
| Scenario: A sale, a correction and a refund in turn | ||
| Given two customers each paid 70.00 for a Festival place | ||
| And the organiser corrected the Festival income to 100.00 | ||
| When the organiser refunds the first customer | ||
| Then no money is left unaccounted for | ||
| And the Festival earnings and the refunded customer's balance agree | ||
|
|
||
| @rule:payments.a-turned-down-refund-changes-nothing | ||
| @surface:admin | ||
| Rule: A refund the provider turns down changes nothing | ||
| The organiser is told it failed, and the books are exactly as they were. | ||
|
|
||
| @case:payment.declined-refund-changes-nothing | ||
| Scenario: The payment provider turns down the refund | ||
| Given a customer paid 45.00 for a Show place | ||
| When the organiser asks for a refund and the provider turns it down | ||
| Then the organiser is told the refund failed | ||
| And the Show has still earned 45.00 and no money was handed back | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| @story:payments.repeated-money-actions | ||
| @owner:payments @risk:high | ||
| @actor:organiser @actor:customer | ||
| @edition:managed @edition:self-hosted | ||
| Feature: Doing the same money action twice counts it once | ||
| A payment message that arrives again, or an income figure saved again, must | ||
| leave the books exactly as they already were. | ||
|
|
||
| @rule:payments.doing-it-twice-counts-once | ||
| @surface:admin | ||
| Rule: Doing the same thing twice counts it only once | ||
| A repeated payment message makes no second booking, and re-saving the same | ||
| income figure makes no second correction. | ||
|
|
||
| @case:payment.replayed-payment-counts-once | ||
| Scenario: The same payment message arrives again | ||
| Given a customer paid 60.00 for a Repeat place | ||
| When the same payment message arrives again | ||
| Then there is still one booking and one sale | ||
|
|
||
| @case:payment.repeated-correction-counts-once | ||
| Scenario: The organiser saves the same income figure twice | ||
| Given a customer paid 60.00 for a Repeat place | ||
| When the organiser sets the Repeat income to 40.00 twice | ||
| Then the Repeat has earned 40.00 from a single correction |
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.