colissimo_label 0.19.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: d58ca859be28bd4c1904888ffd0a04ce9f2a0fe3eb4685d530a9c63ac64fc24d
4
- data.tar.gz: b0101152eecda5a85baaf0f02e337abde20d525646e4c91751104dbc423cb554
3
+ metadata.gz: 104d8402162a7daf6fcf0eaa5c7a9246ed709a8a7e97d37ecdc84631721d5da1
4
+ data.tar.gz: 94e1411b953744780448dcd69aba26ae7d4c4ffad071a7477b6c442f002b71ba
5
5
  SHA512:
6
- metadata.gz: cf756d30f2c61764de70d2e60dbc0d5d0ecd1dbe75a6411a05457e8981042cddec79ebf37143fd5048a60a057e39649060a2e84614233c0f671be3fa97b012d9
7
- data.tar.gz: 01c0681b6bc6c1a619299a6bd94f3151cd8a01ed3ccf4bfe22a8f4fcff77b7b4232cb9f833c5c46d72e2a5fd648869a25bf389f4ad02b5808b5bc3e1576cc423
6
+ metadata.gz: 04ef4dfe6942583abcddee37a7fb1e2519a44c2380b5223c89d28c26284e5dcb746e59086c41e65cb75e98e457862e7429a2c1867eab551f70a8c085d1e78b9e
7
+ data.tar.gz: 42008e2705a23bb3305117c87254baebab36dcf97546ccb7374e15c026ff21c6b78341f61fba522f9db7431ad27b13f3669c79b19b733fde67217dff7cdf713c
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
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
+
1
8
  ## 0.19.0
2
9
 
3
10
  - Add new option field: specific TVA number for customs
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,24 +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)
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
+
25
+ @customs_data = options.fetch(:customs_data, nil)
16
26
  @customs_total_weight = options.fetch(:customs_total_weight, nil)
27
+ @customs_category = options.fetch(:customs_category, 3)
17
28
  @customs_tva_number = options.fetch(:customs_tva_number, nil)
18
- @customs_data = options.fetch(:customs_data, nil)
19
- @with_signature = options.fetch(:with_signature, false)
20
- @insurance_value = options.fetch(:insurance_value, nil)
21
29
  @eori_number = options.fetch(:eori_number, nil)
22
- @label_output_format = options.fetch(:label_output_format, 'PDF_10x15_300dpi')
23
- @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 = []
24
40
  end
25
41
 
26
42
  def perform
@@ -28,25 +44,32 @@ class ColissimoLabel::GenerateLabel
28
44
  status = response.code
29
45
  parts = response.to_a.last.force_encoding('BINARY').split('Content-ID: ')
30
46
  label_filename = @filename + '.' + file_format
31
- local_path = ColissimoLabel.colissimo_local_path&.chomp('/')
47
+ label_path = nil
48
+ customs_path = nil
32
49
 
33
50
  if ColissimoLabel.s3_bucket
34
- 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)
35
53
  colissimo_pdf.put(acl: 'public-read', body: parts[2])
36
54
  else
37
- 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|
38
58
  file.write(parts[2])
39
59
  end
40
60
  end
41
61
 
42
62
  if require_customs?
43
- customs_filename = @filename + '-customs.pdf'
63
+ customs_filename = @filename + '-' + @customs_filename + '.pdf'
44
64
 
45
65
  if ColissimoLabel.s3_bucket
46
- 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)
47
68
  customs_pdf.put(acl: 'public-read', body: parts[3])
48
69
  else
49
- 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|
50
73
  file.write(parts[3])
51
74
  end
52
75
  end
@@ -54,55 +77,68 @@ class ColissimoLabel::GenerateLabel
54
77
 
55
78
  if status == 400 || status == 500
56
79
  error_message = response.body.to_s.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '').scan(/"messageContent":"(.*?)"/).last&.first
57
- raise StandardError, error_message
80
+ raise ServiceUnavailable, error_message
58
81
  elsif status == 503
59
- raise StandardError, { message: 'Colissimo: Service Unavailable' }
82
+ raise ServiceUnavailable, { message: 'Colissimo: Service Unavailable', code: 503 }.to_json
60
83
  else
61
84
  if (response_message = response.body.to_s.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '').scan(/"parcelNumber":"(.*?)",/).last)
62
85
  parcel_number = response_message.first
63
86
 
64
- return parcel_number
87
+ if ColissimoLabel.s3_bucket
88
+ return parcel_number
89
+ else
90
+ return [parcel_number, label_path, customs_path]
91
+ end
65
92
  else
66
93
  error_message = response.body.to_s.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '').scan(/"messageContent":"(.*?)"/).last&.first
67
- raise StandardError, error_message
94
+ raise ServiceUnavailable, error_message
68
95
  end
69
96
  end
70
97
  end
71
98
 
99
+ def payload
100
+ build_colissimo_payload
101
+ end
102
+
72
103
  private
73
104
 
74
105
  def perform_request(delivery_date = Date.today)
75
- HTTP.post(service_url,
76
- json: {
77
- "contractNumber": ColissimoLabel.contract_number,
78
- "password": ColissimoLabel.contract_password,
79
- "outputFormat": {
80
- "x": '0',
81
- "y": '0',
82
- "outputPrintingType": @label_output_format
83
- },
84
- "letter": {
85
- "service": {
86
- "commercialName": @sender_data[:company_name],
87
- "productCode": product_code,
88
- "depositDate": delivery_date.strftime('%F'),
89
- "totalAmount": (@shipping_fees * 100).to_i,
90
- # "returnTypeChoice": '2' # Retour à la maison en prioritaire
91
- },
92
- "parcel": {
93
- "weight": format_weight,
94
- "pickupLocationId": @pickup_id,
95
- "insuranceValue": @insurance_value
96
- }.compact,
97
- "sender": {
98
- "address": format_sender
99
- },
100
- "addressee": {
101
- "address": format_addressee
102
- }
103
- }.merge(customs_letter)
104
- }.merge(customs_fields)
105
- .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
106
142
  end
107
143
 
108
144
  # Services =>
@@ -133,10 +169,13 @@ class ColissimoLabel::GenerateLabel
133
169
  "companyName": @sender_data[:company_name],
134
170
  "lastName": @sender_data[:last_name],
135
171
  "firstName": @sender_data[:first_name],
172
+ "line0": @sender_data[:apartment],
173
+ "line1": @sender_data[:address_bis],
136
174
  "line2": @sender_data[:address],
137
175
  "city": @sender_data[:city],
138
176
  "zipCode": @sender_data[:postcode],
139
- "countryCode": @sender_data[:country_code]
177
+ "countryCode": @sender_data[:country_code],
178
+ "phoneNumber": @sender_data[:phone].presence || @sender_data[:mobile]
140
179
  }.compact.transform_values(&:strip)
141
180
  end
142
181
 
@@ -152,7 +191,7 @@ class ColissimoLabel::GenerateLabel
152
191
  "countryCode": @addressee_data[:country_code], # Code ISO du pays
153
192
  "city": @addressee_data[:city], # Ville
154
193
  "zipCode": @addressee_data[:postcode], # Code postal
155
- "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
156
195
  "mobileNumber": @addressee_data[:mobile], # Numéro de portable, obligatoire si pickup
157
196
  "doorCode1": @addressee_data[:door_code_1], # Code porte 1
158
197
  "doorCode2": @addressee_data[:door_code_2], # Code porte 2
@@ -166,41 +205,42 @@ class ColissimoLabel::GenerateLabel
166
205
  if require_customs?
167
206
  @customs_total_weight
168
207
  else
169
- @total_weight ? @total_weight : '0.1'
208
+ @total_weight.presence || '0.1'
170
209
  end
171
210
  end
172
211
 
173
212
  # Déclaration douanière de type CN23
174
- def customs_letter
213
+ def customs_declaration
175
214
  if require_customs?
176
215
  {
177
- "customsDeclarations": {
178
- "includeCustomsDeclarations": 1, # Inclure déclaration,
179
- "importersReference": @customs_tva_number, # Numéro TVA pour la douane, si besoin
180
- "contents": {
181
- "article": @customs_data.map { |customs|
182
- {
183
- "description": customs[:description],
184
- "quantity": customs[:quantity]&.to_i,
185
- "weight": customs[:weight]&.to_f.round(2),
186
- "value": customs[:item_price]&.to_f.round(2),
187
- "originCountry": customs[:country_code],
188
- "currency": customs[:currency_code],
189
- "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
190
241
  }
191
- },
192
- "category": {
193
- # Nature de l'envoi
194
- # 1 => Cadeau
195
- # 2 => Echantillon commercial
196
- # 3 => Envoi commercial
197
- # 4 => Document
198
- # 5 => Autre
199
- # 6 => Retour de marchandise
200
- "value": 3
201
242
  }
202
- }
203
- }
243
+ }.compact
204
244
  }
205
245
  else
206
246
  {}
@@ -208,7 +248,7 @@ class ColissimoLabel::GenerateLabel
208
248
  end
209
249
 
210
250
  def customs_fields
211
- if require_customs?
251
+ if require_customs? && @eori_number.present?
212
252
  {
213
253
  "fields": {
214
254
  "customField": [
@@ -225,7 +265,7 @@ class ColissimoLabel::GenerateLabel
225
265
  end
226
266
 
227
267
  def require_customs?
228
- %w[CH NO US GB].include?(@destination_country)
268
+ @customs_data.present? || %w[CH NO US GB].include?(@destination_country)
229
269
  end
230
270
 
231
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.19.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.19.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-04-09 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.3
185
+ rubygems_version: 3.3.22
186
186
  signing_key:
187
187
  specification_version: 4
188
188
  summary: Generate Colissimo label for all countries