(function ($) { "use strict"; var ikkm = function () { var o = this; }; var p = ikkm.prototype; p.url = '';//адрес терминала p.key = '';//актуальный api ключ p.webroot = '';//корень сайта p.trackdocument = '';//идентификатор банковских документов p.init = function(init_data) { p.url = init_data.url; p.key = init_data.key; p.webroot = '/'+window.location.pathname.split('/')[1]+'/'; }; //тест связи с терминалом p.apicheck = function() { load_start(); $.post(p.url + '/apicheck',{"key":p.key}, function(data){ if (data == '0') ajax_msg('main_ikkm', 'success', p.error_connect(data), 2); else ajax_msg('main_ikkm', 'danger', p.error_connect(''), 2); load_finish(); }).fail(function(xhr, status, error) { ajax_msg('main_ikkm', 'danger', p.error_connect(xhr.responseText), 2); load_finish(); }); } //(promise) тест связи с терминалом p.status = function() { return $.post(p.url + '/apicheck',{key:p.key}); } //продажа p.sale = function(data, after_fn) { load_start(); var obj = JSON.parse(data); //console.log(obj); var new_data = { "key": String(p.key), "sale": String(obj['params']['sum']), "cash": String(obj['params']['cash']), "bank": String(obj['params']['noncash']) }; var items = []; $.post(p.url + '/dump/table/taxes', {"key":p.key}, function(data, textStatus, xhr){ var taxes = JSON.parse(data); var nds_id = ''; console.log(taxes); Object.keys(taxes).forEach(function(key){ if(String(taxes[key]).toLowerCase().includes('ндс') && !String(taxes[key]).toLowerCase().includes('без ндс')) { nds_id = key; console.log(nds_id); } }); Object.entries(obj['items']).forEach(function(element, index){ var itemdata = { "name": element[1]['name'].replace(/("\;|<([^>]+)>)/ig, "").replace(/"/g, "'"), "price": String(element[1]['price']), "qty": String(element[1]['count']), "sum": String(element[1]['summ']), }; if (parseInt(element[1]['sum_nds']) > 0) { itemdata['taxid'] = nds_id; } items.push(itemdata); }); if (obj['summ_discount'] > 0) { items.push({ "name": "Скидка итого:", "discount": obj['summ_discount'] }); } //console.log(new_data); new_data['itemdata'] = JSON.stringify(items); console.log(new_data); $.post(p.url + '/api', new_data, function(data, textStatus, xhr){ //console.log(xhr); var old_key = p.key; p.key = data; //обновляем ключ //сохраняем данные данные чека на сервере p.save_check(obj['out_guid'], old_key, xhr.statusText);//xhr.statusText - номер чека load_finish(); if (after_fn != undefined) after_fn(); }).fail(function(xhr, status, error) { console.log(xhr); ajax_msg('main', 'danger', p.error_connect(xhr.responseText), 2); }); }).fail(function(xhr, status, error) { console.log(xhr); ajax_msg('main', 'danger', p.error_connect(xhr.responseText), 2); }); } //возврат p.saleReturn = function (data) { load_start(); var obj = JSON.parse(data)['check']; var type = 'cash'; if (parseInt(obj['params']['cash']) == 0) { type = 'bank'; } //console.log(obj); var new_data = { "key": p.key, "saleReturn": Number(obj['params']['sum']) }; new_data[type] = parseInt(obj['params']['cash']) + parseInt(obj['params']['noncash']); var items = []; Object.entries(obj['items']).forEach(function(element, index) { items.push({ "name": element[1]['name'].replace(/("\;|<([^>]+)>)/ig, "").replace(/"/g, "'"), "price": Number(element[1]['price']), "qty": Number(element[1]['count']), "sum": Number(element[1]['summ']) }); }); if (obj['summ_discount'] > 0) { items.push({ "name": "Скидка итого:", "discount": obj['summ_discount'] }); } new_data['itemdata'] = JSON.stringify(items); //console.log(new_data); $.post(p.url + '/api', new_data, function(data){ p.key = data; p.update_session(); load_finish(); }).fail(function(xhr, status, error) { console.log(xhr); ajax_msg('main', 'danger', p.error_connect(xhr.responseText), 2); }); } //z-отчет p.zreport = function() { load_start(); p.current_shift().done(function(data) {//получаем текущую смену var obj = JSON.parse(data); //console.log(obj); if (obj['shiftState'] == 'opened') {//открыта ли текущая смена $.post(p.url + '/apizreport', { key: p.key }, function(data, textStatus, xhr){ //console.log(data); ajax_msg('main','success', 'Z отчет формируется. Смена будет закрыта.', 2); //регистрация отчета на сервере p.reg_zreport({ shift_number: obj['shiftId'], dateOpen: obj['dateOpen'], dateClose: obj['dateClose'] }); load_finish(); }).fail(function(xhr, status, error) { console.log(xhr); ajax_msg('main', 'danger', p.error_connect(xhr.responseText), 2); }); }else { ajax_msg('main', 'danger', 'Смена уже закрыта. Нет открытых смен.', 2); load_finish(); } }); } //x-отчет p.xreport = function() { $.post(p.url + '/apixreport', { key: p.key }, function(data){ //console.log(data); ajax_msg('main','success', 'X отчет успешно сформирован.', 2); }).fail(function(xhr, status, error) { console.log(xhr); ajax_msg('main', 'danger', p.error_connect(xhr.responseText), 2); }); } //старт банковской операции - покупка p.bank_purchase = function(amount) { //индентификатор чека (для отслеживания результата операции) p.trackdocument = p.generateUUID(); p.bank_operation({ message: 'purchase', amount: amount, trackdocument: p.trackdocument }); $('#bankOperation').modal('show'); $('#ikkm_bank_ok').focus(); } //старт банковской операции - возврат p.bank_refund = function(amount) { //индентификатор чека (для отслеживания результата операции) p.trackdocument = p.generateUUID(); p.bank_operation({ message: 'refund', amount: amount, trackdocument: p.trackdocument }); $('#bankOperation').modal('show'); $('#ikkm_bank_ok').focus(); } //старт банковской операции p.bank_operation = function(init_data) { console.log(trackdocument); $.post(p.url + '/apibank', { key: p.key, message: init_data.message, amount: init_data.amount, trackdocument: init_data.trackdocument }, function(data){ //console.log(data); if (data != '0') { ajax_msg('ikkm_modal', 'danger', p.error_connect(data), 2); } }).fail(function(xhr, status, error) { console.log(xhr); }); } //проверка результата банковской операции p.check_bank = function() { return $.post(p.url + '/dump/bank/'+Number(p.trackdocument)+'/trackdocument', {"key": p.key}); } //данные текущей/последней смены p.current_shift = function() { return $.post(p.url + '/dump/table/shifts/0/report', {key: p.key}); } //подробные данные о текущем состоянии терминала p.сurrent_state = function() { return $.post(p.url + '/apicheck/getInfo', {key: p.key}); } //снятие наличности p.withdraw = function(cash) { $.post(p.url + '/apiwithdraw', { key: p.key, cash: parseInt(cash) }, function(data){ //console.log(data); p.key = data; //регистрация операции на сервере p.reg_transaction('remove_cash', {cash: parseInt(cash)}); $('#formIkkmTransaction').modal('hide'); ajax_msg('main','success', 'Cумма '+cash+' успешно изъята.', 2); }).fail(function(xhr, status, error) { console.log(xhr); ajax_msg('main', 'danger', p.error_connect(xhr.responseText), 2); }); } //внесение наличности p.deposit = function(cash) { //console.log(cash); $.post(p.url + '/apideposit', { key: p.key, cash: parseInt(cash) }, function(data){ //console.log(data); p.key = data; //регистрация операции на сервере p.reg_transaction('deposit_cash', {cash: parseInt(cash)}); $('#formIkkmTransaction').modal('hide'); ajax_msg('main','success', 'Cумма '+cash+' успешно внесена.', 2); }).fail(function(xhr, status, error) { console.log(xhr); ajax_msg('main', 'danger', p.error_connect(xhr.responseText), 2); }); } //печать дубликата чека p.print_duplicate_check = function(key, number) { $.post(p.url + '/api', { "key": key, "sale": 0 }, function(data){ //console.log(data); }).fail(function(xhr, status, error) { //console.log(xhr); ajax_msg('main', 'warning', 'Дубликат чека доступен для печати через терминал. Документ №'+number+'.', 2); }); } //сохраняем данные данные чека на сервере p.save_check = function(out_guid, old_key, check_number){ $.post(p.webroot + 'Ikkm/save_check',{ out_guid: out_guid, old_key: old_key, check_number: check_number, trackdocument: p.trackdocument, key: p.key, url: p.url }, function(data){ console.log('check saved'); console.log('session updated'); console.log(data); p.trackdocument = ''; }); } //регистрация z-отчета на сервере (для кассовых отчетов) p.reg_zreport = function(data){ $.post(p.webroot + 'Ikkm/reg_zreport',data, function(data){ console.log('reg_zreport'); console.log(data); }); } //регистрация операций на сервере (для кассовых отчетов) p.reg_transaction = function(operation, data){ data['key'] = p.key; data['url'] = p.url; $.post(p.webroot + 'Ikkm/reg_transaction/'+operation, data, function(data){ console.log('reg_transaction'); console.log(data); }); } //обновляем сессионные переменные iKKM p.update_session = function(){ $.post(p.webroot + 'Ikkm/update_session',{ key: p.key, url: p.url }, function(data){ console.log('session updated'); console.log(data); }); } //коды ошибок p.error_connect = function(code) { if (parseInt(code) > 0) return 'Данные приняты'; switch (parseInt(code)) { case 0: return 'Устройство готово к работе'; case -1: return 'Неверный web-api ключ'; case -2: return 'Происходит регистрация или банковская операция, повторите запрос позже'; case -3: return 'Смена превысила 24 часа, необходимо закрыть смену'; case -4: return 'Oффлайн период более 72 часов, решить проблему связи и разблокировать ккм'; case -5: return 'Низкий заряд батареи ккм'; case -6: return 'Принтер не готов, проверить бумагу'; case -7: return 'Ошибка запроса, проверьте передаваемые параметры'; case -8: return 'Ошибка метода'; case -9: return 'Ошибка значений параметров передавать только цифры (кроме параметра print)'; case -10: return 'Сумма cash (bank, tara, credit) меньше sale (buy…), проверьте логику работы с API'; case -11: return 'Смена открыта другим кассиром, закрыть смену'; case -12: return 'Значение cash меньше чем расчетная итоговая сумма, может возникнуть если налог насчитывается поверх суммы'; case -13: return 'Банк или тара или кредит больше чем итоговая сумма (или чек уже оплачен наличностью) проверьте логику работы с API'; case -14: return 'Ошибка налога, указанный налог не найден'; case -15: return 'Нет наличности в кассе (возврат продажи, покупка), проверьте передаваемые параметры'; case -16: return 'Операцию может проводить только старший кассир, проверить пользователя'; case -17: return 'Ошибка обработки JSON запроса в itemdata, проверьте логику работы с API'; case -18: return 'Отклонен IP адрес хоста с которого выполнен запрос'; case -100: return '…-199 ккм заблокирован ОФД. см документацию ОФД'; case -99: return 'Ошибка iKKM "смотрите журнал событий на iKKM в меню состояние устройства"'; default: return 'Терминал недоступен или не работает, проверьте сеть, включен ли режим web-api, итд'; } } p.generateUUID = function () { //1 - 999.999.999 var uuid = Math.floor(Math.random() * Date.now()).toString(); return uuid.substring(uuid.length-9, uuid.length); } window.iKKM = new ikkm; }(jQuery));