MriHook is a Ruby gem that provides a simple interface to interact with the MRI ERP API. It allows you to retrieve information from MRI and map the responses to Ruby objects.
Add this line to your application's Gemfile:
gem 'mri_hook'And then execute:
bundle installOr install it yourself as:
gem install mri_hookMriHook requires the following environment variables to be set:
ENV['BASE_MRI_DOMAIN'] = 'https://mrix5api.saas.mrisoftware.com' # Default if not set
ENV['BASE_MRI_API_ENDPOINT'] = '/mriapiservices/api.asp' # Default if not set
ENV['MRI_USERNAME'] = 'your_username' # Required
ENV['MRI_PASSWORD'] = 'your_password' # RequiredYou can create your own .env.development file in the root of your project to set these variables, or you can set them directly in your environment.
Below you can see how to "load" them in irb
If run in IRB, important to run the following command to load the gem:
require 'bundler/setup'
require 'dotenv'
Dotenv.load('.env.development')
require 'mri_hook'# Create a handler for the residents by property endpoint
handler = MriHook::RequestHandlers::ResidentsByPropertyHandler.new
# Execute the request with the property ID
result = handler.execute(property_id: 'GCNS01')
# Process the residents
result[:values].each do |resident|
puts "Name: #{resident.full_name}"
puts "Status: #{resident.status}"
puts "Active: #{resident.active?}"
puts "Owner: #{resident.owner?}"
puts "Unit: #{resident.unit_id}"
puts "---"
end
# Check if there are more pages
if result[:next_link]
puts "More residents available. Use pagination to retrieve them."
endThe ResidentsHandler allows you to retrieve residents using different parameter combinations:
# Create a handler for the residents endpoint
handler = MriHook::RequestHandlers::ResidentsHandler.new
# Option 1: Get residents by last update date
result = handler.execute(last_update: '01-01-2024')
# Option 2: Get residents by name ID
result = handler.execute(resident_name_id: '0000000298')
# Option 3: Get residents by date range
result = handler.execute(start_date: '01-01-2024', end_date: '01-31-2024')
# Option 4: Get residents by property ID, type, and status
result = handler.execute(property_id: 'GCNS01', type: 'R', status: 'O')
# You can also control whether to include PII (Personally Identifiable Information)
# By default, PII is included (include_pii: true)
result = handler.execute(last_update: '01-01-2024', include_pii: false)
# Process the residents
result[:values].each do |resident|
puts "Name: #{resident.full_name}"
puts "Status: #{resident.status}"
puts "Active: #{resident.active?}"
puts "Owner: #{resident.owner?}"
puts "Unit: #{resident.unit_id}"
puts "---"
end
# Check if there are more pages
if result[:next_link]
puts "More residents available. Use pagination to retrieve them."
endThe ResidentLeaseDetailsByPropertyHandler allows you to retrieve lease details for residents:
# Create a handler for the resident lease details endpoint
handler = MriHook::RequestHandlers::ResidentLeaseDetailsByPropertyHandler.new
# Option 1: Get lease details by property ID
result = handler.execute(property_id: 'GCNS01')
# Option 2: Get lease details by last update date
result = handler.execute(last_update_date: '2020-02-25')
# Option 3: Get lease details by date range
result = handler.execute(start_date: '2019-05-01', end_date: '2020-04-30')
# Process the lease details
result[:values].each do |lease|
puts "Resident: #{lease.full_name}"
puts "Property: #{lease.property_id}, Building: #{lease.building_id}, Unit: #{lease.unit_id}"
puts "Lease Start: #{lease.lease_start}, Lease End: #{lease.lease_end}"
puts "Monthly Rent: #{lease.monthly_rent} #{lease.curr_code}"
puts "Current: #{lease.current?}, Month-to-Month: #{lease.month_to_month?}"
puts "Has Pet: #{lease.has_pet?}"
puts "---"
end
# Check if there are more pages
if result[:next_link]
puts "More lease details available. Use pagination to retrieve them."
endThe OpenChargesHandler allows you to retrieve open charges for residents:
# Create a handler for the open charges endpoint
handler = MriHook::RequestHandlers::OpenChargesHandler.new
# Option 1: Get open charges by property ID
result = handler.execute(property_id: 'GCNS01')
# Option 2: Get open charges by last update date
result = handler.execute(last_update: '2024-01-01')
# Option 3: Get open charges by property ID and resident ID
result = handler.execute(property_id: 'GCNS01', resident_id: '0000000502')
# Process the open charges
result[:values].each do |charge|
puts "Resident: #{charge.full_name}"
puts "Property: #{charge.property_id}, Unit: #{charge.unit_unique_tag}"
puts "Charge Date: #{charge.charge_date}, Description: #{charge.description}"
puts "Charge Code: #{charge.charge_code} - #{charge.charge_code_description}"
puts "Original Amount: #{charge.original_amount_value}, Unpaid Amount: #{charge.unpaid_amount_value}"
puts "Late Fee: #{charge.late_fee?}, Auto-Generated: #{charge.auto_generated?}, Posted: #{charge.posted?}"
puts "---"
end
# Check if there are more pages
if result[:next_link]
puts "More charges available. Use pagination to retrieve them."
endThe PendingMoveInsHandler allows you to retrieve information about residents who are scheduled to move in:
# Create a handler for the pending move-ins endpoint
handler = MriHook::RequestHandlers::PendingMoveInsHandler.new
# Get pending move-ins by property ID
result = handler.execute(property_id: 'GCCH02')
# Process the pending move-ins
result[:values].each do |move_in|
puts "Resident: #{move_in.full_name}"
puts "Property: #{move_in.property_id}, Building: #{move_in.building_id}, Unit: #{move_in.unit_id}"
puts "Scheduled Move-In Date: #{move_in.scheduled_move_in_date}"
puts "Email: #{move_in.email}"
# Access previous address information if available
if move_in.primary_previous_address
puts "Previous Address: #{move_in.primary_previous_address.full_address}"
end
puts "---"
end
# Check if there are more pages
if result[:next_link]
puts "More pending move-ins available. Use pagination to retrieve them."
endThe ResidentLedgerHandler allows you to retrieve ledger transactions for a resident:
# Create a handler for the resident ledger endpoint
handler = MriHook::RequestHandlers::ResidentLedgerHandler.new
# Get ledger transactions for a resident
# Note: All parameters are required and dates must be in yyyy-mm-dd format
result = handler.execute(
start_date: '2024-01-01',
end_date: '2025-06-30',
resident_name_id: '0000009006',
property_id: 'GCCH01'
)
# Process the ledger transactions
result[:values].each do |transaction|
puts "Transaction ID: #{transaction.transaction_id}"
puts "Date: #{transaction.transaction_date}"
puts "Description: #{transaction.description}"
puts "Amount: #{transaction.transaction_amount_value}"
puts "Type: #{transaction.payment? ? 'Payment' : (transaction.charge? ? 'Charge' : 'Other')}"
puts "Posted: #{transaction.posted? ? 'Yes' : 'No'}"
puts "---"
end
# Check if there are more pages
if result[:next_link]
puts "More transactions available. Use pagination to retrieve them."
endThe PaymentSubmitterHandler allows you to post payment details to MRI:
# Create a handler for the payment details endpoint
handler = MriHook::RequestHandlers::PaymentSubmitterHandler.new
# Post payment details
# Note: All parameters except check_url and deposit_date are required
# Also, on every transaction: check_number, external_transaction_number, and external_batch_id are required and they can't be repeated
payment = handler.execute(
resident_name_id: '0000000467',
property_id: 'GCNS01',
paid_at: DateTime.parse('2024-02-22'),
amount: 1000.00,
check_number: '1232',
external_transaction_number: '0000000002',
charge_id: '0000325496', # Coming from the OpenChargesHandler/Ledger
external_batch_id: 'B1',
description: 'Custom Description',
batch_description: 'Custom Description',
check_url: 'http://example.mrisoftware.com/checkImage', # Optional, defaults to nil
deposit_date: DateTime.parse('2024-12-12'), # Optional, defaults to paid_at
cash_type: "V2" # Optional, defaults to VM
)
# Process the payment response
puts "Transaction ID: #{payment.transaction_id}"
puts "Resident Name ID: #{payment.resident_name_id}"
puts "Property ID: #{payment.property_id}"
puts "Charge Code: #{payment.charge_code}"
puts "Payment Amount: #{payment.amount}"
puts "Batch ID: #{payment.batch_id}"
puts "Transaction ID": "#{payment.transaction_id}" # This is the ID of the transaction in MRINote the following field length restrictions:
- check_number: maximum 15 characters
- external_transaction_number: maximum 10 characters
- external_batch_id: maximum 30 characters
- description: maximum 30 characters
- batch_description: maximum 30 characters
After checking out the repo, run bin/setup to install dependencies. You can also run bin/console for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and the created tag, and push the .gem file to rubygems.org.
MRI API endpoints that return large datasets support pagination. The MriHook gem handles this by returning a hash with two keys:
values: An array of objects (residents, leases, transactions, etc.)next_link: A URL string for the next page of results, ornilif there are no more pages
All request handlers now return a hash with the following structure:
{
values: [/* Array of objects (residents, leases, etc.) */],
next_link: "https://mrix5api.saas.mrisoftware.com/mriapiservices/api.asp?%24api=..." # URL for next page or nil
}To paginate through results, you can use the next_link value to determine if there are more pages available, and then make subsequent requests with the appropriate pagination parameters:
# Create a handler
handler = MriHook::RequestHandlers::ResidentsByPropertyHandler.new
# Get the first page of results (default is 300 records)
result = handler.execute(property_id: 'GCNS01')
# Process the current page of residents
result[:values].each do |resident|
puts "Name: #{resident.full_name}"
end
# Check if there are more pages
if result[:next_link]
# Extract pagination parameters from next_link
# The next_link URL typically includes top and skip parameters
# You can parse these or simply use your own values
# Get the next page (for example, skip the first 300 records)
next_link = result[:next_link]
next_page = handler.execute(property_id: 'GCNS01', top: next_link[:top], skip: next_link[:skip])
# Process the next page
next_page[:values].each do |resident|
puts "Name: #{resident.full_name}"
end
endBug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/mri_hook. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
Everyone interacting in the MriHook project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.