|
1 | 1 | module Processes |
2 | 2 | class ReleasePaymentProcess |
3 | | - include Infra::Retry |
4 | 3 |
|
5 | | - def initialize(event_store, command_bus) |
6 | | - @event_store = event_store |
7 | | - @command_bus = command_bus |
8 | | - end |
9 | | - |
10 | | - def call(event) |
11 | | - state = build_state(event) |
12 | | - release_payment(state) if state.release? |
13 | | - end |
14 | | - |
15 | | - private |
| 4 | + ProcessState = Data.define(:order, :payment, :order_id) do |
| 5 | + def initialize(order: :draft, payment: :none, order_id: nil) |
| 6 | + super(order:, payment:, order_id:) |
| 7 | + end |
16 | 8 |
|
17 | | - def release_payment(state) |
18 | | - command_bus.call(Payments::ReleasePayment.new(order_id: state.order_id)) |
| 9 | + def release? |
| 10 | + payment.eql?(:authorized) && order.eql?(:expired) |
| 11 | + end |
19 | 12 | end |
20 | 13 |
|
21 | | - attr_reader :command_bus, :event_store |
22 | | - |
23 | | - def build_state(event) |
24 | | - with_retry do |
25 | | - stream_name = "PaymentProcess$#{event.data.fetch(:order_id)}" |
26 | | - past_events = event_store.read.stream(stream_name).to_a |
27 | | - last_stored = past_events.size - 1 |
28 | | - event_store.link(event.event_id, stream_name: stream_name, expected_version: last_stored) |
29 | | - ProcessState.new.tap do |state| |
30 | | - past_events.each { |ev| state.call(ev) } |
31 | | - state.call(event) |
32 | | - end |
| 14 | + include Infra::ProcessManager.with_state(ProcessState) |
| 15 | + |
| 16 | + subscribes_to( |
| 17 | + Payments::PaymentAuthorized, |
| 18 | + Payments::PaymentReleased, |
| 19 | + Fulfillment::OrderRegistered, |
| 20 | + Pricing::OfferExpired, |
| 21 | + Fulfillment::OrderConfirmed |
| 22 | + ) |
| 23 | + |
| 24 | + def apply(event) |
| 25 | + case event |
| 26 | + when Payments::PaymentAuthorized |
| 27 | + state.with(payment: :authorized) |
| 28 | + when Payments::PaymentReleased |
| 29 | + state.with(payment: :released) |
| 30 | + when Fulfillment::OrderRegistered |
| 31 | + state.with( |
| 32 | + order: :placed, |
| 33 | + order_id: event.data.fetch(:order_id) |
| 34 | + ) |
| 35 | + when Pricing::OfferExpired |
| 36 | + state.with(order: :expired) |
| 37 | + when Fulfillment::OrderConfirmed |
| 38 | + state.with(order: :confirmed) |
33 | 39 | end |
34 | 40 | end |
35 | 41 |
|
36 | | - class ProcessState |
37 | | - def initialize |
38 | | - @order = :draft |
39 | | - @payment = :none |
40 | | - end |
| 42 | + def act |
| 43 | + release_payment if state.release? |
| 44 | + end |
41 | 45 |
|
42 | | - attr_reader :order_id |
| 46 | + private |
43 | 47 |
|
44 | | - def call(event) |
45 | | - case event |
46 | | - when Payments::PaymentAuthorized |
47 | | - @payment = :authorized |
48 | | - when Payments::PaymentReleased |
49 | | - @payment = :released |
50 | | - when Fulfillment::OrderRegistered |
51 | | - @order = :placed |
52 | | - @order_id = event.data.fetch(:order_id) |
53 | | - when Pricing::OfferExpired |
54 | | - @order = :expired |
55 | | - when Fulfillment::OrderConfirmed |
56 | | - @order = :confirmed |
57 | | - end |
58 | | - end |
| 48 | + def release_payment |
| 49 | + command_bus.call(Payments::ReleasePayment.new(order_id: state.order_id)) |
| 50 | + end |
59 | 51 |
|
60 | | - def release? |
61 | | - @payment.eql?(:authorized) && @order.eql?(:expired) |
62 | | - end |
| 52 | + def fetch_id(event) |
| 53 | + event.data.fetch(:order_id) |
63 | 54 | end |
64 | 55 | end |
65 | 56 | end |
0 commit comments