@cloudcommerce/app-tiny-erp 0.0.109 → 0.0.111
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 +25 -5
- package/lib/event-to-tiny.js +94 -94
- package/lib/index.js +1 -1
- package/lib/integration/after-tiny-queue.js +71 -74
- package/lib/integration/export-order-to-tiny.js +70 -73
- package/lib/integration/export-product-to-tiny.js +49 -53
- package/lib/integration/helpers/format-tiny-date.js +3 -3
- package/lib/integration/import-order-from-tiny.js +76 -75
- package/lib/integration/import-product-from-tiny.js +137 -140
- package/lib/integration/parsers/order-from-tiny.js +40 -39
- package/lib/integration/parsers/order-to-tiny.js +173 -178
- package/lib/integration/parsers/product-from-tiny.js +173 -171
- package/lib/integration/parsers/product-to-tiny.js +123 -127
- package/lib/integration/parsers/status-from-tiny.js +32 -32
- package/lib/integration/parsers/status-to-tiny.js +37 -37
- package/lib/integration/post-tiny-erp.js +42 -43
- package/lib/tiny-erp.js +8 -6
- package/lib/tiny-webhook.js +76 -73
- package/package.json +4 -4
|
@@ -1,34 +1,34 @@
|
|
|
1
1
|
export default (situacao) => {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
2
|
+
let financialStatus;
|
|
3
|
+
let fulfillmentStatus;
|
|
4
|
+
switch (situacao) {
|
|
5
|
+
case 'aprovado':
|
|
6
|
+
financialStatus = 'paid';
|
|
7
|
+
break;
|
|
8
|
+
case 'preparando_envio':
|
|
9
|
+
case 'preparando envio':
|
|
10
|
+
fulfillmentStatus = 'in_separation';
|
|
11
|
+
break;
|
|
12
|
+
case 'faturado':
|
|
13
|
+
case 'faturado (atendido)':
|
|
14
|
+
case 'atendido':
|
|
15
|
+
fulfillmentStatus = 'invoice_issued';
|
|
16
|
+
break;
|
|
17
|
+
case 'pronto_envio':
|
|
18
|
+
case 'pronto para envio':
|
|
19
|
+
fulfillmentStatus = 'ready_for_shipping';
|
|
20
|
+
break;
|
|
21
|
+
case 'enviado':
|
|
22
|
+
fulfillmentStatus = 'shipped';
|
|
23
|
+
break;
|
|
24
|
+
case 'entregue':
|
|
25
|
+
fulfillmentStatus = 'delivered';
|
|
26
|
+
break;
|
|
27
|
+
case 'cancelado':
|
|
28
|
+
financialStatus = 'voided';
|
|
29
|
+
break;
|
|
30
|
+
default:
|
|
31
|
+
}
|
|
32
|
+
return { financialStatus, fulfillmentStatus };
|
|
33
33
|
};
|
|
34
|
-
|
|
34
|
+
// # sourceMappingURL=status-from-tiny.js.map
|
|
@@ -1,39 +1,39 @@
|
|
|
1
1
|
export default (order) => {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
2
|
+
const financialStatus = order.financial_status && order.financial_status.current;
|
|
3
|
+
switch (financialStatus) {
|
|
4
|
+
case 'pending':
|
|
5
|
+
case 'under_analysis':
|
|
6
|
+
case 'unknown':
|
|
7
|
+
case 'authorized':
|
|
8
|
+
case 'partially_paid':
|
|
9
|
+
return 'aberto';
|
|
10
|
+
case 'voided':
|
|
11
|
+
case 'refunded':
|
|
12
|
+
case 'in_dispute':
|
|
13
|
+
case 'unauthorized':
|
|
14
|
+
return 'cancelado';
|
|
15
|
+
default:
|
|
16
|
+
}
|
|
17
|
+
switch (order.fulfillment_status && order.fulfillment_status.current) {
|
|
18
|
+
case 'in_production':
|
|
19
|
+
case 'in_separation':
|
|
20
|
+
return 'preparando_envio';
|
|
21
|
+
case 'invoice_issued':
|
|
22
|
+
return 'faturado';
|
|
23
|
+
case 'ready_for_shipping':
|
|
24
|
+
return 'pronto_envio';
|
|
25
|
+
case 'shipped':
|
|
26
|
+
case 'partially_shipped':
|
|
27
|
+
return 'enviado';
|
|
28
|
+
case 'delivered':
|
|
29
|
+
return 'entregue';
|
|
30
|
+
case 'returned':
|
|
31
|
+
return 'cancelado';
|
|
32
|
+
default:
|
|
33
|
+
}
|
|
34
|
+
if (financialStatus === 'paid') {
|
|
35
|
+
return 'aprovado';
|
|
36
|
+
}
|
|
37
|
+
return 'aberto';
|
|
38
38
|
};
|
|
39
|
-
|
|
39
|
+
// # sourceMappingURL=status-to-tiny.js.map
|
|
@@ -1,48 +1,47 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
|
+
|
|
2
3
|
export default (url, body, token = process.env.TINY_ERP_TOKEN, options = {}) => {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
return axios.post(url, data, {
|
|
22
|
-
baseURL: 'https://api.tiny.com.br/api2/',
|
|
23
|
-
timeout: 30000,
|
|
24
|
-
...options,
|
|
25
|
-
})
|
|
26
|
-
.then((response) => {
|
|
27
|
-
const { retorno } = response.data;
|
|
28
|
-
if (retorno.status === 'Erro') {
|
|
29
|
-
const err = new Error('Tiny error response');
|
|
30
|
-
const tinyErrorCode = parseInt(retorno.codigo_erro, 10);
|
|
31
|
-
if (tinyErrorCode <= 2) {
|
|
32
|
-
response.status = 401;
|
|
33
|
-
}
|
|
34
|
-
else if (tinyErrorCode === 6) {
|
|
35
|
-
response.status = 503;
|
|
36
|
-
}
|
|
37
|
-
else if (tinyErrorCode === 20) {
|
|
38
|
-
response.status = 404;
|
|
39
|
-
}
|
|
40
|
-
err.response = response;
|
|
41
|
-
err.config = response.config;
|
|
42
|
-
err.request = response.request;
|
|
43
|
-
throw err;
|
|
4
|
+
// https://www.tiny.com.br/ajuda/api/api2
|
|
5
|
+
let data = `token=${token}&formato=JSON`;
|
|
6
|
+
if (body) {
|
|
7
|
+
Object.keys(body).forEach((field) => {
|
|
8
|
+
if (body[field]) {
|
|
9
|
+
switch (typeof body[field]) {
|
|
10
|
+
case 'object':
|
|
11
|
+
data += `&${field}=${JSON.stringify(body[field])}`;
|
|
12
|
+
break;
|
|
13
|
+
case 'string':
|
|
14
|
+
case 'number':
|
|
15
|
+
data += `&${field}=${body[field]}`;
|
|
16
|
+
break;
|
|
17
|
+
default:
|
|
44
18
|
}
|
|
45
|
-
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
return axios.post(url, data, {
|
|
23
|
+
baseURL: 'https://api.tiny.com.br/api2/',
|
|
24
|
+
timeout: 30000,
|
|
25
|
+
...options,
|
|
26
|
+
})
|
|
27
|
+
.then((response) => {
|
|
28
|
+
const { retorno } = response.data;
|
|
29
|
+
if (retorno.status === 'Erro') {
|
|
30
|
+
const err = new Error('Tiny error response');
|
|
31
|
+
const tinyErrorCode = parseInt(retorno.codigo_erro, 10);
|
|
32
|
+
if (tinyErrorCode <= 2) {
|
|
33
|
+
response.status = 401;
|
|
34
|
+
} else if (tinyErrorCode === 6) {
|
|
35
|
+
response.status = 503;
|
|
36
|
+
} else if (tinyErrorCode === 20) {
|
|
37
|
+
response.status = 404;
|
|
38
|
+
}
|
|
39
|
+
err.response = response;
|
|
40
|
+
err.config = response.config;
|
|
41
|
+
err.request = response.request;
|
|
42
|
+
throw err;
|
|
43
|
+
}
|
|
44
|
+
return retorno;
|
|
46
45
|
});
|
|
47
46
|
};
|
|
48
|
-
|
|
47
|
+
// # sourceMappingURL=post-tiny-erp.js.map
|
package/lib/tiny-erp.js
CHANGED
|
@@ -3,14 +3,16 @@ import '@cloudcommerce/firebase/lib/init';
|
|
|
3
3
|
// eslint-disable-next-line import/no-unresolved
|
|
4
4
|
import { onRequest } from 'firebase-functions/v2/https';
|
|
5
5
|
import config from '@cloudcommerce/firebase/lib/config';
|
|
6
|
-
import { createAppEventsFunction
|
|
6
|
+
import { createAppEventsFunction } from '@cloudcommerce/firebase/lib/helpers/pubsub';
|
|
7
7
|
import handleApiEvent from './event-to-tiny.js';
|
|
8
8
|
import handleTinyWebhook from './tiny-webhook.js';
|
|
9
|
+
|
|
9
10
|
const { httpsFunctionOptions } = config.get();
|
|
11
|
+
|
|
10
12
|
export const tinyerp = {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
onStoreEvent: createAppEventsFunction('tinyErp', handleApiEvent),
|
|
14
|
+
webhook: onRequest(httpsFunctionOptions, (req, res) => {
|
|
15
|
+
handleTinyWebhook(req, res);
|
|
16
|
+
}),
|
|
15
17
|
};
|
|
16
|
-
|
|
18
|
+
// # sourceMappingURL=tiny-erp.js.map
|
package/lib/tiny-webhook.js
CHANGED
|
@@ -3,87 +3,90 @@ import api from '@cloudcommerce/api';
|
|
|
3
3
|
import config from '@cloudcommerce/firebase/lib/config';
|
|
4
4
|
import importProduct from './integration/import-product-from-tiny.js';
|
|
5
5
|
import importOrder from './integration/import-order-from-tiny.js';
|
|
6
|
+
|
|
6
7
|
let appData = {};
|
|
7
8
|
let application;
|
|
9
|
+
|
|
8
10
|
export default async (req, res) => {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
const tinyToken = req.query.token;
|
|
12
|
+
if (typeof tinyToken === 'string' && tinyToken && req.body) {
|
|
13
|
+
const { dados, tipo } = req.body;
|
|
14
|
+
if (dados) {
|
|
15
|
+
/*
|
|
14
16
|
TODO: Check Tiny server IPs
|
|
15
17
|
const clientIp = req.get('x-forwarded-for') || req.connection.remoteAddress
|
|
16
18
|
*/
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
else if ((tipo === 'produto' || tipo === 'estoque')
|
|
19
|
+
const { TINY_ERP_TOKEN } = process.env;
|
|
20
|
+
if (!TINY_ERP_TOKEN || TINY_ERP_TOKEN !== tinyToken) {
|
|
21
|
+
const { apps: { tinyErp: { appId } } } = config.get();
|
|
22
|
+
const applicationId = req.query._id;
|
|
23
|
+
const appEndpoint = applicationId && typeof applicationId === 'string'
|
|
24
|
+
? `applications/${applicationId}`
|
|
25
|
+
: `applications/app_id:${appId}`;
|
|
26
|
+
application = (await api.get(appEndpoint)).data;
|
|
27
|
+
appData = {
|
|
28
|
+
...application.data,
|
|
29
|
+
...application.hidden_data,
|
|
30
|
+
};
|
|
31
|
+
if (appData.tiny_api_token !== tinyToken) {
|
|
32
|
+
return res.sendStatus(401);
|
|
33
|
+
}
|
|
34
|
+
process.env.TINY_ERP_TOKEN = tinyToken;
|
|
35
|
+
}
|
|
36
|
+
if (dados.idVendaTiny) {
|
|
37
|
+
const orderNumber = `id:${dados.idVendaTiny}`;
|
|
38
|
+
const queueEntry = {
|
|
39
|
+
nextId: orderNumber,
|
|
40
|
+
isNotQueued: true,
|
|
41
|
+
};
|
|
42
|
+
await importOrder({}, queueEntry);
|
|
43
|
+
} else if ((tipo === 'produto' || tipo === 'estoque')
|
|
43
44
|
&& (dados.id || dados.idProduto)
|
|
44
45
|
&& (dados.codigo || dados.sku)) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
83
|
-
return res.sendStatus(200);
|
|
46
|
+
const nextId = String(dados.skuMapeamento || dados.sku || dados.codigo);
|
|
47
|
+
const tinyStockUpdate = {
|
|
48
|
+
ref: `${nextId}`,
|
|
49
|
+
tipo,
|
|
50
|
+
produto: {
|
|
51
|
+
id: dados.idProduto,
|
|
52
|
+
codigo: dados.sku,
|
|
53
|
+
...dados,
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
logger.info(`> Tiny webhook: ${nextId} => ${tinyStockUpdate.produto.saldo}`);
|
|
57
|
+
const queueEntry = {
|
|
58
|
+
nextId,
|
|
59
|
+
tinyStockUpdate,
|
|
60
|
+
isNotQueued: true,
|
|
61
|
+
app: application,
|
|
62
|
+
};
|
|
63
|
+
await importProduct({}, queueEntry, appData, false, true);
|
|
64
|
+
}
|
|
65
|
+
if (tipo === 'produto') {
|
|
66
|
+
const mapeamentos = [];
|
|
67
|
+
const parseTinyItem = (tinyItem) => {
|
|
68
|
+
if (tinyItem) {
|
|
69
|
+
const {
|
|
70
|
+
idMapeamento, id, codigo, sku,
|
|
71
|
+
} = tinyItem;
|
|
72
|
+
mapeamentos.push({
|
|
73
|
+
idMapeamento: idMapeamento || id,
|
|
74
|
+
skuMapeamento: codigo || sku,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
parseTinyItem(dados);
|
|
79
|
+
if (Array.isArray(dados.variacoes)) {
|
|
80
|
+
dados.variacoes.forEach((variacao) => {
|
|
81
|
+
parseTinyItem(variacao.id ? variacao : variacao.variacao);
|
|
82
|
+
});
|
|
84
83
|
}
|
|
85
|
-
|
|
84
|
+
return res.status(200).send(mapeamentos);
|
|
85
|
+
}
|
|
86
|
+
return res.sendStatus(200);
|
|
86
87
|
}
|
|
87
|
-
|
|
88
|
+
logger.warn('< Invalid Tiny Webhook body', req.body);
|
|
89
|
+
}
|
|
90
|
+
return res.sendStatus(403);
|
|
88
91
|
};
|
|
89
|
-
|
|
92
|
+
// # sourceMappingURL=tiny-webhook.js.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudcommerce/app-tiny-erp",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.111",
|
|
5
5
|
"description": "E-Com Plus Cloud Commerce app for Tiny ERP",
|
|
6
6
|
"main": "lib/tiny-erp.js",
|
|
7
7
|
"repository": {
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
},
|
|
17
17
|
"homepage": "https://github.com/ecomplus/cloud-commerce/tree/main/packages/apps/tiny-erp#readme",
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@cloudcommerce/api": "0.0.
|
|
20
|
-
"@cloudcommerce/firebase": "0.0.
|
|
19
|
+
"@cloudcommerce/api": "0.0.111",
|
|
20
|
+
"@cloudcommerce/firebase": "0.0.111",
|
|
21
21
|
"@ecomplus/utils": "^1.4.1",
|
|
22
22
|
"axios": "^0.27.2",
|
|
23
23
|
"firebase-admin": "^11.0.1",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"form-data": "^4.0.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@cloudcommerce/types": "0.0.
|
|
28
|
+
"@cloudcommerce/types": "0.0.111",
|
|
29
29
|
"@firebase/app-types": "^0.7.0"
|
|
30
30
|
},
|
|
31
31
|
"scripts": {
|