tracking_number 2.3.0 → 2.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: 6b89a47ae97b7827ccdcba6c1c58aefb21868fb44810727983d451ebc8ff7448
4
- data.tar.gz: f0a25b8c5152b426887c4afcc2060b737471a90db462cd48ed516c09be1f3476
3
+ metadata.gz: 7c0ef2fa722ce7a2d9cc6cfaac9c5510ef7ac79074ba4e227f9554b8157da2ee
4
+ data.tar.gz: 3a5f46d4dc5027e8bf68c4f7cf0756851e284d29b499c38d4c264b57ebc61fc4
5
5
  SHA512:
6
- metadata.gz: 355632def57fa6426ca6d1d901f2c6e06fee9f7c54d6d295ee31fdbba65e62ff9fa79e28a6a935f83858c964ca7cb06606fad2add55ff4fb9306ec3b79f1369c
7
- data.tar.gz: c9f3f31326e0ee37948a16ece6fedec22ec87316250d03f99fafa9a510c9ddecdb68cff7bafe0afa17a9fe1f01b995c2bf7a70c9f92555764ca604f364b3242e
6
+ metadata.gz: 404a19a4f9847ade5581c5ff7c0cf950fde208d773f81f6882715d44b4395f94fc505538d46b718ad0c7fbfcdf152e512619ca86372dc1021a524ab2614cd898
7
+ data.tar.gz: c4fbe1cf3637fea233106008bc31c1b555a63ea7e04588f08446d00a5d6dd3948daf744e078a74c6e96d7f257c51986fa8712db5f3b9e1e742e0ea9d61a6c63c
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  tracking_number changelog
2
2
 
3
+ # [2.4.0](https://github.com/jkeen/tracking_number/compare/v2.3.0...v2.4.0) (2025-08-21)
4
+
5
+
6
+ ### Features
7
+
8
+ * update to tracking_number_data 1.9.0 ([f885bfd](https://github.com/jkeen/tracking_number/commit/f885bfd956ffacb22f38967754ec14551bca8d50))
9
+
3
10
  # [2.3.0](https://github.com/jkeen/tracking_number/compare/v2.2.0...v2.3.0) (2025-08-21)
4
11
 
5
12
 
@@ -89,6 +89,80 @@
89
89
  "GR295117494011169045"
90
90
  ]
91
91
  }
92
+ },
93
+ {
94
+ "name": "DHL E-Commerce (30)",
95
+ "id": "dhl_ecommerce_30",
96
+ "regex": [
97
+ "\\s*(?<RoutingApplicationId>4\\s*2\\s*0\\s*)(?<DestinationZip>([0-9]\\s*){5})",
98
+ "(?!\\s*9\\s*[1-5]\\b)",
99
+ "(?<SerialNumber>",
100
+ "(?<ServiceType>(9[2-5]\\s*))",
101
+ "(?<ShipperId>([0-9]\\s*){9})",
102
+ "(?<PackageId>([0-9]\\s*){10})",
103
+ ")",
104
+ "(?<CheckDigit>[0-9]\\s*)"
105
+ ],
106
+ "validation": {
107
+ "checksum": {
108
+ "name": "mod10",
109
+ "evens_multiplier": 3,
110
+ "odds_multiplier": 1,
111
+ "reverse": true
112
+ }
113
+ },
114
+ "tracking_url": "https://ecommerceportal.dhl.com/track?trackingnumber=%s",
115
+ "partners": [{
116
+ "description": "DHL eCommerce hands off to USPS for the last mile",
117
+ "partner_type": "carrier",
118
+ "partner_id": "usps_22",
119
+ "validation": {
120
+ "matches_all": [
121
+ { "regex_group_name": "RoutingApplicationId", "matches": "420" },
122
+ { "regex_group_name": "ServiceType", "matches_regex": "9[2345]" }
123
+ ]
124
+ }
125
+ },
126
+ {
127
+ "description": "DHL eCommerce hands off to USPS for the last mile",
128
+ "partner_type": "carrier",
129
+ "partner_id": "usps_91",
130
+ "validation": {
131
+ "matches_all": [
132
+ { "regex_group_name": "RoutingApplicationId", "matches": "420" },
133
+ { "regex_group_name": "ServiceType", "matches_regex": "9[2345]" }
134
+ ]
135
+ }
136
+ }],
137
+ "additional": [
138
+ {
139
+ "name": "Service Type",
140
+ "regex_group_name": "ServiceType",
141
+ "lookup": [
142
+ { "matches": "92", "name": "USPS Tracking (Commercial)" },
143
+ { "matches": "93", "name": "Collect on Delivery (COD)" },
144
+ { "matches": "94", "name": "USPS Tracking" },
145
+ { "matches": "95", "name": "Certified Mail" }
146
+ ]
147
+ }
148
+ ],
149
+ "test_numbers": {
150
+ "valid": [
151
+ "420902459261290336128704042634",
152
+ "420941179261290336128704062441",
153
+ "420926029261290336128704067248",
154
+ "420902729261290336128704124163",
155
+ "420950549261290336128704133837",
156
+ "420193809261290336128704280838",
157
+ "420900469261290336128704216936"
158
+ ],
159
+ "invalid": [
160
+ "420941179261290336128704062442",
161
+ "420941179261290336128704062400",
162
+ "420941179261290336128704062422"
163
+ ]
164
+ }
92
165
  }
