/** * The transaction performs a transfer of the amount from a submitter to a recipient. This is the * same as performing a contribution of the submitter and then a payout to the recipient. * * @param sender the name of the participant who lost the amount * @param amount the amount of the transfer * @param comment a <code>String</code> to make the transaction recognizable * @param recipient the name of the participant who got the amount * @return the entry id of the transaction or -1 in case the transaction failed or -2 if the * transaction violates the 'no negative total' rule */ public int performTransfer(String sender, double amount, String comment, String recipient) { boolean internal = isInternal(sender); if (internal) { if (breaksDebtLimit(amount)) return -2; } int transactionCode = 2; int flags = composeFlags(transactionCode, false); int entryId = addEntry(sender, amount, currency, comment, flags); if (entryId < 0) return -1; flags = composeFlags(transactionCode, sender.equals(recipient)); long rowId = addRecord(entryId, recipient, -amount, currency, Helper.timestampNow(), comment, flags); if (rowId < 0) { removeEntry(entryId); return -1; } Log.i( TAG, String.format( "entry %d: %s transfer %f %s for '%s' to %s", entryId, sender, amount, currency, comment, recipient)); return entryId; }
/** * The transaction registers multiple submissions. This transaction as a whole is not allowed if * it causes a negative total. * * @param deals a <code>ShareMap</code> containing the deals of participants involved * @param comment a <code>String</code> to make the transactions recognizable * @return the entry id of the transaction or -1 in case the transaction failed or -2 if the * transactions in the sum violate the 'no negative total' rule */ public int performMultiple(ShareMap deals, String comment) { if (breaksDebtLimit(-deals.sum())) return -2; int transactionCode = 4; int flags = composeFlags(transactionCode, false); int entryId = getNewEntryId(); if (entryId > -1) { for (Map.Entry<String, Double> share : deals.rawMap.entrySet()) if (addRecord( entryId, share.getKey(), share.getValue(), currency, Helper.timestampNow(), comment, flags) < 0) { removeEntry(entryId); return -1; } Log.i( TAG, String.format("entry %d: '%s' submissions : %s", entryId, comment, deals.toString())); } return entryId; }
/** * The transaction registers the negated sum of the shares as an expense by a group of * contributors. Additionally all the shares in the map are registered with the same entry id. * Those names in the deals map that are empty <code>String</code> trigger transfers of internal * amounts. Such an internal transfer is not allowed if the transaction causes a negative total. * * @param deals the names of the contributors and their contributions who expended an amount * matching the negated sum of the deals * @param comment a <code>String</code> to make the transaction recognizable * @param shares a <code>ShareMap</code> containing the shares of participants involved * @return the entry id of the transaction or a negative value in case the transaction failed */ public int performComplexExpense(ShareMap deals, String comment, ShareMap shares) { int entryId = -1; int transactionCode = 3; int flags = composeFlags(transactionCode, true); double amount = deals.sum(); if (Math.abs(amount + shares.sum()) < ShareUtil.delta) { if (deals.option != null) switch (deals.option) { default: setDebtLimit(1000. * deals.option); break; } if (deals.rawMap.containsKey(kitty)) entryId = performTransfer(kitty, -deals.rawMap.get(kitty), comment, kitty); else entryId = getNewEntryId(); Collection<String> dealers = ShareUtil.filter(deals.rawMap.keySet(), true, ShareUtil.isKitty); for (String name : dealers) { long rowId = addRecord( entryId, name, deals.rawMap.get(name), currency, Helper.timestampNow(), comment, flags); if (rowId < 0) { entryId = -1; break; } } } else Log.w( TAG, String.format( "the sum of the deals (%f) for '%s' doesn't match the sum of the shares (%f)", amount, comment, shares.sum())); if (entryId > -1) { if (allocate(flags, entryId, shares.rawMap)) { Log.i( TAG, String.format( "entry %d: %s expended %f %s for '%s' shared by %s", entryId, deals.toString(), Math.abs(amount), currency, comment, shares.toString())); } else { removeEntry(entryId); entryId = -1; } } if (entryId < 0) removeEntry(entryId); return entryId; }
/** @hide */ public int addEntry(String name, double amount, String currency, String comment, int flags) { int entryId = getNewEntryId(); long rowId = addRecord(entryId, name, amount, currency, Helper.timestampNow(), comment, flags); if (rowId < 0) { removeEntry(entryId); entryId = -1; } return entryId; }