costa_rica_address_utils 0.3.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5499eeebb373e3b50ca5eb2c4e566830f157e390a39893a3f55f613b968a7466
4
- data.tar.gz: 5b7ae3823faf5a3792398aeca1d7226db12d9659c95245ca2b97f8299ee722c2
3
+ metadata.gz: e88494ff983e9e75ca80537f1d42f97bd31a0ce606f17a450bc7a4a6ec6dd7db
4
+ data.tar.gz: 914e71a23e8a05acbf39aa99a8d85c87decd700403e420fcc02324f448409308
5
5
  SHA512:
6
- metadata.gz: e237a271be1b395114a457b55ec458e4a8bead6d01f256ea7bcc5abaa47de0839a7fa8728abf56cb738e6922951da0d69b5b01b9fc5efc4c801cdd085dbf50e1
7
- data.tar.gz: 208affcee44657c5f423d9c13e4fa49111a34580bf5d72c0ce3829574198345d44ddd1968a7536b07cef462a79d3386ec100fa31a7c6b6a1d52a7d4619a47e9b
6
+ metadata.gz: 35c91696f8bf675e556daf9b1393bcade9d4fa3ebe03fdab5bfbebbf9402cf128966078ab23e4256d5d672160c4ba40f0fb27ee52b9b9c9053be2e51e75eda34
7
+ data.tar.gz: 1a943483975c277de9b5287e356a9bbf50c7fbcc4666444108725f77bb4943842fad28b661c85906af838f2a0fce9b03bc015bff7b0f0797b00c0cc0bd01b064
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.4.0]
4
+
5
+ * Move existing logic for main module to its own module called `CostaRica`
6
+ * Create new module `Guatemala` for Guatemala address logic
7
+ * New method `for_country` to explicitly use methods for each country
8
+ * Extract method `build_address_from_provider` as a global method instead of per region to build an address from an external provider (Shopify, Brightpearl, etc)
9
+
10
+ > To avoid breaking calls of older versions, if the methods are called directly with `CostaRicaAddressUtils` it will automatically use the methods from `CostaRica` module.
11
+
3
12
  ## [0.3.2]
4
13
 
5
14
  * Add missing accents from GT dataset on top level items
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- costa_rica_address_utils (0.3.2)
4
+ costa_rica_address_utils (0.4.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -40,11 +40,17 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
40
40
 
41
41
  To install this gem onto your local machine, run `bundle exec rake install`.
42
42
 
43
- To release a new version, update the version number in `version.rb` and `Gemfile.lock` (using bundle), and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
43
+ ## Release
44
44
 
45
- > `Gemfile.lock` update for version is done after running `bundle install` with the `version.rb` updated
45
+ To release a new version follow these steps:,
46
+ 1. Update CHANGELOG.md with the new version changes
47
+ 2. Update the version number in `version.rb`
48
+ 3. Execute bundle to update version on `Gemfile.lock` automatically
49
+ 4. Commit the changes and change the branch to `main`
50
+ 5. Run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
46
51
 
47
52
  > Remember to execute `bundle exec rake release` on `main` branch
53
+ > `Gemfile.lock` update for version is done after running `bundle install` with the `version.rb` updated
48
54
 
49
55
  ## Contributing
50
56
 
@@ -0,0 +1,81 @@
1
+ require 'json'
2
+
3
+ # TODO: find way to optimize dataset loading
4
+
5
+ module CostaRicaAddressUtils
6
+ module CostaRica
7
+ JSON_FILE_PATH = File.join(File.dirname(__FILE__), '..', '..', 'data', 'locations_dataset.json')
8
+
9
+ # Load the JSON file and parse it into a Ruby object for general usage
10
+ LOCATIONS_DATASET = JSON.parse(File.read(JSON_FILE_PATH))
11
+
12
+ class Error < StandardError; end
13
+ # Your code goes here...
14
+
15
+ # Fetch the address data from provided input, return options for subaddresses on each level and zip code if full address is valid
16
+ def fetch_address_data(province:, canton: nil, district: nil)
17
+ raise CostaRicaAddressUtils::InvalidData, 'Province is required' if province.nil? || province.empty?
18
+
19
+ province_data = LOCATIONS_DATASET[province]
20
+ canton_data = !!province_data ? province_data['cantons'][canton] : nil
21
+ district_data = !!canton_data ? canton_data['districts'][district] : nil
22
+
23
+ canton_options = !!province_data ? province_data['cantons'].keys : [] # Cantons options, only if province is valid
24
+ district_options = !!canton_data ? canton_data['districts'].keys : [] # Districts options, only if canton is valid
25
+ zip = (!!district_data && district_data['zip_code']) || nil # Zip code, only if full address is valid
26
+
27
+ {
28
+ zip: zip,
29
+ # Names options
30
+ province_options: LOCATIONS_DATASET.keys,
31
+ canton_options: canton_options,
32
+ district_options: district_options
33
+ }
34
+ end
35
+
36
+ # Get one address information from a zip code
37
+ def fetch_address_from_zip(zip_code)
38
+ return nil unless zip_valid?(zip_code)
39
+
40
+ zip_code_s = zip_code.to_s
41
+ LOCATIONS_DATASET.each do |province, province_data|
42
+ province_data['cantons'].each do |canton, canton_data|
43
+ canton_data['districts'].each do |district, district_data|
44
+ if district_data['zip_code'] == zip_code_s
45
+ return {
46
+ province: province,
47
+ canton: canton,
48
+ district: district,
49
+ zip: zip_code_s
50
+ }
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ nil
57
+ end
58
+
59
+ def fetch_address_from_zip!(zip_code)
60
+ raise "Zip code provided #{zip_code} is invalid. Must be a 5 digits number" unless zip_valid?(zip_code)
61
+
62
+ fetch_address_from_zip(zip_code)
63
+ end
64
+
65
+ def address_valid?(province:, canton:, district:)
66
+ is_valid = true
67
+ begin
68
+ data = fetch_address_data(province: province, canton: canton, district: district)
69
+ is_valid = !!data[:zip] # Is valid if matched to a zip code
70
+ rescue CostaRicaAddressUtils::InvalidData => e
71
+ is_valid = false
72
+ end
73
+
74
+ is_valid
75
+ end
76
+
77
+ def zip_valid?(zip_code)
78
+ !!zip_code && zip_code.to_s.length == 5
79
+ end
80
+ end # CostaRica
81
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CostaRicaAddressUtils
4
+ module Guatemala
5
+ # Guatemala-specific implementation
6
+ JSON_FILE_PATH = File.join(File.dirname(__FILE__), '..', '..', 'data', 'guatemala_dataset.json')
7
+ LOCATIONS_DATASET = JSON.parse(File.read(JSON_FILE_PATH))
8
+
9
+ # Your Guatemala-specific methods here
10
+
11
+ # For a given address of 2 levels, return options for each level found and zip code if full address is valid
12
+ def self.fetch_address_data(department:, municipality:)
13
+ raise CostaRicaAddressUtils::InvalidData, 'Department is required' if department.nil? || department.empty?
14
+
15
+ department_data = LOCATIONS_DATASET[department]
16
+ municipality_data = !!department_data ? department_data['locationsLevel2'][municipality] : nil
17
+
18
+ # Municipality options(lv2), only if department(lv1) is valid
19
+ municipality_options = !!department_data ? department_data['locationsLevel2'].keys : []
20
+ zip = (!!municipality_data && municipality_data['zipCode']) || nil # Zip code, only if full address is valid
21
+
22
+ {
23
+ zip: zip,
24
+ # Names options
25
+ department_options: LOCATIONS_DATASET.keys,
26
+ municipality_options: municipality_options
27
+ }
28
+ end
29
+
30
+ # Get one address information from a zip code
31
+ def self.fetch_address_from_zip(zip_code)
32
+ return nil unless zip_valid?(zip_code)
33
+
34
+ zip_code_s = zip_code.to_s
35
+ LOCATIONS_DATASET.each do |department, department_data|
36
+ department_data['locationsLevel2'].each do |municipality, municipality_data|
37
+ if municipality_data['zipCode'] == zip_code_s
38
+ return {
39
+ department: department,
40
+ municipality: municipality,
41
+ zip: zip_code_s
42
+ }
43
+ end
44
+ end
45
+ end
46
+
47
+ nil
48
+ end
49
+
50
+ def self.address_valid?(department:, municipality:)
51
+ is_valid = true
52
+ begin
53
+ data = fetch_address_data(department: department, municipality: municipality)
54
+ is_valid = !!data[:zip] # Is valid if matched to a zip code
55
+ rescue CostaRicaAddressUtils::InvalidData => e
56
+ is_valid = false
57
+ end
58
+
59
+ is_valid
60
+ end
61
+ end # Guatemala
62
+ end # CostaRicaAddressUtils
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CostaRicaAddressUtils
4
- VERSION = '0.3.2'
4
+ VERSION = '0.4.0'
5
5
  end
@@ -1,118 +1,67 @@
1
1
  # frozen_string_literal: true
2
- # TODO find way to optimize dataset loading
3
- require 'json'
4
- require_relative "costa_rica_address_utils/version"
5
- require_relative "costa_rica_address_utils/errors"
6
2
 
7
- JSON_FILE_PATH = File.join(File.dirname(__FILE__), '..', 'data', 'locations_dataset.json')
3
+ require_relative 'costa_rica_address_utils/version'
4
+ require_relative 'costa_rica_address_utils/errors'
5
+ require_relative 'costa_rica_address_utils/costa_rica'
6
+ require_relative 'costa_rica_address_utils/guatemala'
8
7
 
9
- module CostaRicaAddressUtils
10
- # Load the JSON file and parse it into a Ruby object for general usage
11
- LOCATIONS_DATASET = JSON.parse(File.read(JSON_FILE_PATH))
12
- VAlID_PROVIDERS = [:shopify, :brightpearl]
8
+ module CostaRicaAddressUtils # rubocop:disable Style/Documentation
9
+ # Backwards compatibility before usage of for_country
10
+ # Old version will be able to call methods with CostaRicaAddressUtils directly
11
+ extend CostaRicaAddressUtils::CostaRica
13
12
 
14
- class Error < StandardError; end
15
- # Your code goes here...
13
+ SUPPORTED_COUNTRIES = %i[costa_rica guatemala].freeze
14
+ VALID_INPUT_PROVIDERS = %i[shopify brightpearl].freeze
16
15
 
17
- # Fetch the address data from provided input, return options for subaddresses on each level and zip code if full address is valid
18
- def self.fetch_address_data(province:, canton: nil, district: nil)
19
- raise InvalidData, "Province is required" if province.nil? || province.empty?
16
+ # TODO: merge the methods from both countries using new dataset for costa rica instead of previous one
17
+ # Newer files contains a standarized format for fields.
20
18
 
21
- province_data = LOCATIONS_DATASET[province]
22
- canton_data = !!province_data ? province_data["cantons"][canton] : nil
23
- district_data = !!canton_data ? canton_data["districts"][district] : nil
24
-
25
- canton_options = !!province_data ? province_data["cantons"].keys : [] # Cantons options, only if province is valid
26
- district_options = !!canton_data ? canton_data["districts"].keys : [] # Districts options, only if canton is valid
27
- zip = (!!district_data && district_data["zip_code"]) || nil # Zip code, only if full address is valid
28
-
29
- return {
30
- zip: zip,
31
- # Names options
32
- province_options: LOCATIONS_DATASET.keys,
33
- canton_options: canton_options,
34
- district_options: district_options,
35
- }
36
- end
37
-
38
- # Get one address information from a zip code
39
- def self.fetch_address_from_zip(zip_code)
40
- return nil unless zip_valid?(zip_code)
41
- zip_code_s = zip_code.to_s
42
- LOCATIONS_DATASET.each do |province, province_data|
43
- province_data["cantons"].each do |canton, canton_data|
44
- canton_data["districts"].each do |district, district_data|
45
- if district_data["zip_code"] == zip_code_s
46
- return {
47
- province: province,
48
- canton: canton,
49
- district: district,
50
- zip: zip_code_s,
51
- }
52
- end
53
- end
54
- end
55
- end
56
-
57
- return nil
58
- end
59
-
60
- def self.fetch_address_from_zip!(zip_code)
61
- raise "Zip code provided #{zip_code} is invalid. Must be a 5 digits number" unless zip_valid?(zip_code)
62
- fetch_address_from_zip(zip_code)
63
- end
64
-
65
- def self.address_valid?(province:, canton:, district:)
66
- is_valid = true
67
- begin
68
- data = fetch_address_data(province: province, canton: canton, district: district)
69
- is_valid = !!data[:zip] # Is valid if matched to a zip code
70
- rescue InvalidData => e
71
- is_valid = false
19
+ def self.for_country(country)
20
+ case country.to_sym
21
+ when :costa_rica
22
+ CostaRicaAddressUtils::CostaRica
23
+ when :guatemala
24
+ CostaRicaAddressUtils::Guatemala
25
+ else
26
+ raise ArgumentError, "Unsupported country: #{country}. Supported countries are: #{SUPPORTED_COUNTRIES}"
72
27
  end
73
-
74
- return is_valid
75
- end
76
-
77
- def self.zip_valid?(zip_code)
78
- !!zip_code && zip_code.to_s.length == 5
79
28
  end
80
29
 
81
30
  # Build a Costa Rica address from an address of an external provider (Shopify, Brightpearl, etc)
82
31
  # https://shopify.dev/api/admin-graphql/2022-10/objects/mailingaddress
83
32
  # https://api-docs.brightpearl.com/contact/postal-address/get.html
84
- def self.build_address_from_provider(address:, provider:)
33
+ # Standarized format locationLevelX for the address Province/Department, Municipality/Canton, District/Parish
34
+ # since they are named differently in each country
35
+ def self.build_address_from_provider(address:, provider:)
85
36
  case provider
86
37
  when :shopify
87
- return {
38
+ {
88
39
  name: address.name, # Customer name
89
40
  address1: address.address1,
90
-
91
- province: address.province,
92
- canton: address.city,
93
- district: address.address2,
41
+
42
+ locationLevel1: address.province,
43
+ locationLevel2: address.city,
44
+ locationLevel3: address.address2,
94
45
  zip: address.zip,
95
46
 
96
47
  national_id: address.company,
97
- phone: address.phone,
48
+ phone: address.phone
98
49
  }
99
50
  when :brightpearl
100
- return {
101
- name: address["addressFullName"], # Customer name
102
- address1: address["addressLine1"],
103
-
104
- province: address["addressLine4"],
105
- canton: address["addressLine3"],
106
- district: address["addressLine2"],
107
- zip: address["postalCode"],
51
+ {
52
+ name: address['addressFullName'], # Customer name
53
+ address1: address['addressLine1'],
108
54
 
109
- national_id: address["companyName"],
110
- phone: address["telephone"],
55
+ locationLevel1: address['addressLine4'],
56
+ locationLevel2: address['addressLine3'],
57
+ locationLevel3: address['addressLine2'],
58
+ zip: address['postalCode'],
59
+
60
+ national_id: address['companyName'],
61
+ phone: address['telephone']
111
62
  }
112
63
  else
113
- raise InvalidData("Invalid provider, valid providers are: #{VAlID_PROVIDERS}")
64
+ raise InvalidData("Invalid provider, valid providers are: #{VALID_INPUT_PROVIDERS}")
114
65
  end
115
66
  end
116
-
117
- private
118
- end # module CostaRicaAddressUtils
67
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: costa_rica_address_utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - vicvans20
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-11-21 00:00:00.000000000 Z
11
+ date: 2025-01-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: byebug
@@ -45,7 +45,9 @@ files:
45
45
  - data/guatemala_dataset.json
46
46
  - data/locations_dataset.json
47
47
  - lib/costa_rica_address_utils.rb
48
+ - lib/costa_rica_address_utils/costa_rica.rb
48
49
  - lib/costa_rica_address_utils/errors.rb
50
+ - lib/costa_rica_address_utils/guatemala.rb
49
51
  - lib/costa_rica_address_utils/version.rb
50
52
  - sig/costa_rica_address_utils.rbs
51
53
  homepage: https://github.com/vicvans20/costa_rica_address_utils