Skip to content

Inter-organizational Contact and Time Transfers #792

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

Open
wants to merge 17 commits into
base: interbank-offer-visibility
Choose a base branch
from

Conversation

gmartincor
Copy link
Collaborator

@gmartincor gmartincor commented Apr 18, 2025

grabacion-de-pantalla-2025-04-18-a-las-194441_V2kUy43a.mp4

This pull request introduces contact and time transfers between organizations, fixes how movements derived from these flows are displayed, and adds clear messaging for users. The goal is to allow members of different time banks to collaborate without exposing private data while keeping hour accounting balanced on both sides. The changes span controllers, models, views, routes, locales, and a database migration.

Organization-to-Organization Contact

  • New contact action in PostsController: Allows a member of another organization to request the offerer's email; the request is authorized only if the requester is active in their bank and the offer is not from their own organization.

  • "Request contact" button added to offers and inquiries views when the visitor meets the above conditions.

  • Help text: Includes a banner explaining that contact data is not visible and guides the user to use the button.

  • Reusable route: The action is declared as post :contact, on: :member and added via concern to offers, inquiries, and posts, maintaining consistency with existing convention.

  • Purpose: Facilitate collaboration between organizations without exposing emails or phone numbers and without breaking the current publication flow.

Cross-Bank Transfers

  • TransferFactory

    • Adds cross_bank flag and stores metadata (source_organization_id, destination_organization_id, final_destination_user_id) in meta.
    • Determines the correct destination account based on whether the transfer is cross-bank or internal.
  • Transfer

    • New make_cross_bank_movements method that generates the 6 movements needed for the User A → Bank A → Bank B → User B flow, keeping the balance at zero in each organization.
    • Helper related_account_for used by the movements view to show the real counterpart in each entry.
  • TransfersController

    • Auxiliary action create_cross_bank_transfer that encapsulates the logic and simplifies the create action.
    • The transfers/new view displays an informative banner when @cross_bank is true.
  • Migration 20250418100031_add_cross_bank_fields_to_transfers.rb

    • Adds two columns (is_cross_bank and meta) and an index to the transfers table to manage inter-bank transfers and facilitate analytical reports.
    • is_cross_bank (boolean, default: false) indicates if the transfer involves multiple organizations.
    • The meta field (jsonb) stores additional details such as organization and end-user identifiers.
    • The index_transfers_on_is_cross_bank index optimizes frequent queries.
  • Purpose: Explicitly record inter-bank transfers, provide transparency to users, and maintain correct accounting on both sides.

Movement View Improvements

  • _movements.html.erb now invokes related_account_for when the transfer is cross-bank, so each row shows the account the user expects to see (not the intermediate step).

  • There are now two types of transfers:

    • Internal: between two members of the same time bank.
    • Cross-bank: between members of different banks (the new feature in this PR).
  • Previously, the movements view showed the counterpart using mv.other_side.account

    • This works well for internal transfers, as there are only two movements (debit-credit) and the "other side" is always the receiving user.

    • For cross-bank transfers, we generate 6 movements; there other_side is insufficient, which is why we added Transfer#related_account_for and use it only if mv.transfer.is_cross_bank is true.

    • If the transfer is internal → the view continues to show other_side.account (historical logic).

    • If it is cross-bank → the view uses related_account_for so that each entry shows the account actually involved in that step of the chain.

  • Purpose: Eliminate confusion in the movements table and promote transparency in transfers between organizations.

Internationalization and UX

  • New keys in en.yml and es.yml for buttons, banners, and flash messages.

  • Minor style adjustments (btn-primary me-2, bg-info) to maintain consistency with Bootstrap.

  • Purpose: Provide clear messages in both official languages and maintain the project's visual style.

Tests

  • Finally, several tests are added to ensure the functionality works as expected.

@gmartincor gmartincor requested a review from Copilot April 18, 2025 18:20
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This pull request adds inter‐organizational contact functionality and introduces cross‐bank time transfers while updating the related views, models, controllers, routes, locales, and database schema. Key changes include:

  • Introducing a new contact action for posts that securely handles contact requests between organizations.
  • Adding cross‐bank transfer logic in both the Transfer model and TransferFactory, with adjustments to controllers and views to support the 6‐movement flow.
  • Updating internationalization files and UI elements to clearly inform users regarding contact privacy and cross‐bank transfers.

Reviewed Changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
db/migrate/20250418100031_add_cross_bank_fields_to_transfers.rb Adds migration for cross-bank support by including a jsonb meta field.
config/routes.rb Introduces a reusable route concern for contact functionality.
config/locales/(en es).yml
app/views/transfers/new.html.erb Updates transfer form to handle cross-bank transfers with hidden fields.
app/views/shared/_post.html.erb Modifies alert messaging for posts to indicate contact information handling.
app/views/shared/_movements.html.erb Adjusts movement display to use the related account for cross-bank transfers.
app/views/organization_notifier/contact_request.html.erb Implements new contact request email view.
app/views/(offers inquiries)/show.html.erb
app/models/transfer_factory.rb Enhances transfer creation with a cross-bank flag and related account logic.
app/models/transfer.rb Implements cross-bank movements and related account lookup logic.
app/mailers/organization_notifier.rb Adds a mailer action for contact requests.
app/controllers/(transfers posts
Comments suppressed due to low confidence (1)

app/models/transfer_factory.rb:72

  • [nitpick] Consider replacing the class equality check with a more robust type verification (e.g., using 'is_a?(Organization)') to improve clarity and resilience.
destination_account.try(:accountable).class == Organization

elsif offer
# Get the destination account from the offer's user
member = offer.user.members.find_by(organization: offer.organization)
member.account if member
Copy link
Preview

Copilot AI Apr 18, 2025

Choose a reason for hiding this comment

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

If no member is found for the offer's user in the offer's organization, the destination account will be nil, which could lead to runtime errors. Consider adding a fallback mechanism or explicit error handling.

Suggested change
member.account if member
if member
member.account
else
nil # Fallback when no member is found
end

Copilot uses AI. Check for mistakes.

@@ -3,6 +3,13 @@ class TransfersController < ApplicationController

def create
@source = find_source

if params[:cross_bank] == "true" && params[:post_id].present?
Copy link
Preview

Copilot AI Apr 18, 2025

Choose a reason for hiding this comment

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

[nitpick] Relying on a string comparison for the 'cross_bank' parameter could be error-prone if the parameter type changes. Consider normalizing the parameter to a boolean value before performing the comparison.

Suggested change
if params[:cross_bank] == "true" && params[:post_id].present?
if normalize_to_boolean(params[:cross_bank]) && params[:post_id].present?

Copilot uses AI. Check for mistakes.

@franpb14 franpb14 changed the base branch from interbank-offer-visibility to time-between-banks-base April 21, 2025 18:41
@franpb14 franpb14 changed the base branch from time-between-banks-base to interbank-offer-visibility April 21, 2025 18:42
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.

1 participant