Обработка запросов на получение статуса чека в ATOL-онлайн, смена типа данных тэга 1199 (признак ставки НДС), корректная установка времени истечения сессии ATOL при аутентификации, дополнительный контроль наличия данных в посылке при отправке запроса на регистрацию чека

This commit is contained in:
Mikhail Chechnev 2019-01-10 17:24:53 +03:00
parent e67b078ca4
commit c352f9f487
2 changed files with 90 additions and 15 deletions

View File

@ -7,6 +7,13 @@ create or replace package UDO_PKG_EXS_ATOL as
NEXSQUEUE in number -- Ðåãèñòðàöèîííûé íîìåð îáðàáàòûâàåìîé ïîçèöèè î÷åðåäè îáìåíà NEXSQUEUE in number -- Ðåãèñòðàöèîííûé íîìåð îáðàáàòûâàåìîé ïîçèöèè î÷åðåäè îáìåíà
); );
/* Îòðàáîòêà îòâåòîâ ÀÒÎË (v4) íà çàïðîñ ñâåäåíèé î çàðåãèñòðèðîâàííîì äîêóìåíòå (ÔÔÄ 1.05) */
procedure V4_FFD105_PROCESS_GET_BILL_INF
(
NIDENT in number, -- Èäåíòèôèêàòîð ïðîöåññà
NEXSQUEUE in number -- Ðåãèñòðàöèîííûé íîìåð îáðàáàòûâàåìîé ïîçèöèè î÷åðåäè îáìåíà
);
end; end;
/ /
create or replace package body UDO_PKG_EXS_ATOL as create or replace package body UDO_PKG_EXS_ATOL as
@ -50,5 +57,29 @@ create or replace package body UDO_PKG_EXS_ATOL as
PKG_EXS.PRC_RESP_RESULT_SET(NIDENT => NIDENT, SRESULT => PKG_EXS.SPRC_RESP_RESULT_ERR, SMSG => sqlerrm); 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;
/* Îòðàáîòêà îòâåòîâ ÀÒÎË (v4) íà çàïðîñ ñâåäåíèé î çàðåãèñòðèðîâàííîì äîêóìåíòå (ÔÔÄ 1.05) */
procedure V4_FFD105_PROCESS_GET_BILL_INF
(
NIDENT in number, -- Èäåíòèôèêàòîð ïðîöåññà
NEXSQUEUE in number -- Ðåãèñòðàöèîííûé íîìåð îáðàáàòûâàåìîé ïîçèöèè î÷åðåäè îáìåíà
)
is
REXSQUEUE EXSQUEUE%rowtype; -- Çàïèñü ïîçèöèè î÷åðåäè
CTMP clob; -- Áóôåð äëÿ õðàíåíèÿ äàííûõ îòâåòà ñåðâåðà
begin
/* Ñ÷èòàåì çàïèñü î÷åðåäè */
REXSQUEUE := GET_EXSQUEUE_ID(NFLAG_SMART => 0, NRN => NEXSQUEUE);
/* Ðàçáèðàåì îòâåò */
CTMP := BLOB2CLOB(LBDATA => REXSQUEUE.RESP, SCHARSET => 'UTF8');
if (CTMP is null) then
P_EXCEPTION(0, 'Íåò îòâåòà îò ñåðâåðà.');
end if;
/* Âñ¸ ïðîøëî óñïåøíî */
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_GET_BILL_INF;
end; end;
/ /

View File

