Method: ActiveShipping::RateEstimate#origin

Defined in:
lib/active_shipping/rate_estimate.rb,
lib/active_shipping/rate_estimate.rb

#originActiveShipping::Location

The origin of the shipment



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/active_shipping/rate_estimate.rb', line 69

class RateEstimate
  attr_accessor :origin, :destination, :package_rates,
              :carrier, :service_name, :service_code,
              :shipping_date, :delivery_date, :delivery_range,
              :currency, :negotiated_rate, :insurance_price,
              :estimate_reference, :expires_at, :pickup_time,
              :compare_price, :phone_required, :delivery_category

  def initialize(origin, destination, carrier, service_name, options = {})
    self.origin, self.destination, self.carrier, self.service_name = origin, destination, carrier, service_name
    self.service_code = options[:service_code]
    self.estimate_reference = options[:estimate_reference]
    self.pickup_time = options[:pickup_time]
    self.expires_at = options[:expires_at]
    if options[:package_rates]
      self.package_rates = options[:package_rates].map { |p| p.update(:rate => Package.cents_from(p[:rate])) }
    else
      self.package_rates = Array(options[:packages]).map { |p| {:package => p} }
    end
    self.total_price = options[:total_price]
    self.negotiated_rate = options[:negotiated_rate]
    self.compare_price = options[:compare_price]
    self.phone_required = options[:phone_required]
    self.currency = options[:currency]
    self.delivery_range = options[:delivery_range]
    self.shipping_date = options[:shipping_date]
    self.delivery_date = @delivery_range.last
    self.insurance_price = options[:insurance_price]
    self.delivery_category = options[:delivery_category]
  end

  # The total price of the shipments in cents.
  # @return [Integer]
  def total_price
    @total_price || @package_rates.sum { |pr| pr[:rate] }
  rescue NoMethodError
    raise ArgumentError.new("RateEstimate must have a total_price set, or have a full set of valid package rates.")
  end
  alias_method :price, :total_price

  # Adds a package to this rate estimate
  # @param package [ActiveShipping::Package] The package to add.
  # @param rate [#cents, Float, String, nil] The rate for this package. This is only required if
  #   there is no total price for this shipment
  # @return [self]
  def add(package, rate = nil)
    cents = Package.cents_from(rate)
    raise ArgumentError.new("New packages must have valid rate information since this RateEstimate has no total_price set.") if cents.nil? and total_price.nil?
    @package_rates << {:package => package, :rate => cents}
    self
  end

  # The list of packages for which rate estimates are given.
  # @return [Array<ActiveShipping::Package>]
  def packages
    package_rates.map { |p| p[:package] }
  end

  # The number of packages for which rate estimates are given.
  # @return [Integer]
  def package_count
    package_rates.length
  end

  protected

  def delivery_range=(delivery_range)
    @delivery_range = delivery_range ? delivery_range.map { |date| date_for(date) }.compact : []
  end

  def total_price=(total_price)
    @total_price = Package.cents_from(total_price)
  end

  def negotiated_rate=(negotiated_rate)
    @negotiated_rate = negotiated_rate ? Package.cents_from(negotiated_rate) : nil
  end

  def compare_price=(compare_price)
    @compare_price = compare_price ? Package.cents_from(compare_price) : nil
  end

  def currency=(currency)
    @currency = ActiveUtils::CurrencyCode.standardize(currency)
  end

  def phone_required=(phone_required)
    @phone_required = !!phone_required
  end

  def shipping_date=(shipping_date)
    @shipping_date = date_for(shipping_date)
  end

  def insurance_price=(insurance_price)
    @insurance_price = Package.cents_from(insurance_price)
  end

  private

  # Returns a Date object for a given input
  # @param [String, Date, Time, DateTime, ...] The object to infer a date from.
  # @return [Date, nil] The Date object absed on the input, or `nil` if no date
  #   could be determined.
  def date_for(date)
    date && DateTime.strptime(date.to_s, "%Y-%m-%d")
  rescue ArgumentError
    nil
  end
end