Skip to content

Commit a534e5a

Browse files
committed
feat(tiny-erp): New cronSendOrders function to work as queue fallback
1 parent 23cf4fa commit a534e5a

File tree

3 files changed

+110
-1
lines changed

3 files changed

+110
-1
lines changed

packages/apps/tiny-erp/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,4 @@
3737
"@cloudcommerce/types": "workspace:*",
3838
"@firebase/app-types": "^0.9.3"
3939
}
40-
}
40+
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import type { Orders } from '@cloudcommerce/types';
2+
import logger from 'firebase-functions/logger';
3+
import api from '@cloudcommerce/api';
4+
import getAppData from '@cloudcommerce/firebase/lib/helpers/get-app-data';
5+
import exportOrderToTiny from './integration/export-order-to-tiny';
6+
7+
export const sendWaitingOrders = async () => {
8+
const startDate = new Date();
9+
const isEvenHour = !(startDate.getHours() % 2);
10+
11+
const appData = await getAppData('tinyErp', ['hidden_data', 'data']);
12+
if (!process.env.TINYERP_TOKEN) {
13+
const tinyToken = appData?.tiny_api_token;
14+
if (!tinyToken) {
15+
logger.warn('Missing Tiny API token');
16+
return;
17+
}
18+
process.env.TINYERP_TOKEN = tinyToken;
19+
}
20+
21+
const d = new Date();
22+
d.setDate(d.getDate() - 60);
23+
const fields = [
24+
'_id',
25+
'number',
26+
'amount',
27+
'financial_status',
28+
'fulfillment_status',
29+
'fulfillments',
30+
'shipping_lines',
31+
'buyers',
32+
'items',
33+
'transactions',
34+
'opened_at',
35+
'created_at',
36+
'notes',
37+
'staff_notes',
38+
'extra_discount',
39+
'payment_method_label',
40+
'shipping_method_label',
41+
] as const;
42+
const endpoint = 'orders'
43+
+ `?fields=${fields.join(',')}`
44+
+ '&financial_status.current=paid'
45+
+ '&fulfillment_status.current=null'
46+
+ `&updated_at>=${d.toISOString()}`
47+
+ `&sort=${isEvenHour ? 'number' : '-number'}`
48+
+ '&limit=200' as `orders?${string}`;
49+
50+
logger.info('Start sending orders to Tiny', { endpoint });
51+
52+
try {
53+
const { data } = await api.get(endpoint);
54+
const orders = data.result;
55+
logger.info(`${orders.length} orders listed`, {
56+
ids: orders.map(({ _id }) => _id),
57+
numbers: orders.map(({ number }) => number),
58+
});
59+
60+
let createdCount = 0;
61+
let skippedCount = 0;
62+
for (let i = 0; i < orders.length; i++) {
63+
const order = orders[i] as Orders;
64+
if (!order.number) continue;
65+
try {
66+
const queueEntry = { nextId: order._id };
67+
// eslint-disable-next-line no-await-in-loop
68+
const result = await exportOrderToTiny(order, queueEntry, appData, true);
69+
if (result && typeof result === 'object' && 'registros' in result) {
70+
createdCount += 1;
71+
} else {
72+
skippedCount += 1;
73+
}
74+
} catch (error: any) {
75+
const err = new Error(`Failed sending order ${order.number} to Tiny`);
76+
logger.error(err, {
77+
orderId: order._id,
78+
orderNumber: order.number,
79+
request: error.config,
80+
response: error.response?.data,
81+
});
82+
}
83+
// Rate limit: 150ms between requests
84+
// eslint-disable-next-line no-await-in-loop
85+
await new Promise((resolve) => { setTimeout(resolve, 150); });
86+
}
87+
88+
logger.info(`Finished sending orders to Tiny: ${createdCount} created, ${skippedCount} skipped`);
89+
} catch (_err: any) {
90+
if (_err.response) {
91+
const err = new Error('Failed listing orders for Tiny');
92+
logger.error(err, {
93+
request: _err.config,
94+
response: _err.response.data,
95+
});
96+
} else {
97+
logger.error(_err);
98+
}
99+
}
100+
};
101+
102+
export default sendWaitingOrders;

packages/apps/tiny-erp/src/tiny-erp.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import config, { createExecContext } from '@cloudcommerce/firebase/lib/config';
66
import { createAppEventsFunction } from '@cloudcommerce/firebase/lib/helpers/pubsub';
77
import handleApiEvent from './event-to-tiny';
88
import handleTinyWebhook from './tiny-webhook';
9+
import sendWaitingOrders from './tiny-erp-send-orders';
910

1011
const { httpsFunctionOptions } = config.get();
1112
const { region } = httpsFunctionOptions;
@@ -27,4 +28,10 @@ export const tinyerp = {
2728
.https.onRequest((req, res) => {
2829
return createExecContext(() => handleTinyWebhook(req, res));
2930
}),
31+
32+
cronSendOrders: functions
33+
.region(region)
34+
.runWith({ timeoutSeconds: 540, memory: '512MB' })
35+
.pubsub.schedule(process.env.CRONTAB_TINYERP_SEND_ORDERS || '17 */3 * * *')
36+
.onRun(() => sendWaitingOrders()),
3037
};

0 commit comments

Comments
 (0)