@cloudcommerce/app-tiny-erp 0.0.97 → 0.0.98

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.
@@ -1 +1,5 @@
1
- @cloudcommerce/app-tiny-erp:build: cache hit, replaying output c3d468bac5dc7cec
1
+ @cloudcommerce/app-tiny-erp:build: cache hit, replaying output 1dda44cfd224828c
2
+ @cloudcommerce/app-tiny-erp:build: 
3
+ @cloudcommerce/app-tiny-erp:build: > @cloudcommerce/app-tiny-erp@0.0.97 build /home/leo/code/ecomplus/cloud-commerce/packages/apps/tiny-erp
4
+ @cloudcommerce/app-tiny-erp:build: > sh ../../../scripts/build-lib.sh
5
+ @cloudcommerce/app-tiny-erp:build: 
@@ -4,112 +4,112 @@ import exportOrder from './integration/export-order-to-tiny.js';
4
4
  import importProduct from './integration/import-product-from-tiny.js';
5
5
  import importOrder from './integration/import-order-from-tiny.js';
6
6
  import afterQueue from './integration/after-tiny-queue.js';
7
-
8
7
  // Async integration handlers
9
8
  const integrationHandlers = {
10
- exportation: {
11
- product_ids: exportProduct,
12
- order_ids: exportOrder,
13
- },
14
- importation: {
15
- skus: importProduct,
16
- order_numbers: importOrder,
17
- },
9
+ exportation: {
10
+ product_ids: exportProduct,
11
+ order_ids: exportOrder,
12
+ },
13
+ importation: {
14
+ skus: importProduct,
15
+ order_numbers: importOrder,
16
+ },
18
17
  };
