Подключаемые модули взаимодействия с АТОЛ-Онлайн под реальную схему аутентификации

This commit is contained in:
Mikhail Chechnev 2019-01-06 00:37:19 +03:00
parent 1a64f7999b
commit 1661b36faf
2 changed files with 88 additions and 96 deletions

View File

@ -4,7 +4,6 @@ create or replace package UDO_PKG_EXS_ATOL as
procedure V4_FFD105_PROCESS_REG_BILL_SIR procedure V4_FFD105_PROCESS_REG_BILL_SIR
( (
NIDENT in number, -- Èäåíòèôèêàòîð ïðîöåññà NIDENT in number, -- Èäåíòèôèêàòîð ïðîöåññà
NSRV_TYPE in number, -- Òèï ñåðâèñà (ñì. êîíñòàíòû PKG_EXS.NSRV_TYPE*)
NEXSQUEUE in number -- Ðåãèñòðàöèîííûé íîìåð îáðàáàòûâàåìîé ïîçèöèè î÷åðåäè îáìåíà NEXSQUEUE in number -- Ðåãèñòðàöèîííûé íîìåð îáðàáàòûâàåìîé ïîçèöèè î÷åðåäè îáìåíà
); );
@ -16,7 +15,6 @@ create or replace package body UDO_PKG_EXS_ATOL as
procedure V4_FFD105_PROCESS_REG_BILL_SIR procedure V4_FFD105_PROCESS_REG_BILL_SIR
( (
NIDENT in number, -- Èäåíòèôèêàòîð ïðîöåññà NIDENT in number, -- Èäåíòèôèêàòîð ïðîöåññà
NSRV_TYPE in number, -- Òèï ñåðâèñà (ñì. êîíñòàíòû PKG_EXS.NSRV_TYPE*)
NEXSQUEUE in number -- Ðåãèñòðàöèîííûé íîìåð îáðàáàòûâàåìîé ïîçèöèè î÷åðåäè îáìåíà NEXSQUEUE in number -- Ðåãèñòðàöèîííûé íîìåð îáðàáàòûâàåìîé ïîçèöèè î÷åðåäè îáìåíà
) )
is is
@ -44,6 +42,12 @@ create or replace package body UDO_PKG_EXS_ATOL as
end if; end if;
/* Âûñòàâëÿåì èäåíòèôèêàòîð ÀÒÎË â ÔÄ */ /* Âûñòàâëÿåì èäåíòèôèêàòîð ÀÒÎË â ÔÄ */
update UDO_FISCDOCS T set T.NUMB_FD = CTMP where T.RN = REXSQUEUE.LNK_DOCUMENT; update UDO_FISCDOCS T set T.NUMB_FD = CTMP where T.RN = REXSQUEUE.LNK_DOCUMENT;
/* Âñ¸ ïðîøëî óñïåøíî */
PKG_EXS.PRC_RESP_RESULT_SET(NIDENT => NIDENT);
exception
when others then
/* Âåðí¸ì îøèáêó */
PKG_EXS.PRC_RESP_RESULT_SET(NIDENT => NIDENT, SRESULT => PKG_EXS.SPRC_RESP_RESULT_ERR, SMSG => sqlerrm);
end V4_FFD105_PROCESS_REG_BILL_SIR; end V4_FFD105_PROCESS_REG_BILL_SIR;
end; end;

View File

@ -4,8 +4,8 @@
Полный формат формируемой посылки: Полный формат формируемой посылки:
reqBody = { reqBody = {
timestamp: doc.SDDOC_DATE, timestamp: "",
external_id: doc.NRN, external_id: 0,
service: { service: {
callback_url: "" callback_url: ""
}, },
@ -237,26 +237,62 @@ const getPropValueByCode = (props, sCode, sValType = "STR", sValField = "VALUE")
return res; return res;
}; };
//Подключение к сервису //Конвертация строки в формате ДД.ММ.ГГГГ ЧЧ:МИ:СС в JS Date
const connect = async prms => { const strDDMMYYYYHHMISStoDate = sDate => {
let authFn = _.find(prms.service.functions, { nFnType: NFN_TYPE_LOGIN }); let res = null;
if (!authFn) throw Error(`Для сервиса ${prms.service.sCode} не определена функция аутентификации`); if (sDate) {
try { try {
let serverResp = JSON.parse( const [date, time] = sDate.split(" ");
await rqp({ const [day, month, year] = date.split(".");
method: authFn.sFnPrmsType, const [hh, min, ss] = time.split(":");
url: buildURL({ sSrvRoot: prms.service.sSrvRoot, sFnURL: authFn.sFnURL }), res = new Date(year, month - 1, day, hh, min, ss);
body: JSON.stringify({ login: prms.service.sSrvUser, pass: prms.service.sSrvPass }), if (isNaN(res.getTime())) {
simple: false res = null;
}) } else {
); res.addHours = function(nHours) {
if (serverResp.error === null) { this.setTime(this.getTime() + nHours * 60 * 60 * 1000);
return serverResp.token; return this;
} else { };
throw Error(serverResp.error.text); }
} catch (e) {
res = null;
} }
} catch (e) { }
throw Error(`Ошибка аутентификации на сервере АТОЛ-Онлайн: ${e.message}`); return res;
};
//Обработчик "До" подключения к сервису
const beforeConnect = async prms => {
return {
options: {
headers: {
"Content-type": "application/json; charset=utf-8"
},
body: JSON.stringify({ login: prms.service.sSrvUser, pass: prms.service.sSrvPass }),
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 === null) {
return {
sCtx: resp.token,
dCtxExp: strDDMMYYYYHHMISStoDate(resp.timestamp).addHours(24)
};
} else {
throw new Error(`Сервер АТОЛ-Онлайн вернул ошибку: ${resp.error.text}`);
} }
}; };
@ -267,13 +303,11 @@ const beforeRegBillSIR = async prms => {
const sGroupCode = "v4-online-atol-ru_4179"; const sGroupCode = "v4-online-atol-ru_4179";
//Токен доступа //Токен доступа
let sToken = null; let sToken = null;
if (prms.service.context && prms.service.context.sToken) { if (prms.service.sCtx) {
sToken = prms.service.context.sToken; sToken = prms.service.sCtx;
} else {
sToken = await connect(prms);
} }
//Если не достали из контекста токен доступа - значит нет аутентификации на сервере
if (!sToken) throw Error("Не удалось получить токен доступа"); if (!sToken) return { bUnAuth: true };
//Разберем XML-данные фискального документа //Разберем XML-данные фискального документа
const parseRes = await parseXML(prms.queue.blMsg.toString()); const parseRes = await parseXML(prms.queue.blMsg.toString());
//Сохраним короткие ссылки на документ и его свойства //Сохраним короткие ссылки на документ и его свойства
@ -285,12 +319,6 @@ const beforeRegBillSIR = async prms => {
let reqBody = { let reqBody = {
timestamp: doc.SDDOC_DATE, timestamp: doc.SDDOC_DATE,
external_id: doc.NRN, external_id: doc.NRN,
/*
service: {
callback_url: ""
},
*/
receipt: { receipt: {
client: { client: {
email: "mim_@mail.ru", //getPropValueByCode(docProps, "1008"), email: "mim_@mail.ru", //getPropValueByCode(docProps, "1008"),
@ -302,27 +330,6 @@ const beforeRegBillSIR = async prms => {
inn: getPropValueByCode(docProps, "1018"), inn: getPropValueByCode(docProps, "1018"),
payment_address: "г. Казань" //getPropValueByCode(docProps, "1187") payment_address: "г. Казань" //getPropValueByCode(docProps, "1187")
}, },
/*
agent_info: {
type: "",
paying_agent: {
operation: "",
phones: [""]
},
receive_payments_operator: {
phones: [""]
},
money_transfer_operator: {
phones: [""],
name: "",
address: "",
inn: ""
}
},
supplier_info: {
phones: [""]
},
*/
items: [ items: [
{ {
name: getPropValueByCode(docProps, "1030"), name: getPropValueByCode(docProps, "1030"),
@ -337,31 +344,7 @@ const beforeRegBillSIR = async prms => {
vat: { vat: {
type: "none", //getPropValueByCode(docProps, "1199") type: "none", //getPropValueByCode(docProps, "1199")
sum: getPropValueByCode(docProps, "1200", "NUM") sum: getPropValueByCode(docProps, "1200", "NUM")
} /*, }
agent_info: {
type: "",
paying_agent: {
operation: "",
phones: [""]
},
receive_payments_operator: {
phones: [""]
},
money_transfer_operator: {
phones: [""],
name: "",
address: "",
inn: ""
}
},
supplier_info: {
phones: [""],
name: "",
address: "",
inn: ""
},
user_data: ""
*/
} }
], ],
total: getPropValueByCode(docProps, "1020", "NUM") total: getPropValueByCode(docProps, "1020", "NUM")
@ -448,7 +431,6 @@ const beforeRegBillSIR = async prms => {
//Собираем общий результат работы //Собираем общий результат работы
let res = { let res = {
options: { options: {
method: prms.function.sFnPrmsType,
url: buildURL({ sSrvRoot: prms.service.sSrvRoot, sFnURL: prms.function.sFnURL }) url: buildURL({ sSrvRoot: prms.service.sSrvRoot, sFnURL: prms.function.sFnURL })
.replace("<group_code>", sGroupCode) .replace("<group_code>", sGroupCode)
.replace("<operation>", sOperation), .replace("<operation>", sOperation),
@ -458,11 +440,8 @@ const beforeRegBillSIR = async prms => {
}, },
simple: false simple: false
}, },
blMsg: new Buffer(JSON.stringify(reqBody)), blMsg: new Buffer(JSON.stringify(reqBody))
context: { sToken }
}; };
//Выводим что получилось
console.log(util.inspect(res, false, null));
//Возврат резульатата //Возврат резульатата
return res; return res;
} catch (e) { } catch (e) {
@ -472,19 +451,26 @@ const beforeRegBillSIR = async prms => {
//Обработчик "После" отправки запроса на регистрацию чека (приход, расход, возврат) серверу "АТОЛ-Онлайн" //Обработчик "После" отправки запроса на регистрацию чека (приход, расход, возврат) серверу "АТОЛ-Онлайн"
const afterRegBillSIR = async prms => { const afterRegBillSIR = async prms => {
let tmp = null; let resp = null;
try { if (prms.queue.blResp) {
tmp = JSON.parse(prms.serverResp); try {
} catch (e) { resp = JSON.parse(prms.queue.blResp.toString());
throw Error("Неожиданный ответ сервера АТОЛ-Онлайн!"); } catch (e) {
} throw new Error(`Неожиданный ответ сервера АТОЛ-Онлайн. Ошибка интерпретации: ${e.message}`);
if (tmp.error !== null) { }
throw Error(tmp.error.text);
} else { } else {
console.log(tmp); throw new Error(`Сервер АТОЛ-Онлайн не вернул ответ`);
}
if (resp.error === null) {
return { return {
blResp: new Buffer(tmp.uuid) blResp: new Buffer(resp.uuid)
}; };
} else {
if (resp.error.code === 10 || resp.error.code === 11) {
return { bUnAuth: true };
} else {
throw new Error(`Сервер АТОЛ-Онлайн вернул ошибку: ${resp.error.text}`);
}
} }
}; };
@ -492,5 +478,7 @@ const afterRegBillSIR = async prms => {
// Интерфейс модуля // Интерфейс модуля
//----------------- //-----------------
exports.beforeConnect = beforeConnect;
exports.afterConnect = afterConnect;
exports.beforeRegBillSIR = beforeRegBillSIR; exports.beforeRegBillSIR = beforeRegBillSIR;
exports.afterRegBillSIR = afterRegBillSIR; exports.afterRegBillSIR = afterRegBillSIR;