67 lines
2.8 KiB
JavaScript
67 lines
2.8 KiB
JavaScript
|
const axios = require('axios');
|
||
|
const {DOMParser} = require('xmldom');
|
||
|
const UserError = require('vn-loopback/util/user-error');
|
||
|
|
||
|
module.exports = Self => {
|
||
|
Self.remoteMethod('exchangeRateUpdate', {
|
||
|
description: 'Updates the exchange rates from an XML feed',
|
||
|
accessType: 'WRITE',
|
||
|
accepts: [],
|
||
|
http: {
|
||
|
path: '/exchangeRateUpdate',
|
||
|
verb: 'post'
|
||
|
},
|
||
|
returns: {
|
||
|
arg: 'result',
|
||
|
type: 'object',
|
||
|
root: true
|
||
|
}
|
||
|
});
|
||
|
|
||
|
Self.exchangeRateUpdate = async() => {
|
||
|
const response = await axios.get('http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml');
|
||
|
const xmlData = response.data;
|
||
|
|
||
|
const doc = new DOMParser().parseFromString(xmlData, 'text/xml');
|
||
|
const cubes = doc.getElementsByTagName('Cube');
|
||
|
|
||
|
const models = Self.app.models;
|
||
|
|
||
|
const maxDateRecord = await models.ReferenceRate.findOne({order: 'dated DESC'});
|
||
|
let maxDate = maxDateRecord ? new Date(maxDateRecord.dated) : null;
|
||
|
|
||
|
for (const cube of cubes) {
|
||
|
if (cube.attributes.getNamedItem('time')) {
|
||
|
const xmlDate = new Date(cube.getAttribute('time'));
|
||
|
if (!maxDate || maxDate < xmlDate) {
|
||
|
for (const rateCube of cube.childNodes) {
|
||
|
if (rateCube.nodeType === Node.ELEMENT_NODE) {
|
||
|
const currencyCode = rateCube.getAttribute('currency');
|
||
|
const rate = rateCube.getAttribute('rate');
|
||
|
if (['USD', 'CNY', 'GBP'].includes(currencyCode)) {
|
||
|
const currency = await models.Currency.findOne({where: {code: currencyCode}});
|
||
|
if (!currency) throw new UserError(`Currency not found for code: ${currencyCode}`);
|
||
|
|
||
|
try {
|
||
|
await models.ReferenceRate.upsertWithWhere(
|
||
|
{currencyFk: currency.id, dated: xmlDate},
|
||
|
{
|
||
|
currencyFk: currency.id,
|
||
|
dated: xmlDate,
|
||
|
value: rate
|
||
|
}
|
||
|
);
|
||
|
} catch (error) {
|
||
|
console.error(`Failed to upsert rate for ${currencyCode} on ${xmlDate}: ${error}`);
|
||
|
// Handle or throw the error accordingly
|
||
|
throw error;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
};
|