Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@nthj
Created November 17, 2015 17:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nthj/4b2dcdfe47fdbb0bd5c2 to your computer and use it in GitHub Desktop.
Save nthj/4b2dcdfe47fdbb0bd5c2 to your computer and use it in GitHub Desktop.
DSL for calculating various fees on an eCommerce purchase. Developed for @Ticketbud. Not our actual equation, but an example of how you could use it...
# ASSUMPTIONS
# Assumes we respond_to #fee_schedule, which has various details,
# like processor_rate, merchant_custom_handling_fee, or the like.
module CalculatorDSL
extend ActiveSupport::Concern
included do
singleton_class.send :alias_method, :method_missing, :define_method
end
def method_missing(name, &block)
unless defined?(@@calculated)
# voodoo. Sends each method defined on a calculator.
@@calculated = true and self.class.instance_methods(false).each(&method(:send))
end
self.class.send(name, &block) if block_given?
[self, fee_schedule].find { |obj| obj.respond_to?(name) }.try(name) || 0.0
end
end
class ExampleLineItemCalculator < Struct.new(:price, :fee_schedule) # lazy example, don't mind the Struct
include CalculatorDSL
# You can nest blocks as many times as you want,
# for example, if you want to wrap net and our_revenue in
# a sans_processor_fees { ... } block, go for it...
gross {
net { price +
merchant_custom_item_handling_fee } +
our_revenue { net * our_rate +
our_per_item_fee }
processor_revenue { ( net + our_revenue ) *
processor_rate }
} # end gross
end
schedule = Struct.new(:merchant_custom_item_handling_fee, :our_rate, :our_per_item_fee, :processor_rate).
new( 1.00, 0.02, 0.99, 0.029)
calculator = ExampleLineCalculator.new(10.0, schedule)
calculator.net # => 11
calculator.our_revenue # => 1.21
calculator.gross # => 12.56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment