colissimo_label 0.18.0 → 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e85c64c5c035a54da59c9695851ad8be29dc0083353f10065dc2b35e9088ee5e
4
- data.tar.gz: 863ca8375cdf9bacafde3fea451fd695051d3bee5b5b52d1f2f44c606637a441
3
+ metadata.gz: 104d8402162a7daf6fcf0eaa5c7a9246ed709a8a7e97d37ecdc84631721d5da1
4
+ data.tar.gz: 94e1411b953744780448dcd69aba26ae7d4c4ffad071a7477b6c442f002b71ba
5
5
  SHA512:
6
- metadata.gz: 395bd4aa3613b9e253dd641e38d74ed3205768e47ada8d6d07a06372225aa2afd5476b99c4736393b163192e405d832ef08059b3eabeef589a3877887d94e7a0
7
- data.tar.gz: 4982d55a321d6579a3655c0a3306bd09396a34db819a410fc308931439701a55178da0bdee852674ec2becfa749a71a4c9eb363c1c7a10bcacdcd628f03088b9
6
+ metadata.gz: 04ef4dfe6942583abcddee37a7fb1e2519a44c2380b5223c89d28c26284e5dcb746e59086c41e65cb75e98e457862e7429a2c1867eab551f70a8c085d1e78b9e
7
+ data.tar.gz: 42008e2705a23bb3305117c87254baebab36dcf97546ccb7374e15c026ff21c6b78341f61fba522f9db7431ad27b13f3669c79b19b733fde67217dff7cdf713c
data/CHANGELOG.md CHANGED
@@ -1,3 +1,14 @@
1
+ ## 0.20.0
2
+
3
+ - Automatically create the path for label and customs documents
4
+ - Add more parameter options for customs
5
+ - Add parameters for specific addressee and sender reference
6
+ - Update dependencies
7
+
8
+ ## 0.19.0
9
+
10
+ - Add new option field: specific TVA number for customs
11
+
1
12
  ## 0.18.0
2
13
 
3
14
  - Add new fields for UK after Brexit
data/README.md CHANGED
@@ -144,6 +144,12 @@ You can add the following option to require the signature:
144
144
  with_signature: true
145
145
  ```
146
146
 
147
+ To provide the insurance value (by default, it depends of the weight of the package), add this parameter:
148
+
149
+ ```
150
+ insurance_value: 100
151
+ ```
152
+
147
153
  For a national address and delivered to a relay point:
148
154
 
149
155
  ```ruby
@@ -201,7 +207,8 @@ parcel_number = ColissimoLabel::GenerateLabel.new(
201
207
  mobile: 'Mobile number of the addressee',
202
208
  email: 'Email of the addressee'
203
209
  },
204
- customs_total_weight: 2, # Total weight of the package
210
+ customs_total_weight: 2, # Total weight of the package, required for customs
211
+ customs_category: 3, # Type of business (commercial by default)
205
212
  customs_data: [ # Details content of your package
206
213
  {
207
214
  description: 'Product description',
@@ -210,7 +217,7 @@ parcel_number = ColissimoLabel::GenerateLabel.new(
210
217
  item_price: 100,
211
218
  country_code: 'FR',
212
219
  currency_code: 'EUR',
213
- customs_code: 'hsCode' # Harmonized system code of your product
220
+ customs_code: 'hsCode' # Harmonized system code of your product, it's a number or a string (starting with '0')
214
221
  }
215
222
  ]
216
223
  ).perform
@@ -222,7 +229,7 @@ In both cases, if the label cannot be generated it raises a StandardError with t
222
229
 
223
230
  Colissimo documentation can be found here:
224
231
 
225
- https://www.colissimo.entreprise.laposte.fr/system/files/imagescontent/docs/spec_ws_affranchissement.pdf
232
+ https://www.colissimo.entreprise.laposte.fr/sites/default/files/2021-03/spec_ws_affranchissement.pdf
226
233
 
227
234
  ## Contributing
228
235
 
@@ -21,13 +21,13 @@ Gem::Specification.new do |spec|
21
21
  spec.require_paths = ['lib']
22
22
 
23
23
  spec.add_dependency 'rack', '~> 2'
24
+ spec.add_dependency 'http', '>= 4'
24
25
  spec.add_dependency 'activesupport', '>= 5'
25
26
  spec.add_dependency 'railties', '>= 5'
26
- spec.add_dependency 'http', '~> 4'
27
27
 
28
28
  spec.add_development_dependency 'bundler', '~> 2'
29
29
  spec.add_development_dependency 'rake', '~> 12'
30
30
  spec.add_development_dependency 'rspec', '~> 3'
31
- spec.add_development_dependency 'simplecov', '~> 0.17'
31
+ spec.add_development_dependency 'simplecov', '>= 0.16'
32
32
  spec.add_development_dependency 'webmock', '~> 3'
33
33
  end
@@ -3,23 +3,40 @@
3
3
  require 'http'
4
4
 
5
5
  class ColissimoLabel::GenerateLabel
6
+ class ServiceUnavailable < StandardError; end
6
7
 
7
8
  def initialize(filename, destination_country, shipping_fees, sender_data, addressee_data, options = {})
8
- @filename = filename
9
- @destination_country = destination_country
10
- @shipping_fees = shipping_fees
11
- @sender_data = sender_data
12
- @addressee_data = addressee_data
13
- @pickup_id = options.fetch(:pickup_id, nil)
14
- @pickup_type = options.fetch(:pickup_type, nil)
15
- @total_weight = options.fetch(:total_weight, nil)
16
- @customs_total_weight = options.fetch(:customs_total_weight, nil)
9
+ @filename = filename
10
+ @destination_country = destination_country
11
+ @shipping_fees = shipping_fees
12
+
13
+ @sender_data = sender_data
14
+ @addressee_data = addressee_data
15
+
16
+ @pickup_id = options.fetch(:pickup_id, nil)
17
+ @pickup_type = options.fetch(:pickup_type, nil)
18
+ @total_weight = options.fetch(:total_weight, nil)
19
+ @product_code = options.fetch(:product_code, nil)
20
+ @with_signature = options.fetch(:with_signature, false)
21
+ @insurance_value = options.fetch(:insurance_value, nil)
22
+ @label_output_format = options.fetch(:label_output_format, 'PDF_10x15_300dpi')
23
+ @label_path = options.fetch(:label_path, nil)
24
+
17
25
  @customs_data = options.fetch(:customs_data, nil)
18
- @with_signature = options.fetch(:with_signature, false)
19
- @insurance_value = options.fetch(:insurance_value, nil)
26
+ @customs_total_weight = options.fetch(:customs_total_weight, nil)
27
+ @customs_category = options.fetch(:customs_category, 3)
28
+ @customs_tva_number = options.fetch(:customs_tva_number, nil)
20
29
  @eori_number = options.fetch(:eori_number, nil)
21
- @label_output_format = options.fetch(:label_output_format, 'PDF_10x15_300dpi')
22
- @errors = []
30
+ @customs_path = options.fetch(:customs_path, nil)
31
+ @customs_filename = options.fetch(:customs_filename, 'customs')
32
+
33
+ @order_id = options.fetch(:order_id, nil)
34
+ @sender_data = sender_data
35
+ @sender_ref_id = options.fetch(:sender_ref_id, nil)
36
+ @addressee_data = addressee_data
37
+ @addressee_ref_id = options.fetch(:addressee_ref_id, nil)
38
+
39
+ @errors = []
23
40
  end
24
41
 
25
42
  def perform
@@ -27,25 +44,32 @@ class ColissimoLabel::GenerateLabel
27
44
  status = response.code
28
45
  parts = response.to_a.last.force_encoding('BINARY').split('Content-ID: ')
29
46
  label_filename = @filename + '.' + file_format
30
- local_path = ColissimoLabel.colissimo_local_path&.chomp('/')
47
+ label_path = nil
48
+ customs_path = nil
31
49
 
32
50
  if ColissimoLabel.s3_bucket
33
- colissimo_pdf = ColissimoLabel.s3_bucket.object(ColissimoLabel.s3_path.chomp('/') + '/' + label_filename)
51
+ label_path = ColissimoLabel.s3_path.chomp('/') + '/' + (@label_path.present? ? @label_path + '/' : '')
52
+ colissimo_pdf = ColissimoLabel.s3_bucket.object(label_path + label_filename)
34
53
  colissimo_pdf.put(acl: 'public-read', body: parts[2])
