decorate tx history with notes
This commit is contained in:
parent
a5c172af15
commit
fa1c63ac66
|
@ -15,8 +15,8 @@ TxNote.create = function(opts) {
|
|||
x.walletId = opts.walletId;
|
||||
x.txid = opts.txid;
|
||||
x.body = opts.body;
|
||||
x.lastEditedOn = now;
|
||||
x.lastEditedBy = opts.copayerId;
|
||||
x.editedOn = now;
|
||||
x.editedBy = opts.copayerId;
|
||||
|
||||
return x;
|
||||
};
|
||||
|
@ -29,16 +29,16 @@ TxNote.fromObj = function(obj) {
|
|||
x.walletId = obj.walletId;
|
||||
x.txid = obj.txid;
|
||||
x.body = obj.body;
|
||||
x.lastEditedOn = obj.lastEditedOn;
|
||||
x.lastEditedBy = obj.lastEditedBy;
|
||||
x.editedOn = obj.editedOn;
|
||||
x.editedBy = obj.editedBy;
|
||||
|
||||
return x;
|
||||
};
|
||||
|
||||
TxNote.prototype.edit = function(body, copayerId) {
|
||||
this.body = body;
|
||||
this.lastEditedBy = copayerId;
|
||||
this.lastEditedOn = Math.floor(Date.now() / 1000);
|
||||
this.editedBy = copayerId;
|
||||
this.editedOn = Math.floor(Date.now() / 1000);
|
||||
};
|
||||
|
||||
TxNote.prototype.toObject = function() {
|
||||
|
|
|
@ -2033,6 +2033,8 @@ WalletService.prototype.getTx = function(opts, cb) {
|
|||
if (err) return cb(err);
|
||||
if (!txp) return cb(Errors.TX_NOT_FOUND);
|
||||
|
||||
if (!txp.txid) return cb(null, txp);
|
||||
|
||||
self.storage.fetchTxNote(self.walletId, txp.txid, function(err, note) {
|
||||
if (err) {
|
||||
log.warn('Error fetching tx note for ' + txp.txid);
|
||||
|
@ -2542,10 +2544,11 @@ WalletService.prototype.getTxHistory = function(opts, cb) {
|
|||
if (opts.limit > Defaults.HISTORY_LIMIT)
|
||||
return cb(Errors.HISTORY_LIMIT_EXCEEDED);
|
||||
|
||||
function decorate(txs, addresses, proposals) {
|
||||
function decorate(txs, addresses, proposals, notes) {
|
||||
|
||||
var indexedAddresses = _.indexBy(addresses, 'address');
|
||||
var indexedProposals = _.indexBy(proposals, 'txid');
|
||||
var indexedNotes = _.indexBy(notes, 'txid');
|
||||
|
||||
function sum(items, isMine, isChange) {
|
||||
var filter = {};
|
||||
|
@ -2659,6 +2662,11 @@ WalletService.prototype.getTxHistory = function(opts, cb) {
|
|||
//newTx.paymentAckMemo = proposal.paymentAckMemo;
|
||||
}
|
||||
|
||||
var note = indexedNotes[tx.txid];
|
||||
if (note) {
|
||||
newTx.note = _.pick(note, ['body', 'editedBy', 'editedByName', 'editedOn']);
|
||||
}
|
||||
|
||||
return newTx;
|
||||
});
|
||||
};
|
||||
|
@ -2675,10 +2683,7 @@ WalletService.prototype.getTxHistory = function(opts, cb) {
|
|||
async.parallel([
|
||||
|
||||
function(next) {
|
||||
self.storage.fetchTxs(self.walletId, {}, function(err, txps) {
|
||||
if (err) return next(err);
|
||||
next(null, txps);
|
||||
});
|
||||
self.storage.fetchTxs(self.walletId, {}, next);
|
||||
},
|
||||
function(next) {
|
||||
var from = opts.skip || 0;
|
||||
|
@ -2688,13 +2693,17 @@ WalletService.prototype.getTxHistory = function(opts, cb) {
|
|||
next(null, self._normalizeTxHistory(txs));
|
||||
});
|
||||
},
|
||||
function(next) {
|
||||
self.storage.fetchTxNotes(self.walletId, next);
|
||||
},
|
||||
], function(err, res) {
|
||||
if (err) return cb(err);
|
||||
|
||||
var proposals = res[0];
|
||||
var txs = res[1];
|
||||
var notes = res[2];
|
||||
|
||||
txs = decorate(txs, addresses, proposals);
|
||||
txs = decorate(txs, addresses, proposals, notes);
|
||||
|
||||
return cb(null, txs);
|
||||
});
|
||||
|
|
|
@ -630,6 +630,33 @@ Storage.prototype.fetchTxNote = function(walletId, txid, cb) {
|
|||
});
|
||||
};
|
||||
|
||||
// TODO: should be done client-side
|
||||
Storage.prototype._completeTxNotesData = function(walletId, notes, cb) {
|
||||
var notesList = [].concat(notes);
|
||||
this.fetchWallet(walletId, function(err, wallet) {
|
||||
if (err) return cb(err);
|
||||
_.each(notesList, function(note) {
|
||||
note.editedByName = wallet.getCopayer(note.editedBy).name;
|
||||
});
|
||||
return cb(null, notes);
|
||||
});
|
||||
};
|
||||
|
||||
Storage.prototype.fetchTxNotes = function(walletId, cb) {
|
||||
var self = this;
|
||||
|
||||
this.db.collection(collections.TX_NOTES).find({
|
||||
walletId: walletId,
|
||||
}).toArray(function(err, result) {
|
||||
if (err) return cb(err);
|
||||
var notes = _.compact(_.map(result, function(note) {
|
||||
if (!note.body) return;
|
||||
return Model.TxNote.fromObj(note);
|
||||
}));
|
||||
return self._completeTxNotesData(walletId, notes, cb);
|
||||
});
|
||||
};
|
||||
|
||||
Storage.prototype.storeTxNote = function(txNote, cb) {
|
||||
this.db.collection(collections.TX_NOTES).update({
|
||||
txid: txNote.txid,
|
||||
|
|
|
@ -3858,8 +3858,8 @@ describe('Wallet service', function() {
|
|||
note.txid.should.equal('123');
|
||||
note.walletId.should.equal(wallet.id);
|
||||
note.body.should.equal('note body');
|
||||
note.lastEditedBy.should.equal(server.copayerId);
|
||||
note.createdOn.should.equal(note.lastEditedOn);
|
||||
note.editedBy.should.equal(server.copayerId);
|
||||
note.createdOn.should.equal(note.editedOn);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@ -3876,9 +3876,9 @@ describe('Wallet service', function() {
|
|||
}, function(err, note) {
|
||||
should.not.exist(err);
|
||||
should.exist(note);
|
||||
note.lastEditedBy.should.equal(server.copayerId);
|
||||
note.createdOn.should.equal(note.lastEditedOn);
|
||||
var creator = note.lastEditedBy;
|
||||
note.editedBy.should.equal(server.copayerId);
|
||||
note.createdOn.should.equal(note.editedOn);
|
||||
var creator = note.editedBy;
|
||||
helpers.getAuthServer(wallet.copayers[1].id, function(server) {
|
||||
clock.tick(60 * 1000);
|
||||
server.editTxNote({
|
||||
|
@ -3891,9 +3891,9 @@ describe('Wallet service', function() {
|
|||
}, function(err, note) {
|
||||
should.not.exist(err);
|
||||
should.exist(note);
|
||||
note.lastEditedBy.should.equal(server.copayerId);
|
||||
note.createdOn.should.be.below(note.lastEditedOn);
|
||||
creator.should.not.equal(note.lastEditedBy);
|
||||
note.editedBy.should.equal(server.copayerId);
|
||||
note.createdOn.should.be.below(note.editedOn);
|
||||
creator.should.not.equal(note.editedBy);
|
||||
clock.restore();
|
||||
done();
|
||||
});
|
||||
|
@ -3935,7 +3935,7 @@ describe('Wallet service', function() {
|
|||
txp.note.txid.should.equal(txp.txid);
|
||||
txp.note.walletId.should.equal(wallet.id);
|
||||
txp.note.body.should.equal('note body');
|
||||
txp.note.lastEditedBy.should.equal(server.copayerId);
|
||||
txp.note.editedBy.should.equal(server.copayerId);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@ -3954,8 +3954,8 @@ describe('Wallet service', function() {
|
|||
}, function(err, note) {
|
||||
should.not.exist(err);
|
||||
should.exist(note);
|
||||
note.lastEditedBy.should.equal(server.copayerId);
|
||||
var creator = note.lastEditedBy;
|
||||
note.editedBy.should.equal(server.copayerId);
|
||||
var creator = note.editedBy;
|
||||
helpers.getAuthServer(wallet.copayers[1].id, function(server) {
|
||||
server.getTxNote({
|
||||
txid: '123',
|
||||
|
@ -3963,7 +3963,7 @@ describe('Wallet service', function() {
|
|||
should.not.exist(err);
|
||||
should.exist(note);
|
||||
note.body.should.equal('note body');
|
||||
note.lastEditedBy.should.equal(creator);
|
||||
note.editedBy.should.equal(creator);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@ -3997,6 +3997,43 @@ describe('Wallet service', function() {
|
|||
});
|
||||
});
|
||||
});
|
||||
it('should include the note in tx history listing', function(done) {
|
||||
helpers.createAddresses(server, wallet, 1, 1, function(mainAddresses, changeAddress) {
|
||||
server._normalizeTxHistory = sinon.stub().returnsArg(0);
|
||||
var txs = [{
|
||||
txid: '123',
|
||||
confirmations: 1,
|
||||
fees: 100,
|
||||
time: 20,
|
||||
inputs: [{
|
||||
address: 'external',
|
||||
amount: 500,
|
||||
}],
|
||||
outputs: [{
|
||||
address: mainAddresses[0].address,
|
||||
amount: 200,
|
||||
}],
|
||||
}];
|
||||
helpers.stubHistory(txs);
|
||||
server.editTxNote({
|
||||
txid: '123',
|
||||
body: 'just some note'
|
||||
}, function(err) {
|
||||
should.not.exist(err);
|
||||
server.getTxHistory({}, function(err, txs) {
|
||||
should.not.exist(err);
|
||||
should.exist(txs);
|
||||
txs.length.should.equal(1);
|
||||
var tx = txs[0];
|
||||
should.exist(tx.note);
|
||||
tx.note.body.should.equal('just some note');
|
||||
tx.note.editedBy.should.equal(server.copayerId);
|
||||
should.exist(tx.note.editedOn);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue