Модуль обмена с АТОЛ-онлайн - API v4, ФФД 1.05 (начало)
This commit is contained in:
parent
c9f7eff30f
commit
8962defb1d
@ -3,38 +3,245 @@
|
|||||||
Дополнительный модуль: Взаимодействие с "АТОЛ-Онлайн" (v4) в формате ФФД 1.05
|
Дополнительный модуль: Взаимодействие с "АТОЛ-Онлайн" (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"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
//------------
|
//------------
|
||||||
// Тело модуля
|
// Тело модуля
|
||||||
//------------
|
//------------
|
||||||
|
|
||||||
//Обработчик "До" отправки чека серверу "АТОЛ-Онлайн"
|
//Разбор XML
|
||||||
const beforeRegBillSIR = async prms => {
|
const parseXML = xmlDoc => {
|
||||||
console.log(`Начал обработку отправки чека ДО - ${prms.queue.nId}`);
|
return new Promise((resolve, reject) => {
|
||||||
//throw Error("AAAAAAAAAAAAA");
|
parseString(xmlDoc, { explicitArray: false, mergeAttrs: true }, function(err, result) {
|
||||||
let res = {
|
if (err) reject(err);
|
||||||
blMsg: new Buffer("NEW SOME DATA")
|
else resolve(result);
|
||||||
|
});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
if (!prms.service.context.token) {
|
|
||||||
console.log("NO TOKEN!!!");
|
//Конвертация значений в ожидаемые систеой АТОЛ-онлайн
|
||||||
res.context = { token: `NEW TOKEN FOR${prms.queue.nId}` };
|
const mapDictionary = (dict, sValue) => {
|
||||||
} else {
|
if (!dict) throw Error(`Словарь не определен`);
|
||||||
console.log(prms.service.context);
|
if (!dict.sName || !dict.vals || !(dict.vals instanceof Object)) throw Error(`Словарь имеет некорректный формат`);
|
||||||
}
|
if (typeof sValue === "undefined" || sValue === null || sValue === "")
|
||||||
console.log(prms.queue.blMsg.toString());
|
throw Error(`Не указано значение для привязки к словарю "${dict.sName}"`);
|
||||||
await promiceTimer(2500);
|
const res = dict.vals[sValue];
|
||||||
console.log(`Закончил обработку отправки чека ДО - ${prms.queue.nId}`);
|
if (typeof res === "undefined") throw Error(`Значение "${sValue}" отсутствует в словаре "${dict.sName}"`);
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
//Обработчик "После" отправки чека серверу "АТОЛ-Онлайн"
|
//Поиск значения в составе свойств фискального документа по коду свойства
|
||||||
const afterRegBillSIR = async prms => {
|
const getPropValueByCode = (props, sCode, sValType = "STR", sValField = "VALUE") => {
|
||||||
console.log(`Начал обработку отправки чека ПОСЛЕ - ${prms.queue.nId}`);
|
if (!["STR", "NUM", "DATE"].includes(sValType)) throw Error(`Тип данных "${sValType}" не поддерживается`);
|
||||||
console.log(prms.service.context);
|
let res = null;
|
||||||
console.log(prms.queue.blMsg.toString());
|
let prop = _.find(props, { SCODE: sCode });
|
||||||
//await promiceTimer(2500);
|
if (typeof prop !== "undefined") {
|
||||||
console.log(`Закончил обработку отправки чека ПОСЛЕ - ${prms.queue.nId}`);
|
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 => {};
|
||||||
|
|
||||||
//-----------------
|
//-----------------
|
||||||
// Интерфейс модуля
|
// Интерфейс модуля
|
||||||
//-----------------
|
//-----------------
|
||||||
|
Loading…
x
Reference in New Issue
Block a user