@ -115,6 +115,9 @@ const { NFN_TYPE_LOGIN } = require("@models/obj_service_function");
// Глобальные константы // Глобальные константы
//--------------------- //---------------------
//Код круппы ККТ
const SGROUP_CODE = "v4-online-atol-ru_4179";
//Словарь - Признак способа расчёта //Словарь - Признак способа расчёта
const paymentMethod = { const paymentMethod = {
sName: "Признак способа расчёта", sName: "Признак способа расчёта",
@ -250,6 +253,12 @@ const getPropValueByCode = (props, sCode, sValType = "STR", sValField = "VALUE")
return res; return res;
}; };
//Добавление определённого количетсва часов к дате
const addHours = (dDate, nHours) => {
dDate.setTime(dDate.getTime() + nHours * 60 * 60 * 1000);
return new Date(dDate);
};
//Конвертация строки в формате ДД.ММ.ГГГГ ЧЧ:МИ:СС в JS Date //Конвертация строки в формате ДД.ММ.ГГГГ ЧЧ:МИ:СС в JS Date
const strDDMMYYYYHHMISStoDate = sDate => { const strDDMMYYYYHHMISStoDate = sDate => {
let res = null; let res = null;
@ -261,11 +270,6 @@ const strDDMMYYYYHHMISStoDate = sDate => {
res = new Date(year, month - 1, day, hh, min, ss); res = new Date(year, month - 1, day, hh, min, ss);
if (isNaN(res.getTime())) { if (isNaN(res.getTime())) {
res = null; res = null;
} else {
res.addHours = function(nHours) {
this.setTime(this.getTime() + nHours * 60 * 60 * 1000);
return this;
};
} }
} catch (e) { } catch (e) {
res = null; res = null;
@ -303,7 +307,7 @@ const afterConnect = async prms => {
return { return {
blResp: new Buffer(resp.token), blResp: new Buffer(resp.token),
sCtx: resp.token, sCtx: resp.token,
dCtxExp: strDDMMYYYYHHMISStoDate(resp.timestamp).addHours(24) dCtxExp: addHours(new Date(), 23)
}; };
} else { } else {
throw new Error(`Сервер АТОЛ-Онлайн вернул ошибку: ${resp.error.text}`); throw new Error(`Сервер АТОЛ-Онлайн вернул ошибку: ${resp.error.text}`);
@ -313,8 +317,6 @@ const afterConnect = async prms => {
//Обработчик "До" отправки запроса на регистрацию чека (приход, расход, возврат) серверу "АТОЛ-Онлайн" //Обработчик "До" отправки запроса на регистрацию чека (приход, расход, возврат) серверу "АТОЛ-Онлайн"
const beforeRegBillSIR = async prms => { const beforeRegBillSIR = async prms => {
try { try {
//Код круппы ККТ
const sGroupCode = "v4-online-atol-ru_4179";
//Токен доступа //Токен доступа
let sToken = null; let sToken = null;
if (prms.service.sCtx) { if (prms.service.sCtx) {
@ -324,11 +326,15 @@ const beforeRegBillSIR = async prms => {
if (!sToken) return { bUnAuth: true }; if (!sToken) return { bUnAuth: true };
//Разберем XML-данные фискального документа //Разберем XML-данные фискального документа
let parseRes = null; let parseRes = null;
if (prms.queue.blMsg) {
try { try {
parseRes = await parseXML(prms.queue.blMsg.toString()); parseRes = await parseXML(prms.queue.blMsg.toString());
} catch (e) { } catch (e) {
throw new Error("Ошибка рабора XML"); throw new Error("Ошибка рабора XML");
} }
} else {
throw new Error("В теле сообщения отсутствуют данные фискального документа");
}
//Сохраним короткие ссылки на документ и его свойства //Сохраним короткие ссылки на документ и его свойства
const doc = parseRes.FISCDOC; const doc = parseRes.FISCDOC;
const docProps = parseRes.FISCDOC.FISCDOC_PROPS.FISCDOC_PROP; const docProps = parseRes.FISCDOC.FISCDOC_PROPS.FISCDOC_PROP;
@ -359,7 +365,7 @@ const beforeRegBillSIR = async prms => {
payment_method: mapDictionary(paymentMethod, getPropValueByCode(docProps, "1214")), payment_method: mapDictionary(paymentMethod, getPropValueByCode(docProps, "1214")),
payment_object: mapDictionary(paymentObject, getPropValueByCode(docProps, "1212")), payment_object: mapDictionary(paymentObject, getPropValueByCode(docProps, "1212")),
vat: { vat: {
type: mapDictionary(receiptItemVat, getPropValueByCode(docProps, "1199")), type: mapDictionary(receiptItemVat, getPropValueByCode(docProps, "1199", "NUM")),
sum: getPropValueByCode(docProps, "1200", "NUM") sum: getPropValueByCode(docProps, "1200", "NUM")
} }
} }
@ -449,7 +455,7 @@ const beforeRegBillSIR = async prms => {
let res = { let res = {
options: { options: {
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>", SGROUP_CODE)
.replace("<operation>", sOperation), .replace("<operation>", sOperation),
headers: { headers: {
"Content-type": "application/json; charset=utf-8", "Content-type": "application/json; charset=utf-8",
@ -491,6 +497,42 @@ const afterRegBillSIR = async prms => {
} }
}; };
//Обработчик "До" отправки запроса на получение информации о чеке серверу "АТОЛ-Онлайн"
const beforeGetBillInfo = async prms => {
//Токен доступа
let sToken = null;
if (prms.service.sCtx) {
sToken = prms.service.sCtx;
}
//Если не достали из контекста токен доступа - значит нет аутентификации на сервере
if (!sToken) return { bUnAuth: true };
//Забираем идентификатор документа из тела сообщения
let sUUID = null;
if (prms.queue.blMsg) sUUID = prms.queue.blMsg.toString();
if (!sUUID) throw new Error("В теле сообщения не указан идентификатор документа в АТОЛ-Онлайн");
//Собираем общий результат работы
let res = {
options: {
url: buildURL({ sSrvRoot: prms.service.sSrvRoot, sFnURL: prms.function.sFnURL })
.replace("<group_code>", SGROUP_CODE)
.replace("<uuid>", sUUID),
headers: {
"Content-type": "application/json; charset=utf-8",
Token: sToken
},
simple: false
}
};
//Возврат резульатата
return res;
};
//Обработчик "После" отправки запроса на получение информации о чеке серверу "АТОЛ-Онлайн"
const afterGetBillInfo = async prms => {
if (prms.queue.blResp) console.log(prms.queue.blResp.toString());
else console.log("Сервер не вернул ответ");
};
//----------------- //-----------------
// Интерфейс модуля // Интерфейс модуля
//----------------- //-----------------
@ -499,3 +541,5 @@ exports.beforeConnect = beforeConnect;
exports.afterConnect = afterConnect; exports.afterConnect = afterConnect;
exports.beforeRegBillSIR = beforeRegBillSIR; exports.beforeRegBillSIR = beforeRegBillSIR;
exports.afterRegBillSIR = afterRegBillSIR; exports.afterRegBillSIR = afterRegBillSIR;
exports.beforeGetBillInfo = beforeGetBillInfo;
exports.afterGetBillInfo = afterGetBillInfo;