feat(txs): support for partial txs and full bill logging
This commit is contained in:
parent
bb4336b78f
commit
55abaa1bb9
3 changed files with 172 additions and 109 deletions
|
|
@ -1,6 +1,8 @@
|
|||
'use strict';
|
||||
|
||||
var pg = require('pg');
|
||||
var async = require('async');
|
||||
|
||||
var logger = require('./logger');
|
||||
|
||||
var PG_ERRORS = {
|
||||
|
|
@ -55,7 +57,7 @@ exports.recordBill = function recordBill(deviceFingerprint, rec, cb) {
|
|||
deviceFingerprint,
|
||||
rec.currency,
|
||||
rec.toAddress,
|
||||
res.txId,
|
||||
rec.txId,
|
||||
rec.deviceTime,
|
||||
|
||||
rec.satoshis,
|
||||
|
|
@ -67,7 +69,18 @@ exports.recordBill = function recordBill(deviceFingerprint, rec, cb) {
|
|||
fields.push('total_satoshis', 'total_fiat');
|
||||
}
|
||||
|
||||
client.query(getInsertQuery('bills', fields), values, cb);
|
||||
// NOTE: if is here to maintain compatibility with older machines
|
||||
if (rec.uuid) {
|
||||
values.push(rec.uuid);
|
||||
fields.push('uuid');
|
||||
}
|
||||
|
||||
client.query(getInsertQuery('bills', fields), values, function(err, billInfo) {
|
||||
if (err && PG_ERRORS[err.code] === 'uniqueViolation')
|
||||
return cb(null, {code: 304}); // 304 => Not Modified (vel. already noted)
|
||||
|
||||
cb(); // 201 => Accepted (vel. saved)
|
||||
});
|
||||
};
|
||||
|
||||
exports.recordDeviceEvent = function recordDeviceEvent(deviceFingerprint, event, cb) {
|
||||
|
|
@ -101,14 +114,59 @@ exports.getTransactions = function getTransactions(txId, cb) {
|
|||
_getTransactions(txId, false, cb);
|
||||
};
|
||||
|
||||
// TODO: this should probably return bills, associated with failed/inexistent tx
|
||||
exports.getPendingTransactions = function getPendingTransactions(txId, cb) {
|
||||
// should return
|
||||
// is_completed === false
|
||||
// amount from bils is less than sum of all parts with the same txId
|
||||
// latest bill with txId not present in transactions
|
||||
//
|
||||
_getTransactions(txId, true, cb);
|
||||
exports.getPendingAmount = function getPendingAmount(txId, cb) {
|
||||
async.parallel({
|
||||
// NOTE: `async.apply()` would strip context here
|
||||
txs: function(callback) {
|
||||
client.query(
|
||||
'SELECT * FROM transactions WHERE id=$1',
|
||||
[txId],
|
||||
callback
|
||||
);
|
||||
},
|
||||
bills: function(callback) {
|
||||
client.query(
|
||||
'SELECT * FROM bills WHERE transaction_id=$1 ORDER BY created DESC',
|
||||
[txId],
|
||||
callback
|
||||
);
|
||||
}
|
||||
}, function(err, results) {
|
||||
if (err) return cb(err);
|
||||
|
||||
// No bills == nothing to do
|
||||
if (results.bills.rows.length === 0)
|
||||
return cb();
|
||||
|
||||
var lastBill = results.bills.rows[0];
|
||||
|
||||
var newTx = {
|
||||
txId: txId,
|
||||
satoshis: lastBill.total_satoshis,
|
||||
fiat: lastBill.total_fiat,
|
||||
deviceDingerprint: lastBill.device_fingerprint,
|
||||
toAddress: lastBill.to_address,
|
||||
currencyCode: lastBill.currency_code
|
||||
};
|
||||
|
||||
// if there are txs, substract already sent amount
|
||||
if (results.txs.rows.length > 0) {
|
||||
newTx.part = results.txs.rows.length + 1;
|
||||
newTx.satoshis = lastBill.total_satoshis;
|
||||
newTx.fiat = lastBill.total_fiat;
|
||||
|
||||
results.txs.rows.forEach(function(tx) {
|
||||
newTx.satoshis -= tx.satoshis;
|
||||
newTx.fiat -= tx.fiat;
|
||||
});
|
||||
}
|
||||
|
||||
// Nothing to send == nothing to do
|
||||
if (newTx.satoshis <= 0)
|
||||
return cb();
|
||||
|
||||
cb(null, newTx);
|
||||
});
|
||||
};
|
||||
|
||||
exports.summonTransaction = function summonTransaction(deviceFingerprint, tx, cb) {
|
||||
|
|
@ -144,7 +202,7 @@ exports.summonTransaction = function summonTransaction(deviceFingerprint, tx, cb
|
|||
function(err) {
|
||||
if (err) {
|
||||
if (PG_ERRORS[err.code] === 'uniqueViolation')
|
||||
return exports.getTransactions(tx.txId, cb);
|
||||
return _getTransactions(tx.txId, false, cb);
|
||||
|
||||
return cb(err);
|
||||
}
|
||||
|
|
@ -155,6 +213,7 @@ exports.summonTransaction = function summonTransaction(deviceFingerprint, tx, cb
|
|||
|
||||
// `@more` can contain `part`, `hash`, or `error`
|
||||
exports.changeTxStatus = function changeTxStatus(txId, newStatus, more, cb) {
|
||||
more = more || {};
|
||||
cb = typeof cb === 'function' ? cb : function() {};
|
||||
|
||||
var query = 'UPDATE transactions SET status=$1';
|
||||
|
|
@ -174,8 +233,14 @@ exports.changeTxStatus = function changeTxStatus(txId, newStatus, more, cb) {
|
|||
values.push(more.hash);
|
||||
}
|
||||
|
||||
query += ' WHERE id=$' + n;
|
||||
query += ' WHERE id=$' + n++;
|
||||
values.push(txId);
|
||||
|
||||
var part = parseInt(more.part);
|
||||
if (part > 1) {
|
||||
query += ' AND part=$' + n++;
|
||||
values.push(part);
|
||||
}
|
||||
|
||||
client.query(query, values, cb);
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue