/** * 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; }