Class: GoogleI18n::Address

Inherits:
Object
  • Object
show all
Defined in:
lib/google_i18n/address.rb

Constant Summary collapse

VALID_COUNTRY_CODE =
%r(^\w{2,3}$)
VALIDATION_DATA_DIR =
File.join(File.dirname(__FILE__), "data")
VALIDATION_DATA_PATH =
File.join(VALIDATION_DATA_DIR, "%s.json")
FIELD_MAPPING =
{
  "A" => "street_address",
  "C" => "city",
  "D" => "city_area",
  "N" => "name",
  "O" => "company_name",
  "S" => "country_area",
  "X" => "sorting_code",
  "Z" => "postal_code",
}
KNOWN_FIELDS =
FIELD_MAPPING.values.push("country_code")

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ GoogleI18n::Address

Creates a new Address object from component parts

Parameters:

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • :country_code (String)

    The two-letter ISO 3166-1 country code

  • :street_address (String)

    The street address

  • :city (String)

    The city or town

  • :city_area (String)

    The sublocality or district

  • :name (String)

    A person’s name

  • :company_name (String)

    The name of a company or organization

  • :country_area (String)

    The region, province or state

  • :sorting_code (String)

    The sorting code

  • :postal_code (String)

    The postal code or zip code



36
37
38
39
40
41
42
43
44
45
46
# File 'lib/google_i18n/address.rb', line 36

def initialize(options={})
  @country_code = options[:country_code] if options[:country_code]
  @street_address = options[:street_address] if options[:street_address]
  @city = options[:city] if options[:city]
  @city_area = options[:city_area] if options[:city_area]
  @name = options[:name] if options[:name]
  @company_name = options[:company_name] if options[:company_name]
  @country_area = options[:country_area] if options[:country_area]
  @sorting_code = options[:sorting_code] if options[:sorting_code]
  @postal_code = options[:postal_code] if options[:postal_code]
end

Instance Attribute Details

#cityObject

Returns the value of attribute city.



20
21
22
# File 'lib/google_i18n/address.rb', line 20

def city
  @city
end

#city_areaObject

Returns the value of attribute city_area.



20
21
22
# File 'lib/google_i18n/address.rb', line 20

def city_area
  @city_area
end

#company_nameObject

Returns the value of attribute company_name.



20
21
22
# File 'lib/google_i18n/address.rb', line 20

def company_name
  @company_name
end

#country_areaObject

Returns the value of attribute country_area.



20
21
22
# File 'lib/google_i18n/address.rb', line 20

def country_area
  @country_area
end

#country_codeObject

Returns the value of attribute country_code.



20
21
22
# File 'lib/google_i18n/address.rb', line 20

def country_code
  @country_code
end

#nameObject

Returns the value of attribute name.



20
21
22
# File 'lib/google_i18n/address.rb', line 20

def name
  @name
end

#postal_codeObject

Returns the value of attribute postal_code.



20
21
22
# File 'lib/google_i18n/address.rb', line 20

def postal_code
  @postal_code
end

#sorting_codeObject

Returns the value of attribute sorting_code.



20
21
22
# File 'lib/google_i18n/address.rb', line 20

def sorting_code
  @sorting_code
end

#street_addressObject

Returns the value of attribute street_address.



20
21
22
# File 'lib/google_i18n/address.rb', line 20

def street_address
  @street_address
end

Instance Method Details

#country_area_choicesObject

Returns an array where each element is an array representing the key and value for each country area. e.g:

[['AL', 'Alabama'], ..., ['WY', 'Wyoming']]


140
141
142
# File 'lib/google_i18n/address.rb', line 140

def country_area_choices
  get_validation_rules.country_area_choices
end

#dupObject



48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/google_i18n/address.rb', line 48

def dup
  self.class.new(
    country_code: self.country_code ? self.country_code.dup : nil,
    street_address: self.street_address ? self.street_address.dup : nil,
    city: self.city ? self.city.dup : nil,
    city_area: self.city_area ? self.city_area.dup : nil,
    name: self.name ? self.name.dup : nil,
    company_name: self.company_name ? self.company_name.dup : nil,
    country_area: self.country_area ? self.country_area.dup : nil,
    sorting_code: self.sorting_code ? self.sorting_code.dup : nil,
    postal_code: self.postal_code ? self.postal_code.dup : nil,
  )
end

#field_order(latin: false) ⇒ Array<Array<String>>

Returns an array where each element is an array representing the fields to include on each address line, e.g:

[["name"], ["company_name"], ["street_address"], ["city", "country_area", "postal_code"], ["country_name"]]

Parameters:

  • latin (Boolean) (defaults to: false)

    Show the address fields in Latinized order

Returns:

  • (Array<Array<String>>)


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
# File 'lib/google_i18n/address.rb', line 112

