Module: ONIX::ProductSuppliesMethods

Included in:
ONIX21::Product, Product
Defined in:
lib/onix/product_supplies_methods.rb

Overview

flattened supplies extractor

High level collapse

Instance Method Details

#add_ending_period(supply, global_supply) ⇒ Object



197
198
199
200
201
202
# File 'lib/onix/product_supplies_methods.rb', line 197

def add_ending_period(supply, global_supply)
  missing_supply = global_supply.dup
  missing_supply[:from_date] = supply[:until_date] + 1

  [supply, missing_supply]
end

#add_missing_periods(supplies, global_supply) ⇒ Object



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/onix/product_supplies_methods.rb', line 169

def add_missing_periods(supplies, global_supply)
  new_supplies = []

  supplies.each.with_index do |supply, index|
    new_supplies << global_supply.dup.tap { |start_sup| start_sup[:until_date] = supply[:from_date] - 1 } if index == 0

    if index > 0 && index != supplies.length
      new_supplies << global_supply.dup.tap do |missing_supply|
        missing_supply[:from_date] = supplies[index - 1][:until_date] + 1
        missing_supply[:until_date] = supply[:from_date] - 1
      end
    end

    new_supplies << supply

    new_supplies << global_supply.dup.tap { |end_sup| end_sup[:from_date] = supply[:until_date] + 1 } if index == supplies.length - 1
  end

  new_supplies
end

#add_starting_period(supply, global_supply) ⇒ Object



190
191
192
193
194
195
# File 'lib/onix/product_supplies_methods.rb', line 190

def add_starting_period(supply, global_supply)
  missing_supply = global_supply.dup
  missing_supply[:until_date] = supply[:from_date] - 1

  [missing_supply, supply]
end

#at_time_price_amount_for(time, currency, country = nil) ⇒ Object

price amount for given currency and country at time



235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
# File 'lib/onix/product_supplies_methods.rb', line 235

def at_time_price_amount_for(time, currency, country = nil)
  sups = self.supplies_with_default_tax.select { |p| p[:currency] == currency }
  if country
    sups = sups.select { |p| p[:territory].include?(country) }
  end
  if sups.length > 0
    # exclusive
    sup = sups.first[:prices].select { |p|
      (!p[:from_date] or p[:from_date].to_date <= time.to_date) and
          (!p[:until_date] or p[:until_date].to_date > time.to_date)
    }.first

    if sup
      sup[:amount]
    else
      # or inclusive
      sup = sups.first[:prices].select { |p|
        (!p[:from_date] or p[:from_date].to_date <= time.to_date) and
            (!p[:until_date] or p[:until_date].to_date >= time.to_date)
      }.first

      if sup
        sup[:amount]
      else
        nil
      end
    end

  else
    nil
  end
end

#current_price_amount_for(currency, country = nil) ⇒ Object

current price amount for given currency and country



269
270
271
# File 'lib/onix/product_supplies_methods.rb', line 269

def current_price_amount_for(currency, country = nil)
  at_time_price_amount_for(Time.now, currency, country)
end

#prices_with_periods(supplies, global_supply) ⇒ Object

add missing periods when they can be guessed



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/onix/product_supplies_methods.rb', line 151

def prices_with_periods(supplies, global_supply)
  complete_supplies = supplies.select { |supply| supply[:from_date] && supply[:until_date] }.sort_by { |supply| supply[:from_date] }
  missing_start_period_supplies = supplies.select { |supply| supply[:from_date] && !supply[:until_date] }.sort_by { |supply| supply[:from_date] }
  missing_end_period_supplies = supplies.select { |supply| !supply[:from_date] && supply[:until_date] }.sort_by { |supply| supply[:until_date] }

  return [global_supply] if [complete_supplies, missing_start_period_supplies, missing_end_period_supplies].all? { |supply| supply.empty? }

  return self.add_missing_periods(complete_supplies, global_supply) unless complete_supplies.empty?

  without_start = missing_start_period_supplies.length == 1 && complete_supplies.empty? && missing_end_period_supplies.empty?
  without_end = missing_end_period_supplies.length == 1 && complete_supplies.empty? && missing_start_period_supplies.empty?

  return self.add_starting_period(missing_start_period_supplies.first, global_supply) if without_start
  return self.add_ending_period(missing_end_period_supplies.first, global_supply) if without_end

  [global_supply]
end

#supplies(keep_all_prices_dates = false) ⇒ Object

flattened supplies with prices

supplies is a hash symbol array in the form :

[{:available=>bool,
  :availability_date=>date,
  :including_tax=>bool,
  :currency=>string,
  :territory=>string,
  :suppliers=>[Supplier,...],
  :prices=>[{:amount=>int,
             :from_date=>date,
             :until_date=>date,
             :tax=>{:amount=>int, :rate_percent=>float}}]}]


23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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
# File 'lib/onix/product_supplies_methods.rb', line 23

