@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
package/.turbo/turbo-build.log
CHANGED
package/lib/correios.d.ts
CHANGED
package/lib/correios.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import '@cloudcommerce/firebase/lib/init';
|
|
2
|
+
import handleCalculateShipping from '../lib-mjs/calculate-shipping.mjs';
|
|
2
3
|
|
|
3
4
|
export const calculateShipping = async (modBody) => {
|
|
4
5
|
return handleCalculateShipping(modBody);
|
package/lib/correios.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"correios.js","sourceRoot":"","sources":["../src/correios.ts"],"names":[],"mappings":"AAEA,OAAO,uBAAuB,MAAM,mCAAmC,CAAC;AAExE,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,EAAE,OAAsB,EAAE,EAAE;IAChE,OAAO,uBAAuB,CAAC,OAAO,CAAC,CAAC;AAC1C,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"correios.js","sourceRoot":"","sources":["../src/correios.ts"],"names":[],"mappings":"AAEA,OAAO,kCAAkC,CAAC;AAC1C,OAAO,uBAAuB,MAAM,mCAAmC,CAAC;AAExE,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,EAAE,OAAsB,EAAE,EAAE;IAChE,OAAO,uBAAuB,CAAC,OAAO,CAAC,CAAC;AAC1C,CAAC,CAAC"}
|
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
import logger from 'firebase-functions/logger';
|
|
2
|
+
import config from '@cloudcommerce/firebase/lib/config';
|
|
3
|
+
import { getFirestore, Timestamp } from 'firebase-admin/firestore';
|
|
4
|
+
import {
|
|
5
|
+
getDocId,
|
|
6
|
+
parseZipCode,
|
|
7
|
+
findBaseWeight,
|
|
8
|
+
setCredentials,
|
|
9
|
+
dataToDoc,
|
|
10
|
+
docToData,
|
|
11
|
+
} from './utils/constants-parsers.mjs';
|
|
12
|
+
import calculateV2 from './correios-v2.mjs';
|
|
13
|
+
import { newCorreios } from './utils/correios-axios.mjs';
|
|
14
|
+
|
|
15
|
+
export default async ({ params, application }) => {
|
|
16
|
+
const configApp = {
|
|
17
|
+
...application.data,
|
|
18
|
+
...application.hidden_data,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const { metafields } = config.get();
|
|
22
|
+
|
|
23
|
+
setCredentials(configApp);
|
|
24
|
+
|
|
25
|
+
// setup basic required response object
|
|
26
|
+
const response = {
|
|
27
|
+
shipping_services: [],
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
if (configApp.free_shipping_from_value >= 0) {
|
|
31
|
+
response.free_shipping_from_value = configApp.free_shipping_from_value;
|
|
32
|
+
}
|
|
33
|
+
if (!params.to) {
|
|
34
|
+
// just a free shipping preview with no shipping address received
|
|
35
|
+
// respond only with free shipping option
|
|
36
|
+
return response;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const cepDestino = params.to ? params.to.zip.replace(/\D/g, '') : '';
|
|
40
|
+
|
|
41
|
+
let cepOrigem;
|
|
42
|
+
if (params.from) {
|
|
43
|
+
cepOrigem = params.from.zip.replace(/\D/g, '');
|
|
44
|
+
} else if (configApp.zip) {
|
|
45
|
+
cepOrigem = configApp.zip.replace(/\D/g, '');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (!cepOrigem) {
|
|
49
|
+
// must have configured origin zip code to continue
|
|
50
|
+
return {
|
|
51
|
+
error: 'CALCULATE_ERR',
|
|
52
|
+
message: 'Zip code is unset on app hidden data (merchant must configure the app)',
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
if (!params.items) {
|
|
56
|
+
return {
|
|
57
|
+
error: 'CALCULATE_EMPTY_CART',
|
|
58
|
+
message: 'Cannot calculate shipping without cart items',
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const checkZipCode = (rule) => {
|
|
63
|
+
// validate rule zip range
|
|
64
|
+
if (cepDestino && rule.zip_range) {
|
|
65
|
+
const { min, max } = rule.zip_range;
|
|
66
|
+
return Boolean((!min || cepDestino >= min) && (!max || cepDestino <= max));
|
|
67
|
+
}
|
|
68
|
+
return true;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
// search for configured free shipping rule
|
|
72
|
+
if (Array.isArray(configApp.shipping_rules)) {
|
|
73
|
+
for (let i = 0; i < configApp.shipping_rules.length; i++) {
|
|
74
|
+
const rule = configApp.shipping_rules[i];
|
|
75
|
+
if (rule.free_shipping && checkZipCode(rule)) {
|
|
76
|
+
if (!rule.min_amount) {
|
|
77
|
+
response.free_shipping_from_value = 0;
|
|
78
|
+
break;
|
|
79
|
+
} else if (!(response.free_shipping_from_value <= rule.min_amount)) {
|
|
80
|
+
response.free_shipping_from_value = rule.min_amount;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// optinal predefined or configured service codes
|
|
87
|
+
let serviceCodes;
|
|
88
|
+
if (params.service_code) {
|
|
89
|
+
serviceCodes = [params.service_code];
|
|
90
|
+
} else if (configApp.services?.[0]?.service_code) {
|
|
91
|
+
serviceCodes = configApp.services.map((service) => service.service_code);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// optional params to Correios services
|
|
95
|
+
let vlDeclarado = 0;
|
|
96
|
+
// const servicosAdicionais = [];
|
|
97
|
+
if (params.subtotal && !configApp.no_declare_value) {
|
|
98
|
+
vlDeclarado = params.subtotal;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// calculate weight and pkg value from items list
|
|
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: 'g',
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
let cubicWeight = 0;
|
|
124
|
+
let psObj = 0;
|
|
125
|
+
|
|
126
|
+
params.items.forEach(({
|
|
127
|
+
price,
|
|
128
|
+
quantity,
|
|
129
|
+
dimensions,
|
|
130
|
+
weight,
|
|
131
|
+
}) => {
|
|
132
|
+
if (!params.subtotal && !configApp.no_declare_value) {
|
|
133
|
+
vlDeclarado += price * quantity;
|
|
134
|
+
}
|
|
135
|
+
// sum physical weight
|
|
136
|
+
let weightValue;
|
|
137
|
+
if (weight && weight.value) {
|
|
138
|
+
switch (weight.unit) {
|
|
139
|
+
case 'kg':
|
|
140
|
+
weightValue = weight.value * 1000;
|
|
141
|
+
break;
|
|
142
|
+
case 'g':
|
|
143
|
+
weightValue = weight.value;
|
|
144
|
+
break;
|
|
145
|
+
case 'mg':
|
|
146
|
+
weightValue = weight.value / 1000;
|
|
147
|
+
break;
|
|
148
|
+
default:
|
|
149
|
+
weightValue = weight.value;
|
|
150
|
+
}
|
|
151
|
+
if (weightValue) {
|
|
152
|
+
pkg.weight.value += weightValue * quantity;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// sum total items dimensions to calculate cubic weight
|
|
157
|
+
if (dimensions) {
|
|
158
|
+
const sumDimensions = {};
|
|
159
|
+
Object.keys(dimensions).forEach((side) => {
|
|
160
|
+
const dimension = dimensions[side];
|
|
161
|
+
if (dimension && dimension.value) {
|
|
162
|
+
let dimensionValue;
|
|
163
|
+
switch (dimension.unit) {
|
|
164
|
+
case 'cm':
|
|
165
|
+
dimensionValue = dimension.value;
|
|
166
|
+
break;
|
|
167
|
+
case 'm':
|
|
168
|
+
dimensionValue = dimension.value * 100;
|
|
169
|
+
break;
|
|
170
|
+
case 'mm':
|
|
171
|
+
dimensionValue = dimension.value / 10;
|
|
172
|
+
break;
|
|
173
|
+
default:
|
|
174
|
+
dimensionValue = dimension.value;
|
|
175
|
+
}
|
|
176
|
+
// add/sum current side to final dimensions object
|
|
177
|
+
if (dimensionValue) {
|
|
178
|
+
sumDimensions[side] = sumDimensions[side]
|
|
179
|
+
? sumDimensions[side] + dimensionValue
|
|
180
|
+
: dimensionValue;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
// calculate cubic weight
|
|
185
|
+
// https://suporte.boxloja.pro/article/82-correios-calculo-frete
|
|
186
|
+
// (C x L x A) / 6.000
|
|
187
|
+
Object.keys(sumDimensions).forEach((side) => {
|
|
188
|
+
if (sumDimensions[side]) {
|
|
189
|
+
cubicWeight = cubicWeight > 0
|
|
190
|
+
? cubicWeight * sumDimensions[side]
|
|
191
|
+
: sumDimensions[side];
|
|
192
|
+
pkg.dimensions[side].value += sumDimensions[side] * quantity;
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
if (cubicWeight > 0) {
|
|
196
|
+
cubicWeight /= 6; // representation in g
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if (!configApp.free_no_weight_shipping || weightValue > 0) {
|
|
200
|
+
psObj += quantity * (cubicWeight < 5 || weightValue > cubicWeight
|
|
201
|
+
? weightValue : cubicWeight);
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
let correios;
|
|
206
|
+
let correiosResult;
|
|
207
|
+
let docId;
|
|
208
|
+
let isFromDb = false;
|
|
209
|
+
|
|
210
|
+
try {
|
|
211
|
+
correios = await newCorreios();
|
|
212
|
+
if (!correios.$contract || !correios.$contract.nuContrato) {
|
|
213
|
+
throw new Error('Correios contract not found');
|
|
214
|
+
}
|
|
215
|
+
} catch (err) {
|
|
216
|
+
err.app = '[calculate Correios]';
|
|
217
|
+
logger.error(err);
|
|
218
|
+
const message = err.message || '[calculate Correios] Contract not found';
|
|
219
|
+
return {
|
|
220
|
+
error: 'CALCULATE_ERR',
|
|
221
|
+
message,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const correiosParams = {
|
|
226
|
+
cepOrigem,
|
|
227
|
+
cepDestino: parseZipCode(cepDestino),
|
|
228
|
+
psObjeto: findBaseWeight(psObj),
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
try {
|
|
232
|
+
const docParams = {
|
|
233
|
+
...correiosParams,
|
|
234
|
+
nuContrato: correios.$contract.nuContrato,
|
|
235
|
+
serviceCodes,
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
docId = getDocId(docParams);
|
|
239
|
+
const docRef = getFirestore().doc(docId);
|
|
240
|
+
const docSnapshot = await docRef.get();
|
|
241
|
+
if (docSnapshot.exists) {
|
|
242
|
+
const docData = docSnapshot.data();
|
|
243
|
+
const expiresIn = 1000 * 60 * 60 * 24 * 30
|
|
244
|
+
* (metafields?.correiosResultsExpirationMonths || 3);
|
|
245
|
+
|
|
246
|
+
const now = Timestamp.now().toMillis();
|
|
247
|
+
if ((docData.t.toMillis() + expiresIn) > now) {
|
|
248
|
+
correiosResult = docToData(docData);
|
|
249
|
+
isFromDb = true;
|
|
250
|
+
} else {
|
|
251
|
+
docRef.delete();
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
} catch (err) {
|
|
255
|
+
logger.error(new Error(`[calculate Correios] Cannot get doc ID ${docId}`));
|
|
256
|
+
logger.error(err);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// fallback Calculate
|
|
260
|
+
if (!correiosResult) {
|
|
261
|
+
try {
|
|
262
|
+
const { data } = await calculateV2({
|
|
263
|
+
correiosParams,
|
|
264
|
+
serviceCodes,
|
|
265
|
+
correios,
|
|
266
|
+
});
|
|
267
|
+
correiosResult = data;
|
|
268
|
+
|
|
269
|
+
// save in database
|
|
270
|
+
if (docId) {
|
|
271
|
+
getFirestore()
|
|
272
|
+
.doc(docId)
|
|
273
|
+
.set({
|
|
274
|
+
...dataToDoc(data),
|
|
275
|
+
t: Timestamp.fromDate(new Date()),
|
|
276
|
+
})
|
|
277
|
+
.catch(logger.error);
|
|
278
|
+
}
|
|
279
|
+
} catch (err) {
|
|
280
|
+
const message = err?.response?.data?.[0]?.txErro || err.message;
|
|
281
|
+
return {
|
|
282
|
+
error: 'CALCULATE_FAILED',
|
|
283
|
+
message,
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
correiosResult.forEach(({
|
|
289
|
+
coProduto,
|
|
290
|
+
pcProduto,
|
|
291
|
+
prazoEntrega,
|
|
292
|
+
txErro,
|
|
293
|
+
}) => {
|
|
294
|
+
if (txErro) {
|
|
295
|
+
logger.warn(`[calculate Correios] alert/error ${coProduto}`, {
|
|
296
|
+
pcProduto,
|
|
297
|
+
prazoEntrega,
|
|
298
|
+
txErro,
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
if (!pcProduto || !prazoEntrega) {
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
// find respective configured service label
|
|
305
|
+
let serviceName;
|
|
306
|
+
switch (coProduto) {
|
|
307
|
+
case '04014':
|
|
308
|
+
case '03220':
|
|
309
|
+
case '03204':
|
|
310
|
+
serviceName = 'SEDEX';
|
|
311
|
+
break;
|
|
312
|
+
case '04510':
|
|
313
|
+
case '03298':
|
|
314
|
+
serviceName = 'PAC';
|
|
315
|
+
break;
|
|
316
|
+
default:
|
|
317
|
+
break;
|
|
318
|
+
}
|
|
319
|
+
let label = serviceName || `Correios ${coProduto}`;
|
|
320
|
+
if (Array.isArray(configApp.services)) {
|
|
321
|
+
for (let i = 0; i < configApp.services.length; i++) {
|
|
322
|
+
const service = configApp.services[i];
|
|
323
|
+
if (service && service.service_code === coProduto && service.label) {
|
|
324
|
+
label = service.label;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// parse to E-Com Plus shipping line object
|
|
330
|
+
const parseMoney = (str) => (Number(str.replace(',', '.') || 0));
|
|
331
|
+
let pcFinal = parseMoney(`${pcProduto}`);
|
|
332
|
+
let valorAvisoRecebimento;
|
|
333
|
+
let valorMaoPropria;
|
|
334
|
+
let taxDeclaredValue;
|
|
335
|
+
|
|
336
|
+
// https://api.correios.com.br/preco/v1/servicos-adicionais/03220
|
|
337
|
+
// https://www.correios.com.br/enviar/servicos-adicionais
|
|
338
|
+
if (params.own_hand) {
|
|
339
|
+
valorMaoPropria = configApp.own_hand_price || metafields.correiosOwnHandPrice || 8.75;
|
|
340
|
+
pcFinal += valorMaoPropria;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
if (params.receipt) {
|
|
344
|
+
valorAvisoRecebimento = configApp.receipt_price || metafields.correiosReceiptPrice || 7.4;
|
|
345
|
+
pcFinal += valorAvisoRecebimento;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
if (vlDeclarado) {
|
|
349
|
+
// pre check for maximum allowed declared value
|
|
350
|
+
if (vlDeclarado > 10000) {
|
|
351
|
+
vlDeclarado = 10000;
|
|
352
|
+
}
|
|
353
|
+
taxDeclaredValue = parseInt(vlDeclarado * 0.02 * 100, 10) / 100;
|
|
354
|
+
pcFinal += taxDeclaredValue || 0;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
const shippingLine = {
|
|
358
|
+
from: {
|
|
359
|
+
...params.from,
|
|
360
|
+
zip: cepOrigem,
|
|
361
|
+
},
|
|
362
|
+
to: params.to,
|
|
363
|
+
package: pkg,
|
|
364
|
+
price: parseMoney(pcProduto) || pcFinal,
|
|
365
|
+
declared_value: vlDeclarado,
|
|
366
|
+
declared_value_price: taxDeclaredValue > 0 ? taxDeclaredValue : 0,
|
|
367
|
+
own_hand: Boolean(params.own_hand),
|
|
368
|
+
own_hand_price: valorMaoPropria,
|
|
369
|
+
receipt: Boolean(params.receipt),
|
|
370
|
+
receipt_price: valorAvisoRecebimento,
|
|
371
|
+
discount: 0,
|
|
372
|
+
total_price: pcFinal,
|
|
373
|
+
delivery_time: {
|
|
374
|
+
days: Number(prazoEntrega),
|
|
375
|
+
working_days: true,
|
|
376
|
+
},
|
|
377
|
+
posting_deadline: {
|
|
378
|
+
days: 3,
|
|
379
|
+
...configApp.posting_deadline,
|
|
380
|
+
},
|
|
381
|
+
flags: [`correios-${isFromDb ? 'off' : 'api'}`],
|
|
382
|
+
};
|
|
383
|
+
|
|
384
|
+
// search for discount by shipping rule
|
|
385
|
+
if (Array.isArray(configApp.shipping_rules)) {
|
|
386
|
+
for (let i = 0; i < configApp.shipping_rules.length; i++) {
|
|
387
|
+
const rule = configApp.shipping_rules[i];
|
|
388
|
+
if (
|
|
389
|
+
rule
|
|
390
|
+
&& (!rule.service_code || rule.service_code === coProduto)
|
|
391
|
+
&& checkZipCode(rule)
|
|
392
|
+
&& !(rule.min_amount > params.subtotal)
|
|
393
|
+
) {
|
|
394
|
+
// valid shipping rule
|
|
395
|
+
if (rule.free_shipping) {
|
|
396
|
+
shippingLine.discount += shippingLine.total_price;
|
|
397
|
+
shippingLine.total_price = 0;
|
|
398
|
+
break;
|
|
399
|
+
} else if (rule.discount) {
|
|
400
|
+
let discountValue = rule.discount.value;
|
|
401
|
+
if (rule.discount.percentage) {
|
|
402
|
+
discountValue *= (shippingLine.total_price / 100);
|
|
403
|
+
}
|
|
404
|
+
if (discountValue) {
|
|
405
|
+
shippingLine.discount += discountValue;
|
|
406
|
+
shippingLine.total_price -= discountValue;
|
|
407
|
+
if (shippingLine.total_price < 0) {
|
|
408
|
+
shippingLine.total_price = 0;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
break;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// push shipping service object to response
|
|
418
|
+
response.shipping_services.push({
|
|
419
|
+
label,
|
|
420
|
+
carrier: 'Correios',
|
|
421
|
+
// https://informederendimentos.com/consulta/cnpj-correios/
|
|
422
|
+
carrier_doc_number: '34028316000103',
|
|
423
|
+
service_code: coProduto,
|
|
424
|
+
service_name: serviceName || label,
|
|
425
|
+
shipping_line: shippingLine,
|
|
426
|
+
});
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
return response;
|
|
430
|
+
};
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import api from '@cloudcommerce/api';
|
|
2
|
+
import config from '@cloudcommerce/firebase/lib/config';
|
|
3
|
+
import { PubSub } from '@google-cloud/pubsub';
|
|
4
|
+
import { getFirestore, Timestamp } from 'firebase-admin/firestore';
|
|
5
|
+
import logger from 'firebase-functions/logger';
|
|
6
|
+
import calculateV2 from './correios-v2.mjs';
|
|
7
|
+
import { newCorreios } from './utils/correios-axios.mjs';
|
|
8
|
+
import {
|
|
9
|
+
weights,
|
|
10
|
+
zipRangeStep,
|
|
11
|
+
getDocId,
|
|
12
|
+
setCredentials,
|
|
13
|
+
dataToDoc,
|
|
14
|
+
} from './utils/constants-parsers.mjs';
|
|
15
|
+
|
|
16
|
+
const VERSION = 1;
|
|
17
|
+
|
|
18
|
+
const firstZipCode = 1000001;
|
|
19
|
+
const maxZipCode = 99999999;
|
|
20
|
+
const lastZipCode = maxZipCode - zipRangeStep + 2;
|
|
21
|
+
|
|
22
|
+
const getAppData = async () => {
|
|
23
|
+
const [application] = (await api.get(
|
|
24
|
+
`applications?app_id=${config.get().apps.correios.appId}&fields=hidden_data,data`,
|
|
25
|
+
)).data.result;
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
...application.data,
|
|
29
|
+
...application.hidden_data,
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const fillDb = async (state) => {
|
|
34
|
+
if (state?.nextZipCode && state.V !== VERSION) {
|
|
35
|
+
logger.warn(`Skip old dup call for (${state.nextZipCode})`);
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const continueDbFill = async (retryZipCode) => {
|
|
40
|
+
let json;
|
|
41
|
+
let isRetry = false;
|
|
42
|
+
if (retryZipCode && (!state?.retries || state.retries < 3)) {
|
|
43
|
+
json = { ...state };
|
|
44
|
+
json.nextZipCode = retryZipCode;
|
|
45
|
+
json.retries = state?.retries ? state.retries + 1 : 1;
|
|
46
|
+
isRetry = true;
|
|
47
|
+
}
|
|
48
|
+
if (!isRetry) {
|
|
49
|
+
if (state?.nextZipCode && state.nextZipCode < lastZipCode) {
|
|
50
|
+
json = { ...state };
|
|
51
|
+
} else {
|
|
52
|
+
json = {};
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
json.V = VERSION;
|
|
57
|
+
await new PubSub()
|
|
58
|
+
.topic('continueDbFill')
|
|
59
|
+
.publishMessage({ json });
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
let configApp;
|
|
63
|
+
|
|
64
|
+
if (
|
|
65
|
+
!process.env.CORREIOS_POSTCARD
|
|
66
|
+
|| !process.env.CORREIOS_USER
|
|
67
|
+
|| !process.env.CORREIOS_ACCESS_CODE
|
|
68
|
+
) {
|
|
69
|
+
logger.info('> Set credentials');
|
|
70
|
+
try {
|
|
71
|
+
configApp = await getAppData();
|
|
72
|
+
if (configApp) {
|
|
73
|
+
setCredentials(configApp);
|
|
74
|
+
}
|
|
75
|
+
} catch {
|
|
76
|
+
logger.warn('Skipped (404)');
|
|
77
|
+
return continueDbFill();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (!state?.cepOrigem) {
|
|
82
|
+
logger.info('Starting');
|
|
83
|
+
if (!state) {
|
|
84
|
+
state = {};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
state.serviceCodes = configApp?.services
|
|
88
|
+
&& configApp?.services.length
|
|
89
|
+
&& configApp?.services.map((service) => service.service_code);
|
|
90
|
+
|
|
91
|
+
state.cepOrigem = configApp?.zip?.replace(/\D/g, '');
|
|
92
|
+
|
|
93
|
+
if (!state.cepOrigem || !state.serviceCodes) {
|
|
94
|
+
logger.warn('Skipped (400)');
|
|
95
|
+
return continueDbFill();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
let zipCode;
|
|
100
|
+
const calculateNextZip = async () => {
|
|
101
|
+
const { cepOrigem, serviceCodes } = state;
|
|
102
|
+
|
|
103
|
+
if (zipCode === lastZipCode) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
zipCode = state.nextZipCode || firstZipCode;
|
|
107
|
+
state.nextZipCode = Math.min(zipCode + zipRangeStep, lastZipCode);
|
|
108
|
+
|
|
109
|
+
const cepDestino = zipCode.toString().padStart(8, '0');
|
|
110
|
+
const _calculateParams = {
|
|
111
|
+
cepOrigem,
|
|
112
|
+
cepDestino,
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
const correios = await newCorreios();
|
|
116
|
+
|
|
117
|
+
if (!correios?.$contract?.nuContrato) {
|
|
118
|
+
logger.warn('Contract not found');
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (Number(cepDestino) > 2000000) {
|
|
123
|
+
const docSnapshot = await getFirestore()
|
|
124
|
+
.doc(getDocId({
|
|
125
|
+
..._calculateParams,
|
|
126
|
+
psObjeto: 10000,
|
|
127
|
+
nuContrato: correios?.$contract?.nuContrato,
|
|
128
|
+
serviceCodes,
|
|
129
|
+
})).get();
|
|
130
|
+
if (docSnapshot.exists) {
|
|
131
|
+
const { t } = docSnapshot.data();
|
|
132
|
+
if (t && t.toMillis() > Date.now() - 1000 * 60 * 60 * 24 * 3) {
|
|
133
|
+
logger.warn(`> Skip probably dup call for (${cepDestino})`);
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
logger.info(`> ZipCode: ${cepDestino}}`);
|
|
139
|
+
|
|
140
|
+
const calculateMany = async (calculateWeights, listServiceCode) => {
|
|
141
|
+
return calculateWeights.map((psObjeto) => {
|
|
142
|
+
const promises = [];
|
|
143
|
+
|
|
144
|
+
const calculateParams = { ..._calculateParams, psObjeto };
|
|
145
|
+
promises.push(
|
|
146
|
+
calculateV2({
|
|
147
|
+
calculateParams,
|
|
148
|
+
correios,
|
|
149
|
+
serviceCodes: listServiceCode,
|
|
150
|
+
})
|
|
151
|
+
.then(async ({ data }) => {
|
|
152
|
+
const docId = getDocId({
|
|
153
|
+
...calculateParams,
|
|
154
|
+
nuContrato: correios?.$contract?.nuContrato,
|
|
155
|
+
serviceCodes: listServiceCode,
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
await getFirestore().doc(docId)
|
|
159
|
+
.set({
|
|
160
|
+
...dataToDoc(data),
|
|
161
|
+
t: Timestamp.fromDate(new Date()),
|
|
162
|
+
})
|
|
163
|
+
.catch(logger.error);
|
|
164
|
+
}),
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
return Promise.all(promises);
|
|
168
|
+
});
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
await Promise.all(calculateMany(weights.slice(0, 8), serviceCodes));
|
|
172
|
+
await Promise.all(calculateMany(weights.slice(8, 16), serviceCodes));
|
|
173
|
+
await Promise.allSettled(calculateMany(weights.slice(16), serviceCodes));
|
|
174
|
+
return true;
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
try {
|
|
178
|
+
let shouldNext = await calculateNextZip();
|
|
179
|
+
if (shouldNext !== false) shouldNext = await calculateNextZip();
|
|
180
|
+
if (shouldNext !== false) shouldNext = await calculateNextZip();
|
|
181
|
+
if (state?.retries) state.retries = 0;
|
|
182
|
+
return shouldNext !== false ? continueDbFill() : true;
|
|
183
|
+
} catch {
|
|
184
|
+
logger.info(`> May retry ${zipCode}`);
|
|
185
|
+
return continueDbFill(zipCode);
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
export default fillDb;
|