35
54
  else
36
- File.open(local_path + '/' + label_filename, 'wb') do |file|
55
+ label_path = ColissimoLabel.colissimo_local_path.chomp('/') + '/' + (@label_path.present? ? @label_path + '/' : '')
56
+ FileUtils.mkdir_p(label_path) unless File.directory?(label_path)
57
+ File.open(label_path + label_filename, 'wb') do |file|
37
58
  file.write(parts[2])
38
59
  end
39
60
  end
40
61
 
41
62
  if require_customs?
42
- customs_filename = @filename + '-customs.pdf'
63
+ customs_filename = @filename + '-' + @customs_filename + '.pdf'
43
64
 
44
65
  if ColissimoLabel.s3_bucket
45
- customs_pdf = ColissimoLabel.s3_bucket.object(ColissimoLabel.s3_path.chomp('/') + '/' + customs_filename)
66
+ customs_path = ColissimoLabel.s3_path.chomp('/') + '/' + (@customs_path.present? ? @customs_path + '/' : '')
67
+ customs_pdf = ColissimoLabel.s3_bucket.object(customs_path + customs_filename)
46
68
  customs_pdf.put(acl: 'public-read', body: parts[3])
47
69
  else
48
- File.open(local_path + '/' + customs_filename, 'wb') do |file|
70
+ customs_path = ColissimoLabel.colissimo_local_path.chomp('/') + '/' + (@customs_path.present? ? @customs_path + '/' : '')
71
+ FileUtils.mkdir_p(customs_path) unless File.directory?(customs_path)
72
+ File.open(customs_path + customs_filename, 'wb') do |file|
49
73
  file.write(parts[3])
50
74
  end
51
75
  end
@@ -53,55 +77,68 @@ class ColissimoLabel::GenerateLabel
53
77
 
54
78
  if status == 400 || status == 500
55
79
  error_message = response.body.to_s.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '').scan(/"messageContent":"(.*?)"/).last&.first
56
- raise StandardError, error_message
80
+ raise ServiceUnavailable, error_message
57
81
  elsif status == 503
58
- raise StandardError, { message: 'Colissimo: Service Unavailable' }
82
+ raise ServiceUnavailable, { message: 'Colissimo: Service Unavailable', code: 503 }.to_json
59
83
  else
60
84
  if (response_message = response.body.to_s.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '').scan(/"parcelNumber":"(.*?)",/).last)
61
85
  parcel_number = response_message.first
62
86
 
63
- return parcel_number
87
+ if ColissimoLabel.s3_bucket
88
+ return parcel_number
89
+ else
90
+ return [parcel_number, label_path, customs_path]
91
+ end
64
92
  else
65
93
  error_message = response.body.to_s.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '').scan(/"messageContent":"(.*?)"/).last&.first
66
- raise StandardError, error_message
94
+ raise ServiceUnavailable, error_message
67
95
  end
68
96
  end
69
97
  end
70
98
 
99
+ def payload
100
+ build_colissimo_payload
101
+ end
102
+
71
103
  private
72
104
 
73
105
  def perform_request(delivery_date = Date.today)
74
- HTTP.post(service_url,
75
- json: {
76
- "contractNumber": ColissimoLabel.contract_number,
77
- "password": ColissimoLabel.contract_password,
78
- "outputFormat": {
79
- "x": '0',
80
- "y": '0',
81
- "outputPrintingType": @label_output_format
82
- },
83
- "letter": {
84
- "service": {
85
- "commercialName": @sender_data[:company_name],
86
- "productCode": product_code,
87
- "depositDate": delivery_date.strftime('%F'),
88
- "totalAmount": (@shipping_fees * 100).to_i,
89
- # "returnTypeChoice": '2' # Retour à la maison en prioritaire
90
- },
91
- "parcel": {
92
- "weight": format_weight,
93
- "pickupLocationId": @pickup_id,
94
- "insuranceValue": @insurance_value
95
- }.compact,
96
- "sender": {
97
- "address": format_sender
98
- },
99
- "addressee": {
100
- "address": format_addressee
101
- }
102
- }.merge(customs_letter)
103
- }.merge(customs_fields)
104
- .compact)
106
+ HTTP.post(service_url, json: build_colissimo_payload(delivery_date))
107
+ end
108
+
109
+ def build_colissimo_payload(delivery_date = Date.today)
110
+ {
111
+ "contractNumber": ColissimoLabel.contract_number,
112
+ "password": ColissimoLabel.contract_password,
113
+ "outputFormat": {
114
+ "x": '0',
115
+ "y": '0',
116
+ "outputPrintingType": @label_output_format
117
+ },
118
+ "letter": {
119
+ "service": {
120
+ "commercialName": @sender_data[:company_name],
121
+ "productCode": @product_code.presence || product_code,
122
+ "depositDate": delivery_date.strftime('%F'),
123
+ "totalAmount": (@shipping_fees * 100).to_i,
124
+ "returnTypeChoice": '2', # Retour à la maison en prioritaire
125
+ "orderNumber": @order_id
126
+ },
127
+ "parcel": {
128
+ "weight": @weight,
129
+ "pickupLocationId": @pickup_id,
130
+ "insuranceValue": @insurance_value
131
+ }.compact,
132
+ "sender": {
133
+ "senderParcelRef": @sender_ref_id,
134
+ "address": format_sender
135
+ }.compact,
136
+ "addressee": {
137
+ "addresseeParcelRef": @addressee_ref_id,
138
+ "address": format_addressee
139
+ }.compact
140
+ }.merge(customs_declaration)
141
+ }.merge(customs_fields).compact
105
142
  end
106
143
 
107
144
  # Services =>
@@ -132,10 +169,13 @@ class ColissimoLabel::GenerateLabel
132
169
  "companyName": @sender_data[:company_name],
133
170
  "lastName": @sender_data[:last_name],
134
171
  "firstName": @sender_data[:first_name],
172
+ "line0": @sender_data[:apartment],
173
+ "line1": @sender_data[:address_bis],
135
174
  "line2": @sender_data[:address],
136
175
  "city": @sender_data[:city],
137
176
  "zipCode": @sender_data[:postcode],
138
- "countryCode": @sender_data[:country_code]
177
+ "countryCode": @sender_data[:country_code],
178
+ "phoneNumber": @sender_data[:phone].presence || @sender_data[:mobile]
139
179
  }.compact.transform_values(&:strip)
140
180
  end
141
181
 
@@ -151,7 +191,7 @@ class ColissimoLabel::GenerateLabel
151
191
  "countryCode": @addressee_data[:country_code], # Code ISO du pays
152
192
  "city": @addressee_data[:city], # Ville
153
193
  "zipCode": @addressee_data[:postcode], # Code postal
154
- "phoneNumber": @addressee_data[:phone], # Numéro de téléphone
194
+ "phoneNumber": @addressee_data[:phone].presence || @addressee_data[:mobile], # Numéro de téléphone
155
195
  "mobileNumber": @addressee_data[:mobile], # Numéro de portable, obligatoire si pickup
156
196
  "doorCode1": @addressee_data[:door_code_1], # Code porte 1
157
197
  "doorCode2": @addressee_data[:door_code_2], # Code porte 2
@@ -165,40 +205,42 @@ class ColissimoLabel::GenerateLabel
165
205
  if require_customs?
166
206
  @customs_total_weight
167
207
  else
168
- @total_weight ? @total_weight : '0.1'
208
+ @total_weight.presence || '0.1'
169
209
  end
170
210
  end
171
211
 
172
212
  # Déclaration douanière de type CN23
173
- def customs_letter
213
+ def customs_declaration
174
214
  if require_customs?
175
215
  {
176
- "customsDeclarations": {
177
- "includeCustomsDeclarations": 1, # Inclure déclaration
178
- "contents": {
179
- "article": @customs_data.map { |customs|
180
- {
181
- "description": customs[:description],
182
- "quantity": customs[:quantity]&.to_i,
183
- "weight": customs[:weight]&.to_f.round(2),
184
- "value": customs[:item_price]&.to_f.round(2),
185
- "originCountry": customs[:country_code],
186
- "currency": customs[:currency_code],
187
- "hsCode": customs[:customs_code] # Objets d'art, de collection ou d'antiquité (https://pro.douane.gouv.fr/prodouane.asp)
216
+ "customsDeclarations":
217
+ {
218
+ "includeCustomsDeclarations": 1, # Inclure déclaration
219
+ "importersReference": @customs_tva_number, # Numéro TVA pour la douane, si besoin
220
+ "contents": {
221
+ "article": @customs_data.map { |product_customs|
222
+ {
223
+ "description": product_customs[:description],
224
+ "quantity": product_customs[:quantity]&.to_i,
225
+ "weight": product_customs[:weight]&.to_f.round(2),
226
+ "value": product_customs[:item_price]&.to_f.round(2),
227
+ "originCountry": product_customs[:country_code],
228
+ "currency": product_customs[:currency_code],
229
+ "hsCode": product_customs[:customs_code].presence
230
+ }.compact
231
+ },
232
+ "category": {
233
+ # Nature de l'envoi
234
+ # 1 => Cadeau
235
+ # 2 => Echantillon commercial
236
+ # 3 => Envoi commercial
237
+ # 4 => Document
238
+ # 5 => Autre
239
+ # 6 => Retour de marchandise
240
+ "value": @customs_category
188
241
  }
189
- },
190
- "category": {
191
- # Nature de l'envoi
192
- # 1 => Cadeau
193
- # 2 => Echantillon commercial
194
- # 3 => Envoi commercial
195
- # 4 => Document
196
- # 5 => Autre
197
- # 6 => Retour de marchandise
198
- "value": 3
199
242
  }
200
- }
201
- }
243
+ }.compact
202
244
  }
203
245
  else
204
246
  {}
@@ -206,7 +248,7 @@ class ColissimoLabel::GenerateLabel
206
248
  end
207
249
 
208
250
  def customs_fields
209
- if require_customs?
251
+ if require_customs? && @eori_number.present?
210
252
  {
211
253
  "fields": {
212
254
  "customField": [
@@ -223,7 +265,7 @@ class ColissimoLabel::GenerateLabel
223
265
  end
224
266
 
225
267
  def require_customs?
226
- %w[CH NO US GB].include?(@destination_country)
268
+ @customs_data.present? || %w[CH NO US GB].include?(@destination_country)
227
269
  end
228
270
 
229
271
  # Certains pays, comme l'Allemagne, requiert une signature pour la livraison
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ColissimoLabel
4
- VERSION = '0.18.0'.freeze
4
+ VERSION = '0.20.0'.freeze
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: colissimo_label
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.0
4
+ version: 0.20.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - FloXcoder
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-01-05 00:00:00.000000000 Z
11
+ date: 2022-10-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -25,21 +25,21 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2'
27
27
  - !ruby/object:Gem::Dependency
28
- name: activesupport
28
+ name: http
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '5'
33
+ version: '4'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '5'
40
+ version: '4'
41
41
  - !ruby/object:Gem::Dependency
42
- name: railties
42
+ name: activesupport
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -53,19 +53,19 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '5'
55
55
  - !ruby/object:Gem::Dependency
56
- name: http
56
+ name: railties
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: '4'
61
+ version: '5'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '4'
68
+ version: '5'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: bundler
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -112,16 +112,16 @@ dependencies:
112
112
  name: simplecov
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - "~>"
115
+ - - ">="
116
116
  - !ruby/object:Gem::Version
117
- version: '0.17'
117
+ version: '0.16'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - "~>"
122
+ - - ">="
123
123
  - !ruby/object:Gem::Version
124
- version: '0.17'
124
+ version: '0.16'
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: webmock
127
127
  requirement: !ruby/object:Gem::Requirement
@@ -182,7 +182,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
182
182
  - !ruby/object:Gem::Version
183
183
  version: '0'
184
184
  requirements: []
185
- rubygems_version: 3.2.4
185
+ rubygems_version: 3.3.22
186
186
  signing_key:
187
187
  specification_version: 4
188
188
  summary: Generate Colissimo label for all countries