def field_order(latin: false)
  rules = get_validation_rules

  address_format = if latin
    rules.address_latin_format
  else
    rules.address_format
  end

  address_lines = address_format.split("%n")

  replacements = FIELD_MAPPING.inject({}) do |m, (code, field_name)|
    m["%#{code}"] = field_name
    m
  end

  all_lines = []
  address_lines.each do |line|
    fields = line.split(%r{(%.)})
    single_line = fields.map {|field| replacements[field]}.compact
    all_lines << single_line
  end

  all_lines << Array('country_name')
end

#latinize(normalize: true) ⇒ GoogleI18n::Address

Format the address in a way suitable for use in Latin alphabets.

If a latinized version is not available, the local version will be used instead.

Parameters:

  • normalize (Boolean) (defaults to: true)

    If true, address will be normalized first

Returns:



197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/google_i18n/address.rb', line 197

def latinize(normalize: true)
  cleaned_data = address.dup
  cleaned_data = cleaned_data.normalize if normalize

  country_code = cleaned_data.country_code&.upcase
  dummy_country_data, database = load_country_data(country_code)

  if country_code.present?
    country_area = cleaned_data.country_area
    if country_area.present?
      key = "%s/%s" % [country_code, country_area]
      country_area_data = database[key]
      if country_area_data.present?
        cleaned_data.country_area = country_area_data.fetch("lname", country_area_data.fetch("name", country_area))
        city = cleaned_data.city
        key = "%s/%s/%s" % [country_code, country_area, city]
        city_data = database[key]
        if city_data.present?
          cleaned_data.city = city_data.fetch("lname", city_data.fetch("name", city))
          city_area = cleaned_data.city_area
          key = "%s/%s/%s/%s" % [country_code, country_area, city, city_area]
          city_area_data = database[key]
          if city_area_data.present?
            cleaned_data.city_area = city_area_data.fetch("lname", city_area_data.fetch("name", city_area))
          end
        end
      end
    end
  end

  cleaned_data
end

#normalizeGoogleI18n::Address

Format the address in a way suitable for use in its part of the world

Returns:



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
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/google_i18n/address.rb', line 147

def normalize
  errors = {}
  # begin
    rules = get_validation_rules
  # rescue StandardError
  #   errors["country_code"] = "invalid"
  # end

  if errors.blank?
    cleaned_data = address.dup
    country_code = cleaned_data.country_code
    if country_code.blank?
      errors["country_code"] = "required"
    else
      cleaned_data.country_code = country_code.upcase
    end

    cleaned_data.country_area, errors = normalize_field("country_area", rules, cleaned_data, rules.country_area_choices, errors)
    cleaned_data.city, errors = normalize_field("city", rules, cleaned_data, rules.city_choices, errors)
    cleaned_data.city_area, errors = normalize_field("city_area", rules, cleaned_data, rules.city_area_choices, errors)
    cleaned_data.postal_code, errors = normalize_field("postal_code", rules, cleaned_data, [], errors)

    postal_code = cleaned_data.postal_code
    if rules.postal_code_matchers.present? && postal_code.present?
      rules.postal_code_matchers.each do |matcher|
        if !matcher.match(postal_code)
          errors["postal_code"] = "invalid"
          break
        end
      end
    end

    cleaned_data.street_address, errors = normalize_field("street_address", rules, cleaned_data, [], errors)
    cleaned_data.sorting_code, errors = normalize_field("sorting_code", rules, cleaned_data, [], errors)
    cleaned_data
  end

  if errors.present?
    raise InvalidAddress, "Invalid address #{errors}"
  end

  cleaned_data
end

#to_hObject



62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/google_i18n/address.rb', line 62

def to_h
  {
    country_code: self.country_code,
    street_address: self.street_address,
    city: self.city,
    city_area: self.city_area,
    name: self.name,
    company_name: self.company_name,
    country_area: self.country_area,
    sorting_code: self.sorting_code,
    postal_code: self.postal_code,
  }
end

#to_s(normalize: true, latin: false) ⇒ String

Displays the address in a newline delimited format suitable for printing

Parameters:

  • normalize (Boolean) (defaults to: true)

    If true, address will be normalized first

  • latin (Boolean) (defaults to: false)

    Show the address fields in Latinized order

Returns:

  • (String)


82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/google_i18n/address.rb', line 82

def to_s(normalize: true, latin: false)
  cleaned_data = address.dup
  cleaned_data = cleaned_data.normalize if normalize

  rules = get_validation_rules

  address_format = if latin
    rules.address_latin_format
  else
    rules.address_format
  end

  address_line_formats = address_format.split("%n")

  address_lines = address_line_formats.inject([]) do |m, line_format|
    m << format_address_line(line_format, cleaned_data, rules)
    m
  end

  address_lines << rules.country_name
  address_lines.keep_if(&:present?)
  address_lines.join("\n")
end