166
+
93
167
  ]
94
168
  }
@@ -98,7 +98,7 @@
98
98
  "(?<ApplicationIdentifier>9\\s*2\\s*)",
99
99
  ")?",
100
100
  "(?<SerialNumber>",
101
- "(?<SCNC>([0-9]\\s*){2})",
101
+ "(?<SCNC>6\\s*1\\s*)",
102
102
  "(?<ServiceType>2\\s*9\\s*)",
103
103
  "(?<ShipperId>([0-9]\\s*){8})",
104
104
  "(?<PackageId>([0-9]\\s*){11}|([0-9]\\s*){7})",
@@ -138,11 +138,9 @@
138
138
  "tracking_url": "https://www.fedex.com/apps/fedextrack/?tracknumbers=%s",
139
139
  "test_numbers": {
140
140
  "valid": [
141
- "61299998820821171811",
142
141
  "9261292700768711948021",
143
142
  "420 11213 92 6129098349792366623 8",
144
- "92 6129098349792366623 8",
145
- "6129098349792366623 8"
143
+ "92 6129098349792366623 8"
146
144
  ],
147
145
  "invalid": [
148
146
  "9261292700768711948020",
@@ -3,10 +3,10 @@
3
3
  "courier_code": "usps",
4
4
  "tracking_numbers": [
5
5
  {
6
- "tracking_url": "https://tools.usps.com/go/TrackConfirmAction?tLabels=%s",
7
6
  "name": "USPS 20",
8
7
  "id": "usps_20",
9
8
  "description": "20 digit USPS numbers",
9
+ "tracking_url": "https://tools.usps.com/go/TrackConfirmAction?tLabels=%s",
10
10
  "regex": [
11
11
  "\\s*(?<SerialNumber>",
12
12
  "(?<ServiceType>([0-9]\\s*){2})",
@@ -57,6 +57,76 @@
57
57
  }
58
58
  ]
59
59
  },
60
+ {
61
+ "name": "USPS 22",
62
+ "id": "usps_22",
63
+ "description": "22 digit USPS numbers",
64
+ "tracking_url": "https://tools.usps.com/go/TrackConfirmAction?tLabels=%s",
65
+ "regex": [
66
+ "\\s*((?<RoutingApplicationId>4\\s*2\\s*0\\s*)(?<DestinationZip>([0-9]\\s*){5}))?",
67
+ "(?<SerialNumber>",
68
+ "(?<ServiceType>(9\\s*[4-8]\\s*))",
69
+ "(?<ShipperId>([0-9]\\s*){9})",
70
+ "(?<PackageId>([0-9]\\s*){10})",
71
+ ")",
72
+ "(?<CheckDigit>[0-9]\\s*)"
73
+ ],
74
+ "validation": {
75
+ "checksum": {
76
+ "name": "mod10",
77
+ "evens_multiplier": 3,
78
+ "odds_multiplier": 1,
79
+ "reverse": true
80
+ }
81
+ },
82
+ "test_numbers": {
83
+ "valid": [
84
+ "420787459400111206206406260787",
85
+ "9400111206206406260787",
86
+ "9434611206206406227577",
87
+ "9434611206206407667136",
88
+ "9400111206206407628746",
89
+ "9400111206206407628845"
90
+ ],
91
+ "invalid": [
92
+ "9434611206206407667131",
93
+ "9434611306206407667222",
94
+ "2334611306206407667222"
95
+ ]
96
+ },
97
+ "partners": [{
98
+ "description": "DHL ECommerce uses USPS for last mile delivery",
99
+ "partner_type": "shipper",
100
+ "partner_id": "dhl_ecommerce_30",
101
+ "validation": {
102
+ "matches_all": [
103
+ {
104
+ "regex_group_name": "RoutingApplicationId",
105
+ "matches": "420"
106
+ },
107
+ {
108
+ "matches_regex": "9[24]",
109
+ "regex_group_name": "ServiceType"
110
+ }
111
+ ]
112
+ }
113
+ }],
114
+ "additional": [
115
+ {
116
+ "name": "Service Type",
117
+ "regex_group_name": "ServiceType",
118
+ "lookup": [
119
+ { "matches": "92", "name": "Signature Confirmation" },
120
+ { "matches": "93", "name": "Collect on Delivery (COD)" },
121
+ { "matches": "94", "name": "USPS Tracking" },
122
+ { "matches": "95", "name": "Certified Mail" },
123
+ { "matches": "96", "name": "Insured Mail" },
124
+ { "matches": "97", "name": "Registered Mail" },
125
+ { "matches": "98", "name": "Return Receipt for Merchandise" }
126
+ ]
127
+ }
128
+ ]
129
+ },
60
130
  {
61
131
  "name": "USPS 34v2",
62
132
  "id": "usps_32V2",
@@ -131,6 +201,31 @@
131
201
  {
132
202
  "matches": "61",
133
203
  "regex_group_name": "SCNC"
204
+ },
205
+ {
206
+ "regex_group_name": "ApplicationIdentifier",
207
+ "matches": "92"
208
+ }
209
+ ]
210
+ }
211
+ },
212
+ {
213
+ "description": "DHL uses USPS for last mile delivery, but not all USPS91 numbers are DHL Ecommerce",
214
+ "partner_type": "shipper",
215
+ "partner_id": "dhl_ecommerce_30",
216
+ "validation": {
217
+ "matches_all": [
218
+ {
219
+ "regex_group_name": "ServiceType",
220
+ "matches": "29"
221
+ },
222
+ {
223
+ "matches": "61",
224
+ "regex_group_name": "SCNC"
225
+ },
226
+ {
227
+ "matches": "420",
228
+ "regex_group_name": "RoutingApplicationId"
134
229
  }
135
230
  ]
136
231
  }
@@ -126,16 +126,16 @@ module TrackingNumber
126
126
 
127
127
  def info
128
128
  Info.new({
129
- courier: courier_info,
130
- service_type: service_type,
131
- service_description: service_description,
132
- destination_zip: destination_zip,
133
- shipper_id: shipper_id,
134
- package_type: package_type,
135
- tracking_url: tracking_url,
136
- partners: partners,
137
- decode: decode
138
- })
129
+ courier: courier_info,
130
+ service_type: service_type,
131
+ service_description: service_description,
132
+ destination_zip: destination_zip,
133
+ shipper_id: shipper_id,
134
+ package_type: package_type,
135
+ tracking_url: tracking_url,
136
+ partners: partners,
137
+ decode: decode
138
+ })
139
139
  end