def supplies(keep_all_prices_dates = false)
  supplies = []

  # add territories if missing
  if self.product_supplies
    self.product_supplies.each do |ps|
      ps.supply_details.each do |sd|
        sd.prices.each do |p|
          supply = {}
          supply[:suppliers] = sd.suppliers
          supply[:available] = sd.available?
          supply[:availability_date] = sd.availability_date

          unless supply[:availability_date]
            if ps.availability_date
              supply[:availability_date] = ps.market_publishing_detail.availability_date
            end
          end
          supply[:price] = p.amount
          supply[:qualifier] = p.qualifier.human if p.qualifier
          supply[:including_tax] = p.including_tax?
          if !p.territory or p.territory.countries.length == 0
            supply[:territory] = []
            supply[:territory] = ps.countries

            if supply[:territory].length == 0
              if @publishing_detail
                supply[:territory] = self.countries_rights
              end
            end
          else
            supply[:territory] = p.territory.countries
          end
          supply[:from_date] = p.from_date
          supply[:until_date] = p.until_date
          supply[:currency] = p.currency
          supply[:tax] = p.tax

          unless supply[:availability_date]
            if @publishing_detail
              supply[:availability_date] = @publishing_detail.publication_date
            end
          end

          supplies << supply
        end
      end
    end
  end

  grouped_supplies = {}
  supplies.each do |supply|
    supply[:territory].each do |territory|
      pr_key = "#{supply[:available]}_#{supply[:including_tax]}_#{supply[:currency]}_#{territory}"
      grouped_supplies[pr_key] ||= []
      grouped_supplies[pr_key] << supply
    end
  end

  nb_suppliers = supplies.map { |s| s[:suppliers][0].name }.uniq.length
  # render prices sequentially with dates
  grouped_supplies.each do |ksup, supply|
    if supply.length > 1
      global_price = supply.select { |p| not p[:from_date] and not p[:until_date] }
      global_price = global_price.first

      if global_price
        if nb_suppliers > 1
          grouped_supplies[ksup] += self.prices_with_periods(supply, global_price)
        else
          grouped_supplies[ksup] = self.prices_with_periods(supply, global_price)
        end
        grouped_supplies[ksup].uniq!
      else
        # remove explicit from date
        explicit_from = supply.select { |p| p[:from_date] and not supply.select { |sp| sp[:until_date] and sp[:until_date] <= p[:from_date] }.first }.first
        if explicit_from
          explicit_from[:from_date] = nil unless keep_all_prices_dates
        end
      end
    else
      supply.each do |s|
        if s[:from_date] and s[:availability_date] and s[:from_date] >= s[:availability_date]
          s[:availability_date] = s[:from_date]
        end
        s[:from_date] = nil unless keep_all_prices_dates
      end
    end
  end

  # merge by territories
  grouped_territories_supplies = {}
  grouped_supplies.values.each do |supply|
    fsupply = supply.first
    pr_key = "#{fsupply[:available]}_#{fsupply[:including_tax]}_#{fsupply[:currency]}"
    supply.each do |s|
      pr_key += "_#{s[:price]}_#{s[:from_date]}_#{s[:until_date]}"
    end
    grouped_territories_supplies[pr_key] ||= []
    grouped_territories_supplies[pr_key] << supply
  end

  supplies = []

  grouped_territories_supplies.values.each do |supply|
    fsupply = supply.first.first
    supplies << {:including_tax => fsupply[:including_tax], :currency => fsupply[:currency],
                 :territory => supply.map { |fs| fs.map { |s| s[:territory] } }.flatten.uniq,
                 :available => fsupply[:available],
                 :availability_date => fsupply[:availability_date],
                 :suppliers => fsupply[:suppliers],
                 :prices => supply.first.map { |s|

                   s[:amount] = s[:price]
                   s.delete(:price)
                   s.delete(:available)
                   s.delete(:currency)
                   s.delete(:availability_date)
                   s.delete(:including_tax)
                   s.delete(:territory)
                   s
                 }}
  end

  supplies
end

#supplies_excluding_taxObject

flattened supplies only excluding taxes



210
211
212
# File 'lib/onix/product_supplies_methods.rb', line 210

def supplies_excluding_tax
  self.supplies.select { |p| not p[:including_tax] }
end

#supplies_for_country(country, currency = nil) ⇒ Object

flattened supplies for country



220
221
222
223
224
225
226
227
228
229
230
231
232
# File 'lib/onix/product_supplies_methods.rb', line 220

def supplies_for_country(country, currency = nil)
  country_supplies = self.supplies
  if currency
    country_supplies = country_supplies.select { |s| s[:currency] == currency }
  end
  country_supplies.select { |s|
    if s[:territory].include?(country)
      true
    else
      false
    end
  }
end

#supplies_including_taxObject

flattened supplies only including taxes



205
206
207
# File 'lib/onix/product_supplies_methods.rb', line 205

def supplies_including_tax
  self.supplies.select { |p| p[:including_tax] }
end

#supplies_with_default_taxObject

flattened supplies with default tax (excluding tax for US and CA, including otherwise)



215
216
217
# File 'lib/onix/product_supplies_methods.rb', line 215

def supplies_with_default_tax
  self.supplies_including_tax + self.supplies_excluding_tax.select { |s| ["CAD", "USD"].include?(s[:currency]) }
end