@cloudcommerce/app-correios 0.30.0 → 0.31.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.
- package/.turbo/turbo-build.log +1 -1
- package/lib/correios.d.ts +1 -0
- package/lib/correios.js +2 -1
- package/lib/correios.js.map +1 -1
- package/lib-mjs/calculate-shipping.mjs +430 -0
- package/lib-mjs/correios-db.mjs +189 -0
- package/lib-mjs/correios-v2.mjs +84 -0
- package/lib-mjs/utils/constants-parsers.mjs +135 -0
- package/lib-mjs/utils/correios-axios.mjs +93 -0
- package/package.json +16 -8
- package/scripts/tests.sh +11 -0
- package/src/correios.ts +2 -1
- package/tests/calculate-shipping.test.mjs +1 -1
- package/lib-mjs/calculate-correios.mjs +0 -470
- package/lib-mjs/correios-ws.mjs +0 -155
|
@@ -1,470 +0,0 @@
|
|
|
1
|
-
import correiosCalculate from './correios-ws.mjs';
|
|
2
|
-
|
|
3
|
-
export default async ({ params, application }) => {
|
|
4
|
-
const config = {
|
|
5
|
-
...application.data,
|
|
6
|
-
...application.hidden_data,
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
// Correios calculate params
|
|
10
|
-
let nCdServico;
|
|
11
|
-
let sCdMaoPropria;
|
|
12
|
-
let sCdAvisoRecebimento;
|
|
13
|
-
let nVlPeso = 0;
|
|
14
|
-
let nVlValorDeclarado = 0;
|
|
15
|
-
let nCdEmpresa = '';
|
|
16
|
-
let sDsSenha = '';
|
|
17
|
-
const contract = config.correios_contract;
|
|
18
|
-
if (contract) {
|
|
19
|
-
const code = typeof contract.code === 'string' && contract.code.trim();
|
|
20
|
-
if (code) {
|
|
21
|
-
nCdEmpresa = code;
|
|
22
|
-
const password = typeof contract.password === 'string' && contract.password.trim();
|
|
23
|
-
if (password) {
|
|
24
|
-
sDsSenha = password;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
const sCepDestino = params.to?.zip.replace(/\D/g, '') || '';
|
|
29
|
-
const sCepOrigem = params.from?.zip.replace(/\D/g, '')
|
|
30
|
-
|| config.zip?.replace(/\D/g, '')
|
|
31
|
-
|| '';
|
|
32
|
-
|
|
33
|
-
const checkZipCode = (rule) => {
|
|
34
|
-
// validate rule zip range
|
|
35
|
-
if (sCepDestino && rule.zip_range) {
|
|
36
|
-
const { min, max } = rule.zip_range;
|
|
37
|
-
return Boolean((!min || sCepDestino >= min) && (!max || sCepDestino <= max));
|
|
38
|
-
}
|
|
39
|
-
return true;
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
// https://apx-mods.e-com.plus/api/v1/calculate_shipping/response_schema.json?store_id=100
|
|
43
|
-
const response = {
|
|
44
|
-
shipping_services: [],
|
|
45
|
-
};
|
|
46
|
-
// search for configured free shipping rule
|
|
47
|
-
if (Array.isArray(config.shipping_rules)) {
|
|
48
|
-
for (let i = 0; i < config.shipping_rules.length; i++) {
|
|
49
|
-
const rule = config.shipping_rules[i];
|
|
50
|
-
if (rule.free_shipping && checkZipCode(rule)) {
|
|
51
|
-
if (!rule.min_amount) {
|
|
52
|
-
response.free_shipping_from_value = 0;
|
|
53
|
-
break;
|
|
54
|
-
} else if (!(response.free_shipping_from_value <= rule.min_amount)) {
|
|
55
|
-
response.free_shipping_from_value = rule.min_amount;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// params object follows calculate shipping request schema:
|
|
62
|
-
// https://apx-mods.e-com.plus/api/v1/calculate_shipping/schema.json?store_id=100
|
|
63
|
-
if (!params.to) {
|
|
64
|
-
// respond only with free shipping option
|
|
65
|
-
return response;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if (!sCepOrigem) {
|
|
69
|
-
// must have configured origin zip code to continue
|
|
70
|
-
return {
|
|
71
|
-
error: 'CALCULATE_ERR',
|
|
72
|
-
message: 'Zip code is unset on app hidden data (merchant must configure the app)',
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// optinal predefined or configured service codes
|
|
77
|
-
if (params.service_code) {
|
|
78
|
-
nCdServico = params.service_code;
|
|
79
|
-
} else if (Array.isArray(config.services) && config.services[0]) {
|
|
80
|
-
const firstServiceCode = config.services[0].service_code;
|
|
81
|
-
if (firstServiceCode) {
|
|
82
|
-
nCdServico = firstServiceCode;
|
|
83
|
-
for (let i = 1; i < config.services.length; i++) {
|
|
84
|
-
nCdServico += `,${config.services[i].service_code}`;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// optional params to Correios services
|
|
90
|
-
if (params.subtotal && !config.no_declare_value) {
|
|
91
|
-
nVlValorDeclarado = params.subtotal;
|
|
92
|
-
}
|
|
93
|
-
if (params.own_hand) {
|
|
94
|
-
sCdMaoPropria = 's';
|
|
95
|
-
}
|
|
96
|
-
if (params.receipt) {
|
|
97
|
-
sCdAvisoRecebimento = 's';
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// calculate weight and pkg value from items list
|
|
101
|
-
if (params.items) {
|
|
102
|
-
const pkg = {
|
|
103
|
-
dimensions: {
|
|
104
|
-
width: {
|
|
105
|
-
value: 0,
|
|
106
|
-
unit: 'cm',
|
|
107
|
-
},
|
|
108
|
-
height: {
|
|
109
|
-
value: 0,
|
|
110
|
-
unit: 'cm',
|
|
111
|
-
},
|
|
112
|
-
length: {
|
|
113
|
-
value: 0,
|
|
114
|
-
unit: 'cm',
|
|
115
|
-
},
|
|
116
|
-
},
|
|
117
|
-
weight: {
|
|
118
|
-
value: 0,
|
|
119
|
-
unit: 'kg',
|
|
120
|
-
},
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
params.items.forEach(({
|
|
124
|
-
price,
|
|
125
|
-
quantity,
|
|
126
|
-
dimensions,
|
|
127
|
-
weight,
|
|
128
|
-
}) => {
|
|
129
|
-
let physicalWeight = 0;
|
|
130
|
-
let cubicWeight = 0;
|
|
131
|
-
if (!params.subtotal && !config.no_declare_value) {
|
|
132
|
-
nVlValorDeclarado += price * quantity;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// sum physical weight
|
|
136
|
-
if (weight && weight.value) {
|
|
137
|
-
switch (weight.unit) {
|
|
138
|
-
case 'kg':
|
|
139
|
-
physicalWeight = weight.value;
|
|
140
|
-
break;
|
|
141
|
-
case 'g':
|
|
142
|
-
physicalWeight = weight.value / 1000;
|
|
143
|
-
break;
|
|
144
|
-
case 'mg':
|
|
145
|
-
physicalWeight = weight.value / 1000000;
|
|
146
|
-
break;
|
|
147
|
-
default:
|
|
148
|
-
}
|
|
149
|
-
pkg.weight.value += physicalWeight * quantity;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// sum total items dimensions to calculate cubic weight
|
|
153
|
-
if (dimensions) {
|
|
154
|
-
const sumDimensions = {};
|
|
155
|
-
Object.keys(dimensions).forEach((side) => {
|
|
156
|
-
const dimension = dimensions[side];
|
|
157
|
-
if (dimension && dimension.value) {
|
|
158
|
-
let dimensionValue;
|
|
159
|
-
switch (dimension.unit) {
|
|
160
|
-
case 'cm':
|
|
161
|
-
dimensionValue = dimension.value;
|
|
162
|
-
break;
|
|
163
|
-
case 'm':
|
|
164
|
-
dimensionValue = dimension.value * 100;
|
|
165
|
-
break;
|
|
166
|
-
case 'mm':
|
|
167
|
-
dimensionValue = dimension.value / 10;
|
|
168
|
-
break;
|
|
169
|
-
default:
|
|
170
|
-
}
|
|
171
|
-
// add/sum current side to final dimensions object
|
|
172
|
-
if (dimensionValue) {
|
|
173
|
-
sumDimensions[side] = sumDimensions[side]
|
|
174
|
-
? sumDimensions[side] + dimensionValue
|
|
175
|
-
: dimensionValue;
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
// calculate cubic weight
|
|
181
|
-
// https://suporte.boxloja.pro/article/82-correios-calculo-frete
|
|
182
|
-
// (C x L x A) / 6.000
|
|
183
|
-
Object.keys(sumDimensions).forEach((side) => {
|
|
184
|
-
if (sumDimensions[side]) {
|
|
185
|
-
cubicWeight = cubicWeight > 0
|
|
186
|
-
? cubicWeight * sumDimensions[side]
|
|
187
|
-
: sumDimensions[side];
|
|
188
|
-
pkg.dimensions[side].value += sumDimensions[side] * quantity;
|
|
189
|
-
}
|
|
190
|
-
});
|
|
191
|
-
if (cubicWeight > 0) {
|
|
192
|
-
cubicWeight /= 6000;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
if (!config.free_no_weight_shipping || physicalWeight > 0) {
|
|
196
|
-
const unitWeight = cubicWeight < 5 || physicalWeight > cubicWeight
|
|
197
|
-
? physicalWeight : cubicWeight;
|
|
198
|
-
nVlPeso += (quantity * unitWeight);
|
|
199
|
-
}
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
// pre check for maximum allowed declared value
|
|
203
|
-
if (nVlValorDeclarado > 10000) {
|
|
204
|
-
nVlValorDeclarado = 10000;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
let result;
|
|
208
|
-
try {
|
|
209
|
-
result = await correiosCalculate({
|
|
210
|
-
sCepOrigem,
|
|
211
|
-
sCepDestino,
|
|
212
|
-
nCdEmpresa,
|
|
213
|
-
sDsSenha,
|
|
214
|
-
nCdServico,
|
|
215
|
-
sCdMaoPropria,
|
|
216
|
-
sCdAvisoRecebimento,
|
|
217
|
-
nVlPeso,
|
|
218
|
-
nVlValorDeclarado,
|
|
219
|
-
});
|
|
220
|
-
} catch (err) {
|
|
221
|
-
return {
|
|
222
|
-
error: 'CALCULATE_FAILED',
|
|
223
|
-
message: err.message,
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
const { Servicos, cServico } = result;
|
|
228
|
-
// set services array from `Servicos` or `cServico`
|
|
229
|
-
let services;
|
|
230
|
-
if (Servicos) {
|
|
231
|
-
if (Array.isArray(Servicos)) {
|
|
232
|
-
services = Servicos;
|
|
233
|
-
} else if (Servicos.cServico) {
|
|
234
|
-
services = Array.isArray(Servicos.cServico) ? Servicos.cServico : [Servicos.cServico];
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
if (!services) {
|
|
238
|
-
services = Array.isArray(cServico) ? cServico : [cServico];
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
if (services[0] && services[0].Codigo) {
|
|
242
|
-
let errorMsg;
|
|
243
|
-
services.forEach((service) => {
|
|
244
|
-
// check error first
|
|
245
|
-
let { Erro, PrazoEntrega } = service;
|
|
246
|
-
const { MsgErro, url } = service;
|
|
247
|
-
let notes;
|
|
248
|
-
PrazoEntrega = parseInt(PrazoEntrega, 10);
|
|
249
|
-
// known Correios errors
|
|
250
|
-
switch (Erro) {
|
|
251
|
-
case '010':
|
|
252
|
-
case 10:
|
|
253
|
-
Erro = false;
|
|
254
|
-
notes = MsgErro;
|
|
255
|
-
break;
|
|
256
|
-
case '011':
|
|
257
|
-
case 11:
|
|
258
|
-
Erro = false;
|
|
259
|
-
PrazoEntrega += 7;
|
|
260
|
-
break;
|
|
261
|
-
default:
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
if ((!Erro || Erro === '0') && PrazoEntrega >= 0) {
|
|
265
|
-
// fix price strings to number
|
|
266
|
-
[
|
|
267
|
-
'Valor',
|
|
268
|
-
'ValorSemAdicionais',
|
|
269
|
-
'ValorMaoPropria',
|
|
270
|
-
'ValorAvisoRecebimento',
|
|
271
|
-
'ValorValorDeclarado',
|
|
272
|
-
].forEach((field) => {
|
|
273
|
-
switch (typeof service[field]) {
|
|
274
|
-
case 'number':
|
|
275
|
-
break;
|
|
276
|
-
case 'string':
|
|
277
|
-
service[field] = parseFloat(service[field].replace('.', '').replace(',', '.'));
|
|
278
|
-
break;
|
|
279
|
-
default:
|
|
280
|
-
service[field] = 0;
|
|
281
|
-
}
|
|
282
|
-
});
|
|
283
|
-
const {
|
|
284
|
-
Codigo,
|
|
285
|
-
Valor,
|
|
286
|
-
ValorSemAdicionais,
|
|
287
|
-
ValorMaoPropria,
|
|
288
|
-
ValorAvisoRecebimento,
|
|
289
|
-
ValorValorDeclarado,
|
|
290
|
-
} = service;
|
|
291
|
-
|
|
292
|
-
// find respective configured service label
|
|
293
|
-
let serviceName;
|
|
294
|
-
switch (Codigo) {
|
|
295
|
-
case '04014':
|
|
296
|
-
serviceName = 'SEDEX';
|
|
297
|
-
break;
|
|
298
|
-
case '04510':
|
|
299
|
-
serviceName = 'PAC';
|
|
300
|
-
break;
|
|
301
|
-
default:
|
|
302
|
-
}
|
|
303
|
-
let label = serviceName || `Correios ${Codigo}`;
|
|
304
|
-
if (Array.isArray(config.services)) {
|
|
305
|
-
for (let i = 0; i < config.services.length; i++) {
|
|
306
|
-
const _service = config.services[i];
|
|
307
|
-
if (_service && _service.service_code === Codigo && _service.label) {
|
|
308
|
-
label = _service.label;
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
// parse to E-Com Plus shipping line object
|
|
314
|
-
const shippingLine = {
|
|
315
|
-
from: {
|
|
316
|
-
...params.from,
|
|
317
|
-
zip: sCepOrigem,
|
|
318
|
-
},
|
|
319
|
-
to: params.to,
|
|
320
|
-
package: pkg,
|
|
321
|
-
price: ValorSemAdicionais || Valor,
|
|
322
|
-
declared_value: nVlValorDeclarado,
|
|
323
|
-
declared_value_price: ValorValorDeclarado > 0 ? ValorValorDeclarado : 0,
|
|
324
|
-
own_hand: Boolean(sCdMaoPropria),
|
|
325
|
-
own_hand_price: ValorMaoPropria,
|
|
326
|
-
receipt: Boolean(sCdAvisoRecebimento),
|
|
327
|
-
receipt_price: ValorAvisoRecebimento,
|
|
328
|
-
discount: 0,
|
|
329
|
-
total_price: Valor,
|
|
330
|
-
delivery_time: {
|
|
331
|
-
days: PrazoEntrega,
|
|
332
|
-
working_days: true,
|
|
333
|
-
},
|
|
334
|
-
posting_deadline: {
|
|
335
|
-
days: 3,
|
|
336
|
-
...config.posting_deadline,
|
|
337
|
-
},
|
|
338
|
-
flags: ['correios-ws'],
|
|
339
|
-
notes,
|
|
340
|
-
};
|
|
341
|
-
|
|
342
|
-
// check for default configured additional/discount price
|
|
343
|
-
if (typeof config.additional_price === 'number' && config.additional_price) {
|
|
344
|
-
if (config.additional_price > 0) {
|
|
345
|
-
shippingLine.other_additionals = [{
|
|
346
|
-
tag: 'additional_price',
|
|
347
|
-
label: 'Adicional padrão',
|
|
348
|
-
price: config.additional_price,
|
|
349
|
-
}];
|
|
350
|
-
} else {
|
|
351
|
-
// negative additional price to apply discount
|
|
352
|
-
shippingLine.discount -= config.additional_price;
|
|
353
|
-
}
|
|
354
|
-
// update total price
|
|
355
|
-
shippingLine.total_price += config.additional_price;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
// search for discount by shipping rule
|
|
359
|
-
if (Array.isArray(config.shipping_rules)) {
|
|
360
|
-
for (let i = 0; i < config.shipping_rules.length; i++) {
|
|
361
|
-
const rule = config.shipping_rules[i];
|
|
362
|
-
if (
|
|
363
|
-
rule
|
|
364
|
-
&& (!rule.service_code || rule.service_code === Codigo)
|
|
365
|
-
&& checkZipCode(rule)
|
|
366
|
-
&& !(rule.min_amount > params.subtotal)
|
|
367
|
-
) {
|
|
368
|
-
// valid shipping rule
|
|
369
|
-
if (rule.free_shipping) {
|
|
370
|
-
shippingLine.discount += shippingLine.total_price;
|
|
371
|
-
shippingLine.total_price = 0;
|
|
372
|
-
break;
|
|
373
|
-
} else if (rule.discount) {
|
|
374
|
-
let discountValue = rule.discount.value;
|
|
375
|
-
if (rule.discount.percentage) {
|
|
376
|
-
discountValue *= (shippingLine.total_price / 100);
|
|
377
|
-
}
|
|
378
|
-
if (discountValue) {
|
|
379
|
-
shippingLine.discount += discountValue;
|
|
380
|
-
shippingLine.total_price -= discountValue;
|
|
381
|
-
if (shippingLine.total_price < 0) {
|
|
382
|
-
shippingLine.total_price = 0;
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
break;
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
if (typeof url === 'string') {
|
|
392
|
-
// add WS URL to custom fields to facilitate debugging
|
|
393
|
-
shippingLine.custom_fields = [{
|
|
394
|
-
field: 'correios_ws_params',
|
|
395
|
-
value: (nCdEmpresa ? url.replace(nCdEmpresa, 'c').replace(sDsSenha, 's') : url)
|
|
396
|
-
.replace(/[^?]+\?(.*)/, '$1')
|
|
397
|
-
.replace(/(StrRetorno|nIndicaCalculo|nCdFormato|nVlDiametro)=[^&]+&?/g, '')
|
|
398
|
-
.slice(0, 255),
|
|
399
|
-
}];
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
// push shipping service object to response
|
|
403
|
-
response.shipping_services.push({
|
|
404
|
-
label,
|
|
405
|
-
carrier: 'Correios',
|
|
406
|
-
// https://informederendimentos.com/consulta/cnpj-correios/
|
|
407
|
-
carrier_doc_number: '34028316000103',
|
|
408
|
-
service_code: Codigo,
|
|
409
|
-
service_name: serviceName || label,
|
|
410
|
-
shipping_line: shippingLine,
|
|
411
|
-
});
|
|
412
|
-
} else {
|
|
413
|
-
errorMsg = `Correios erro ${Erro}`;
|
|
414
|
-
if (typeof MsgErro === 'string') {
|
|
415
|
-
errorMsg += `: ${MsgErro}`;
|
|
416
|
-
}
|
|
417
|
-
if (typeof url === 'string') {
|
|
418
|
-
errorMsg += `\n${url}`;
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
});
|
|
422
|
-
|
|
423
|
-
if (response.shipping_services.length) {
|
|
424
|
-
// free shipping if all items has no weigth
|
|
425
|
-
const freeNoWeightShipping = nVlPeso <= 0 && config.free_no_weight_shipping;
|
|
426
|
-
if (freeNoWeightShipping) {
|
|
427
|
-
let cheapestShippingLine;
|
|
428
|
-
for (let i = 0; i < response.shipping_services.length; i++) {
|
|
429
|
-
const shippingLine = response.shipping_services[i].shipping_line;
|
|
430
|
-
if (!shippingLine.total_price) {
|
|
431
|
-
// already free
|
|
432
|
-
break;
|
|
433
|
-
}
|
|
434
|
-
if (
|
|
435
|
-
!cheapestShippingLine
|
|
436
|
-
|| cheapestShippingLine.total_price > shippingLine.total_price
|
|
437
|
-
) {
|
|
438
|
-
cheapestShippingLine = shippingLine;
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
if (cheapestShippingLine) {
|
|
442
|
-
// set the cheapest shipping line free
|
|
443
|
-
cheapestShippingLine.discount = cheapestShippingLine.total_price;
|
|
444
|
-
cheapestShippingLine.total_price = 0;
|
|
445
|
-
cheapestShippingLine.flags.push('free_no_weight');
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
} else if (errorMsg) {
|
|
449
|
-
// pass Correios error message
|
|
450
|
-
return {
|
|
451
|
-
error: 'CALCULATE_ERR_MSG',
|
|
452
|
-
message: errorMsg,
|
|
453
|
-
};
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
// success response with available shipping services
|
|
457
|
-
return response;
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
// unexpected result object
|
|
461
|
-
return {
|
|
462
|
-
error: 'CALCULATE_UNEXPECTED_RSP',
|
|
463
|
-
message: 'Unexpected object from Correios response, please try again later',
|
|
464
|
-
};
|
|
465
|
-
}
|
|
466
|
-
return {
|
|
467
|
-
error: 'CALCULATE_EMPTY_CART',
|
|
468
|
-
message: 'Cannot calculate shipping without cart items',
|
|
469
|
-
};
|
|
470
|
-
};
|
package/lib-mjs/correios-ws.mjs
DELETED
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-console */
|
|
2
|
-
import axios from 'axios';
|
|
3
|
-
import * as xml2js from 'xml2js';
|
|
4
|
-
|
|
5
|
-
const roundDecimal = (num) => Math.round(num * 100) / 100;
|
|
6
|
-
|
|
7
|
-
// https://www.correios.com.br/precos-e-prazos/calculador-remoto-de-precos-e-prazos
|
|
8
|
-
const baseUrl = 'http://ws.correios.com.br/calculador/CalcPrecoPrazo.aspx?StrRetorno=xml';
|
|
9
|
-
|
|
10
|
-
const sendCalculateRequest = (params, timeout, isDebug = false) => {
|
|
11
|
-
let url = baseUrl;
|
|
12
|
-
Object.keys(params).forEach((param) => {
|
|
13
|
-
if (params[param] !== undefined) {
|
|
14
|
-
url += `&${param}=${params[param]}`;
|
|
15
|
-
}
|
|
16
|
-
});
|
|
17
|
-
if (isDebug === true) {
|
|
18
|
-
// eslint-disable-next-line no-console
|
|
19
|
-
console.log(`[ws] ${url}`);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
return axios({
|
|
23
|
-
method: 'get',
|
|
24
|
-
url,
|
|
25
|
-
timeout,
|
|
26
|
-
responseType: 'text',
|
|
27
|
-
})
|
|
28
|
-
.then(async (response) => {
|
|
29
|
-
// parse XML to object
|
|
30
|
-
// https://www.npmjs.com/package/xml2js#options/
|
|
31
|
-
const result = await xml2js.parseStringPromise(response.data, { explicitArray: false });
|
|
32
|
-
let services;
|
|
33
|
-
if (Array.isArray(result.Servicos)) {
|
|
34
|
-
services = result.Servicos;
|
|
35
|
-
} else {
|
|
36
|
-
services = Array.isArray(result.Servicos.cServico)
|
|
37
|
-
? result.Servicos.cServico
|
|
38
|
-
: [result.Servicos.cServico];
|
|
39
|
-
}
|
|
40
|
-
const availableService = services.find(({ Erro, MsgErro }) => {
|
|
41
|
-
return String(Erro) !== '-33' && !String(MsgErro).includes('Unavailable');
|
|
42
|
-
});
|
|
43
|
-
if (availableService) {
|
|
44
|
-
return {
|
|
45
|
-
...result,
|
|
46
|
-
services,
|
|
47
|
-
url,
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
const err = new Error('Correios WS unavailable');
|
|
51
|
-
err.code = 'E503';
|
|
52
|
-
err.config = response.config;
|
|
53
|
-
err.response = response;
|
|
54
|
-
throw err;
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
.catch((error) => {
|
|
58
|
-
switch (error.code) {
|
|
59
|
-
case 'ECONNRESET':
|
|
60
|
-
case 'ECONNABORTED':
|
|
61
|
-
case 'ETIMEDOUT':
|
|
62
|
-
break;
|
|
63
|
-
default:
|
|
64
|
-
// Debug unknown error
|
|
65
|
-
if (error.response) {
|
|
66
|
-
const err = new Error('Correios WS error');
|
|
67
|
-
err.code = error.code;
|
|
68
|
-
err.config = error.config;
|
|
69
|
-
err.response = {
|
|
70
|
-
status: error.response.status,
|
|
71
|
-
data: error.response.data,
|
|
72
|
-
};
|
|
73
|
-
console.error(err);
|
|
74
|
-
} else {
|
|
75
|
-
console.error(error);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
throw error;
|
|
79
|
-
});
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
export default (params, timeout = 20000, isDebug = false) => {
|
|
83
|
-
params.nIndicaCalculo = 3;
|
|
84
|
-
params.nCdFormato = 1;
|
|
85
|
-
params.nVlDiametro = 0;
|
|
86
|
-
if (!params.nCdServico) {
|
|
87
|
-
// PAC, SEDEX
|
|
88
|
-
params.nCdServico = '04510,04014';
|
|
89
|
-
}
|
|
90
|
-
// Check minimum package dimensions
|
|
91
|
-
if (!(params.nVlPeso >= 0.1)) {
|
|
92
|
-
params.nVlPeso = 0.1;
|
|
93
|
-
} else {
|
|
94
|
-
params.nVlPeso = roundDecimal(params.nVlPeso);
|
|
95
|
-
}
|
|
96
|
-
if (!(params.nVlComprimento >= 16)) {
|
|
97
|
-
params.nVlComprimento = 16;
|
|
98
|
-
}
|
|
99
|
-
if (!(params.nVlAltura >= 2)) {
|
|
100
|
-
params.nVlAltura = 2;
|
|
101
|
-
}
|
|
102
|
-
if (!(params.nVlLargura >= 11)) {
|
|
103
|
-
params.nVlLargura = 11;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// Optional additional services
|
|
107
|
-
['sCdMaoPropria', 'sCdAvisoRecebimento'].forEach((param) => {
|
|
108
|
-
if (!params[param]) {
|
|
109
|
-
params[param] = 'n';
|
|
110
|
-
}
|
|
111
|
-
});
|
|
112
|
-
if (params.nVlValorDeclarado === undefined) {
|
|
113
|
-
params.nVlValorDeclarado = 0;
|
|
114
|
-
} else if (params.nVlValorDeclarado < 24) {
|
|
115
|
-
params.nVlValorDeclarado = 24;
|
|
116
|
-
} else if (params.nVlValorDeclarado > 10000) {
|
|
117
|
-
params.nVlValorDeclarado = 10000;
|
|
118
|
-
} else {
|
|
119
|
-
params.nVlValorDeclarado = roundDecimal(params.nVlValorDeclarado);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
const promises = [];
|
|
123
|
-
if (!params.nCdEmpresa || !params.sDsSenha) {
|
|
124
|
-
// Correios limit up to 1 service code per public request
|
|
125
|
-
params.nCdServico.split(',').forEach((nCdServico) => {
|
|
126
|
-
if (nCdServico) {
|
|
127
|
-
promises.push(sendCalculateRequest({ ...params, nCdServico }, timeout, isDebug));
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
|
-
} else {
|
|
131
|
-
// Can send multiple service codes
|
|
132
|
-
promises.push(sendCalculateRequest(params, timeout, isDebug));
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
return Promise.all(promises).then((results) => {
|
|
136
|
-
if (results.length === 1) {
|
|
137
|
-
// single request with multiple services
|
|
138
|
-
const { Servicos, url } = results[0];
|
|
139
|
-
const { cServico } = Servicos;
|
|
140
|
-
return {
|
|
141
|
-
Servicos: {
|
|
142
|
-
cServico: (Array.isArray(cServico) ? cServico : [cServico])
|
|
143
|
-
.map((_cServico) => ({ ..._cServico, url })),
|
|
144
|
-
},
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
return {
|
|
148
|
-
Servicos: {
|
|
149
|
-
cServico: results.map(({ Servicos, url }) => {
|
|
150
|
-
return { ...Servicos.cServico, url };
|
|
151
|
-
}),
|
|
152
|
-
},
|
|
153
|
-
};
|
|
154
|
-
});
|
|
155
|
-
};
|