diff --git a/index.js b/index.js index bc14214..fefaeb7 100644 --- a/index.js +++ b/index.js @@ -3,11 +3,22 @@ process.chdir(__dirname); const fs = require('fs'); fs.writeFileSync('pid.txt', process.pid); +const config = require('komodo-sdk/config'); +const logger = require('komodo-sdk/logger'); + require('komodo-sdk/api-server'); const pullgw = require('komodo-sdk/gateway/pull'); const partner = require('./lib/partner'); -require('./lib/reverse-report'); const adviceServer = require('komodo-sdk/gateway/advice-push-server'); +if (config.partner && config.partner.reverse_report_irs) { + logger.info('Reverse report using IRS mode'); + require('./lib/irs/reverse-report'); +} +else { + require('./lib/reverse-report'); +} + + pullgw.setPartner(partner); adviceServer.setPartner(partner); diff --git a/lib/irs/irs.js b/lib/irs/irs.js new file mode 100644 index 0000000..7a743d0 --- /dev/null +++ b/lib/irs/irs.js @@ -0,0 +1,103 @@ +"use strict"; + +const rcFromMsg = require('komodo-sdk/rc-from-msg'); +const organicRc = require('./rc'); + +function getRcFromMessage(msg, customRc) { + let rc; + if (customRc) { + rc = rcFromMsg(msg, customRc); + } + + if (!rc) { + rc = rcFromMsg(msg, organicRc); + } + + return rc; +} + +function getPriceFromMessage(msg, rule) { + if (typeof msg !== 'string') { + return; + } + + if (process.env.DEBUG_IRS && !rule) { + console.log('** IRS.getPriceFromMessage no rule'); // eslint-disable-line no-console + } + + if (process.env.DEBUG_IRS && rule) { + console.log('** IRS.getPriceFromMessage rule: ' + JSON.stringify(rule, null, 2)); // eslint-disable-line no-console + } + + const pattern = (rule && typeof rule.pattern === 'string') ? rule.pattern : "Harga: ([\\d\\.]+?) "; + const match_idx = (rule && typeof rule.match_idx === 'number') ? rule.match_idx : 1; + + const re = new RegExp(pattern); + const matches = msg.match(re); + if (process.env.DEBUG_IRS) { + console.log('** IRS.getPriceFromMessage msg: "' + msg + '" active_pattern: "' + pattern + '" active_match_idx: ' + match_idx); // eslint-disable-line no-console + console.log('** IRS.getPriceFromMessage matches:\n' + JSON.stringify(matches)); // eslint-disable-line no-console + } + if (matches && matches[match_idx]) { + const result = Number(matches[match_idx].replace(/\./g, '')); + if (process.env.DEBUG_IRS) { + console.log('** IRS.getPriceFromMessage SUPPLIER-PRICE: ' + result); // eslint-disable-line no-console + } + return result; + } +} + +function extractFromMessage(msg, rule) { + if (typeof msg !== 'string') { return; } + + if (!rule) { return; } + + if (typeof rule !== 'object') { + return; + } + + rule.match_idx = Number(rule.match_idx); + + if (!rule.match_idx) { + rule.match_idx = 1; + } + + const re = new RegExp(rule.pattern); + const matches = msg.match(re); + if (matches && matches[rule.match_idx] && typeof matches[rule.match_idx] === 'string') { + return matches[rule.match_idx]; + } +} + +function getSnFromMessage(msg, rule) { + if (!rule) { + rule = { + pattern: "SN: (\\d+)", + match_idx: 1 + } + } + + let sn = extractFromMessage(msg, rule); + if (!sn || typeof sn !== 'string') { return; } + + return sn.toUpperCase().replace(/[^a-zA-Z0-9/]/g, '-').replace(/-+/g, '-').replace(/-*\/-*/g, '/').replace(/^-+/, '').replace(/-+$/, ''); +} + +function getBalanceFromMessage(msg, rule) { + if (!rule) { + rule = { + pattern: "Sisa Saldo: .+? = ([\\d\\.]+) ", + match_idx: 1 + } + } + + let result = extractFromMessage(msg, rule); + if (!result || typeof result !== 'string') { return; } + + return Number(result.replace(/\./g, '')); +} + +exports.getRcFromMessage = getRcFromMessage; +exports.getPriceFromMessage = getPriceFromMessage; +exports.getSnFromMessage = getSnFromMessage; +exports.getBalanceFromMessage = getBalanceFromMessage; diff --git a/lib/irs/rc.js b/lib/irs/rc.js new file mode 100644 index 0000000..a179a95 --- /dev/null +++ b/lib/irs/rc.js @@ -0,0 +1,65 @@ +module.exports = [ + { + pattern: " BERHASIL", + rc: '00' + }, + { + pattern: "SUKSES", + rc: '00' + }, + { + pattern: " under process", + rc: '68' + }, + { + pattern: " under proses", + rc: '68' + }, + { + pattern: " sedang dalam antrian", + rc: '68' + }, + { + pattern: " sdg dalam antrian", + rc: '68' + }, + { + pattern: " sedang diproses", + rc: '68' + }, + { + pattern: " sdg diproses", + rc: '68' + }, + { + pattern: " nomor tujuan dan produk tidak sesuai", + rc: '14', + flags: 'i' + }, + { + pattern: " tujuan salah", + rc: '14' + }, + { + pattern: "Nomor tidak valid", + rc: '14' + }, + { + pattern: "Maaf Produk sedang gangguan", + rc: '90', + flags: 'i' + }, + { + pattern: "Maaf.*Sedang gangguan. Coba ulangi beberapa saat lagi", + rc: '90', + flags: 'i' + }, + { + pattern: " RC:61 ", + rc: '90' + }, + { + pattern: "GAGAL", + rc: '40' + } +] diff --git a/lib/irs/reverse-report.js b/lib/irs/reverse-report.js new file mode 100644 index 0000000..638fa85 --- /dev/null +++ b/lib/irs/reverse-report.js @@ -0,0 +1,62 @@ +"use strict"; + +const http = require('http'); +const url = require('url'); + +const stringify = require("json-stringify-pretty-compact"); + +const config = require('komodo-sdk/config'); +const logger = require('komodo-sdk/logger'); + +const partner = require('../partner'); +const irs = require('./irs'); + +function processPartnerReport(qs) { + let rc = '68'; + if (qs.statuscode === '1') { + rc = '00'; + } + else if (qs.statuscode === '2') { + rc = '40'; + } + + if (rc === '40') { + rc = irs.getRcFromMessage(qs.msg) || '40'; + } + + let amount = null; + if (rc === '00') { + amount = Number(qs.hrg); + if (!amount) { + amount = irs.getPriceFromMessage(qs.msg, config.partner.price_pattern); + } + } + + partner.report({ + trx_id: qs.clientid, + rc: rc, + message: 'REVERSE-REPORT: ' + stringify(qs), + raw: stringify(qs), + sn: (qs.sn ? qs.sn : null) || irs.getSnFromMessage(qs.msg, config.partner.sn_pattern) || null, + amount: amount, + balance: (rc === '00') ? irs.getBalanceFromMessage(qs.msg, config.partner.balance_pattern) : null, + misc: {} + }) +} + +function create() { + http.createServer(function (req, res) { + res.writeHead(200, {'Content-Type': 'text/html'}); + const qs = url.parse(req.url, true).query; + res.end('OK'); + + const remote_ip = req.connection ? req.connection.remoteAddress : null; + logger.verbose('REVERSE-REPORT: got report from partner', {url: req.url, remote_ip: remote_ip}); + + processPartnerReport(qs); + }).listen(config.reverse_report_port); + + logger.info('REVERSE-REPORT: listen on port ' + config.reverse_report_port); +} + +config.reverse_report_port && create();