generated from ecomplus/application-starter
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: refactored check orders tracking routine
removing ecom webhook in favor of cron send tags with reduced interval
- Loading branch information
Showing
10 changed files
with
182 additions
and
514 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
const { firestore } = require('firebase-admin') | ||
const { setup } = require('@ecomplus/application-sdk') | ||
const logger = require('firebase-functions/logger') | ||
const getAppData = require('../store-api/get-app-data') | ||
const importOrderStatus = require('./import-order-status') | ||
|
||
const listStoreIds = () => { | ||
const storeIds = [] | ||
const date = new Date() | ||
date.setHours(date.getHours() - 24) | ||
return firestore() | ||
.collection('ecomplus_app_auth') | ||
.where('updated_at', '>', firestore.Timestamp.fromDate(date)) | ||
.get().then(querySnapshot => { | ||
querySnapshot.forEach(documentSnapshot => { | ||
const storeId = documentSnapshot.get('store_id') | ||
if (storeIds.indexOf(storeId) === -1) { | ||
storeIds.push(storeId) | ||
} | ||
}) | ||
return storeIds | ||
}) | ||
} | ||
|
||
const fetchUndeliveredOrders = async ({ appSdk, storeId }) => { | ||
const auth = await appSdk.getAuth(storeId) | ||
return new Promise((resolve, reject) => { | ||
getAppData({ appSdk, storeId, auth }) | ||
.then(async (appData) => { | ||
resolve() | ||
let mandaeTrackingPrefix = appData.__order_settings?.tracking_prefix | ||
if (mandaeTrackingPrefix === undefined) { | ||
mandaeTrackingPrefix = storeId === 1024 ? 'TIA' : '' | ||
} | ||
const mandaeToken = appData.mandae_token | ||
if (mandaeToken) { | ||
const d = new Date() | ||
d.setDate(d.getDate() - 30) | ||
const endpoint = '/orders.json' + | ||
'?fields=_id,number,fulfillment_status,shipping_lines' + | ||
'&shipping_lines.tracking_codes.tag=mandae' + | ||
'&financial_status.current=paid' + | ||
'&fulfillment_status.current!=delivered' + | ||
`&updated_at>=${d.toISOString()}` + | ||
'&sort=number' + | ||
'&limit=200' | ||
try { | ||
const { response } = await appSdk.apiRequest(storeId, endpoint, 'GET') | ||
const orders = response.data.result | ||
for (let i = 0; i < orders.length; i++) { | ||
const order = orders[i] | ||
await importOrderStatus( | ||
{ appSdk, storeId, auth }, | ||
{ order, mandaeToken, mandaeTrackingPrefix } | ||
) | ||
} | ||
} catch (_err) { | ||
if (_err.response) { | ||
const err = new Error(`Failed exporting order for #${storeId}`) | ||
logger.error(err, { | ||
request: _err.config, | ||
response: _err.response.data | ||
}) | ||
} else { | ||
logger.error(_err) | ||
} | ||
} | ||
} | ||
}) | ||
.catch(reject) | ||
}) | ||
} | ||
|
||
module.exports = context => setup(null, true, firestore()) | ||
.then(appSdk => { | ||
return listStoreIds().then(storeIds => { | ||
const runAllStores = fn => storeIds | ||
.sort(() => Math.random() - Math.random()) | ||
.map(storeId => fn({ appSdk, storeId })) | ||
return Promise.all(runAllStores(fetchUndeliveredOrders)) | ||
}) | ||
}) | ||
.catch(logger.error) |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
const logger = require('firebase-functions/logger') | ||
const axios = require('axios') | ||
|
||
const parseMandaeStatus = ({ id, name }) => { | ||
switch (id) { | ||
case '1': | ||
return 'delivered' | ||
case '101': | ||
case '110': | ||
case '31': | ||
case '33': | ||
case '118': | ||
case '160': | ||
case '122': | ||
case '123': | ||
case '124': | ||
case '119': | ||
case '120': | ||
case '0': | ||
case '121': | ||
return 'shipped' | ||
} | ||
if (name === 'Encomenda coletada') { | ||
return 'shipped' | ||
} | ||
return null | ||
} | ||
|
||
module.exports = async ( | ||
{ appSdk, storeId, auth }, | ||
{ order, mandaeToken, mandaeTrackingPrefix } | ||
) => { | ||
const { number } = order | ||
const shippingLine = order.shipping_lines?.find(({ app }) => app?.carrier === 'MANDAE') | ||
if (!shippingLine?.to) return | ||
const invoice = shippingLine.invoices?.[0] | ||
if (!invoice?.number || !invoice.serial_number || !invoice.access_key) { | ||
logger.warn(`Skipping #${storeId} ${number} without invoice data`) | ||
return | ||
} | ||
const trackingId = (mandaeTrackingPrefix || '') + | ||
invoice.number.replace(/^0+/, '') + | ||
invoice.serial_number.replace(/^0+/, '') | ||
logger.info(`Tracking #${storeId} ${number} with ID ${trackingId}`) | ||
const { data } = await axios.get(`https://api.mandae.com.br/v3/trackings/${trackingId}`, { | ||
headers: { Authorization: mandaeToken }, | ||
timeout: 7000 | ||
}) | ||
const trackingResult = data?.events?.[0] | ||
if (!trackingResult) return | ||
const status = parseMandaeStatus(trackingResult) | ||
if (!status) { | ||
logger.warn(`No parsed fulfillment status for #${storeId} ${number}`, { | ||
trackingId, | ||
trackingResult | ||
}) | ||
return | ||
} | ||
const lineTrackingCodes = shippingLine.tracking_codes || [] | ||
if (!lineTrackingCodes.find(({ code }) => code === trackingId)) { | ||
lineTrackingCodes.push({ | ||
tag: 'mandae', | ||
code: trackingId, | ||
link: `https://rastreae.com.br/resultado/${trackingId}` | ||
}) | ||
await appSdk.apiRequest( | ||
storeId, | ||
`/orders/${order._id}/shipping_lines/${shippingLine._id}.json`, | ||
'PATCH', | ||
{ tracking_codes: lineTrackingCodes }, | ||
auth | ||
) | ||
} | ||
if (status !== order.fulfillment_status.current) { | ||
await appSdk.apiRequest( | ||
storeId, | ||
`/orders/${order._id}/fulfillments.json`, | ||
'POST', | ||
{ | ||
shipping_line_id: shippingLine._id, | ||
date_time: new Date().toISOString(), | ||
status, | ||
notification_code: `mandae:${trackingResult.id}:${trackingResult.name}`, | ||
flags: ['mandae'] | ||
}, | ||
auth | ||
) | ||
logger.info(`#${storeId} ${number} updated to ${status}`) | ||
} | ||
} |
Oops, something went wrong.