Skip to content

Instantly share code, notes, and snippets.

@davydotcom
Last active December 10, 2015 15:08
Show Gist options
  • Select an option

  • Save davydotcom/4452487 to your computer and use it in GitHub Desktop.

Select an option

Save davydotcom/4452487 to your computer and use it in GitHub Desktop.
Example of creating a service class in Rails that uses exception raising
class Gl::TransactionsController < ApplicationController
def new
end
def create
teller = Gl::TellerService.new()
response = teller.transfer_funds(params)
if response.successful?
@transactions = response.data
respond_with @transactions
else
flash[:error] = response.errors.join(", ")
redirect_to gl_accounts_url and return false
end
end
end
class Gl::TellerService
def transfer_funds(options)
source_account = Gl::Account.where(:id => options[:source_account_id]).first
destination_account = Gl::Account.where(:id => options[:account_id]).first
return ServiceResponse.error("Source Account not found!") if source_account.blank?
return ServiceResponse.error("Destination Account not found!") if destination_account.blank?
return ServiceResponse.error("Amount must be specified and > 0") if options[:amount].blank? || options[:amount] <= 0
period = period_for_transaction(source_account.company, options[:transaction_date] || Time.now)
if period.blank?
return ServiceResponse.error("GL Period not found for the specified transaction date.")
end
options.merge! period
source_transaction = create_transaction(source_account, options, !source_account.debit_account?)
destination_transaction = create_transaction(destination_account, options, destination_account.debit_account?)
begin
Gl::Account.transaction do
source_transaction.save!
destination_transaction.save!
end
rescue ActiveRecord::RecordInvalid
return ServiceResponse.error("Invalid Transaction Records")
end
return ServiceResponse.success([source_transaction, destination_transaction])
end
private
def period_for_transaction(company, transaction_date=Time.now)
if company.use_gl_periods
period = Gl::Period.where(:company_id => self.company_id).where(["start_date >= :transaction_date AND end_date < :transaction_date",{:transaction_date => transaction_date}]).first
return nil if period.blank?
return {:gl_period => period.period_number, :gl_period_year => period.period_year}
else
{:gl_period => transaction_date.month, :gl_period_year => transaction_date.year}
end
end
def create_transaction(account, options, debit)
transaction = account.transactions.new(:gl_period => options[:gl_period],:gl_period_year => options[:gl_period_year], :transaction_date => options[:transaction_date] || Time.now,:memo => options[:memo],:source => options[:source] ? options[:source] : "Manual")
if debit
transaction.debit = options[:amount]
else
transaction.credit = options[:amount]
end
return transaction
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment