Last active
December 24, 2015 09:58
-
-
Save nicholasjhenry/6780432 to your computer and use it in GitHub Desktop.
Alternative implementation to LightService example
https://github.com/adomokos/light-service
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class TaxController < ApplicationController | |
| def update | |
| update_tax.call(order) | |
| redirect_to checkout_shipping_path(order), :notice => "Tax was calculated successfully" | |
| rescue BusinessException => e | |
| render :action => :edit, :error => e.message | |
| end | |
| private | |
| def update_tax | |
| UpdateTaxFactory.build | |
| end | |
| def order | |
| @order ||= Order.find(params[:id]) | |
| end | |
| end | |
| class UpdateTaxFactory | |
| def self.build | |
| UpdateTax.new(tax_calculator) do |service| | |
| service.add_listener FreeShippingListener.new | |
| end | |
| end | |
| private | |
| def self.tax_calculator | |
| TaxCalculator.new | |
| end | |
| end | |
| class TaxCalculator | |
| def initialize | |
| @tax_ranges = TaxRange | |
| end | |
| def calculate(order) | |
| tax_ranges = @tax_ranges.for_region(order.region) | |
| raise BusinessException.new("The tax ranges were not found") if tax_ranges.nil? | |
| tax_percentage = tax_ranges.for_total(order.total) | |
| raise BusinessException.new("The tax percentage was not found") if tax_percentage.nil? | |
| order.total * (tax_percentage/100).round(2) | |
| end | |
| end | |
| class UpdateTax | |
| include Annoucer | |
| def initialize(tax_calculator) | |
| @tax_calculator = tax_calculator | |
| yield self if block_given? | |
| end | |
| def call(order) | |
| tax_total = @tax_calculator.calculate(order) | |
| order.update_attribute(:tax, tax_total) | |
| annouce :tax_updated, order | |
| end | |
| end | |
| class FreeShippingListener | |
| def tax_updated(order) | |
| assign_free_shipping(order) | |
| end | |
| private | |
| def assign_free_shipping(order) | |
| unless FreeShippingPolicy.applicable?(order) | |
| order.provide_free_shipping! | |
| end | |
| end | |
| class FreeShippingPolicy | |
| def self.applicable?(order) | |
| order.total_with_tax > 200 | |
| end | |
| end | |
| # Framework code | |
| # | |
| require 'set' | |
| module Announcer | |
| def announce(event, *args) | |
| listeners.each { listener.send(event, *args) if listener.respond_to?(event) } | |
| end | |
| def add_listener(listener) | |
| listeners.add(listener) | |
| end | |
| def listeners | |
| @listeners ||= Set.new | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment