Added Editing Wise Reimbursements: Admins can now edit the payout inf…#13758
Added Editing Wise Reimbursements: Admins can now edit the payout inf…#13758Acidicts wants to merge 4 commits into
Conversation
…o on case by case basis without editing user payout data, only the reimbursement's info which is prefilled with user payout settings
…in and report is open
There was a problem hiding this comment.
Pull request overview
Adds an admin-editable Wise transfer draft layer for reimbursement reports, so ops can correct payout info on a Wise reimbursement without mutating the recipient's saved User::PayoutMethod. A new Reimbursement::WiseTransferDraft model is auto-populated from the user's payout method on report submission/show, surfaced through a modal-driven edit form on the report page, and consumed by admin_send_wise_transfer when fulfilling the transfer.
Changes:
- Introduce
Reimbursement::WiseTransferDraft(model, migrations,has_oneonReport,ensure_wise_transfer_draft!seeding helper). - Add
update_wise_transfer_draftcontroller action, policy, route, and an "Edit Wise Info" modal/form on the report show page; switch payout/wise information views to prefer draft → payout_holding wise_transfer → payout_method. - Tighten
WiseTransfersControlleredit/updateto respecteditable?, and hardenHcbCode::Memo#reimbursement_expense_payout_memoagainst nil.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| db/migrate/20260519000000_create_reimbursement_wise_transfer_drafts.rb | Creates the new drafts table (uses Migration[7.0]). |
| db/migrate/20260519000100_add_wise_recipient_id_to_reimbursement_wise_transfer_drafts.rb | Adds wise_recipient_id in a second migration. |
| db/schema.rb | Schema dump for the new table and FK. |
| config/routes.rb | Adds POST update_wise_transfer_draft member route. |
| app/models/reimbursement/wise_transfer_draft.rb | New draft model using HasWiseRecipient and encrypted recipient_information. |
| app/models/reimbursement/report.rb | Adds has_one :wise_transfer_draft and ensure_wise_transfer_draft! seeding. |
| app/models/hcb_code/memo.rb | Nil-safe expense payout memo. |
| app/policies/reimbursement/report_policy.rb | Adds admin-only update_wise_transfer_draft?. |
| app/controllers/reimbursement/reports_controller.rb | New update_wise_transfer_draft action and draft-aware fields in admin_send_wise_transfer; ensures draft on show. |
| app/controllers/wise_transfers_controller.rb | Blocks edit/update when transfer is no longer editable. |
| app/views/reimbursement/reports/show.html.erb | Renders the new edit Wise info modal. |
| app/views/reimbursement/reports/_edit_wise_info_modal.html.erb | Modal wrapper for the draft form. |
| app/views/reimbursement/reports/_wise_transfer_draft_form.html.erb | New admin-facing form (currency select is disabled). |
| app/views/reimbursement/reports/_wise_information.html.erb | Switches data source to draft → payout_method. |
| app/views/reimbursement/reports/_payout_information.html.erb | Adds edit button and prefers draft/holding transfer for Wise display. |
| app/views/reimbursement/reports/_actions.html.erb | Switches the Wise quick-link to read wise_recipient_id from the draft. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @@ -0,0 +1,22 @@ | |||
| # frozen_string_literal: true | |||
|
|
|||
| class CreateReimbursementWiseTransferDrafts < ActiveRecord::Migration[7.0] | |||
| @@ -0,0 +1,7 @@ | |||
| # frozen_string_literal: true | |||
|
|
|||
| class AddWiseRecipientIdToReimbursementWiseTransferDrafts < ActiveRecord::Migration[7.0] | |||
| <% if report.wise_transfer_draft.wise_recipient_id.present? %> | ||
| <%= link_to "https://wise.com/send#?contact=#{report.wise_transfer_draft.wise_recipient_id}", class: "btn btn-small tooltipped tooltipped--w bg-[#9FE870] text-[#163300] flex-shrink-0", style: "color: #163300!important; background: #9FE870", target: "_blank", "aria-label": "Use recipient information from previous transfer" do %> |
| <% if auditor_signed_in? && !report.closed? && payout_method.is_a?(User::PayoutMethod::WiseTransfer) %> | ||
| <%= pop_icon_to "settings", | ||
| "#", | ||
| data: { behavior: "modal_trigger", modal: "edit_wise_info" }, | ||
| icon_size: 28, | ||
| class: "tooltipped tooltipped--w", | ||
| style: "height: 32px; width: 32px;", | ||
| 'aria-label': "Edit Wise Info", | ||
| disabled: !policy(@report).edit? %> |
| recipient_information: user.payout_method.recipient_information&.deep_dup | ||
| ) | ||
| draft.account_holder = account_holder if account_holder.present? | ||
| draft.save! |
| <tr> | ||
| <td>Name on account:</td> | ||
| <td><%= payout_method.try(:account_holder).presence || user.full_name %></td> | ||
| <td><%= wise_display&.account_holder.presence || payout_method.try(:account_holder).presence || user.full_name %></td> |
| @@ -1,5 +1,7 @@ | |||
| <%# locals: (report:) %> | |||
|
|
|||
| <% wise_details = report.wise_transfer_draft || report.user.payout_method %> | |||
| <div class="field"> | ||
| <%= form.label :currency, "Currency" %> | ||
| <%= form.select :currency, WiseTransfer::AVAILABLE_CURRENCIES, { selected: wise_transfer_draft.currency || report.currency, disabled: true }, { "@change" => "currency = $event.target.value;" } %> | ||
| </div> |
…d field descriptions and indexes Co-authored-by: Copilot <copilot@github.com>
|
Hi @Acidicts! Thanks for submitting this PR, however, #13724 is intended for editing Wise Transfers and is unrelated to reimbursements. I appreciate you taking the time and effort to tackle this, but unfortunately, it's not what we're looking for. You're always welcome to contribute/tackle other open issues, and we're happy to answer any clarifying questions you have. |
Summary of the problem
Ops were unable to edit payout info on a Wise Transfer
Describe your changes
I added a wise_transfer_draft which is created with reimbursement and is prefilled with user data. The draft can be edited without editing user payout info, and when processing/approving the draft info is carried forward for fufillment.
Demo video - Note i got a bit lost in the UI, but it shows the changes
Screen.Recording.2026-05-19.at.16.21.17.mov
Image to show that the button to open the wise transfer menu isn't showing for other payout methods