From 863b1bd1a38cf5b063a08abce867ac2129f3ad1f Mon Sep 17 00:00:00 2001 From: Mikhail Chechnev Date: Wed, 22 Jul 2020 17:38:29 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=B1=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D1=87=D0=B8=D0=BA=20=D1=81=D0=BE=D0=BE=D0=B1=D1=89=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B9=20=D0=B4=D0=BB=D1=8F=20=D1=80=D0=B0=D1=81=D1=88?= =?UTF-8?q?=D0=B8=D1=80=D0=B5=D0=BD=D0=B8=D1=8F=20"=D0=98=D0=BD=D1=82?= =?UTF-8?q?=D0=B5=D0=B3=D1=80=D0=B0=D1=86=D0=B8=D1=8F=20=D0=AD=D0=94=D0=9E?= =?UTF-8?q?=20=D0=A1=D0=91=D0=98=D0=A1"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/sbis.js | 217 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 modules/sbis.js diff --git a/modules/sbis.js b/modules/sbis.js new file mode 100644 index 0000000..c9fd683 --- /dev/null +++ b/modules/sbis.js @@ -0,0 +1,217 @@ +/* + Сервис интеграции ПП Парус 8 с WEB API + Дополнительный модуль: Интеграция с ЭДО "СБИС" (SBIS) +*/ + +//------------------------------ +// Подключение внешних библиотек +//------------------------------ + +const xml2js = require("xml2js"); //Конвертация XML в JSON и JSON в XML +const _ = require("lodash"); //Работа с коллекциями и объектами + +//--------------------- +// Глобальные константы +//--------------------- + +// Список тегов которые должны содержать массив +const tag = [ + "Вложение", + "Редакция", + "ДокументОснование", + "ДокументСледствие", + "Подпись", + "Событие", + "Этап", + "Действие", + "Сертификат" +]; + +//------------ +// Тело модуля +//------------ + +//Обернуть содержимое тега в массив +const toArray = (obj, tags) => { + for (const prop in obj) { + const value = obj[prop]; + if (tags.indexOf(prop) != -1 && !_.isArray(obj[prop])) { + obj[prop] = JSON.parse("[" + JSON.stringify(value) + "]"); + } + if (typeof value === "object") { + toArray(value, tag); + } + } + return obj; +}; + +//Конвертация в XML +const toXML = obj => { + const builder = new xml2js.Builder(); + return builder.buildObject(obj); +}; + +//Конвертация в JSON +const parseXML = xmlDoc => { + return new Promise((resolve, reject) => { + xml2js.parseString(xmlDoc, { explicitArray: false, mergeAttrs: true }, (err, result) => { + if (err) reject(err); + else resolve(result); + }); + }); +}; + +//Конвертация в JSON +const toJSON = async obj => { + let result = await parseXML(obj); + result = result.root; + toArray(result, tag); + return result; +}; + +//Добавление определённого количетсва часов к дате +const addHours = (dDate, nHours) => { + dDate.setTime(dDate.getTime() + nHours * 60 * 60 * 1000); + return new Date(dDate); +}; + +//Обработчик "До" подключения к сервису +const beforeConnect = async prms => { + //Подготовим параметры аутентификации + const prmAtribute = "Параметр"; + const loginAtribute = "Логин"; + const passAtribute = "Пароль"; + //Сформируем запрос на аутентификацию + return { + options: { + headers: { + "content-type": "application/json;charset=utf-8" + }, + body: JSON.stringify({ + jsonrpc: "2.0", + method: "СБИС.Аутентифицировать", + params: { + [prmAtribute]: { + [loginAtribute]: prms.service.sSrvUser, + [passAtribute]: prms.service.sSrvPass + } + }, + id: 0 + }), + simple: false + } + }; +}; + +//Обработчик "После" подключения к сервису +const afterConnect = async prms => { + let resp = null; + //Разберем ответ + if (prms.queue.blResp) { + try { + resp = JSON.parse(prms.queue.blResp.toString()); + } catch (e) { + throw new Error(`Неожиданный ответ сервера ЭДО "СБИС". Ошибка интерпретации: ${e.message}`); + } + } else { + throw new Error('Сервер ЭДО "СБИС" не вернул ответ'); + } + //Если в нём нет ошибок + if (!resp.error) { + //Сохраним полученный токен доступа в контекст сервиса + return { + blResp: new Buffer(resp.result), + sCtx: resp.result, + dCtxExp: addHours(new Date(), 23) + }; + } else { + throw new Error( + `Сервер ЭДО "СБИС" вернул ошибку: ${resp.error.message ? resp.error.message : "Неожиданная ошибка"}` + ); + } +}; + +//Обработчик "До" отправки запроса к сервису "СБИС" +const beforeDocParse = async prms => { + try { + //Считаем токен доступа из контекста сервиса + let sToken = null; + if (prms.service.sCtx) { + sToken = prms.service.sCtx; + } + //Если не достали из контекста токен доступа - значит нет аутентификации на сервере + if (!sToken) return { bUnAuth: true }; + //Конвертируем XML из "Парус 8" в понятный "СБИСу" JSON + let obj = await toJSON(prms.queue.blMsg.toString()); + //Собираем и отдаём общий результат работы + return { + options: { + headers: { + "Content-type": "application/json; charset=utf-8", + "X-SBISSessionID": sToken, + srv: 1 + }, + simple: false, + func: obj.method + }, + blMsg: new Buffer(JSON.stringify(obj)) + }; + } catch (e) { + throw Error(e); + } +}; + +//Обработчик "После" запроса к сервису "СБИС" +const afterDocParse = async prms => { + //Преобразуем JSON ответ сервиса "СБИС" в XML, понятный "Парус 8" + let resu = null; + if (prms.queue.blResp) { + try { + resu = toXML(JSON.parse(prms.queue.blResp.toString())); + } catch (e) { + throw new Error(`Неожиданный ответ сервера ЭДО "СБИС". Ошибка интерпретации: ${e.message}`); + } + } else { + throw new Error('Сервер ЭДО "СБИС" не вернул ответ'); + } + //Возврат результата + return { + blResp: new Buffer(resu) + }; +}; + +//Обработчик "До" отправки запроса на загрузку вложения +const beforeAttParse = async prms => { + try { + //Считаем токен доступа из контекста сервиса + let sToken = null; + if (prms.service.sCtx) { + sToken = prms.service.sCtx; + } + //Если не достали из контекста токен доступа - значит нет аутентификации на сервере + if (!sToken) return { bUnAuth: true }; + //Собираем и отдаём общий результат работы + return { + options: { + headers: { + "Content-type": "application/json; charset=utf-8", + "X-SBISSessionID": sToken, + srv: 1 + }, + simple: false + } + }; + } catch (e) { + throw Error(e); + } +}; + +//----------------- +// Интерфейс модуля +//----------------- + +exports.beforeConnect = beforeConnect; +exports.afterConnect = afterConnect; +exports.beforeDocParse = beforeDocParse; +exports.afterDocParse = afterDocParse; +exports.beforeAttParse = beforeAttParse;