Skip to content
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

Adding/Removing items to refunds #425

Open
wants to merge 5 commits into
base: add-new-refund-form
Choose a base branch
from

Conversation

marlena-b
Copy link
Collaborator

Issue: #154

This is the second step to allow order refunds. First step is here: #424.

  • add/remove buttons now works, the form can be filled
  • the form cannot be submitted yet - it will be added in another PR :)
Nagranie.z.ekranu.2025-01-7.o.10.07.34.mov

end

def remove_item(product_id)
raise ProductNotFoundError unless @refund_items.quantity(product_id).positive?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this error could have more meaningful business name. Something like RefundHaveNotBeenRequestedForThisProduct

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea, I changed the name 👍

def call(event)
refund_id = event.data.fetch(:refund_id)
product_id = event.data.fetch(:product_id)
item = find(refund_id, product_id)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this event handler idempotent?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, it isn't, but most, if not all, of our event handlers aren't idempotent 🤔 I'm not sure if I know how to make it idempotent, maybe you have some ideas?

@@ -0,0 +1,11 @@
module Ordering
class Projections
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Projection is an implementation detail. I suggest calling this class ProductQuantityAvailableToRefund. Method could be named as call

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, changed!

@@ -12,6 +12,14 @@ def create
redirect_to edit_order_refund_path(refund_id, order_id: params[:order_id])
end

def add_item
add_item_to_refund
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this abstraction brings any benefit. Do you think it is more readable this way?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tbh I followed the same pattern as is in e.g. products_controller but it is not followed everywhere so it might also be done without this abstraction.

refund.add_item(command.product_id)
refund.add_item(
command.product_id,
available_quantity_to_refund(command.order_id, command.product_id)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that the available quantity to refund information should be passed to Refund once it is requested. We don't want this value to be changed.

I see it that way:

  • Order has been paid
  • Someone wants to refund part of it or whole
  • Refund is created, it knows what products (or how many this case*) were there in the order
  • It allows refunding those products or not
    • Perhaps it should know which products were in the order initially, not only quantity of them?
  • Are we talking about refunding items or product? Method names of refund imply items, but projection's method indicates product.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion! I'm not sure if I understand what you mean.
You propose that when creating a Refund, we should pass in all the quantities per product (e.g., { product_1_id: 13, product_2_id: 3 }), and store this information within the Refund aggregate. This would allow us to validate refund operations against the original available quantities without needing to query the projection each time.
Is that what you mean?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants