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 +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +10 -3
- data/colissimo_label.gemspec +2 -2
- data/lib/colissimo_label/generate_label.rb +125 -85
- data/lib/colissimo_label/version.rb +1 -1
- metadata +16 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 104d8402162a7daf6fcf0eaa5c7a9246ed709a8a7e97d37ecdc84631721d5da1
|
4
|
+
data.tar.gz: 94e1411b953744780448dcd69aba26ae7d4c4ffad071a7477b6c442f002b71ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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/
|
232
|
+
https://www.colissimo.entreprise.laposte.fr/sites/default/files/2021-03/spec_ws_affranchissement.pdf
|
226
233
|
|
227
234
|
## Contributing
|
228
235
|
|
data/colissimo_label.gemspec
CHANGED
@@ -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', '
|
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
|
9
|
-
@destination_country
|
10
|
-
@shipping_fees
|
11
|
-
|
12
|
-
@
|
13
|
-
@
|
14
|
-
|
15
|
-
@
|
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
|
-
@
|
23
|
-
@
|
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
|
-
|
47
|
+
label_path = nil
|
48
|
+
customs_path = nil
|
32
49
|
|
33
50
|
if ColissimoLabel.s3_bucket
|
34
|
-
|
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
|
-
|
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 + '-
|
63
|
+
customs_filename = @filename + '-' + @customs_filename + '.pdf'
|
44
64
|
|
45
65
|
if ColissimoLabel.s3_bucket
|
46
|
-
|
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
|
-
|
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
|
80
|
+
raise ServiceUnavailable, error_message
|
58
81
|
elsif status == 503
|
59
|
-
raise
|
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
|
-
|
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
|
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
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
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
|
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
|
213
|
+
def customs_declaration
|
175
214
|
if require_customs?
|
176
215
|
{
|
177
|
-
"customsDeclarations":
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
"
|
182
|
-
{
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
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
|
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.
|
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:
|
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:
|
28
|
+
name: http
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
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: '
|
40
|
+
version: '4'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
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:
|
56
|
+
name: railties
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
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: '
|
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.
|
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.
|
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.
|
185
|
+
rubygems_version: 3.3.22
|
186
186
|
signing_key:
|
187
187
|
specification_version: 4
|
188
188
|
summary: Generate Colissimo label for all countries
|