19
- const handleApiEvent = async ({
20
- evName, apiEvent, apiDoc, app,
21
- }) => {
22
- const resourceId = apiEvent.resource_id;
23
- logger.info('>> ', resourceId, ' - Action: ', apiEvent.action);
24
- const key = `${evName}_${resourceId}`;
25
- const appData = { ...app.data, ...app.hidden_data };
26
- if (Array.isArray(appData.ignore_events)
18
+ const handleApiEvent = async ({ evName, apiEvent, apiDoc, app, }) => {
19
+ const resourceId = apiEvent.resource_id;
20
+ logger.info('>> ', resourceId, ' - Action: ', apiEvent.action);
21
+ const key = `${evName}_${resourceId}`;
22
+ const appData = { ...app.data, ...app.hidden_data };
23
+ if (Array.isArray(appData.ignore_events)
27
24
  && appData.ignore_events.includes(evName)) {
28
- logger.info('>> ', key, ' - Ignored event');
29
- return null;
30
- }
31
- logger.info(`> Webhook ${resourceId} [${evName}]`);
32
- if (!process.env.TINY_ERP_TOKEN) {
33
- const tinyToken = appData.tiny_api_token;
34
- if (typeof tinyToken === 'string' && tinyToken) {
35
- process.env.TINY_ERP_TOKEN = tinyToken;
36
- } else {
37
- logger.warn('Missing Tiny API token');
25
+ logger.info('>> ', key, ' - Ignored event');
26
+ return null;
38
27
  }
39
- }
40
- if (process.env.TINY_ERP_TOKEN) {
41
- let integrationConfig;
42
- let canCreateNew = false;
43
- if (evName === 'applications-dataSet') {
44
- integrationConfig = appData;
45
- canCreateNew = true;
46
- } else if (evName === 'orders-anyStatusSet') {
47
- canCreateNew = Boolean(appData.new_orders);
48
- integrationConfig = {
49
- _exportation: {
50
- order_ids: [resourceId],
51
- },
52
- };
53
- } else {
54
- if (evName === 'products-new') {
55
- if (!appData.new_products) {
56
- return null;
28
+ logger.info(`> Webhook ${resourceId} [${evName}]`);
29
+ if (!process.env.TINY_ERP_TOKEN) {
30
+ const tinyToken = appData.tiny_api_token;
31
+ if (typeof tinyToken === 'string' && tinyToken) {
32
+ process.env.TINY_ERP_TOKEN = tinyToken;
33
+ }
34
+ else {
35
+ logger.warn('Missing Tiny API token');
57
36
  }
58
- } else if (!appData.update_price) {
59
- return null;
60
- }
61
- integrationConfig = {
62
- _exportation: {
63
- product_ids: [resourceId],
64
- },
65
- };
66
37
  }
67
- if (integrationConfig) {
68
- const actions = Object.keys(integrationHandlers);
69
- actions.forEach((action) => {
70
- for (let i = 1; i <= 3; i++) {
71
- actions.push(`${('_'.repeat(i))}${action}`);
38
+ if (process.env.TINY_ERP_TOKEN) {
39
+ let integrationConfig;
40
+ let canCreateNew = false;
41
+ if (evName === 'applications-dataSet') {
42
+ integrationConfig = appData;
43
+ canCreateNew = true;
44
+ }
45
+ else if (evName === 'orders-anyStatusSet') {
46
+ canCreateNew = Boolean(appData.new_orders);
47
+ integrationConfig = {
48
+ _exportation: {
49
+ order_ids: [resourceId],
50
+ },
51
+ };
72
52
  }
73
- });
74
- for (let i = 0; i < actions.length; i++) {
75
- const action = actions[i];
76
- const actionQueues = integrationConfig[action];
77
- if (typeof actionQueues === 'object' && actionQueues) {
78
- // eslint-disable-next-line guard-for-in, no-restricted-syntax
79
- for (const queue in actionQueues) {
80
- const ids = actionQueues[queue];
81
- if (Array.isArray(ids) && ids.length) {
82
- const isHiddenQueue = action.charAt(0) === '_';
83
- const handlerName = action.replace(/^_+/, '');
84
- const handler = integrationHandlers[handlerName][queue.toLowerCase()];
85
- const nextId = ids[0];
86
- if (typeof nextId === 'string'
53
+ else {
54
+ if (evName === 'products-new') {
55
+ if (!appData.new_products) {
56
+ return null;
57
+ }
58
+ }
59
+ else if (!appData.update_price) {
60
+ return null;
61
+ }
62
+ integrationConfig = {
63
+ _exportation: {
64
+ product_ids: [resourceId],
65
+ },
66
+ };
67
+ }
68
+ if (integrationConfig) {
69
+ const actions = Object.keys(integrationHandlers);
70
+ actions.forEach((action) => {
71
+ for (let i = 1; i <= 3; i++) {
72
+ actions.push(`${('_'.repeat(i))}${action}`);
73
+ }
74
+ });
75
+ for (let i = 0; i < actions.length; i++) {
76
+ const action = actions[i];
77
+ const actionQueues = integrationConfig[action];
78
+ if (typeof actionQueues === 'object' && actionQueues) {
79
+ // eslint-disable-next-line guard-for-in, no-restricted-syntax
80
+ for (const queue in actionQueues) {
81
+ const ids = actionQueues[queue];
82
+ if (Array.isArray(ids) && ids.length) {
83
+ const isHiddenQueue = action.charAt(0) === '_';
84
+ const handlerName = action.replace(/^_+/, '');
85
+ const handler = integrationHandlers[handlerName][queue.toLowerCase()];
86
+ const nextId = ids[0];
87
+ if (typeof nextId === 'string'
87
88
  && nextId.length
88
89
  && handler) {
89
- const debugFlag = `#${action}/${queue}/${nextId}`;
90
- logger.info(`> Starting ${debugFlag}`);
91
- const queueEntry = {
92
- action,
93
- queue,
94
- nextId,
95
- key,
96
- app,
97
- };
98
- return handler(apiDoc, queueEntry, appData, canCreateNew, isHiddenQueue).then((payload) => {
99
- return afterQueue(queueEntry, appData, app, payload);
100
- }).catch((err) => {
101
- return afterQueue(queueEntry, appData, app, err);
102
- });
103
- }
90
+ const debugFlag = `#${action}/${queue}/${nextId}`;
91
+ logger.info(`> Starting ${debugFlag}`);
92
+ const queueEntry = {
93
+ action,
94
+ queue,
95
+ nextId,
96
+ key,
97
+ app,
98
+ };
99
+ return handler(apiDoc, queueEntry, appData, canCreateNew, isHiddenQueue).then((payload) => {
100
+ return afterQueue(queueEntry, appData, app, payload);
101
+ }).catch((err) => {
102
+ return afterQueue(queueEntry, appData, app, err);
103
+ });
104
+ }
105
+ }
106
+ }
107
+ }
104
108
  }
105
- }
106
109
  }
107
- }
108
110
  }
109
- }
110
- // Nothing to do
111
- return null;
111
+ // Nothing to do
112
+ return null;
112
113
  };
113
-
114
114
  export default handleApiEvent;
115
- // # sourceMappingURL=event-to-tiny.js.map
115
+ //# sourceMappingURL=event-to-tiny.js.map
package/lib/index.js CHANGED
@@ -1,2 +1,2 @@
1
1
  export * from './tiny-erp.js';
2
- // # sourceMappingURL=index.js.map
2
+ //# sourceMappingURL=index.js.map
@@ -1,79 +1,82 @@
1
1
  import logger from 'firebase-functions/lib/logger';
2
2
  import updateAppData from '@cloudcommerce/firebase/lib/helpers/update-app-data';
3
-
4
3
  export default async (queueEntry, appData, application, payload) => {
5
- const isError = payload instanceof Error;
6
- const isImportation = queueEntry.action.endsWith('importation');
7
- const logs = appData.logs || [];
8
- const logEntry = {
9
- resource: /order/i.test(queueEntry.queue) ? 'orders' : 'products',
10
- [(isImportation ? 'tiny_id' : 'resource_id')]: queueEntry.nextId,
11
- success: !isError,
12
- imestamp: new Date().toISOString(),
13
- };
14
- let notes;
15
- if (payload) {
16
- if (!isError) {
17
- // payload = response
18
- const { data, status, config } = payload;
19
- if (data && data._id) {
20
- logEntry.resource_id = data._id;
21
- }
22
- notes = `Status ${status}`;
23
- if (config) {
24
- notes += ` [${config.url}]`;
25
- }
26
- } else {
27
- const { config, response } = payload;
28
- if (response) {
29
- const { data, status } = response;
30
- notes = `Error: Status ${status} \n${JSON.stringify(data)}`;
31
- if (!status || status === 429 || status >= 500) {
32
- return setTimeout(() => {
33
- throw payload;
34
- }, 2000);
4
+ const isError = payload instanceof Error;
5
+ const isImportation = queueEntry.action.endsWith('importation');
6
+ const logs = appData.logs || [];
7
+ const logEntry = {
8
+ resource: /order/i.test(queueEntry.queue) ? 'orders' : 'products',
9
+ [(isImportation ? 'tiny_id' : 'resource_id')]: queueEntry.nextId,
10
+ success: !isError,
11
+ imestamp: new Date().toISOString(),
12
+ };
13
+ let notes;
14
+ if (payload) {
15
+ if (!isError) {
16
+ // payload = response
17
+ const { data, status, config } = payload;
18
+ if (data && data._id) {
19
+ logEntry.resource_id = data._id;
20
+ }
21
+ notes = `Status ${status}`;
22
+ if (config) {
23
+ notes += ` [${config.url}]`;
24
+ }
35
25
  }
36
- if (config) {
37
- const { url, method, data } = config;
38
- notes += `\n\n-- Request -- \n${method} ${url} \n${JSON.stringify(data)}`;
26
+ else {
27
+ const { config, response } = payload;
28
+ if (response) {
29
+ const { data, status } = response;
30
+ notes = `Error: Status ${status} \n${JSON.stringify(data)}`;
31
+ if (!status || status === 429 || status >= 500) {
32
+ return setTimeout(() => {
33
+ throw payload;
34
+ }, 2000);
35
+ }
36
+ if (config) {
37
+ const { url, method, data } = config;
38
+ notes += `\n\n-- Request -- \n${method} ${url} \n${JSON.stringify(data)}`;
39
+ }
40
+ // @ts-ignore
41
+ }
42
+ else if (payload.isConfigError === true) {
43
+ notes = payload.message;
44
+ }
45
+ else {
46
+ notes = payload.stack;
47
+ }
39
48
  }
40
- // @ts-ignore
41
- } else if (payload.isConfigError === true) {
42
- notes = payload.message;
43
- } else {
44
- notes = payload.stack;
45
- }
46
49
  }
47
- }
48
- if (notes) {
49
- logEntry.notes = notes.substring(0, 5000);
50
- }
51
- if (isError || !isImportation) {
52
- logs.unshift(logEntry);
53
- await updateAppData(application, {
54
- logs: logs.slice(0, 200),
55
- }, {
56
- isHiddenData: true,
57
- canSendPubSub: false,
58
- });
59
- }
60
- const { action, queue, nextId } = queueEntry;
61
- let queueList = appData[action][queue];
62
- if (Array.isArray(queueList)) {
63
- const idIndex = queueList.indexOf(nextId);
64
- if (idIndex > -1) {
65
- queueList.splice(idIndex, 1);
50
+ if (notes) {
51
+ logEntry.notes = notes.substring(0, 5000);
66
52
  }
67
- } else {
68
- queueList = [];
69
- }
70
- const data = {
71
- [action]: {
72
- ...appData[action],
73
- [queue]: queueList,
74
- },
75
- };
76
- logger.info(JSON.stringify(data));
77
- return updateAppData(application, data);
53
+ if (isError || !isImportation) {
54
+ logs.unshift(logEntry);
55
+ await updateAppData(application, {
56
+ logs: logs.slice(0, 200),
57
+ }, {
58
+ isHiddenData: true,
59
+ canSendPubSub: false,
60
+ });
61
+ }
62
+ const { action, queue, nextId } = queueEntry;
63
+ let queueList = appData[action][queue];
64
+ if (Array.isArray(queueList)) {
65
+ const idIndex = queueList.indexOf(nextId);
66
+ if (idIndex > -1) {
67
+ queueList.splice(idIndex, 1);
68
+ }
69
+ }
70
+ else {
71
+ queueList = [];
72
+ }
73
+ const data = {
74
+ [action]: {
75
+ ...appData[action],
76
+ [queue]: queueList,
77
+ },
78
+ };
79
+ logger.info(JSON.stringify(data));
80
+ return updateAppData(application, data);
78
81
  };
79
- // # sourceMappingURL=after-tiny-queue.js.map
82
+ //# sourceMappingURL=after-tiny-queue.js.map
@@ -3,82 +3,85 @@ import api from '@cloudcommerce/api';
3
3
  import postTiny from './post-tiny-erp.js';
4
4
  import parseStatus from './parsers/status-to-tiny.js';
5
5
  import parseOrder from './parsers/order-to-tiny.js';
6
-
7
6
  export default async (apiDoc, queueEntry, appData, canCreateNew) => {
8
- const orderId = queueEntry.nextId;
9
- let order;
10
- if (orderId === apiDoc._id) {
11
- order = apiDoc;
12
- } else {
13
- try {
14
- order = (await api.get(`orders/${orderId}`)).data;
15
- } catch (err) {
16
- if (err.statusCode === 404) {
17
- const msg = `O pedido ${orderId} não existe (:${err.statusCode})`;
18
- const error = new Error(msg);
19
- error.isConfigError = true;
20
- return error;
21
- }
22
- throw err;
7
+ const orderId = queueEntry.nextId;
8
+ let order;
9
+ if (orderId === apiDoc._id) {
10
+ order = apiDoc;
23
11
  }
24
- }
25
- if (!order.financial_status) {
26
- logger.info(`${orderId} skipped with no financial status`);
27
- return null;
28
- }
29
- logger.info(`${orderId} searching order ${order.number}`);
30
- let tinyData;
31
- try {
32
- tinyData = await postTiny('/pedidos.pesquisa.php', {
33
- numeroEcommerce: String(order.number),
34
- });
35
- } catch (err) {
36
- const status = err.response && err.response.status;
37
- if (status === 404) {
38
- tinyData = {};
39
- } else {
40
- logger.info(`${orderId} search on tiny ends with status ${status}`);
41
- throw err;
12
+ else {
13
+ try {
14
+ order = (await api.get(`orders/${orderId}`)).data;
15
+ }
16
+ catch (err) {
17
+ if (err.statusCode === 404) {
18
+ const msg = `O pedido ${orderId} não existe (:${err.statusCode})`;
19
+ const error = new Error(msg);
20
+ error.isConfigError = true;
21
+ return error;
22
+ }
23
+ throw err;
24
+ }
42
25
  }
43
- }
44
- const { pedidos } = tinyData;
45
- const tinyStatus = parseStatus(order);
46
- let originalTinyOrder;
47
- if (Array.isArray(pedidos)) {
48
- originalTinyOrder = pedidos.find(({ pedido }) => {
49
- return order.number === Number(pedido.numero_ecommerce);
50
- });
51
- if (originalTinyOrder) {
52
- originalTinyOrder = originalTinyOrder.pedido;
26
+ if (!order.financial_status) {
27
+ logger.info(`${orderId} skipped with no financial status`);
28
+ return null;
29
+ }
30
+ logger.info(`${orderId} searching order ${order.number}`);
31
+ let tinyData;
32
+ try {
33
+ tinyData = await postTiny('/pedidos.pesquisa.php', {
34
+ numeroEcommerce: String(order.number),
35
+ });
36
+ }
37
+ catch (err) {
38
+ const status = err.response && err.response.status;
39
+ if (status === 404) {
40
+ tinyData = {};
41
+ }
42
+ else {
43
+ logger.info(`${orderId} search on tiny ends with status ${status}`);
44
+ throw err;
45
+ }
53
46
  }
54
- }
55
- if (!originalTinyOrder) {
56
- if (!canCreateNew) {
57
- return null;
47
+ const { pedidos } = tinyData;
48
+ const tinyStatus = parseStatus(order);
49
+ let originalTinyOrder;
50
+ if (Array.isArray(pedidos)) {
51
+ originalTinyOrder = pedidos.find(({ pedido }) => {
52
+ return order.number === Number(pedido.numero_ecommerce);
53
+ });
54
+ if (originalTinyOrder) {
55
+ originalTinyOrder = originalTinyOrder.pedido;
56
+ }
58
57
  }
59
- if (appData.approved_orders_only
58
+ if (!originalTinyOrder) {
59
+ if (!canCreateNew) {
60
+ return null;
61
+ }
62
+ if (appData.approved_orders_only
60
63
  && (tinyStatus === 'aberto' || tinyStatus === 'cancelado')) {
61
- logger.info(`${orderId} skipped with status "${tinyStatus}"`);
62
- return null;
64
+ logger.info(`${orderId} skipped with status "${tinyStatus}"`);
65
+ return null;
66
+ }
67
+ const tinyOrder = parseOrder(order, appData);
68
+ logger.info(`${orderId} ${JSON.stringify(tinyOrder)}`);
69
+ return postTiny('/pedido.incluir.php', {
70
+ pedido: {
71
+ pedido: tinyOrder,
72
+ },
73
+ });
63
74
  }
64
- const tinyOrder = parseOrder(order, appData);
65
- logger.info(`${orderId} ${JSON.stringify(tinyOrder)}`);
66
- return postTiny('/pedido.incluir.php', {
67
- pedido: {
68
- pedido: tinyOrder,
69
- },
70
- });
71
- }
72
- if (originalTinyOrder) {
73
- const { id, situacao } = originalTinyOrder;
74
- logger.info(`${orderId} found with tiny status ${situacao} => ${tinyStatus}`);
75
- if (tinyStatus && tinyStatus !== situacao) {
76
- return postTiny('/pedido.alterar.situacao', {
77
- id,
78
- situacao: tinyStatus,
79
- });
75
+ if (originalTinyOrder) {
76
+ const { id, situacao } = originalTinyOrder;
77
+ logger.info(`${orderId} found with tiny status ${situacao} => ${tinyStatus}`);
78
+ if (tinyStatus && tinyStatus !== situacao) {
79
+ return postTiny('/pedido.alterar.situacao', {
80
+ id,
81
+ situacao: tinyStatus,
82
+ });
83
+ }
80
84
  }
81
- }
82
- return null;
85
+ return null;
83
86
  };
84
- // # sourceMappingURL=export-order-to-tiny.js.map
87
+ //# sourceMappingURL=export-order-to-tiny.js.map
@@ -1,58 +1,62 @@
1
1
  import api from '@cloudcommerce/api';
2
2
  import postTiny from './post-tiny-erp.js';
3
3
  import parseProduct from './parsers/product-to-tiny.js';
4
-
5
4
  export default async (apiDoc, queueEntry, appData, canCreateNew) => {
6
- const productId = queueEntry.nextId;
7
- let product;
8
- if (productId === apiDoc._id) {
9
- product = apiDoc;
10
- } else {
5
+ const productId = queueEntry.nextId;
6
+ let product;
7
+ if (productId === apiDoc._id) {
8
+ product = apiDoc;
9
+ }
10
+ else {
11
+ try {
12
+ product = (await api.get(`products/${productId}`)).data;
13
+ }
14
+ catch (err) {
15
+ if (err.statusCode === 404) {
16
+ const msg = `O produto ${productId} não existe (:${err.statusCode})`;
17
+ const error = new Error(msg);
18
+ error.isConfigError = true;
19
+ return error;
20
+ }
21
+ throw err;
22
+ }
23
+ }
24
+ let tinyData;
11
25
  try {
12
- product = (await api.get(`products/${productId}`)).data;
13
- } catch (err) {
14
- if (err.statusCode === 404) {
15
- const msg = `O produto ${productId} não existe (:${err.statusCode})`;
16
- const error = new Error(msg);
17
- error.isConfigError = true;
18
- return error;
19
- }
20
- throw err;
26
+ tinyData = await postTiny('/produtos.pesquisa.php', {
27
+ pesquisa: product.sku,
28
+ });
21
29
  }
22
- }
23
- let tinyData;
24
- try {
25
- tinyData = await postTiny('/produtos.pesquisa.php', {
26
- pesquisa: product.sku,
27
- });
28
- } catch (err) {
29
- if (err.response && err.response.status === 404) {
30
- tinyData = {};
31
- } else {
32
- throw err;
30
+ catch (err) {
31
+ if (err.response && err.response.status === 404) {
32
+ tinyData = {};
33
+ }
34
+ else {
35
+ throw err;
36
+ }
33
37
  }
34
- }
35
- const { produtos } = tinyData;
36
- let originalTinyProduct;
37
- if (Array.isArray(produtos)) {
38
- originalTinyProduct = produtos.find(({ produto }) => {
39
- return product.sku === String(produto.codigo);
40
- });
41
- if (originalTinyProduct) {
42
- originalTinyProduct = originalTinyProduct.produto;
43
- } else if (!canCreateNew) {
44
- return null;
38
+ const { produtos } = tinyData;
39
+ let originalTinyProduct;
40
+ if (Array.isArray(produtos)) {
41
+ originalTinyProduct = produtos.find(({ produto }) => {
42
+ return product.sku === String(produto.codigo);
43
+ });
44
+ if (originalTinyProduct) {
45
+ originalTinyProduct = originalTinyProduct.produto;
46
+ }
47
+ else if (!canCreateNew) {
48
+ return null;
49
+ }
45
50
  }
46
- }
47
- const tinyProduct = parseProduct(product, originalTinyProduct, appData);
48
- return tinyProduct
49
- ? postTiny(originalTinyProduct ? '/produto.alterar.php' : '/produto.incluir.php', {
50
- produto: {
51
- produtos: [{
52
- produto: tinyProduct,
53
- }],
54
- },
55
- })
56
- : null;
51
+ const tinyProduct = parseProduct(product, originalTinyProduct, appData);
52
+ return tinyProduct
53
+ ? postTiny(originalTinyProduct ? '/produto.alterar.php' : '/produto.incluir.php', {
54
+ produto: {
55
+ produtos: [{
56
+ produto: tinyProduct,
57
+ }],
58
+ },
59
+ })
60
+ : null;
57
61
  };
58
- // # sourceMappingURL=export-product-to-tiny.js.map
62
+ //# sourceMappingURL=export-product-to-tiny.js.map
@@ -1,7 +1,7 @@
1
1
  export default (d) => {
2
- /* eslint-disable prefer-template */
3
- return d.getDate().toString().padStart(2, '0') + '/'
2
+ /* eslint-disable prefer-template */
3
+ return d.getDate().toString().padStart(2, '0') + '/'
4
4
  + (d.getMonth() + 1).toString().padStart(2, '0') + '/'
5
5
  + d.getFullYear();
6
6
  };
7
- // # sourceMappingURL=format-tiny-date.js.map
7
+ //# sourceMappingURL=format-tiny-date.js.map