140
140
 
141
141
  def courier_code
@@ -186,8 +186,7 @@ module TrackingNumber
186
186
  partner_hash = {}
187
187
 
188
188
  return unless (partner_tn = find_matching_partner)
189
-
190
- possible_twin = partner_tn.send(:find_matching_partner)
189
+ possible_twin = partner_tn.send(:find_matching_partner, self.class.const_get("ID"))
191
190
 
192
191
  if possible_twin.instance_of?(self.class) && possible_twin.tracking_number == tracking_number
193
192
  partner_hash[partner_data[:partner_type].to_sym] = partner_tn
@@ -295,8 +294,12 @@ module TrackingNumber
295
294
  nil
296
295
  end
297
296
 
298
- def find_matching_partner
299
- partner_info = self.class.const_get(:PARTNERS) || []
297
+ def find_matching_partner(partner_id = nil)
298
+ partner_info = if partner_id
299
+ (self.class.const_get(:PARTNERS) || []).select { |info| info[:partner_id]&.to_sym == partner_id.to_sym }
300
+ else
301
+ self.class.const_get(:PARTNERS) || []
302
+ end
300
303
 
301
304
  partner_info.each do |partner_data|
302
305
  klass = find_tracking_class_by_id(partner_data[:partner_id])
@@ -304,7 +307,6 @@ module TrackingNumber
304
307
  return false unless klass
305
308
 
306
309
  tn = klass.new(tracking_number)
307
-
308
310
  valid = if partner_data.dig(:validation, :matches_all)
309
311
  tn.valid? && match_all(partner_data.dig(:validation, :matches_all))
310
312
  elsif partner_data.dig(:validation, :matches_any)
@@ -1,3 +1,3 @@
1
1
  module TrackingNumber
2
- VERSION = "2.3.0"
2
+ VERSION = "2.4.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tracking_number
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0
4
+ version: 2.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Keen