Модуль обмена с АТОЛ-онлайн - API v4, ФФД 1.05 (начало)

This commit is contained in:
Mikhail Chechnev 2018-12-26 14:59:51 +03:00
parent c9f7eff30f
commit 8962defb1d

View File

@ -3,38 +3,245 @@
Дополнительный модуль: Взаимодействие с "АТОЛ-Онлайн" (v4) в формате ФФД 1.05
*/
//----------------------
// Подключение библиотек
//----------------------
const util = require("util"); //Встроенные вспомогательные утилиты
const parseString = require("xml2js").parseString; //Конвертация XML в JSON
const _ = require("lodash"); //Работа с массивами и коллекциями
//---------------------
// Глобальные константы
//---------------------
//Словарь - Признак способа расчёта
const paymentMethod = {
sName: "Признак способа расчёта",
vals: {
"1": "full_prepayment",
"2": "prepayment",
"3": "advance",
"4": "full_payment",
"5": "partial_payment",
"6": "credit",
"7": "credit_payment"
}
};
//Словарь - Признак предмета расчёта
const paymentObject = {
sName: "Признак предмета расчёта",
vals: {
"1": "commodity",
"2": "excise",
"3": "job",
"4": "service",
"5": "gambling_bet",
"6": "gambling_prize",
"7": "lottery",
"8": "lottery_prize",
"9": "intellectual_activity",
"10": "payment",
"11": "agent_commission",
"12": "composite",
"13": "another",
"14": "property_right",
"15": "non-operating_gain",
"16": "insurance_premium",
"17": "sales_tax",
"18": "resort_fee"
}
};
//------------
// Тело модуля
//------------
//Обработчик "До" отправки чека серверу "АТОЛ-Онлайн"
const beforeRegBillSIR = async prms => {
console.log(`Начал обработку отправки чека ДО - ${prms.queue.nId}`);
//throw Error("AAAAAAAAAAAAA");
let res = {
blMsg: new Buffer("NEW SOME DATA")
};
if (!prms.service.context.token) {
console.log("NO TOKEN!!!");
res.context = { token: `NEW TOKEN FOR${prms.queue.nId}` };
} else {
console.log(prms.service.context);
}
console.log(prms.queue.blMsg.toString());
await promiceTimer(2500);
console.log(`Закончил обработку отправки чека ДО - ${prms.queue.nId}`);
//Разбор XML
const parseXML = xmlDoc => {
return new Promise((resolve, reject) => {
parseString(xmlDoc, { explicitArray: false, mergeAttrs: true }, function(err, result) {
if (err) reject(err);
else resolve(result);
});
});
};
//Конвертация значений в ожидаемые систеой АТОЛ-онлайн
const mapDictionary = (dict, sValue) => {
if (!dict) throw Error(`Словарь не определен`);
if (!dict.sName || !dict.vals || !(dict.vals instanceof Object)) throw Error(`Словарь имеет некорректный формат`);
if (typeof sValue === "undefined" || sValue === null || sValue === "")
throw Error(`Не указано значение для привязки к словарю "${dict.sName}"`);
const res = dict.vals[sValue];
if (typeof res === "undefined") throw Error(`Значение "${sValue}" отсутствует в словаре "${dict.sName}"`);
return res;
};
//Обработчик "После" отправки чека серверу "АТОЛ-Онлайн"
const afterRegBillSIR = async prms => {
console.log(`Начал обработку отправки чека ПОСЛЕ - ${prms.queue.nId}`);
console.log(prms.service.context);
console.log(prms.queue.blMsg.toString());
//await promiceTimer(2500);
console.log(`Закончил обработку отправки чека ПОСЛЕ - ${prms.queue.nId}`);
//Поиск значения в составе свойств фискального документа по коду свойства
const getPropValueByCode = (props, sCode, sValType = "STR", sValField = "VALUE") => {
if (!["STR", "NUM", "DATE"].includes(sValType)) throw Error(`Тип данных "${sValType}" не поддерживается`);
let res = null;
let prop = _.find(props, { SCODE: sCode });
if (typeof prop !== "undefined") {
res = prop[sValField];
if (typeof res === "undefined") res = null;
else if (res === "") res = null;
if (res !== null) {
switch (sValType) {
case "STR": {
try {
res = res.toString();
} catch (e) {
throw Error(`Ошибка конвертации значения "${res}" в строку: ${e.message}`);
}
break;
}
case "NUM": {
if (isNaN(res)) throw Error(`Значение "${res}" не является числом`);
try {
res = Number(res);
} catch (e) {
throw Error(`Ошибка конвертации значения "${res}" в число: ${e.message}`);
}
break;
}
case "DATE": {
const resTmp = res;
try {
res = new Date(res);
} catch (e) {
throw Error(`Ошибка конвертации значения "${resTmp}" в дату: ${e.message}`);
}
if (res instanceof Date && isNaN(res))
throw Error(`Значение "${resTmp}" не является корректной датой`);
break;
}
default:
throw Error(`Тип данных "${sValType}" не поддерживается`);
}
}
}
return res;
};
//Обработчик "До" отправки запроса на регистрацию чека (приход, расход, возврат) серверу "АТОЛ-Онлайн"
const beforeRegBillSIR = async prms => {
try {
const parseRes = await parseXML(prms.queue.blMsg.toString());
const doc = parseRes.FISCDOC;
const docProps = parseRes.FISCDOC.FISCDOC_PROPS.FISCDOC_PROP;
let reqBody = {
timestamp: doc.SDDOC_DATE,
external_id: doc.NRN,
/*
service: {
callback_url: ""
},
*/
receipt: {
client: {
email: getPropValueByCode(docProps, "1008"),
phone: ""
},
company: {
email: getPropValueByCode(docProps, "1117"),
sno: getPropValueByCode(docProps, "1117"),
inn: getPropValueByCode(docProps, "1018"),
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: [
{
name: getPropValueByCode(docProps, "1030"),
price: getPropValueByCode(docProps, "1079", "NUM"),
quantity: getPropValueByCode(docProps, "1023", "NUM"),
sum: getPropValueByCode(docProps, "1043", "NUM"),
measurement_unit: getPropValueByCode(docProps, "1197"),
payment_method: mapDictionary(paymentMethod, getPropValueByCode(docProps, "1214")),
payment_object: mapDictionary(paymentObject, getPropValueByCode(docProps, "1212")),
vat: {
type: "none",
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: ""
*/
}
],
payments: [
{
type: 0,
sum: 0
}
],
vats: [
{
type: "",
sum: 0
}
],
total: 0 /*,
additional_check_props: "",
cashier: "",
additional_user_props: {
name: "",
value: ""
}
*/
}
};
console.log(util.inspect(reqBody, false, null));
} catch (e) {
throw Error(e);
}
};
//Обработчик "После" отправки запроса на регистрацию чека (приход, расход, возврат) серверу "АТОЛ-Онлайн"
const afterRegBillSIR = async prms => {};
//-----------------
// Интерфейс модуля
//-----------------